Commit c27ebf58 authored by Suresh Reddy's avatar Suresh Reddy Committed by David S. Miller

be2net: Fix mac address collision in some configurations

If the device mac address is updated using ndo_set_mac_address(),
while the same mac address is already programmed, the driver does not
detect this condition if its netdev->dev_addr has been changed. The
driver tries to add the same mac address resulting in mac address
collision error. This has been observed in bonding mode-5 configuration.

To fix this, store the mac address configured in HW in the adapter
structure. Use this to compare against the new address being updated
to avoid collision.
Signed-off-by: default avatarSuresh Reddy <Suresh.Reddy@broadcom.com>
Signed-off-by: default avatarSathya Perla <sathya.perla@broadcom.com>
Signed-off-by: default avatarSriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 988d44b1
...@@ -693,6 +693,7 @@ struct be_adapter { ...@@ -693,6 +693,7 @@ struct be_adapter {
u32 fat_dump_len; u32 fat_dump_len;
u16 serial_num[CNTL_SERIAL_NUM_WORDS]; u16 serial_num[CNTL_SERIAL_NUM_WORDS];
u8 phy_state; /* state of sfp optics (functional, faulted, etc.,) */ u8 phy_state; /* state of sfp optics (functional, faulted, etc.,) */
u8 dev_mac[ETH_ALEN];
u32 priv_flags; /* ethtool get/set_priv_flags() */ u32 priv_flags; /* ethtool get/set_priv_flags() */
struct be_error_recovery error_recovery; struct be_error_recovery error_recovery;
}; };
......
...@@ -316,7 +316,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) ...@@ -316,7 +316,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
/* Proceed further only if, User provided MAC is different /* Proceed further only if, User provided MAC is different
* from active MAC * from active MAC
*/ */
if (ether_addr_equal(addr->sa_data, netdev->dev_addr)) if (ether_addr_equal(addr->sa_data, adapter->dev_mac))
return 0; return 0;
/* if device is not running, copy MAC to netdev->dev_addr */ /* if device is not running, copy MAC to netdev->dev_addr */
...@@ -357,6 +357,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) ...@@ -357,6 +357,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
goto err; goto err;
} }
done: done:
ether_addr_copy(adapter->dev_mac, addr->sa_data);
ether_addr_copy(netdev->dev_addr, addr->sa_data); ether_addr_copy(netdev->dev_addr, addr->sa_data);
dev_info(dev, "MAC address changed to %pM\n", addr->sa_data); dev_info(dev, "MAC address changed to %pM\n", addr->sa_data);
return 0; return 0;
...@@ -1662,7 +1663,7 @@ static void be_clear_mc_list(struct be_adapter *adapter) ...@@ -1662,7 +1663,7 @@ static void be_clear_mc_list(struct be_adapter *adapter)
static int be_uc_mac_add(struct be_adapter *adapter, int uc_idx) static int be_uc_mac_add(struct be_adapter *adapter, int uc_idx)
{ {
if (ether_addr_equal((u8 *)&adapter->uc_list[uc_idx * ETH_ALEN], if (ether_addr_equal((u8 *)&adapter->uc_list[uc_idx * ETH_ALEN],
adapter->netdev->dev_addr)) { adapter->dev_mac)) {
adapter->pmac_id[uc_idx + 1] = adapter->pmac_id[0]; adapter->pmac_id[uc_idx + 1] = adapter->pmac_id[0];
return 0; return 0;
} }
...@@ -3774,6 +3775,7 @@ static int be_enable_if_filters(struct be_adapter *adapter) ...@@ -3774,6 +3775,7 @@ static int be_enable_if_filters(struct be_adapter *adapter)
status = be_dev_mac_add(adapter, adapter->netdev->dev_addr); status = be_dev_mac_add(adapter, adapter->netdev->dev_addr);
if (status) if (status)
return status; return status;
ether_addr_copy(adapter->dev_mac, adapter->netdev->dev_addr);
} }
if (adapter->vlans_added) if (adapter->vlans_added)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment