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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
26922c0ef3
|
@ -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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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,6 +1561,7 @@ 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) {
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue