From: Zaiyu Wang <zaiyuwang@trustnetic.com>
To: dev@dpdk.org
Cc: Zaiyu Wang <zaiyuwang@trustnetic.com>,
Jiawen Wu <jiawenwu@trustnetic.com>
Subject: [PATCH 03/15] net/ngbe: add hardware configuration code for VF device
Date: Thu, 9 Jan 2025 12:02:13 +0800 [thread overview]
Message-ID: <20250109040227.1016-4-zaiyuwang@trustnetic.com> (raw)
In-Reply-To: <20250109040227.1016-1-zaiyuwang@trustnetic.com>
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
next prev parent reply other threads:[~2025-01-09 4:03 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
2025-01-09 4:02 ` [PATCH 04/15] net/ngbe: add promiscuous and allmulticast ops for VF device 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250109040227.1016-4-zaiyuwang@trustnetic.com \
--to=zaiyuwang@trustnetic.com \
--cc=dev@dpdk.org \
--cc=jiawenwu@trustnetic.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).