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