Whenever MGMT requests MAC addr change and FW does it, driver does not get aligned to that change. Current - legacy approach doesn't handle such scenario. Poll RAR0 (Receive Address Register) each service task cycle and update driver and netdev structs once new MAC addr is detected. It may happen that FW updates MAC address stored in RAR0 during runtime so SW shall fetch the new address. Refresh addr also during reset path to ensure the address survives RAR0 clearing during init_hw(). Signed-off-by: Jedrzej Jagielski --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index d1cfe913081f..ce2b1e208c0f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -6499,6 +6499,36 @@ void ixgbe_disable_tx(struct ixgbe_adapter *adapter) } } +static void ixgbe_mac_addr_refresh(struct ixgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct ixgbe_hw *hw = &adapter->hw; + int err; + + if (hw->mac.type != ixgbe_mac_e610) + return; + + /* fetch address stored currently in RAR0 in case the addr has been + * altered by FW; if so, use it as the default one + */ + err = hw->mac.ops.get_mac_addr(hw, hw->mac.addr); + if (err) { + e_dev_warn("Cannot get MAC address\n"); + return; + } + + if (ether_addr_equal(netdev->dev_addr, hw->mac.addr) || + !is_valid_ether_addr(hw->mac.addr)) + return; + + ASSERT_RTNL(); + + eth_hw_addr_set(netdev, hw->mac.addr); + ether_addr_copy(adapter->mac_table[0].addr, hw->mac.addr); + + call_netdevice_notifiers(NETDEV_CHANGEADDR, netdev); +} + void ixgbe_reset(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; @@ -6516,6 +6546,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) IXGBE_FLAG2_SFP_NEEDS_RESET); adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG; + ixgbe_mac_addr_refresh(adapter); + err = hw->mac.ops.init_hw(hw); switch (err) { case 0: @@ -8701,6 +8733,11 @@ static void ixgbe_service_task(struct work_struct *work) ixgbe_handle_fw_event(adapter); ixgbe_check_media_subtask(adapter); } + + rtnl_lock(); + ixgbe_mac_addr_refresh(adapter); + rtnl_unlock(); + ixgbe_reset_subtask(adapter); ixgbe_phy_interrupt_subtask(adapter); ixgbe_sfp_detection_subtask(adapter); -- 2.31.1