Skip to content

Commit 92df825

Browse files
committed
Merge branch 'ionic-bug-fixes'
Shannon Nelson says: ==================== ionic: bug fixes These are a couple of maintenance bug fixes for the Pensando ionic networking driver. Mohamed takes care of a "plays well with others" issue where the VF spec is a bit vague on VF mac addresses, but certain customers have come to expect behavior based on other vendor drivers. Shannon addresses a couple of corner cases seen in internal stress testing. ==================== Link: https://lore.kernel.org/r/20220824165051.6185-1-snelson@pensando.io Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents b0f571e + 19058be commit 92df825

File tree

2 files changed

+93
-6
lines changed

2 files changed

+93
-6
lines changed

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

Lines changed: 90 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;
@@ -2963,6 +3030,9 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
29633030

29643031
mutex_lock(&lif->queue_lock);
29653032

3033+
if (test_and_clear_bit(IONIC_LIF_F_BROKEN, lif->state))
3034+
dev_info(ionic->dev, "FW Up: clearing broken state\n");
3035+
29663036
err = ionic_qcqs_alloc(lif);
29673037
if (err)
29683038
goto err_unlock;
@@ -3169,6 +3239,7 @@ static int ionic_station_set(struct ionic_lif *lif)
31693239
.attr = IONIC_LIF_ATTR_MAC,
31703240
},
31713241
};
3242+
u8 mac_address[ETH_ALEN];
31723243
struct sockaddr addr;
31733244
int err;
31743245

@@ -3177,21 +3248,35 @@ static int ionic_station_set(struct ionic_lif *lif)
31773248
return err;
31783249
netdev_dbg(lif->netdev, "found initial MAC addr %pM\n",
31793250
ctx.comp.lif_getattr.mac);
3180-
if (is_zero_ether_addr(ctx.comp.lif_getattr.mac))
3181-
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+
}
31823268

31833269
if (!is_zero_ether_addr(netdev->dev_addr)) {
31843270
/* If the netdev mac is non-zero and doesn't match the default
31853271
* device address, it was set by something earlier and we're
31863272
* likely here again after a fw-upgrade reset. We need to be
31873273
* sure the netdev mac is in our filter list.
31883274
*/
3189-
if (!ether_addr_equal(ctx.comp.lif_getattr.mac,
3190-
netdev->dev_addr))
3275+
if (!ether_addr_equal(mac_address, netdev->dev_addr))
31913276
ionic_lif_addr_add(lif, netdev->dev_addr);
31923277
} else {
31933278
/* Update the netdev mac with the device's mac */
3194-
memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len);
3279+
ether_addr_copy(addr.sa_data, mac_address);
31953280
addr.sa_family = AF_INET;
31963281
err = eth_prepare_mac_addr_change(netdev, &addr);
31973282
if (err) {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,8 @@ static int __ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds,
474474
ionic_opcode_to_str(opcode), opcode,
475475
ionic_error_to_str(err), err);
476476

477-
msleep(1000);
478477
iowrite32(0, &idev->dev_cmd_regs->done);
478+
msleep(1000);
479479
iowrite32(1, &idev->dev_cmd_regs->doorbell);
480480
goto try_again;
481481
}
@@ -488,6 +488,8 @@ static int __ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds,
488488
return ionic_error_to_errno(err);
489489
}
490490

491+
ionic_dev_cmd_clean(ionic);
492+
491493
return 0;
492494
}
493495

0 commit comments

Comments
 (0)