diff options
author | Mark Starovoytov <mstarovoitov@marvell.com> | 2020-05-09 09:47:00 +0300 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2020-05-09 11:47:25 -0700 |
commit | b4de6c49e569c7ca91bf0d4c25cdb6eeca9c9529 (patch) | |
tree | fa4de5589f90228f431513a5daab93e2798e067d /drivers/net/ethernet/aquantia/atlantic | |
parent | 097d638cf4e19be208d26c6bbbca7f8da348294a (diff) |
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>
Diffstat (limited to 'drivers/net/ethernet/aquantia/atlantic')
3 files changed, 15 insertions, 44 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 18cad06f2ea7..1c6d12deb47a 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -272,6 +272,14 @@ exit: 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; diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c index 017364486703..eeedd8c90067 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c @@ -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; } diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c index e8f4aad8c1e5..0ffc33bd67d0 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c @@ -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; } |