mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-02 02:47:31 -04:00
net: atlantic: unify MAC generation
This patch unifies invalid MAC address handling with other drivers.
Basically we've switched to using standard APIs (is_valid_ether_addr /
eth_hw_addr_random) where possible.
It's worth noting that some of engineering Aquantia NICs might be
provisioned with a partially zeroed out MAC, which is still invalid,
but not caught by is_valid_ether_addr(), so we've added a special
handling for this case.
Also adding a warning in case of fallback to random MAC, because
this shouldn't be needed on production NICs, they should all be
provisioned with unique MAC.
NB! Default systemd/udevd configuration is 'MACAddressPolicy=persistent'.
This causes MAC address to be persisted across driver reloads and
reboots. We had to change it to 'none' for verification purposes.
Signed-off-by: Mark Starovoytov <mstarovoitov@marvell.com>
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
097d638cf4
commit
b4de6c49e5
@@ -272,6 +272,14 @@ static int aq_nic_hw_prepare(struct aq_nic_s *self)
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool aq_nic_is_valid_ether_addr(const u8 *addr)
|
||||
{
|
||||
/* Some engineering samples of Aquantia NICs are provisioned with a
|
||||
* partially populated MAC, which is still invalid.
|
||||
*/
|
||||
return !(addr[0] == 0 && addr[1] == 0 && addr[2] == 0);
|
||||
}
|
||||
|
||||
int aq_nic_ndev_register(struct aq_nic_s *self)
|
||||
{
|
||||
int err = 0;
|
||||
@@ -296,6 +304,12 @@ int aq_nic_ndev_register(struct aq_nic_s *self)
|
||||
if (err)
|
||||
goto err_exit;
|
||||
|
||||
if (!is_valid_ether_addr(self->ndev->dev_addr) ||
|
||||
!aq_nic_is_valid_ether_addr(self->ndev->dev_addr)) {
|
||||
netdev_warn(self->ndev, "MAC is invalid, will use random.");
|
||||
eth_hw_addr_random(self->ndev);
|
||||
}
|
||||
|
||||
#if defined(AQ_CFG_MAC_ADDR_PERMANENT)
|
||||
{
|
||||
static u8 mac_addr_permanent[] = AQ_CFG_MAC_ADDR_PERMANENT;
|
||||
|
||||
@@ -283,8 +283,6 @@ static int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac)
|
||||
u32 efuse_addr = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_EFUSE_ADDR);
|
||||
u32 mac_addr[2] = { 0 };
|
||||
int err = 0;
|
||||
u32 h = 0U;
|
||||
u32 l = 0U;
|
||||
|
||||
if (efuse_addr != 0) {
|
||||
err = hw_atl_utils_fw_downld_dwords(self,
|
||||
@@ -299,26 +297,6 @@ static int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac)
|
||||
|
||||
ether_addr_copy(mac, (u8 *)mac_addr);
|
||||
|
||||
if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
|
||||
unsigned int rnd = 0;
|
||||
|
||||
get_random_bytes(&rnd, sizeof(unsigned int));
|
||||
|
||||
l = 0xE3000000U | (0xFFFFU & rnd) | (0x00 << 16);
|
||||
h = 0x8001300EU;
|
||||
|
||||
mac[5] = (u8)(0xFFU & l);
|
||||
l >>= 8;
|
||||
mac[4] = (u8)(0xFFU & l);
|
||||
l >>= 8;
|
||||
mac[3] = (u8)(0xFFU & l);
|
||||
l >>= 8;
|
||||
mac[2] = (u8)(0xFFU & l);
|
||||
mac[1] = (u8)(0xFFU & h);
|
||||
h >>= 8;
|
||||
mac[0] = (u8)(0xFFU & h);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <linux/iopoll.h>
|
||||
|
||||
#include "aq_hw.h"
|
||||
#include "aq_hw_utils.h"
|
||||
#include "hw_atl/hw_atl_llh.h"
|
||||
#include "hw_atl2_utils.h"
|
||||
#include "hw_atl2_llh.h"
|
||||
@@ -212,28 +213,6 @@ static int aq_a2_fw_get_mac_permanent(struct aq_hw_s *self, u8 *mac)
|
||||
hw_atl2_shared_buffer_get(self, mac_address, mac_address);
|
||||
ether_addr_copy(mac, (u8 *)mac_address.aligned.mac_address);
|
||||
|
||||
if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
|
||||
unsigned int rnd = 0;
|
||||
u32 h;
|
||||
u32 l;
|
||||
|
||||
get_random_bytes(&rnd, sizeof(unsigned int));
|
||||
|
||||
l = 0xE3000000U | (0xFFFFU & rnd) | (0x00 << 16);
|
||||
h = 0x8001300EU;
|
||||
|
||||
mac[5] = (u8)(0xFFU & l);
|
||||
l >>= 8;
|
||||
mac[4] = (u8)(0xFFU & l);
|
||||
l >>= 8;
|
||||
mac[3] = (u8)(0xFFU & l);
|
||||
l >>= 8;
|
||||
mac[2] = (u8)(0xFFU & l);
|
||||
mac[1] = (u8)(0xFFU & h);
|
||||
h >>= 8;
|
||||
mac[0] = (u8)(0xFFU & h);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user