[dpdk-dev] [PATCH 51/52] common/cnxk: add tim irq support

Nithin Dabilpuram ndabilpuram at marvell.com
Fri Mar 5 14:39:17 CET 2021


From: Pavan Nikhilesh <pbhagavatula at marvell.com>

Add TIM LF IRQ register and un-register functions.

Signed-off-by: Pavan Nikhilesh <pbhagavatula at marvell.com>
---
 drivers/common/cnxk/meson.build    |   1 +
 drivers/common/cnxk/roc_tim.c      |  51 ++++++++++++++++++
 drivers/common/cnxk/roc_tim_irq.c  | 104 +++++++++++++++++++++++++++++++++++++
 drivers/common/cnxk/roc_tim_priv.h |   9 ++++
 4 files changed, 165 insertions(+)
 create mode 100644 drivers/common/cnxk/roc_tim_irq.c

diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build
index 14fbade..83feb10 100644
--- a/drivers/common/cnxk/meson.build
+++ b/drivers/common/cnxk/meson.build
@@ -44,5 +44,6 @@ sources = files('roc_dev.c',
 		'roc_sso_debug.c',
 		'roc_sso_irq.c',
 		'roc_tim.c',
+		'roc_tim_irq.c',
 		'roc_utils.c')
 includes += include_directories('../../bus/pci')
diff --git a/drivers/common/cnxk/roc_tim.c b/drivers/common/cnxk/roc_tim.c
index bd803db..a4ed15e 100644
--- a/drivers/common/cnxk/roc_tim.c
+++ b/drivers/common/cnxk/roc_tim.c
@@ -5,6 +5,25 @@
 #include "roc_api.h"
 #include "roc_priv.h"
 
+static int
+tim_fill_msix(struct roc_tim *roc_tim, uint16_t nb_ring)
+{
+	struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
+	struct tim *tim = roc_tim_to_tim_priv(roc_tim);
+	struct msix_offset_rsp *rsp;
+	int i, rc;
+
+	mbox_alloc_msg_msix_offset(dev->mbox);
+	rc = mbox_process_msg(dev->mbox, (void **)&rsp);
+	if (rc < 0)
+		return rc;
+
+	for (i = 0; i < nb_ring; i++)
+		tim->tim_msix_offsets[i] = rsp->timlf_msixoff[i];
+
+	return 0;
+}
+
 static void
 tim_err_desc(int rc)
 {
@@ -158,6 +177,8 @@ int
 roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk)
 {
 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
+	struct tim *tim = roc_tim_to_tim_priv(roc_tim);
+	struct tim_ring_req *free_req;
 	struct tim_lf_alloc_req *req;
 	struct tim_lf_alloc_rsp *rsp;
 	struct dev *dev = &sso->dev;
@@ -179,6 +200,17 @@ roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk)
 	if (clk)
 		*clk = rsp->tenns_clk;
 
+	rc = tim_register_irq_priv(roc_tim, &sso->pci_dev->intr_handle, ring_id,
+				   tim->tim_msix_offsets[ring_id]);
+	if (rc < 0) {
+		plt_tim_dbg("Failed to register Ring[%d] IRQ", ring_id);
+		free_req = mbox_alloc_msg_tim_lf_free(dev->mbox);
+		if (free_req == NULL)
+			return -ENOSPC;
+		free_req->ring = ring_id;
+		mbox_process(dev->mbox);
+	}
+
 	return rc;
 }
 
@@ -186,10 +218,14 @@ int
 roc_tim_lf_free(struct roc_tim *roc_tim, uint8_t ring_id)
 {
 	struct sso *sso = roc_sso_to_sso_priv(roc_tim->roc_sso);
+	struct tim *tim = roc_tim_to_tim_priv(roc_tim);
 	struct dev *dev = &sso->dev;
 	struct tim_ring_req *req;
 	int rc = -ENOSPC;
 
+	tim_unregister_irq_priv(roc_tim, &sso->pci_dev->intr_handle, ring_id,
+				tim->tim_msix_offsets[ring_id]);
+
 	req = mbox_alloc_msg_tim_lf_free(dev->mbox);
 	if (req == NULL)
 		return rc;
@@ -208,6 +244,7 @@ int
 roc_tim_init(struct roc_tim *roc_tim)
 {
 	struct rsrc_attach_req *attach_req;
+	struct rsrc_detach_req *detach_req;
 	struct free_rsrcs_rsp *free_rsrc;
 	struct dev *dev;
 	uint16_t nb_lfs;
@@ -245,6 +282,20 @@ roc_tim_init(struct roc_tim *roc_tim)
 		return 0;
 	}
 
+	rc = tim_fill_msix(roc_tim, nb_lfs);
+	if (rc < 0) {
+		plt_err("Unable to get TIM MSIX vectors");
+
+		detach_req = mbox_alloc_msg_detach_resources(dev->mbox);
+		if (detach_req == NULL)
+			return -ENOSPC;
+		detach_req->partial = true;
+		detach_req->timlfs = true;
+		mbox_process(dev->mbox);
+
+		return 0;
+	}
+
 	return nb_lfs;
 }
 
diff --git a/drivers/common/cnxk/roc_tim_irq.c b/drivers/common/cnxk/roc_tim_irq.c
new file mode 100644
index 0000000..29758c9
--- /dev/null
+++ b/drivers/common/cnxk/roc_tim_irq.c
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+
+#include "roc_api.h"
+#include "roc_priv.h"
+
+static void
+tim_lf_irq(void *param)
+{
+	uintptr_t base = (uintptr_t)param;
+	uint64_t intr;
+	uint8_t ring;
+
+	ring = (base >> 12) & 0xFF;
+
+	intr = plt_read64(base + TIM_LF_NRSPERR_INT);
+	plt_err("TIM RING %d TIM_LF_NRSPERR_INT=0x%" PRIx64 "", ring, intr);
+	intr = plt_read64(base + TIM_LF_RAS_INT);
+	plt_err("TIM RING %d TIM_LF_RAS_INT=0x%" PRIx64 "", ring, intr);
+
+	/* Clear interrupt */
+	plt_write64(intr, base + TIM_LF_NRSPERR_INT);
+	plt_write64(intr, base + TIM_LF_RAS_INT);
+}
+
+static int
+tim_lf_register_irq(uintptr_t base, struct plt_intr_handle *handle,
+		    uint16_t msix_offset)
+{
+	unsigned int vec;
+	int rc;
+
+	vec = msix_offset + TIM_LF_INT_VEC_NRSPERR_INT;
+
+	/* Clear err interrupt */
+	plt_write64(~0ull, base + TIM_LF_NRSPERR_INT);
+	/* Set used interrupt vectors */
+	rc = dev_irq_register(handle, tim_lf_irq, (void *)base, vec);
+	/* Enable hw interrupt */
+	plt_write64(~0ull, base + TIM_LF_NRSPERR_INT_ENA_W1S);
+
+	vec = msix_offset + TIM_LF_INT_VEC_RAS_INT;
+
+	/* Clear err interrupt */
+	plt_write64(~0ull, base + TIM_LF_RAS_INT);
+	/* Set used interrupt vectors */
+	rc = dev_irq_register(handle, tim_lf_irq, (void *)base, vec);
+	/* Enable hw interrupt */
+	plt_write64(~0ull, base + TIM_LF_RAS_INT_ENA_W1S);
+
+	return rc;
+}
+
+int
+tim_register_irq_priv(struct roc_tim *roc_tim, struct plt_intr_handle *handle,
+		      uint8_t ring_id, uint16_t msix_offset)
+{
+	struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
+	uintptr_t base;
+
+	if (msix_offset == MSIX_VECTOR_INVALID) {
+		plt_err("Invalid MSIX offset for TIM LF %d", ring_id);
+		return TIM_ERR_PARAM;
+	}
+
+	base = dev->bar2 + (RVU_BLOCK_ADDR_TIM << 20 | ring_id << 12);
+	return tim_lf_register_irq(base, handle, msix_offset);
+}
+
+static void
+tim_lf_unregister_irq(uintptr_t base, struct plt_intr_handle *handle,
+		      uint16_t msix_offset)
+{
+	unsigned int vec;
+
+	vec = msix_offset + TIM_LF_INT_VEC_NRSPERR_INT;
+
+	/* Clear err interrupt */
+	plt_write64(~0ull, base + TIM_LF_NRSPERR_INT_ENA_W1C);
+	dev_irq_unregister(handle, tim_lf_irq, (void *)base, vec);
+
+	vec = msix_offset + TIM_LF_INT_VEC_RAS_INT;
+
+	/* Clear err interrupt */
+	plt_write64(~0ull, base + TIM_LF_RAS_INT_ENA_W1C);
+	dev_irq_unregister(handle, tim_lf_irq, (void *)base, vec);
+}
+
+void
+tim_unregister_irq_priv(struct roc_tim *roc_tim, struct plt_intr_handle *handle,
+			uint8_t ring_id, uint16_t msix_offset)
+{
+	struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
+	uintptr_t base;
+
+	if (msix_offset == MSIX_VECTOR_INVALID) {
+		plt_err("Invalid MSIX offset for TIM LF %d", ring_id);
+		return;
+	}
+
+	base = dev->bar2 + (RVU_BLOCK_ADDR_TIM << 20 | ring_id << 12);
+	tim_lf_unregister_irq(base, handle, msix_offset);
+}
diff --git a/drivers/common/cnxk/roc_tim_priv.h b/drivers/common/cnxk/roc_tim_priv.h
index 9eaff22..bfe7f1b 100644
--- a/drivers/common/cnxk/roc_tim_priv.h
+++ b/drivers/common/cnxk/roc_tim_priv.h
@@ -6,6 +6,7 @@
 #define _ROC_TIM_PRIV_H_
 
 struct tim {
+	uint16_t tim_msix_offsets[MAX_RVU_BLKLF_CNT];
 };
 
 enum tim_err_status {
@@ -18,4 +19,12 @@ roc_tim_to_tim_priv(struct roc_tim *roc_tim)
 	return (struct tim *)&roc_tim->reserved[0];
 }
 
+/* TIM IRQ*/
+int tim_register_irq_priv(struct roc_tim *roc_tim,
+			  struct plt_intr_handle *handle, uint8_t ring_id,
+			  uint16_t msix_offset);
+void tim_unregister_irq_priv(struct roc_tim *roc_tim,
+			     struct plt_intr_handle *handle, uint8_t ring_id,
+			     uint16_t msix_offset);
+
 #endif /* _ROC_TIM_PRIV_H_ */
-- 
2.8.4



More information about the dev mailing list