@@ -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
~~~~~~~~~~~~~~~~~
@@ -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;
@@ -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)
{
@@ -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_ */
@@ -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)
{