Skip to content

Commit 49d3b49

Browse files
emuslndavem330
authored andcommitted
ionic: disable the queues on link down
When the link goes down, we need to disable the queues on the NIC in addition to stopping the netdev stack. This lets the FW know that the driver has stopped queue activity, and then the FW can do internal reconfiguration work, whether actually Link related, or for other internal FW needs. To do this, we pull out the queue enable and disable from ionic_open() and ionic_stop() so they can be used by other routines. To help keep things sane, we swap the queue enables so that the rx queue and its napi are enabled before the tx queue which rides on the rx queues napi. We also drop the ionic_lif_quiesce() as it doesn't do anything more than what the queue disable has already taken care of. Signed-off-by: Shannon Nelson <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d5eddde commit 49d3b49

File tree

1 file changed

+61
-56
lines changed

1 file changed

+61
-56
lines changed

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

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr);
2222
static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr);
2323
static void ionic_link_status_check(struct ionic_lif *lif);
2424

25+
static int ionic_start_queues(struct ionic_lif *lif);
26+
static void ionic_stop_queues(struct ionic_lif *lif);
27+
2528
static void ionic_lif_deferred_work(struct work_struct *work)
2629
{
2730
struct ionic_lif *lif = container_of(work, struct ionic_lif, deferred.work);
@@ -73,6 +76,9 @@ static void ionic_link_status_check(struct ionic_lif *lif)
7376
u16 link_status;
7477
bool link_up;
7578

79+
if (!test_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state))
80+
return;
81+
7682
if (lif->ionic->is_mgmt_nic)
7783
return;
7884

@@ -90,16 +96,16 @@ static void ionic_link_status_check(struct ionic_lif *lif)
9096
netif_carrier_on(netdev);
9197
}
9298

93-
if (test_bit(IONIC_LIF_F_UP, lif->state))
94-
netif_tx_wake_all_queues(lif->netdev);
99+
if (netif_running(lif->netdev))
100+
ionic_start_queues(lif);
95101
} else {
96102
if (netif_carrier_ok(netdev)) {
97103
netdev_info(netdev, "Link down\n");
98104
netif_carrier_off(netdev);
99105
}
100106

101-
if (test_bit(IONIC_LIF_F_UP, lif->state))
102-
netif_tx_stop_all_queues(netdev);
107+
if (netif_running(lif->netdev))
108+
ionic_stop_queues(lif);
103109
}
104110

105111
clear_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state);
@@ -248,21 +254,6 @@ static int ionic_qcq_disable(struct ionic_qcq *qcq)
248254
return ionic_adminq_post_wait(lif, &ctx);
249255
}
250256

251-
static void ionic_lif_quiesce(struct ionic_lif *lif)
252-
{
253-
struct ionic_admin_ctx ctx = {
254-
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
255-
.cmd.lif_setattr = {
256-
.opcode = IONIC_CMD_LIF_SETATTR,
257-
.attr = IONIC_LIF_ATTR_STATE,
258-
.index = lif->index,
259-
.state = IONIC_LIF_DISABLE
260-
},
261-
};
262-
263-
ionic_adminq_post_wait(lif, &ctx);
264-
}
265-
266257
static void ionic_lif_qcq_deinit(struct ionic_lif *lif, struct ionic_qcq *qcq)
267258
{
268259
struct ionic_dev *idev = &lif->ionic->idev;
@@ -615,6 +606,10 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
615606
dev_dbg(dev, "txq_init.ring_base 0x%llx\n", ctx.cmd.q_init.ring_base);
616607
dev_dbg(dev, "txq_init.ring_size %d\n", ctx.cmd.q_init.ring_size);
617608

609+
q->tail = q->info;
610+
q->head = q->tail;
611+
cq->tail = cq->info;
612+
618613
err = ionic_adminq_post_wait(lif, &ctx);
619614
if (err)
620615
return err;
@@ -660,6 +655,10 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
660655
dev_dbg(dev, "rxq_init.ring_base 0x%llx\n", ctx.cmd.q_init.ring_base);
661656
dev_dbg(dev, "rxq_init.ring_size %d\n", ctx.cmd.q_init.ring_size);
662657

658+
q->tail = q->info;
659+
q->head = q->tail;
660+
cq->tail = cq->info;
661+
663662
err = ionic_adminq_post_wait(lif, &ctx);
664663
if (err)
665664
return err;
@@ -1473,6 +1472,7 @@ static void ionic_txrx_deinit(struct ionic_lif *lif)
14731472
ionic_rx_empty(&lif->rxqcqs[i].qcq->q);
14741473
}
14751474
}
1475+
lif->rx_mode = 0;
14761476
}
14771477

14781478
static void ionic_txrx_free(struct ionic_lif *lif)
@@ -1582,15 +1582,15 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
15821582
int i, err;
15831583

15841584
for (i = 0; i < lif->nxqs; i++) {
1585-
err = ionic_qcq_enable(lif->txqcqs[i].qcq);
1585+
ionic_rx_fill(&lif->rxqcqs[i].qcq->q);
1586+
err = ionic_qcq_enable(lif->rxqcqs[i].qcq);
15861587
if (err)
15871588
goto err_out;
15881589

1589-
ionic_rx_fill(&lif->rxqcqs[i].qcq->q);
1590-
err = ionic_qcq_enable(lif->rxqcqs[i].qcq);
1590+
err = ionic_qcq_enable(lif->txqcqs[i].qcq);
15911591
if (err) {
15921592
if (err != -ETIMEDOUT)
1593-
ionic_qcq_disable(lif->txqcqs[i].qcq);
1593+
ionic_qcq_disable(lif->rxqcqs[i].qcq);
15941594
goto err_out;
15951595
}
15961596
}
@@ -1599,17 +1599,34 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
15991599

16001600
err_out:
16011601
while (i--) {
1602-
err = ionic_qcq_disable(lif->rxqcqs[i].qcq);
1602+
err = ionic_qcq_disable(lif->txqcqs[i].qcq);
16031603
if (err == -ETIMEDOUT)
16041604
break;
1605-
err = ionic_qcq_disable(lif->txqcqs[i].qcq);
1605+
err = ionic_qcq_disable(lif->rxqcqs[i].qcq);
16061606
if (err == -ETIMEDOUT)
16071607
break;
16081608
}
16091609

16101610
return err;
16111611
}
16121612

1613+
static int ionic_start_queues(struct ionic_lif *lif)
1614+
{
1615+
int err;
1616+
1617+
if (test_and_set_bit(IONIC_LIF_F_UP, lif->state))
1618+
return 0;
1619+
1620+
err = ionic_txrx_enable(lif);
1621+
if (err) {
1622+
clear_bit(IONIC_LIF_F_UP, lif->state);
1623+
return err;
1624+
}
1625+
netif_tx_wake_all_queues(lif->netdev);
1626+
1627+
return 0;
1628+
}
1629+
16131630
int ionic_open(struct net_device *netdev)
16141631
{
16151632
struct ionic_lif *lif = netdev_priv(netdev);
@@ -1621,54 +1638,42 @@ int ionic_open(struct net_device *netdev)
16211638

16221639
err = ionic_txrx_init(lif);
16231640
if (err)
1624-
goto err_txrx_free;
1625-
1626-
err = ionic_txrx_enable(lif);
1627-
if (err)
1628-
goto err_txrx_deinit;
1629-
1630-
netif_set_real_num_tx_queues(netdev, lif->nxqs);
1631-
netif_set_real_num_rx_queues(netdev, lif->nxqs);
1632-
1633-
set_bit(IONIC_LIF_F_UP, lif->state);
1641+
goto err_out;
16341642

1635-
ionic_link_status_check_request(lif);
1636-
if (netif_carrier_ok(netdev))
1637-
netif_tx_wake_all_queues(netdev);
1643+
/* don't start the queues until we have link */
1644+
if (netif_carrier_ok(netdev)) {
1645+
err = ionic_start_queues(lif);
1646+
if (err)
1647+
goto err_txrx_deinit;
1648+
}
16381649

16391650
return 0;
16401651

16411652
err_txrx_deinit:
16421653
ionic_txrx_deinit(lif);
1643-
err_txrx_free:
1654+
err_out:
16441655
ionic_txrx_free(lif);
16451656
return err;
16461657
}
16471658

1648-
int ionic_stop(struct net_device *netdev)
1659+
static void ionic_stop_queues(struct ionic_lif *lif)
16491660
{
1650-
struct ionic_lif *lif = netdev_priv(netdev);
1651-
int err = 0;
1661+
if (!test_and_clear_bit(IONIC_LIF_F_UP, lif->state))
1662+
return;
16521663

1653-
if (!test_bit(IONIC_LIF_F_UP, lif->state)) {
1654-
dev_dbg(lif->ionic->dev, "%s: %s state=DOWN\n",
1655-
__func__, lif->name);
1656-
return 0;
1657-
}
1658-
dev_dbg(lif->ionic->dev, "%s: %s state=UP\n", __func__, lif->name);
1659-
clear_bit(IONIC_LIF_F_UP, lif->state);
1664+
ionic_txrx_disable(lif);
1665+
netif_tx_disable(lif->netdev);
1666+
}
16601667

1661-
/* carrier off before disabling queues to avoid watchdog timeout */
1662-
netif_carrier_off(netdev);
1663-
netif_tx_stop_all_queues(netdev);
1664-
netif_tx_disable(netdev);
1668+
int ionic_stop(struct net_device *netdev)
1669+
{
1670+
struct ionic_lif *lif = netdev_priv(netdev);
16651671

1666-
ionic_txrx_disable(lif);
1667-
ionic_lif_quiesce(lif);
1672+
ionic_stop_queues(lif);
16681673
ionic_txrx_deinit(lif);
16691674
ionic_txrx_free(lif);
16701675

1671-
return err;
1676+
return 0;
16721677
}
16731678

16741679
static int ionic_get_vf_config(struct net_device *netdev,

0 commit comments

Comments
 (0)