[PATCH 03/14] common/cnxk: fix NIX QINT count reset

Rahul Bhansali rbhansali at marvell.com
Thu Sep 17 09:10:05 CEST 2026


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: stable at dpdk.org

Signed-off-by: Rahul Bhansali <rbhansali at marvell.com>
---
 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



More information about the stable mailing list