``rte_rawdev_dequeue_buffers()`` APIs. Not all messages produce sensible
 responses hence dequeueing is not always necessary.
 
+BPHY CGX/RPM PMD
+----------------
+
 BPHY CGX/RPM PMD accepts ``struct cnxk_bphy_cgx_msg`` messages which differ by type and payload.
 Message types along with description are listed below. As for the usage examples please refer to
 ``cnxk_bphy_cgx_dev_selftest()``.
 ``CNXK_BPHY_CGX_MSG_TYPE_STOP_RXTX``. Former will enable traffic while the latter will
 do the opposite.
 
+BPHY PMD
+--------
+
+BPHY PMD accepts ``struct cnxk_bphy_irq_msg`` messages which differ by type and payload.
+Message types along with description are listed below. For some usage examples please refer to
+``bphy_rawdev_selftest()``.
+
+Initialize or finalize interrupt handling
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Message is used to setup low level interrupt handling.
+
+Message must have type set to ``CNXK_BPHY_IRQ_MSG_TYPE_INIT`` or ``CNXK_BPHY_IRQ_MSG_TYPE_FINI``.
+The former will setup low level interrupt handling while the latter will tear everything down. There
+are also two convenience functions namely ``rte_pmd_bphy_intr_init()`` and
+``rte_pmd_bphy_intr_fini()`` that take care of all details.
+
 Self test
 ---------
 
 
                return 0;
 
        switch (msg->type) {
+       case CNXK_BPHY_IRQ_MSG_TYPE_INIT:
+               ret = cnxk_bphy_intr_init(dev->dev_id);
+               break;
+       case CNXK_BPHY_IRQ_MSG_TYPE_FINI:
+               cnxk_bphy_intr_fini(dev->dev_id);
+               break;
        default:
                ret = -EINVAL;
        }
 
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+#include <rte_bus_pci.h>
+#include <rte_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include <roc_api.h>
+#include <roc_bphy_irq.h>
+
+#include "cnxk_bphy_irq.h"
+
+static struct bphy_device *
+cnxk_bphy_get_bphy_dev_by_dev_id(uint16_t dev_id)
+{
+       struct rte_rawdev *rawdev;
+
+       if (!rte_rawdev_pmd_is_valid_dev(dev_id))
+               return NULL;
+
+       rawdev = &rte_rawdevs[dev_id];
+
+       return (struct bphy_device *)rawdev->dev_private;
+}
+
+int
+cnxk_bphy_intr_init(uint16_t dev_id)
+{
+       struct bphy_device *bphy_dev = cnxk_bphy_get_bphy_dev_by_dev_id(dev_id);
+
+       bphy_dev->irq_chip = roc_bphy_intr_init();
+       if (bphy_dev->irq_chip == NULL)
+               return -ENOMEM;
+
+       return 0;
+}
+
+void
+cnxk_bphy_intr_fini(uint16_t dev_id)
+{
+       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;
+
+       roc_bphy_intr_fini(irq_chip);
+       bphy_dev->irq_chip = NULL;
+}
 
 
 #include <roc_api.h>
 
+typedef void (*cnxk_bphy_intr_handler_t)(int irq_num, void *isr_data);
+
 struct bphy_mem {
        struct rte_mem_resource res0;
        struct rte_mem_resource res2;
        struct bphy_irq_queue queues[1];
 };
 
+int cnxk_bphy_intr_init(uint16_t dev_id);
+void cnxk_bphy_intr_fini(uint16_t dev_id);
+
 #endif /* _CNXK_BPHY_IRQ_ */
 
         'cnxk_bphy.c',
         'cnxk_bphy_cgx.c',
         'cnxk_bphy_cgx_test.c',
+        'cnxk_bphy_irq.c',
 )
 headers = files('rte_pmd_bphy.h')
 
 #ifndef _CNXK_BPHY_H_
 #define _CNXK_BPHY_H_
 
+#include "cnxk_bphy_irq.h"
+
 enum cnxk_bphy_cgx_msg_type {
        CNXK_BPHY_CGX_MSG_TYPE_GET_LINKINFO,
        CNXK_BPHY_CGX_MSG_TYPE_INTLBK_DISABLE,
        void *data;
 };
 
+#define CNXK_BPHY_DEF_QUEUE 0
+
 enum cnxk_bphy_irq_msg_type {
        CNXK_BPHY_IRQ_MSG_TYPE_INIT,
        CNXK_BPHY_IRQ_MSG_TYPE_FINI,
        void *data;
 };
 
+struct cnxk_bphy_irq_info {
+       int irq_num;
+       cnxk_bphy_intr_handler_t handler;
+       void *data;
+       int cpu;
+};
+
+static __rte_always_inline int
+rte_pmd_bphy_intr_init(uint16_t dev_id)
+{
+       struct cnxk_bphy_irq_msg msg = {
+               .type = CNXK_BPHY_IRQ_MSG_TYPE_INIT,
+       };
+       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_fini(uint16_t dev_id)
+{
+       struct cnxk_bphy_irq_msg msg = {
+               .type = CNXK_BPHY_IRQ_MSG_TYPE_FINI,
+       };
+       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, CNXK_BPHY_DEF_QUEUE);
+}
+
 #endif /* _CNXK_BPHY_H_ */