Skip to content

Commit 19058be

Browse files
rmohamedshahkuba-moo
authored andcommitted
ionic: VF initial random MAC address if no assigned mac
Assign a random mac address to the VF interface station address if it boots with a zero mac address in order to match similar behavior seen in other VF drivers. Handle the errors where the older firmware does not allow the VF to set its own station address. Newer firmware will allow the VF to set the station mac address if it hasn't already been set administratively through the PF. Setting it will also be allowed if the VF has trust. Fixes: fbb3980 ("ionic: support sr-iov operations") Signed-off-by: R Mohamed Shah <[email protected]> Signed-off-by: Shannon Nelson <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 0fc4dd4 commit 19058be

File tree

1 file changed

+87
-5
lines changed

1 file changed

+87
-5
lines changed

drivers/net/ethernet/pensando/ionic/ionic_lif.c

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,8 +1564,67 @@ static int ionic_set_features(struct net_device *netdev,
15641564
return err;
15651565
}
15661566

1567+
static int ionic_set_attr_mac(struct ionic_lif *lif, u8 *mac)
1568+
{
1569+
struct ionic_admin_ctx ctx = {
1570+
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
1571+
.cmd.lif_setattr = {
1572+
.opcode = IONIC_CMD_LIF_SETATTR,
1573+
.index = cpu_to_le16(lif->index),
1574+
.attr = IONIC_LIF_ATTR_MAC,
1575+
},
1576+
};
1577+
1578+
ether_addr_copy(ctx.cmd.lif_setattr.mac, mac);
1579+
return ionic_adminq_post_wait(lif, &ctx);
1580+
}
1581+
1582+
static int ionic_get_attr_mac(struct ionic_lif *lif, u8 *mac_addr)
1583+
{
1584+
struct ionic_admin_ctx ctx = {
1585+
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
1586+
.cmd.lif_getattr = {
1587+
.opcode = IONIC_CMD_LIF_GETATTR,
1588+
.index = cpu_to_le16(lif->index),
1589+
.attr = IONIC_LIF_ATTR_MAC,
1590+
},
1591+
};
1592+
int err;
1593+
1594+
err = ionic_adminq_post_wait(lif, &ctx);
1595+
if (err)
1596+
return err;
1597+
1598+
ether_addr_copy(mac_addr, ctx.comp.lif_getattr.mac);
1599+
return 0;
1600+
}
1601+
1602+
static int ionic_program_mac(struct ionic_lif *lif, u8 *mac)
1603+
{
1604+
u8 get_mac[ETH_ALEN];
1605+
int err;
1606+
1607+
err = ionic_set_attr_mac(lif, mac);
1608+
if (err)
1609+
return err;
1610+
1611+
err = ionic_get_attr_mac(lif, get_mac);
1612+
if (err)
1613+
return err;
1614+
1615+
/* To deal with older firmware that silently ignores the set attr mac:
1616+
* doesn't actually change the mac and doesn't return an error, so we
1617+
* do the get attr to verify whether or not the set actually happened
1618+
*/
1619+
if (!ether_addr_equal(get_mac, mac))
1620+
return 1;
1621+
1622+
return 0;
1623+
}
1624+
15671625
static int ionic_set_mac_address(struct net_device *netdev, void *sa)
15681626
{
1627+
struct ionic_lif *lif = netdev_priv(netdev);
15691628
struct sockaddr *addr = sa;
15701629
u8 *mac;
15711630
int err;
@@ -1574,6 +1633,14 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa)
15741633
if (ether_addr_equal(netdev->dev_addr, mac))
15751634
return 0;
15761635

1636+
err = ionic_program_mac(lif, mac);
1637+
if (err < 0)
1638+
return err;
1639+
1640+
if (err > 0)
1641+
netdev_dbg(netdev, "%s: SET and GET ATTR Mac are not equal-due to old FW running\n",
1642+
__func__);
1643+
15771644
err = eth_prepare_mac_addr_change(netdev, addr);
15781645
if (err)
15791646
return err;
@@ -3172,6 +3239,7 @@ static int ionic_station_set(struct ionic_lif *lif)
31723239
.attr = IONIC_LIF_ATTR_MAC,
31733240
},
31743241
};
3242+
u8 mac_address[ETH_ALEN];
31753243
struct sockaddr addr;
31763244
int err;
31773245

@@ -3180,21 +3248,35 @@ static int ionic_station_set(struct ionic_lif *lif)
31803248
return err;
31813249
netdev_dbg(lif->netdev, "found initial MAC addr %pM\n",
31823250
ctx.comp.lif_getattr.mac);
3183-
if (is_zero_ether_addr(ctx.comp.lif_getattr.mac))
3184-
return 0;
3251+
ether_addr_copy(mac_address, ctx.comp.lif_getattr.mac);
3252+
3253+
if (is_zero_ether_addr(mac_address)) {
3254+
eth_hw_addr_random(netdev);
3255+
netdev_dbg(netdev, "Random Mac generated: %pM\n", netdev->dev_addr);
3256+
ether_addr_copy(mac_address, netdev->dev_addr);
3257+
3258+
err = ionic_program_mac(lif, mac_address);
3259+
if (err < 0)
3260+
return err;
3261+
3262+
if (err > 0) {
3263+
netdev_dbg(netdev, "%s:SET/GET ATTR Mac are not same-due to old FW running\n",
3264+
__func__);
3265+
return 0;
3266+
}
3267+
}
31853268

31863269
if (!is_zero_ether_addr(netdev->dev_addr)) {
31873270
/* If the netdev mac is non-zero and doesn't match the default
31883271
* device address, it was set by something earlier and we're
31893272
* likely here again after a fw-upgrade reset. We need to be
31903273
* sure the netdev mac is in our filter list.
31913274
*/
3192-
if (!ether_addr_equal(ctx.comp.lif_getattr.mac,
3193-
netdev->dev_addr))
3275+
if (!ether_addr_equal(mac_address, netdev->dev_addr))
31943276
ionic_lif_addr_add(lif, netdev->dev_addr);
31953277
} else {
31963278
/* Update the netdev mac with the device's mac */
3197-
memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len);
3279+
ether_addr_copy(addr.sa_data, mac_address);
31983280
addr.sa_family = AF_INET;
31993281
err = eth_prepare_mac_addr_change(netdev, &addr);
32003282
if (err) {

0 commit comments

Comments
 (0)