diff --git a/doc/guides/rawdevs/cnxk_bphy.rst b/doc/guides/rawdevs/cnxk_bphy.rst
index 2edd814da..00edca4be 100644
--- a/doc/guides/rawdevs/cnxk_bphy.rst
+++ b/doc/guides/rawdevs/cnxk_bphy.rst
@@ -37,6 +37,9 @@ To perform data transfer use standard ``rte_rawdev_enqueue_buffers()`` and
 ``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()``.
@@ -95,6 +98,23 @@ Message must have type set to ``CNXK_BPHY_CGX_MSG_TYPE_START_RXTX`` or
 ``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
 ---------
 
diff --git a/drivers/raw/cnxk_bphy/cnxk_bphy.c b/drivers/raw/cnxk_bphy/cnxk_bphy.c
index 7e541bac4..3f8679534 100644
--- a/drivers/raw/cnxk_bphy/cnxk_bphy.c
+++ b/drivers/raw/cnxk_bphy/cnxk_bphy.c
@@ -47,6 +47,12 @@ cnxk_bphy_irq_enqueue_bufs(struct rte_rawdev *dev,
 		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;
 	}
diff --git a/drivers/raw/cnxk_bphy/cnxk_bphy_irq.c b/drivers/raw/cnxk_bphy/cnxk_bphy_irq.c
new file mode 100644
index 000000000..c4df539cd
--- /dev/null
+++ b/drivers/raw/cnxk_bphy/cnxk_bphy_irq.c
@@ -0,0 +1,47 @@
+/* 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;
+}
diff --git a/drivers/raw/cnxk_bphy/cnxk_bphy_irq.h b/drivers/raw/cnxk_bphy/cnxk_bphy_irq.h
index 16243efc9..3acc47fe8 100644
--- a/drivers/raw/cnxk_bphy/cnxk_bphy_irq.h
+++ b/drivers/raw/cnxk_bphy/cnxk_bphy_irq.h
@@ -10,6 +10,8 @@
 
 #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;
@@ -27,4 +29,7 @@ struct bphy_device {
 	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_ */
diff --git a/drivers/raw/cnxk_bphy/meson.build b/drivers/raw/cnxk_bphy/meson.build
index f2868fd68..14147feaf 100644
--- a/drivers/raw/cnxk_bphy/meson.build
+++ b/drivers/raw/cnxk_bphy/meson.build
@@ -7,5 +7,6 @@ sources = files(
         'cnxk_bphy.c',
         'cnxk_bphy_cgx.c',
         'cnxk_bphy_cgx_test.c',
+        'cnxk_bphy_irq.c',
 )
 headers = files('rte_pmd_bphy.h')
diff --git a/drivers/raw/cnxk_bphy/rte_pmd_bphy.h b/drivers/raw/cnxk_bphy/rte_pmd_bphy.h
index eb39654f1..c667d984e 100644
--- a/drivers/raw/cnxk_bphy/rte_pmd_bphy.h
+++ b/drivers/raw/cnxk_bphy/rte_pmd_bphy.h
@@ -5,6 +5,8 @@
 #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,
@@ -101,6 +103,8 @@ struct cnxk_bphy_cgx_msg {
 	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,
@@ -114,4 +118,41 @@ struct cnxk_bphy_irq_msg {
 	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_ */
