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: Suresh Reddy <Suresh.Reddy@broadcom.com> Signed-off-by: Sathya Perla <sathya.perla@broadcom.com> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
988d44b163
commit
c27ebf5851
@ -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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user