Commit f053e1f8 authored by Shannon Nelson's avatar Shannon Nelson Committed by David S. Miller

ionic: change mtu without full queue rebuild

We really don't need to tear down and rebuild the whole queue structure
when changing the MTU; we can simply stop the queues, clean and refill,
then restart the queues.
Signed-off-by: default avatarShannon Nelson <snelson@pensando.io>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f1d2e894
...@@ -36,6 +36,8 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif); ...@@ -36,6 +36,8 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif);
static void ionic_lif_handle_fw_up(struct ionic_lif *lif); static void ionic_lif_handle_fw_up(struct ionic_lif *lif);
static void ionic_lif_set_netdev_info(struct ionic_lif *lif); static void ionic_lif_set_netdev_info(struct ionic_lif *lif);
static void ionic_txrx_deinit(struct ionic_lif *lif);
static int ionic_txrx_init(struct ionic_lif *lif);
static int ionic_start_queues(struct ionic_lif *lif); static int ionic_start_queues(struct ionic_lif *lif);
static void ionic_stop_queues(struct ionic_lif *lif); static void ionic_stop_queues(struct ionic_lif *lif);
static void ionic_lif_queue_identify(struct ionic_lif *lif); static void ionic_lif_queue_identify(struct ionic_lif *lif);
...@@ -593,6 +595,17 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif) ...@@ -593,6 +595,17 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif)
return err; return err;
} }
static void ionic_qcq_sanitize(struct ionic_qcq *qcq)
{
qcq->q.tail_idx = 0;
qcq->q.head_idx = 0;
qcq->cq.tail_idx = 0;
qcq->cq.done_color = 1;
memset(qcq->q_base, 0, qcq->q_size);
memset(qcq->cq_base, 0, qcq->cq_size);
memset(qcq->sg_base, 0, qcq->sg_size);
}
static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq) static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
{ {
struct device *dev = lif->ionic->dev; struct device *dev = lif->ionic->dev;
...@@ -632,9 +645,7 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq) ...@@ -632,9 +645,7 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
dev_dbg(dev, "txq_init.ver %d\n", ctx.cmd.q_init.ver); dev_dbg(dev, "txq_init.ver %d\n", ctx.cmd.q_init.ver);
dev_dbg(dev, "txq_init.intr_index %d\n", ctx.cmd.q_init.intr_index); dev_dbg(dev, "txq_init.intr_index %d\n", ctx.cmd.q_init.intr_index);
q->tail_idx = 0; ionic_qcq_sanitize(qcq);
q->head_idx = 0;
cq->tail_idx = 0;
err = ionic_adminq_post_wait(lif, &ctx); err = ionic_adminq_post_wait(lif, &ctx);
if (err) if (err)
...@@ -689,9 +700,7 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq) ...@@ -689,9 +700,7 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
dev_dbg(dev, "rxq_init.ver %d\n", ctx.cmd.q_init.ver); dev_dbg(dev, "rxq_init.ver %d\n", ctx.cmd.q_init.ver);
dev_dbg(dev, "rxq_init.intr_index %d\n", ctx.cmd.q_init.intr_index); dev_dbg(dev, "rxq_init.intr_index %d\n", ctx.cmd.q_init.intr_index);
q->tail_idx = 0; ionic_qcq_sanitize(qcq);
q->head_idx = 0;
cq->tail_idx = 0;
err = ionic_adminq_post_wait(lif, &ctx); err = ionic_adminq_post_wait(lif, &ctx);
if (err) if (err)
...@@ -1307,6 +1316,35 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa) ...@@ -1307,6 +1316,35 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa)
return ionic_addr_add(netdev, mac); return ionic_addr_add(netdev, mac);
} }
static void ionic_stop_queues_reconfig(struct ionic_lif *lif)
{
/* Stop and clean the queues before reconfiguration */
mutex_lock(&lif->queue_lock);
netif_device_detach(lif->netdev);
ionic_stop_queues(lif);
ionic_txrx_deinit(lif);
}
static int ionic_start_queues_reconfig(struct ionic_lif *lif)
{
int err;
/* Re-init the queues after reconfiguration */
/* The only way txrx_init can fail here is if communication
* with FW is suddenly broken. There's not much we can do
* at this point - error messages have already been printed,
* so we can continue on and the user can eventually do a
* DOWN and UP to try to reset and clear the issue.
*/
err = ionic_txrx_init(lif);
mutex_unlock(&lif->queue_lock);
ionic_link_status_check_request(lif);
netif_device_attach(lif->netdev);
return err;
}
static int ionic_change_mtu(struct net_device *netdev, int new_mtu) static int ionic_change_mtu(struct net_device *netdev, int new_mtu)
{ {
struct ionic_lif *lif = netdev_priv(netdev); struct ionic_lif *lif = netdev_priv(netdev);
...@@ -1326,9 +1364,12 @@ static int ionic_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -1326,9 +1364,12 @@ static int ionic_change_mtu(struct net_device *netdev, int new_mtu)
return err; return err;
netdev->mtu = new_mtu; netdev->mtu = new_mtu;
err = ionic_reset_queues(lif, NULL, NULL); /* if we're not running, nothing more to do */
if (!netif_running(netdev))
return 0;
return err; ionic_stop_queues_reconfig(lif);
return ionic_start_queues_reconfig(lif);
} }
static void ionic_tx_timeout_work(struct work_struct *ws) static void ionic_tx_timeout_work(struct work_struct *ws)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment