Skip to content

Commit 4993b39

Browse files
iveceradavem330
authored andcommitted
be2net: fix initial MAC setting
Recent commit 3439352 ("be2net: fix MAC addr setting on privileged BE3 VFs") allows privileged BE3 VFs to set its MAC address during initialization. Although the initial MAC for such VFs is already programmed by parent PF the subsequent setting performed by VF is OK, but in certain cases (after fresh boot) this command in VF can fail. The MAC should be initialized only when: 1) no MAC is programmed (always except BE3 VFs during first init) 2) programmed MAC is different from requested (e.g. MAC is set when interface is down). In this case the initial MAC programmed by PF needs to be deleted. The adapter->dev_mac contains MAC address currently programmed in HW so it should be zeroed when the MAC is deleted from HW and should not be filled when MAC is set when interface is down in be_mac_addr_set() as no programming is performed in this case. Example of failure without the fix (immediately after fresh boot): # ip link set eth0 up <- eth0 is BE3 PF be2net 0000:01:00.0 eth0: Link is Up # echo 1 > /sys/class/net/eth0/device/sriov_numvfs <- Create 1 VF ... be2net 0000:01:04.0: Emulex OneConnect(be3): VF port 0 # ip link set eth8 up <- eth8 is created privileged VF be2net 0000:01:04.0: opcode 59-1 failed:status 1-76 RTNETLINK answers: Input/output error # echo 0 > /sys/class/net/eth0/device/sriov_numvfs <- Delete VF iommu: Removing device 0000:01:04.0 from group 33 ... # echo 1 > /sys/class/net/eth0/device/sriov_numvfs <- Create it again iommu: Removing device 0000:01:04.0 from group 33 ... # ip link set eth8 up be2net 0000:01:04.0 eth8: Link is Up Initialization is now OK. v2 - Corrected the comment and condition check suggested by Suresh & Harsha Fixes: 3439352 ("be2net: fix MAC addr setting on privileged BE3 VFs") Cc: Sathya Perla <sathya.perla@broadcom.com> Cc: Ajit Khaparde <ajit.khaparde@broadcom.com> Cc: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com> Cc: Somnath Kotur <somnath.kotur@broadcom.com> Signed-off-by: Ivan Vecera <cera@cera.cz> Acked-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 90427ef commit 4993b39

File tree

1 file changed

+28
-5
lines changed

1 file changed

+28
-5
lines changed

drivers/net/ethernet/emulex/benet/be_main.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,10 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
362362
status = -EPERM;
363363
goto err;
364364
}
365-
done:
365+
366+
/* Remember currently programmed MAC */
366367
ether_addr_copy(adapter->dev_mac, addr->sa_data);
368+
done:
367369
ether_addr_copy(netdev->dev_addr, addr->sa_data);
368370
dev_info(dev, "MAC address changed to %pM\n", addr->sa_data);
369371
return 0;
@@ -3618,8 +3620,10 @@ static void be_disable_if_filters(struct be_adapter *adapter)
36183620
{
36193621
/* Don't delete MAC on BE3 VFs without FILTMGMT privilege */
36203622
if (!BEx_chip(adapter) || !be_virtfn(adapter) ||
3621-
check_privilege(adapter, BE_PRIV_FILTMGMT))
3623+
check_privilege(adapter, BE_PRIV_FILTMGMT)) {
36223624
be_dev_mac_del(adapter, adapter->pmac_id[0]);
3625+
eth_zero_addr(adapter->dev_mac);
3626+
}
36233627

36243628
be_clear_uc_list(adapter);
36253629
be_clear_mc_list(adapter);
@@ -3773,12 +3777,27 @@ static int be_enable_if_filters(struct be_adapter *adapter)
37733777
if (status)
37743778
return status;
37753779

3776-
/* Don't add MAC on BE3 VFs without FILTMGMT privilege */
3777-
if (!BEx_chip(adapter) || !be_virtfn(adapter) ||
3778-
check_privilege(adapter, BE_PRIV_FILTMGMT)) {
3780+
/* Normally this condition usually true as the ->dev_mac is zeroed.
3781+
* But on BE3 VFs the initial MAC is pre-programmed by PF and
3782+
* subsequent be_dev_mac_add() can fail (after fresh boot)
3783+
*/
3784+
if (!ether_addr_equal(adapter->dev_mac, adapter->netdev->dev_addr)) {
3785+
int old_pmac_id = -1;
3786+
3787+
/* Remember old programmed MAC if any - can happen on BE3 VF */
3788+
if (!is_zero_ether_addr(adapter->dev_mac))
3789+
old_pmac_id = adapter->pmac_id[0];
3790+
37793791
status = be_dev_mac_add(adapter, adapter->netdev->dev_addr);
37803792
if (status)
37813793
return status;
3794+
3795+
/* Delete the old programmed MAC as we successfully programmed
3796+
* a new MAC
3797+
*/
3798+
if (old_pmac_id >= 0 && old_pmac_id != adapter->pmac_id[0])
3799+
be_dev_mac_del(adapter, old_pmac_id);
3800+
37823801
ether_addr_copy(adapter->dev_mac, adapter->netdev->dev_addr);
37833802
}
37843803

@@ -4552,6 +4571,10 @@ static int be_mac_setup(struct be_adapter *adapter)
45524571

45534572
memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
45544573
memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
4574+
4575+
/* Initial MAC for BE3 VFs is already programmed by PF */
4576+
if (BEx_chip(adapter) && be_virtfn(adapter))
4577+
memcpy(adapter->dev_mac, mac, ETH_ALEN);
45554578
}
45564579

45574580
return 0;

0 commit comments

Comments
 (0)