[dpdk-dev] [PATCH v3 51/52] common/cnxk: add tim irq support
Nithin Dabilpuram
ndabilpuram at marvell.com
Thu Apr 1 14:38:16 CEST 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 1b02178..4573d13 100644
--- a/drivers/common/cnxk/meson.build
+++ b/drivers/common/cnxk/meson.build
@@ -43,5 +43,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 37faa37..387164b 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..7bd3e76
--- /dev/null
+++ b/drivers/common/cnxk/roc_tim_irq.c
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 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 08697f6..cc083d2 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