Introduce virtual function driver in ngbe PMD, add simple init and
uninit function to probe and remove the device.

With this single patch, app/dpdk-testpmd can launch/quit normally
and recognize the VF 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    | 166 +++++++++++++++++++++++++++
 8 files changed, 223 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..26e2a331b1
--- /dev/null
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -0,0 +1,11 @@
+;
+; Supported features of the 'txgbe_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
\ No newline at end of file
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..4d3982b3c1
--- /dev/null
+++ b/drivers/net/ngbe/base/ngbe_vf.c
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 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..856fed261b
--- /dev/null
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -0,0 +1,166 @@
+/* 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_info_get(struct rte_eth_dev *dev,
+                                struct rte_eth_dev_info *dev_info);
+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

Reply via email to