Add the basic framework of vDPA PMD. Signed-off-by: Chaoyong He <chaoyong...@corigine.com> Signed-off-by: Shujing Dong <shujing.d...@corigine.com> Reviewed-by: Long Wu <long...@corigine.com> Reviewed-by: Peng Zhang <peng.zh...@corigine.com> --- drivers/common/nfp/nfp_common_pci.c | 1 + drivers/common/nfp/nfp_common_pci.h | 1 + drivers/vdpa/nfp/meson.build | 7 ++ drivers/vdpa/nfp/nfp_vdpa.c | 153 ++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 drivers/vdpa/nfp/nfp_vdpa.c
diff --git a/drivers/common/nfp/nfp_common_pci.c b/drivers/common/nfp/nfp_common_pci.c index 1aa8dd4bbd..c73f4888a9 100644 --- a/drivers/common/nfp/nfp_common_pci.c +++ b/drivers/common/nfp/nfp_common_pci.c @@ -32,6 +32,7 @@ static const struct { enum nfp_class drv_class; } nfp_classes[] = { { .name = "eth", .drv_class = NFP_CLASS_ETH }, + { .name = "vdpa", .drv_class = NFP_CLASS_VDPA }, }; static enum nfp_class diff --git a/drivers/common/nfp/nfp_common_pci.h b/drivers/common/nfp/nfp_common_pci.h index 21465fca68..80c027c3a5 100644 --- a/drivers/common/nfp/nfp_common_pci.h +++ b/drivers/common/nfp/nfp_common_pci.h @@ -16,6 +16,7 @@ typedef int (nfp_class_driver_remove_t)(struct rte_pci_device *dev); enum nfp_class { NFP_CLASS_ETH, + NFP_CLASS_VDPA, NFP_CLASS_INVALID, }; diff --git a/drivers/vdpa/nfp/meson.build b/drivers/vdpa/nfp/meson.build index b17866e157..e1cc244578 100644 --- a/drivers/vdpa/nfp/meson.build +++ b/drivers/vdpa/nfp/meson.build @@ -12,5 +12,12 @@ if not dpdk_conf.has('RTE_LIB_VHOST') endif sources = files( + 'nfp_vdpa.c', 'nfp_vdpa_log.c', ) + +deps += ['common_nfp'] + +if not dpdk_conf.has('RTE_COMMON_NFP') + error('Missing internal dependency "common/nfp"') +endif diff --git a/drivers/vdpa/nfp/nfp_vdpa.c b/drivers/vdpa/nfp/nfp_vdpa.c new file mode 100644 index 0000000000..ef4ae4946a --- /dev/null +++ b/drivers/vdpa/nfp/nfp_vdpa.c @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2023 Corigine, Inc. + * All rights reserved. + */ + +#include <pthread.h> + +#include <nfp_common_pci.h> +#include <nfp_dev.h> +#include <vdpa_driver.h> + +#include "nfp_vdpa_log.h" + +#define NFP_VDPA_DRIVER_NAME nfp_vdpa + +struct nfp_vdpa_dev { + struct rte_pci_device *pci_dev; + struct rte_vdpa_device *vdev; +}; + +struct nfp_vdpa_dev_node { + TAILQ_ENTRY(nfp_vdpa_dev_node) next; + struct nfp_vdpa_dev *device; +}; + +TAILQ_HEAD(vdpa_dev_list_head, nfp_vdpa_dev_node); + +static struct vdpa_dev_list_head vdpa_dev_list = + TAILQ_HEAD_INITIALIZER(vdpa_dev_list); + +static pthread_mutex_t vdpa_list_lock = PTHREAD_MUTEX_INITIALIZER; + +static struct nfp_vdpa_dev_node * +nfp_vdpa_find_node_by_pdev(struct rte_pci_device *pdev) +{ + bool found = false; + struct nfp_vdpa_dev_node *node; + + pthread_mutex_lock(&vdpa_list_lock); + + TAILQ_FOREACH(node, &vdpa_dev_list, next) { + if (pdev == node->device->pci_dev) { + found = true; + break; + } + } + + pthread_mutex_unlock(&vdpa_list_lock); + + if (found) + return node; + + return NULL; +} + +struct rte_vdpa_dev_ops nfp_vdpa_ops = { +}; + +static int +nfp_vdpa_pci_probe(struct rte_pci_device *pci_dev) +{ + struct nfp_vdpa_dev *device; + struct nfp_vdpa_dev_node *node; + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + node = calloc(1, sizeof(*node)); + if (node == NULL) + return -ENOMEM; + + device = calloc(1, sizeof(*device)); + if (device == NULL) + goto free_node; + + device->pci_dev = pci_dev; + + device->vdev = rte_vdpa_register_device(&pci_dev->device, &nfp_vdpa_ops); + if (device->vdev == NULL) { + DRV_VDPA_LOG(ERR, "Failed to register device %s", pci_dev->name); + goto free_device; + } + + node->device = device; + pthread_mutex_lock(&vdpa_list_lock); + TAILQ_INSERT_TAIL(&vdpa_dev_list, node, next); + pthread_mutex_unlock(&vdpa_list_lock); + + return 0; + +free_device: + free(device); +free_node: + free(node); + + return -1; +} + +static int +nfp_vdpa_pci_remove(struct rte_pci_device *pci_dev) +{ + struct nfp_vdpa_dev *device; + struct nfp_vdpa_dev_node *node; + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + node = nfp_vdpa_find_node_by_pdev(pci_dev); + if (node == NULL) { + DRV_VDPA_LOG(ERR, "Invalid device: %s", pci_dev->name); + return -ENODEV; + } + + device = node->device; + + pthread_mutex_lock(&vdpa_list_lock); + TAILQ_REMOVE(&vdpa_dev_list, node, next); + pthread_mutex_unlock(&vdpa_list_lock); + + rte_vdpa_unregister_device(device->vdev); + + free(device); + free(node); + + return 0; +} + +static const struct rte_pci_id pci_id_nfp_vdpa_map[] = { + { + RTE_PCI_DEVICE(PCI_VENDOR_ID_NETRONOME, + PCI_DEVICE_ID_NFP6000_VF_NIC) + }, + { + .vendor_id = 0, + }, +}; + +static struct nfp_class_driver nfp_vdpa = { + .drv_class = NFP_CLASS_VDPA, + .name = RTE_STR(NFP_VDPA_DRIVER_NAME), + .id_table = pci_id_nfp_vdpa_map, + .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, + .probe = nfp_vdpa_pci_probe, + .remove = nfp_vdpa_pci_remove, +}; + +RTE_INIT(nfp_vdpa_init) +{ + nfp_class_driver_register(&nfp_vdpa); +} + +RTE_PMD_REGISTER_PCI_TABLE(NFP_VDPA_DRIVER_NAME, pci_id_nfp_vdpa_map); +RTE_PMD_REGISTER_KMOD_DEP(NFP_VDPA_DRIVER_NAME, "* vfio-pci"); -- 2.39.1