[v3,1/9] drivers/raw: introduce cnxk rvu lf device driver

Message ID 20241008184915.1356089-2-gakhil@marvell.com (mailing list archive)
State Changes Requested, archived
Delegated to: Jerin Jacob
Headers
Series drivers/raw: introduce cnxk rvu lf device driver |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/iol-testing fail build patch failure

Commit Message

Akhil Goyal Oct. 8, 2024, 6:49 p.m. UTC
CNXK product families can have a use case to allow PF and VF
applications to communicate using mailboxes and also get notified
of any interrupt that may occur on the device.
Hence, a new raw device driver is added for such RVU LF devices.
These devices can map to a PF or a VF which can send mailboxes to
each other.

Signed-off-by: Akhil Goyal <gakhil@marvell.com>
---
 MAINTAINERS                           |   6 ++
 doc/guides/rawdevs/cnxk_rvu_lf.rst    |  40 +++++++++
 doc/guides/rawdevs/index.rst          |   1 +
 drivers/common/cnxk/meson.build       |   1 +
 drivers/common/cnxk/roc_api.h         |   3 +
 drivers/common/cnxk/roc_constants.h   |   3 +
 drivers/common/cnxk/roc_dev_priv.h    |   1 +
 drivers/common/cnxk/roc_idev.c        |  46 ++++++++++
 drivers/common/cnxk/roc_idev.h        |   4 +
 drivers/common/cnxk/roc_idev_priv.h   |   1 +
 drivers/common/cnxk/roc_priv.h        |   2 +
 drivers/common/cnxk/roc_rvu_lf.c      |  63 +++++++++++++
 drivers/common/cnxk/roc_rvu_lf.h      |  24 +++++
 drivers/common/cnxk/roc_rvu_lf_priv.h |  32 +++++++
 drivers/common/cnxk/roc_utils.c       |   2 +
 drivers/common/cnxk/version.map       |   5 ++
 drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c | 123 ++++++++++++++++++++++++++
 drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h |  35 ++++++++
 drivers/raw/cnxk_rvu_lf/meson.build   |   9 ++
 drivers/raw/meson.build               |   1 +
 20 files changed, 402 insertions(+)
 create mode 100644 doc/guides/rawdevs/cnxk_rvu_lf.rst
 create mode 100644 drivers/common/cnxk/roc_rvu_lf.c
 create mode 100644 drivers/common/cnxk/roc_rvu_lf.h
 create mode 100644 drivers/common/cnxk/roc_rvu_lf_priv.h
 create mode 100644 drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c
 create mode 100644 drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h
 create mode 100644 drivers/raw/cnxk_rvu_lf/meson.build
  

Comments

Stephen Hemminger Oct. 8, 2024, 8:44 p.m. UTC | #1
On Wed, 9 Oct 2024 00:19:07 +0530
Akhil Goyal <gakhil@marvell.com> wrote:

> +Marvell CNXK RVU LF Driver
> +==========================
> +
> +CNXK product families can have a use case to allow PF and VF
> +applications to communicate using mailboxes and also get notified
> +of any interrupt that may occur on the device.
> +Hence, a new raw device driver is added for such RVU LF devices.
> +These devices can map to a PF or a VF which can send mailboxes to
> +each other.

This wording is very indirect and awkward.
Please write documentation in imperative not passive voice.
If you need help, there are many online grammar tools to fix this kind of stuff.
  
Stephen Hemminger Oct. 9, 2024, 6:09 p.m. UTC | #2
On Wed, 9 Oct 2024 00:19:07 +0530
Akhil Goyal <gakhil@marvell.com> wrote:

> CNXK product families can have a use case to allow PF and VF
> applications to communicate using mailboxes and also get notified
> of any interrupt that may occur on the device.
> Hence, a new raw device driver is added for such RVU LF devices.
> These devices can map to a PF or a VF which can send mailboxes to
> each other.
> 
> Signed-off-by: Akhil Goyal <gakhil@marvell.com>
> ---
>  MAINTAINERS                           |   6 ++
>  doc/guides/rawdevs/cnxk_rvu_lf.rst    |  40 +++++++++
>  doc/guides/rawdevs/index.rst          |   1 +
>  drivers/common/cnxk/meson.build       |   1 +
>  drivers/common/cnxk/roc_api.h         |   3 +
>  drivers/common/cnxk/roc_constants.h   |   3 +

This patch set does not apply to main branch, are you targeting another tree
or is there a dependency on a previous patch series.

$ cat drivers/common/cnxk/roc_constants.h.rej 
--- drivers/common/cnxk/roc_constants.h
+++ drivers/common/cnxk/roc_constants.h
@@ -65,6 +67,7 @@
 #define PCI_SUBSYSTEM_DEVID_CNF10KB 0xBC00
 
 #define PCI_SUBSYSTEM_DEVID_CN20KA 0xA020
+#define PCI_SUBSYSTEM_DEVID_CNF20KA 0xA000
 
 #define PCI_SUBSYSTEM_DEVID_CN9KA  0x0000
 #define PCI_SUBSYSTEM_DEVID_CN9KB  0xb400
  
Akhil Goyal Oct. 9, 2024, 6:14 p.m. UTC | #3
> On Wed, 9 Oct 2024 00:19:07 +0530
> Akhil Goyal <gakhil@marvell.com> wrote:
> 
> > CNXK product families can have a use case to allow PF and VF
> > applications to communicate using mailboxes and also get notified
> > of any interrupt that may occur on the device.
> > Hence, a new raw device driver is added for such RVU LF devices.
> > These devices can map to a PF or a VF which can send mailboxes to
> > each other.
> >
> > Signed-off-by: Akhil Goyal <gakhil@marvell.com>
> > ---
> >  MAINTAINERS                           |   6 ++
> >  doc/guides/rawdevs/cnxk_rvu_lf.rst    |  40 +++++++++
> >  doc/guides/rawdevs/index.rst          |   1 +
> >  drivers/common/cnxk/meson.build       |   1 +
> >  drivers/common/cnxk/roc_api.h         |   3 +
> >  drivers/common/cnxk/roc_constants.h   |   3 +
> 
> This patch set does not apply to main branch, are you targeting another tree
> or is there a dependency on a previous patch series.

This is targeted for next-net-mrvl and as mentioned in cover-letter it depends on 
https://patches.dpdk.org/project/dpdk/patch/20241008074000.3745855-1-gakhil@marvell.com/
> 
> $ cat drivers/common/cnxk/roc_constants.h.rej
> --- drivers/common/cnxk/roc_constants.h
> +++ drivers/common/cnxk/roc_constants.h
> @@ -65,6 +67,7 @@
>  #define PCI_SUBSYSTEM_DEVID_CNF10KB 0xBC00
> 
>  #define PCI_SUBSYSTEM_DEVID_CN20KA 0xA020
> +#define PCI_SUBSYSTEM_DEVID_CNF20KA 0xA000
> 
>  #define PCI_SUBSYSTEM_DEVID_CN9KA  0x0000
>  #define PCI_SUBSYSTEM_DEVID_CN9KB  0xb400
  
David Marchand Oct. 23, 2024, 2:01 p.m. UTC | #4
On Tue, Oct 8, 2024 at 8:49 PM Akhil Goyal <gakhil@marvell.com> wrote:
>
> CNXK product families can have a use case to allow PF and VF
> applications to communicate using mailboxes and also get notified
> of any interrupt that may occur on the device.
> Hence, a new raw device driver is added for such RVU LF devices.
> These devices can map to a PF or a VF which can send mailboxes to
> each other.
>
> Signed-off-by: Akhil Goyal <gakhil@marvell.com>

Some small comments below.


> diff --git a/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c
> new file mode 100644
> index 0000000000..36067909be
> --- /dev/null
> +++ b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c
> @@ -0,0 +1,123 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2024 Marvell.
> + */
> +
> +#include <bus_pci_driver.h>
> +#include <rte_common.h>
> +#include <dev_driver.h>
> +#include <rte_eal.h>
> +#include <rte_lcore.h>
> +#include <rte_pci.h>
> +#include <rte_rawdev.h>
> +#include <rte_rawdev_pmd.h>
> +
> +#include <roc_api.h>
> +
> +#include "cnxk_rvu_lf.h"
> +
> +static const struct rte_rawdev_ops rvu_lf_rawdev_ops = {
> +       .dev_selftest = NULL,
> +};
> +
> +static void
> +rvu_lf_rawdev_get_name(char *name, struct rte_pci_device *pci_dev)
> +{
> +       snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "RVU LF:%02x:%02x.%x",
> +                pci_dev->addr.bus, pci_dev->addr.devid,
> +                pci_dev->addr.function);
> +}
> +
> +static int
> +rvu_lf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
> +{
> +       char name[RTE_RAWDEV_NAME_MAX_LEN];
> +       struct rte_rawdev *rvu_lf_rawdev;
> +       struct roc_rvu_lf *roc_rvu_lf;
> +       int ret;
> +
> +       RTE_SET_USED(pci_drv);
> +
> +       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> +               return 0;
> +
> +       if (!pci_dev->mem_resource[2].addr) {
> +               CNXK_RVU_LF_LOG(ERR, "BARs have invalid values: BAR0 %p\n BAR2 %p",

No \n in the middle of a log please.


> +                             pci_dev->mem_resource[2].addr, pci_dev->mem_resource[4].addr);
> +               return -ENODEV;
> +       }
> +
> +       ret = roc_plt_init();
> +       if (ret)
> +               return ret;
> +
> +       rvu_lf_rawdev_get_name(name, pci_dev);
> +       rvu_lf_rawdev = rte_rawdev_pmd_allocate(name, sizeof(*roc_rvu_lf),
> +                                             rte_socket_id());
> +       if (rvu_lf_rawdev == NULL) {
> +               CNXK_RVU_LF_LOG(ERR, "Failed to allocate rawdev");
> +               return -ENOMEM;
> +       }
> +
> +       rvu_lf_rawdev->dev_ops = &rvu_lf_rawdev_ops;
> +       rvu_lf_rawdev->device = &pci_dev->device;
> +       rvu_lf_rawdev->driver_name = pci_dev->driver->driver.name;
> +
> +       roc_rvu_lf = (struct roc_rvu_lf *)rvu_lf_rawdev->dev_private;
> +       roc_rvu_lf->pci_dev = pci_dev;
> +
> +       ret = roc_rvu_lf_dev_init(roc_rvu_lf);
> +       if (ret) {
> +               rte_rawdev_pmd_release(rvu_lf_rawdev);
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static int
> +rvu_lf_remove(struct rte_pci_device *pci_dev)
> +{
> +       char name[RTE_RAWDEV_NAME_MAX_LEN];
> +       struct roc_rvu_lf *roc_rvu_lf;
> +       struct rte_rawdev *rawdev;
> +
> +       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> +               return 0;
> +
> +       if (pci_dev == NULL) {
> +               CNXK_RVU_LF_LOG(ERR, "invalid pci_dev");
> +               return -EINVAL;
> +       }
> +
> +       rvu_lf_rawdev_get_name(name, pci_dev);
> +       rawdev = rte_rawdev_pmd_get_named_dev(name);
> +       if (rawdev == NULL) {
> +               CNXK_RVU_LF_LOG(ERR, "invalid device name (%s)", name);
> +               return -EINVAL;
> +       }
> +
> +       roc_rvu_lf = (struct roc_rvu_lf *)rawdev->dev_private;
> +       roc_rvu_lf_dev_fini(roc_rvu_lf);
> +
> +       return rte_rawdev_pmd_release(rawdev);
> +}
> +
> +static const struct rte_pci_id pci_rvu_lf_map[] = {
> +       CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CNF20KA, PCI_DEVID_CNXK_RVU_BPHY_PF),
> +       CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CNF20KA, PCI_DEVID_CNXK_RVU_BPHY_VF),
> +       {
> +               .vendor_id = 0,
> +       },
> +};
> +
> +static struct rte_pci_driver cnxk_rvu_lf_rawdev_pmd = {
> +       .id_table = pci_rvu_lf_map,
> +       .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
> +       .probe = rvu_lf_probe,
> +       .remove = rvu_lf_remove,
> +};
> +
> +RTE_PMD_REGISTER_PCI(rvu_lf_rawdev_pci_driver, cnxk_rvu_lf_rawdev_pmd);
> +RTE_PMD_REGISTER_PCI_TABLE(rvu_lf_rawdev_pci_driver, pci_rvu_lf_map);
> +RTE_PMD_REGISTER_KMOD_DEP(rvu_lf_rawdev_pci_driver, "vfio-pci");
> +RTE_LOG_REGISTER_SUFFIX(cnxk_logtype_rvu_lf, rvu_lf, INFO);
> diff --git a/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h
> new file mode 100644
> index 0000000000..a23a629500
> --- /dev/null
> +++ b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h
> @@ -0,0 +1,35 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2024 Marvell.
> + */
> +
> +#ifndef _CNXK_RVU_LF_H_
> +#define _CNXK_RVU_LF_H_
> +
> +#include <stdint.h>
> +
> +#include <rte_common.h>
> +
> +/**
> + * @file cnxk_rvu_lf.h
> + *
> + * Marvell RVU LF raw PMD specific internal structures
> + *
> + * This API allows applications to manage RVU LF device in user space along with
> + * installing interrupt handlers for low latency signal processing.
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif

You don't need this for non exported/internal headers.


> +
> +extern int cnxk_logtype_rvu_lf;
> +
> +#define CNXK_RVU_LF_LOG(level, fmt, args...)   \
> +       rte_log(RTE_LOG_ ## level, cnxk_logtype_rvu_lf, \
> +               "%s(): " fmt "\n", __func__, ## args)

Please convert to RTE_LOG_LINE_PREFIX.


> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _CNXK_RVU_LF_H_ */
  

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index 812463fe9f..97e934edb0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1498,6 +1498,12 @@  T: git://dpdk.org/next/dpdk-next-net-mrvl
 F: doc/guides/rawdevs/cnxk_gpio.rst
 F: drivers/raw/cnxk_gpio/
 
+Marvell CNXK RVU LF
+M: Akhil Goyal <gakhil@marvell.com>
+T: git://dpdk.org/next/dpdk-next-net-mrvl
+F: doc/guides/rawdevs/cnxk_rvu_lf.rst
+F: drivers/raw/cnxk_rvu_lf/
+
 NTB
 M: Jingjing Wu <jingjing.wu@intel.com>
 F: drivers/raw/ntb/
diff --git a/doc/guides/rawdevs/cnxk_rvu_lf.rst b/doc/guides/rawdevs/cnxk_rvu_lf.rst
new file mode 100644
index 0000000000..8a0bc22dd5
--- /dev/null
+++ b/doc/guides/rawdevs/cnxk_rvu_lf.rst
@@ -0,0 +1,40 @@ 
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2024 Marvell.
+
+Marvell CNXK RVU LF Driver
+==========================
+
+CNXK product families can have a use case to allow PF and VF
+applications to communicate using mailboxes and also get notified
+of any interrupt that may occur on the device.
+Hence, a new raw device driver is added for such RVU LF devices.
+These devices can map to a PF or a VF which can send mailboxes to
+each other.
+
+Features
+--------
+
+The RVU LF device implements following features in the rawdev API:
+
+- Register mailbox callbacks for the other side to process mailboxes.
+- Register interrupt handler callbacks.
+- Process mailbox.
+- Set range of message IDs allowed for communication.
+
+Limitations
+-----------
+
+In multiprocess mode user-space application must ensure
+no resources sharing takes place.
+Otherwise, user-space application should ensure synchronization.
+
+Device Setup
+------------
+
+The RVU LF devices will need to be bound to a user-space IO driver for use.
+The script ``dpdk-devbind.py`` included with DPDK can be used to
+view the state of the devices and to bind them to a suitable DPDK-supported
+kernel driver. When querying the status of the devices, they will appear under
+the category of "Misc (rawdev) devices", i.e. the command
+``dpdk-devbind.py --status-dev misc`` can be used to see the state of those
+devices alone.
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index f34315f051..8e07cf4d6c 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -13,6 +13,7 @@  application through rawdev API.
 
     cnxk_bphy
     cnxk_gpio
+    cnxk_rvu_lf
     dpaa2_cmdif
     ifpga
     ntb
diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build
index dc2ddf1f20..f847aa5d34 100644
--- a/drivers/common/cnxk/meson.build
+++ b/drivers/common/cnxk/meson.build
@@ -71,6 +71,7 @@  sources = files(
         'roc_tim_irq.c',
         'roc_utils.c',
         'roc_ree.c',
+        'roc_rvu_lf.c',
 )
 
 # Security common code
diff --git a/drivers/common/cnxk/roc_api.h b/drivers/common/cnxk/roc_api.h
index 6a86863c57..93e7bf11bb 100644
--- a/drivers/common/cnxk/roc_api.h
+++ b/drivers/common/cnxk/roc_api.h
@@ -120,4 +120,7 @@ 
 /* Eswitch */
 #include "roc_eswitch.h"
 
+/* RVU LF */
+#include "roc_rvu_lf.h"
+
 #endif /* _ROC_API_H_ */
diff --git a/drivers/common/cnxk/roc_constants.h b/drivers/common/cnxk/roc_constants.h
index 0e7495a37c..67cd74b28a 100644
--- a/drivers/common/cnxk/roc_constants.h
+++ b/drivers/common/cnxk/roc_constants.h
@@ -45,6 +45,8 @@ 
 #define PCI_DEVID_CNXK_RVU_REE_VF     0xA0f5
 #define PCI_DEVID_CNXK_RVU_ESWITCH_PF 0xA0E0
 #define PCI_DEVID_CNXK_RVU_ESWITCH_VF 0xA0E1
+#define PCI_DEVID_CNXK_RVU_BPHY_PF    0xA0E4
+#define PCI_DEVID_CNXK_RVU_BPHY_VF    0xA0E5
 
 #define PCI_DEVID_CN9K_CGX  0xA059
 #define PCI_DEVID_CN10K_RPM 0xA060
@@ -63,6 +65,7 @@ 
 #define PCI_SUBSYSTEM_DEVID_CNF10KB 0xBC00
 
 #define PCI_SUBSYSTEM_DEVID_CN20KA 0xA020
+#define PCI_SUBSYSTEM_DEVID_CNF20KA 0xA000
 
 #define PCI_SUBSYSTEM_DEVID_CN9KA  0x0000
 #define PCI_SUBSYSTEM_DEVID_CN9KB  0xb400
diff --git a/drivers/common/cnxk/roc_dev_priv.h b/drivers/common/cnxk/roc_dev_priv.h
index 5ab4f72f8f..dd4949b32c 100644
--- a/drivers/common/cnxk/roc_dev_priv.h
+++ b/drivers/common/cnxk/roc_dev_priv.h
@@ -141,6 +141,7 @@  struct dev {
 	void *roc_cpt;
 	void *roc_tim;
 	void *roc_ml;
+	void *roc_rvu_lf;
 	bool disable_shared_lmt; /* false(default): shared lmt mode enabled */
 	const struct plt_memzone *lmt_mz;
 	struct mbox_sync sync;
diff --git a/drivers/common/cnxk/roc_idev.c b/drivers/common/cnxk/roc_idev.c
index 0778d51d1e..84812f73e0 100644
--- a/drivers/common/cnxk/roc_idev.c
+++ b/drivers/common/cnxk/roc_idev.c
@@ -38,6 +38,7 @@  idev_set_defaults(struct idev_cfg *idev)
 	idev->num_lmtlines = 0;
 	idev->bphy = NULL;
 	idev->cpt = NULL;
+	TAILQ_INIT(&idev->rvu_lf_list);
 	TAILQ_INIT(&idev->mcs_list);
 	idev->nix_inl_dev = NULL;
 	TAILQ_INIT(&idev->roc_nix_list);
@@ -188,6 +189,51 @@  roc_idev_cpt_get(void)
 	return NULL;
 }
 
+struct roc_rvu_lf *
+roc_idev_rvu_lf_get(uint8_t rvu_lf_idx)
+{
+	struct idev_cfg *idev = idev_get_cfg();
+	struct roc_rvu_lf *rvu_lf = NULL;
+
+	if (idev != NULL) {
+		TAILQ_FOREACH(rvu_lf, &idev->rvu_lf_list, next) {
+			if (rvu_lf->idx == rvu_lf_idx)
+				return rvu_lf;
+		}
+	}
+
+	return NULL;
+}
+
+void
+roc_idev_rvu_lf_set(struct roc_rvu_lf *rvu)
+{
+	struct idev_cfg *idev = idev_get_cfg();
+	struct roc_rvu_lf *rvu_lf_iter = NULL;
+
+	if (idev != NULL) {
+		TAILQ_FOREACH(rvu_lf_iter, &idev->rvu_lf_list, next) {
+			if (rvu_lf_iter->idx == rvu->idx)
+				return;
+		}
+		TAILQ_INSERT_TAIL(&idev->rvu_lf_list, rvu, next);
+	}
+}
+
+void
+roc_idev_rvu_lf_free(struct roc_rvu_lf *rvu)
+{
+	struct idev_cfg *idev = idev_get_cfg();
+	struct roc_rvu_lf *rvu_lf_iter = NULL;
+
+	if (idev != NULL) {
+		TAILQ_FOREACH(rvu_lf_iter, &idev->rvu_lf_list, next) {
+			if (rvu_lf_iter->idx == rvu->idx)
+				TAILQ_REMOVE(&idev->rvu_lf_list, rvu, next);
+		}
+	}
+}
+
 struct roc_mcs *
 roc_idev_mcs_get(uint8_t mcs_idx)
 {
diff --git a/drivers/common/cnxk/roc_idev.h b/drivers/common/cnxk/roc_idev.h
index fc0f7db54e..6edb5f83b2 100644
--- a/drivers/common/cnxk/roc_idev.h
+++ b/drivers/common/cnxk/roc_idev.h
@@ -29,4 +29,8 @@  uint16_t *__roc_api roc_idev_nix_rx_chan_base_get(void);
 void __roc_api roc_idev_nix_rx_chan_set(uint16_t port, uint16_t chan);
 
 uint16_t __roc_api roc_idev_nix_inl_dev_pffunc_get(void);
+
+struct roc_rvu_lf *__roc_api roc_idev_rvu_lf_get(uint8_t rvu_lf_idx);
+void __roc_api roc_idev_rvu_lf_set(struct roc_rvu_lf *rvu);
+void __roc_api roc_idev_rvu_lf_free(struct roc_rvu_lf *rvu);
 #endif /* _ROC_IDEV_H_ */
diff --git a/drivers/common/cnxk/roc_idev_priv.h b/drivers/common/cnxk/roc_idev_priv.h
index 6628b18152..98b6286bfe 100644
--- a/drivers/common/cnxk/roc_idev_priv.h
+++ b/drivers/common/cnxk/roc_idev_priv.h
@@ -36,6 +36,7 @@  struct idev_cfg {
 	struct roc_bphy *bphy;
 	struct roc_cpt *cpt;
 	struct roc_sso *sso;
+	struct roc_rvu_lf_head rvu_lf_list;
 	struct roc_mcs_head mcs_list;
 	struct nix_inl_dev *nix_inl_dev;
 	struct idev_nix_inl_cfg inl_cfg;
diff --git a/drivers/common/cnxk/roc_priv.h b/drivers/common/cnxk/roc_priv.h
index 254a2d3310..8732a05ac3 100644
--- a/drivers/common/cnxk/roc_priv.h
+++ b/drivers/common/cnxk/roc_priv.h
@@ -53,4 +53,6 @@ 
 /* ML */
 #include "roc_ml_priv.h"
 
+/* RVU LF */
+#include "roc_rvu_lf_priv.h"
 #endif /* _ROC_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_rvu_lf.c b/drivers/common/cnxk/roc_rvu_lf.c
new file mode 100644
index 0000000000..1ae39e746e
--- /dev/null
+++ b/drivers/common/cnxk/roc_rvu_lf.c
@@ -0,0 +1,63 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#include "roc_api.h"
+#include "roc_priv.h"
+
+int
+roc_rvu_lf_dev_init(struct roc_rvu_lf *roc_rvu_lf)
+{
+	struct plt_pci_device *pci_dev;
+	struct dev *dev;
+	struct rvu_lf *rvu;
+	int rc;
+
+	if (roc_rvu_lf == NULL || roc_rvu_lf->pci_dev == NULL)
+		return RVU_ERR_PARAM;
+
+	rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
+	pci_dev = roc_rvu_lf->pci_dev;
+	dev = &rvu->dev;
+
+	if (rvu->dev.drv_inited)
+		return 0;
+
+	if (dev->mbox_active)
+		goto skip_dev_init;
+
+	memset(rvu, 0, sizeof(*rvu));
+
+	/* Initialize device  */
+	rc = dev_init(dev, pci_dev);
+	if (rc) {
+		plt_err("Failed to init roc device");
+		goto fail;
+	}
+
+skip_dev_init:
+	dev->roc_rvu_lf = roc_rvu_lf;
+	rvu->pci_dev = pci_dev;
+
+	roc_idev_rvu_lf_set(roc_rvu_lf);
+	rvu->dev.drv_inited = true;
+
+	return 0;
+fail:
+	return rc;
+}
+
+int
+roc_rvu_lf_dev_fini(struct roc_rvu_lf *roc_rvu_lf)
+{
+	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
+
+	if (rvu == NULL)
+		return NIX_ERR_PARAM;
+
+	rvu->dev.drv_inited = false;
+
+	roc_idev_rvu_lf_free(roc_rvu_lf);
+
+	return dev_fini(&rvu->dev, rvu->pci_dev);
+}
diff --git a/drivers/common/cnxk/roc_rvu_lf.h b/drivers/common/cnxk/roc_rvu_lf.h
new file mode 100644
index 0000000000..7ce8065a8b
--- /dev/null
+++ b/drivers/common/cnxk/roc_rvu_lf.h
@@ -0,0 +1,24 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#ifndef _ROC_RVU_LF_H_
+#define _ROC_RVU_LF_H_
+
+#include "roc_platform.h"
+
+struct roc_rvu_lf {
+	TAILQ_ENTRY(roc_rvu_lf) next;
+	struct plt_pci_device *pci_dev;
+	uint8_t idx;
+#define ROC_RVU_MEM_SZ (6 * 1024)
+	uint8_t reserved[ROC_RVU_MEM_SZ] __plt_cache_aligned;
+};
+
+TAILQ_HEAD(roc_rvu_lf_head, roc_rvu_lf);
+
+/* Dev */
+int __roc_api roc_rvu_lf_dev_init(struct roc_rvu_lf *roc_rvu_lf);
+int __roc_api roc_rvu_lf_dev_fini(struct roc_rvu_lf *roc_rvu_lf);
+
+#endif /* _ROC_RVU_LF_H_ */
diff --git a/drivers/common/cnxk/roc_rvu_lf_priv.h b/drivers/common/cnxk/roc_rvu_lf_priv.h
new file mode 100644
index 0000000000..8feff82961
--- /dev/null
+++ b/drivers/common/cnxk/roc_rvu_lf_priv.h
@@ -0,0 +1,32 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#ifndef _ROC_RVU_LF_PRIV_H_
+#define _ROC_RVU_LF_PRIV_H_
+
+enum rvu_err_status {
+	RVU_ERR_PARAM = -1,
+	RVU_ERR_NO_MEM = -2,
+};
+
+struct rvu_lf {
+	struct plt_pci_device *pci_dev;
+	struct dev dev;
+	uint16_t msg_id_from;
+	uint16_t msg_id_to;
+};
+
+static inline struct rvu_lf *
+roc_rvu_lf_to_rvu_priv(struct roc_rvu_lf *roc_rvu_lf)
+{
+	return (struct rvu_lf *)&roc_rvu_lf->reserved[0];
+}
+
+static inline struct roc_rvu_lf *
+rvu_priv_to_roc_rvu_lf(struct rvu_lf *rvu_lf)
+{
+	return (struct roc_rvu_lf *)((char *)rvu_lf - offsetof(struct roc_rvu_lf, reserved));
+}
+
+#endif /* _ROC_RVU_LF_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_utils.c b/drivers/common/cnxk/roc_utils.c
index 9af2ae9b69..bcc0d2de38 100644
--- a/drivers/common/cnxk/roc_utils.c
+++ b/drivers/common/cnxk/roc_utils.c
@@ -17,11 +17,13 @@  roc_error_msg_get(int errorcode)
 	case NPC_ERR_PARAM:
 	case SSO_ERR_PARAM:
 	case MCS_ERR_PARAM:
+	case RVU_ERR_PARAM:
 	case UTIL_ERR_PARAM:
 		err_msg = "Invalid parameter";
 		break;
 	case NIX_ERR_NO_MEM:
 	case NPC_ERR_NO_MEM:
+	case RVU_ERR_NO_MEM:
 		err_msg = "Out of memory";
 		break;
 	case NIX_ERR_INVALID_RANGE:
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index 6f8a2e02da..9f7c804542 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -118,6 +118,9 @@  INTERNAL {
 	roc_idev_nix_rx_chan_set;
 	roc_idev_nix_rx_inject_get;
 	roc_idev_nix_rx_inject_set;
+	roc_idev_rvu_lf_free;
+	roc_idev_rvu_lf_get;
+	roc_idev_rvu_lf_set;
 	roc_ml_reg_read64;
 	roc_ml_reg_write64;
 	roc_ml_reg_read32;
@@ -543,5 +546,7 @@  INTERNAL {
 	roc_ree_rule_db_get;
 	roc_ree_rule_db_len_get;
 	roc_ree_rule_db_prog;
+	roc_rvu_lf_dev_fini;
+	roc_rvu_lf_dev_init;
 	local: *;
 };
diff --git a/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c
new file mode 100644
index 0000000000..36067909be
--- /dev/null
+++ b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.c
@@ -0,0 +1,123 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#include <bus_pci_driver.h>
+#include <rte_common.h>
+#include <dev_driver.h>
+#include <rte_eal.h>
+#include <rte_lcore.h>
+#include <rte_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include <roc_api.h>
+
+#include "cnxk_rvu_lf.h"
+
+static const struct rte_rawdev_ops rvu_lf_rawdev_ops = {
+	.dev_selftest = NULL,
+};
+
+static void
+rvu_lf_rawdev_get_name(char *name, struct rte_pci_device *pci_dev)
+{
+	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "RVU LF:%02x:%02x.%x",
+		 pci_dev->addr.bus, pci_dev->addr.devid,
+		 pci_dev->addr.function);
+}
+
+static int
+rvu_lf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
+{
+	char name[RTE_RAWDEV_NAME_MAX_LEN];
+	struct rte_rawdev *rvu_lf_rawdev;
+	struct roc_rvu_lf *roc_rvu_lf;
+	int ret;
+
+	RTE_SET_USED(pci_drv);
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	if (!pci_dev->mem_resource[2].addr) {
+		CNXK_RVU_LF_LOG(ERR, "BARs have invalid values: BAR0 %p\n BAR2 %p",
+			      pci_dev->mem_resource[2].addr, pci_dev->mem_resource[4].addr);
+		return -ENODEV;
+	}
+
+	ret = roc_plt_init();
+	if (ret)
+		return ret;
+
+	rvu_lf_rawdev_get_name(name, pci_dev);
+	rvu_lf_rawdev = rte_rawdev_pmd_allocate(name, sizeof(*roc_rvu_lf),
+					      rte_socket_id());
+	if (rvu_lf_rawdev == NULL) {
+		CNXK_RVU_LF_LOG(ERR, "Failed to allocate rawdev");
+		return -ENOMEM;
+	}
+
+	rvu_lf_rawdev->dev_ops = &rvu_lf_rawdev_ops;
+	rvu_lf_rawdev->device = &pci_dev->device;
+	rvu_lf_rawdev->driver_name = pci_dev->driver->driver.name;
+
+	roc_rvu_lf = (struct roc_rvu_lf *)rvu_lf_rawdev->dev_private;
+	roc_rvu_lf->pci_dev = pci_dev;
+
+	ret = roc_rvu_lf_dev_init(roc_rvu_lf);
+	if (ret) {
+		rte_rawdev_pmd_release(rvu_lf_rawdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+rvu_lf_remove(struct rte_pci_device *pci_dev)
+{
+	char name[RTE_RAWDEV_NAME_MAX_LEN];
+	struct roc_rvu_lf *roc_rvu_lf;
+	struct rte_rawdev *rawdev;
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	if (pci_dev == NULL) {
+		CNXK_RVU_LF_LOG(ERR, "invalid pci_dev");
+		return -EINVAL;
+	}
+
+	rvu_lf_rawdev_get_name(name, pci_dev);
+	rawdev = rte_rawdev_pmd_get_named_dev(name);
+	if (rawdev == NULL) {
+		CNXK_RVU_LF_LOG(ERR, "invalid device name (%s)", name);
+		return -EINVAL;
+	}
+
+	roc_rvu_lf = (struct roc_rvu_lf *)rawdev->dev_private;
+	roc_rvu_lf_dev_fini(roc_rvu_lf);
+
+	return rte_rawdev_pmd_release(rawdev);
+}
+
+static const struct rte_pci_id pci_rvu_lf_map[] = {
+	CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CNF20KA, PCI_DEVID_CNXK_RVU_BPHY_PF),
+	CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CNF20KA, PCI_DEVID_CNXK_RVU_BPHY_VF),
+	{
+		.vendor_id = 0,
+	},
+};
+
+static struct rte_pci_driver cnxk_rvu_lf_rawdev_pmd = {
+	.id_table = pci_rvu_lf_map,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
+	.probe = rvu_lf_probe,
+	.remove = rvu_lf_remove,
+};
+
+RTE_PMD_REGISTER_PCI(rvu_lf_rawdev_pci_driver, cnxk_rvu_lf_rawdev_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(rvu_lf_rawdev_pci_driver, pci_rvu_lf_map);
+RTE_PMD_REGISTER_KMOD_DEP(rvu_lf_rawdev_pci_driver, "vfio-pci");
+RTE_LOG_REGISTER_SUFFIX(cnxk_logtype_rvu_lf, rvu_lf, INFO);
diff --git a/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h
new file mode 100644
index 0000000000..a23a629500
--- /dev/null
+++ b/drivers/raw/cnxk_rvu_lf/cnxk_rvu_lf.h
@@ -0,0 +1,35 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2024 Marvell.
+ */
+
+#ifndef _CNXK_RVU_LF_H_
+#define _CNXK_RVU_LF_H_
+
+#include <stdint.h>
+
+#include <rte_common.h>
+
+/**
+ * @file cnxk_rvu_lf.h
+ *
+ * Marvell RVU LF raw PMD specific internal structures
+ *
+ * This API allows applications to manage RVU LF device in user space along with
+ * installing interrupt handlers for low latency signal processing.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int cnxk_logtype_rvu_lf;
+
+#define CNXK_RVU_LF_LOG(level, fmt, args...)	\
+	rte_log(RTE_LOG_ ## level, cnxk_logtype_rvu_lf, \
+		"%s(): " fmt "\n", __func__, ## args)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CNXK_RVU_LF_H_ */
diff --git a/drivers/raw/cnxk_rvu_lf/meson.build b/drivers/raw/cnxk_rvu_lf/meson.build
new file mode 100644
index 0000000000..32081e147f
--- /dev/null
+++ b/drivers/raw/cnxk_rvu_lf/meson.build
@@ -0,0 +1,9 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(C) 2024 Marvell.
+#
+
+deps += ['bus_pci', 'common_cnxk', 'rawdev']
+sources = files(
+        'cnxk_rvu_lf.c',
+)
+require_iova_in_mbuf = false
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index 05cad143fe..54221643d5 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -8,6 +8,7 @@  endif
 drivers = [
         'cnxk_bphy',
         'cnxk_gpio',
+        'cnxk_rvu_lf',
         'dpaa2_cmdif',
         'ifpga',
         'ntb',