ionic: clean interrupt before enabling queue to avoid credit race
authorNeel Patel <neel.patel@amd.com>
Thu, 2 Feb 2023 21:55:35 +0000 (13:55 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Feb 2023 18:11:44 +0000 (19:11 +0100)
[ Upstream commit e8797a058466b60fc5a3291b92430c93ba90eaff ]

Clear the interrupt credits before enabling the queue rather
than after to be sure that the enabled queue starts at 0 and
that we don't wipe away possible credits after enabling the
queue.

Fixes: 0f3154e6bcb3 ("ionic: Add Tx and Rx handling")
Signed-off-by: Neel Patel <neel.patel@amd.com>
Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/pensando/ionic/ionic_lif.c

index 19d4848..147e234 100644 (file)
@@ -269,6 +269,7 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq)
                        .oper = IONIC_Q_ENABLE,
                },
        };
+       int ret;
 
        idev = &lif->ionic->idev;
        dev = lif->ionic->dev;
@@ -276,16 +277,24 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq)
        dev_dbg(dev, "q_enable.index %d q_enable.qtype %d\n",
                ctx.cmd.q_control.index, ctx.cmd.q_control.type);
 
+       if (qcq->flags & IONIC_QCQ_F_INTR)
+               ionic_intr_clean(idev->intr_ctrl, qcq->intr.index);
+
+       ret = ionic_adminq_post_wait(lif, &ctx);
+       if (ret)
+               return ret;
+
+       if (qcq->napi.poll)
+               napi_enable(&qcq->napi);
+
        if (qcq->flags & IONIC_QCQ_F_INTR) {
                irq_set_affinity_hint(qcq->intr.vector,
                                      &qcq->intr.affinity_mask);
-               napi_enable(&qcq->napi);
-               ionic_intr_clean(idev->intr_ctrl, qcq->intr.index);
                ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
                                IONIC_INTR_MASK_CLEAR);
        }
 
-       return ionic_adminq_post_wait(lif, &ctx);
+       return 0;
 }
 
 static int ionic_qcq_disable(struct ionic_lif *lif, struct ionic_qcq *qcq, int fw_err)