raw/cnxk_bphy: support registering BPHY IRQ handlers
authorTomasz Duszynski <tduszynski@marvell.com>
Mon, 21 Jun 2021 15:04:48 +0000 (17:04 +0200)
committerThomas Monjalon <thomas@monjalon.net>
Mon, 5 Jul 2021 21:08:46 +0000 (23:08 +0200)
Custom IRQ handlers may be registered/removed on demand.
Since registration and removal are related they are in the
same patch.

Signed-off-by: Jakub Palider <jpalider@marvell.com>
Signed-off-by: Tomasz Duszynski <tduszynski@marvell.com>
Reviewed-by: Jerin Jacob <jerinj@marvell.com>
doc/guides/rawdevs/cnxk_bphy.rst
drivers/raw/cnxk_bphy/cnxk_bphy.c
drivers/raw/cnxk_bphy/cnxk_bphy_irq.c
drivers/raw/cnxk_bphy/cnxk_bphy_irq.h
drivers/raw/cnxk_bphy/rte_pmd_bphy.h

index 16195d2..1e17d60 100644 (file)
@@ -18,6 +18,7 @@ The BPHY CGX/RPM implements following features in the rawdev API:
 
 - Access to BPHY CGX/RPM via a set of predefined messages
 - Access to BPHY memory
+- Custom interrupt handlers
 
 Device Setup
 ------------
@@ -117,6 +118,18 @@ are also two convenience functions namely ``rte_pmd_bphy_intr_init()`` and
 ``rte_pmd_bphy_intr_fini()`` that take care of all details.
 
 
+Register or remove interrupt handler
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Message is used setup custom interrupt handler.
+
+Message must have type set to ``CNXK_BPHY_IRQ_MSG_TYPE_REGISTER`` or
+``CNXK_BPHY_IRQ_MSG_TYPE_UNREGISTER``. The former will register an interrupt handler while the
+latter will remove it. Prior sending actual message payload i.e ``struct cnxk_bphy_irq_info`` needs
+to be filled with relevant information. There are also two convenience functions namely
+``rte_pmd_bphy_intr_register()`` and ``rte_pmd_bphy_intr_unregister()`` that take care of all
+details.
+
 Get device memory
 ~~~~~~~~~~~~~~~~~
 
index 278e26a..2a516ae 100644 (file)
@@ -38,6 +38,7 @@ cnxk_bphy_irq_enqueue_bufs(struct rte_rawdev *dev,
        struct bphy_device *bphy_dev = (struct bphy_device *)dev->dev_private;
        struct cnxk_bphy_irq_msg *msg = buffers[0]->buf_addr;
        unsigned int queue = (size_t)context;
+       struct cnxk_bphy_irq_info *info;
        int ret = 0;
 
        if (queue >= RTE_DIM(bphy_dev->queues))
@@ -53,6 +54,16 @@ cnxk_bphy_irq_enqueue_bufs(struct rte_rawdev *dev,
        case CNXK_BPHY_IRQ_MSG_TYPE_FINI:
                cnxk_bphy_intr_fini(dev->dev_id);
                break;
+       case CNXK_BPHY_IRQ_MSG_TYPE_REGISTER:
+               info = (struct cnxk_bphy_irq_info *)msg->data;
+               ret = cnxk_bphy_intr_register(dev->dev_id, info->irq_num,
+                                             info->handler, info->data,
+                                             info->cpu);
+               break;
+       case CNXK_BPHY_IRQ_MSG_TYPE_UNREGISTER:
+               info = (struct cnxk_bphy_irq_info *)msg->data;
+               cnxk_bphy_intr_unregister(dev->dev_id, info->irq_num);
+               break;
        case CNXK_BPHY_IRQ_MSG_TYPE_MEM_GET:
                bphy_dev->queues[queue].rsp = &bphy_dev->mem;
                break;
index 13a0d8a..bbcc285 100644 (file)
@@ -58,6 +58,39 @@ cnxk_bphy_intr_fini(uint16_t dev_id)
        bphy_dev->irq_chip = NULL;
 }
 
+int
+cnxk_bphy_intr_register(uint16_t dev_id, int irq_num,
+                       cnxk_bphy_intr_handler_t handler, void *data, int cpu)
+{
+       struct roc_bphy_intr intr = {
+               .irq_num = irq_num,
+               .intr_handler = handler,
+               .isr_data = data,
+               .cpu = cpu
+       };
+
+       struct bphy_device *bphy_dev = cnxk_bphy_get_bphy_dev_by_dev_id(dev_id);
+       struct roc_bphy_irq_chip *irq_chip = bphy_dev->irq_chip;
+
+       if (!irq_chip)
+               return -ENODEV;
+       if (!handler || !data)
+               return -EINVAL;
+
+       return roc_bphy_intr_register(irq_chip, &intr);
+}
+
+void
+cnxk_bphy_intr_unregister(uint16_t dev_id, int irq_num)
+{
+       struct bphy_device *bphy_dev = cnxk_bphy_get_bphy_dev_by_dev_id(dev_id);
+
+       if (bphy_dev->irq_chip)
+               roc_bphy_handler_clear(bphy_dev->irq_chip, irq_num);
+       else
+               plt_err("Missing irq chip");
+}
+
 struct bphy_mem *
 cnxk_bphy_mem_get(uint16_t dev_id)
 {
index 5f87143..b55147b 100644 (file)
@@ -32,6 +32,10 @@ struct bphy_device {
 int cnxk_bphy_intr_init(uint16_t dev_id);
 void cnxk_bphy_intr_fini(uint16_t dev_id);
 struct bphy_mem *cnxk_bphy_mem_get(uint16_t dev_id);
+int cnxk_bphy_intr_register(uint16_t dev_id, int irq_num,
+                           cnxk_bphy_intr_handler_t handler,
+                           void *isr_data, int cpu);
+void cnxk_bphy_intr_unregister(uint16_t dev_id, int irq_num);
 uint64_t cnxk_bphy_irq_max_get(uint16_t dev_id);
 
 #endif /* _CNXK_BPHY_IRQ_ */
index d08b14b..f3387f3 100644 (file)
@@ -118,6 +118,8 @@ struct cnxk_bphy_irq_msg {
        enum cnxk_bphy_irq_msg_type type;
        /*
         * The data field, depending on message type, may point to
+        * - (enq) full struct cnxk_bphy_irq_info for registration request
+        * - (enq) struct cnxk_bphy_irq_info with irq_num set for unregistration
         * - (deq) struct cnxk_bphy_mem for memory range request response
         * - (xxx) NULL
         */
@@ -161,6 +163,49 @@ rte_pmd_bphy_intr_fini(uint16_t dev_id)
        rte_rawdev_enqueue_buffers(dev_id, bufs, 1, CNXK_BPHY_DEF_QUEUE);
 }
 
+static __rte_always_inline int
+rte_pmd_bphy_intr_register(uint16_t dev_id, int irq_num,
+                          cnxk_bphy_intr_handler_t handler, void *data,
+                          int cpu)
+{
+       struct cnxk_bphy_irq_info info = {
+               .irq_num = irq_num,
+               .handler = handler,
+               .data = data,
+               .cpu = cpu,
+       };
+       struct cnxk_bphy_irq_msg msg = {
+               .type = CNXK_BPHY_IRQ_MSG_TYPE_REGISTER,
+               .data = &info
+       };
+       struct rte_rawdev_buf *bufs[1];
+       struct rte_rawdev_buf buf;
+
+       buf.buf_addr = &msg;
+       bufs[0] = &buf;
+
+       return rte_rawdev_enqueue_buffers(dev_id, bufs, 1, CNXK_BPHY_DEF_QUEUE);
+}
+
+static __rte_always_inline void
+rte_pmd_bphy_intr_unregister(uint16_t dev_id, int irq_num)
+{
+       struct cnxk_bphy_irq_info info = {
+               .irq_num = irq_num,
+       };
+       struct cnxk_bphy_irq_msg msg = {
+               .type = CNXK_BPHY_IRQ_MSG_TYPE_UNREGISTER,
+               .data = &info
+       };
+       struct rte_rawdev_buf *bufs[1];
+       struct rte_rawdev_buf buf;
+
+       buf.buf_addr = &msg;
+       bufs[0] = &buf;
+
+       rte_rawdev_enqueue_buffers(dev_id, bufs, 1, 0);
+}
+
 static __rte_always_inline struct cnxk_bphy_mem *
 rte_pmd_bphy_intr_mem_get(uint16_t dev_id)
 {