Introduce virtual function driver in ngbe PMD, add simple init and uninit function to probe and remove the device.
Signed-off-by: Zaiyu Wang <zaiyuw...@trustnetic.com> --- doc/guides/nics/features/ngbe_vf.ini | 11 ++ drivers/net/ngbe/base/meson.build | 1 + drivers/net/ngbe/base/ngbe.h | 1 + drivers/net/ngbe/base/ngbe_hw.c | 4 + drivers/net/ngbe/base/ngbe_vf.c | 26 +++++ drivers/net/ngbe/base/ngbe_vf.h | 13 +++ drivers/net/ngbe/meson.build | 1 + drivers/net/ngbe/ngbe_ethdev_vf.c | 163 +++++++++++++++++++++++++++ 8 files changed, 220 insertions(+) create mode 100644 doc/guides/nics/features/ngbe_vf.ini create mode 100644 drivers/net/ngbe/base/ngbe_vf.c create mode 100644 drivers/net/ngbe/base/ngbe_vf.h create mode 100644 drivers/net/ngbe/ngbe_ethdev_vf.c diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini new file mode 100644 index 0000000000..4da36e0085 --- /dev/null +++ b/doc/guides/nics/features/ngbe_vf.ini @@ -0,0 +1,11 @@ +; +; Supported features of the 'ngbe_vf' network poll mode driver. +; +; Refer to default.ini for the full list of available PMD features. +; +[Features] +Multiprocess aware = Y +Linux = Y +ARMv8 = Y +x86-32 = Y +x86-64 = Y diff --git a/drivers/net/ngbe/base/meson.build b/drivers/net/ngbe/base/meson.build index 390b0f9c12..dd68100bf8 100644 --- a/drivers/net/ngbe/base/meson.build +++ b/drivers/net/ngbe/base/meson.build @@ -10,6 +10,7 @@ sources = [ 'ngbe_phy_rtl.c', 'ngbe_phy_mvl.c', 'ngbe_phy_yt.c', + 'ngbe_vf.c', ] error_cflags = [] diff --git a/drivers/net/ngbe/base/ngbe.h b/drivers/net/ngbe/base/ngbe.h index 1d17c2f115..da20829c40 100644 --- a/drivers/net/ngbe/base/ngbe.h +++ b/drivers/net/ngbe/base/ngbe.h @@ -11,5 +11,6 @@ #include "ngbe_eeprom.h" #include "ngbe_phy.h" #include "ngbe_hw.h" +#include "ngbe_vf.h" #endif /* _NGBE_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index 29944f5070..e29a1946e5 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -9,6 +9,7 @@ #include "ngbe_eeprom.h" #include "ngbe_mng.h" #include "ngbe_hw.h" +#include "ngbe_vf.h" static s32 ngbe_is_lldp(struct ngbe_hw *hw) { @@ -2113,6 +2114,9 @@ s32 ngbe_init_shared_code(struct ngbe_hw *hw) case ngbe_mac_em: ngbe_init_ops_pf(hw); break; + case ngbe_mac_em_vf: + ngbe_init_ops_vf(hw); + break; default: status = NGBE_ERR_DEVICE_NOT_SUPPORTED; break; diff --git a/drivers/net/ngbe/base/ngbe_vf.c b/drivers/net/ngbe/base/ngbe_vf.c new file mode 100644 index 0000000000..91b8d1bbe2 --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_vf.c @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2025 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#include "ngbe_type.h" +#include "ngbe_vf.h" + +/** + * ngbe_init_ops_vf - Initialize the pointers for vf + * @hw: pointer to hardware structure + * + * This will assign function pointers, adapter-specific functions can + * override the assignment of generic function pointers by assigning + * their own adapter-specific function pointers. + * Does not touch the hardware. + **/ +s32 ngbe_init_ops_vf(struct ngbe_hw *hw) +{ + struct ngbe_mac_info *mac = &hw->mac; + + mac->max_tx_queues = 1; + mac->max_rx_queues = 1; + + return 0; +} diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h new file mode 100644 index 0000000000..7982ea231e --- /dev/null +++ b/drivers/net/ngbe/base/ngbe_vf.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2025 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#ifndef _NGBE_VF_H_ +#define _NGBE_VF_H_ + +#include "ngbe_type.h" + +s32 ngbe_init_ops_vf(struct ngbe_hw *hw); + +#endif /* __NGBE_VF_H__ */ diff --git a/drivers/net/ngbe/meson.build b/drivers/net/ngbe/meson.build index 402cea1c13..f4f8f7ee79 100644 --- a/drivers/net/ngbe/meson.build +++ b/drivers/net/ngbe/meson.build @@ -15,6 +15,7 @@ sources = files( 'ngbe_ptypes.c', 'ngbe_pf.c', 'ngbe_rxtx.c', + 'ngbe_ethdev_vf.c', ) deps += ['hash'] diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c new file mode 100644 index 0000000000..164a97fac1 --- /dev/null +++ b/drivers/net/ngbe/ngbe_ethdev_vf.c @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018-2025 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation + */ + +#include <sys/queue.h> +#include <stdio.h> +#include <errno.h> +#include <stdint.h> +#include <string.h> +#include <ethdev_pci.h> + +#include "ngbe_logs.h" +#include "base/ngbe.h" +#include "ngbe_ethdev.h" +#include "ngbe_rxtx.h" +#include "ngbe_regs_group.h" + +#define NGBEVF_PMD_NAME "rte_ngbevf_pmd" /* PMD name */ +static int ngbevf_dev_close(struct rte_eth_dev *dev); + +/* + * The set of PCI devices this driver supports (for VF) + */ +static const struct rte_pci_id pci_id_ngbevf_map[] = { + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL_W_VF) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A2_VF) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A2S_VF) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A4_VF) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A4S_VF) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL2_VF) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL2S_VF) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL4_VF) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL4S_VF) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860NCSI_VF) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A1_VF) }, + { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A1L_VF) }, + { .vendor_id = 0, /* sentinel */ }, +}; + +static const struct eth_dev_ops ngbevf_eth_dev_ops; + +/* + * Virtual Function device init + */ +static int +eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev) +{ + int err; + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); + struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); + + PMD_INIT_FUNC_TRACE(); + + eth_dev->dev_ops = &ngbevf_eth_dev_ops; + + rte_eth_copy_pci_info(eth_dev, pci_dev); + + hw->device_id = pci_dev->id.device_id; + hw->vendor_id = pci_dev->id.vendor_id; + hw->sub_system_id = pci_dev->id.subsystem_device_id; + ngbe_map_device_id(hw); + hw->hw_addr = (void *)pci_dev->mem_resource[0].addr; + + /* Initialize the shared code (base driver) */ + err = ngbe_init_shared_code(hw); + if (err != 0) { + PMD_INIT_LOG(ERR, + "Shared code init failed for ngbevf: %d", err); + return -EIO; + } + + hw->mac.num_rar_entries = 32; /* The MAX of the underlying PF */ + + /* Allocate memory for storing MAC addresses */ + eth_dev->data->mac_addrs = rte_zmalloc("ngbevf", RTE_ETHER_ADDR_LEN * + hw->mac.num_rar_entries, 0); + if (eth_dev->data->mac_addrs == NULL) { + PMD_INIT_LOG(ERR, + "Failed to allocate %u bytes needed to store MAC addresses", + RTE_ETHER_ADDR_LEN * hw->mac.num_rar_entries); + return -ENOMEM; + } + + PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x mac.type=%s", + eth_dev->data->port_id, pci_dev->id.vendor_id, + pci_dev->id.device_id, "ngbe_mac_sp_vf"); + + return 0; +} + +/* Virtual Function device uninit */ +static int +eth_ngbevf_dev_uninit(struct rte_eth_dev *eth_dev) +{ + PMD_INIT_FUNC_TRACE(); + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + ngbevf_dev_close(eth_dev); + + return 0; +} + +static int eth_ngbevf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, + struct rte_pci_device *pci_dev) +{ + return rte_eth_dev_pci_generic_probe(pci_dev, + sizeof(struct ngbe_adapter), eth_ngbevf_dev_init); +} + +static int eth_ngbevf_pci_remove(struct rte_pci_device *pci_dev) +{ + return rte_eth_dev_pci_generic_remove(pci_dev, eth_ngbevf_dev_uninit); +} + +/* + * virtual function driver struct + */ +static struct rte_pci_driver rte_ngbevf_pmd = { + .id_table = pci_id_ngbevf_map, + .drv_flags = RTE_PCI_DRV_NEED_MAPPING, + .probe = eth_ngbevf_pci_probe, + .remove = eth_ngbevf_pci_remove, +}; + +static int +ngbevf_dev_info_get(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + + dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues; + dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues; + + return 0; +} + +static int +ngbevf_dev_close(struct rte_eth_dev *dev) +{ + PMD_INIT_FUNC_TRACE(); + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + rte_free(dev->data->mac_addrs); + dev->data->mac_addrs = NULL; + + return 0; +} + +/* + * dev_ops for virtual function, bare necessities for basic vf + * operation have been implemented + */ +static const struct eth_dev_ops ngbevf_eth_dev_ops = { + .dev_infos_get = ngbevf_dev_info_get, +}; + +RTE_PMD_REGISTER_PCI(net_ngbe_vf, rte_ngbevf_pmd); +RTE_PMD_REGISTER_PCI_TABLE(net_ngbe_vf, pci_id_ngbevf_map); +RTE_PMD_REGISTER_KMOD_DEP(net_ngbe_vf, "* igb_uio | vfio-pci"); -- 2.21.0.windows.1