* [PATCH 00/15] net/ngbe: add VF driver support
@ 2025-01-09 4:02 Zaiyu Wang
2025-01-09 4:02 ` [PATCH 01/15] net/ngbe: add ethdev probe and remove for VF device Zaiyu Wang
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang
This patch adds support to VF device for ngbe PMD
Zaiyu Wang (15):
net/ngbe: add ethdev probe and remove for VF device
net/ngbe: add support for PF-VF mailbox interface
net/ngbe: add hardware configuration code for VF device
net/ngbe: add promiscuous and allmulticast ops for VF device
net/ngbe: add set MTU ops for VF device
net/ngbe: add add/remove/set mac addr ops for VF device
net/ngbe: add datapath init code for VF device
net/ngbe: add vlan related ops for VF device
net/ngbe: add interrupt support for VF device
net/ngbe: add link update ops for VF device
net/ngbe: add stats and xstats ops for VF device
net/ngbe: add start/stop/reset/close ops for VF device
net/ngbe: add multicast MAC filter ops for VF device
net/ngbe: add dump registers ops for VF device
net/ngbe: add some ops which PF has implemented
doc/guides/nics/features/ngbe_vf.ini | 38 +
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_mbx.c | 338 +++++++
drivers/net/ngbe/base/ngbe_mbx.h | 31 +
drivers/net/ngbe/base/ngbe_type.h | 15 +
drivers/net/ngbe/base/ngbe_vf.c | 669 +++++++++++++
drivers/net/ngbe/base/ngbe_vf.h | 68 ++
drivers/net/ngbe/meson.build | 1 +
drivers/net/ngbe/ngbe_ethdev.h | 6 +
drivers/net/ngbe/ngbe_ethdev_vf.c | 1351 ++++++++++++++++++++++++++
drivers/net/ngbe/ngbe_rxtx.c | 210 ++++
13 files changed, 2733 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
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 01/15] net/ngbe: add ethdev probe and remove for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 02/15] net/ngbe: add support for PF-VF mailbox interface Zaiyu Wang
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu, Anatoly Burakov
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 <zaiyuwang@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
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 02/15] net/ngbe: add support for PF-VF mailbox interface
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
2025-01-09 4:02 ` [PATCH 01/15] net/ngbe: add ethdev probe and remove for VF device Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 03/15] net/ngbe: add hardware configuration code for VF device Zaiyu Wang
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Add basic code to serve the communication between VF and PF devices.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/ngbe/base/ngbe_mbx.c | 338 ++++++++++++++++++++++++++++++
drivers/net/ngbe/base/ngbe_mbx.h | 29 +++
drivers/net/ngbe/base/ngbe_type.h | 7 +
drivers/net/ngbe/base/ngbe_vf.c | 56 +++++
drivers/net/ngbe/base/ngbe_vf.h | 1 +
5 files changed, 431 insertions(+)
diff --git a/drivers/net/ngbe/base/ngbe_mbx.c b/drivers/net/ngbe/base/ngbe_mbx.c
index bc0adbb3ec..a96a4aced7 100644
--- a/drivers/net/ngbe/base/ngbe_mbx.c
+++ b/drivers/net/ngbe/base/ngbe_mbx.c
@@ -109,6 +109,344 @@ s32 ngbe_check_for_rst(struct ngbe_hw *hw, u16 mbx_id)
return ret_val;
}
+/**
+ * ngbe_poll_for_msg - Wait for message notification
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message notification
+ **/
+STATIC s32 ngbe_poll_for_msg(struct ngbe_hw *hw, u16 mbx_id)
+{
+ struct ngbe_mbx_info *mbx = &hw->mbx;
+ int countdown = mbx->timeout;
+
+ if (!countdown || !mbx->check_for_msg)
+ goto out;
+
+ while (countdown && mbx->check_for_msg(hw, mbx_id)) {
+ countdown--;
+ if (!countdown)
+ break;
+ usec_delay(mbx->usec_delay);
+ }
+
+ if (countdown == 0)
+ DEBUGOUT("Polling for VF%d mailbox message timedout", mbx_id);
+
+out:
+ return countdown ? 0 : NGBE_ERR_MBX;
+}
+
+/**
+ * ngbe_poll_for_ack - Wait for message acknowledgment
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message acknowledgment
+ **/
+STATIC s32 ngbe_poll_for_ack(struct ngbe_hw *hw, u16 mbx_id)
+{
+ struct ngbe_mbx_info *mbx = &hw->mbx;
+ int countdown = mbx->timeout;
+
+ if (!countdown || !mbx->check_for_ack)
+ goto out;
+
+ while (countdown && mbx->check_for_ack(hw, mbx_id)) {
+ countdown--;
+ if (!countdown)
+ break;
+ usec_delay(mbx->usec_delay);
+ }
+
+ if (countdown == 0)
+ DEBUGOUT("Polling for VF%d mailbox ack timedout", mbx_id);
+
+out:
+ return countdown ? 0 : NGBE_ERR_MBX;
+}
+
+/**
+ * ngbe_read_posted_mbx - Wait for message notification and receive message
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message notification and
+ * copied it into the receive buffer.
+ **/
+s32 ngbe_read_posted_mbx(struct ngbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+ struct ngbe_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = NGBE_ERR_MBX;
+
+ if (!mbx->read)
+ goto out;
+
+ ret_val = ngbe_poll_for_msg(hw, mbx_id);
+
+ /* if ack received read message, otherwise we timed out */
+ if (!ret_val)
+ ret_val = mbx->read(hw, msg, size, mbx_id);
+out:
+ return ret_val;
+}
+
+/**
+ * ngbe_write_posted_mbx - Write a message to the mailbox, wait for ack
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully copied message into the buffer and
+ * received an ack to that message within delay * timeout period
+ **/
+s32 ngbe_write_posted_mbx(struct ngbe_hw *hw, u32 *msg, u16 size,
+ u16 mbx_id)
+{
+ struct ngbe_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = NGBE_ERR_MBX;
+
+ /* exit if either we can't write or there isn't a defined timeout */
+ if (!mbx->write || !mbx->timeout)
+ goto out;
+
+ /* send msg */
+ ret_val = mbx->write(hw, msg, size, mbx_id);
+
+ /* if msg sent wait until we receive an ack */
+ if (!ret_val)
+ ret_val = ngbe_poll_for_ack(hw, mbx_id);
+out:
+ return ret_val;
+}
+
+/**
+ * ngbe_read_v2p_mailbox - read v2p mailbox
+ * @hw: pointer to the HW structure
+ *
+ * This function is used to read the v2p mailbox without losing the read to
+ * clear status bits.
+ **/
+STATIC u32 ngbe_read_v2p_mailbox(struct ngbe_hw *hw)
+{
+ u32 v2p_mailbox = rd32(hw, NGBE_VFMBCTL);
+
+ v2p_mailbox |= hw->mbx.v2p_mailbox;
+ hw->mbx.v2p_mailbox |= v2p_mailbox & NGBE_VFMBCTL_R2C_BITS;
+
+ return v2p_mailbox;
+}
+
+/**
+ * ngbe_check_for_bit_vf - Determine if a status bit was set
+ * @hw: pointer to the HW structure
+ * @mask: bitmask for bits to be tested and cleared
+ *
+ * This function is used to check for the read to clear bits within
+ * the V2P mailbox.
+ **/
+STATIC s32 ngbe_check_for_bit_vf(struct ngbe_hw *hw, u32 mask)
+{
+ u32 v2p_mailbox = ngbe_read_v2p_mailbox(hw);
+ s32 ret_val = NGBE_ERR_MBX;
+
+ if (v2p_mailbox & mask)
+ ret_val = 0;
+
+ hw->mbx.v2p_mailbox &= ~mask;
+
+ return ret_val;
+}
+
+/**
+ * ngbe_check_for_msg_vf - checks to see if the PF has sent mail
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to check
+ *
+ * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
+ **/
+s32 ngbe_check_for_msg_vf(struct ngbe_hw *hw, u16 mbx_id)
+{
+ s32 ret_val = NGBE_ERR_MBX;
+
+ UNREFERENCED_PARAMETER(mbx_id);
+
+ if (!ngbe_check_for_bit_vf(hw, NGBE_VFMBCTL_PFSTS)) {
+ ret_val = 0;
+ hw->mbx.stats.reqs++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * ngbe_check_for_ack_vf - checks to see if the PF has ACK'd
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to check
+ *
+ * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
+ **/
+s32 ngbe_check_for_ack_vf(struct ngbe_hw *hw, u16 mbx_id)
+{
+ s32 ret_val = NGBE_ERR_MBX;
+
+ UNREFERENCED_PARAMETER(mbx_id);
+
+ if (!ngbe_check_for_bit_vf(hw, NGBE_VFMBCTL_PFACK)) {
+ ret_val = 0;
+ hw->mbx.stats.acks++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * ngbe_check_for_rst_vf - checks to see if the PF has reset
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to check
+ *
+ * returns true if the PF has set the reset done bit or else false
+ **/
+s32 ngbe_check_for_rst_vf(struct ngbe_hw *hw, u16 mbx_id)
+{
+ s32 ret_val = NGBE_ERR_MBX;
+
+ UNREFERENCED_PARAMETER(mbx_id);
+
+ if (!ngbe_check_for_bit_vf(hw, (NGBE_VFMBCTL_RSTD |
+ NGBE_VFMBCTL_RSTI))) {
+ ret_val = 0;
+ hw->mbx.stats.rsts++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * ngbe_obtain_mbx_lock_vf - obtain mailbox lock
+ * @hw: pointer to the HW structure
+ *
+ * return SUCCESS if we obtained the mailbox lock
+ **/
+STATIC s32 ngbe_obtain_mbx_lock_vf(struct ngbe_hw *hw)
+{
+ s32 ret_val = NGBE_ERR_MBX;
+
+ /* Take ownership of the buffer */
+ wr32(hw, NGBE_VFMBCTL, NGBE_VFMBCTL_VFU);
+
+ /* reserve mailbox for vf use */
+ if (ngbe_read_v2p_mailbox(hw) & NGBE_VFMBCTL_VFU)
+ ret_val = 0;
+
+ return ret_val;
+}
+
+/**
+ * ngbe_write_mbx_vf - Write a message to the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully copied message into the buffer
+ **/
+s32 ngbe_write_mbx_vf(struct ngbe_hw *hw, u32 *msg, u16 size,
+ u16 mbx_id)
+{
+ s32 ret_val;
+ u16 i;
+
+ UNREFERENCED_PARAMETER(mbx_id);
+
+ /* lock the mailbox to prevent pf/vf race condition */
+ ret_val = ngbe_obtain_mbx_lock_vf(hw);
+ if (ret_val)
+ goto out_no_write;
+
+ /* flush msg and acks as we are overwriting the message buffer */
+ ngbe_check_for_msg_vf(hw, 0);
+ ngbe_check_for_ack_vf(hw, 0);
+
+ /* copy the caller specified message to the mailbox memory buffer */
+ for (i = 0; i < size; i++)
+ wr32a(hw, NGBE_VFMBX, i, msg[i]);
+
+ /* update stats */
+ hw->mbx.stats.msgs_tx++;
+
+ /* Drop VFU and interrupt the PF to tell it a message has been sent */
+ wr32(hw, NGBE_VFMBCTL, NGBE_VFMBCTL_REQ);
+
+out_no_write:
+ return ret_val;
+}
+
+/**
+ * ngbe_read_mbx_vf - Reads a message from the inbox intended for vf
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to read
+ *
+ * returns SUCCESS if it successfully read message from buffer
+ **/
+s32 ngbe_read_mbx_vf(struct ngbe_hw *hw, u32 *msg, u16 size,
+ u16 mbx_id)
+{
+ s32 ret_val = 0;
+ u16 i;
+
+ UNREFERENCED_PARAMETER(mbx_id);
+
+ /* lock the mailbox to prevent pf/vf race condition */
+ ret_val = ngbe_obtain_mbx_lock_vf(hw);
+ if (ret_val)
+ goto out_no_read;
+
+ /* copy the message from the mailbox memory buffer */
+ for (i = 0; i < size; i++)
+ msg[i] = rd32a(hw, NGBE_VFMBX, i);
+
+ /* Acknowledge receipt and release mailbox, then we're done */
+ wr32(hw, NGBE_VFMBCTL, NGBE_VFMBCTL_ACK);
+
+ /* update stats */
+ hw->mbx.stats.msgs_rx++;
+
+out_no_read:
+ return ret_val;
+}
+
+/**
+ * ngbe_init_mbx_params_vf - set initial values for vf mailbox
+ * @hw: pointer to the HW structure
+ *
+ * Initializes the hw->mbx struct to correct values for vf mailbox
+ */
+void ngbe_init_mbx_params_vf(struct ngbe_hw *hw)
+{
+ struct ngbe_mbx_info *mbx = &hw->mbx;
+
+ /* start mailbox as timed out and let the reset_hw call set the timeout
+ * value to begin communications
+ */
+ mbx->timeout = 0;
+ mbx->usec_delay = NGBE_VF_MBX_INIT_DELAY;
+
+ mbx->size = NGBE_P2VMBX_SIZE;
+
+ mbx->stats.msgs_tx = 0;
+ mbx->stats.msgs_rx = 0;
+ mbx->stats.reqs = 0;
+ mbx->stats.acks = 0;
+ mbx->stats.rsts = 0;
+}
+
STATIC s32 ngbe_check_for_bit_pf(struct ngbe_hw *hw, u32 mask)
{
u32 mbvficr = rd32(hw, NGBE_MBVFICR);
diff --git a/drivers/net/ngbe/base/ngbe_mbx.h b/drivers/net/ngbe/base/ngbe_mbx.h
index d47da2718c..83561fd4cf 100644
--- a/drivers/net/ngbe/base/ngbe_mbx.h
+++ b/drivers/net/ngbe/base/ngbe_mbx.h
@@ -73,11 +73,34 @@ enum ngbevf_xcast_modes {
/* length of permanent address message returned from PF */
#define NGBE_VF_PERMADDR_MSG_LEN 4
+/* word in permanent address message with the current multicast type */
+#define NGBE_VF_MC_TYPE_WORD 3
+
+#define NGBE_PF_CONTROL_MSG 0x0100 /* PF control message */
+
+/* mailbox API, version 2.0 VF requests */
+#define NGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */
+#define NGBE_VF_GET_QUEUES 0x09 /* get queue configuration */
+#define NGBE_VF_ENABLE_MACADDR 0x0A /* enable MAC address */
+#define NGBE_VF_DISABLE_MACADDR 0x0B /* disable MAC address */
+#define NGBE_VF_GET_MACADDRS 0x0C /* get all configured MAC addrs */
+#define NGBE_VF_SET_MCAST_PROMISC 0x0D /* enable multicast promiscuous */
+#define NGBE_VF_GET_MTU 0x0E /* get bounds on MTU */
+#define NGBE_VF_SET_MTU 0x0F /* set a specific MTU */
+
+/* mailbox API, version 2.0 PF requests */
+#define NGBE_PF_TRANSPARENT_VLAN 0x0101 /* enable transparent vlan */
+
+#define NGBE_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */
+#define NGBE_VF_MBX_INIT_DELAY 500 /* microseconds between retries */
s32 ngbe_read_mbx(struct ngbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 ngbe_write_mbx(struct ngbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
+s32 ngbe_read_posted_mbx(struct ngbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
+s32 ngbe_write_posted_mbx(struct ngbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
s32 ngbe_check_for_msg(struct ngbe_hw *hw, u16 mbx_id);
s32 ngbe_check_for_ack(struct ngbe_hw *hw, u16 mbx_id);
s32 ngbe_check_for_rst(struct ngbe_hw *hw, u16 mbx_id);
+void ngbe_init_mbx_params_vf(struct ngbe_hw *hw);
void ngbe_init_mbx_params_pf(struct ngbe_hw *hw);
s32 ngbe_read_mbx_pf(struct ngbe_hw *hw, u32 *msg, u16 size, u16 vf_number);
@@ -86,4 +109,10 @@ s32 ngbe_check_for_msg_pf(struct ngbe_hw *hw, u16 vf_number);
s32 ngbe_check_for_ack_pf(struct ngbe_hw *hw, u16 vf_number);
s32 ngbe_check_for_rst_pf(struct ngbe_hw *hw, u16 vf_number);
+s32 ngbe_read_mbx_vf(struct ngbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
+s32 ngbe_write_mbx_vf(struct ngbe_hw *hw, u32 *msg, u16 size, u16 mbx_id);
+s32 ngbe_check_for_msg_vf(struct ngbe_hw *hw, u16 mbx_id);
+s32 ngbe_check_for_ack_vf(struct ngbe_hw *hw, u16 mbx_id);
+s32 ngbe_check_for_rst_vf(struct ngbe_hw *hw, u16 mbx_id);
+
#endif /* _NGBE_MBX_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h
index a987bbe25b..35ebb7208a 100644
--- a/drivers/net/ngbe/base/ngbe_type.h
+++ b/drivers/net/ngbe/base/ngbe_type.h
@@ -311,6 +311,7 @@ struct ngbe_mac_info {
s32 (*enable_sec_rx_path)(struct ngbe_hw *hw);
s32 (*acquire_swfw_sync)(struct ngbe_hw *hw, u32 mask);
void (*release_swfw_sync)(struct ngbe_hw *hw, u32 mask);
+ s32 (*negotiate_api_version)(struct ngbe_hw *hw, int api);
/* Link */
s32 (*setup_link)(struct ngbe_hw *hw, u32 speed,
@@ -422,6 +423,10 @@ struct ngbe_mbx_info {
void (*init_params)(struct ngbe_hw *hw);
s32 (*read)(struct ngbe_hw *hw, u32 *msg, u16 size, u16 vf_number);
s32 (*write)(struct ngbe_hw *hw, u32 *msg, u16 size, u16 vf_number);
+ s32 (*read_posted)(struct ngbe_hw *hw, u32 *msg, u16 size,
+ u16 mbx_id);
+ s32 (*write_posted)(struct ngbe_hw *hw, u32 *msg, u16 size,
+ u16 mbx_id);
s32 (*check_for_msg)(struct ngbe_hw *hw, u16 mbx_id);
s32 (*check_for_ack)(struct ngbe_hw *hw, u16 mbx_id);
s32 (*check_for_rst)(struct ngbe_hw *hw, u16 mbx_id);
@@ -429,6 +434,7 @@ struct ngbe_mbx_info {
struct ngbe_mbx_stats stats;
u32 timeout;
u32 usec_delay;
+ u32 v2p_mailbox;
u16 size;
};
@@ -458,6 +464,7 @@ struct ngbe_hw {
u8 port_id;
u8 revision_id;
bool adapter_stopped;
+ int api_version;
bool wol_enabled;
bool ncsi_enabled;
bool lldp_enabled;
diff --git a/drivers/net/ngbe/base/ngbe_vf.c b/drivers/net/ngbe/base/ngbe_vf.c
index 4d3982b3c1..c3bffe70fd 100644
--- a/drivers/net/ngbe/base/ngbe_vf.c
+++ b/drivers/net/ngbe/base/ngbe_vf.c
@@ -4,8 +4,52 @@
*/
#include "ngbe_type.h"
+#include "ngbe_mbx.h"
#include "ngbe_vf.h"
+STATIC s32 ngbevf_write_msg_read_ack(struct ngbe_hw *hw, u32 *msg,
+ u32 *retmsg, u16 size)
+{
+ struct ngbe_mbx_info *mbx = &hw->mbx;
+ s32 retval = mbx->write_posted(hw, msg, size, 0);
+
+ if (retval)
+ return retval;
+
+ return mbx->read_posted(hw, retmsg, size, 0);
+}
+
+/**
+ * ngbevf_negotiate_api_version - Negotiate supported API version
+ * @hw: pointer to the HW structure
+ * @api: integer containing requested API version
+ **/
+int ngbevf_negotiate_api_version(struct ngbe_hw *hw, int api)
+{
+ int err;
+ u32 msg[3];
+
+ /* Negotiate the mailbox API version */
+ msg[0] = NGBE_VF_API_NEGOTIATE;
+ msg[1] = api;
+ msg[2] = 0;
+
+ err = ngbevf_write_msg_read_ack(hw, msg, msg, 3);
+ if (!err) {
+ msg[0] &= ~NGBE_VT_MSGTYPE_CTS;
+
+ /* Store value and return 0 on success */
+ if (msg[0] == (NGBE_VF_API_NEGOTIATE | NGBE_VT_MSGTYPE_ACK)) {
+ hw->api_version = api;
+ return 0;
+ }
+
+ err = NGBE_ERR_INVALID_ARGUMENT;
+ }
+
+ return err;
+}
+
/**
* ngbe_init_ops_vf - Initialize the pointers for vf
* @hw: pointer to hardware structure
@@ -18,9 +62,21 @@
s32 ngbe_init_ops_vf(struct ngbe_hw *hw)
{
struct ngbe_mac_info *mac = &hw->mac;
+ struct ngbe_mbx_info *mbx = &hw->mbx;
+
+ mac->negotiate_api_version = ngbevf_negotiate_api_version;
mac->max_tx_queues = 1;
mac->max_rx_queues = 1;
+ mbx->init_params = ngbe_init_mbx_params_vf;
+ mbx->read = ngbe_read_mbx_vf;
+ mbx->write = ngbe_write_mbx_vf;
+ mbx->read_posted = ngbe_read_posted_mbx;
+ mbx->write_posted = ngbe_write_posted_mbx;
+ mbx->check_for_msg = ngbe_check_for_msg_vf;
+ mbx->check_for_ack = ngbe_check_for_ack_vf;
+ mbx->check_for_rst = ngbe_check_for_rst_vf;
+
return 0;
}
diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h
index 7982ea231e..23e5b0d8a3 100644
--- a/drivers/net/ngbe/base/ngbe_vf.h
+++ b/drivers/net/ngbe/base/ngbe_vf.h
@@ -9,5 +9,6 @@
#include "ngbe_type.h"
s32 ngbe_init_ops_vf(struct ngbe_hw *hw);
+int ngbevf_negotiate_api_version(struct ngbe_hw *hw, int api);
#endif /* __NGBE_VF_H__ */
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 03/15] net/ngbe: add hardware configuration code for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
2025-01-09 4:02 ` [PATCH 01/15] net/ngbe: add ethdev probe and remove for VF device Zaiyu Wang
2025-01-09 4:02 ` [PATCH 02/15] net/ngbe: add support for PF-VF mailbox interface Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 04/15] net/ngbe: add promiscuous and allmulticast ops " Zaiyu Wang
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Add basic hardware configure flow and device information statement.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
doc/guides/nics/features/ngbe_vf.ini | 7 +
drivers/net/ngbe/base/ngbe_mbx.h | 2 +
drivers/net/ngbe/base/ngbe_type.h | 5 +
drivers/net/ngbe/base/ngbe_vf.c | 235 +++++++++++++++++++++++++++
drivers/net/ngbe/base/ngbe_vf.h | 9 +
drivers/net/ngbe/ngbe_ethdev_vf.c | 114 +++++++++++++
6 files changed, 372 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index 26e2a331b1..b3d86e65ae 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -4,6 +4,13 @@
; Refer to default.ini for the full list of available PMD features.
;
[Features]
+CRC offload = P
+VLAN offload = P
+QinQ offload = P
+L3 checksum offload = P
+L4 checksum offload = P
+Inner L3 checksum = P
+Inner L4 checksum = P
Multiprocess aware = Y
Linux = Y
ARMv8 = Y
diff --git a/drivers/net/ngbe/base/ngbe_mbx.h b/drivers/net/ngbe/base/ngbe_mbx.h
index 83561fd4cf..27e977737d 100644
--- a/drivers/net/ngbe/base/ngbe_mbx.h
+++ b/drivers/net/ngbe/base/ngbe_mbx.h
@@ -57,6 +57,8 @@ enum ngbe_pfvf_api_rev {
#define NGBE_VF_GET_RSS_KEY 0x0b /* get RSS key */
#define NGBE_VF_UPDATE_XCAST_MODE 0x0c
+#define NGBE_VF_BACKUP 0x8001 /* VF requests backup */
+
/* mode choices for NGBE_VF_UPDATE_XCAST_MODE */
enum ngbevf_xcast_modes {
NGBEVF_XCAST_MODE_NONE = 0,
diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h
index 35ebb7208a..4fd7080847 100644
--- a/drivers/net/ngbe/base/ngbe_type.h
+++ b/drivers/net/ngbe/base/ngbe_type.h
@@ -8,6 +8,9 @@
#define NGBE_LINK_UP_TIME 90 /* 9.0 Seconds */
+#define NGBE_RX_HDR_SIZE 256
+#define NGBE_RX_BUF_SIZE 2048
+
#define NGBE_FRAME_SIZE_MAX (9728) /* Maximum frame size, +FCS */
#define NGBE_FRAME_SIZE_DFT (1518) /* Default frame size, +FCS */
#define NGBE_NUM_POOL (32)
@@ -17,6 +20,7 @@
#define NGBE_MAX_QP (8)
#define NGBE_MAX_UTA 128
+#define NGBE_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */
#define NGBE_PCI_MASTER_DISABLE_TIMEOUT 800
#define NGBE_SPI_TIMEOUT 10000
@@ -480,6 +484,7 @@ struct ngbe_hw {
u32 q_tx_regs[8 * 4];
u32 gphy_efuse[2];
bool offset_loaded;
+ bool rx_loaded;
bool is_pf;
bool gpio_ctl;
bool lsc;
diff --git a/drivers/net/ngbe/base/ngbe_vf.c b/drivers/net/ngbe/base/ngbe_vf.c
index c3bffe70fd..41684a2e50 100644
--- a/drivers/net/ngbe/base/ngbe_vf.c
+++ b/drivers/net/ngbe/base/ngbe_vf.c
@@ -7,6 +7,178 @@
#include "ngbe_mbx.h"
#include "ngbe_vf.h"
+/* ngbe_virt_clr_reg - Set register to default (power on) state.
+ * @hw: pointer to hardware structure
+ */
+static void ngbe_virt_clr_reg(struct ngbe_hw *hw)
+{
+ u32 vfsrrctl;
+
+ /* default values (BUF_SIZE = 2048, HDR_SIZE = 256) */
+ vfsrrctl = NGBE_RXCFG_HDRLEN(NGBE_RX_HDR_SIZE);
+ vfsrrctl |= NGBE_RXCFG_PKTLEN(NGBE_RX_BUF_SIZE);
+
+ wr32m(hw, NGBE_RXCFG(0),
+ (NGBE_RXCFG_HDRLEN_MASK | NGBE_RXCFG_PKTLEN_MASK),
+ vfsrrctl);
+
+
+ ngbe_flush(hw);
+}
+
+/**
+ * ngbe_start_hw_vf - Prepare hardware for Tx/Rx
+ * @hw: pointer to hardware structure
+ *
+ * Starts the hardware by filling the bus info structure and media type, clears
+ * all on chip counters, initializes receive address registers, multicast
+ * table, VLAN filter table, calls routine to set up link and flow control
+ * settings, and leaves transmit and receive units disabled and uninitialized
+ **/
+s32 ngbe_start_hw_vf(struct ngbe_hw *hw)
+{
+ /* Clear adapter stopped flag */
+ hw->adapter_stopped = false;
+
+ return 0;
+}
+
+/**
+ * ngbe_init_hw_vf - virtual function hardware initialization
+ * @hw: pointer to hardware structure
+ *
+ * Initialize the hardware by resetting the hardware and then starting
+ * the hardware
+ **/
+s32 ngbe_init_hw_vf(struct ngbe_hw *hw)
+{
+ s32 status = hw->mac.start_hw(hw);
+
+ hw->mac.get_mac_addr(hw, hw->mac.addr);
+
+ return status;
+}
+
+/**
+ * ngbe_reset_hw_vf - Performs hardware reset
+ * @hw: pointer to hardware structure
+ *
+ * Resets the hardware by resetting the transmit and receive units, masks and
+ * clears all interrupts.
+ **/
+s32 ngbe_reset_hw_vf(struct ngbe_hw *hw)
+{
+ struct ngbe_mbx_info *mbx = &hw->mbx;
+ u32 timeout = NGBE_VF_INIT_TIMEOUT;
+ s32 ret_val = NGBE_ERR_INVALID_MAC_ADDR;
+ u32 msgbuf[NGBE_VF_PERMADDR_MSG_LEN];
+ u8 *addr = (u8 *)(&msgbuf[1]);
+
+ /* Call adapter stop to disable tx/rx and clear interrupts */
+ hw->mac.stop_hw(hw);
+
+ /* reset the api version */
+ hw->api_version = ngbe_mbox_api_10;
+
+ /* backup msix vectors */
+ mbx->timeout = NGBE_VF_MBX_INIT_TIMEOUT;
+ msgbuf[0] = NGBE_VF_BACKUP;
+ mbx->write_posted(hw, msgbuf, 1, 0);
+ msec_delay(10);
+
+ DEBUGOUT("Issuing a function level reset to MAC");
+ wr32(hw, NGBE_VFRST, NGBE_VFRST_SET);
+ ngbe_flush(hw);
+ msec_delay(50);
+
+ hw->offset_loaded = 1;
+
+ /* we cannot reset while the RSTI / RSTD bits are asserted */
+ while (!mbx->check_for_rst(hw, 0) && timeout) {
+ timeout--;
+ usec_delay(5);
+ }
+
+ if (!timeout)
+ return NGBE_ERR_RESET_FAILED;
+
+ /* Reset VF registers to initial values */
+ ngbe_virt_clr_reg(hw);
+
+ /* mailbox timeout can now become active */
+ mbx->timeout = NGBE_VF_MBX_INIT_TIMEOUT;
+
+ msgbuf[0] = NGBE_VF_RESET;
+ mbx->write_posted(hw, msgbuf, 1, 0);
+
+ msec_delay(10);
+
+ /*
+ * set our "perm_addr" based on info provided by PF
+ * also set up the mc_filter_type which is piggy backed
+ * on the mac address in word 3
+ */
+ ret_val = mbx->read_posted(hw, msgbuf,
+ NGBE_VF_PERMADDR_MSG_LEN, 0);
+ if (ret_val)
+ return ret_val;
+
+ if (msgbuf[0] != (NGBE_VF_RESET | NGBE_VT_MSGTYPE_ACK) &&
+ msgbuf[0] != (NGBE_VF_RESET | NGBE_VT_MSGTYPE_NACK))
+ return NGBE_ERR_INVALID_MAC_ADDR;
+
+ if (msgbuf[0] == (NGBE_VF_RESET | NGBE_VT_MSGTYPE_ACK))
+ memcpy(hw->mac.perm_addr, addr, ETH_ADDR_LEN);
+
+ hw->mac.mc_filter_type = msgbuf[NGBE_VF_MC_TYPE_WORD];
+
+ return ret_val;
+}
+
+/**
+ * ngbe_stop_hw_vf - Generic stop Tx/Rx units
+ * @hw: pointer to hardware structure
+ *
+ * Sets the adapter_stopped flag within ngbe_hw struct. Clears interrupts,
+ * disables transmit and receive units. The adapter_stopped flag is used by
+ * the shared code and drivers to determine if the adapter is in a stopped
+ * state and should not touch the hardware.
+ **/
+s32 ngbe_stop_hw_vf(struct ngbe_hw *hw)
+{
+ u16 i;
+
+ /*
+ * Set the adapter_stopped flag so other driver functions stop touching
+ * the hardware
+ */
+ hw->adapter_stopped = true;
+
+ /* Clear interrupt mask to stop from interrupts being generated */
+ wr32(hw, NGBE_VFIMC, NGBE_VFIMC_MASK);
+
+ /* Clear any pending interrupts, flush previous writes */
+ wr32(hw, NGBE_VFICR, NGBE_VFICR_MASK);
+
+ /* Disable the transmit unit. Each queue must be disabled. */
+ for (i = 0; i < hw->mac.max_tx_queues; i++)
+ wr32(hw, NGBE_TXCFG(i), NGBE_TXCFG_FLUSH);
+
+ /* Disable the receive unit by stopping each queue */
+ for (i = 0; i < hw->mac.max_rx_queues; i++)
+ wr32m(hw, NGBE_RXCFG(i), NGBE_RXCFG_ENA, 0);
+
+ /* Clear packet split and pool config */
+ wr32(hw, NGBE_VFPLCFG, 0);
+ hw->rx_loaded = 1;
+
+ /* flush all queues disables */
+ ngbe_flush(hw);
+ msec_delay(2);
+
+ return 0;
+}
+
STATIC s32 ngbevf_write_msg_read_ack(struct ngbe_hw *hw, u32 *msg,
u32 *retmsg, u16 size)
{
@@ -50,6 +222,64 @@ int ngbevf_negotiate_api_version(struct ngbe_hw *hw, int api)
return err;
}
+int ngbevf_get_queues(struct ngbe_hw *hw, unsigned int *num_tcs,
+ unsigned int *default_tc)
+{
+ int err, i;
+ u32 msg[5];
+
+ /* do nothing if API doesn't support ngbevf_get_queues */
+ switch (hw->api_version) {
+ case ngbe_mbox_api_11:
+ case ngbe_mbox_api_12:
+ case ngbe_mbox_api_13:
+ break;
+ default:
+ return 0;
+ }
+
+ /* Fetch queue configuration from the PF */
+ msg[0] = NGBE_VF_GET_QUEUES;
+ for (i = 1; i < 5; i++)
+ msg[i] = 0;
+
+ err = ngbevf_write_msg_read_ack(hw, msg, msg, 5);
+ if (!err) {
+ msg[0] &= ~NGBE_VT_MSGTYPE_CTS;
+
+ /*
+ * if we didn't get an ACK there must have been
+ * some sort of mailbox error so we should treat it
+ * as such
+ */
+ if (msg[0] != (NGBE_VF_GET_QUEUES | NGBE_VT_MSGTYPE_ACK))
+ return NGBE_ERR_MBX;
+
+ /* record and validate values from message */
+ hw->mac.max_tx_queues = msg[NGBE_VF_TX_QUEUES];
+ if (hw->mac.max_tx_queues == 0 ||
+ hw->mac.max_tx_queues > NGBE_VF_MAX_TX_QUEUES)
+ hw->mac.max_tx_queues = NGBE_VF_MAX_TX_QUEUES;
+
+ hw->mac.max_rx_queues = msg[NGBE_VF_RX_QUEUES];
+ if (hw->mac.max_rx_queues == 0 ||
+ hw->mac.max_rx_queues > NGBE_VF_MAX_RX_QUEUES)
+ hw->mac.max_rx_queues = NGBE_VF_MAX_RX_QUEUES;
+
+ *num_tcs = msg[NGBE_VF_TRANS_VLAN];
+ /* in case of unknown state assume we cannot tag frames */
+ if (*num_tcs > hw->mac.max_rx_queues)
+ *num_tcs = 1;
+
+ *default_tc = msg[NGBE_VF_DEF_QUEUE];
+ /* default to queue 0 on out-of-bounds queue number */
+ if (*default_tc >= hw->mac.max_tx_queues)
+ *default_tc = 0;
+ }
+
+ return err;
+}
+
/**
* ngbe_init_ops_vf - Initialize the pointers for vf
* @hw: pointer to hardware structure
@@ -64,6 +294,11 @@ s32 ngbe_init_ops_vf(struct ngbe_hw *hw)
struct ngbe_mac_info *mac = &hw->mac;
struct ngbe_mbx_info *mbx = &hw->mbx;
+ /* MAC */
+ mac->init_hw = ngbe_init_hw_vf;
+ mac->reset_hw = ngbe_reset_hw_vf;
+ mac->start_hw = ngbe_start_hw_vf;
+ mac->stop_hw = ngbe_stop_hw_vf;
mac->negotiate_api_version = ngbevf_negotiate_api_version;
mac->max_tx_queues = 1;
diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h
index 23e5b0d8a3..da846dda45 100644
--- a/drivers/net/ngbe/base/ngbe_vf.h
+++ b/drivers/net/ngbe/base/ngbe_vf.h
@@ -8,7 +8,16 @@
#include "ngbe_type.h"
+#define NGBE_VF_MAX_TX_QUEUES 1
+#define NGBE_VF_MAX_RX_QUEUES 1
+
s32 ngbe_init_ops_vf(struct ngbe_hw *hw);
+s32 ngbe_init_hw_vf(struct ngbe_hw *hw);
+s32 ngbe_start_hw_vf(struct ngbe_hw *hw);
+s32 ngbe_reset_hw_vf(struct ngbe_hw *hw);
+s32 ngbe_stop_hw_vf(struct ngbe_hw *hw);
int ngbevf_negotiate_api_version(struct ngbe_hw *hw, int api);
+int ngbevf_get_queues(struct ngbe_hw *hw, unsigned int *num_tcs,
+ unsigned int *default_tc);
#endif /* __NGBE_VF_H__ */
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index 856fed261b..275f682c05 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -40,8 +40,48 @@ static const struct rte_pci_id pci_id_ngbevf_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static const struct rte_eth_desc_lim rx_desc_lim = {
+ .nb_max = NGBE_RING_DESC_MAX,
+ .nb_min = NGBE_RING_DESC_MIN,
+ .nb_align = NGBE_RXD_ALIGN,
+};
+
+static const struct rte_eth_desc_lim tx_desc_lim = {
+ .nb_max = NGBE_RING_DESC_MAX,
+ .nb_min = NGBE_RING_DESC_MIN,
+ .nb_align = NGBE_TXD_ALIGN,
+ .nb_seg_max = NGBE_TX_MAX_SEG,
+ .nb_mtu_seg_max = NGBE_TX_MAX_SEG,
+};
+
static const struct eth_dev_ops ngbevf_eth_dev_ops;
+/*
+ * Negotiate mailbox API version with the PF.
+ * After reset API version is always set to the basic one (ngbe_mbox_api_10).
+ * Then we try to negotiate starting with the most recent one.
+ * If all negotiation attempts fail, then we will proceed with
+ * the default one (ngbe_mbox_api_10).
+ */
+static void
+ngbevf_negotiate_api(struct ngbe_hw *hw)
+{
+ int32_t i;
+
+ /* start with highest supported, proceed down */
+ static const int sup_ver[] = {
+ ngbe_mbox_api_13,
+ ngbe_mbox_api_12,
+ ngbe_mbox_api_11,
+ ngbe_mbox_api_10,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(sup_ver); i++) {
+ if (ngbevf_negotiate_api_version(hw, sup_ver[i]) == 0)
+ break;
+ }
+}
+
/*
* Virtual Function device init
*/
@@ -49,6 +89,7 @@ static int
eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
{
int err;
+ uint32_t tc, tcs;
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
struct ngbe_hw *hw = ngbe_dev_hw(eth_dev);
@@ -72,7 +113,32 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
return -EIO;
}
+ /* init_mailbox_params */
+ hw->mbx.init_params(hw);
+
hw->mac.num_rar_entries = 32; /* The MAX of the underlying PF */
+ err = hw->mac.reset_hw(hw);
+
+ /*
+ * The VF reset operation returns the NGBE_ERR_INVALID_MAC_ADDR when
+ * the underlying PF driver has not assigned a MAC address to the VF.
+ * In this case, assign a random MAC address.
+ */
+ if (err != 0 && err != NGBE_ERR_INVALID_MAC_ADDR) {
+ PMD_INIT_LOG(ERR, "VF Initialization Failure: %d", err);
+ /*
+ * This error code will be propagated to the app by
+ * rte_eth_dev_reset, so use a public error code rather than
+ * the internal-only NGBE_ERR_RESET_FAILED
+ */
+ return -EAGAIN;
+ }
+
+ /* negotiate mailbox API version to use with the PF. */
+ ngbevf_negotiate_api(hw);
+
+ /* Get Rx/Tx queue count via mailbox, which is ready after reset_hw */
+ ngbevf_get_queues(hw, &tcs, &tc);
/* Allocate memory for storing MAC addresses */
eth_dev->data->mac_addrs = rte_zmalloc("ngbevf", RTE_ETHER_ADDR_LEN *
@@ -85,6 +151,13 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
return -ENOMEM;
}
+ /* reset the hardware with the new settings */
+ err = hw->mac.start_hw(hw);
+ if (err) {
+ PMD_INIT_LOG(ERR, "VF Initialization Failure: %d", err);
+ return -EIO;
+ }
+
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");
@@ -132,10 +205,47 @@ static int
ngbevf_dev_info_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info)
{
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
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;
+ dev_info->min_rx_bufsize = 1024;
+ dev_info->max_rx_pktlen = NGBE_FRAME_SIZE_MAX;
+ dev_info->max_mac_addrs = hw->mac.num_rar_entries;
+ dev_info->max_hash_mac_addrs = NGBE_VMDQ_NUM_UC_MAC;
+ dev_info->max_vfs = pci_dev->max_vfs;
+ dev_info->max_vmdq_pools = RTE_ETH_64_POOLS;
+ dev_info->rx_queue_offload_capa = ngbe_get_rx_queue_offloads(dev);
+ dev_info->rx_offload_capa = (ngbe_get_rx_port_offloads(dev) |
+ dev_info->rx_queue_offload_capa);
+ dev_info->tx_queue_offload_capa = 0;
+ dev_info->tx_offload_capa = ngbe_get_tx_port_offloads(dev);
+ dev_info->hash_key_size = NGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
+ dev_info->reta_size = RTE_ETH_RSS_RETA_SIZE_128;
+ dev_info->default_rxconf = (struct rte_eth_rxconf) {
+ .rx_thresh = {
+ .pthresh = NGBE_DEFAULT_RX_PTHRESH,
+ .hthresh = NGBE_DEFAULT_RX_HTHRESH,
+ .wthresh = NGBE_DEFAULT_RX_WTHRESH,
+ },
+ .rx_free_thresh = NGBE_DEFAULT_RX_FREE_THRESH,
+ .rx_drop_en = 0,
+ .offloads = 0,
+ };
+
+ dev_info->default_txconf = (struct rte_eth_txconf) {
+ .tx_thresh = {
+ .pthresh = NGBE_DEFAULT_TX_PTHRESH,
+ .hthresh = NGBE_DEFAULT_TX_HTHRESH,
+ .wthresh = NGBE_DEFAULT_TX_WTHRESH,
+ },
+ .tx_free_thresh = NGBE_DEFAULT_TX_FREE_THRESH,
+ .offloads = 0,
+ };
+
+ dev_info->rx_desc_lim = rx_desc_lim;
+ dev_info->tx_desc_lim = tx_desc_lim;
return 0;
}
@@ -143,10 +253,14 @@ ngbevf_dev_info_get(struct rte_eth_dev *dev,
static int
ngbevf_dev_close(struct rte_eth_dev *dev)
{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+
PMD_INIT_FUNC_TRACE();
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return 0;
+ hw->mac.reset_hw(hw);
+
rte_free(dev->data->mac_addrs);
dev->data->mac_addrs = NULL;
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 04/15] net/ngbe: add promiscuous and allmulticast ops for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (2 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 03/15] net/ngbe: add hardware configuration code for VF device Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 05/15] net/ngbe: add set MTU " Zaiyu Wang
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Support to enable and disable promiscuous and allmulticast mode on VF
device.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
doc/guides/nics/features/ngbe_vf.ini | 2 +
drivers/net/ngbe/base/ngbe_type.h | 1 +
drivers/net/ngbe/base/ngbe_vf.c | 39 +++++++++++
drivers/net/ngbe/base/ngbe_vf.h | 1 +
drivers/net/ngbe/ngbe_ethdev_vf.c | 96 ++++++++++++++++++++++++++++
5 files changed, 139 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index b3d86e65ae..aa628dfa97 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -4,6 +4,8 @@
; Refer to default.ini for the full list of available PMD features.
;
[Features]
+Promiscuous mode = Y
+Allmulticast mode = Y
CRC offload = P
VLAN offload = P
QinQ offload = P
diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h
index 4fd7080847..29dcd5f912 100644
--- a/drivers/net/ngbe/base/ngbe_type.h
+++ b/drivers/net/ngbe/base/ngbe_type.h
@@ -351,6 +351,7 @@ struct ngbe_mac_info {
void (*set_mac_anti_spoofing)(struct ngbe_hw *hw, bool enable, int vf);
void (*set_vlan_anti_spoofing)(struct ngbe_hw *hw,
bool enable, int vf);
+ s32 (*update_xcast_mode)(struct ngbe_hw *hw, int xcast_mode);
/* Flow Control */
s32 (*fc_enable)(struct ngbe_hw *hw);
diff --git a/drivers/net/ngbe/base/ngbe_vf.c b/drivers/net/ngbe/base/ngbe_vf.c
index 41684a2e50..918df6f0dc 100644
--- a/drivers/net/ngbe/base/ngbe_vf.c
+++ b/drivers/net/ngbe/base/ngbe_vf.c
@@ -191,6 +191,43 @@ STATIC s32 ngbevf_write_msg_read_ack(struct ngbe_hw *hw, u32 *msg,
return mbx->read_posted(hw, retmsg, size, 0);
}
+/**
+ * ngbevf_update_xcast_mode - Update Multicast mode
+ * @hw: pointer to the HW structure
+ * @xcast_mode: new multicast mode
+ *
+ * Updates the Multicast Mode of VF.
+ **/
+s32 ngbevf_update_xcast_mode(struct ngbe_hw *hw, int xcast_mode)
+{
+ u32 msgbuf[2];
+ s32 err;
+
+ switch (hw->api_version) {
+ case ngbe_mbox_api_12:
+ /* New modes were introduced in 1.3 version */
+ if (xcast_mode > NGBEVF_XCAST_MODE_ALLMULTI)
+ return NGBE_ERR_FEATURE_NOT_SUPPORTED;
+ /* Fall through */
+ case ngbe_mbox_api_13:
+ break;
+ default:
+ return NGBE_ERR_FEATURE_NOT_SUPPORTED;
+ }
+
+ msgbuf[0] = NGBE_VF_UPDATE_XCAST_MODE;
+ msgbuf[1] = xcast_mode;
+
+ err = ngbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
+ if (err)
+ return err;
+
+ msgbuf[0] &= ~NGBE_VT_MSGTYPE_CTS;
+ if (msgbuf[0] == (NGBE_VF_UPDATE_XCAST_MODE | NGBE_VT_MSGTYPE_NACK))
+ return NGBE_ERR_FEATURE_NOT_SUPPORTED;
+ return 0;
+}
+
/**
* ngbevf_negotiate_api_version - Negotiate supported API version
* @hw: pointer to the HW structure
@@ -301,6 +338,8 @@ s32 ngbe_init_ops_vf(struct ngbe_hw *hw)
mac->stop_hw = ngbe_stop_hw_vf;
mac->negotiate_api_version = ngbevf_negotiate_api_version;
+ mac->update_xcast_mode = ngbevf_update_xcast_mode;
+
mac->max_tx_queues = 1;
mac->max_rx_queues = 1;
diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h
index da846dda45..79891e8389 100644
--- a/drivers/net/ngbe/base/ngbe_vf.h
+++ b/drivers/net/ngbe/base/ngbe_vf.h
@@ -16,6 +16,7 @@ s32 ngbe_init_hw_vf(struct ngbe_hw *hw);
s32 ngbe_start_hw_vf(struct ngbe_hw *hw);
s32 ngbe_reset_hw_vf(struct ngbe_hw *hw);
s32 ngbe_stop_hw_vf(struct ngbe_hw *hw);
+s32 ngbevf_update_xcast_mode(struct ngbe_hw *hw, int xcast_mode);
int ngbevf_negotiate_api_version(struct ngbe_hw *hw, int api);
int ngbevf_get_queues(struct ngbe_hw *hw, unsigned int *num_tcs,
unsigned int *default_tc);
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index 275f682c05..d8ece38b00 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -20,6 +20,8 @@
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);
+static int ngbevf_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static int ngbevf_dev_promiscuous_disable(struct rte_eth_dev *dev);
/*
* The set of PCI devices this driver supports (for VF)
@@ -158,6 +160,9 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
return -EIO;
}
+ /* enter promiscuous mode */
+ ngbevf_dev_promiscuous_enable(eth_dev);
+
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");
@@ -267,11 +272,102 @@ ngbevf_dev_close(struct rte_eth_dev *dev)
return 0;
}
+static int
+ngbevf_dev_promiscuous_enable(struct rte_eth_dev *dev)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ int ret;
+
+ switch (hw->mac.update_xcast_mode(hw, NGBEVF_XCAST_MODE_PROMISC)) {
+ case 0:
+ ret = 0;
+ break;
+ case NGBE_ERR_FEATURE_NOT_SUPPORTED:
+ ret = -ENOTSUP;
+ break;
+ default:
+ ret = -EAGAIN;
+ break;
+ }
+
+ return ret;
+}
+
+static int
+ngbevf_dev_promiscuous_disable(struct rte_eth_dev *dev)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ int ret;
+
+ switch (hw->mac.update_xcast_mode(hw, NGBEVF_XCAST_MODE_NONE)) {
+ case 0:
+ ret = 0;
+ break;
+ case NGBE_ERR_FEATURE_NOT_SUPPORTED:
+ ret = -ENOTSUP;
+ break;
+ default:
+ ret = -EAGAIN;
+ break;
+ }
+
+ return ret;
+}
+
+static int
+ngbevf_dev_allmulticast_enable(struct rte_eth_dev *dev)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ int ret;
+
+ if (dev->data->promiscuous == 1)
+ return 0;
+
+ switch (hw->mac.update_xcast_mode(hw, NGBEVF_XCAST_MODE_ALLMULTI)) {
+ case 0:
+ ret = 0;
+ break;
+ case NGBE_ERR_FEATURE_NOT_SUPPORTED:
+ ret = -ENOTSUP;
+ break;
+ default:
+ ret = -EAGAIN;
+ break;
+ }
+
+ return ret;
+}
+
+static int
+ngbevf_dev_allmulticast_disable(struct rte_eth_dev *dev)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ int ret;
+
+ switch (hw->mac.update_xcast_mode(hw, NGBEVF_XCAST_MODE_MULTI)) {
+ case 0:
+ ret = 0;
+ break;
+ case NGBE_ERR_FEATURE_NOT_SUPPORTED:
+ ret = -ENOTSUP;
+ break;
+ default:
+ ret = -EAGAIN;
+ break;
+ }
+
+ return ret;
+}
+
/*
* dev_ops for virtual function, bare necessities for basic vf
* operation have been implemented
*/
static const struct eth_dev_ops ngbevf_eth_dev_ops = {
+ .promiscuous_enable = ngbevf_dev_promiscuous_enable,
+ .promiscuous_disable = ngbevf_dev_promiscuous_disable,
+ .allmulticast_enable = ngbevf_dev_allmulticast_enable,
+ .allmulticast_disable = ngbevf_dev_allmulticast_disable,
.dev_infos_get = ngbevf_dev_info_get,
};
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 05/15] net/ngbe: add set MTU ops for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (3 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 04/15] net/ngbe: add promiscuous and allmulticast ops " Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 06/15] net/ngbe: add add/remove/set mac addr " Zaiyu Wang
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Support to update MTU for VF device.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
doc/guides/nics/features/ngbe_vf.ini | 1 +
drivers/net/ngbe/base/ngbe_type.h | 1 +
drivers/net/ngbe/base/ngbe_vf.c | 24 +++++++++++++++++++
drivers/net/ngbe/base/ngbe_vf.h | 1 +
drivers/net/ngbe/ngbe_ethdev_vf.c | 36 ++++++++++++++++++++++++++++
5 files changed, 63 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index aa628dfa97..333f02c854 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -4,6 +4,7 @@
; Refer to default.ini for the full list of available PMD features.
;
[Features]
+MTU update = Y
Promiscuous mode = Y
Allmulticast mode = Y
CRC offload = P
diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h
index 29dcd5f912..f780b92efa 100644
--- a/drivers/net/ngbe/base/ngbe_type.h
+++ b/drivers/net/ngbe/base/ngbe_type.h
@@ -352,6 +352,7 @@ struct ngbe_mac_info {
void (*set_vlan_anti_spoofing)(struct ngbe_hw *hw,
bool enable, int vf);
s32 (*update_xcast_mode)(struct ngbe_hw *hw, int xcast_mode);
+ s32 (*set_rlpml)(struct ngbe_hw *hw, u16 max_size);
/* Flow Control */
s32 (*fc_enable)(struct ngbe_hw *hw);
diff --git a/drivers/net/ngbe/base/ngbe_vf.c b/drivers/net/ngbe/base/ngbe_vf.c
index 918df6f0dc..2d00d5998d 100644
--- a/drivers/net/ngbe/base/ngbe_vf.c
+++ b/drivers/net/ngbe/base/ngbe_vf.c
@@ -228,6 +228,29 @@ s32 ngbevf_update_xcast_mode(struct ngbe_hw *hw, int xcast_mode)
return 0;
}
+/**
+ * ngbevf_rlpml_set_vf - Set the maximum receive packet length
+ * @hw: pointer to the HW structure
+ * @max_size: value to assign to max frame size
+ **/
+s32 ngbevf_rlpml_set_vf(struct ngbe_hw *hw, u16 max_size)
+{
+ u32 msgbuf[2];
+ s32 retval;
+
+ msgbuf[0] = NGBE_VF_SET_LPE;
+ msgbuf[1] = max_size;
+
+ retval = ngbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
+ if (retval)
+ return retval;
+ if ((msgbuf[0] & NGBE_VF_SET_LPE) &&
+ (msgbuf[0] & NGBE_VT_MSGTYPE_NACK))
+ return NGBE_ERR_MBX;
+
+ return 0;
+}
+
/**
* ngbevf_negotiate_api_version - Negotiate supported API version
* @hw: pointer to the HW structure
@@ -339,6 +362,7 @@ s32 ngbe_init_ops_vf(struct ngbe_hw *hw)
mac->negotiate_api_version = ngbevf_negotiate_api_version;
mac->update_xcast_mode = ngbevf_update_xcast_mode;
+ mac->set_rlpml = ngbevf_rlpml_set_vf;
mac->max_tx_queues = 1;
mac->max_rx_queues = 1;
diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h
index 79891e8389..a64de9d332 100644
--- a/drivers/net/ngbe/base/ngbe_vf.h
+++ b/drivers/net/ngbe/base/ngbe_vf.h
@@ -17,6 +17,7 @@ s32 ngbe_start_hw_vf(struct ngbe_hw *hw);
s32 ngbe_reset_hw_vf(struct ngbe_hw *hw);
s32 ngbe_stop_hw_vf(struct ngbe_hw *hw);
s32 ngbevf_update_xcast_mode(struct ngbe_hw *hw, int xcast_mode);
+s32 ngbevf_rlpml_set_vf(struct ngbe_hw *hw, u16 max_size);
int ngbevf_negotiate_api_version(struct ngbe_hw *hw, int api);
int ngbevf_get_queues(struct ngbe_hw *hw, unsigned int *num_tcs,
unsigned int *default_tc);
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index d8ece38b00..5ce0c2df98 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -272,6 +272,41 @@ ngbevf_dev_close(struct rte_eth_dev *dev)
return 0;
}
+static int
+ngbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
+{
+ struct ngbe_hw *hw;
+ uint32_t max_frame = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
+ struct rte_eth_dev_data *dev_data = dev->data;
+
+ hw = ngbe_dev_hw(dev);
+
+ if (mtu < RTE_ETHER_MIN_MTU ||
+ max_frame > RTE_ETHER_MAX_JUMBO_FRAME_LEN)
+ return -EINVAL;
+
+ /* If device is started, refuse mtu that requires the support of
+ * scattered packets when this feature has not been enabled before.
+ */
+ if (dev_data->dev_started && !dev_data->scattered_rx &&
+ (max_frame + 2 * RTE_VLAN_HLEN >
+ dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM)) {
+ PMD_INIT_LOG(ERR, "Stop port first.");
+ return -EINVAL;
+ }
+
+ /*
+ * When supported by the underlying PF driver, use the NGBE_VF_SET_MTU
+ * request of the version 2.0 of the mailbox API.
+ * For now, use the NGBE_VF_SET_LPE request of the version 1.0
+ * of the mailbox API.
+ */
+ if (ngbevf_rlpml_set_vf(hw, max_frame))
+ return -EINVAL;
+
+ return 0;
+}
+
static int
ngbevf_dev_promiscuous_enable(struct rte_eth_dev *dev)
{
@@ -369,6 +404,7 @@ static const struct eth_dev_ops ngbevf_eth_dev_ops = {
.allmulticast_enable = ngbevf_dev_allmulticast_enable,
.allmulticast_disable = ngbevf_dev_allmulticast_disable,
.dev_infos_get = ngbevf_dev_info_get,
+ .mtu_set = ngbevf_dev_set_mtu,
};
RTE_PMD_REGISTER_PCI(net_ngbe_vf, rte_ngbevf_pmd);
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 06/15] net/ngbe: add add/remove/set mac addr ops for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (4 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 05/15] net/ngbe: add set MTU " Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 07/15] net/ngbe: add datapath init code " Zaiyu Wang
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Generate a random MAC address if none was assigned by PF during
the initialization of VF device. And support to add and remove
MAC address.
---
doc/guides/nics/features/ngbe_vf.ini | 1 +
drivers/net/ngbe/base/ngbe_type.h | 1 +
drivers/net/ngbe/base/ngbe_vf.c | 82 +++++++++++++++
drivers/net/ngbe/base/ngbe_vf.h | 4 +
drivers/net/ngbe/ngbe_ethdev_vf.c | 146 +++++++++++++++++++++++++++
5 files changed, 234 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index 333f02c854..bbeb8aeb00 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -4,6 +4,7 @@
; Refer to default.ini for the full list of available PMD features.
;
[Features]
+Unicast MAC filter = Y
MTU update = Y
Promiscuous mode = Y
Allmulticast mode = Y
diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h
index f780b92efa..7a3b52ffd4 100644
--- a/drivers/net/ngbe/base/ngbe_type.h
+++ b/drivers/net/ngbe/base/ngbe_type.h
@@ -335,6 +335,7 @@ struct ngbe_mac_info {
/* RAR */
s32 (*set_rar)(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
u32 enable_addr);
+ s32 (*set_uc_addr)(struct ngbe_hw *hw, u32 index, u8 *addr);
s32 (*clear_rar)(struct ngbe_hw *hw, u32 index);
s32 (*set_vmdq)(struct ngbe_hw *hw, u32 rar, u32 vmdq);
s32 (*clear_vmdq)(struct ngbe_hw *hw, u32 rar, u32 vmdq);
diff --git a/drivers/net/ngbe/base/ngbe_vf.c b/drivers/net/ngbe/base/ngbe_vf.c
index 2d00d5998d..18bb8d263f 100644
--- a/drivers/net/ngbe/base/ngbe_vf.c
+++ b/drivers/net/ngbe/base/ngbe_vf.c
@@ -191,6 +191,39 @@ STATIC s32 ngbevf_write_msg_read_ack(struct ngbe_hw *hw, u32 *msg,
return mbx->read_posted(hw, retmsg, size, 0);
}
+/**
+ * ngbe_set_rar_vf - set device MAC address
+ * @hw: pointer to hardware structure
+ * @index: Receive address register to write
+ * @addr: Address to put into receive address register
+ * @vmdq: VMDq "set" or "pool" index
+ * @enable_addr: set flag that address is active
+ **/
+s32 ngbe_set_rar_vf(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
+ u32 enable_addr)
+{
+ u32 msgbuf[3];
+ u8 *msg_addr = (u8 *)(&msgbuf[1]);
+ s32 ret_val;
+ UNREFERENCED_PARAMETER(vmdq, enable_addr, index);
+
+ memset(msgbuf, 0, 12);
+ msgbuf[0] = NGBE_VF_SET_MAC_ADDR;
+ memcpy(msg_addr, addr, 6);
+ ret_val = ngbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3);
+
+ msgbuf[0] &= ~NGBE_VT_MSGTYPE_CTS;
+
+ /* if nacked the address was rejected, use "perm_addr" */
+ if (!ret_val &&
+ (msgbuf[0] == (NGBE_VF_SET_MAC_ADDR | NGBE_VT_MSGTYPE_NACK))) {
+ ngbe_get_mac_addr_vf(hw, hw->mac.addr);
+ return NGBE_ERR_MBX;
+ }
+
+ return ret_val;
+}
+
/**
* ngbevf_update_xcast_mode - Update Multicast mode
* @hw: pointer to the HW structure
@@ -228,6 +261,51 @@ s32 ngbevf_update_xcast_mode(struct ngbe_hw *hw, int xcast_mode)
return 0;
}
+/**
+ * ngbe_get_mac_addr_vf - Read device MAC address
+ * @hw: pointer to the HW structure
+ * @mac_addr: the MAC address
+ **/
+s32 ngbe_get_mac_addr_vf(struct ngbe_hw *hw, u8 *mac_addr)
+{
+ int i;
+
+ for (i = 0; i < ETH_ADDR_LEN; i++)
+ mac_addr[i] = hw->mac.perm_addr[i];
+
+ return 0;
+}
+
+s32 ngbevf_set_uc_addr_vf(struct ngbe_hw *hw, u32 index, u8 *addr)
+{
+ u32 msgbuf[3], msgbuf_chk;
+ u8 *msg_addr = (u8 *)(&msgbuf[1]);
+ s32 ret_val;
+
+ memset(msgbuf, 0, sizeof(msgbuf));
+ /*
+ * If index is one then this is the start of a new list and needs
+ * indication to the PF so it can do it's own list management.
+ * If it is zero then that tells the PF to just clear all of
+ * this VF's macvlans and there is no new list.
+ */
+ msgbuf[0] |= index << NGBE_VT_MSGINFO_SHIFT;
+ msgbuf[0] |= NGBE_VF_SET_MACVLAN;
+ msgbuf_chk = msgbuf[0];
+ if (addr)
+ memcpy(msg_addr, addr, 6);
+
+ ret_val = ngbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3);
+ if (!ret_val) {
+ msgbuf[0] &= ~NGBE_VT_MSGTYPE_CTS;
+
+ if (msgbuf[0] == (msgbuf_chk | NGBE_VT_MSGTYPE_NACK))
+ return NGBE_ERR_OUT_OF_MEM;
+ }
+
+ return ret_val;
+}
+
/**
* ngbevf_rlpml_set_vf - Set the maximum receive packet length
* @hw: pointer to the HW structure
@@ -359,8 +437,12 @@ s32 ngbe_init_ops_vf(struct ngbe_hw *hw)
mac->reset_hw = ngbe_reset_hw_vf;
mac->start_hw = ngbe_start_hw_vf;
mac->stop_hw = ngbe_stop_hw_vf;
+ mac->get_mac_addr = ngbe_get_mac_addr_vf;
mac->negotiate_api_version = ngbevf_negotiate_api_version;
+ /* RAR, Multicast */
+ mac->set_rar = ngbe_set_rar_vf;
+ mac->set_uc_addr = ngbevf_set_uc_addr_vf;
mac->update_xcast_mode = ngbevf_update_xcast_mode;
mac->set_rlpml = ngbevf_rlpml_set_vf;
diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h
index a64de9d332..3f328a0221 100644
--- a/drivers/net/ngbe/base/ngbe_vf.h
+++ b/drivers/net/ngbe/base/ngbe_vf.h
@@ -16,6 +16,10 @@ s32 ngbe_init_hw_vf(struct ngbe_hw *hw);
s32 ngbe_start_hw_vf(struct ngbe_hw *hw);
s32 ngbe_reset_hw_vf(struct ngbe_hw *hw);
s32 ngbe_stop_hw_vf(struct ngbe_hw *hw);
+s32 ngbe_get_mac_addr_vf(struct ngbe_hw *hw, u8 *mac_addr);
+s32 ngbe_set_rar_vf(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
+ u32 enable_addr);
+s32 ngbevf_set_uc_addr_vf(struct ngbe_hw *hw, u32 index, u8 *addr);
s32 ngbevf_update_xcast_mode(struct ngbe_hw *hw, int xcast_mode);
s32 ngbevf_rlpml_set_vf(struct ngbe_hw *hw, u16 max_size);
int ngbevf_negotiate_api_version(struct ngbe_hw *hw, int api);
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index 5ce0c2df98..29979785cf 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -22,6 +22,7 @@ static int ngbevf_dev_info_get(struct rte_eth_dev *dev,
static int ngbevf_dev_close(struct rte_eth_dev *dev);
static int ngbevf_dev_promiscuous_enable(struct rte_eth_dev *dev);
static int ngbevf_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static void ngbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
/*
* The set of PCI devices this driver supports (for VF)
@@ -84,6 +85,22 @@ ngbevf_negotiate_api(struct ngbe_hw *hw)
}
}
+static void
+generate_random_mac_addr(struct rte_ether_addr *mac_addr)
+{
+ uint64_t random;
+
+ /* Set Organizationally Unique Identifier (OUI) prefix. */
+ mac_addr->addr_bytes[0] = 0x00;
+ mac_addr->addr_bytes[1] = 0x09;
+ mac_addr->addr_bytes[2] = 0xC0;
+ /* Force indication of locally assigned MAC address. */
+ mac_addr->addr_bytes[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;
+ /* Generate the last 3 bytes of the MAC address with a random number. */
+ random = rte_rand();
+ memcpy(&mac_addr->addr_bytes[3], &random, 3);
+}
+
/*
* Virtual Function device init
*/
@@ -94,6 +111,8 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
uint32_t tc, tcs;
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
struct ngbe_hw *hw = ngbe_dev_hw(eth_dev);
+ struct rte_ether_addr *perm_addr =
+ (struct rte_ether_addr *)hw->mac.perm_addr;
PMD_INIT_FUNC_TRACE();
@@ -153,6 +172,29 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
return -ENOMEM;
}
+ /* Generate a random MAC address, if none was assigned by PF. */
+ if (rte_is_zero_ether_addr(perm_addr)) {
+ generate_random_mac_addr(perm_addr);
+ err = ngbe_set_rar_vf(hw, 1, perm_addr->addr_bytes, 0, 1);
+ if (err) {
+ rte_free(eth_dev->data->mac_addrs);
+ eth_dev->data->mac_addrs = NULL;
+ return err;
+ }
+ PMD_INIT_LOG(INFO, "\tVF MAC address not assigned by Host PF");
+ PMD_INIT_LOG(INFO, "\tAssign randomly generated MAC address "
+ "%02x:%02x:%02x:%02x:%02x:%02x",
+ perm_addr->addr_bytes[0],
+ perm_addr->addr_bytes[1],
+ perm_addr->addr_bytes[2],
+ perm_addr->addr_bytes[3],
+ perm_addr->addr_bytes[4],
+ perm_addr->addr_bytes[5]);
+ }
+
+ /* Copy the permanent MAC address */
+ rte_ether_addr_copy(perm_addr, ð_dev->data->mac_addrs[0]);
+
/* reset the hardware with the new settings */
err = hw->mac.start_hw(hw);
if (err) {
@@ -266,12 +308,113 @@ ngbevf_dev_close(struct rte_eth_dev *dev)
hw->mac.reset_hw(hw);
+ /**
+ * Remove the VF MAC address ro ensure
+ * that the VF traffic goes to the PF
+ * after stop, close and detach of the VF
+ **/
+ ngbevf_remove_mac_addr(dev, 0);
+
+ dev->rx_pkt_burst = NULL;
+ dev->tx_pkt_burst = NULL;
+
rte_free(dev->data->mac_addrs);
dev->data->mac_addrs = NULL;
return 0;
}
+static int
+ngbevf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
+ __rte_unused uint32_t index,
+ __rte_unused uint32_t pool)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ int err;
+
+ /*
+ * On a VF, adding again the same MAC addr is not an idempotent
+ * operation. Trap this case to avoid exhausting the [very limited]
+ * set of PF resources used to store VF MAC addresses.
+ */
+ if (memcmp(hw->mac.perm_addr, mac_addr,
+ sizeof(struct rte_ether_addr)) == 0)
+ return -1;
+ err = ngbevf_set_uc_addr_vf(hw, 2, mac_addr->addr_bytes);
+ if (err != 0)
+ PMD_DRV_LOG(ERR, "Unable to add MAC address "
+ "%02x:%02x:%02x:%02x:%02x:%02x - err=%d",
+ mac_addr->addr_bytes[0],
+ mac_addr->addr_bytes[1],
+ mac_addr->addr_bytes[2],
+ mac_addr->addr_bytes[3],
+ mac_addr->addr_bytes[4],
+ mac_addr->addr_bytes[5],
+ err);
+ return err;
+}
+
+static void
+ngbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ struct rte_ether_addr *perm_addr =
+ (struct rte_ether_addr *)hw->mac.perm_addr;
+ struct rte_ether_addr *mac_addr;
+ uint32_t i;
+ int err;
+
+ /*
+ * The NGBE_VF_SET_MACVLAN command of the ngbe-pf driver does
+ * not support the deletion of a given MAC address.
+ * Instead, it imposes to delete all MAC addresses, then to add again
+ * all MAC addresses with the exception of the one to be deleted.
+ */
+ (void)ngbevf_set_uc_addr_vf(hw, 0, NULL);
+
+ /*
+ * Add again all MAC addresses, with the exception of the deleted one
+ * and of the permanent MAC address.
+ */
+ for (i = 0, mac_addr = dev->data->mac_addrs;
+ i < hw->mac.num_rar_entries; i++, mac_addr++) {
+ /* Skip the deleted MAC address */
+ if (i == index)
+ continue;
+ /* Skip NULL MAC addresses */
+ if (rte_is_zero_ether_addr(mac_addr))
+ continue;
+ /* Skip the permanent MAC address */
+ if (memcmp(perm_addr, mac_addr,
+ sizeof(struct rte_ether_addr)) == 0)
+ continue;
+ err = ngbevf_set_uc_addr_vf(hw, 2, mac_addr->addr_bytes);
+ if (err != 0)
+ PMD_DRV_LOG(ERR,
+ "Adding again MAC address "
+ "%02x:%02x:%02x:%02x:%02x:%02x failed "
+ "err=%d",
+ mac_addr->addr_bytes[0],
+ mac_addr->addr_bytes[1],
+ mac_addr->addr_bytes[2],
+ mac_addr->addr_bytes[3],
+ mac_addr->addr_bytes[4],
+ mac_addr->addr_bytes[5],
+ err);
+ }
+}
+
+static int
+ngbevf_set_default_mac_addr(struct rte_eth_dev *dev,
+ struct rte_ether_addr *addr)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+
+ hw->mac.set_rar(hw, 0, (void *)addr, 0, 0);
+
+ return 0;
+}
+
static int
ngbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
{
@@ -405,6 +548,9 @@ static const struct eth_dev_ops ngbevf_eth_dev_ops = {
.allmulticast_disable = ngbevf_dev_allmulticast_disable,
.dev_infos_get = ngbevf_dev_info_get,
.mtu_set = ngbevf_dev_set_mtu,
+ .mac_addr_add = ngbevf_add_mac_addr,
+ .mac_addr_remove = ngbevf_remove_mac_addr,
+ .mac_addr_set = ngbevf_set_default_mac_addr,
};
RTE_PMD_REGISTER_PCI(net_ngbe_vf, rte_ngbevf_pmd);
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 07/15] net/ngbe: add datapath init code for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (5 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 06/15] net/ngbe: add add/remove/set mac addr " Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 08/15] net/ngbe: add vlan related ops " Zaiyu Wang
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu, Anatoly Burakov
Add support for datapath init, including RX and TX unit init.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
doc/guides/nics/features/ngbe_vf.ini | 6 +
drivers/net/ngbe/ngbe_ethdev.h | 6 +
drivers/net/ngbe/ngbe_ethdev_vf.c | 63 ++++++++
drivers/net/ngbe/ngbe_rxtx.c | 210 +++++++++++++++++++++++++++
4 files changed, 285 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index bbeb8aeb00..024d161c5e 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -8,11 +8,17 @@ Unicast MAC filter = Y
MTU update = Y
Promiscuous mode = Y
Allmulticast mode = Y
+Jumbo frame = Y
+Scattered Rx = Y
+LRO = Y
+TSO = Y
CRC offload = P
VLAN offload = P
QinQ offload = P
L3 checksum offload = P
L4 checksum offload = P
+Rx descriptor status = Y
+Tx descriptor status = Y
Inner L3 checksum = P
Inner L4 checksum = P
Multiprocess aware = Y
diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h
index 7af58a57ac..37c6459f51 100644
--- a/drivers/net/ngbe/ngbe_ethdev.h
+++ b/drivers/net/ngbe/ngbe_ethdev.h
@@ -241,6 +241,12 @@ int
ngbe_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id,
struct rte_eth_burst_mode *mode);
+int ngbevf_dev_rx_init(struct rte_eth_dev *dev);
+
+void ngbevf_dev_tx_init(struct rte_eth_dev *dev);
+
+void ngbevf_dev_rxtx_start(struct rte_eth_dev *dev);
+
uint16_t ngbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index 29979785cf..1970bfcd05 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -117,6 +117,34 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
PMD_INIT_FUNC_TRACE();
eth_dev->dev_ops = &ngbevf_eth_dev_ops;
+ eth_dev->rx_descriptor_status = ngbe_dev_rx_descriptor_status;
+ eth_dev->tx_descriptor_status = ngbe_dev_tx_descriptor_status;
+ eth_dev->rx_pkt_burst = &ngbe_recv_pkts;
+ eth_dev->tx_pkt_burst = &ngbe_xmit_pkts;
+
+ /* for secondary processes, we don't initialise any further as primary
+ * has already done this work. Only check we don't need a different
+ * RX function
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ struct ngbe_tx_queue *txq;
+ uint16_t nb_tx_queues = eth_dev->data->nb_tx_queues;
+ /* TX queue function in primary, set by last queue initialized
+ * Tx queue may not initialized by primary process
+ */
+ if (eth_dev->data->tx_queues) {
+ txq = eth_dev->data->tx_queues[nb_tx_queues - 1];
+ ngbe_set_tx_function(eth_dev, txq);
+ } else {
+ /* Use default TX function if we get here */
+ PMD_INIT_LOG(NOTICE,
+ "No TX queues configured yet. Using default TX function.");
+ }
+
+ ngbe_set_rx_function(eth_dev);
+
+ return 0;
+ }
rte_eth_copy_pci_info(eth_dev, pci_dev);
@@ -297,6 +325,40 @@ ngbevf_dev_info_get(struct rte_eth_dev *dev,
return 0;
}
+static int
+ngbevf_dev_configure(struct rte_eth_dev *dev)
+{
+ struct rte_eth_conf *conf = &dev->data->dev_conf;
+ struct ngbe_adapter *adapter = ngbe_dev_adapter(dev);
+
+ PMD_INIT_LOG(DEBUG, "Configured Virtual Function port id: %d",
+ dev->data->port_id);
+
+ /*
+ * VF has no ability to enable/disable HW CRC
+ * Keep the persistent behavior the same as Host PF
+ */
+#ifndef RTE_LIBRTE_NGBE_PF_DISABLE_STRIP_CRC
+ if (conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC) {
+ PMD_INIT_LOG(NOTICE, "VF can't disable HW CRC Strip");
+ conf->rxmode.offloads &= ~RTE_ETH_RX_OFFLOAD_KEEP_CRC;
+ }
+#else
+ if (!(conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)) {
+ PMD_INIT_LOG(NOTICE, "VF can't enable HW CRC Strip");
+ conf->rxmode.offloads |= RTE_ETH_RX_OFFLOAD_KEEP_CRC;
+ }
+#endif
+
+ /*
+ * Initialize to TRUE. If any of Rx queues doesn't meet the bulk
+ * allocation or vector Rx preconditions we will reset it.
+ */
+ adapter->rx_bulk_alloc_allowed = true;
+
+ return 0;
+}
+
static int
ngbevf_dev_close(struct rte_eth_dev *dev)
{
@@ -542,6 +604,7 @@ ngbevf_dev_allmulticast_disable(struct rte_eth_dev *dev)
* operation have been implemented
*/
static const struct eth_dev_ops ngbevf_eth_dev_ops = {
+ .dev_configure = ngbevf_dev_configure,
.promiscuous_enable = ngbevf_dev_promiscuous_enable,
.promiscuous_disable = ngbevf_dev_promiscuous_disable,
.allmulticast_enable = ngbevf_dev_allmulticast_enable,
diff --git a/drivers/net/ngbe/ngbe_rxtx.c b/drivers/net/ngbe/ngbe_rxtx.c
index 8d31d47de9..b84e24f6e1 100644
--- a/drivers/net/ngbe/ngbe_rxtx.c
+++ b/drivers/net/ngbe/ngbe_rxtx.c
@@ -3458,6 +3458,216 @@ ngbe_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
}
+/*
+ * [VF] Initializes Receive Unit.
+ */
+int
+ngbevf_dev_rx_init(struct rte_eth_dev *dev)
+{
+ struct ngbe_hw *hw;
+ struct ngbe_rx_queue *rxq;
+ struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+ uint64_t bus_addr;
+ uint32_t srrctl;
+ uint16_t buf_size;
+ uint16_t i;
+ int ret;
+
+ PMD_INIT_FUNC_TRACE();
+ hw = ngbe_dev_hw(dev);
+
+ if (rte_is_power_of_2(dev->data->nb_rx_queues) == 0) {
+ PMD_INIT_LOG(ERR, "The number of Rx queue invalid, "
+ "it should be power of 2");
+ return -1;
+ }
+
+ if (dev->data->nb_rx_queues > hw->mac.max_rx_queues) {
+ PMD_INIT_LOG(ERR, "The number of Rx queue invalid, "
+ "it should be equal to or less than %d",
+ hw->mac.max_rx_queues);
+ return -1;
+ }
+
+ /*
+ * When the VF driver issues a NGBE_VF_RESET request, the PF driver
+ * disables the VF receipt of packets if the PF MTU is > 1500.
+ * This is done to deal with limitations that imposes
+ * the PF and all VFs to share the same MTU.
+ * Then, the PF driver enables again the VF receipt of packet when
+ * the VF driver issues a NGBE_VF_SET_LPE request.
+ * In the meantime, the VF device cannot be used, even if the VF driver
+ * and the Guest VM network stack are ready to accept packets with a
+ * size up to the PF MTU.
+ * As a work-around to this PF behaviour, force the call to
+ * ngbevf_rlpml_set_vf even if jumbo frames are not used. This way,
+ * VF packets received can work in all cases.
+ */
+ if (ngbevf_rlpml_set_vf(hw,
+ (uint16_t)dev->data->mtu + NGBE_ETH_OVERHEAD)) {
+ PMD_INIT_LOG(ERR, "Set max packet length to %d failed.",
+ dev->data->mtu + NGBE_ETH_OVERHEAD);
+
+ return -EINVAL;
+ }
+
+ /*
+ * Assume no header split and no VLAN strip support
+ * on any Rx queue first .
+ */
+ rxmode->offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
+ /* Setup RX queues */
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ rxq = dev->data->rx_queues[i];
+
+ /* Allocate buffers for descriptor rings */
+ ret = ngbe_alloc_rx_queue_mbufs(rxq);
+ if (ret)
+ return ret;
+
+ /* Setup the Base and Length of the Rx Descriptor Rings */
+ bus_addr = rxq->rx_ring_phys_addr;
+
+ wr32(hw, NGBE_RXBAL(i),
+ (uint32_t)(bus_addr & BIT_MASK32));
+ wr32(hw, NGBE_RXBAH(i),
+ (uint32_t)(bus_addr >> 32));
+ wr32(hw, NGBE_RXRP(i), 0);
+ wr32(hw, NGBE_RXWP(i), 0);
+
+ /* Configure the RXCFG register */
+ srrctl = NGBE_RXCFG_RNGLEN(rxq->nb_rx_desc);
+
+ /* Set if packets are dropped when no descriptors available */
+ if (rxq->drop_en)
+ srrctl |= NGBE_RXCFG_DROP;
+
+ /*
+ * Configure the RX buffer size in the PKTLEN field of
+ * the RXCFG register of the queue.
+ * The value is in 1 KB resolution. Valid values can be from
+ * 1 KB to 16 KB.
+ */
+ buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) -
+ RTE_PKTMBUF_HEADROOM);
+ buf_size = ROUND_UP(buf_size, 1 << 10);
+ srrctl |= NGBE_RXCFG_PKTLEN(buf_size);
+
+ /*
+ * VF modification to write virtual function RXCFG register
+ */
+ wr32(hw, NGBE_RXCFG(i), srrctl);
+
+ if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_SCATTER ||
+ /* It adds dual VLAN length for supporting dual VLAN */
+ (dev->data->mtu + NGBE_ETH_OVERHEAD +
+ 2 * RTE_VLAN_HLEN) > buf_size) {
+ if (!dev->data->scattered_rx)
+ PMD_INIT_LOG(DEBUG, "forcing scatter mode");
+ dev->data->scattered_rx = 1;
+ }
+
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
+ rxmode->offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
+ }
+
+ ngbe_set_rx_function(dev);
+
+ return 0;
+}
+
+/*
+ * [VF] Initializes Transmit Unit.
+ */
+void
+ngbevf_dev_tx_init(struct rte_eth_dev *dev)
+{
+ struct ngbe_hw *hw;
+ struct ngbe_tx_queue *txq;
+ uint64_t bus_addr;
+ uint16_t i;
+
+ PMD_INIT_FUNC_TRACE();
+ hw = ngbe_dev_hw(dev);
+
+ /* Setup the Base and Length of the Tx Descriptor Rings */
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ bus_addr = txq->tx_ring_phys_addr;
+ wr32(hw, NGBE_TXBAL(i),
+ (uint32_t)(bus_addr & BIT_MASK32));
+ wr32(hw, NGBE_TXBAH(i),
+ (uint32_t)(bus_addr >> 32));
+ wr32m(hw, NGBE_TXCFG(i), NGBE_TXCFG_BUFLEN_MASK,
+ NGBE_TXCFG_BUFLEN(txq->nb_tx_desc));
+ /* Setup the HW Tx Head and TX Tail descriptor pointers */
+ wr32(hw, NGBE_TXRP(i), 0);
+ wr32(hw, NGBE_TXWP(i), 0);
+ }
+}
+
+/*
+ * [VF] Start Transmit and Receive Units.
+ */
+void
+ngbevf_dev_rxtx_start(struct rte_eth_dev *dev)
+{
+ struct ngbe_hw *hw;
+ struct ngbe_tx_queue *txq;
+ struct ngbe_rx_queue *rxq;
+ uint32_t txdctl;
+ uint32_t rxdctl;
+ uint16_t i;
+ int poll_ms;
+
+ PMD_INIT_FUNC_TRACE();
+ hw = ngbe_dev_hw(dev);
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ /* Setup Transmit Threshold Registers */
+ wr32m(hw, NGBE_TXCFG(txq->reg_idx),
+ NGBE_TXCFG_HTHRESH_MASK |
+ NGBE_TXCFG_WTHRESH_MASK,
+ NGBE_TXCFG_HTHRESH(txq->hthresh) |
+ NGBE_TXCFG_WTHRESH(txq->wthresh));
+ }
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ wr32m(hw, NGBE_TXCFG(i), NGBE_TXCFG_ENA, NGBE_TXCFG_ENA);
+
+ poll_ms = 10;
+ /* Wait until TX Enable ready */
+ do {
+ rte_delay_ms(1);
+ txdctl = rd32(hw, NGBE_TXCFG(i));
+ } while (--poll_ms && !(txdctl & NGBE_TXCFG_ENA));
+ if (!poll_ms)
+ PMD_INIT_LOG(ERR, "Could not enable Tx Queue %d", i);
+ else
+ dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
+ }
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ rxq = dev->data->rx_queues[i];
+
+ wr32m(hw, NGBE_RXCFG(i), NGBE_RXCFG_ENA, NGBE_RXCFG_ENA);
+
+ /* Wait until RX Enable ready */
+ poll_ms = 10;
+ do {
+ rte_delay_ms(1);
+ rxdctl = rd32(hw, NGBE_RXCFG(i));
+ } while (--poll_ms && !(rxdctl & NGBE_RXCFG_ENA));
+ if (!poll_ms)
+ PMD_INIT_LOG(ERR, "Could not enable Rx Queue %d", i);
+ else
+ dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
+ rte_wmb();
+ wr32(hw, NGBE_RXWP(i), rxq->nb_rx_desc - 1);
+ }
+}
+
+
/* Stubs needed for linkage when RTE_ARCH_PPC_64, RTE_ARCH_RISCV or
* RTE_ARCH_LOONGARCH is set.
*/
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 08/15] net/ngbe: add vlan related ops for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (6 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 07/15] net/ngbe: add datapath init code " Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 09/15] net/ngbe: add interrupt support " Zaiyu Wang
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Add support for VLAN filter, offload and strip set feature.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
doc/guides/nics/features/ngbe_vf.ini | 1 +
drivers/net/ngbe/base/ngbe_vf.c | 32 +++++++-
drivers/net/ngbe/base/ngbe_vf.h | 2 +
drivers/net/ngbe/ngbe_ethdev_vf.c | 113 +++++++++++++++++++++++++++
4 files changed, 147 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index 024d161c5e..e365f85e47 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -12,6 +12,7 @@ Jumbo frame = Y
Scattered Rx = Y
LRO = Y
TSO = Y
+VLAN filter = Y
CRC offload = P
VLAN offload = P
QinQ offload = P
diff --git a/drivers/net/ngbe/base/ngbe_vf.c b/drivers/net/ngbe/base/ngbe_vf.c
index 18bb8d263f..d50806876f 100644
--- a/drivers/net/ngbe/base/ngbe_vf.c
+++ b/drivers/net/ngbe/base/ngbe_vf.c
@@ -261,6 +261,35 @@ s32 ngbevf_update_xcast_mode(struct ngbe_hw *hw, int xcast_mode)
return 0;
}
+/**
+ * ngbe_set_vfta_vf - Set/Unset vlan filter table address
+ * @hw: pointer to the HW structure
+ * @vlan: 12 bit VLAN ID
+ * @vind: unused by VF drivers
+ * @vlan_on: if true then set bit, else clear bit
+ * @vlvf_bypass: boolean flag indicating updating default pool is okay
+ *
+ * Turn on/off specified VLAN in the VLAN filter table.
+ **/
+s32 ngbe_set_vfta_vf(struct ngbe_hw *hw, u32 vlan, u32 vind,
+ bool vlan_on, bool vlvf_bypass)
+{
+ u32 msgbuf[2];
+ s32 ret_val;
+ UNREFERENCED_PARAMETER(vind, vlvf_bypass);
+
+ msgbuf[0] = NGBE_VF_SET_VLAN;
+ msgbuf[1] = vlan;
+ /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */
+ msgbuf[0] |= vlan_on << NGBE_VT_MSGINFO_SHIFT;
+
+ ret_val = ngbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
+ if (!ret_val && (msgbuf[0] & NGBE_VT_MSGTYPE_ACK))
+ return 0;
+
+ return ret_val | (msgbuf[0] & NGBE_VT_MSGTYPE_NACK);
+}
+
/**
* ngbe_get_mac_addr_vf - Read device MAC address
* @hw: pointer to the HW structure
@@ -440,10 +469,11 @@ s32 ngbe_init_ops_vf(struct ngbe_hw *hw)
mac->get_mac_addr = ngbe_get_mac_addr_vf;
mac->negotiate_api_version = ngbevf_negotiate_api_version;
- /* RAR, Multicast */
+ /* RAR, Multicast, VLAN */
mac->set_rar = ngbe_set_rar_vf;
mac->set_uc_addr = ngbevf_set_uc_addr_vf;
mac->update_xcast_mode = ngbevf_update_xcast_mode;
+ mac->set_vfta = ngbe_set_vfta_vf;
mac->set_rlpml = ngbevf_rlpml_set_vf;
mac->max_tx_queues = 1;
diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h
index 3f328a0221..596f41dcb0 100644
--- a/drivers/net/ngbe/base/ngbe_vf.h
+++ b/drivers/net/ngbe/base/ngbe_vf.h
@@ -21,6 +21,8 @@ s32 ngbe_set_rar_vf(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
u32 enable_addr);
s32 ngbevf_set_uc_addr_vf(struct ngbe_hw *hw, u32 index, u8 *addr);
s32 ngbevf_update_xcast_mode(struct ngbe_hw *hw, int xcast_mode);
+s32 ngbe_set_vfta_vf(struct ngbe_hw *hw, u32 vlan, u32 vind,
+ bool vlan_on, bool vlvf_bypass);
s32 ngbevf_rlpml_set_vf(struct ngbe_hw *hw, u16 max_size);
int ngbevf_negotiate_api_version(struct ngbe_hw *hw, int api);
int ngbevf_get_queues(struct ngbe_hw *hw, unsigned int *num_tcs,
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index 1970bfcd05..193e29d0c1 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -20,6 +20,8 @@
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);
+static int ngbevf_vlan_offload_config(struct rte_eth_dev *dev, int mask);
+static void ngbevf_set_vfta_all(struct rte_eth_dev *dev, bool on);
static int ngbevf_dev_promiscuous_enable(struct rte_eth_dev *dev);
static int ngbevf_dev_promiscuous_disable(struct rte_eth_dev *dev);
static void ngbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
@@ -111,6 +113,8 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
uint32_t tc, tcs;
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
struct ngbe_hw *hw = ngbe_dev_hw(eth_dev);
+ struct ngbe_vfta *shadow_vfta = NGBE_DEV_VFTA(eth_dev);
+ struct ngbe_hwstrip *hwstrip = NGBE_DEV_HWSTRIP(eth_dev);
struct rte_ether_addr *perm_addr =
(struct rte_ether_addr *)hw->mac.perm_addr;
@@ -154,6 +158,12 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
ngbe_map_device_id(hw);
hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
+ /* initialize the vfta */
+ memset(shadow_vfta, 0, sizeof(*shadow_vfta));
+
+ /* initialize the hw strip bitmap*/
+ memset(hwstrip, 0, sizeof(*hwstrip));
+
/* Initialize the shared code (base driver) */
err = ngbe_init_shared_code(hw);
if (err != 0) {
@@ -386,6 +396,106 @@ ngbevf_dev_close(struct rte_eth_dev *dev)
return 0;
}
+static void ngbevf_set_vfta_all(struct rte_eth_dev *dev, bool on)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ struct ngbe_vfta *shadow_vfta = NGBE_DEV_VFTA(dev);
+ int i = 0, j = 0, vfta = 0, mask = 1;
+
+ for (i = 0; i < NGBE_VFTA_SIZE; i++) {
+ vfta = shadow_vfta->vfta[i];
+ if (vfta) {
+ mask = 1;
+ for (j = 0; j < 32; j++) {
+ if (vfta & mask)
+ hw->mac.set_vfta(hw, (i << 5) + j, 0,
+ on, false);
+ mask <<= 1;
+ }
+ }
+ }
+}
+
+static int
+ngbevf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ struct ngbe_vfta *shadow_vfta = NGBE_DEV_VFTA(dev);
+ uint32_t vid_idx = 0;
+ uint32_t vid_bit = 0;
+ int ret = 0;
+
+ PMD_INIT_FUNC_TRACE();
+
+ /* vind is not used in VF driver, set to 0, check ngbe_set_vfta_vf */
+ ret = hw->mac.set_vfta(hw, vlan_id, 0, !!on, false);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Unable to set VF vlan");
+ return ret;
+ }
+ vid_idx = (uint32_t)((vlan_id >> 5) & 0x7F);
+ vid_bit = (uint32_t)(1 << (vlan_id & 0x1F));
+
+ /* Save what we set and restore it after device reset */
+ if (on)
+ shadow_vfta->vfta[vid_idx] |= vid_bit;
+ else
+ shadow_vfta->vfta[vid_idx] &= ~vid_bit;
+
+ return 0;
+}
+
+static void
+ngbevf_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ uint32_t ctrl;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (queue >= hw->mac.max_rx_queues)
+ return;
+
+ ctrl = rd32(hw, NGBE_RXCFG(queue));
+ if (on)
+ ctrl |= NGBE_RXCFG_VLAN;
+ else
+ ctrl &= ~NGBE_RXCFG_VLAN;
+ wr32(hw, NGBE_RXCFG(queue), ctrl);
+
+ ngbe_vlan_hw_strip_bitmap_set(dev, queue, on);
+}
+
+static int
+ngbevf_vlan_offload_config(struct rte_eth_dev *dev, int mask)
+{
+ struct ngbe_rx_queue *rxq;
+ uint16_t i;
+ int on = 0;
+
+ /* VF function only support hw strip feature, others are not support */
+ if (mask & RTE_ETH_VLAN_STRIP_MASK) {
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ rxq = dev->data->rx_queues[i];
+ on = !!(rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP);
+ ngbevf_vlan_strip_queue_set(dev, i, on);
+ }
+ }
+
+ return 0;
+}
+
+static int
+ngbevf_vlan_offload_set(struct rte_eth_dev *dev, int mask)
+{
+ ngbe_config_vlan_strip_on_all_queues(dev, mask);
+
+ ngbevf_vlan_offload_config(dev, mask);
+
+ return 0;
+}
+
+
static int
ngbevf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
__rte_unused uint32_t index,
@@ -611,6 +721,9 @@ static const struct eth_dev_ops ngbevf_eth_dev_ops = {
.allmulticast_disable = ngbevf_dev_allmulticast_disable,
.dev_infos_get = ngbevf_dev_info_get,
.mtu_set = ngbevf_dev_set_mtu,
+ .vlan_filter_set = ngbevf_vlan_filter_set,
+ .vlan_strip_queue_set = ngbevf_vlan_strip_queue_set,
+ .vlan_offload_set = ngbevf_vlan_offload_set,
.mac_addr_add = ngbevf_add_mac_addr,
.mac_addr_remove = ngbevf_remove_mac_addr,
.mac_addr_set = ngbevf_set_default_mac_addr,
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 09/15] net/ngbe: add interrupt support for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (7 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 08/15] net/ngbe: add vlan related ops " Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 10/15] net/ngbe: add link update ops " Zaiyu Wang
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Add VF device interrupt handler, support to enable and disable RX queue
interrupt, and configure misx interrupt.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
doc/guides/nics/features/ngbe_vf.ini | 1 +
drivers/net/ngbe/ngbe_ethdev_vf.c | 225 +++++++++++++++++++++++++++
2 files changed, 226 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index e365f85e47..e7eaee1e44 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -5,6 +5,7 @@
;
[Features]
Unicast MAC filter = Y
+Rx interrupt = Y
MTU update = Y
Promiscuous mode = Y
Allmulticast mode = Y
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index 193e29d0c1..7783fb6537 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -20,11 +20,15 @@
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);
+static void ngbevf_intr_disable(struct rte_eth_dev *dev);
+static void ngbevf_intr_enable(struct rte_eth_dev *dev);
static int ngbevf_vlan_offload_config(struct rte_eth_dev *dev, int mask);
static void ngbevf_set_vfta_all(struct rte_eth_dev *dev, bool on);
+static void ngbevf_configure_msix(struct rte_eth_dev *dev);
static int ngbevf_dev_promiscuous_enable(struct rte_eth_dev *dev);
static int ngbevf_dev_promiscuous_disable(struct rte_eth_dev *dev);
static void ngbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
+static void ngbevf_dev_interrupt_handler(void *param);
/*
* The set of PCI devices this driver supports (for VF)
@@ -112,6 +116,7 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
int err;
uint32_t tc, tcs;
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
struct ngbe_hw *hw = ngbe_dev_hw(eth_dev);
struct ngbe_vfta *shadow_vfta = NGBE_DEV_VFTA(eth_dev);
struct ngbe_hwstrip *hwstrip = NGBE_DEV_HWSTRIP(eth_dev);
@@ -175,6 +180,9 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
/* init_mailbox_params */
hw->mbx.init_params(hw);
+ /* Disable the interrupts for VF */
+ ngbevf_intr_disable(eth_dev);
+
hw->mac.num_rar_entries = 32; /* The MAX of the underlying PF */
err = hw->mac.reset_hw(hw);
@@ -243,6 +251,11 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
/* enter promiscuous mode */
ngbevf_dev_promiscuous_enable(eth_dev);
+ rte_intr_callback_register(intr_handle,
+ ngbevf_dev_interrupt_handler, eth_dev);
+ rte_intr_enable(intr_handle);
+ ngbevf_intr_enable(eth_dev);
+
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");
@@ -335,6 +348,39 @@ ngbevf_dev_info_get(struct rte_eth_dev *dev,
return 0;
}
+static void
+ngbevf_intr_disable(struct rte_eth_dev *dev)
+{
+ struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+
+ PMD_INIT_FUNC_TRACE();
+
+ /* Clear interrupt mask to stop from interrupts being generated */
+ wr32(hw, NGBE_VFIMS, NGBE_VFIMS_MASK);
+
+ ngbe_flush(hw);
+
+ /* Clear mask value. */
+ intr->mask_misc = NGBE_VFIMS_MASK;
+}
+
+static void
+ngbevf_intr_enable(struct rte_eth_dev *dev)
+{
+ struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+
+ PMD_INIT_FUNC_TRACE();
+
+ /* VF enable interrupt autoclean */
+ wr32(hw, NGBE_VFIMC, NGBE_VFIMC_MASK);
+
+ ngbe_flush(hw);
+
+ intr->mask_misc = 0;
+}
+
static int
ngbevf_dev_configure(struct rte_eth_dev *dev)
{
@@ -373,6 +419,8 @@ static int
ngbevf_dev_close(struct rte_eth_dev *dev)
{
struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
PMD_INIT_FUNC_TRACE();
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
@@ -390,9 +438,16 @@ ngbevf_dev_close(struct rte_eth_dev *dev)
dev->rx_pkt_burst = NULL;
dev->tx_pkt_burst = NULL;
+ /* Disable the interrupts for VF */
+ ngbevf_intr_disable(dev);
+
rte_free(dev->data->mac_addrs);
dev->data->mac_addrs = NULL;
+ rte_intr_disable(intr_handle);
+ rte_intr_callback_unregister(intr_handle,
+ ngbevf_dev_interrupt_handler, dev);
+
return 0;
}
@@ -495,6 +550,112 @@ ngbevf_vlan_offload_set(struct rte_eth_dev *dev, int mask)
return 0;
}
+static int
+ngbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+ struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ uint32_t vec = NGBE_MISC_VEC_ID;
+
+ if (rte_intr_allow_others(intr_handle))
+ vec = NGBE_RX_VEC_START;
+ intr->mask_misc &= ~(1 << vec);
+ RTE_SET_USED(queue_id);
+ wr32(hw, NGBE_VFIMC, ~intr->mask_misc);
+
+ rte_intr_enable(intr_handle);
+
+ return 0;
+}
+
+static int
+ngbevf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+ struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+ uint32_t vec = NGBE_MISC_VEC_ID;
+
+ if (rte_intr_allow_others(intr_handle))
+ vec = NGBE_RX_VEC_START;
+ intr->mask_misc |= (1 << vec);
+ RTE_SET_USED(queue_id);
+ wr32(hw, NGBE_VFIMS, intr->mask_misc);
+
+ return 0;
+}
+
+static void
+ngbevf_set_ivar_map(struct ngbe_hw *hw, int8_t direction,
+ uint8_t queue, uint8_t msix_vector)
+{
+ uint32_t tmp, idx;
+
+ if (direction == -1) {
+ /* other causes */
+ msix_vector |= NGBE_VFIVAR_VLD;
+ tmp = rd32(hw, NGBE_VFIVARMISC);
+ tmp &= ~0xFF;
+ tmp |= msix_vector;
+ wr32(hw, NGBE_VFIVARMISC, tmp);
+ } else {
+ /* rx or tx cause */
+ /* Workaround for ICR lost */
+ idx = ((16 * (queue & 1)) + (8 * direction));
+ tmp = rd32(hw, NGBE_VFIVAR(queue >> 1));
+ tmp &= ~(0xFF << idx);
+ tmp |= (msix_vector << idx);
+ wr32(hw, NGBE_VFIVAR(queue >> 1), tmp);
+ }
+}
+
+static void
+ngbevf_configure_msix(struct rte_eth_dev *dev)
+{
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ uint32_t q_idx;
+ uint32_t vector_idx = NGBE_MISC_VEC_ID;
+ uint32_t base = NGBE_MISC_VEC_ID;
+
+ /* Configure VF other cause ivar */
+ ngbevf_set_ivar_map(hw, -1, 1, vector_idx);
+
+ /* won't configure msix register if no mapping is done
+ * between intr vector and event fd.
+ */
+ if (!rte_intr_dp_is_en(intr_handle))
+ return;
+
+ if (rte_intr_allow_others(intr_handle)) {
+ base = NGBE_RX_VEC_START;
+ vector_idx = NGBE_RX_VEC_START;
+ }
+
+ /* Configure all RX queues of VF */
+ for (q_idx = 0; q_idx < dev->data->nb_rx_queues; q_idx++) {
+ /* Force all queue use vector 0,
+ * as NGBE_VF_MAXMSIVECOTR = 1
+ */
+ ngbevf_set_ivar_map(hw, 0, q_idx, vector_idx);
+ rte_intr_vec_list_index_set(intr_handle, q_idx,
+ vector_idx);
+ if (vector_idx < base + rte_intr_nb_efd_get(intr_handle)
+ - 1)
+ vector_idx++;
+ }
+
+ /* As RX queue setting above show, all queues use the vector 0.
+ * Set only the ITR value of NGBE_MISC_VEC_ID.
+ */
+ wr32(hw, NGBE_ITR(NGBE_MISC_VEC_ID),
+ NGBE_ITR_IVAL(NGBE_QUEUE_ITR_INTERVAL_DEFAULT)
+ | NGBE_ITR_WRDSA);
+}
static int
ngbevf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
@@ -709,6 +870,68 @@ ngbevf_dev_allmulticast_disable(struct rte_eth_dev *dev)
return ret;
}
+static void ngbevf_mbx_process(struct rte_eth_dev *dev)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ u32 in_msg = 0;
+
+ /* peek the message first */
+ in_msg = rd32(hw, NGBE_VFMBX);
+
+ /* PF reset VF event */
+ if (in_msg == NGBE_PF_CONTROL_MSG) {
+ /* dummy mbx read to ack pf */
+ if (ngbe_read_mbx(hw, &in_msg, 1, 0))
+ return;
+ rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
+ NULL);
+ }
+}
+
+static int
+ngbevf_dev_interrupt_get_status(struct rte_eth_dev *dev)
+{
+ uint32_t eicr;
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
+ ngbevf_intr_disable(dev);
+
+ /* read-on-clear nic registers here */
+ eicr = rd32(hw, NGBE_VFICR);
+ intr->flags = 0;
+
+ /* only one misc vector supported - mailbox */
+ eicr &= NGBE_VFICR_MASK;
+ /* Workaround for ICR lost */
+ intr->flags |= NGBE_FLAG_MAILBOX;
+
+ return 0;
+}
+
+static int
+ngbevf_dev_interrupt_action(struct rte_eth_dev *dev)
+{
+ struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
+
+ if (intr->flags & NGBE_FLAG_MAILBOX) {
+ ngbevf_mbx_process(dev);
+ intr->flags &= ~NGBE_FLAG_MAILBOX;
+ }
+
+ ngbevf_intr_enable(dev);
+
+ return 0;
+}
+
+static void
+ngbevf_dev_interrupt_handler(void *param)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+
+ ngbevf_dev_interrupt_get_status(dev);
+ ngbevf_dev_interrupt_action(dev);
+}
+
/*
* dev_ops for virtual function, bare necessities for basic vf
* operation have been implemented
@@ -724,6 +947,8 @@ static const struct eth_dev_ops ngbevf_eth_dev_ops = {
.vlan_filter_set = ngbevf_vlan_filter_set,
.vlan_strip_queue_set = ngbevf_vlan_strip_queue_set,
.vlan_offload_set = ngbevf_vlan_offload_set,
+ .rx_queue_intr_enable = ngbevf_dev_rx_queue_intr_enable,
+ .rx_queue_intr_disable = ngbevf_dev_rx_queue_intr_disable,
.mac_addr_add = ngbevf_add_mac_addr,
.mac_addr_remove = ngbevf_remove_mac_addr,
.mac_addr_set = ngbevf_set_default_mac_addr,
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 10/15] net/ngbe: add link update ops for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (8 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 09/15] net/ngbe: add interrupt support " Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 11/15] net/ngbe: add stats and xstats " Zaiyu Wang
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Add support to check link feature for VF device, including link speed,
duplex mode and link state.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
doc/guides/nics/features/ngbe_vf.ini | 1 +
drivers/net/ngbe/base/ngbe_vf.c | 96 ++++++++++++++++++++++++++++
drivers/net/ngbe/base/ngbe_vf.h | 2 +
drivers/net/ngbe/ngbe_ethdev_vf.c | 9 +++
4 files changed, 108 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index e7eaee1e44..b5c4981195 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -4,6 +4,7 @@
; Refer to default.ini for the full list of available PMD features.
;
[Features]
+Link status = Y
Unicast MAC filter = Y
Rx interrupt = Y
MTU update = Y
diff --git a/drivers/net/ngbe/base/ngbe_vf.c b/drivers/net/ngbe/base/ngbe_vf.c
index d50806876f..b6556520bd 100644
--- a/drivers/net/ngbe/base/ngbe_vf.c
+++ b/drivers/net/ngbe/base/ngbe_vf.c
@@ -335,6 +335,99 @@ s32 ngbevf_set_uc_addr_vf(struct ngbe_hw *hw, u32 index, u8 *addr)
return ret_val;
}
+/**
+ * ngbe_check_mac_link_vf - Get link/speed status
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @link_up: true is link is up, false otherwise
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
+ *
+ * Reads the links register to determine if link is up and the current speed
+ **/
+s32 ngbe_check_mac_link_vf(struct ngbe_hw *hw, u32 *speed,
+ bool *link_up, bool wait_to_complete)
+{
+ /**
+ * for a quick link status checking, wait_to_compelet == 0,
+ * skip PF link status checking
+ */
+ bool no_pflink_check = 0;
+ struct ngbe_mbx_info *mbx = &hw->mbx;
+ struct ngbe_mac_info *mac = &hw->mac;
+ s32 ret_val = 0;
+ u32 links_reg;
+ u32 in_msg = 0;
+
+ UNREFERENCED_PARAMETER(wait_to_complete);
+
+ /* If we were hit with a reset drop the link */
+ if (!mbx->check_for_rst(hw, 0) || !mbx->timeout)
+ mac->get_link_status = true;
+
+ if (!mac->get_link_status)
+ goto out;
+
+ /* if link status is down no point in checking to see if pf is up */
+ links_reg = rd32(hw, NGBE_VFSTATUS);
+ if (!(links_reg & NGBE_VFSTATUS_BW_MASK))
+ goto out;
+
+ /* for SFP+ modules and DA cables it can take up to 500usecs
+ * before the link status is correct
+ */
+ if (mac->type == ngbe_mac_em_vf) {
+ if (po32m(hw, NGBE_VFSTATUS, NGBE_VFSTATUS_BW_MASK,
+ 0, NULL, 5, 100))
+ goto out;
+ }
+
+ if (links_reg & NGBE_VFSTATUS_BW_1G)
+ *speed = NGBE_LINK_SPEED_1GB_FULL;
+ else if (links_reg & NGBE_VFSTATUS_BW_100M)
+ *speed = NGBE_LINK_SPEED_100M_FULL;
+ else if (links_reg & NGBE_VFSTATUS_BW_10M)
+ *speed = NGBE_LINK_SPEED_10M_FULL;
+ else
+ *speed = NGBE_LINK_SPEED_UNKNOWN;
+
+ if (no_pflink_check) {
+ if (*speed == NGBE_LINK_SPEED_UNKNOWN)
+ mac->get_link_status = true;
+ else
+ mac->get_link_status = false;
+
+ goto out;
+ }
+
+ /* if the read failed it could just be a mailbox collision, best wait
+ * until we are called again and don't report an error
+ */
+ if (mbx->read(hw, &in_msg, 1, 0))
+ goto out;
+
+ if (!(in_msg & NGBE_VT_MSGTYPE_CTS)) {
+ /* msg is not CTS and is NACK we must have lost CTS status */
+ if (in_msg & NGBE_VT_MSGTYPE_NACK)
+ ret_val = -1;
+ goto out;
+ }
+
+ /* the pf is talking, if we timed out in the past we reinit */
+ if (!mbx->timeout) {
+ ret_val = -1;
+ goto out;
+ }
+
+ /* if we passed all the tests above then the link is up and we no
+ * longer need to check for link
+ */
+ mac->get_link_status = false;
+
+out:
+ *link_up = !mac->get_link_status;
+ return ret_val;
+}
+
/**
* ngbevf_rlpml_set_vf - Set the maximum receive packet length
* @hw: pointer to the HW structure
@@ -469,6 +562,9 @@ s32 ngbe_init_ops_vf(struct ngbe_hw *hw)
mac->get_mac_addr = ngbe_get_mac_addr_vf;
mac->negotiate_api_version = ngbevf_negotiate_api_version;
+ /* Link */
+ mac->check_link = ngbe_check_mac_link_vf;
+
/* RAR, Multicast, VLAN */
mac->set_rar = ngbe_set_rar_vf;
mac->set_uc_addr = ngbevf_set_uc_addr_vf;
diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h
index 596f41dcb0..5cf225dd35 100644
--- a/drivers/net/ngbe/base/ngbe_vf.h
+++ b/drivers/net/ngbe/base/ngbe_vf.h
@@ -17,6 +17,8 @@ s32 ngbe_start_hw_vf(struct ngbe_hw *hw);
s32 ngbe_reset_hw_vf(struct ngbe_hw *hw);
s32 ngbe_stop_hw_vf(struct ngbe_hw *hw);
s32 ngbe_get_mac_addr_vf(struct ngbe_hw *hw, u8 *mac_addr);
+s32 ngbe_check_mac_link_vf(struct ngbe_hw *hw, u32 *speed,
+ bool *link_up, bool autoneg_wait_to_complete);
s32 ngbe_set_rar_vf(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
u32 enable_addr);
s32 ngbevf_set_uc_addr_vf(struct ngbe_hw *hw, u32 index, u8 *addr);
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index 7783fb6537..1f3f957d8a 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -20,6 +20,8 @@
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);
+static int ngbevf_dev_link_update(struct rte_eth_dev *dev,
+ int wait_to_complete);
static void ngbevf_intr_disable(struct rte_eth_dev *dev);
static void ngbevf_intr_enable(struct rte_eth_dev *dev);
static int ngbevf_vlan_offload_config(struct rte_eth_dev *dev, int mask);
@@ -348,6 +350,12 @@ ngbevf_dev_info_get(struct rte_eth_dev *dev,
return 0;
}
+static int
+ngbevf_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+ return ngbe_dev_link_update_share(dev, wait_to_complete);
+}
+
static void
ngbevf_intr_disable(struct rte_eth_dev *dev)
{
@@ -938,6 +946,7 @@ ngbevf_dev_interrupt_handler(void *param)
*/
static const struct eth_dev_ops ngbevf_eth_dev_ops = {
.dev_configure = ngbevf_dev_configure,
+ .link_update = ngbevf_dev_link_update,
.promiscuous_enable = ngbevf_dev_promiscuous_enable,
.promiscuous_disable = ngbevf_dev_promiscuous_disable,
.allmulticast_enable = ngbevf_dev_allmulticast_enable,
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 11/15] net/ngbe: add stats and xstats ops for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (9 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 10/15] net/ngbe: add link update ops " Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 12/15] net/ngbe: add start/stop/reset/close " Zaiyu Wang
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Add support to get stats and extended stats by reading hardware
registers
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
doc/guides/nics/features/ngbe_vf.ini | 2 +
drivers/net/ngbe/base/ngbe_vf.h | 32 +++++++
drivers/net/ngbe/ngbe_ethdev_vf.c | 137 +++++++++++++++++++++++++++
3 files changed, 171 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index b5c4981195..0c26db73f9 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -24,6 +24,8 @@ Rx descriptor status = Y
Tx descriptor status = Y
Inner L3 checksum = P
Inner L4 checksum = P
+Basic stats = Y
+Extended stats = Y
Multiprocess aware = Y
Linux = Y
ARMv8 = Y
diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h
index 5cf225dd35..abe1655f8e 100644
--- a/drivers/net/ngbe/base/ngbe_vf.h
+++ b/drivers/net/ngbe/base/ngbe_vf.h
@@ -11,6 +11,38 @@
#define NGBE_VF_MAX_TX_QUEUES 1
#define NGBE_VF_MAX_RX_QUEUES 1
+struct ngbevf_hw_stats {
+ u64 base_vfgprc;
+ u64 base_vfgptc;
+ u64 base_vfgorc;
+ u64 base_vfgotc;
+ u64 base_vfmprc;
+
+ u64 last_vfgprc;
+ u64 last_vfgptc;
+ u64 last_vfgorc;
+ u64 last_vfgotc;
+ u64 last_vfmprc;
+ u64 last_vfbprc;
+ u64 last_vfmptc;
+ u64 last_vfbptc;
+
+ u64 vfgprc;
+ u64 vfgptc;
+ u64 vfgorc;
+ u64 vfgotc;
+ u64 vfmprc;
+ u64 vfbprc;
+ u64 vfmptc;
+ u64 vfbptc;
+
+ u64 saved_reset_vfgprc;
+ u64 saved_reset_vfgptc;
+ u64 saved_reset_vfgorc;
+ u64 saved_reset_vfgotc;
+ u64 saved_reset_vfmprc;
+};
+
s32 ngbe_init_ops_vf(struct ngbe_hw *hw);
s32 ngbe_init_hw_vf(struct ngbe_hw *hw);
s32 ngbe_start_hw_vf(struct ngbe_hw *hw);
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index 1f3f957d8a..434776b26b 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -67,6 +67,13 @@ static const struct rte_eth_desc_lim tx_desc_lim = {
static const struct eth_dev_ops ngbevf_eth_dev_ops;
+static const struct rte_ngbe_xstats_name_off rte_ngbevf_stats_strings[] = {
+ {"rx_multicast_packets", offsetof(struct ngbevf_hw_stats, vfmprc)},
+};
+
+#define NGBEVF_NB_XSTATS (sizeof(rte_ngbevf_stats_strings) / \
+ sizeof(rte_ngbevf_stats_strings[0]))
+
/*
* Negotiate mailbox API version with the PF.
* After reset API version is always set to the basic one (ngbe_mbox_api_10).
@@ -182,6 +189,9 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
/* init_mailbox_params */
hw->mbx.init_params(hw);
+ /* Reset the hw statistics */
+ ngbevf_dev_stats_reset(eth_dev);
+
/* Disable the interrupts for VF */
ngbevf_intr_disable(eth_dev);
@@ -301,6 +311,128 @@ static struct rte_pci_driver rte_ngbevf_pmd = {
.remove = eth_ngbevf_pci_remove,
};
+static int ngbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names, unsigned int limit)
+{
+ unsigned int i;
+
+ if (limit < NGBEVF_NB_XSTATS && xstats_names != NULL)
+ return -ENOMEM;
+
+ if (xstats_names != NULL)
+ for (i = 0; i < NGBEVF_NB_XSTATS; i++)
+ snprintf(xstats_names[i].name,
+ sizeof(xstats_names[i].name),
+ "%s", rte_ngbevf_stats_strings[i].name);
+ return NGBEVF_NB_XSTATS;
+}
+
+static void
+ngbevf_update_stats(struct rte_eth_dev *dev)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ struct ngbevf_hw_stats *hw_stats = (struct ngbevf_hw_stats *)
+ NGBE_DEV_STATS(dev);
+
+ /* Good Rx packet, include VF loopback */
+ NGBE_UPDCNT32(NGBE_QPRXPKT(0),
+ hw_stats->last_vfgprc, hw_stats->vfgprc);
+
+ /* Good Rx octets, include VF loopback */
+ NGBE_UPDCNT36(NGBE_QPRXOCTL(0),
+ hw_stats->last_vfgorc, hw_stats->vfgorc);
+
+ /* Rx Multicst Packet */
+ NGBE_UPDCNT32(NGBE_QPRXMPKT(0),
+ hw_stats->last_vfmprc, hw_stats->vfmprc);
+
+ /* Rx Broadcast Packet */
+ NGBE_UPDCNT32(NGBE_QPRXBPKT(0),
+ hw_stats->last_vfbprc, hw_stats->vfbprc);
+
+ hw->rx_loaded = 0;
+
+ /* Good Tx packet, include VF loopback */
+ NGBE_UPDCNT32(NGBE_QPTXPKT(0),
+ hw_stats->last_vfgptc, hw_stats->vfgptc);
+
+ /* Good Tx octets, include VF loopback */
+ NGBE_UPDCNT36(NGBE_QPTXOCTL(0),
+ hw_stats->last_vfgotc, hw_stats->vfgotc);
+
+ /* Tx Multicst Packet */
+ NGBE_UPDCNT32(NGBE_QPTXMPKT(0),
+ hw_stats->last_vfmprc, hw_stats->vfmprc);
+
+ /* Tx Broadcast Packet */
+ NGBE_UPDCNT32(NGBE_QPTXBPKT(0),
+ hw_stats->last_vfbptc, hw_stats->vfbptc);
+
+ hw->offset_loaded = 0;
+}
+
+static int
+ngbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
+ unsigned int n)
+{
+ struct ngbevf_hw_stats *hw_stats = (struct ngbevf_hw_stats *)
+ NGBE_DEV_STATS(dev);
+ unsigned int i;
+
+ if (n < NGBEVF_NB_XSTATS)
+ return NGBEVF_NB_XSTATS;
+
+ ngbevf_update_stats(dev);
+
+ if (!xstats)
+ return 0;
+
+ /* Extended stats */
+ for (i = 0; i < NGBEVF_NB_XSTATS; i++) {
+ xstats[i].id = i;
+ xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+ rte_ngbevf_stats_strings[i].offset);
+ }
+
+ return NGBEVF_NB_XSTATS;
+}
+
+static int
+ngbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+ struct ngbevf_hw_stats *hw_stats = (struct ngbevf_hw_stats *)
+ NGBE_DEV_STATS(dev);
+
+ ngbevf_update_stats(dev);
+
+ if (stats == NULL)
+ return -EINVAL;
+
+ stats->ipackets = hw_stats->vfgprc;
+ stats->ibytes = hw_stats->vfgorc;
+ stats->opackets = hw_stats->vfgptc;
+ stats->obytes = hw_stats->vfgotc;
+ return 0;
+}
+
+static int
+ngbevf_dev_stats_reset(struct rte_eth_dev *dev)
+{
+ struct ngbevf_hw_stats *hw_stats = (struct ngbevf_hw_stats *)
+ NGBE_DEV_STATS(dev);
+
+ /* Sync HW register to the last stats */
+ ngbevf_dev_stats_get(dev, NULL);
+
+ /* reset HW current stats*/
+ hw_stats->vfgprc = 0;
+ hw_stats->vfgorc = 0;
+ hw_stats->vfgptc = 0;
+ hw_stats->vfgotc = 0;
+
+ return 0;
+}
+
static int
ngbevf_dev_info_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info)
@@ -947,6 +1079,11 @@ ngbevf_dev_interrupt_handler(void *param)
static const struct eth_dev_ops ngbevf_eth_dev_ops = {
.dev_configure = ngbevf_dev_configure,
.link_update = ngbevf_dev_link_update,
+ .stats_get = ngbevf_dev_stats_get,
+ .xstats_get = ngbevf_dev_xstats_get,
+ .stats_reset = ngbevf_dev_stats_reset,
+ .xstats_reset = ngbevf_dev_stats_reset,
+ .xstats_get_names = ngbevf_dev_xstats_get_names,
.promiscuous_enable = ngbevf_dev_promiscuous_enable,
.promiscuous_disable = ngbevf_dev_promiscuous_disable,
.allmulticast_enable = ngbevf_dev_allmulticast_enable,
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 12/15] net/ngbe: add start/stop/reset/close ops for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (10 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 11/15] net/ngbe: add stats and xstats " Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 13/15] net/ngbe: add multicast MAC filter " Zaiyu Wang
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Add the complete configuration process for start/stop/reset/close ops,
so that applications can enable the device correctly.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
drivers/net/ngbe/ngbe_ethdev_vf.c | 170 +++++++++++++++++++++++++++++-
1 file changed, 169 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index 434776b26b..ac02b7ac7f 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -555,12 +555,151 @@ ngbevf_dev_configure(struct rte_eth_dev *dev)
return 0;
}
+static int
+ngbevf_dev_start(struct rte_eth_dev *dev)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ uint32_t intr_vector = 0;
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+
+ int err, mask = 0;
+
+ PMD_INIT_FUNC_TRACE();
+
+ err = hw->mac.reset_hw(hw);
+ if (err) {
+ PMD_INIT_LOG(ERR, "Unable to reset vf hardware (%d)", err);
+ return err;
+ }
+ hw->mac.get_link_status = true;
+
+ /* negotiate mailbox API version to use with the PF. */
+ ngbevf_negotiate_api(hw);
+
+ ngbevf_dev_tx_init(dev);
+
+ /* This can fail when allocating mbufs for descriptor rings */
+ err = ngbevf_dev_rx_init(dev);
+
+ /**
+ * In this case, reuses the MAC address assigned by VF
+ * initialization.
+ */
+ if (err != 0 && err != NGBE_ERR_INVALID_MAC_ADDR) {
+ PMD_INIT_LOG(ERR, "Unable to initialize RX hardware (%d)", err);
+ ngbe_dev_clear_queues(dev);
+ return err;
+ }
+
+ /* Set vfta */
+ ngbevf_set_vfta_all(dev, 1);
+
+ /* Set HW strip */
+ mask = RTE_ETH_VLAN_STRIP_MASK | RTE_ETH_VLAN_FILTER_MASK |
+ RTE_ETH_VLAN_EXTEND_MASK;
+ err = ngbevf_vlan_offload_config(dev, mask);
+ if (err) {
+ PMD_INIT_LOG(ERR, "Unable to set VLAN offload (%d)", err);
+ ngbe_dev_clear_queues(dev);
+ return err;
+ }
+
+ ngbevf_dev_rxtx_start(dev);
+
+ /* check and configure queue intr-vector mapping */
+ if (rte_intr_cap_multiple(intr_handle) &&
+ dev->data->dev_conf.intr_conf.rxq) {
+ /* According to datasheet, only vector 0/1/2 can be used,
+ * now only one vector is used for Rx queue
+ */
+ intr_vector = 1;
+ if (rte_intr_efd_enable(intr_handle, intr_vector))
+ return -1;
+ }
+
+ if (rte_intr_dp_is_en(intr_handle)) {
+ if (rte_intr_vec_list_alloc(intr_handle, "intr_vec",
+ dev->data->nb_rx_queues)) {
+ PMD_INIT_LOG(ERR,
+ "Failed to allocate %d rx_queues intr_vec",
+ dev->data->nb_rx_queues);
+ return -ENOMEM;
+ }
+ }
+
+ ngbevf_configure_msix(dev);
+
+ /* When a VF port is bound to VFIO-PCI, only miscellaneous interrupt
+ * is mapped to VFIO vector 0 in eth_ngbevf_dev_init( ).
+ * If previous VFIO interrupt mapping setting in eth_ngbevf_dev_init( )
+ * is not cleared, it will fail when following rte_intr_enable( ) tries
+ * to map Rx queue interrupt to other VFIO vectors.
+ * So clear uio/vfio intr/evevnfd first to avoid failure.
+ */
+ rte_intr_disable(intr_handle);
+
+ rte_intr_enable(intr_handle);
+
+ /* Re-enable interrupt for VF */
+ ngbevf_intr_enable(dev);
+
+ /*
+ * Update link status right before return, because it may
+ * start link configuration process in a separate thread.
+ */
+ ngbevf_dev_link_update(dev, 0);
+
+ hw->adapter_stopped = false;
+
+ return 0;
+}
+
+static int
+ngbevf_dev_stop(struct rte_eth_dev *dev)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ struct ngbe_adapter *adapter = ngbe_dev_adapter(dev);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+
+ if (hw->adapter_stopped)
+ return 0;
+
+ PMD_INIT_FUNC_TRACE();
+
+ ngbevf_intr_disable(dev);
+
+ hw->adapter_stopped = 1;
+ hw->mac.stop_hw(hw);
+
+ /*
+ * Clear what we set, but we still keep shadow_vfta to
+ * restore after device starts
+ */
+ ngbevf_set_vfta_all(dev, 0);
+
+ /* Clear stored conf */
+ dev->data->scattered_rx = 0;
+
+ ngbe_dev_clear_queues(dev);
+
+ /* Clean datapath event and queue/vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ rte_intr_vec_list_free(intr_handle);
+
+ adapter->rss_reta_updated = 0;
+
+ return 0;
+}
+
static int
ngbevf_dev_close(struct rte_eth_dev *dev)
{
struct ngbe_hw *hw = ngbe_dev_hw(dev);
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+ int ret;
PMD_INIT_FUNC_TRACE();
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
@@ -568,6 +707,10 @@ ngbevf_dev_close(struct rte_eth_dev *dev)
hw->mac.reset_hw(hw);
+ ret = ngbevf_dev_stop(dev);
+
+ ngbe_dev_free_queues(dev);
+
/**
* Remove the VF MAC address ro ensure
* that the VF traffic goes to the PF
@@ -588,7 +731,24 @@ ngbevf_dev_close(struct rte_eth_dev *dev)
rte_intr_callback_unregister(intr_handle,
ngbevf_dev_interrupt_handler, dev);
- return 0;
+ return ret;
+}
+
+/*
+ * Reset VF device
+ */
+static int
+ngbevf_dev_reset(struct rte_eth_dev *dev)
+{
+ int ret;
+
+ ret = eth_ngbevf_dev_uninit(dev);
+ if (ret)
+ return ret;
+
+ ret = eth_ngbevf_dev_init(dev);
+
+ return ret;
}
static void ngbevf_set_vfta_all(struct rte_eth_dev *dev, bool on)
@@ -1078,12 +1238,16 @@ ngbevf_dev_interrupt_handler(void *param)
*/
static const struct eth_dev_ops ngbevf_eth_dev_ops = {
.dev_configure = ngbevf_dev_configure,
+ .dev_start = ngbevf_dev_start,
+ .dev_stop = ngbevf_dev_stop,
.link_update = ngbevf_dev_link_update,
.stats_get = ngbevf_dev_stats_get,
.xstats_get = ngbevf_dev_xstats_get,
.stats_reset = ngbevf_dev_stats_reset,
.xstats_reset = ngbevf_dev_stats_reset,
.xstats_get_names = ngbevf_dev_xstats_get_names,
+ .dev_close = ngbevf_dev_close,
+ .dev_reset = ngbevf_dev_reset,
.promiscuous_enable = ngbevf_dev_promiscuous_enable,
.promiscuous_disable = ngbevf_dev_promiscuous_disable,
.allmulticast_enable = ngbevf_dev_allmulticast_enable,
@@ -1093,6 +1257,10 @@ static const struct eth_dev_ops ngbevf_eth_dev_ops = {
.vlan_filter_set = ngbevf_vlan_filter_set,
.vlan_strip_queue_set = ngbevf_vlan_strip_queue_set,
.vlan_offload_set = ngbevf_vlan_offload_set,
+ .rx_queue_setup = ngbe_dev_rx_queue_setup,
+ .rx_queue_release = ngbe_dev_rx_queue_release,
+ .tx_queue_setup = ngbe_dev_tx_queue_setup,
+ .tx_queue_release = ngbe_dev_tx_queue_release,
.rx_queue_intr_enable = ngbevf_dev_rx_queue_intr_enable,
.rx_queue_intr_disable = ngbevf_dev_rx_queue_intr_disable,
.mac_addr_add = ngbevf_add_mac_addr,
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 13/15] net/ngbe: add multicast MAC filter ops for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (11 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 12/15] net/ngbe: add start/stop/reset/close " Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 14/15] net/ngbe: add dump registers " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 15/15] net/ngbe: add some ops which PF has implemented Zaiyu Wang
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Add support to update multicast MAC filter.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
doc/guides/nics/features/ngbe_vf.ini | 1 +
drivers/net/ngbe/base/ngbe_vf.c | 81 ++++++++++++++++++++++++++++
drivers/net/ngbe/base/ngbe_vf.h | 3 ++
3 files changed, 85 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index 0c26db73f9..55763a311a 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -6,6 +6,7 @@
[Features]
Link status = Y
Unicast MAC filter = Y
+Multicast MAC filter = Y
Rx interrupt = Y
MTU update = Y
Promiscuous mode = Y
diff --git a/drivers/net/ngbe/base/ngbe_vf.c b/drivers/net/ngbe/base/ngbe_vf.c
index b6556520bd..7b976661a9 100644
--- a/drivers/net/ngbe/base/ngbe_vf.c
+++ b/drivers/net/ngbe/base/ngbe_vf.c
@@ -179,6 +179,39 @@ s32 ngbe_stop_hw_vf(struct ngbe_hw *hw)
return 0;
}
+/**
+ * ngbe_mta_vector - Determines bit-vector in multicast table to set
+ * @hw: pointer to hardware structure
+ * @mc_addr: the multicast address
+ **/
+STATIC s32 ngbe_mta_vector(struct ngbe_hw *hw, u8 *mc_addr)
+{
+ u32 vector = 0;
+
+ switch (hw->mac.mc_filter_type) {
+ case 0: /* use bits [47:36] of the address */
+ vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
+ break;
+ case 1: /* use bits [46:35] of the address */
+ vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
+ break;
+ case 2: /* use bits [45:34] of the address */
+ vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
+ break;
+ case 3: /* use bits [43:32] of the address */
+ vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
+ break;
+ default: /* Invalid mc_filter_type */
+ DEBUGOUT("MC filter type param set incorrectly");
+ ASSERT(0);
+ break;
+ }
+
+ /* vector can only be 12-bits or boundary will be exceeded */
+ vector &= 0xFFF;
+ return vector;
+}
+
STATIC s32 ngbevf_write_msg_read_ack(struct ngbe_hw *hw, u32 *msg,
u32 *retmsg, u16 size)
{
@@ -224,6 +257,53 @@ s32 ngbe_set_rar_vf(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
return ret_val;
}
+/**
+ * ngbe_update_mc_addr_list_vf - Update Multicast addresses
+ * @hw: pointer to the HW structure
+ * @mc_addr_list: array of multicast addresses to program
+ * @mc_addr_count: number of multicast addresses to program
+ * @next: caller supplied function to return next address in list
+ * @clear: unused
+ *
+ * Updates the Multicast Table Array.
+ **/
+s32 ngbe_update_mc_addr_list_vf(struct ngbe_hw *hw, u8 *mc_addr_list,
+ u32 mc_addr_count, ngbe_mc_addr_itr next,
+ bool clear)
+{
+ struct ngbe_mbx_info *mbx = &hw->mbx;
+ u32 msgbuf[NGBE_P2VMBX_SIZE];
+ u16 *vector_list = (u16 *)&msgbuf[1];
+ u32 vector;
+ u32 cnt, i;
+ u32 vmdq;
+
+ UNREFERENCED_PARAMETER(clear);
+
+ /* Each entry in the list uses 1 16 bit word. We have 30
+ * 16 bit words available in our HW msg buffer (minus 1 for the
+ * msg type). That's 30 hash values if we pack 'em right. If
+ * there are more than 30 MC addresses to add then punt the
+ * extras for now and then add code to handle more than 30 later.
+ * It would be unusual for a server to request that many multi-cast
+ * addresses except for in large enterprise network environments.
+ */
+
+ DEBUGOUT("MC Addr Count = %d", mc_addr_count);
+
+ cnt = (mc_addr_count > 30) ? 30 : mc_addr_count;
+ msgbuf[0] = NGBE_VF_SET_MULTICAST;
+ msgbuf[0] |= cnt << NGBE_VT_MSGINFO_SHIFT;
+
+ for (i = 0; i < cnt; i++) {
+ vector = ngbe_mta_vector(hw, next(hw, &mc_addr_list, &vmdq));
+ DEBUGOUT("Hash value = 0x%03X", vector);
+ vector_list[i] = (u16)vector;
+ }
+
+ return mbx->write_posted(hw, msgbuf, NGBE_P2VMBX_SIZE, 0);
+}
+
/**
* ngbevf_update_xcast_mode - Update Multicast mode
* @hw: pointer to the HW structure
@@ -568,6 +648,7 @@ s32 ngbe_init_ops_vf(struct ngbe_hw *hw)
/* RAR, Multicast, VLAN */
mac->set_rar = ngbe_set_rar_vf;
mac->set_uc_addr = ngbevf_set_uc_addr_vf;
+ mac->update_mc_addr_list = ngbe_update_mc_addr_list_vf;
mac->update_xcast_mode = ngbevf_update_xcast_mode;
mac->set_vfta = ngbe_set_vfta_vf;
mac->set_rlpml = ngbevf_rlpml_set_vf;
diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h
index abe1655f8e..5621ca49cb 100644
--- a/drivers/net/ngbe/base/ngbe_vf.h
+++ b/drivers/net/ngbe/base/ngbe_vf.h
@@ -54,6 +54,9 @@ s32 ngbe_check_mac_link_vf(struct ngbe_hw *hw, u32 *speed,
s32 ngbe_set_rar_vf(struct ngbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
u32 enable_addr);
s32 ngbevf_set_uc_addr_vf(struct ngbe_hw *hw, u32 index, u8 *addr);
+s32 ngbe_update_mc_addr_list_vf(struct ngbe_hw *hw, u8 *mc_addr_list,
+ u32 mc_addr_count, ngbe_mc_addr_itr next,
+ bool clear);
s32 ngbevf_update_xcast_mode(struct ngbe_hw *hw, int xcast_mode);
s32 ngbe_set_vfta_vf(struct ngbe_hw *hw, u32 vlan, u32 vind,
bool vlan_on, bool vlvf_bypass);
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 14/15] net/ngbe: add dump registers ops for VF device
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (12 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 13/15] net/ngbe: add multicast MAC filter " Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
2025-01-09 4:02 ` [PATCH 15/15] net/ngbe: add some ops which PF has implemented Zaiyu Wang
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Add support to dump registers for VF device. Currently we only support a
small number of registers. More registers will be added as needed.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
doc/guides/nics/features/ngbe_vf.ini | 1 +
drivers/net/ngbe/ngbe_ethdev_vf.c | 73 ++++++++++++++++++++++++++++
2 files changed, 74 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index 55763a311a..497b1031b3 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -27,6 +27,7 @@ Inner L3 checksum = P
Inner L4 checksum = P
Basic stats = Y
Extended stats = Y
+Registers dump = Y
Multiprocess aware = Y
Linux = Y
ARMv8 = Y
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index ac02b7ac7f..9b2c899c74 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -16,6 +16,35 @@
#include "ngbe_rxtx.h"
#include "ngbe_regs_group.h"
+static const struct reg_info ngbevf_regs_general[] = {
+ {NGBE_VFRST, 1, 1, "NGBE_VFRST"},
+ {NGBE_VFSTATUS, 1, 1, "NGBE_VFSTATUS"},
+ {NGBE_VFMBCTL, 1, 1, "NGBE_VFMAILBOX"},
+ {NGBE_VFMBX, 16, 4, "NGBE_VFMBX"},
+ {NGBE_VFPBWRAP, 1, 1, "NGBE_VFPBWRAP"},
+ {0, 0, 0, ""}
+};
+
+static const struct reg_info ngbevf_regs_interrupt[] = {
+ {0, 0, 0, ""}
+};
+
+static const struct reg_info ngbevf_regs_rxdma[] = {
+ {0, 0, 0, ""}
+};
+
+static const struct reg_info ngbevf_regs_tx[] = {
+ {0, 0, 0, ""}
+};
+
+/* VF registers */
+static const struct reg_info *ngbevf_regs[] = {
+ ngbevf_regs_general,
+ ngbevf_regs_interrupt,
+ ngbevf_regs_rxdma,
+ ngbevf_regs_tx,
+ NULL};
+
#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);
@@ -1083,6 +1112,49 @@ ngbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
return 0;
}
+static int
+ngbevf_get_reg_length(struct rte_eth_dev *dev __rte_unused)
+{
+ int count = 0;
+ int g_ind = 0;
+ const struct reg_info *reg_group;
+
+ while ((reg_group = ngbevf_regs[g_ind++]))
+ count += ngbe_regs_group_count(reg_group);
+
+ return count;
+}
+
+static int
+ngbevf_get_regs(struct rte_eth_dev *dev,
+ struct rte_dev_reg_info *regs)
+{
+ struct ngbe_hw *hw = ngbe_dev_hw(dev);
+ uint32_t *data = regs->data;
+ int g_ind = 0;
+ int count = 0;
+ const struct reg_info *reg_group;
+
+ if (data == NULL) {
+ regs->length = ngbevf_get_reg_length(dev);
+ regs->width = sizeof(uint32_t);
+ return 0;
+ }
+
+ /* Support only full register dump */
+ if (regs->length == 0 ||
+ regs->length == (uint32_t)ngbevf_get_reg_length(dev)) {
+ regs->version = hw->mac.type << 24 | hw->revision_id << 16 |
+ hw->device_id;
+ while ((reg_group = ngbevf_regs[g_ind++]))
+ count += ngbe_read_regs_group(dev, &data[count],
+ reg_group);
+ return 0;
+ }
+
+ return -ENOTSUP;
+}
+
static int
ngbevf_dev_promiscuous_enable(struct rte_eth_dev *dev)
{
@@ -1266,6 +1338,7 @@ static const struct eth_dev_ops ngbevf_eth_dev_ops = {
.mac_addr_add = ngbevf_add_mac_addr,
.mac_addr_remove = ngbevf_remove_mac_addr,
.mac_addr_set = ngbevf_set_default_mac_addr,
+ .get_reg = ngbevf_get_regs,
};
RTE_PMD_REGISTER_PCI(net_ngbe_vf, rte_ngbevf_pmd);
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 15/15] net/ngbe: add some ops which PF has implemented
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
` (13 preceding siblings ...)
2025-01-09 4:02 ` [PATCH 14/15] net/ngbe: add dump registers " Zaiyu Wang
@ 2025-01-09 4:02 ` Zaiyu Wang
14 siblings, 0 replies; 16+ messages in thread
From: Zaiyu Wang @ 2025-01-09 4:02 UTC (permalink / raw)
To: dev; +Cc: Zaiyu Wang, Jiawen Wu
Some RXTX operations like queue setup and release, packet type get, and
Tx done cleanup have been supported on PF device. There are ops
functions directly added.
Signed-off-by: Zaiyu Wang <zaiyuwang@trustnetic.com>
---
doc/guides/nics/features/ngbe_vf.ini | 3 +++
drivers/net/ngbe/ngbe_ethdev_vf.c | 5 +++++
2 files changed, 8 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini
index 497b1031b3..b340e75a49 100644
--- a/doc/guides/nics/features/ngbe_vf.ini
+++ b/doc/guides/nics/features/ngbe_vf.ini
@@ -16,15 +16,18 @@ Scattered Rx = Y
LRO = Y
TSO = Y
VLAN filter = Y
+Inline crypto = Y
CRC offload = P
VLAN offload = P
QinQ offload = P
L3 checksum offload = P
L4 checksum offload = P
+Packet type parsing = Y
Rx descriptor status = Y
Tx descriptor status = Y
Inner L3 checksum = P
Inner L4 checksum = P
+Free Tx mbuf on demand = Y
Basic stats = Y
Extended stats = Y
Registers dump = Y
diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c
index 9b2c899c74..19bcd1ac8b 100644
--- a/drivers/net/ngbe/ngbe_ethdev_vf.c
+++ b/drivers/net/ngbe/ngbe_ethdev_vf.c
@@ -1325,6 +1325,7 @@ static const struct eth_dev_ops ngbevf_eth_dev_ops = {
.allmulticast_enable = ngbevf_dev_allmulticast_enable,
.allmulticast_disable = ngbevf_dev_allmulticast_disable,
.dev_infos_get = ngbevf_dev_info_get,
+ .dev_supported_ptypes_get = ngbe_dev_supported_ptypes_get,
.mtu_set = ngbevf_dev_set_mtu,
.vlan_filter_set = ngbevf_vlan_filter_set,
.vlan_strip_queue_set = ngbevf_vlan_strip_queue_set,
@@ -1337,8 +1338,12 @@ static const struct eth_dev_ops ngbevf_eth_dev_ops = {
.rx_queue_intr_disable = ngbevf_dev_rx_queue_intr_disable,
.mac_addr_add = ngbevf_add_mac_addr,
.mac_addr_remove = ngbevf_remove_mac_addr,
+ .set_mc_addr_list = ngbe_dev_set_mc_addr_list,
+ .rxq_info_get = ngbe_rxq_info_get,
+ .txq_info_get = ngbe_txq_info_get,
.mac_addr_set = ngbevf_set_default_mac_addr,
.get_reg = ngbevf_get_regs,
+ .tx_done_cleanup = ngbe_dev_tx_done_cleanup,
};
RTE_PMD_REGISTER_PCI(net_ngbe_vf, rte_ngbevf_pmd);
--
2.21.0.windows.1
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2025-01-09 4:05 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-01-09 4:02 [PATCH 00/15] net/ngbe: add VF driver support Zaiyu Wang
2025-01-09 4:02 ` [PATCH 01/15] net/ngbe: add ethdev probe and remove for VF device Zaiyu Wang
2025-01-09 4:02 ` [PATCH 02/15] net/ngbe: add support for PF-VF mailbox interface Zaiyu Wang
2025-01-09 4:02 ` [PATCH 03/15] net/ngbe: add hardware configuration code for VF device Zaiyu Wang
2025-01-09 4:02 ` [PATCH 04/15] net/ngbe: add promiscuous and allmulticast ops " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 05/15] net/ngbe: add set MTU " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 06/15] net/ngbe: add add/remove/set mac addr " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 07/15] net/ngbe: add datapath init code " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 08/15] net/ngbe: add vlan related ops " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 09/15] net/ngbe: add interrupt support " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 10/15] net/ngbe: add link update ops " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 11/15] net/ngbe: add stats and xstats " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 12/15] net/ngbe: add start/stop/reset/close " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 13/15] net/ngbe: add multicast MAC filter " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 14/15] net/ngbe: add dump registers " Zaiyu Wang
2025-01-09 4:02 ` [PATCH 15/15] net/ngbe: add some ops which PF has implemented Zaiyu Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).