Commit 26922c0e authored by David S. Miller's avatar David S. Miller

Merge branch 'ionic-error-recovery-fixes'

Shannon Nelson says:

====================
ionic error recovery fixes

These are a few little patches to make error recovery a little
more safe and successful.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6fcd4224 a4674f34
......@@ -228,7 +228,13 @@ DEFINE_SHOW_ATTRIBUTE(netdev);
void ionic_debugfs_add_lif(struct ionic_lif *lif)
{
lif->dentry = debugfs_create_dir(lif->name, lif->ionic->dentry);
struct dentry *lif_dentry;
lif_dentry = debugfs_create_dir(lif->name, lif->ionic->dentry);
if (IS_ERR_OR_NULL(lif_dentry))
return;
lif->dentry = lif_dentry;
debugfs_create_file("netdev", 0400, lif->dentry,
lif->netdev, &netdev_fops);
}
......
......@@ -275,8 +275,10 @@ static void ionic_lif_qcq_deinit(struct ionic_lif *lif, struct ionic_qcq *qcq)
if (qcq->flags & IONIC_QCQ_F_INTR) {
ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
IONIC_INTR_MASK_SET);
irq_set_affinity_hint(qcq->intr.vector, NULL);
devm_free_irq(dev, qcq->intr.vector, &qcq->napi);
netif_napi_del(&qcq->napi);
qcq->intr.vector = 0;
}
qcq->flags &= ~IONIC_QCQ_F_INITED;
......@@ -318,19 +320,21 @@ static void ionic_qcqs_free(struct ionic_lif *lif)
lif->adminqcq = NULL;
}
for (i = 0; i < lif->nxqs; i++)
if (lif->rxqcqs[i].stats)
devm_kfree(dev, lif->rxqcqs[i].stats);
devm_kfree(dev, lif->rxqcqs);
lif->rxqcqs = NULL;
for (i = 0; i < lif->nxqs; i++)
if (lif->txqcqs[i].stats)
devm_kfree(dev, lif->txqcqs[i].stats);
if (lif->rxqcqs) {
for (i = 0; i < lif->nxqs; i++)
if (lif->rxqcqs[i].stats)
devm_kfree(dev, lif->rxqcqs[i].stats);
devm_kfree(dev, lif->rxqcqs);
lif->rxqcqs = NULL;
}
devm_kfree(dev, lif->txqcqs);
lif->txqcqs = NULL;
if (lif->txqcqs) {
for (i = 0; i < lif->nxqs; i++)
if (lif->txqcqs[i].stats)
devm_kfree(dev, lif->txqcqs[i].stats);
devm_kfree(dev, lif->txqcqs);
lif->txqcqs = NULL;
}
}
static void ionic_link_qcq_interrupts(struct ionic_qcq *src_qcq,
......@@ -832,7 +836,7 @@ static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr)
memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN);
err = ionic_adminq_post_wait(lif, &ctx);
if (err)
if (err && err != -EEXIST)
return err;
return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx);
......@@ -862,7 +866,7 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
spin_unlock_bh(&lif->rx_filters.lock);
err = ionic_adminq_post_wait(lif, &ctx);
if (err)
if (err && err != -EEXIST)
return err;
netdev_dbg(lif->netdev, "rx_filter del ADDR %pM (id %d)\n", addr,
......@@ -1425,10 +1429,15 @@ static void ionic_lif_rss_deinit(struct ionic_lif *lif)
static void ionic_txrx_disable(struct ionic_lif *lif)
{
unsigned int i;
int err;
for (i = 0; i < lif->nxqs; i++) {
ionic_qcq_disable(lif->txqcqs[i].qcq);
ionic_qcq_disable(lif->rxqcqs[i].qcq);
err = ionic_qcq_disable(lif->txqcqs[i].qcq);
if (err == -ETIMEDOUT)
break;
err = ionic_qcq_disable(lif->rxqcqs[i].qcq);
if (err == -ETIMEDOUT)
break;
}
}
......@@ -1552,7 +1561,8 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
ionic_rx_fill(&lif->rxqcqs[i].qcq->q);
err = ionic_qcq_enable(lif->rxqcqs[i].qcq);
if (err) {
ionic_qcq_disable(lif->txqcqs[i].qcq);
if (err != -ETIMEDOUT)
ionic_qcq_disable(lif->txqcqs[i].qcq);
goto err_out;
}
}
......@@ -1561,8 +1571,12 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
err_out:
while (i--) {
ionic_qcq_disable(lif->rxqcqs[i].qcq);
ionic_qcq_disable(lif->txqcqs[i].qcq);
err = ionic_qcq_disable(lif->rxqcqs[i].qcq);
if (err == -ETIMEDOUT)
break;
err = ionic_qcq_disable(lif->txqcqs[i].qcq);
if (err == -ETIMEDOUT)
break;
}
return err;
......
......@@ -243,11 +243,16 @@ static void ionic_adminq_cb(struct ionic_queue *q,
static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
{
struct ionic_queue *adminq = &lif->adminqcq->q;
struct ionic_queue *adminq;
int err = 0;
WARN_ON(in_interrupt());
if (!lif->adminqcq)
return -EIO;
adminq = &lif->adminqcq->q;
spin_lock(&lif->adminq_lock);
if (!ionic_q_has_space(adminq, 1)) {
err = -ENOSPC;
......@@ -360,7 +365,10 @@ int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds)
done, duration / HZ, duration);
if (!done && hb) {
ionic_dev_cmd_clean(ionic);
/* It is possible (but unlikely) that FW was busy and missed a
* heartbeat check but is still alive and will process this
* request, so don't clean the dev_cmd in this case.
*/
dev_warn(ionic->dev, "DEVCMD %s (%d) failed - FW halted\n",
ionic_opcode_to_str(opcode), opcode);
return -ENXIO;
......
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