Fix QINT count reset on NIX queue IRQs register and
unregister.
Queue interrupt will be cleared by individual queue
interrupt operation register update.

Fixes: f6d567b03d28 ("common/cnxk: support NIX IRQ")
Fixes: 3c100e0e6b9c ("common/cnxk: support per-port RQ in inline device")
Cc: [email protected]

Signed-off-by: Rahul Bhansali <[email protected]>
---
 drivers/common/cnxk/roc_nix_inl_dev_irq.c | 21 ++++++++++++---------
 drivers/common/cnxk/roc_nix_irq.c         | 12 ++++++------
 2 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/common/cnxk/roc_nix_inl_dev_irq.c 
b/drivers/common/cnxk/roc_nix_inl_dev_irq.c
index 30986e780a..afbf966f78 100644
--- a/drivers/common/cnxk/roc_nix_inl_dev_irq.c
+++ b/drivers/common/cnxk/roc_nix_inl_dev_irq.c
@@ -396,6 +396,7 @@ nix_inl_nix_register_irqs(struct nix_inl_dev *inl_dev)
        struct nix_inl_qint *qints_mem;
        int rc, q, ret = 0;
        uint16_t msixoff;
+       uint64_t cnt;
        int qints;
 
        msixoff = inl_dev->nix_msixoff;
@@ -434,8 +435,10 @@ nix_inl_nix_register_irqs(struct nix_inl_dev *inl_dev)
 
        for (q = 0; q < qints; q++) {
                /* Clear QINT CNT, interrupt */
-               plt_write64(0, nix_base + NIX_LF_QINTX_CNT(q));
                plt_write64(~0ull, nix_base + NIX_LF_QINTX_ENA_W1C(q));
+               cnt = plt_read64(nix_base + NIX_LF_QINTX_CNT(q));
+               plt_write64((uint64_t)(-(int64_t)cnt), nix_base + 
NIX_LF_QINTX_CNT(q));
+               plt_write64(~0ull, nix_base + NIX_LF_QINTX_INT(q));
 
                /* Register queue irq vector */
                ret = dev_irq_register(handle, nix_inl_nix_q_irq, &qints_mem[q],
@@ -443,9 +446,7 @@ nix_inl_nix_register_irqs(struct nix_inl_dev *inl_dev)
                if (ret)
                        break;
 
-               plt_write64(0, nix_base + NIX_LF_QINTX_CNT(q));
-               plt_write64(0, nix_base + NIX_LF_QINTX_INT(q));
-               /* Enable QINT interrupt */
+               /* Enable QINT interrupt (count/INT already drained above) */
                plt_write64(~0ull, nix_base + NIX_LF_QINTX_ENA_W1S(q));
 
                qints_mem[q].inl_dev = inl_dev;
@@ -463,6 +464,7 @@ nix_inl_nix_unregister_irqs(struct nix_inl_dev *inl_dev)
        struct nix_inl_qint *qints_mem = inl_dev->qints_mem;
        uintptr_t nix_base = inl_dev->nix_base;
        uint16_t msixoff;
+       uint64_t cnt;
        int q;
 
        msixoff = inl_dev->nix_msixoff;
@@ -477,17 +479,18 @@ nix_inl_nix_unregister_irqs(struct nix_inl_dev *inl_dev)
                           msixoff + NIX_LF_INT_VEC_POISON);
 
        for (q = 0; q < inl_dev->configured_qints; q++) {
-               /* Clear QINT CNT */
-               plt_write64(0, nix_base + NIX_LF_QINTX_CNT(q));
-               plt_write64(0, nix_base + NIX_LF_QINTX_INT(q));
-
-               /* Disable QINT interrupt */
+               /* Clear QINT CNT, interrupt */
                plt_write64(~0ull, nix_base + NIX_LF_QINTX_ENA_W1C(q));
 
+               cnt = plt_read64(nix_base + NIX_LF_QINTX_CNT(q));
+               plt_write64((uint64_t)(-(int64_t)cnt), nix_base + 
NIX_LF_QINTX_CNT(q));
+               plt_write64(~0ull, nix_base + NIX_LF_QINTX_INT(q));
+
                /* Unregister queue irq vector */
                dev_irq_unregister(handle, nix_inl_nix_q_irq, &qints_mem[q],
                                   msixoff + NIX_LF_INT_VEC_QINT_START + q);
        }
+       inl_dev->configured_qints = 0;
 
        plt_free(inl_dev->qints_mem);
        inl_dev->qints_mem = NULL;
diff --git a/drivers/common/cnxk/roc_nix_irq.c 
b/drivers/common/cnxk/roc_nix_irq.c
index 6874435a4e..50a1943411 100644
--- a/drivers/common/cnxk/roc_nix_irq.c
+++ b/drivers/common/cnxk/roc_nix_irq.c
@@ -324,9 +324,6 @@ nix_lf_q_irq(void *param)
                        plt_err("SQ=%d NIX_SQINT_SQB_ALLOC_FAIL", sq);
        }
 
-       /* Clear interrupt */
-       plt_write64(intr, nix->base + NIX_LF_QINTX_INT(qintx));
-
        /* Call reset callback */
        if (intr_cb && dev->ops->q_err_cb)
                dev->ops->q_err_cb(nix_priv_to_roc_nix(nix), NULL);
@@ -338,6 +335,7 @@ roc_nix_register_queue_irqs(struct roc_nix *roc_nix)
        int vec, q, sqs, rqs, qs, rc = 0;
        struct plt_intr_handle *handle;
        struct nix *nix;
+       int64_t val;
 
        nix = roc_nix_to_nix_priv(roc_nix);
        handle = nix->pci_dev->intr_handle;
@@ -358,7 +356,8 @@ roc_nix_register_queue_irqs(struct roc_nix *roc_nix)
                vec = nix->msixoff + NIX_LF_INT_VEC_QINT_START + q;
 
                /* Clear QINT CNT */
-               plt_write64(0, nix->base + NIX_LF_QINTX_CNT(q));
+               val = plt_read64(nix->base + NIX_LF_QINTX_CNT(q));
+               plt_write64(-val, nix->base + NIX_LF_QINTX_CNT(q));
 
                /* Clear interrupt */
                plt_write64(~0ull, nix->base + NIX_LF_QINTX_ENA_W1C(q));
@@ -375,7 +374,6 @@ roc_nix_register_queue_irqs(struct roc_nix *roc_nix)
                if (rc)
                        break;
 
-               plt_write64(0, nix->base + NIX_LF_QINTX_CNT(q));
                plt_write64(0, nix->base + NIX_LF_QINTX_INT(q));
                /* Enable QINT interrupt */
                plt_write64(~0ull, nix->base + NIX_LF_QINTX_ENA_W1S(q));
@@ -389,6 +387,7 @@ roc_nix_unregister_queue_irqs(struct roc_nix *roc_nix)
 {
        struct plt_intr_handle *handle;
        struct nix *nix;
+       int64_t val;
        int vec, q;
 
        nix = roc_nix_to_nix_priv(roc_nix);
@@ -398,7 +397,8 @@ roc_nix_unregister_queue_irqs(struct roc_nix *roc_nix)
                vec = nix->msixoff + NIX_LF_INT_VEC_QINT_START + q;
 
                /* Clear QINT CNT */
-               plt_write64(0, nix->base + NIX_LF_QINTX_CNT(q));
+               val = plt_read64(nix->base + NIX_LF_QINTX_CNT(q));
+               plt_write64(-val, nix->base + NIX_LF_QINTX_CNT(q));
                plt_write64(0, nix->base + NIX_LF_QINTX_INT(q));
 
                /* Clear interrupt */
-- 
2.34.1

Reply via email to