@@ -1499,6 +1499,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/
new file mode 100644
@@ -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.
@@ -13,6 +13,7 @@ application through rawdev API.
cnxk_bphy
cnxk_gpio
+ cnxk_rvu_lf
dpaa2_cmdif
ifpga
ntb
@@ -71,6 +71,7 @@ sources = files(
'roc_tim_irq.c',
'roc_utils.c',
'roc_ree.c',
+ 'roc_rvu_lf.c',
)
# Security common code
@@ -120,4 +120,7 @@
/* Eswitch */
#include "roc_eswitch.h"
+/* RVU LF */
+#include "roc_rvu_lf.h"
+
#endif /* _ROC_API_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
@@ -106,6 +106,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;
@@ -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)
{
@@ -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_ */
@@ -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;
@@ -53,4 +53,6 @@
/* ML */
#include "roc_ml_priv.h"
+/* RVU LF */
+#include "roc_rvu_lf_priv.h"
#endif /* _ROC_PRIV_H_ */
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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_ */
new file mode 100644
@@ -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_ */
@@ -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:
@@ -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;
@@ -541,5 +544,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: *;
};
new file mode 100644
@@ -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 "rte_pmd_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_CN10KA, PCI_DEVID_CNXK_RVU_BPHY_PF),
+ CNXK_PCI_ID(PCI_SUBSYSTEM_DEVID_CN10KA, 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);
new file mode 100644
@@ -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
new file mode 100644
@@ -0,0 +1,39 @@
+/* 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>
+#include <rte_dev.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+
+/**
+ * @file rte_pmd_rvu_lf.h
+ *
+ * Marvell RVU LF raw PMD specific structures and interface
+ *
+ * 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_ */
@@ -8,6 +8,7 @@ endif
drivers = [
'cnxk_bphy',
'cnxk_gpio',
+ 'cnxk_rvu_lf',
'dpaa2_cmdif',
'ifpga',
'ntb',