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>
- Access to BPHY CGX/RPM via a set of predefined messages
- Access to BPHY memory
+- Custom interrupt handlers
Device Setup
------------
``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
~~~~~~~~~~~~~~~~~
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))
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;
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)
{
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_ */
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
*/
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)
{