* [PATCH v1 00/13] net/sxe2: fix bugs
@ 2026-08-18 2:15 liujie5
2026-08-18 2:15 ` [PATCH v1 01/13] net/sxe2: add Rx queue buffer split fill support liujie5
` (13 more replies)
0 siblings, 14 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
Jie Liu (13):
net/sxe2: add Rx queue buffer split fill support
net/sxe2: update switchdev repr VSI ID display format
net/sxe2: add ACL engine event statistics support
net/sxe2: enhance device cap and res management
net/sxe2: improve representor device initialization
net/sxe2: refactor flow tunnel port handling
net/sxe2: validate IPsec key length against maximum limit
net/sxe2: enhance repr event handling and MP code
net/sxe2: optimize vectorized Tx/Rx path
common/sxe2: allow munmap during kernel reset
net/sxe2: clean up duplicate function declarations
net/sxe2: clean up structure definitions
doc/sxe2: add acl-stat-type parameter documentation
doc/guides/nics/sxe2.rst | 33 +--
drivers/common/sxe2/sxe2_common.c | 5 +-
drivers/common/sxe2/sxe2_ioctl_chnl.c | 8 +-
drivers/net/sxe2/sxe2_cmd_chnl.c | 215 +++++++++++++++--
drivers/net/sxe2/sxe2_cmd_chnl.h | 15 +-
drivers/net/sxe2/sxe2_drv_cmd.h | 47 ++--
drivers/net/sxe2/sxe2_dump.c | 10 +-
drivers/net/sxe2/sxe2_ethdev.c | 203 +++++++++-------
drivers/net/sxe2/sxe2_ethdev.h | 38 +--
drivers/net/sxe2/sxe2_ethdev_repr.c | 13 +-
drivers/net/sxe2/sxe2_flow.c | 259 +++++++++++++++++----
drivers/net/sxe2/sxe2_flow.h | 6 +-
drivers/net/sxe2/sxe2_flow_define.h | 13 +-
drivers/net/sxe2/sxe2_flow_parse_action.c | 37 ++-
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ---------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 7 -
drivers/net/sxe2/sxe2_ipsec.c | 5 +
drivers/net/sxe2/sxe2_irq.c | 27 ++-
drivers/net/sxe2/sxe2_mac.c | 10 +-
drivers/net/sxe2/sxe2_mp.c | 59 +++--
drivers/net/sxe2/sxe2_queue.c | 2 +
drivers/net/sxe2/sxe2_queue.h | 7 +-
drivers/net/sxe2/sxe2_rx.c | 5 +-
drivers/net/sxe2/sxe2_security.c | 1 +
drivers/net/sxe2/sxe2_switchdev.c | 12 +-
drivers/net/sxe2/sxe2_tx.c | 42 +++-
drivers/net/sxe2/sxe2_tx.h | 4 +
drivers/net/sxe2/sxe2_txrx.c | 19 +-
drivers/net/sxe2/sxe2_txrx_poll.h | 2 -
drivers/net/sxe2/sxe2_txrx_vec.c | 79 +++----
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 133 +----------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 9 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 218 +++++++++++------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
drivers/net/sxe2/sxe2_vsi.c | 8 +-
37 files changed, 988 insertions(+), 697 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 207+ messages in thread
* [PATCH v1 01/13] net/sxe2: add Rx queue buffer split fill support
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 02/13] net/sxe2: update switchdev repr VSI ID display format liujie5
` (12 subsequent siblings)
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
Implement sxe2_rxq_buf_split_fill function to configure Rx queue
buffer split offload. The function validates and sets split
parameters based on protocol header type.
Supports following split types:
- L2: Ether
- L3: IPv4, IPv6
- L4: TCP, UDP, SCTP
- Tunnel: GRE/NAT
- Inner L2/L3/L4 for tunneled packets
Sets split_type_mask and header_len (256 bytes) for hardware
buffer split configuration. Returns error if protocol header
is not configured or unsupported.
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 142 ++++++++++++++++++++++++++++---
1 file changed, 128 insertions(+), 14 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b09989fe50..9ed5559eff 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -26,10 +26,9 @@ static void sxe2_drv_trace_id_alloc(uint64_t *trace_id)
}
static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
- struct sxe2_drv_cmd_params *cmd, uint32_t opc, const char *opc_str,
+ struct sxe2_drv_cmd_params *cmd, uint32_t opc,
void *in_data, uint32_t in_len, void *out_data, uint32_t out_len)
{
- PMD_DEV_LOG_DEBUG(adapter, DRV, "cmd opcode:%s", opc_str);
cmd->timeout = SXE2_DRV_CMD_DFLT_TIMEOUT;
cmd->opcode = opc;
cmd->vsi_id = adapter->vsi_ctxt.dpdk_vsi_id;
@@ -44,7 +43,7 @@ static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
}
#define sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len) \
- __sxe2_drv_cmd_params_fill(adapter, cmd, opc, #opc, in_data, in_len, out_data, out_len)
+ __sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len)
int32_t sxe2_drv_dev_caps_get(struct sxe2_adapter *adapter, struct sxe2_drv_dev_caps_resp *dev_caps)
@@ -193,6 +192,102 @@ int32_t sxe2_drv_vsi_del(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi)
#define SXE2_RXQ_CTXT_CFG_BUF_LEN_ALIGN (1 << 7)
#define SXE2_RX_HDR_SIZE 256
+static int32_t sxe2_rxq_buf_split_fill(struct sxe2_rx_queue *rxq,
+ struct sxe2_drv_rxq_ctxt *ctxt)
+{
+ int32_t ret = 0;
+ uint32_t proto_hdr;
+
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
+ proto_hdr = rxq->rx_seg[0].proto_hdr;
+ if (proto_hdr == RTE_PTYPE_UNKNOWN) {
+ PMD_LOG_ERR(RX, "Buffer split protocol must be configured");
+ ret = -1;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L4_MASK) {
+ case RTE_PTYPE_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_TCP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_UDP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_SCTP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L3_MASK) {
+ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV4;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV6;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L2_MASK) {
+ case RTE_PTYPE_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_L2_ETHER;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L4_MASK) {
+ case RTE_PTYPE_INNER_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_TCP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_UDP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_SCTP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L3_MASK) {
+ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV4;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV6;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L2_MASK) {
+ case RTE_PTYPE_INNER_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L2_ETHER;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_TUNNEL_MASK) {
+ case RTE_PTYPE_TUNNEL_GRENAT:
+ ctxt->split_type_mask = SXE2_PTYPE_TUNNEL_GRENAT;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+ PMD_LOG_ERR(RX, "Buffer split protocol is not supported");
+ ret = -1;
+ } else {
+ ctxt->hdr_len = 0;
+ ctxt->split_type_mask = 0;
+ }
+l_end:
+ return ret;
+}
+
static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
struct sxe2_drv_rxq_cfg_req *req, uint16_t rxq_cnt)
{
@@ -226,7 +321,17 @@ static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
else
ctxt->keep_crc_en = 0;
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
+ ret = sxe2_rxq_buf_split_fill(rxq, ctxt);
+ if (ret)
+ goto l_end;
+ ctxt->split_en = 1;
+ } else {
+ ctxt->split_en = 0;
+ }
+
ctxt->desc_size = sizeof(union sxe2_rx_desc);
+l_end:
return ret;
}
@@ -391,7 +496,7 @@ int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi
&vsi_info_get_resp, sizeof(vsi_info_get_resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_DEV_LOG_ERR(adapter, DRV, "switchdev cpvsi info get failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "vsi %u info get failed, ret=%d", vsi->vsi_id, ret);
goto l_end;
}
@@ -412,6 +517,7 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
{
int32_t ret = 0;
struct sxe2_common_device *cdev = adapter->cdev;
+ struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
struct sxe2_drv_cmd_params param = {0};
struct sxe2_drv_link_info_resp resp = {0};
@@ -425,6 +531,7 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
}
adapter->link_ctxt.speed = resp.speed;
adapter->link_ctxt.link_up = resp.status;
+ (void)sxe2_link_update(dev, 0);
l_end:
return ret;
@@ -447,7 +554,7 @@ int32_t sxe2_drv_rxq_bind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx, ui
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq bind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u bind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -467,7 +574,7 @@ int32_t sxe2_drv_rxq_unbind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx)
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq unbind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u unbind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -668,7 +775,7 @@ int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set)
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_WARN(adapter, DRV, "promic config failed, ret=%d", ret);
+ PMD_DEV_LOG_WARN(adapter, DRV, "promisc config failed, ret=%d", ret);
return ret;
}
@@ -1532,7 +1639,7 @@ int32_t sxe2_drv_get_udp_tunnel_port(struct sxe2_adapter *adapter,
[SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U] = SXE2_UDP_TUNNEL_PROTOCOL_GTP_U,
[SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE] = SXE2_UDP_TUNNEL_PROTOCOL_NVGRE,
};
- struct sxe2_udp_tunnel_cfg tunnel_config = {};
+ struct sxe2_udp_tunnel_cfg tunnel_config = {0};
tunnel_config.protocol = flow_proto_to_udp_tunnel_proto[proto];
ret = sxe2_drv_udp_tunnel_get(adapter, &tunnel_config);
@@ -1560,8 +1667,10 @@ int32_t sxe2_drv_udp_tunnel_get(struct sxe2_adapter *adapter,
&req, sizeof(req),
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_LOG_ERR(DRV, "Failed to get udp proto %d port, ret=%d", req.type, ret);
+ goto l_end;
+ }
tunnel_config->fw_port = resp.port;
tunnel_config->fw_status = resp.enable;
@@ -1569,6 +1678,7 @@ int32_t sxe2_drv_udp_tunnel_get(struct sxe2_adapter *adapter,
tunnel_config->fw_src_en = resp.src;
tunnel_config->fw_used = resp.fw_used;
+l_end:
return ret;
}
@@ -1591,7 +1701,7 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_LOG_ERR(DRV, "get queue info map failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
goto l_end;
}
@@ -1635,7 +1745,7 @@ int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
l_end:
return ret;
@@ -1652,7 +1762,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
txq = eth_dev->data->tx_queues[queue_id];
if (txq == NULL) {
- PMD_LOG_ERR(DRV, "Rx queue %u is not available or setup", queue_id);
+ PMD_LOG_ERR(DRV, "Tx queue %u is not available or setup", queue_id);
ret = -EINVAL;
goto l_end;
}
@@ -1666,7 +1776,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "tx queue mapping failed, ret=%d", ret);
l_end:
return ret;
@@ -1726,10 +1836,14 @@ int32_t sxe2_drv_flow_filter_add(struct sxe2_adapter *adapter, struct sxe2_flow
sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_FILTER_ADD, &req,
sizeof(req), &resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to add flow filter, ret: %d.", ret);
+ flow->create_err = ret;
+ goto l_end;
+ }
flow->flow_id = resp.flow_id;
flow->create_err = ret;
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 02/13] net/sxe2: update switchdev repr VSI ID display format
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
2026-08-18 2:15 ` [PATCH v1 01/13] net/sxe2: add Rx queue buffer split fill support liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 03/13] net/sxe2: add ACL engine event statistics support liujie5
` (11 subsequent siblings)
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
Update the output format for representor primary VSI ID and backup
VSI ID in switchdev dump function. The fields repr_vf_primary_vsi_id
and repr_vf_backup_vsi_id should be displayed correctly for better
debug visibility.
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_dump.c | 8 ++++----
drivers/net/sxe2/sxe2_ethdev.h | 4 ++--
drivers/net/sxe2/sxe2_flow.c | 4 ++--
drivers/net/sxe2/sxe2_switchdev.c | 4 ++--
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index d43473e083..590219f502 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -211,16 +211,16 @@ sxe2_dump_switchdev_info(FILE *file, struct rte_eth_dev *dev)
"\t -- repr_pf_id: %u\n"
"\t -- repr_vf_id: %u\n"
"\t -- repr_vf_vsi_id: %u\n"
- "\t -- repr_vf_k_vsi_id: %s\n"
- "\t -- repr_vf_u_vsi_id: %s\n",
+ "\t -- repr_vf_primary_vsi_id: %s\n"
+ "\t -- repr_vf_backup_vsi_id: %s\n",
adapter->repr_priv_data->repr_id,
adapter->repr_priv_data->repr_q_id,
adapter->repr_priv_data->repr_pf_id,
adapter->repr_priv_data->repr_vf_id,
adapter->repr_priv_data->repr_vf_vsi_id,
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_k_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_primary_vsi_id,
k_vsi_buf, sizeof(k_vsi_buf)),
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_u_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_backup_vsi_id,
u_vsi_buf, sizeof(u_vsi_buf)));
goto l_end;
}
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index c54e8a435e..158198d74b 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -263,8 +263,8 @@ struct sxe2_repr_private_data {
uint16_t repr_pf_id;
uint16_t repr_vf_id;
uint16_t repr_vf_vsi_id;
- uint16_t repr_vf_k_vsi_id;
- uint16_t repr_vf_u_vsi_id;
+ uint16_t repr_vf_primary_vsi_id;
+ uint16_t repr_vf_backup_vsi_id;
};
struct sxe2_sched_hw_cap {
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index 63cfc36968..cf54803301 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -380,9 +380,9 @@ static int32_t sxe2_flow_src_split_proc(struct rte_eth_dev *dev,
if (adapter->switchdev_info.is_switchdev && adapter->is_dev_repr) {
flow_bond_num = 1;
flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] =
- adapter->repr_priv_data->repr_vf_u_vsi_id;
+ adapter->repr_priv_data->repr_vf_backup_vsi_id;
flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] =
- adapter->repr_priv_data->repr_vf_k_vsi_id;
+ adapter->repr_priv_data->repr_vf_primary_vsi_id;
}
for (idx = 0; idx < flow_bond_num; idx++) {
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index 44703cfb5c..efb1468b91 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -312,9 +312,9 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_q_id = repr_id;
repr_priv_data->repr_pf_id = parent_adapter->pf_idx;
repr_priv_data->repr_vf_id = repr_id;
- repr_priv_data->repr_vf_k_vsi_id =
+ repr_priv_data->repr_vf_primary_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
- repr_priv_data->repr_vf_u_vsi_id =
+ repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
repr_priv_data->repr_vf_vsi_id =
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 03/13] net/sxe2: add ACL engine event statistics support
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
2026-08-18 2:15 ` [PATCH v1 01/13] net/sxe2: add Rx queue buffer split fill support liujie5
2026-08-18 2:15 ` [PATCH v1 02/13] net/sxe2: update switchdev repr VSI ID display format liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 04/13] net/sxe2: enhance device cap and res management liujie5
` (10 subsequent siblings)
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
Add statistics support for ACL flow engine to track packet hits
and bytes. This enables flow aging and traffic monitoring for
ACL rules.
Implementation includes:
- Add acl-stat-type devarg to configure statistics type
- Implement sxe2_drv_flow_acl_get_stat_id for stat allocation
- Implement sxe2_drv_flow_acl_free_stat for stat cleanup
- Implement sxe2_drv_flow_acl_query_stat for stat query
- Integrate stat operations into flow create/destroy/query paths
Statistics are accumulated in manager context and reported through
rte_flow_query() interface with COUNT action.
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 73 +++++++++++++-
drivers/net/sxe2/sxe2_cmd_chnl.h | 9 +-
drivers/net/sxe2/sxe2_drv_cmd.h | 17 ++++
drivers/net/sxe2/sxe2_dump.c | 2 +
drivers/net/sxe2/sxe2_ethdev.c | 25 +++--
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_flow.c | 111 ++++++++++++++++------
drivers/net/sxe2/sxe2_flow.h | 6 +-
drivers/net/sxe2/sxe2_flow_define.h | 13 +--
drivers/net/sxe2/sxe2_flow_parse_action.c | 19 +++-
drivers/net/sxe2/sxe2_queue.c | 2 +
11 files changed, 225 insertions(+), 53 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 9ed5559eff..b2dbd4457d 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1914,7 +1914,7 @@ int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat
}
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr)
+ struct sxe2_flow_cid_mgr *mgr)
{
struct sxe2_drv_flow_fnav_query_stat_req req = { 0 };
struct sxe2_drv_flow_fnav_query_stat_resp resp = { 0 };
@@ -1943,6 +1943,77 @@ int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
return ret;
}
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id)
+{
+ struct sxe2_drv_flow_fnav_get_stat_id_req req = { 0 };
+ struct sxe2_drv_flow_fnav_get_stat_id_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC,
+ &req, sizeof(req),
+ &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+ *stat_id = resp.stat_id;
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id)
+{
+ struct sxe2_drv_flow_fnav_free_stat_id_req req = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = stat_id;
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_FREE,
+ &req, sizeof(req),
+ NULL, 0);
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to free acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr)
+{
+ struct sxe2_drv_acl_query_stat_req req = { 0 };
+ struct sxe2_drv_acl_query_stat_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = mgr->stat_index;
+ req.stat_ctrl = mgr->count_type;
+ req.is_clear = 1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY,
+ &req, sizeof(req), &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to query ACL stat, stat id: %u, ret: %d.",
+ req.stat_id, ret);
+ goto l_end;
+ }
+ mgr->hits += resp.stat_hits;
+ mgr->bytes += resp.stat_bytes;
+
+l_end:
+ return ret;
+}
+
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set)
{
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index d63caad526..7d75a91061 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -165,7 +165,14 @@ int32_t sxe2_drv_flow_fnav_get_stat_id(struct sxe2_adapter *adapter, uint32_t *s
int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr);
+ struct sxe2_flow_cid_mgr *mgr);
+
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id);
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr);
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set);
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index 03ef3b315d..d332d15980 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -668,6 +668,18 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_fc_get_resp {
uint8_t rsv[3];
} __rte_packed_end;
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_req {
+ uint32_t stat_id;
+ uint32_t stat_ctrl;
+ uint32_t is_clear;
+} __rte_packed_end;
+
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_resp {
+ uint32_t stat_index;
+ uint64_t stat_hits;
+ uint64_t stat_bytes;
+} __rte_packed_end;
+
enum sxe2_drv_cmd_module {
SXE2_DRV_CMD_MODULE_HANDSHAKE = 0,
SXE2_DRV_CMD_MODULE_DEV = 1,
@@ -824,6 +836,11 @@ enum sxe2_drv_cmd_code {
SXE2_DRV_CMD_OPT_EEP_GET =
SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_OPT, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC,
+ SXE2_DRV_CMD_FLOW_ACL_STAT_FREE,
+
};
#endif /* SXE2_DRV_CMD_H */
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index 590219f502..31f7d6ba61 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -80,12 +80,14 @@ sxe2_dump_dev_args_info(FILE *file, struct rte_eth_dev *dev)
"\t -- no_sched_mode: %s\n"
"\t -- flow-duplicate-pattern: %u\n"
"\t -- fnav-stat-type: %u\n"
+ "\t -- acl-stat-type: %u\n"
"\t -- sched_layer_mode: %u\n"
"\t -- rx_low_latency: %s\n"
"\t -- function-flow-direct: %s\n",
adapter->devargs.no_sched_mode ? "On" : "Off",
adapter->devargs.flow_dup_pattern_mode,
adapter->devargs.fnav_stat_type,
+ adapter->devargs.acl_stat_type,
adapter->devargs.sched_layer_mode,
adapter->devargs.rx_low_latency ? "On" : "Off",
adapter->devargs.func_flow_direct_en ? "On" : "Off");
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 8bbfdc3a15..3c3e78125d 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -44,7 +44,7 @@
#define SXE2_PCI_VENDOR_ID_1 0x1ff2
#define SXE2_PCI_DEVICE_ID_PF_1 0x10b1
-#define SXE2_PCI_DEVICE_ID_VF_1 0x10b
+#define SXE2_PCI_DEVICE_ID_VF_1 0x10b2
#define SXE2_PCI_VENDOR_ID_2 0x1d94
#define SXE2_PCI_DEVICE_ID_PF_2 0x1260
@@ -72,6 +72,7 @@ static const struct rte_pci_id pci_id_sxe2_tbl[] = {
#define SXE2_DEVARG_FLOW_DUP_PATTERN_MODE "flow-duplicate-pattern"
#define SXE2_DEVARG_FUNC_FLOW_DIRCT "function-flow-direct"
#define SXE2_DEVARG_FNAV_STAT_TYPE "fnav-stat-type"
+#define SXE2_DEVARG_ACL_STAT_TYPE "acl-stat-type"
#define SXE2_DEVARG_NO_SCHED_MODE "no-sched-mode"
#define SXE2_DEVARG_SCHED_LAYER_MODE "sched-layer-mode"
#define SXE2_DEVARG_RX_LOW_LATENCY "rx-low-latency"
@@ -971,11 +972,11 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
return ptypes;
}
-static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, void *args)
+static int32_t sxe2_parse_stat_type(const char *key, const char *value, void *args)
{
int32_t ret = -EINVAL;
uint8_t *num = (uint8_t *)args;
- unsigned long fnav_stat_type;
+ unsigned long stat_type;
char *endptr = NULL;
if (value == NULL || args == NULL) {
@@ -983,19 +984,19 @@ static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, voi
goto l_end;
}
errno = 0;
- fnav_stat_type = strtoul(value, &endptr, 10);
+ stat_type = strtoul(value, &endptr, 10);
if (errno != 0 || endptr == value || *endptr != '\0') {
PMD_LOG_WARN(INIT, "%s: \"%s\" is not a valid int value.",
key, value);
goto l_end;
}
- if (fnav_stat_type > SXE2_FNAV_STAT_ENA_ALL ||
- fnav_stat_type == SXE2_FNAV_STAT_ENA_NONE) {
+ if (stat_type > SXE2_FNAV_STAT_ENA_ALL ||
+ stat_type == SXE2_FNAV_STAT_ENA_NONE) {
PMD_LOG_ERR(INIT, "%s: \"%s\" out of range [1-3].",
key, value);
goto l_end;
}
- *num = (uint8_t)fnav_stat_type;
+ *num = (uint8_t)stat_type;
ret = 0;
l_end:
return ret;
@@ -1177,13 +1178,20 @@ static int32_t sxe2_args_parse(struct rte_eth_dev *dev, struct sxe2_dev_kvargs_i
if (kvargs == NULL)
goto l_end;
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_FNAV_STAT_TYPE,
- &sxe2_parse_fnav_stat_type,
+ &sxe2_parse_stat_type,
&adapter->devargs.fnav_stat_type);
if (ret) {
PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse fnav stat type, ret:%d", ret);
goto l_end;
}
+ ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_ACL_STAT_TYPE,
+ &sxe2_parse_stat_type, &adapter->devargs.acl_stat_type);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse acl stat type, ret:%d", ret);
+ goto l_end;
+ }
+
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_NO_SCHED_MODE,
&sxe2_parse_bool,
&adapter->devargs.no_sched_mode);
@@ -2350,6 +2358,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_sxe2,
"flow-duplicate-pattern=<0|1|2> "
"function-flow-direct=<0|1> "
"fnav-stat-type=<1|2|3> "
+ "acl-stat-type=<1|2|3> "
"no-sched-mode=<0|1> "
"sched-layer-mode=<0-3> "
"rx-low-latency=<0|1>");
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 158198d74b..7e495e5cb9 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -138,6 +138,7 @@ struct sxe2_devargs {
uint8_t flow_dup_pattern_mode;
uint8_t func_flow_direct_en;
uint8_t fnav_stat_type;
+ uint8_t acl_stat_type;
uint8_t no_sched_mode;
uint8_t sched_layer_mode;
uint8_t rx_low_latency;
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index cf54803301..3cf98dd294 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -857,7 +857,7 @@ static int32_t sxe2_flow_rte_list_free(struct sxe2_adapter *adapter,
struct rte_flow *flow_temp = NULL;
struct sxe2_flow *hw_flow = NULL;
struct sxe2_flow *hw_flow_temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
rte_spinlock_lock(&adapter->flow_ctxt.flow_list_lock);
TAILQ_FOREACH(flow_temp, &adapter->flow_ctxt.rte_flow_list, next) {
if (flow_temp == flow)
@@ -1028,7 +1028,7 @@ static struct rte_flow *sxe2_flow_create(struct rte_eth_dev *dev,
goto l_free_flow;
TAILQ_FOREACH(flow, &flow_list->sxe2_flow_list, next) {
- ret = sxe2_fnav_get_filter_cid(adapter, flow);
+ ret = sxe2_flow_get_filter_cid(adapter, flow);
if (ret != 0) {
PMD_LOG_ERR(DRV, "fnav get stats id failed, ret:%d", ret);
rte_flow_error_set(error, EIO,
@@ -1088,16 +1088,26 @@ static int32_t sxe2_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e
return ret;
}
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
+ uint32_t count_type;
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.fnav_hw_res.count_type;
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.acl_hw_res.count_type;
+ } else {
+ goto l_end;
+ }
if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
user_id = flow->action.count.user_id;
@@ -1112,7 +1122,7 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
}
if (mgr == NULL) {
mgr = rte_zmalloc("sxe2_fnav_cid_mgr",
- sizeof(struct sxe2_fnav_cid_mgr), 0);
+ sizeof(struct sxe2_flow_cid_mgr), 0);
if (!mgr) {
PMD_LOG_ERR(DRV,
"Failed to alloc sxe2vf_fnav_cid_mgr memory.");
@@ -1120,7 +1130,10 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
goto l_end;
}
- ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ ret = sxe2_drv_flow_acl_get_stat_id(adapter, &stat_index);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to alloc fw count id.");
rte_free(mgr);
@@ -1131,7 +1144,7 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
mgr->user_id = user_id;
mgr->driver_id = driver_id;
mgr->stat_index = stat_index;
- mgr->count_type = adapter->flow_ctxt.hw_res.count_type;
+ mgr->count_type = count_type;
}
flow->action.count.stat_index = mgr->stat_index;
flow->action.count.stat_ctrl = mgr->count_type;
@@ -1143,17 +1156,24 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *mgr = *mgr_ptr;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
+ struct sxe2_flow_cid_mgr *mgr = *mgr_ptr;
uint32_t user_id = flow->action.count.user_id;
- if (user_id == 0) {
- TAILQ_REMOVE(cid_mgr_list, mgr, next);
- ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+
+ if (user_id == 0 && mgr) {
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+ }
if (ret) {
rte_flow_error_set(error, EIO,
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
@@ -1170,17 +1190,23 @@ int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
uint32_t user_id = flow->action.count.user_id;
uint32_t driver_id = flow->action.count.driver_id;
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ else
+ goto l_end;
+
TAILQ_FOREACH(temp, cid_mgr_list, next) {
if (temp->user_id == user_id &&
temp->driver_id == driver_id) {
@@ -1197,7 +1223,15 @@ int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
ret = -EINVAL;
goto l_end;
}
- ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ ret = sxe2_drv_flow_acl_query_stat(adapter, mgr);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+ } else {
+ PMD_LOG_ERR(DRV, "query flow engine neither FNAV nor ACL");
+ ret = -ENOTSUP;
+ }
if (ret) {
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM, NULL,
@@ -1218,7 +1252,7 @@ static int32_t sxe2_flow_query_count(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
switch (flow->action.count.stat_ctrl) {
case SXE2_FNAV_STAT_ENA_NONE:
count->hits_set = 0;
@@ -1348,12 +1382,18 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
int32_t ret = 0;
TAILQ_INIT(&adapter->flow_ctxt.rte_flow_list);
- TAILQ_INIT(&adapter->flow_ctxt.hw_res.fnav_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list);
if (adapter->devargs.fnav_stat_type)
- adapter->flow_ctxt.hw_res.count_type =
+ adapter->flow_ctxt.fnav_hw_res.count_type =
adapter->devargs.fnav_stat_type;
else
- adapter->flow_ctxt.hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+ adapter->flow_ctxt.fnav_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+
+ if (adapter->devargs.acl_stat_type)
+ adapter->flow_ctxt.acl_hw_res.count_type = adapter->devargs.acl_stat_type;
+ else
+ adapter->flow_ctxt.acl_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
adapter->flow_ctxt.fnav_inited = 1;
rte_spinlock_init(&adapter->flow_ctxt.flow_list_lock);
@@ -1370,15 +1410,15 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
int32_t ret = 0;
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct rte_flow_error error;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
ret = sxe2_flow_flush(dev, &error);
if (ret)
PMD_LOG_ERR(DRV, "Failed to flush flow, ret: %d.", ret);
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
TAILQ_REMOVE(cid_mgr_list, mgr, next);
ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
@@ -1387,5 +1427,14 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
"Failed to free fnav stat id, ret: %d.", ret);
rte_free(mgr);
}
+
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ if (ret)
+ PMD_LOG_ERR(DRV, "Failed to free acl stat id, ret: %d.", ret);
+ rte_free(mgr);
+ }
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_flow.h b/drivers/net/sxe2/sxe2_flow.h
index daaeedd4dc..8d47b11ff4 100644
--- a/drivers/net/sxe2/sxe2_flow.h
+++ b/drivers/net/sxe2/sxe2_flow.h
@@ -14,16 +14,16 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev);
int32_t sxe2_flow_uninit(struct rte_eth_dev *dev);
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev);
diff --git a/drivers/net/sxe2/sxe2_flow_define.h b/drivers/net/sxe2/sxe2_flow_define.h
index 263a573f04..f56f687dc7 100644
--- a/drivers/net/sxe2/sxe2_flow_define.h
+++ b/drivers/net/sxe2/sxe2_flow_define.h
@@ -98,8 +98,8 @@ struct rte_flow {
};
TAILQ_HEAD(rte_flow_list_t, rte_flow);
-struct sxe2_fnav_cid_mgr {
- TAILQ_ENTRY(sxe2_fnav_cid_mgr) next;
+struct sxe2_flow_cid_mgr {
+ TAILQ_ENTRY(sxe2_flow_cid_mgr) next;
uint16_t stat_index;
uint32_t user_id;
uint32_t driver_id;
@@ -107,18 +107,19 @@ struct sxe2_fnav_cid_mgr {
uint64_t hits;
uint64_t bytes;
};
-TAILQ_HEAD(sxe2_fnav_cid_mgr_list_t, sxe2_fnav_cid_mgr);
+TAILQ_HEAD(sxe2_flow_cid_mgr_list_t, sxe2_flow_cid_mgr);
-struct sxe2_fnav_count_resource {
+struct sxe2_flow_count_resource {
uint32_t count_type;
uint32_t global_index;
- struct sxe2_fnav_cid_mgr_list_t fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t flow_cid_mgr_list;
};
struct sxe2_flow_context {
struct rte_flow_list_t rte_flow_list;
rte_spinlock_t flow_list_lock;
- struct sxe2_fnav_count_resource hw_res;
+ struct sxe2_flow_count_resource fnav_hw_res;
+ struct sxe2_flow_count_resource acl_hw_res;
uint16_t tunnel_port_list[SXE2_FLOW_UDP_TUNNEL_MAX];
uint32_t fnav_inited;
};
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index a9559e2d7e..cdd6fcfdcd 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -1037,11 +1037,24 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
act_count = action->conf;
- flow->action.count.user_id = act_count->id;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
flow->action.count.driver_id = 0;
- if (flow->action.count.user_id == 0)
+ if (flow->action.count.user_id == 0) {
flow->action.count.driver_id =
- ++adapter->flow_ctxt.hw_res.global_index;
+ ++adapter->flow_ctxt.fnav_hw_res.global_index;
+ }
+ action_num[SXE2_FLOW_ACTION_COUNT]++;
+ } else if (engine_type == SXE2_FLOW_ENGINE_ACL) {
+ sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
+ act_count = action->conf;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
+ flow->action.count.driver_id = 0;
+ if (flow->action.count.user_id == 0) {
+ flow->action.count.driver_id =
+ ++adapter->flow_ctxt.acl_hw_res.global_index;
+ }
action_num[SXE2_FLOW_ACTION_COUNT]++;
} else {
rte_flow_error_set(error, ENOTSUP,
diff --git a/drivers/net/sxe2/sxe2_queue.c b/drivers/net/sxe2/sxe2_queue.c
index afb2681b72..3aaa14c685 100644
--- a/drivers/net/sxe2/sxe2_queue.c
+++ b/drivers/net/sxe2/sxe2_queue.c
@@ -39,6 +39,8 @@ int32_t sxe2_queues_init(struct rte_eth_dev *dev)
rxq->rx_buf_len = RTE_MIN(rxq->rx_buf_len, SXE2_RX_MAX_DATA_BUF_SIZE);
if (frame_size > rxq->rx_buf_len)
dev->data->scattered_rx = 1;
+ if (adapter->flow_ctxt.fnav_inited)
+ rxq->fnav_enable = true;
}
adapter->ptp_ctxt.mbuf_rx_ts_offset = -1;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 04/13] net/sxe2: enhance device cap and res management
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (2 preceding siblings ...)
2026-08-18 2:15 ` [PATCH v1 03/13] net/sxe2: add ACL engine event statistics support liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 05/13] net/sxe2: improve representor device initialization liujie5
` (9 subsequent siblings)
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch improves the SXE2 PMD with several key enhancements:
- Enhance device info reporting:
* Add NULL check for main VSI in dev_infos_get
* Add max_mac_addrs field support
* Add RSS_HASH offload capability
* Conditionally enable QINQ_STRIP/QINQ_INSERT based on port VLAN check
* Fill nb_rx_queues and nb_tx_queues fields
* Set no_of_elements in buffer_split_supported_hdr_ptypes_get
- Unify PCI register operations:
* Move SXE2_PCI_REG_WRITE and SXE2_PCI_REG_READ to common header
* Replace write-combined write with regular write in pci_map_write_reg
* Add resource type validation in dev_pci_res_seg_map
- Improve VF representor matching logic:
* Remove kernel_repr_id encoding approach
* Match PF number and VF ID directly against representor info
* Add proper error handling for mismatched representor types
- Support multi-port probing:
* Loop through nb_ports in eth_pmd_probe
* Handle probe failure with proper cleanup
- Update resource cleanup order in dev_close:
* Adjust uninit sequence to prevent use-after-free
* Add NULL check for dev_ops before calling dev_close
- Add device type checks in UDP tunnel operations:
* Restrict tunnel operations to PF only
* Reject operations on VF representors
- Store additional device capabilities:
* Save port_idx and pf_idx from device capabilities
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 178 +++++++++++++++++++--------------
drivers/net/sxe2/sxe2_ethdev.h | 6 +-
drivers/net/sxe2/sxe2_queue.h | 2 -
3 files changed, 107 insertions(+), 79 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 3c3e78125d..ccf04fe1d9 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -95,7 +95,7 @@ static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_pf[SXE2_PCI_MAP_RES_
.reg_width = 4},
[SXE2_PCI_MAP_RES_IRQ_MSIX] = {.addr_base = SXE2_BAR4_MSIX_CTL(0),
.bar_idx = 4,
- .reg_width = 10},
+ .reg_width = 0x10},
};
static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_vf[SXE2_PCI_MAP_RES_MAX_COUNT] = {
@@ -630,6 +630,10 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
struct sxe2_udp_tunnel_cfg *tunnel_config;
int32_t ret = -1;
+ if (ad->dev_type != SXE2_DEV_T_PF || ad->is_dev_repr) {
+ ret = -ENOTSUP;
+ goto l_end;
+ }
rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
tunnel_config = &ad->udp_tunnel_ctx.tunnel_conf[tunnel_proto];
@@ -659,6 +663,7 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
l_unlock_end:
rte_spinlock_unlock(&ad->udp_tunnel_ctx.lock);
+l_end:
return ret;
}
@@ -782,6 +787,10 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
+ if (unlikely(vsi == NULL)) {
+ PMD_LOG_ERR(INIT, "main vsi is NULL");
+ return -EINVAL;
+ }
dev_info->max_rx_queues = vsi->rxqs.q_cnt;
dev_info->max_tx_queues = vsi->txqs.q_cnt;
dev_info->min_rx_bufsize = SXE2_MIN_BUF_SIZE;
@@ -789,6 +798,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->max_lro_pkt_size = SXE2_FRAME_SIZE_MAX * SXE2_RX_LRO_DESC_MAX_NUM;
dev_info->max_mtu = dev_info->max_rx_pktlen - SXE2_ETH_OVERHEAD;
dev_info->min_mtu = RTE_ETHER_MIN_MTU;
+ dev_info->max_mac_addrs = SXE2_NUM_MACADDR_MAX;
dev_info->rx_offload_capa =
RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
@@ -800,11 +810,9 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_RX_OFFLOAD_SCTP_CKSUM |
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT |
-#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
- RTE_ETH_RX_OFFLOAD_QINQ_STRIP |
-#endif
RTE_ETH_RX_OFFLOAD_VLAN_EXTEND |
- RTE_ETH_RX_OFFLOAD_TCP_LRO;
+ RTE_ETH_RX_OFFLOAD_TCP_LRO |
+ RTE_ETH_RX_OFFLOAD_RSS_HASH;
dev_info->tx_offload_capa =
RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
@@ -850,13 +858,20 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO |
RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
+ if (sxe2_ipsec_supported(adapter)) {
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
+ dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
+ }
if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
- if (sxe2_ipsec_supported(adapter)) {
- dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
- dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
+ if (!sxe2_dev_port_vlan_check(dev)) {
+ dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
+#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
+#endif
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
}
if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_RSS) {
@@ -909,7 +924,8 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->speed_capa = RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G |
RTE_ETH_LINK_SPEED_50G | RTE_ETH_LINK_SPEED_100G;
-
+ dev_info->nb_rx_queues = dev->data->nb_rx_queues;
+ dev_info->nb_tx_queues = dev->data->nb_tx_queues;
dev_info->default_rxportconf.burst_size = SXE2_RX_MAX_BURST;
dev_info->default_txportconf.burst_size = SXE2_TX_MAX_BURST;
dev_info->default_rxportconf.nb_queues = 1;
@@ -918,11 +934,8 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->default_txportconf.ring_size = SXE2_RING_SIZE_MIN;
dev_info->rx_seg_capa.max_nseg = SXE2_RX_MAX_NSEG;
-
dev_info->rx_seg_capa.multi_pools = true;
-
dev_info->rx_seg_capa.offset_allowed = false;
-
dev_info->rx_seg_capa.offset_align_log2 = false;
return 0;
@@ -930,7 +943,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
static const uint32_t *
sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
- size_t *no_of_elements __rte_unused)
+ size_t *no_of_elements)
{
static const uint32_t ptypes[] = {
RTE_PTYPE_L2_ETHER,
@@ -968,6 +981,7 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
RTE_PTYPE_UNKNOWN
};
+ *no_of_elements = RTE_DIM(ptypes);
return ptypes;
}
@@ -1352,6 +1366,8 @@ static int32_t sxe2_func_caps_get(struct sxe2_adapter *adapter)
goto l_end;
adapter->dev_type = dev_caps.dev_type;
+ adapter->port_idx = dev_caps.port_idx;
+ adapter->pf_idx = dev_caps.pf_idx;
sxe2_drv_dev_caps_set(adapter, &dev_caps);
@@ -1437,7 +1453,7 @@ void sxe2_pci_map_write_reg(struct sxe2_adapter *adapter,
goto l_ret;
}
- SXE2_PCI_REG_WRITE_WC(reg_addr, value);
+ SXE2_PCI_REG_WRITE(reg_addr, value);
l_ret:
return;
}
@@ -1550,6 +1566,12 @@ int32_t sxe2_dev_pci_res_seg_map(struct sxe2_adapter *adapter,
struct sxe2_pci_map_addr_info *addr_info = NULL;
int32_t ret = 0;
+ if (unlikely(res_type >= SXE2_PCI_MAP_RES_MAX_COUNT)) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Invalid resource type %u", res_type);
+ ret = -EINVAL;
+ goto l_end;
+ }
+
addr_info = &adapter->map_ctxt.addr_info[res_type];
if (!addr_info || addr_info->bar_idx == SXE2_PCI_MAP_BAR_INVALID) {
PMD_DEV_LOG_ERR(adapter, INIT, "Invalid bar index with resource type %d", res_type);
@@ -1765,14 +1787,13 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
uint8_t i = 0;
PMD_INIT_FUNC_TRACE();
+ if (map_ctxt->bar_info != NULL) {
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
-
- if (map_ctxt != NULL && map_ctxt->bar_info != NULL) {
for (i = 0; i < map_ctxt->bar_cnt; i++) {
bar_info = &map_ctxt->bar_info[i];
if (bar_info != NULL && bar_info->seg_info != NULL) {
@@ -1783,7 +1804,6 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
rte_free(map_ctxt->bar_info);
map_ctxt->bar_info = NULL;
}
-
adapter->dev_info.dev_data = NULL;
}
@@ -1936,6 +1956,12 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_switchdev_err;
}
+ ret = sxe2_eth_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
+ goto init_eth_err;
+ }
+
ret = sxe2_sw_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize sw parameters, ret=[%d]", ret);
@@ -1948,12 +1974,6 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_irq_err;
}
- ret = sxe2_eth_init(dev);
- if (ret) {
- PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
- goto init_eth_err;
- }
-
ret = sxe2_security_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize security, ret=%d", ret);
@@ -2005,15 +2025,15 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
init_fc_state_err:
(void)sxe2_flow_uninit(dev);
init_flow_err:
-init_rss_err:
sxe2_security_uinit(dev);
+init_rss_err:
init_security_err:
- sxe2_eth_uinit(dev);
-init_eth_err:
sxe2_intr_uninit(dev);
init_irq_err:
sxe2_sw_uninit(dev);
init_sw_err:
+ sxe2_eth_uinit(dev);
+init_eth_err:
(void)sxe2_switchdev_uninit(dev);
init_switchdev_err:
init_dev_info_err:
@@ -2035,17 +2055,15 @@ static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
(void)sxe2_queues_release(dev);
sxe2_mp_uninit(dev);
(void)sxe2_sched_uinit(dev);
- (void)sxe2_rss_disable(dev);
(void)sxe2_flow_uninit(dev);
+ (void)sxe2_rss_disable(dev);
(void)sxe2_udp_tunnel_port_clear(dev);
- sxe2_vsi_uninit(dev);
sxe2_security_uinit(dev);
sxe2_intr_uninit(dev);
(void)sxe2_switchdev_uninit(dev);
sxe2_sw_uninit(dev);
- (void)sxe2_switchdev_uninit(dev);
- sxe2_dev_pci_map_uinit(dev);
sxe2_eth_uinit(dev);
+ sxe2_vsi_uninit(dev);
sxe2_dev_pci_map_uinit(dev);
sxe2_free_repr_info(dev);
sxe2_fc_state_uinit(dev);
@@ -2068,9 +2086,11 @@ static int32_t sxe2_dev_uninit(struct rte_eth_dev *dev)
for (i = 0; i < adapter->repr_ctxt.nb_repr_vf; i++) {
rep_dev = adapter->repr_ctxt.vf_rep_eth_dev[i];
if (rep_dev) {
- ret = rep_dev->dev_ops->dev_close(rep_dev);
- if (ret)
- goto l_end;
+ if (rep_dev->dev_ops && rep_dev->dev_ops->dev_close) {
+ ret = rep_dev->dev_ops->dev_close(rep_dev);
+ if (ret)
+ goto l_end;
+ }
if (rep_dev->intr_handle)
rte_intr_instance_free(rep_dev->intr_handle);
ret = rte_eth_dev_release_port(rep_dev);
@@ -2143,42 +2163,25 @@ static int32_t sxe2_fw_version_string_get(struct rte_eth_dev *dev, char *fw_vers
return ret;
}
-static uint16_t sxe2_switchdev_repr_id_encode_get(struct sxe2_switchdev_info *switchdev_info)
-{
- enum rte_eth_representor_type type;
- uint16_t repr = switchdev_info->vf_num;
- uint32_t pf = switchdev_info->pf_num;
-
- switch (switchdev_info->port_name_type) {
- case SXE2_PHYS_PORT_NAME_TYPE_UPLINK:
- if (!switchdev_info->representor)
- return UINT16_MAX;
- type = RTE_ETH_REPRESENTOR_PF;
- pf = switchdev_info->mpesw_owner;
- break;
- case SXE2_PHYS_PORT_NAME_TYPE_PFVF:
- default:
- type = RTE_ETH_REPRESENTOR_VF;
- break;
- }
-
- return SXE2_REPRESENTOR_ID(pf, type, repr);
-}
-
static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
struct rte_eth_devargs *req_eth_da)
{
- uint32_t port_idx = 0;
- uint32_t repr_idx;
- uint16_t kernel_repr_id = sxe2_switchdev_repr_id_encode_get(&adapter->switchdev_info);
- uint16_t repr_id;
+ uint16_t port_idx = UINT16_MAX;
+ uint16_t repr_idx;
+ uint16_t vf_id;
+ uint16_t i;
switch (req_eth_da->type) {
case RTE_ETH_REPRESENTOR_PF:
+ if (adapter->switchdev_info.port_name_type !=
+ SXE2_PHYS_PORT_NAME_TYPE_UPLINK) {
+ rte_errno = EBUSY;
+ return false;
+ }
break;
case RTE_ETH_REPRESENTOR_VF:
if (adapter->switchdev_info.port_name_type !=
- SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
+ SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
rte_errno = EBUSY;
return false;
}
@@ -2191,15 +2194,30 @@ static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
return false;
}
+ for (port_idx = 0; port_idx < req_eth_da->nb_ports; ++port_idx) {
+ if (adapter->switchdev_info.pf_num != req_eth_da->ports[port_idx]) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev pf %u not match req pf %u",
+ adapter->switchdev_info.pf_num, req_eth_da->ports[port_idx]);
+ rte_errno = EBUSY;
+ return false;
+ }
+ }
+
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- repr_id = SXE2_REPRESENTOR_ID(req_eth_da->ports[port_idx],
- req_eth_da->type,
- req_eth_da->representor_ports[repr_idx]);
- if (repr_id == kernel_repr_id)
- return true;
- }
- rte_errno = EBUSY;
- return false;
+ for (i = 0; i < adapter->repr_ctxt.nb_vf; ++i) {
+ vf_id = rte_le_to_cpu_16(adapter->repr_ctxt.repr_vf_id[i].func_id);
+ if (vf_id == req_eth_da->representor_ports[repr_idx])
+ break;
+ }
+ if (i == adapter->repr_ctxt.nb_vf) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev vf %u not match req vf(cnt:%u)",
+ req_eth_da->representor_ports[repr_idx], adapter->repr_ctxt.nb_vf);
+ rte_errno = EBUSY;
+ return false;
+ }
+ }
+
+ return true;
}
static int32_t sxe2_eth_pmd_probe_pf(struct sxe2_common_device *cdev,
@@ -2317,6 +2335,7 @@ static int32_t sxe2_eth_pmd_probe(struct sxe2_common_device *cdev,
{
struct rte_eth_devargs eth_da = { .nb_ports = 0 };
int32_t ret = 0;
+ uint16_t port;
ret = sxe2_parse_eth_devargs(cdev->dev, ð_da);
if (ret != 0) {
@@ -2324,7 +2343,18 @@ static int32_t sxe2_eth_pmd_probe(struct sxe2_common_device *cdev,
goto l_end;
}
- ret = sxe2_eth_pmd_probe_pf(cdev, ð_da, 0, kvargs);
+ if (eth_da.nb_ports > 0) {
+ for (port = 0; port < eth_da.nb_ports; port++) {
+ ret = sxe2_eth_pmd_probe_pf(cdev, ð_da, port, kvargs);
+ if (ret != 0) {
+ PMD_LOG_ERR(INIT, "sxe2 eth pmd probe failed, ret=%d", ret);
+ (void)sxe2_eth_pmd_remove(cdev);
+ goto l_end;
+ }
+ }
+ } else {
+ ret = sxe2_eth_pmd_probe_pf(cdev, ð_da, 0, kvargs);
+ }
l_end:
return ret;
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 7e495e5cb9..cfcb7fcf00 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -65,9 +65,6 @@ enum sxe2_fnav_tunnel_flag_type {
#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
#define lower_32_bits(n) ((uint32_t)((n) & 0xffffffff))
-#define SXE2_REPRESENTOR_ID(pf, type, repr) \
- (((pf) << 14) + ((type) << 12) + ((repr) & 0xfff))
-
#define SXE2_I2C_EEPROM_DEV_ADDR 0xA0
#define SXE2_I2C_EEPROM_DEV_ADDR2 0xA2
#define SXE2_MODULE_TYPE_SFP 0x03
@@ -356,6 +353,9 @@ struct sxe2_adapter {
#define SXE2_DEV_PRIVATE_TO_ADAPTER(dev) \
((struct sxe2_adapter *)(dev)->data->dev_private)
+#define SXE2_PCI_REG_WRITE(reg, value) rte_write32((rte_cpu_to_le_32(value)), (reg))
+#define SXE2_PCI_REG_READ(reg) rte_read32(reg)
+
void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
enum sxe2_pci_map_resource res_type,
uint16_t idx_in_func);
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index a300b66771..10bdaf5b8d 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -12,8 +12,6 @@
#include "sxe2_drv_cmd.h"
#include "sxe2_txrx_common.h"
-#define SXE2_PCI_REG_READ(reg) \
- rte_read32(reg)
#define SXE2_PCI_REG_WRITE_WC(reg, value) \
rte_write32_wc((rte_cpu_to_le_32(value)), reg)
#define SXE2_PCI_REG_WRITE_WC_RELAXED(reg, value) \
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 05/13] net/sxe2: improve representor device initialization
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (3 preceding siblings ...)
2026-08-18 2:15 ` [PATCH v1 04/13] net/sxe2: enhance device cap and res management liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 06/13] net/sxe2: refactor flow tunnel port handling liujie5
` (8 subsequent siblings)
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch enhances the representor device initialization with:
- Add statistics initialization in sxe2_repr_dev_init
* Call sxe2_stats_init to setup statistics infrastructure
* Add proper error handling path for stats init failure
- Add representor device naming and NUMA node assignment:
* Update device name format to use base device name prefix
* Set numa_node from parent device data for proper NUMA locality
* Ensures representor devices are allocated on the same NUMA node
- Code style improvements:
* Align struct member fields in sxe2_adapter for consistency
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.h | 24 ++++++++++++------------
drivers/net/sxe2/sxe2_ethdev_repr.c | 13 +++++++++++--
2 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index cfcb7fcf00..d0a0f41ceb 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -314,10 +314,10 @@ struct sxe2_fc_state_ctxt {
};
struct sxe2_adapter {
- struct sxe2_common_device *cdev;
- struct sxe2_dev_info dev_info;
- struct rte_pci_device *pci_dev;
- struct sxe2_repr_private_data *repr_priv_data;
+ struct sxe2_common_device *cdev;
+ struct sxe2_dev_info dev_info;
+ struct rte_pci_device *pci_dev;
+ struct sxe2_repr_private_data *repr_priv_data;
struct sxe2_pci_map_context map_ctxt;
struct sxe2_irq_context irq_ctxt;
struct sxe2_queue_context q_ctxt;
@@ -338,16 +338,16 @@ struct sxe2_adapter {
bool rule_started;
bool flow_isolated;
bool flow_isolate_cfg;
- uint16_t dev_port_id;
+ uint16_t dev_port_id;
bool is_dev_repr;
- uint64_t cap_flags;
+ uint64_t cap_flags;
enum sxe2_dev_type dev_type;
- struct rte_ether_addr mac_addr;
- uint8_t port_idx;
- uint8_t pf_idx;
- uint32_t tx_mode_flags;
- uint32_t rx_mode_flags;
- uint8_t started;
+ struct rte_ether_addr mac_addr;
+ uint8_t port_idx;
+ uint8_t pf_idx;
+ uint32_t tx_mode_flags;
+ uint32_t rx_mode_flags;
+ uint8_t started;
};
#define SXE2_DEV_PRIVATE_TO_ADAPTER(dev) \
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index f32318b731..b7096f5927 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -483,8 +483,16 @@ int32_t sxe2_repr_dev_init(struct rte_eth_dev *dev,
goto l_init_sw_err;
}
+ ret = sxe2_stats_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize stats, ret=[%d]", ret);
+ goto l_init_irq_ctxt_err;
+ }
+
goto l_end;
+l_init_irq_ctxt_err:
+ sxe2_sw_irq_ctxt_uninit(dev);
l_init_sw_err:
sxe2_eth_uinit(dev);
l_init_eth_err:
@@ -544,8 +552,8 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
}
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- snprintf(name, sizeof(name), "sxe2_representor_c%dpf%d%s%u",
- adapter->pf_idx, adapter->pf_idx,
+ snprintf(name, sizeof(name), "%s_representor_%s%u",
+ adapter->cdev->dev->name,
"vf",
req_eth_da->representor_ports[repr_idx]);
@@ -554,6 +562,7 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
ret = -ENOMEM;
goto l_release_port;
}
+ eth_dev->data->numa_node = adapter->dev_info.dev_data->numa_node;
eth_dev->data->dev_private = rte_zmalloc_socket(name,
sizeof(struct sxe2_adapter),
RTE_CACHE_LINE_SIZE,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 06/13] net/sxe2: refactor flow tunnel port handling
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (4 preceding siblings ...)
2026-08-18 2:15 ` [PATCH v1 05/13] net/sxe2: improve representor device initialization liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 07/13] net/sxe2: validate IPsec key length against maximum limit liujie5
` (7 subsequent siblings)
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch refactors flow tunnel port handling and adds support for
PF bond devices:
- Refactor tunnel port functions from pattern module to flow module:
* Move sxe2_flow_parse_pattern_ipip from sxe2_flow_parse_pattern.c
* Move sxe2_flow_add_udp_tunnel_port from sxe2_flow_parse_pattern.c
* Move sxe2_flow_add_tunnel_port from public API to static function
* Remove public function declaration from header file
* Keep functions internal to flow module for better encapsulation
- Add PF bond device support in flow source split processing:
* Add bond_member_cnt field to sxe2_adapter structure
* Handle SXE2_DEV_T_PF_BOND device type in sxe2_flow_src_split_proc
* Populate flow_src_vsi for all bond members
- Enhance ACL engine support in flow actions:
* Add ACL engine support in flow action checks
* Allow PASSTHRU action for ACL engine
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_flow.c | 144 ++++++++++++++++++++-
drivers/net/sxe2/sxe2_flow_parse_action.c | 18 ++-
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ----------------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 7 -
5 files changed, 151 insertions(+), 132 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index d0a0f41ceb..36f4cc9353 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -340,6 +340,7 @@ struct sxe2_adapter {
bool flow_isolate_cfg;
uint16_t dev_port_id;
bool is_dev_repr;
+ uint16_t bond_member_cnt;
uint64_t cap_flags;
enum sxe2_dev_type dev_type;
struct rte_ether_addr mac_addr;
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index 3cf98dd294..af85cb0d2b 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -285,14 +285,16 @@ static int32_t sxe2_flow_meta_proc(struct rte_eth_dev *dev,
attr, "Only support priority 0.");
ret = -rte_errno;
goto l_end;
- } else if (!adapter->switchdev_info.is_switchdev) {
- PMD_LOG_ERR(DRV, "Legacy mode only support priority 0.");
- rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
- attr, "Legacy mode only priority 0.");
- ret = -rte_errno;
- goto l_end;
} else {
- flow->meta.flow_prio = attr->priority;
+ if (!adapter->switchdev_info.is_switchdev) {
+ PMD_LOG_ERR(DRV, "Legacy mode only support priority 0.");
+ rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
+ attr, "Legacy mode only priority 0.");
+ ret = -rte_errno;
+ goto l_end;
+ } else {
+ flow->meta.flow_prio = attr->priority;
+ }
}
}
@@ -347,6 +349,21 @@ static int32_t sxe2_flow_src_split_proc(struct rte_eth_dev *dev,
flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx] = UINT16_MAX;
}
+ if (adapter->dev_type == SXE2_DEV_T_PF_BOND) {
+ flow_bond_num = adapter->bond_member_cnt;
+ for (idx = 0; idx < flow_bond_num; idx++) {
+ flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][idx] =
+ adapter->vsi_ctxt.bond_member_dpdk_vsi_id[idx];
+ flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][idx] =
+ adapter->vsi_ctxt.bond_member_kernel_vsi_id[idx];
+ }
+ } else {
+ flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] =
+ adapter->vsi_ctxt.dpdk_vsi_id;
+ flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] =
+ adapter->vsi_ctxt.kernel_vsi_id;
+ }
+
flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] = adapter->vsi_ctxt.dpdk_vsi_id;
flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] = adapter->vsi_ctxt.kernel_vsi_id;
if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV ||
@@ -550,6 +567,119 @@ int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev)
return ret;
}
+static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
+ enum sxe2_flow_udp_tunnel_protocol proto,
+ struct sxe2_flow *flow,
+ BITMAP_TYPE *flow_type)
+{
+ int32_t ret = 0;
+ uint16_t tun_port;
+
+ tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
+ if (tun_port == 0xffff || tun_port == 0) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
+ goto l_end;
+ }
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP must be over tunnel");
+ goto l_end;
+ }
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
+ flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
+l_end:
+ return ret;
+}
+
+static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
+{
+ sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ }
+ return 0;
+}
+
+static int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
+ struct rte_flow_error *error,
+ struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
+ enum sxe2_flow_tunnel_type tunnel_type)
+{
+ int32_t ret = 0;
+ enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
+ struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
+ switch (tunnel_type) {
+ case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
+ } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
+ sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GTPU:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GRE:
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
+ }
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_IPIP:
+ ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
+ break;
+ default:
+ break;
+ }
+ if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
+ ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
+ if (ret != 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ NULL, "Failed to add udp port for tunnel.");
+ PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
+ goto l_end;
+ }
+ }
+ if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
+ sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
+ }
+l_end:
+ return ret;
+}
+
static int32_t sxe2_flowlist_add_tunnel_port(struct rte_eth_dev *dev,
struct rte_flow *flow_list,
struct rte_flow_error *error)
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index cdd6fcfdcd..867d90ae1d 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -25,15 +25,21 @@ static int32_t sxe2_flow_check_rss_action_attr(const struct rte_flow_action_rss
goto l_end;
}
- if (rss->level > 2)
+ if (rss->level > 2) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"RSS level is could not be greater than 2");
- if (rss->key_len)
+ goto l_end;
+ }
+ if (rss->key_len) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a nonzero RSS key_len is not supported");
- if (rss->queue_num)
+ goto l_end;
+ }
+ if (rss->queue_num) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a non-NULL RSS queue is not supported");
+ goto l_end;
+ }
ret = 0;
l_end:
return ret;
@@ -953,7 +959,8 @@ static int32_t sxe2_flow_check_actions(struct rte_eth_dev *dev __rte_unused, str
}
}
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
if (vsi_num) {
flow->action.q_region.q_index = 0;
flow->action.q_region.region = 7;
@@ -988,7 +995,8 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
case RTE_FLOW_ACTION_TYPE_VOID:
break;
case RTE_FLOW_ACTION_TYPE_PASSTHRU:
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
sxe2_set_bit(SXE2_FLOW_ACTION_PASSTHRU, flow->action.act_types);
action_num[SXE2_FLOW_ACTION_PASSTHRU]++;
} else {
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.c b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
index f5bf8922c6..189abb1a33 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
@@ -1637,119 +1637,6 @@ static int32_t sxe2_flow_parse_pattern_vxlan_gpe(const struct rte_flow_item *ite
return ret;
}
-static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
-{
- sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- }
- return 0;
-}
-
-static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
- enum sxe2_flow_udp_tunnel_protocol proto,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type)
-{
- int32_t ret = 0;
- uint16_t tun_port;
-
- tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
- if (tun_port == 0xffff || tun_port == 0) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
- goto l_end;
- }
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP must be over tunnel");
- goto l_end;
- }
- sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
- flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
-l_end:
- return ret;
-}
-
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type)
-{
- int32_t ret = 0;
- enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
- struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
- struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
- switch (tunnel_type) {
- case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
- } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
- sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GTPU:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GRE:
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
- }
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_IPIP:
- ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
- break;
- default:
- break;
- }
- if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
- ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
- if (ret != 0) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- NULL, "Failed to add udp port for tunnel.");
- PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
- goto l_end;
- }
- }
- if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
- sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
- }
-l_end:
- return ret;
-}
-
struct sxe2_flow_parse_pattern_ops sxe2_flow_parse_pattern_list[] = {
[SXE2_EXPANSION_OUTER_ETH] = {
.is_inner = false,
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.h b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
index 8442c35cae..6872a767dd 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.h
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
@@ -36,11 +36,4 @@ int32_t sxe2_flow_parse_pattern(struct rte_eth_dev *dev,
const struct rte_flow_item patterns[],
struct rte_flow_error *error,
struct sxe2_flow *flow);
-
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type);
-
#endif /* SXE2_FLOW_PARSE_PATTERN_H_ */
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 07/13] net/sxe2: validate IPsec key length against maximum limit
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (5 preceding siblings ...)
2026-08-18 2:15 ` [PATCH v1 06/13] net/sxe2: refactor flow tunnel port handling liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 08/13] net/sxe2: enhance repr event handling and MP code liujie5
` (6 subsequent siblings)
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
Add validation check in sxe2_security_valid_key to ensure source key
length does not exceed SXE2_IPSEC_MAX_KEY_LEN. This prevents potential
buffer overflows when processing security keys that are longer than
the supported maximum length.
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ipsec.c | 5 +++++
drivers/net/sxe2/sxe2_security.c | 1 +
2 files changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ipsec.c b/drivers/net/sxe2/sxe2_ipsec.c
index e783a51b85..622fd1adfe 100644
--- a/drivers/net/sxe2/sxe2_ipsec.c
+++ b/drivers/net/sxe2/sxe2_ipsec.c
@@ -254,6 +254,11 @@ static bool sxe2_security_valid_key(uint16_t src_key, uint16_t max_key,
goto l_end;
}
+ if (src_key > SXE2_IPSEC_MAX_KEY_LEN) {
+ is_valid = false;
+ goto l_end;
+ }
+
is_valid = true;
l_end:
diff --git a/drivers/net/sxe2/sxe2_security.c b/drivers/net/sxe2/sxe2_security.c
index bc59d1b880..8f31067942 100644
--- a/drivers/net/sxe2/sxe2_security.c
+++ b/drivers/net/sxe2/sxe2_security.c
@@ -326,6 +326,7 @@ void sxe2_security_uinit(struct rte_eth_dev *dev)
if (sctx != NULL) {
rte_free(sctx);
sctx = NULL;
+ dev->security_ctx = NULL;
}
sxe2_ipsec_uinit(adapter);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 08/13] net/sxe2: enhance repr event handling and MP code
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (6 preceding siblings ...)
2026-08-18 2:15 ` [PATCH v1 07/13] net/sxe2: validate IPsec key length against maximum limit liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 09/13] net/sxe2: optimize vectorized Tx/Rx path liujie5
` (5 subsequent siblings)
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch improves representor link state event handling and refactors
multi-process message processing:
- Add representor link state event propagation:
* Propagate LSC events to all VF representors when PF link changes
* Get link status and trigger callbacks for each representor
* Only process in primary process for representor callbacks
* Change OICR log format to hexadecimal for better readability
- Refactor primary process message handling:
* Extract work logic to sxe2_mp_do_primary_work helper function
* Use parameter copy to avoid side effects on original message
* Simplify reply construction in primary handler
- Simplify statistics interface:
* Remove qstats parameter from sxe2_mp_req_get_stats
* Remove qstats copy from shared memory
* Update function signature in header and implementation
- Improve error handling and cleanup:
* Change error return from EINVAL to ENODATA when no response
* Simplify sxe2_link_update_init error path
* Remove unnecessary goto statements and cleanup labels
* Remove extra whitespace
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 27 +++++++++++++----
drivers/net/sxe2/sxe2_mac.c | 10 ++-----
drivers/net/sxe2/sxe2_mp.c | 59 +++++++++++++++++++++----------------
3 files changed, 58 insertions(+), 38 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index 3306504761..7fe500b229 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -77,14 +77,32 @@ static int32_t sxe2_fc_state_callback(struct rte_eth_dev *dev)
static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t oicr)
{
struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
+ struct rte_eth_dev *repr_eth_dev;
+ struct sxe2_adapter *repr_adapter;
+ uint8_t vf_id;
if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
- PMD_DEV_LOG_INFO(adapter, DRV, "OICR=%" PRIu64, oicr);
+ PMD_DEV_LOG_INFO(adapter, DRV, "OICR=0x%" PRIx64, oicr);
(void)sxe2_drv_mac_link_status_get(adapter);
- if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_LSC,
NULL);
+ }
+ if (adapter->switchdev_info.is_switchdev) {
+ for (vf_id = 0; vf_id < adapter->repr_ctxt.nb_repr_vf; vf_id++) {
+ repr_eth_dev = adapter->repr_ctxt.vf_rep_eth_dev[vf_id];
+ if (!repr_eth_dev)
+ continue;
+ repr_adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(repr_eth_dev);
+ (void)sxe2_drv_mac_link_status_get(repr_adapter);
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ rte_eth_dev_callback_process(repr_eth_dev,
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL);
+ }
+ }
+ }
}
if (oicr & RTE_BIT32(SXE2_COM_SW_MODE_SWITCHDEV)) {
PMD_DEV_LOG_INFO(adapter, DRV, "event notify switchdev");
@@ -863,12 +881,11 @@ static void sxe2_rxq_intr_unregister(struct rte_eth_dev *dev)
(void)sxe2_drv_dev_rxq_irq_set(adapter->cdev, i, &efd, 1);
sxe2_rxq_intr_efd_free(irq_ctxt->rxq_event_fd[i]);
}
+ rte_free(irq_ctxt->rxq_event_fd);
+ irq_ctxt->rxq_event_fd = NULL;
}
- rte_free(irq_ctxt->rxq_event_fd);
- irq_ctxt->rxq_event_fd = NULL;
rte_intr_vec_list_free(intr_handle);
-
rte_intr_nb_efd_set(intr_handle, 0);
rte_intr_max_intr_set(intr_handle, 0);
}
diff --git a/drivers/net/sxe2/sxe2_mac.c b/drivers/net/sxe2/sxe2_mac.c
index 729c804ac3..e65c578262 100644
--- a/drivers/net/sxe2/sxe2_mac.c
+++ b/drivers/net/sxe2/sxe2_mac.c
@@ -448,20 +448,14 @@ int32_t sxe2_link_update_init(struct rte_eth_dev *dev)
int32_t ret;
PMD_INIT_FUNC_TRACE();
-
rte_spinlock_init(&adapter->link_ctxt.link_lock);
-
ret = sxe2_drv_mac_link_status_get(adapter);
- if (ret) {
+ if (ret)
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get link status, ret=%d", ret);
- goto l_end;
- }
-
- (void)sxe2_link_update(dev, 0);
-l_end:
return ret;
}
+
int32_t sxe2_link_update(struct rte_eth_dev *dev, __rte_unused int32_t wait_to_complete)
{
struct rte_eth_link new_link;
diff --git a/drivers/net/sxe2/sxe2_mp.c b/drivers/net/sxe2/sxe2_mp.c
index a4a5c76495..93a11150a9 100644
--- a/drivers/net/sxe2/sxe2_mp.c
+++ b/drivers/net/sxe2/sxe2_mp.c
@@ -29,16 +29,11 @@ static int32_t sxe2_mp_secondary_handle(const struct rte_mp_msg *mp_msg,
const void *peer);
static int32_t
-sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+sxe2_mp_do_primary_work(struct sxe2_mp_param *param)
{
- struct rte_mp_msg reply;
- const struct sxe2_mp_param *param =
- (const struct sxe2_mp_param *)mp_msg->param;
- struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
struct rte_eth_dev *dev;
- int32_t ret = 0;
struct sxe2_mp_shared_data *mz_data;
- int32_t send_reply = 0;
+ int32_t ret = 0;
int32_t cnt = 0;
if (!rte_eth_dev_is_valid_port(param->port_id)) {
@@ -49,24 +44,21 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
}
dev = &rte_eth_devices[param->port_id];
- sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+
if (sxe2_mp_mz == NULL) {
- PMD_LOG_ERR(DRV, "Failed to lookup memzone %s", SXE2_MP_MZ_NAME);
- ret = -ENOENT;
- goto out;
+ sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+ if (sxe2_mp_mz == NULL) {
+ PMD_LOG_ERR(DRV, "Failed to lookup memzone %s",
+ SXE2_MP_MZ_NAME);
+ ret = -ENOENT;
+ goto out;
+ }
}
mz_data = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
- send_reply = 1;
-
- memset(&reply, 0, sizeof(reply));
- (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
- reply.len_param = sizeof(*reply_param);
-
switch (param->type) {
case SXE2_MP_REQ_GET_STATS:
- ret = sxe2_stats_info_get(dev,
- &mz_data->payload.stats_blk.stats,
+ ret = sxe2_stats_info_get(dev, &mz_data->payload.stats_blk.stats,
&mz_data->payload.stats_blk.qstats);
break;
case SXE2_MP_REQ_GET_XSTATS:
@@ -88,15 +80,32 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
default:
PMD_LOG_ERR(DRV, "primary process: unrecognized msg type: %d",
param->type);
- send_reply = false;
ret = -EINVAL;
- goto out;
+ break;
}
+
out:
- if (!send_reply)
- return ret;
+ param->result = ret;
+ return ret;
+}
- reply_param->result = ret;
+static int32_t
+sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+{
+ struct rte_mp_msg reply;
+ struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
+ const struct sxe2_mp_param *param =
+ (const struct sxe2_mp_param *)mp_msg->param;
+ struct sxe2_mp_param param_copy;
+
+ memset(&reply, 0, sizeof(reply));
+ (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
+ reply.len_param = sizeof(*reply_param);
+
+ param_copy = *param;
+ (void)sxe2_mp_do_primary_work(¶m_copy);
+
+ reply_param->result = param_copy.result;
reply_param->type = param->type;
reply_param->port_id = param->port_id;
@@ -275,7 +284,7 @@ int32_t sxe2_mp_request_simple(struct rte_eth_dev *dev,
if (reply.nb_received == 0) {
PMD_LOG_ERR(DRV, "No response received from primary for type=%d, port %u",
type, dev->data->port_id);
- ret = -EINVAL;
+ ret = -ENOENT;
goto out;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 09/13] net/sxe2: optimize vectorized Tx/Rx path
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (7 preceding siblings ...)
2026-08-18 2:15 ` [PATCH v1 08/13] net/sxe2: enhance repr event handling and MP code liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 10/13] common/sxe2: allow munmap during kernel reset liujie5
` (4 subsequent siblings)
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch optimizes vectorized packet processing with improved buffer
management and unified buffer structure:
- Introduce unified Tx buffer structure:
* Add union in sxe2_tx_queue for buffer_ring/buffer_ring_vec
* Use sxe2_tx_buffer_vec for vectorized Tx path
* Eliminate runtime type checking and branching
- Refactor Tx queue reset operations:
* Extract desc ring reset to sxe2_tx_queue_desc_ring_reset
* Add sxe2_tx_queue_reset_vec for vectorized queues
* Simplify buffer initialization in vector mode
- Optimize Tx vector path mbuf release:
* Remove conditional AVX512 branching
* Use direct buffer_vec access without casting
* Simplify loop logic with consistent pattern
* Remove NULL checks after initialization validation
- Refactor Tx queue operations:
* Export sxe2_tx_buffer_ring_free as public API
* Add sxe2_tx_vec_ops_get() for vector operations
* Use operation table instead of direct function calls
- Improve VSI management:
* Initialize other_vsi_list before main VSI creation
* Ignore -EPERM errors when destroying VSI in uninit
* Set main_vsi to NULL after successful destroy
* Prevent dangling pointer references
- Enhance Tx mode function selection:
* Use rte_eth_tx_pkt_prepare_dummy for vectorized paths
* Split NEON simple/offload mode selection logic
* Clean up conditional compilation structure
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_queue.h | 5 +-
drivers/net/sxe2/sxe2_rx.c | 5 +-
drivers/net/sxe2/sxe2_switchdev.c | 8 +-
drivers/net/sxe2/sxe2_tx.c | 42 +++--
drivers/net/sxe2/sxe2_tx.h | 4 +
drivers/net/sxe2/sxe2_txrx.c | 19 ++-
drivers/net/sxe2/sxe2_txrx_poll.h | 2 -
drivers/net/sxe2/sxe2_txrx_vec.c | 79 +++------
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 133 +--------------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 9 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 218 +++++++++++++++---------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
drivers/net/sxe2/sxe2_vsi.c | 8 +-
15 files changed, 251 insertions(+), 302 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index 10bdaf5b8d..e53a1ce852 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -62,7 +62,10 @@ struct sxe2_txq_ops {
};
struct sxe2_tx_queue {
volatile union sxe2_tx_data_desc *desc_ring;
- struct sxe2_tx_buffer *buffer_ring;
+ union {
+ struct sxe2_tx_buffer *buffer_ring;
+ struct sxe2_tx_buffer_vec *buffer_ring_vec;
+ };
volatile uint32_t *tdt_reg_addr;
uint64_t offloads;
diff --git a/drivers/net/sxe2/sxe2_rx.c b/drivers/net/sxe2/sxe2_rx.c
index d700c60083..6340ed933a 100644
--- a/drivers/net/sxe2/sxe2_rx.c
+++ b/drivers/net/sxe2/sxe2_rx.c
@@ -319,7 +319,8 @@ int32_t __rte_cold sxe2_rx_queue_setup(struct rte_eth_dev *dev,
rxq->mb_pool = mp;
}
- rxq->rx_free_thresh = rx_conf->rx_free_thresh;
+ rxq->rx_free_thresh = (rx_conf->rx_free_thresh == 0) ?
+ SXE2_DEFAULT_RX_FREE_THRESH : rx_conf->rx_free_thresh;
rxq->port_id = dev->data->port_id;
rxq->offloads = offloads;
if (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
@@ -550,7 +551,7 @@ void __rte_cold sxe2_rxqs_all_stop(struct rte_eth_dev *dev)
static int32_t sxe2_monitor_callback(const uint64_t value,
const uint64_t arg[RTE_POWER_MONITOR_OPAQUE_SZ] __rte_unused)
{
- const uint64_t dd_state = rte_cpu_to_le_64(SXE2_RX_DESC_STATUS_DD_MASK);
+ const uint64_t dd_state = rte_cpu_to_le_64(SXE2_RX_DESC_STATUS_DD_SHIFT);
return (value & dd_state) == dd_state ? -1 : 0;
}
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index efb1468b91..374cc4e223 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -316,13 +316,7 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
-
- repr_priv_data->repr_vf_vsi_id =
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id !=
- SXE2_INVALID_VSI_ID ?
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id :
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
-
+ repr_priv_data->repr_vf_vsi_id = repr_priv_data->repr_vf_primary_vsi_id;
adapter->repr_priv_data = repr_priv_data;
goto l_end;
l_free:
diff --git a/drivers/net/sxe2/sxe2_tx.c b/drivers/net/sxe2/sxe2_tx.c
index f49238ceef..94a6e9afc7 100644
--- a/drivers/net/sxe2/sxe2_tx.c
+++ b/drivers/net/sxe2/sxe2_tx.c
@@ -19,6 +19,17 @@ static void *sxe2_tx_doorbell_addr_get(struct sxe2_adapter *adapter, uint16_t qu
queue_id);
}
+static void sxe2_tx_queue_desc_ring_reset(struct sxe2_tx_queue *txq)
+{
+ uint16_t i;
+ static const union sxe2_tx_data_desc zeroed_desc = {{0}};
+
+ for (i = 0; i < txq->ring_depth; i++) {
+ txq->desc_ring[i] = zeroed_desc;
+ txq->desc_ring[i].wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
+ }
+}
+
static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue *txq)
{
txq->tdt_reg_addr = sxe2_tx_doorbell_addr_get(adapter, txq->queue_id);
@@ -28,20 +39,12 @@ static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
{
uint16_t prev, i;
- volatile union sxe2_tx_data_desc *txd;
- static const union sxe2_tx_data_desc zeroed_desc = {{0}};
struct sxe2_tx_buffer *tx_buffer = txq->buffer_ring;
- for (i = 0; i < txq->ring_depth; i++)
- txq->desc_ring[i] = zeroed_desc;
+ sxe2_tx_queue_desc_ring_reset(txq);
prev = txq->ring_depth - 1;
for (i = 0; i < txq->ring_depth; i++) {
- txd = &txq->desc_ring[i];
- if (txd == NULL)
- continue;
-
- txd->wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
tx_buffer[i].mbuf = NULL;
tx_buffer[i].last_id = i;
tx_buffer[prev].next_id = i;
@@ -56,6 +59,21 @@ void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
txq->next_rs = txq->rs_thresh - 1;
}
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq)
+{
+ sxe2_tx_queue_desc_ring_reset(txq);
+
+ memset(txq->buffer_ring, 0,
+ sizeof(struct sxe2_tx_buffer) * txq->ring_depth);
+
+ txq->desc_used_num = 0;
+ txq->desc_free_num = txq->ring_depth - 1;
+ txq->next_use = 0;
+ txq->next_clean = txq->ring_depth - 1;
+ txq->next_dd = txq->rs_thresh - 1;
+ txq->next_rs = txq->rs_thresh - 1;
+}
+
void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
{
uint32_t i;
@@ -70,10 +88,12 @@ void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
}
}
-static void sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
{
- if (txq != NULL && txq->buffer_ring != NULL)
+ if (txq != NULL && txq->buffer_ring != NULL) {
rte_free(txq->buffer_ring);
+ txq->buffer_ring = NULL;
+ }
}
const struct sxe2_txq_ops sxe2_default_txq_ops = {
diff --git a/drivers/net/sxe2/sxe2_tx.h b/drivers/net/sxe2/sxe2_tx.h
index f4823126b3..bc5ff1c2bc 100644
--- a/drivers/net/sxe2/sxe2_tx.h
+++ b/drivers/net/sxe2/sxe2_tx.h
@@ -9,6 +9,10 @@
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq);
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq);
+
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq);
+
int32_t __rte_cold sxe2_tx_queue_start(struct rte_eth_dev *dev, uint16_t queue_id);
void sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq);
diff --git a/drivers/net/sxe2/sxe2_txrx.c b/drivers/net/sxe2/sxe2_txrx.c
index 79870866d1..d27d2ce630 100644
--- a/drivers/net/sxe2/sxe2_txrx.c
+++ b/drivers/net/sxe2/sxe2_txrx.c
@@ -358,7 +358,7 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
if (tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
#ifdef RTE_ARCH_X86
if (tx_mode_flags & SXE2_TX_MODE_VEC_AVX512) {
#ifdef CC_AVX512_SUPPORT
@@ -386,21 +386,25 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
#elif defined(RTE_ARCH_ARM64)
if (tx_mode_flags & SXE2_TX_MODE_VEC_NEON) {
- dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
- } else {
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ if (tx_mode_flags & SXE2_TX_MODE_VEC_OFFLOAD) {
+ dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
+ } else {
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ }
}
#endif
} else {
if (tx_mode_flags & SXE2_TX_MODE_SIMPLE_BATCH) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
dev->tx_pkt_burst = sxe2_tx_pkts_simple;
} else {
dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
dev->tx_pkt_burst = sxe2_tx_pkts;
}
}
+ PMD_LOG_DEBUG(TX, "Tx mode flags:0x%016x port_id:%u.",
+ tx_mode_flags, dev->data->port_id);
}
static const struct {
@@ -582,6 +586,9 @@ void sxe2_rx_mode_func_set(struct rte_eth_dev *dev)
dev->rx_pkt_burst = sxe2_rx_pkts_scattered_split;
else
dev->rx_pkt_burst = sxe2_rx_pkts_scattered;
+
+ PMD_LOG_DEBUG(RX, "Rx mode flags:0x%016x port_id:%u.",
+ rx_mode_flags, dev->data->port_id);
}
static const struct {
diff --git a/drivers/net/sxe2/sxe2_txrx_poll.h b/drivers/net/sxe2/sxe2_txrx_poll.h
index 708e3839d7..bfa099c097 100644
--- a/drivers/net/sxe2/sxe2_txrx_poll.h
+++ b/drivers/net/sxe2/sxe2_txrx_poll.h
@@ -13,8 +13,6 @@ uint16_t sxe2_tx_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t
uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-
uint16_t sxe2_rx_pkts_scattered_split(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
#endif /* SXE2_TXRX_POLL_H */
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.c b/drivers/net/sxe2/sxe2_txrx_vec.c
index cf004f5eb2..05940c8cb5 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec.c
@@ -8,6 +8,19 @@
#include "sxe2_ethdev.h"
#include "sxe2_common_log.h"
+static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq);
+
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void)
+{
+ static const struct sxe2_txq_ops ops = {
+ .queue_reset = sxe2_tx_queue_reset_vec,
+ .mbufs_release = sxe2_tx_queue_mbufs_release_vec,
+ .buffer_ring_free = sxe2_tx_buffer_ring_free,
+ };
+
+ return ops;
+}
+
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags)
{
struct sxe2_rx_queue *rxq;
@@ -157,67 +170,28 @@ int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *
static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq)
{
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer_vec;
uint16_t i;
- if (unlikely(txq == NULL || txq->buffer_ring == NULL)) {
+ if (unlikely(txq == NULL || txq->buffer_ring_vec == NULL)) {
PMD_LOG_ERR(TX, "Tx release mbufs vec, invalid params.");
return;
}
- i = txq->next_dd - (txq->rs_thresh - 1);
-#ifdef CC_AVX512_SUPPORT
- struct rte_eth_dev *dev;
- struct sxe2_tx_buffer_vec *buffer_vec;
- dev = &rte_eth_devices[txq->port_id];
-
- if (dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512 ||
- dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512_simple) {
- buffer_vec = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ i = txq->next_dd - (txq->rs_thresh - 1);
+ buffer_vec = txq->buffer_ring_vec;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer_vec[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
- buffer_vec[i].mbuf = NULL;
- }
- }
- i = 0;
- }
- for ( ; i < txq->next_use; ++i) {
- if (buffer_vec[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
- buffer_vec[i].mbuf = NULL;
- }
+ if (txq->next_use < i) {
+ for ( ; i < txq->ring_depth; ++i) {
+ rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
+ buffer_vec[i].mbuf = NULL;
}
- } else {
-#endif
- buffer = txq->buffer_ring;
- buffer = txq->buffer_ring;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
- i = 0;
- }
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
-#ifdef CC_AVX512_SUPPORT
+ i = 0;
}
-#endif
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
+ for ( ; i < txq->next_use; ++i) {
+ rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
+ buffer_vec[i].mbuf = NULL;
}
}
@@ -233,7 +207,8 @@ int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev)
PMD_LOG_INFO(TX, "Failed to prepare tx queue, txq[%d] is NULL", i);
continue;
}
- txq->ops.mbufs_release = sxe2_tx_queue_mbufs_release_vec;
+ txq->ops = sxe2_tx_vec_ops_get();
+ txq->ops.queue_reset(txq);
}
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.h b/drivers/net/sxe2/sxe2_txrx_vec.h
index c139aed776..b9bc4f9c27 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec.h
@@ -89,6 +89,7 @@ uint16_t sxe2_rx_pkts_scattered_vec_neon_offload(void *rx_queue, struct rte_mbuf
uint16_t sxe2_tx_pkts_vec_neon_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
#endif
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void);
int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev);
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
index 0618e6d988..da96ca3064 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
@@ -115,7 +115,7 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -134,14 +134,14 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -157,10 +157,10 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
index a830c7a33b..6c8415ee5a 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
@@ -1,8 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
*/
-
-#ifndef SXE2_TEST
#include <rte_vect.h>
#include "sxe2_ethdev.h"
@@ -12,114 +10,6 @@
#include "sxe2_txrx_vec_common.h"
#include "sxe2_vsi.h"
-static __rte_always_inline int32_t sxe2_tx_bufs_free_vec_avx512(struct sxe2_tx_queue *txq)
-{
- struct sxe2_tx_buffer_vec *buffer;
- struct rte_mbuf *mbuf;
- struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC];
- struct rte_mempool *mp;
- struct rte_mempool_cache *cache;
- void **cache_objs;
- uint32_t copied;
- uint32_t i;
- int32_t ret;
- uint16_t rs_thresh;
- uint16_t free_num;
-
- if (rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE) !=
- (txq->desc_ring[txq->next_dd].wb.dd &
- rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK))) {
- ret = 0;
- goto l_end;
- }
-
- rs_thresh = txq->rs_thresh;
-
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += txq->next_dd - (rs_thresh - 1);
-
- if ((txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) &&
- (rs_thresh & 31) == 0) {
- mp = buffer[0].mbuf->pool;
- cache = rte_mempool_default_cache(mp, rte_lcore_id());
-
- if (cache == NULL || cache->len)
- goto normal;
-
- if (rs_thresh > RTE_MEMPOOL_CACHE_MAX_SIZE) {
- (void)rte_mempool_ops_enqueue_bulk(mp, (void *)buffer, rs_thresh);
- goto done;
- }
- cache_objs = &cache->objs[cache->len];
-
- copied = 0;
- while (copied < rs_thresh) {
- const __m512i objs0 = _mm512_loadu_si512(&buffer[copied]);
- const __m512i objs1 = _mm512_loadu_si512(&buffer[copied + 8]);
- const __m512i objs2 = _mm512_loadu_si512(&buffer[copied + 16]);
- const __m512i objs3 = _mm512_loadu_si512(&buffer[copied + 24]);
-
- _mm512_storeu_si512(&cache_objs[copied], objs0);
- _mm512_storeu_si512(&cache_objs[copied + 8], objs1);
- _mm512_storeu_si512(&cache_objs[copied + 16], objs2);
- _mm512_storeu_si512(&cache_objs[copied + 24], objs3);
- copied += 32;
- }
- cache->len += rs_thresh;
-
- if (cache->len >= cache->flushthresh) {
- (void)rte_mempool_ops_enqueue_bulk(mp,
- &cache->objs[cache->size], cache->len - cache->size);
- cache->len = cache->size;
- }
- goto done;
- }
-
-normal:
- mbuf = rte_pktmbuf_prefree_seg(buffer[0].mbuf);
-
- if (likely(mbuf)) {
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
-
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
-
- if (likely(mbuf)) {
- if (likely(mbuf->pool == mbuf_free_arr[0]->pool)) {
- mbuf_free_arr[free_num] = mbuf;
- free_num++;
- } else {
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
-
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
- }
- }
- }
-
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
- } else {
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
- if (mbuf != NULL)
- rte_mempool_put(mbuf->pool, mbuf);
- }
- }
-
-done:
- txq->desc_free_num += txq->rs_thresh;
- txq->next_dd += txq->rs_thresh;
- if (txq->next_dd >= txq->ring_depth)
- txq->next_dd = txq->rs_thresh - 1;
- ret = rs_thresh;
-
-l_end:
- return ret;
-}
-
static __rte_always_inline void
sxe2_tx_desc_fill_one_avx512(volatile union sxe2_tx_data_desc *desc, struct rte_mbuf *pkt,
uint64_t desc_cmd, bool with_offloads)
@@ -207,16 +97,6 @@ void sxe2_tx_desc_fill_avx512(volatile union sxe2_tx_data_desc *desc, struct rte
}
}
-static __rte_always_inline void
-sxe2_tx_pkts_mbuf_fill_avx512(struct sxe2_tx_buffer_vec *buffer,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
- uint16_t i;
-
- for (i = 0; i < nb_pkts; ++i)
- buffer[i].mbuf = tx_pkts[i];
-}
-
static __rte_always_inline uint16_t
sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool with_offloads)
@@ -228,7 +108,7 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
uint16_t tx_num;
if (txq->desc_free_num < txq->free_thresh)
- (void)sxe2_tx_bufs_free_vec_avx512(txq);
+ (void)sxe2_tx_bufs_free_vec(txq);
nb_pkts = RTE_MIN(txq->desc_free_num, nb_pkts);
if (unlikely(nb_pkts == 0)) {
@@ -241,15 +121,14 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += next_use;
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -265,10 +144,10 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = txq->desc_ring;
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -863,5 +742,3 @@ uint16_t sxe2_rx_pkts_scattered_vec_avx512_offload(void *rx_queue,
return sxe2_rx_pkts_scattered_common_vec_avx512(rx_queue,
rx_pkts, nb_pkts, true);
}
-
-#endif
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_common.h b/drivers/net/sxe2/sxe2_txrx_vec_common.h
index 9ac99cf0fa..ede4c236b1 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_common.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec_common.h
@@ -25,10 +25,11 @@
#define SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC 64
static __rte_always_inline void
-sxe2_tx_pkts_mbuf_fill(struct sxe2_tx_buffer *buffer,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+sxe2_tx_pkts_mbuf_fill_vec(struct sxe2_tx_buffer_vec *buffer,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
uint16_t i;
+
for (i = 0; i < nb_pkts; ++i)
buffer[i].mbuf = tx_pkts[i];
}
@@ -36,7 +37,7 @@ sxe2_tx_pkts_mbuf_fill(struct sxe2_tx_buffer *buffer,
static __rte_always_inline int32_t
sxe2_tx_bufs_free_vec(struct sxe2_tx_queue *txq)
{
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
struct rte_mbuf *mbuf;
struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC];
int32_t ret;
@@ -50,7 +51,7 @@ sxe2_tx_bufs_free_vec(struct sxe2_tx_queue *txq)
goto l_end;
}
rs_thresh = txq->rs_thresh;
- buffer = &txq->buffer_ring[txq->next_dd - (rs_thresh - 1)];
+ buffer = &txq->buffer_ring_vec[txq->next_dd - (rs_thresh - 1)];
mbuf = rte_pktmbuf_prefree_seg(buffer[0].mbuf);
if (likely(mbuf)) {
mbuf_free_arr[0] = mbuf;
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_neon.c b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
index 4e5cb87cd5..6e0bdce278 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_neon.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
@@ -34,12 +34,57 @@ sxe2_tx_desc_fill_one_neon(volatile union sxe2_tx_data_desc *desc,
vst1q_u64(RTE_CAST_PTR(uint64_t *, desc), data_desc);
}
+static __rte_always_inline void
+sxe2_tx_desc_fill_4_neon_simple(volatile union sxe2_tx_data_desc *desc,
+ struct rte_mbuf **pkts)
+{
+ uint64x2_t d0, d1, d2, d3;
+ uint64x2x4_t v;
+ const uint64_t cmd_base = ((uint64_t)SXE2_TX_DESC_DTYPE_DATA) |
+ ((uint64_t)SXE2_TX_DATA_DESC_CMD_EOP) << SXE2_TX_DATA_DESC_CMD_SHIFT;
+
+ d0 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[0]),
+ cmd_base |
+ ((uint64_t)pkts[0]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[0]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d1 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[1]),
+ cmd_base |
+ ((uint64_t)pkts[1]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[1]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d2 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[2]),
+ cmd_base |
+ ((uint64_t)pkts[2]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[2]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d3 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[3]),
+ cmd_base |
+ ((uint64_t)pkts[3]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[3]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+
+ v.val[0] = d0;
+ v.val[1] = d1;
+ v.val[2] = d2;
+ v.val[3] = d3;
+ vst1q_u64_x4(RTE_CAST_PTR(uint64_t *, desc), v);
+}
+
static __rte_always_inline uint16_t
sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -59,18 +104,26 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
-
- for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
+ if (with_offloads) {
+ for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ }
+ } else {
+ for (i = 0; i + 3 < res_num - 1; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
sxe2_tx_desc_fill_one_neon(desc, *tx_pkts++,
@@ -82,14 +135,23 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
- for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ if (with_offloads) {
+ for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, true);
+ }
+ } else {
+ for (i = 0; i + 3 < tx_num; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
next_use += tx_num;
@@ -150,22 +212,24 @@ uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue,
}
static __rte_always_inline void
-sxe2_rx_desc_ptype_fill_neon(uint16x8_t staterr, struct rte_mbuf **__rte_restrict rx_pkts)
+sxe2_rx_desc_ptype_fill_neon(uint32x4_t desc_lo,
+ struct rte_mbuf **__rte_restrict rx_pkts,
+ const uint32_t *__rte_restrict ptype_tbl)
{
- uint16x8_t ptype_mask = {
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
+ const uint32x4_t ptype_mask = {
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
};
uint16x8_t ptype_all;
- ptype_all = vandq_u16(staterr, ptype_mask);
+ ptype_all = vreinterpretq_u16_u32(vandq_u32(desc_lo, ptype_mask));
- rx_pkts[3]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
- rx_pkts[2]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
- rx_pkts[1]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
- rx_pkts[0]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[0]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
+ rx_pkts[1]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
+ rx_pkts[2]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[3]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
}
static __rte_always_inline uint32x4_t
@@ -208,9 +272,10 @@ sxe2_rx_desc_fnav_flags_neon(uint64x2_t descs_arr[4])
static __rte_always_inline void
sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
volatile union sxe2_rx_desc *desc,
- uint64x2_t descs[4], struct rte_mbuf **rx_pkts)
+ uint64x2_t descs[4], uint32x4_t desc_lo, uint32x4_t desc_hi,
+ struct rte_mbuf **rx_pkts)
{
- uint32x4_t desc_lo, desc_hi, flags, tmp_flags;
+ uint32x4_t flags, tmp_flags;
const uint64x2_t mbuf_init = {rxq->mbuf_init_value, 0};
uint64x2_t rearm0, rearm1, rearm2, rearm3;
@@ -267,23 +332,6 @@ sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
0, 0, 0, 0, 0, 0, 0, 0
};
- {
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint64x2_t f64, t64;
-
- flags = vzip2q_u32(d1, d0);
- tmp_flags = vzip2q_u32(d3, d2);
- f64 = vreinterpretq_u64_u32(flags);
- t64 = vreinterpretq_u64_u32(tmp_flags);
- desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(f64),
- vget_low_u64(t64)));
- desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(f64),
- vget_high_u64(t64)));
- }
-
desc_lo = vandq_u32(desc_lo, desc_msk);
desc_hi = vandq_u32(desc_hi, rss_msk);
@@ -442,25 +490,39 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
uint64x2_t descs[SXE2_RX_NUM_PER_LOOP_NEON];
uint8x16_t pkt_mb1, pkt_mb2, pkt_mb3, pkt_mb4;
uint64x2_t mbp1, mbp2;
+ uint32x4_t desc_lo, desc_hi;
uint16x8_t staterr;
uint16x8_t tmp;
uint16_t bit_num;
descs[3] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 3));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[2] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 2));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[1] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 1));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[0] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc));
rte_atomic_thread_fence(rte_memory_order_acquire);
-
descs[3] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 3), descs[3], 0);
descs[2] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 2), descs[2], 0);
descs[1] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 1), descs[1], 0);
descs[0] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc), descs[0], 0);
+ {
+ uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
+ uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
+ uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
+ uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
+
+ uint32x4_t q1_01 = vzip2q_u32(d0, d1);
+ uint32x4_t q1_23 = vzip2q_u32(d2, d3);
+ uint64x2_t q1_01_64 = vreinterpretq_u64_u32(q1_01);
+ uint64x2_t q1_23_64 = vreinterpretq_u64_u32(q1_23);
+
+ desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(q1_01_64),
+ vget_low_u64(q1_23_64)));
+ desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(q1_01_64),
+ vget_high_u64(q1_23_64)));
+ }
+
mbp1 = vld1q_u64((uint64_t *)&buffer[i]);
mbp2 = vld1q_u64((uint64_t *)&buffer[i + 2]);
@@ -480,7 +542,8 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
pkt_mb1 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[0]), rvp_shuf_mask);
if (do_offload) {
- sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, &rx_pkts[i]);
+ sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, desc_lo,
+ desc_hi, &rx_pkts[i]);
} else {
const uint64x2_t mbuf_init = {
rxq->mbuf_init_value,
@@ -515,55 +578,48 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
rte_prefetch_non_temporal(desc + SXE2_RX_NUM_PER_LOOP_NEON);
{
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint32x4_t sterr_tmp1 = vzip2q_u32(d1, d0);
- uint32x4_t sterr_tmp2 = vzip2q_u32(d3, d2);
- uint32x4_t sterr_u32 = vzip1q_u32(sterr_tmp1, sterr_tmp2);
-
- staterr = vreinterpretq_u16_u32(sterr_u32);
+ uint16x8_t sterr_tmp1 = vzip2q_u16(vreinterpretq_u16_u64(descs[0]),
+ vreinterpretq_u16_u64(descs[2]));
+ uint16x8_t sterr_tmp2 = vzip2q_u16(vreinterpretq_u16_u64(descs[1]),
+ vreinterpretq_u16_u64(descs[3]));
+ staterr = vzip1q_u16(sterr_tmp1, sterr_tmp2);
}
- sxe2_rx_desc_ptype_fill_neon(staterr, &rx_pkts[i]);
+ sxe2_rx_desc_ptype_fill_neon(desc_lo, &rx_pkts[i], sxe2_ptype_tbl);
if (umbcast_flags != NULL) {
- uint32x4_t umbcast_mask = {
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- };
-
+ const uint32x4_t umbcast_mask =
+ vdupq_n_u32(SXE2_RX_DESC_STATUS_UMBCAST_MASK);
uint8x16_t umbcast_shuf_mask = {
- 0x0B, 0x03, 0x0F, 0x07,
+ 3, 7, 11, 15,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
};
uint8x16_t umbcast_bits =
- vreinterpretq_u8_u32(vandq_u32(vreinterpretq_u32_u16(staterr),
- umbcast_mask));
+ vreinterpretq_u8_u32(vandq_u32(desc_lo, umbcast_mask));
umbcast_bits = vqtbl1q_u8(umbcast_bits, umbcast_shuf_mask);
- vst1q_lane_u32((uint32_t *)umbcast_flags,
- vreinterpretq_u32_u8(umbcast_bits), 0);
+ *(uint32_t *)umbcast_flags =
+ vgetq_lane_u32(vreinterpretq_u32_u8(umbcast_bits), 0);
umbcast_flags += SXE2_RX_NUM_PER_LOOP_NEON;
}
if (split_rxe_flags) {
uint8x16_t eop_shuf_mask = {
- 0x08, 0x00, 0x0C, 0x04,
+ 0, 2, 4, 6,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF};
uint8x16_t eop_bits;
uint32x4_t rxe_mask = {
- 0x2080, 0x2080, 0x2080, 0x2080
+ 0x20802080, 0x20802080, 0x20802080, 0x20802080
};
uint32x4_t rxe_bits;
uint32x4_t eop_mask;
- eop_mask = vshlq_n_u32(vdupq_n_u32(1), SXE2_RX_DESC_STATUS_EOP_SHIFT);
+ eop_mask = vdupq_n_u32((1U << SXE2_RX_DESC_STATUS_EOP_SHIFT) |
+ (1U << (SXE2_RX_DESC_STATUS_EOP_SHIFT + 16)));
eop_bits = vandq_u8(vmvnq_u8(vreinterpretq_u8_u16(staterr)),
vreinterpretq_u8_u32(eop_mask));
@@ -587,12 +643,22 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
}
{
- uint32x4_t dd_mask = vdupq_n_u32(1);
- uint32x4_t sterr_dd = vandq_u32(vreinterpretq_u32_u16(staterr), dd_mask);
- uint16x4_t packed_lo = vmovn_u32(sterr_dd);
- uint64_t dd64 = vget_lane_u64(vreinterpret_u64_u16(packed_lo), 0);
-
- bit_num = (uint16_t)rte_popcount64(dd64);
+ const uint16x8_t dd_check = {
+ 0x0001, 0x0001, 0x0001, 0x0001,
+ 0, 0, 0, 0
+ };
+ uint16x8_t sterr_dd;
+ uint64_t stat;
+ sterr_dd = vandq_u16(staterr, dd_check);
+ sterr_dd = vshlq_n_u16(sterr_dd, 15);
+ sterr_dd =
+ vreinterpretq_u16_s16(vshrq_n_s16(vreinterpretq_s16_u16(sterr_dd),
+ 15));
+ stat = ~vgetq_lane_u64(vreinterpretq_u64_u16(sterr_dd), 0);
+ if (likely(stat == 0))
+ bit_num = SXE2_RX_NUM_PER_LOOP_NEON;
+ else
+ bit_num = (uint16_t)(rte_ctz64(stat) / 16);
}
done_num += bit_num;
if (likely(bit_num != SXE2_RX_NUM_PER_LOOP_NEON))
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_sse.c b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
index c3e8a2983b..181bb40041 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_sse.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
@@ -40,7 +40,7 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -57,11 +57,11 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
tx_num = nb_pkts;
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
@@ -74,9 +74,9 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
diff --git a/drivers/net/sxe2/sxe2_vsi.c b/drivers/net/sxe2/sxe2_vsi.c
index d29480b931..ba4cc7414e 100644
--- a/drivers/net/sxe2/sxe2_vsi.c
+++ b/drivers/net/sxe2/sxe2_vsi.c
@@ -230,7 +230,7 @@ int32_t sxe2_vsi_init(struct rte_eth_dev *dev)
uint16_t srcvsi_cnt;
PMD_INIT_FUNC_TRACE();
-
+ TAILQ_INIT(&adapter->vsi_ctxt.other_vsi_list);
ret = sxe2_main_vsi_create(adapter);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to create main VSI, ret=%d", ret);
@@ -283,13 +283,14 @@ void sxe2_vsi_uninit(struct rte_eth_dev *dev)
l_free:
ret = sxe2_vsi_destroy(adapter, adapter->vsi_ctxt.main_vsi);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
goto l_end;
}
+ adapter->vsi_ctxt.main_vsi = NULL;
RTE_TAILQ_FOREACH_SAFE(var, &adapter->vsi_ctxt.other_vsi_list, next, tvar) {
ret = sxe2_vsi_destroy(adapter, var);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
break;
}
@@ -357,4 +358,5 @@ void sxe2_vsi_repr_main_vsi_destroy(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
sxe2_vsi_node_free(adapter->vsi_ctxt.main_vsi);
+ adapter->vsi_ctxt.main_vsi = NULL;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 10/13] common/sxe2: allow munmap during kernel reset
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (8 preceding siblings ...)
2026-08-18 2:15 ` [PATCH v1 09/13] net/sxe2: optimize vectorized Tx/Rx path liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 11/13] net/sxe2: clean up duplicate function declarations liujie5
` (3 subsequent siblings)
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch improves error handling and resource management:
- Add NULL pointer protection in driver remove path:
* Check cdrv and cdrv->remove before calling remove function
* Prevent NULL pointer dereference in sxe2_classes_driver_remove
* Return SXE2_SUCCESS if no driver or remove handler exists
- Allow memory unmap during kernel reset:
* Remove kernel_reset restriction in sxe2_drv_dev_munmap
* Enable cleanup operations even when kernel has been reset
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_common.c | 5 ++++-
drivers/common/sxe2/sxe2_ioctl_chnl.c | 8 +-------
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/common/sxe2/sxe2_common.c b/drivers/common/sxe2/sxe2_common.c
index 5c5db85f29..3f60b2be11 100644
--- a/drivers/common/sxe2/sxe2_common.c
+++ b/drivers/common/sxe2/sxe2_common.c
@@ -465,8 +465,11 @@ static int32_t sxe2_classes_driver_probe(struct sxe2_common_device *cdev,
static int32_t sxe2_classes_driver_remove(struct sxe2_common_device *cdev)
{
struct sxe2_class_driver *cdrv = cdev->cdrv;
+ int32_t ret = 0;
- return cdrv->remove(cdev);
+ if (cdrv != NULL && cdrv->remove != NULL)
+ ret = cdrv->remove(cdev);
+ return ret;
}
static int32_t sxe2_kvargs_validate(struct sxe2_dev_kvargs_info *kv_info)
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index a233a78136..3e2fbf572f 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -367,16 +367,10 @@ void
RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_munmap)
int32_t
-sxe2_drv_dev_munmap(struct sxe2_common_device *cdev, void *virt, uint64_t len)
+sxe2_drv_dev_munmap(struct sxe2_common_device *cdev __rte_unused, void *virt, uint64_t len)
{
int32_t ret = 0;
- if (cdev->config.kernel_reset) {
- ret = -EPERM;
- PMD_LOG_WARN(COM, "kernel reset, need restart app.");
- goto l_end;
- }
-
PMD_LOG_DEBUG(COM, "Munmap virt=%p, len=0x%"PRIx64"",
virt, len);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 11/13] net/sxe2: clean up duplicate function declarations
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (9 preceding siblings ...)
2026-08-18 2:15 ` [PATCH v1 10/13] common/sxe2: allow munmap during kernel reset liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 12/13] net/sxe2: clean up structure definitions liujie5
` (2 subsequent siblings)
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This commit removes duplicate function declarations in the sxe2
driver header files.
- Remove duplicate sxe2_drv_promisc_config declaration
in sxe2_cmd_chnl.h
- Remove duplicate sxe2_drv_vsi_info_get declaration
in sxe2_cmd_chnl.h
- Remove duplicate sxe2_drv_mac_link_status_get declaration
in sxe2_cmd_chnl.h
- Remove duplicate sxe2_drv_rxq_mapping_set declaration
in sxe2_cmd_chnl.h
- Remove duplicate sxe2_dev_pci_seg_unmap declaration
in sxe2_ethdev.h
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.h | 6 ------
drivers/net/sxe2/sxe2_ethdev.h | 2 --
2 files changed, 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index 7d75a91061..7d07068bfc 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -65,8 +65,6 @@ int32_t sxe2_drv_ipsec_rxsa_delete(struct sxe2_adapter *adapter,
int32_t sxe2_drv_ipsec_txsa_delete(struct sxe2_adapter *adapter,
uint16_t sa_id);
-int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set);
-
int32_t sxe2_drv_udp_tunnel_add(struct sxe2_adapter *adapter,
enum sxe2_udp_tunnel_protocol tunnel_proto,
uint16_t udp_port);
@@ -84,8 +82,6 @@ int32_t sxe2_drv_get_udp_tunnel_port(struct sxe2_adapter *adapter,
int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-
int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter);
int32_t sxe2_drv_get_mac_stats(struct sxe2_adapter *adapter);
@@ -110,8 +106,6 @@ int32_t sxe2_drv_mapping_reset(struct rte_eth_dev *eth_dev);
int32_t sxe2_drv_mapping_stats_info_clear(struct rte_eth_dev *eth_dev);
-int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t pool_idx);
-
int32_t sxe2_drv_allmulti_config(struct sxe2_adapter *adapter, bool set);
int32_t sxe2_drv_uc_config(struct sxe2_adapter *adapter, struct rte_ether_addr *addr, bool add);
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 36f4cc9353..b43030deab 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -387,8 +387,6 @@ void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
int32_t sxe2_dev_pci_map_init(struct rte_eth_dev *dev);
-void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
-
int32_t sxe2_udp_tunnel_port_del_common(struct sxe2_adapter *ad,
enum sxe2_udp_tunnel_protocol tunnel_proto, uint16_t udp_port);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 12/13] net/sxe2: clean up structure definitions
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (10 preceding siblings ...)
2026-08-18 2:15 ` [PATCH v1 11/13] net/sxe2: clean up duplicate function declarations liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
2026-08-18 14:22 ` [PATCH v1 00/13] net/sxe2: fix bugs Stephen Hemminger
13 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This commit removes packed attributes and unused reserved fields
from structure definitions in the sxe2 driver header file.
- Remove packed attributes and rsv[2] field from sxe2_tm_res
structure
- Remove packed attributes from sxe2_tm_info structure
- Remove packed attributes from sxe2_txq_map_info structure
- Remove packed attributes from sxe2_rxq_map_info structure
- Remove packed attributes from sxe2_queue_map_info structure
- Remove packed attributes from sxe2_drv_sfp_req structure
- Remove packed attributes from sxe2_drv_sfp_resp structure
- Remove unused rsv[3] field from sxe2_drv_link_info_resp
structure
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_drv_cmd.h | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index d332d15980..297bdca820 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -230,7 +230,6 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_info_get_resp {
struct __rte_aligned(4) __rte_packed_begin sxe2_drv_link_info_resp {
uint32_t speed;
uint8_t status;
- uint8_t rsv[3];
} __rte_packed_end;
struct __rte_aligned(4) __rte_packed_begin sxe2_switchdev_info {
@@ -348,18 +347,17 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_rss_hf_req {
uint8_t rsv1[3];
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_res {
+struct sxe2_tm_res {
uint16_t teid;
- uint8_t rsv[2];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_info {
+struct sxe2_tm_info {
uint32_t committed;
uint32_t peak;
uint8_t priority;
uint8_t reserve;
uint16_t weight;
-} __rte_packed_end;
+};
struct __rte_aligned(4) __rte_packed_begin sxe2_tm_add_mid_msg {
uint16_t parent_teid;
@@ -526,24 +524,24 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_mac_stats_resp {
uint64_t prio_xon_2_xoff[SXE2_MAX_USER_PRIORITY];
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_txq_map_info {
+struct sxe2_txq_map_info {
uint32_t txq_lan_pkt_cnt;
uint32_t txq_lan_byte_cnt;
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_rxq_map_info {
+struct sxe2_rxq_map_info {
uint64_t rxq_lan_in_pkt_cnt;
uint64_t rxq_lan_in_byte_cnt;
uint64_t rxq_fd_in_pkt_cnt;
uint64_t rxq_mng_in_pkt_cnt;
uint64_t rxq_mng_in_byte_cnt;
uint64_t rxq_mng_out_pkt_cnt;
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_queue_map_info {
+struct sxe2_queue_map_info {
struct sxe2_rxq_map_info rxq_stats_map_info[SXE2_RXQ_STATS_MAP_MAX_NUM];
struct sxe2_txq_map_info txq_stats_map_info[SXE2_TXQ_STATS_MAP_MAX_NUM];
-} __rte_packed_end;
+};
struct __rte_aligned(4) __rte_packed_begin sxe2_drv_rx_map_req {
uint16_t queue_id;
@@ -633,7 +631,7 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_udp_tunnel_resp {
uint8_t rsv;
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
+struct sxe2_drv_sfp_req {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t bus_addr;
@@ -642,14 +640,14 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
uint16_t data_len;
uint16_t rvd;
uint8_t data[];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_resp {
+struct sxe2_drv_sfp_resp {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t data_len;
uint8_t data[];
-} __rte_packed_end;
+};
enum sxe2_fc_type {
SXE2_FC_T_DIS = 0,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (11 preceding siblings ...)
2026-08-18 2:15 ` [PATCH v1 12/13] net/sxe2: clean up structure definitions liujie5
@ 2026-08-18 2:15 ` liujie5
2026-08-26 8:53 ` [PATCH v3 00/51] net/sxe2: add Stars SXE2 net driver with fixes liujie5
` (51 more replies)
2026-08-18 14:22 ` [PATCH v1 00/13] net/sxe2: fix bugs Stephen Hemminger
13 siblings, 52 replies; 207+ messages in thread
From: liujie5 @ 2026-08-18 2:15 UTC (permalink / raw)
To: stephen; +Cc: dev, Jie Liu
From: Jie Liu <liujie5@linkdatatechnology.com>
This commit adds documentation for the acl-stat-type parameter
which controls ACL statistics type used for ACL rule hit counting.
- 1: Only count the number of packets
- 2: Only count the number of bytes
- 3: Count both packets and bytes (default)
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
doc/guides/nics/sxe2.rst | 33 ++++++++++-----------------------
1 file changed, 10 insertions(+), 23 deletions(-)
diff --git a/doc/guides/nics/sxe2.rst b/doc/guides/nics/sxe2.rst
index 8278a5f108..008d944391 100644
--- a/doc/guides/nics/sxe2.rst
+++ b/doc/guides/nics/sxe2.rst
@@ -98,29 +98,16 @@ Runtime Configuration
Default value is 3 (count both packets and bytes).
-- ``drv-sw-stats`` parameter [int]
-
- This parameter controls whether per-packet software statistics (SW stats)
- are collected in the Rx data path.
-
- Hardware packet statistic counters may be inaccurate for certain packet types
- due to hardware design limitations.
- When accuracy of Rx packet classification statistics is critical,
- enabling this parameter allows the driver to accumulate statistics in software
- as packets are received, providing an alternative statistical path
- that bypasses hardware counter inaccuracies.
-
- - 0: Disable software statistics collection (default).
- The basic port statistics (``ipackets``, ``ibytes``) are reported
- from the hardware counters.
- - 1: Enable software statistics collection.
- Per-packet software statistics are accumulated for unicast,
- multicast, broadcast, and dropped packets in the Rx data path.
-
- When enabled, the following extended statistics (xstats) are available:
- ``rx_sw_unicast_packets``, ``rx_sw_multicast_packets``,
- ``rx_sw_broadcast_packets``, ``rx_sw_drop_packets``,
- and ``rx_sw_drop_bytes``.
+- ``acl-stat-type`` parameter [int]
+
+ This parameter controls the ACL statistics type
+ used for ACL rule hit counting (via ``rte_flow_query``).
+
+ - 1: Only count the number of packets.
+ - 2: Only count the number of bytes.
+ - 3: Count both packets and bytes (default).
+
+ Default value is 3 (count both packets and bytes).
- ``no-sched-mode`` parameter [int]
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* Re: [PATCH v1 00/13] net/sxe2: fix bugs
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
` (12 preceding siblings ...)
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
@ 2026-08-18 14:22 ` Stephen Hemminger
13 siblings, 0 replies; 207+ messages in thread
From: Stephen Hemminger @ 2026-08-18 14:22 UTC (permalink / raw)
To: liujie5; +Cc: dev
On Tue, 18 Aug 2026 10:15:05 +0800
liujie5@linkdatatechnology.com wrote:
> From: Jie Liu <liujie5@linkdatatechnology.com>
>
> Jie Liu (13):
> net/sxe2: add Rx queue buffer split fill support
> net/sxe2: update switchdev repr VSI ID display format
> net/sxe2: add ACL engine event statistics support
> net/sxe2: enhance device cap and res management
> net/sxe2: improve representor device initialization
> net/sxe2: refactor flow tunnel port handling
> net/sxe2: validate IPsec key length against maximum limit
> net/sxe2: enhance repr event handling and MP code
> net/sxe2: optimize vectorized Tx/Rx path
> common/sxe2: allow munmap during kernel reset
> net/sxe2: clean up duplicate function declarations
> net/sxe2: clean up structure definitions
> doc/sxe2: add acl-stat-type parameter documentation
Still see lots of errors in AI review. Please fix and resubmit.
In this case, since sxe2 is not in a previous stable release
it is correct to not put stable@dpdk.org in. But it would help
future developers if you added Fixes: tag if you know which
commit introduced the problem.
You should be sending each submission with a different version.
(i.e next should be v3).
# net/sxe2 v1 (13 patches) review notes
## Series-level
1. **Bug fixes buried in feature patches.** There are at least eight of them
(list below). Each should be its own patch. A `Fixes:` tag would help even
though sxe2 is not in 25.11, so nothing here is stable material.
Fixes hiding in feature patches:
- 03: `SXE2_PCI_DEVICE_ID_VF_1` 0x10b -> 0x10b2 (VF never binds today)
- 04: `reg_width` 10 -> 0x10 for `SXE2_PCI_MAP_RES_IRQ_MSIX`
- 04: duplicate `sxe2_switchdev_uninit()` / `sxe2_dev_pci_map_uinit()` in `dev_close`
- 06: `sxe2_flow_check_rss_action_attr()` fell through and returned 0 after
setting an error, so unsupported RSS attrs were silently accepted
- 07: `dev->security_ctx` left dangling after free
- 09: `rx_free_thresh == 0` not defaulted
- 09: `other_vsi_list` not TAILQ_INIT'd before `sxe2_main_vsi_create()`
- 09: NEON Rx DD count used `popcount` instead of "count up to first hole"
2. **Commit messages.** Patches 03, 04, 05, 06, 08, 09, 10 have a bulleted list
of unrelated changes as the message. That is the signal the patch should be
several patches. One logical change per patch, and the message says what the
symptom was and what the fix is, not a changelog of every hunk.
3. **Message/diff mismatches:**
- 08 says "Change error return from EINVAL to ENODATA"; the code returns `-ENOENT`.
- 08 describes removing the `qstats` parameter from `sxe2_mp_req_get_stats`;
no such change is in the diff.
- 11 lists `sxe2_drv_mac_link_status_get` as removed; the diff keeps it.
- 13 says it adds `acl-stat-type` docs; it also deletes the entire
`drv-sw-stats` section (see below).
4. No cover letter in the bundle. Please send a 00/13 describing the series
intent, since it mixes new features (ACL stats, buffer split), refactors and
fixes.
---
## 01/13 net/sxe2: add Rx queue buffer split fill support
The subject covers roughly 20 lines of the diff. The rest is log message
typo fixes, an unrelated `sxe2_link_update()` call, `{}` -> `{0}`, error path
changes in `sxe2_drv_udp_tunnel_get()` and `sxe2_drv_flow_filter_add()`.
Split.
- Removing the `opc_str` argument drops the only debug print of the command
opcode. If that log is unwanted, say so; do not delete it as a side effect
of adding buffer split.
- `sxe2_rxq_buf_split_fill()` re-tests
`rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT`, which the caller already
tested. The `else` branch is dead. Drop the test in the helper and keep the
zeroing in the caller.
- `ret = -1` on failure. Use a negative errno (`-ENOTSUP` for the unsupported
protocol case, `-EINVAL` for unconfigured).
- L3 matching only accepts `RTE_PTYPE_L3_IPV4_EXT_UNKNOWN` /
`RTE_PTYPE_L3_IPV6_EXT_UNKNOWN`. An application that sets plain
`RTE_PTYPE_L3_IPV4` falls through to the L2 test and then errors out.
Is that intended? `sxe2_buffer_split_supported_hdr_ptypes_get()` should
agree with what this function accepts.
- `ctxt->hdr_len = SXE2_RX_HDR_SIZE;` is repeated in every case. Set it once
after the switch chain. Also, why is the header length fixed at 256 bytes
regardless of which layer the split is at?
- Only `rx_seg[0].proto_hdr` is examined. What happens with `nseg > 1`?
- `goto l_end` is being used as a `break` out of a switch. Restructure so the
helper computes `split_type_mask` and returns.
- `(void)sxe2_link_update(dev, 0)` inside `sxe2_drv_mac_link_status_get()`:
this puts an ethdev-layer call inside the command channel layer, gives every
caller (including the interrupt handler) the side effect of publishing link
state, and reaches into `rte_eth_devices[]` directly. It is also only correct
in combination with 08/13, which removes the now duplicate call in
`sxe2_link_update_init()`. Those two hunks belong in one patch, and the
layering should be the other way round: the caller calls `sxe2_link_update()`.
## 02/13 net/sxe2: update switchdev repr VSI ID display
This is a struct field rename across four files, not a display change. Subject
should say so.
The new names lose information. `repr_vf_k_vsi_id` is fed from `kernel_vsi_id`
and `repr_vf_u_vsi_id` from `dpdk_vsi_id`; calling them "primary" and "backup"
hides that, and `sxe2_flow_src_split_proc()` still indexes them by
`SXE2_MAX_DRV_TYPE_KERNEL` / `_DPDK`. Either keep kernel/dpdk in the names or
explain what primary/backup means at the hardware level.
The local buffers in `sxe2_dump_switchdev_info()` are still `k_vsi_buf` /
`u_vsi_buf`.
## 03/13 net/sxe2: add ACL engine event statistics support
Split at minimum into: (a) the `sxe2_fnav_cid_mgr` -> `sxe2_flow_cid_mgr`
rename, (b) ACL stat support, (c) the VF device ID fix, (d) the sxe2_queue.c
change.
- **`SXE2_PCI_DEVICE_ID_VF_1` 0x10b -> 0x10b2** has nothing to do with ACL
stats and is a user visible bug. Own patch, ideally with a `Fixes:` tag.
- **`sxe2_flow_free_mgr()` can free a list member without removing it.**
When `engine_type` is neither ACL nor FNAV, both branches are skipped, so
`TAILQ_REMOVE()` never runs, but the code below still does `rte_free(mgr)`.
That leaves a freed pointer on whichever list the mgr came from. Add an
`else` that errors out, or derive `cid_mgr_list` once and remove
unconditionally.
- Same shape in `sxe2_flow_get_filter_cid()` and `sxe2_flow_query_mgr()`: the
unknown engine case in `get_filter_cid` does `goto l_end` with `ret == 0`, so
the caller sees success and no counter was allocated. `query_mgr` at least
returns `-ENOTSUP`. Be consistent.
- ```
SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY = SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 1),
SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC,
SXE2_DRV_CMD_FLOW_ACL_STAT_FREE,
```
Every other entry in this enum is written with an explicit `SXE2_MK_DRV_CMD()`.
Relying on implicit `+1` over an encoded value is fragile. Write
`SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 2)` and `(..., 3)`.
- `sxe2_drv_flow_acl_get_stat_id()` and `_free_stat()` send
`sxe2_drv_flow_fnav_*` request structures. If the ACL and FNAV messages are
the same on the wire, add a comment; otherwise define ACL types.
- `req.is_clear = 1` is hardcoded, so every `rte_flow_query()` clears the
hardware counter. `struct rte_flow_query_count` has a `reset` field. What
happens with two readers, or with `reset == 0`? `mgr->hits`/`mgr->bytes`
accumulate but nothing ever resets them.
- `struct sxe2_drv_acl_query_stat_resp.stat_index` is never read.
- `mgr->stat_index` is `uint16_t` but the firmware returns and consumes
`uint32_t`. Silent truncation.
- `int32_t ret = -1;` in all three new functions is immediately overwritten.
- The ACL counter default uses `SXE2_FNAV_STAT_ENA_ALL` and
`sxe2_parse_stat_type()` still range-checks against the FNAV enum. If the
values are shared, rename the enum; if not, this is a bug.
- `adapter->flow_ctxt.fnav_inited` now gates ACL too, and the sxe2_queue.c hunk
(`rxq->fnav_enable = true`) is unrelated to ACL statistics. It also introduces
an ordering dependency on `sxe2_flow_init()` running before
`sxe2_queues_init()`. Please justify or drop.
- `rte_zmalloc("sxe2_fnav_cid_mgr", ...)`, the "sxe2vf_fnav_cid_mgr" error
string and "fnav get stats id failed" in `sxe2_flow_create()` are now on the
shared path.
## 04/13 net/sxe2: enhance device cap and res management
Seven unrelated changes in one patch. This one has to be split before it can
be reviewed properly. Specific problems:
- **`init_rss_err` label moved past `sxe2_security_uinit()`.** After the
reorder, a failure in RSS init unwinds to `sxe2_intr_uninit()` and never
calls `sxe2_security_uinit()`, so the security context leaks. The label has
to stay above the `security_uinit` call.
- **`*no_of_elements = RTE_DIM(ptypes)`** counts the trailing
`RTE_PTYPE_UNKNOWN` terminator, so callers see one bogus element. Either
report `RTE_DIM(ptypes) - 1` or drop the terminator from the array.
- **`sxe2_switchdev_repr_match()` PF loop is inverted.** It returns false if
*any* requested port differs from `pf_num`. With `nb_ports > 1` it can never
succeed, which contradicts the new multi-port loop in `sxe2_eth_pmd_probe()`
in this same patch. It should match if the adapter's `pf_num` is among the
requested ports.
- `port_idx = UINT16_MAX` is dead; the loop overwrites it immediately.
- **`SXE2_PCI_REG_WRITE_WC` -> `SXE2_PCI_REG_WRITE`** in
`sxe2_pci_map_write_reg()` changes MMIO write semantics with no explanation.
Why is write combining no longer wanted, and does anything depend on the
ordering difference?
- `dev_info->nb_rx_queues` / `nb_tx_queues`: `rte_eth_dev_info_get()` already
fills these from `dev->data` after calling the PMD op. Drop.
- `RTE_ETH_RX_OFFLOAD_RSS_HASH` is added unconditionally while the rest of the
RSS capability is gated on `SXE2_DEV_CAPS_OFFLOAD_RSS` a few lines below.
- QINQ_STRIP / QINQ_INSERT / VLAN_FILTER are now advertised conditionally on
`sxe2_dev_port_vlan_check()`. `dev_infos_get()` is supposed to report static
hardware capability. Making it vary with runtime port VLAN state means an
application that configured an offload can later see it as unsupported.
What is the actual constraint here?
- `sxe2_dev_infos_get()` returning `-EINVAL` when `main_vsi == NULL`: how can
that happen? This looks like it is papering over an init ordering bug.
- `sxe2_dev_pci_map_uinit()` silently drops the `map_ctxt != NULL` test. If
that test was never needed, remove it in a separate cleanup and say so.
- `sxe2_eth_pmd_probe()` calls `sxe2_eth_pmd_remove(cdev)` on failure. The bus
layer also calls remove when probe fails. Confirm that is not a double
teardown.
- `SXE2_PCI_REG_WRITE` / `SXE2_PCI_REG_READ` moved to sxe2_ethdev.h while
`SXE2_PCI_REG_WRITE_WC*` stays in sxe2_queue.h. Keep the family together.
- `reg_width` 10 -> 0x10: separate fix, `Fixes:`.
- The duplicate `sxe2_switchdev_uninit()` and `sxe2_dev_pci_map_uinit()` calls
removed from `sxe2_dev_close()` are a double free fix. Separate patch,
a `Fixes:` tag, and describe the crash.
- `sxe2_dev_close()` and the `sxe2_dev_init()` unwind path are still not
mirror images of each other (switchdev/eth ordering differs). Worth making
them match.
## 05/13 net/sxe2: improve representor device initialization
- `sxe2_stats_init()` is added with no matching uninit anywhere in the
representor teardown path. If it allocates, that is a leak on port close.
- The struct member realignment is unrelated churn. Drop it or make it its own
patch.
- `l_init_irq_ctxt_err` is entered when `sxe2_stats_init()` fails, but
`l_init_sw_err` / `l_init_eth_err` are named after the step that failed.
Rename to `l_init_stats_err` for consistency.
- `snprintf(name, sizeof(name), "%s_representor_%s%u", ..., "vf", ...)`:
put `vf` in the format string. Also, `cdev->dev->name` is variable length and
truncation is not detected; check the return against `sizeof(name)`.
## 06/13 net/sxe2: refactor flow tunnel port handling
- **The new PF_BOND block is dead code.** The two pre-existing lines
immediately after it unconditionally overwrite index 0:
```
flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] = adapter->vsi_ctxt.dpdk_vsi_id;
flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] = adapter->vsi_ctxt.kernel_vsi_id;
```
so bond member 0 is clobbered and the new `else` branch is redundant with
them. Delete those two lines.
- **`bond_member_cnt` is never assigned anywhere in the series.** It is zero,
so `flow_bond_num = 0` and the loop body never executes. Either the
assignment is missing from the series or the whole PF_BOND block should be
dropped until it is complete.
- No bound check on `flow_bond_num` against the `flow_src_vsi` array
dimensions. That value comes from the device.
- **`sxe2_flow_check_rss_action_attr()`**: adding the `goto l_end` after each
`rte_flow_error_set()` is a real bug fix. Today the function sets an error
and then returns 0, so an unsupported `level`, `key_len` or `queue_num` is
accepted. Separate patch, ideally with a `Fixes:` tag. Also fix the doubled space
and grammar in "RSS level is could not be greater than 2".
- The `sxe2_flow_meta_proc()` restructure (`else if` -> nested `if/else`) is
identical in behaviour and adds a level of indentation. Drop it.
- The function moves from sxe2_flow_parse_pattern.c to sxe2_flow.c are a pure
code move. Put them in their own patch so the diff can be verified as a move.
## 07/13 net/sxe2: validate IPsec key length against maximum
- The sxe2_security.c hunk (`dev->security_ctx = NULL`) is a separate use
after free fix and is not mentioned in the commit message. Own patch,
`Fixes:`. While there, the `sctx = NULL;` on the local is dead.
- `sxe2_security_valid_key()` already takes `max_key`. What is the relationship
between `max_key` and `SXE2_IPSEC_MAX_KEY_LEN`, and can `max_key` exceed it?
If yes, the bug is in the caller and that is where it should be fixed.
- The message claims this "prevents potential buffer overflows". If the
overflow is reachable, this needs a `Fixes:` tag and a note to
security@dpdk.org before posting. If it is defensive hardening, do not
describe it as an overflow fix.
- `>` vs `>=`: which is correct depends on whether the destination is
`key[SXE2_IPSEC_MAX_KEY_LEN]`. Please confirm.
## 08/13 net/sxe2: enhance repr event handling and MP code
Double space in the subject line.
- **Caching `sxe2_mp_mz`.** The lookup is now done once and the result kept
forever. If the memzone is freed and recreated across a device close/open,
the cached pointer is stale. What guarantees its lifetime?
- `uint8_t vf_id` against `nb_repr_vf`: if `nb_repr_vf` is wider and can exceed
255 this loops forever. Use the same type as the counter.
- The new representor LSC loop calls `sxe2_drv_mac_link_status_get()` per
representor from interrupt context, and with 01/13 applied each of those also
runs `sxe2_link_update()`. That is N command channel round trips inside the
interrupt handler on every link change. Consider reading the PF link state
once and pushing it to the representors.
- `sxe2_rxq_intr_unregister()`: moving `rte_free(irq_ctxt->rxq_event_fd)` inside
the enclosing `if` leaks the allocation whenever that condition is false,
unless the condition is exactly `rxq_event_fd != NULL`. Not mentioned in the
commit message at all.
- `sxe2_mp_do_primary_work()` takes a copy of the message parameter to "avoid
side effects", but the original was already `const`. Just return `ret` and
drop `param_copy`.
- 08 removing `(void)sxe2_link_update(dev, 0)` from `sxe2_link_update_init()`
is only correct with 01/13 applied. Squash the two hunks.
## 09/13 net/sxe2: optimize vectorized Tx/Rx path
This patch is doing at least six things, several of which are correctness
changes to the vector data path that are not mentioned in the commit message.
It needs to be broken up, and the correctness changes need to say what was
broken. Blocking issues:
- **`sxe2_tx_queue_mbufs_release_vec()` now calls `rte_pktmbuf_free_seg()`
without a NULL check.** `rte_pktmbuf_free_seg()` dereferences its argument;
it does not tolerate NULL. The only "validation" added is a check on the
ring pointer, not on individual entries, and `sxe2_tx_queue_reset_vec()`
memsets the whole ring to zero. Any stop/start cycle, or any hole in
[next_dd - (rs_thresh-1), next_use), is a NULL dereference. Restore the
checks.
- **`SXE2_RX_DESC_STATUS_DD_MASK` -> `SXE2_RX_DESC_STATUS_DD_SHIFT`** in
`sxe2_monitor_callback()`. A shift count is not a mask. This looks like a
regression, it is unrelated to the vector path, and it is unexplained.
- **Acquire fences removed from the NEON Rx descriptor loads.** The three
`rte_atomic_thread_fence(rte_memory_order_acquire)` calls between the
`descs[3]`..`descs[0]` loads are gone. Those barriers are what stops arm64
from observing a partially DMA written descriptor. If they really are
redundant given the single remaining fence before the lane reloads, spell
out the argument in the commit message. Otherwise this is descriptor tearing
under load.
- **`repr_vf_vsi_id` fallback dropped.** In sxe2_switchdev.c the
`kernel_vsi_id != SXE2_INVALID_VSI_ID ? kernel : dpdk` selection is replaced
by an unconditional assignment from the primary (kernel) VSI, so
`repr_vf_vsi_id` can now be `SXE2_INVALID_VSI_ID`. Functional regression, in
a patch about vector Tx/Rx, with no mention in the message.
- **NEON Rx ptype lane mapping changed.** Old:
pkt0<-lane5, pkt1<-lane1, pkt2<-lane7, pkt3<-lane3. New:
pkt0<-lane1, pkt1<-lane3, pkt2<-lane5, pkt3<-lane7. One of the two is wrong.
Same for the ptype mask (`0x3FF` -> `SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16`),
the `umbcast`/`eop` shuffle masks, `rxe_mask` `0x2080` -> `0x20802080`, and
`eop_mask` gaining the +16 bit. These are correctness fixes to Rx flag and
ptype parsing. They belong in their own patch with `Fixes:` and a
description of the wrong behaviour they produce.
- **The DD count rewrite is a real bug fix.** The old `popcount` counted every
set DD bit in the group, so a pattern like DD,not-DD,DD,DD reported 4 and the
driver consumed descriptors the hardware had not written. The new
`rte_ctz64(stat) / 16` stops at the first hole, which is correct. Own patch,
ideally with a `Fixes:` tag.
- **`vst1q_lane_u32(...)` -> `*(uint32_t *)umbcast_flags = vgetq_lane_u32(...)`.**
The intrinsic does not require 4 byte alignment; the direct store does. If
`umbcast_flags` can be unaligned this is undefined behaviour.
- **`sxe2_tx_desc_fill_4_neon_simple()` disagrees with the tail loop.** The
4-wide body always encodes `MACLEN` from `pkt->l2_len`, but the scalar tail
calls `sxe2_tx_desc_fill_one_neon(..., false)`. Within one burst, packets get
different descriptor contents depending on their position in the ring. Also,
in simple mode the application is not required to set `l2_len`.
- `vst1q_u64_x4()` is not available on all arm64 toolchains DPDK supports.
Check the minimum GCC/clang requirement.
- **`sxe2_tx_queue_reset_vec()`** memsets `sizeof(struct sxe2_tx_buffer) *
ring_depth` while every other line in the vec path now uses
`struct sxe2_tx_buffer_vec`. Which type owns the allocation? State it, and
use that type consistently, otherwise the next person who shrinks the vec
allocation gets a heap overflow here.
- `sxe2_tx_queues_vec_prepare()` used to override only `mbufs_release`; it now
replaces the whole ops table and calls `queue_reset()`. Resetting the
descriptor ring here is a behaviour change that is not described.
- `sxe2_tx_vec_ops_get()` returns a `struct` by value. Return
`const struct sxe2_txq_ops *` like `sxe2_default_txq_ops`.
- Deleting `sxe2_tx_bufs_free_vec_avx512()` removes the mempool cache bulk
free fast path. That is a performance regression in a patch titled
"optimize". If it was removed because it was wrong (the
`rte_mempool_ops_enqueue_bulk(mp, (void *)buffer, rs_thresh)` call assumes
`struct sxe2_tx_buffer_vec` is exactly one pointer, and the `goto normal`
jumps into scope), say that.
- `dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy` instead of `NULL`:
is that symbol available to out of tree and in tree PMDs, and what does it
buy over the NULL fast path in `rte_eth_tx_prepare()`?
- Removing `#ifndef SXE2_TEST` from sxe2_txrx_vec_avx512.c is unexplained.
- `PMD_LOG_DEBUG(TX, "Tx mode flags:0x%016x ...")`: `%016x` on a 32 bit value
pads to 16 digits. Use `%#010x`.
- Unrelated but welcome fixes to pull out of here: `rx_free_thresh` defaulting,
`TAILQ_INIT(&other_vsi_list)` before `sxe2_main_vsi_create()`,
`main_vsi = NULL` after destroy, `sxe2_tx_buffer_ring_free()` NULLing the
pointer, and the duplicate `sxe2_rx_pkts_scattered` declaration (that last
one belongs in 11/13).
- `if (ret && ret != -EPERM)` in `sxe2_vsi_uninit()`: why is `-EPERM` expected?
Add a comment. Note the code then proceeds to drop the VSI list even though
the firmware side destroy failed.
## 10/13 common/sxe2: allow munmap during kernel reset
Two unrelated changes; the subject only covers one.
- Removing the `kernel_reset` guard from `sxe2_drv_dev_munmap()`: what was the
guard protecting against, and why is it safe now? "Enable cleanup operations"
is not an explanation of why unmapping after a kernel reset is safe.
- `cdev` becomes unused. Check whether the `l_end:` label still has a `goto`
reaching it; if not, that is `-Wunused-label`.
- `sxe2_classes_driver_remove()` returning 0 when `cdrv == NULL` hides a
probe/remove asymmetry. A NULL `cdrv->remove` is legitimately optional; a
NULL `cdrv` on a device that was probed is a bug worth logging.
## 11/13 net/sxe2: clean up duplicate function declarations
Fine, with two notes: the commit message lists
`sxe2_drv_mac_link_status_get` but the diff keeps it, and the duplicate
`sxe2_rx_pkts_scattered` declaration removed in 09/13 belongs in this patch.
## 12/13 net/sxe2: clean up structure definitions
These are firmware message structures. Removing `__rte_packed_begin` /
`__rte_packed_end` and `__rte_aligned(4)` changes their size and alignment, and
therefore the wire format:
- `sxe2_tm_res`: dropping `rsv[2]` takes `sizeof()` from 4 to 2.
- `sxe2_rxq_map_info`: alignment goes from 4 to 8, which changes the offset of
the embedded arrays in `sxe2_queue_map_info` and possibly the size of any
parent message.
- `sxe2_drv_sfp_req` / `_resp` have flexible array members and are presumably
sized as `sizeof(req) + data_len` at the call site. Tail padding changes the
length sent to firmware.
I am not going to take this without either a firmware ABI document confirming
the new layouts, or `static_assert(sizeof(...) == N)` on every message
structure so a future change cannot silently break it. Note that someone
deliberately converted these to the `__rte_packed_begin/_end` form recently;
please explain what is wrong with them now.
## 13/13 doc/sxe2: add acl-stat-type parameter documentation
**This deletes the entire `drv-sw-stats` section** (23 lines removed, 10
added) while the commit message only describes adding `acl-stat-type`. Nothing
in this series removes the `drv-sw-stats` devarg from the driver, so this looks
like a rebase accident that drops documentation for a supported parameter.
Please restore it.
Minor: the new block says both "- 3: Count both packets and bytes (default)."
and "Default value is 3 (count both packets and bytes)." Pick one.
Also, the documentation should land in the same patch as the devarg it
documents (03/13), not eleven patches later.
^ permalink raw reply [flat|nested] 207+ messages in thread
* [PATCH v3 00/51] net/sxe2: add Stars SXE2 net driver with fixes
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
@ 2026-08-26 8:53 ` liujie5
2026-08-26 17:07 ` Stephen Hemminger
2026-08-26 8:53 ` [PATCH v3 01/51] common/sxe2: fix null pointer in class driver remove liujie5
` (50 subsequent siblings)
51 siblings, 1 reply; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:53 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
This series adds the Stars SXE2 (Wuxi Stars Micro System) Ethernet
driver, including the common driver (drivers/common/sxe2), the net
driver (drivers/net/sxe2), and its documentation.
The driver supports:
- Legacy and switchdev modes with VF representors
- Scalar and vectorized (SSE/AVX2/AVX512/NEON) Rx/Tx paths
- FNAV and ACL flow engines with per-flow statistics
- RSS, QinQ, IPsec, Traffic Management and multi-process support
In addition to the driver functionality, the series fixes a number of
correctness issues found during review, including a security context
leak in the device init error path, a NULL dereference in the
vectorized Tx mbuf release path, an out-of-bounds representor ID
access, and a representor LSC loop counter type mismatch. The command
channel log messages and ioctl channel handling are also aligned with
the reference implementation.
This is v3 of the series, incorporating review feedback. All patches
build independently and no ABI changes are introduced.
Jie Liu (51):
common/sxe2: fix null pointer in class driver remove
common/sxe2: allow munmap during kernel reset
net/sxe2: fix VF PCI device ID
net/sxe2: fix MSIX register width in PF map table
net/sxe2: restore pf and port index caps assignment
net/sxe2: fix VSI lifecycle management
net/sxe2: initialize stats in representor device init
net/sxe2: use base device name for representor naming
net/sxe2: propagate LSC event to VF representors
net/sxe2: validate IPsec key length against maximum limit
net/sxe2: rename representor VSI ID fields
net/sxe2: clean up duplicate function declarations
net/sxe2: fix null VSI dereference in device info
net/sxe2: fill MAC and queue counts in device info
net/sxe2: fix QinQ and RSS offload capability report
net/sxe2: use regular write for mapped registers
net/sxe2: move PCI register read macro to common header
net/sxe2: validate PCI map resource type
net/sxe2: guard PCI BAR unmap when not initialized
net/sxe2: fix null dereference in dev uninit
net/sxe2: fix duplicated cleanup in dev close
net/sxe2: align dev init and cleanup order
net/sxe2: simplify switchdev representor matching
net/sxe2: probe all requested PF ports
net/sxe2: rename fnav cid manager symbols to flow
net/sxe2: move tunnel port helpers into flow module
net/sxe2: add ACL engine event statistics support
net/sxe2: guard Rx queue event FD free in unregister
net/sxe2: refactor primary process MP message handling
net/sxe2: refactor Tx queue reset operations
net/sxe2: unify vectorized Tx buffer handling
net/sxe2: refine vectorized Tx/Rx mode setup
net/sxe2: fix RSS action attribute validation
net/sxe2: restore PF-only guard in udp tunnel port add
net/sxe2: align flow meta proc priority handling with V3
net/sxe2: restore link update call in status query
net/sxe2: validate representor ID against VF count
net/sxe2: use primary VSI ID for representor VSI
net/sxe2: wrap command params fill debug log in macro
net/sxe2: restore Rx queue buffer split fill support
net/sxe2: skip tunnel config fill on get failure
net/sxe2: skip flow id assignment on filter add failure
net/sxe2: fix command channel log messages
net/sxe2: align command structs with historical kernel layout
common/sxe2: fix ioctl channel log and close handling
doc/sxe2: remove drv-sw-stats parameter documentation
net/sxe2: harden ACL flow count resource handling
net/sxe2: fix device init and representor matching issues
net/sxe2: use correct loop counter type for representor LSC
net/sxe2: restore NULL check in vectorized Tx mbuf release
net/sxe2: simplify Rx queue buffer split fill helper
doc/guides/nics/sxe2.rst | 58 +----
drivers/common/sxe2/sxe2_common.c | 6 +-
drivers/common/sxe2/sxe2_ioctl_chnl.c | 18 +-
drivers/net/sxe2/sxe2_cmd_chnl.c | 200 +++++++++++++++--
drivers/net/sxe2/sxe2_cmd_chnl.h | 15 +-
drivers/net/sxe2/sxe2_drv_cmd.h | 45 ++--
drivers/net/sxe2/sxe2_dump.c | 10 +-
drivers/net/sxe2/sxe2_ethdev.c | 202 ++++++++++-------
drivers/net/sxe2/sxe2_ethdev.h | 13 +-
drivers/net/sxe2/sxe2_ethdev_repr.c | 13 +-
drivers/net/sxe2/sxe2_flow.c | 250 +++++++++++++++++----
drivers/net/sxe2/sxe2_flow.h | 6 +-
drivers/net/sxe2/sxe2_flow_define.h | 15 +-
drivers/net/sxe2/sxe2_flow_parse_action.c | 37 ++-
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ----------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 6 -
drivers/net/sxe2/sxe2_ipsec.c | 5 +
drivers/net/sxe2/sxe2_irq.c | 27 ++-
drivers/net/sxe2/sxe2_mac.c | 9 +-
drivers/net/sxe2/sxe2_mp.c | 59 ++---
drivers/net/sxe2/sxe2_queue.c | 2 +
drivers/net/sxe2/sxe2_queue.h | 7 +-
drivers/net/sxe2/sxe2_rx.c | 3 +-
drivers/net/sxe2/sxe2_security.c | 1 +
drivers/net/sxe2/sxe2_switchdev.c | 16 +-
drivers/net/sxe2/sxe2_tx.c | 42 +++-
drivers/net/sxe2/sxe2_tx.h | 4 +
drivers/net/sxe2/sxe2_txrx.c | 19 +-
drivers/net/sxe2/sxe2_txrx_poll.h | 2 -
drivers/net/sxe2/sxe2_txrx_vec.c | 73 +++---
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 133 +----------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 9 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 219 +++++++++++-------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
drivers/net/sxe2/sxe2_vsi.c | 8 +-
37 files changed, 964 insertions(+), 702 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 207+ messages in thread
* [PATCH v3 01/51] common/sxe2: fix null pointer in class driver remove
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
2026-08-26 8:53 ` [PATCH v3 00/51] net/sxe2: add Stars SXE2 net driver with fixes liujie5
@ 2026-08-26 8:53 ` liujie5
2026-08-26 8:53 ` [PATCH v3 02/51] common/sxe2: allow munmap during kernel reset liujie5
` (49 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:53 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_classes_driver_remove() calls cdrv->remove(cdev) without
checking whether cdrv or cdrv->remove is NULL. If the class driver
was never probed, cdev->cdrv remains NULL, and the unconditional
call dereferences a NULL pointer, crashing during device removal.
Add NULL checks for cdrv and cdrv->remove, returning 0 when either
is NULL.
Fixes: 83866f8d76 ("common/sxe2: add base driver skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_common.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/common/sxe2/sxe2_common.c b/drivers/common/sxe2/sxe2_common.c
index 5c5db85f29..6e387a8a73 100644
--- a/drivers/common/sxe2/sxe2_common.c
+++ b/drivers/common/sxe2/sxe2_common.c
@@ -465,8 +465,12 @@ static int32_t sxe2_classes_driver_probe(struct sxe2_common_device *cdev,
static int32_t sxe2_classes_driver_remove(struct sxe2_common_device *cdev)
{
struct sxe2_class_driver *cdrv = cdev->cdrv;
+ int32_t ret = 0;
+
+ if (cdrv != NULL && cdrv->remove != NULL)
+ ret = cdrv->remove(cdev);
- return cdrv->remove(cdev);
+ return ret;
}
static int32_t sxe2_kvargs_validate(struct sxe2_dev_kvargs_info *kv_info)
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 02/51] common/sxe2: allow munmap during kernel reset
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
2026-08-26 8:53 ` [PATCH v3 00/51] net/sxe2: add Stars SXE2 net driver with fixes liujie5
2026-08-26 8:53 ` [PATCH v3 01/51] common/sxe2: fix null pointer in class driver remove liujie5
@ 2026-08-26 8:53 ` liujie5
2026-08-26 8:53 ` [PATCH v3 03/51] net/sxe2: fix VF PCI device ID liujie5
` (48 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:53 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_dev_munmap() refuses to unmap the BAR region when
cdev->config.kernel_reset is set, returning -EPERM. After a kernel
reset the application still needs to release the previously mapped
regions during cleanup; blocking munmap leaves stale mappings and
prevents a clean teardown.
Remove the kernel_reset check from sxe2_drv_dev_munmap() so the
mapping is always released. The cdev parameter is no longer used,
so mark it __rte_unused.
Fixes: 66a10eb60e ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_ioctl_chnl.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index a233a78136..3e2fbf572f 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -367,16 +367,10 @@ void
RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_munmap)
int32_t
-sxe2_drv_dev_munmap(struct sxe2_common_device *cdev, void *virt, uint64_t len)
+sxe2_drv_dev_munmap(struct sxe2_common_device *cdev __rte_unused, void *virt, uint64_t len)
{
int32_t ret = 0;
- if (cdev->config.kernel_reset) {
- ret = -EPERM;
- PMD_LOG_WARN(COM, "kernel reset, need restart app.");
- goto l_end;
- }
-
PMD_LOG_DEBUG(COM, "Munmap virt=%p, len=0x%"PRIx64"",
virt, len);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 03/51] net/sxe2: fix VF PCI device ID
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (2 preceding siblings ...)
2026-08-26 8:53 ` [PATCH v3 02/51] common/sxe2: allow munmap during kernel reset liujie5
@ 2026-08-26 8:53 ` liujie5
2026-08-26 8:54 ` [PATCH v3 04/51] net/sxe2: fix MSIX register width in PF map table liujie5
` (47 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:53 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The VF PCI device ID is defined as 0x10b2 per the hardware specification,
but the code incorrectly uses 0x10b.
As a result, the VF driver never binds to the device, making VF
functionality completely unusable.
Fix this by changing SXE2_PCI_DEVICE_ID_VF_1 from 0x10b to 0x10b2.
Fixes: d8e4e075ac ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 8bbfdc3a15..ec376b76dc 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -44,7 +44,7 @@
#define SXE2_PCI_VENDOR_ID_1 0x1ff2
#define SXE2_PCI_DEVICE_ID_PF_1 0x10b1
-#define SXE2_PCI_DEVICE_ID_VF_1 0x10b
+#define SXE2_PCI_DEVICE_ID_VF_1 0x10b2
#define SXE2_PCI_VENDOR_ID_2 0x1d94
#define SXE2_PCI_DEVICE_ID_PF_2 0x1260
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 04/51] net/sxe2: fix MSIX register width in PF map table
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (3 preceding siblings ...)
2026-08-26 8:53 ` [PATCH v3 03/51] net/sxe2: fix VF PCI device ID liujie5
@ 2026-08-26 8:54 ` liujie5
2026-08-26 8:54 ` [PATCH v3 05/51] net/sxe2: restore pf and port index caps assignment liujie5
` (46 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:54 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The MSIX entry in sxe2_net_map_addr_info_pf sets a register width
of 10 (decimal), but each PCIe MSIX table entry is 16 bytes (0x10).
The VF map table already uses 0x10.
Since reg_width is used as the stride between MSIX entries in
sxe2_dev_pci_seg_map(), the wrong value makes the mapped region too
short and places the entries at incorrect offsets.
Change .reg_width from 10 to 0x10 for the SXE2_PCI_MAP_RES_IRQ_MSIX
entry to match the VF table.
Fixes: 66a10eb60e ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index ec376b76dc..5d8cfca6cf 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -94,7 +94,7 @@ static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_pf[SXE2_PCI_MAP_RES_
.reg_width = 4},
[SXE2_PCI_MAP_RES_IRQ_MSIX] = {.addr_base = SXE2_BAR4_MSIX_CTL(0),
.bar_idx = 4,
- .reg_width = 10},
+ .reg_width = 0x10},
};
static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_vf[SXE2_PCI_MAP_RES_MAX_COUNT] = {
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 05/51] net/sxe2: restore pf and port index caps assignment
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (4 preceding siblings ...)
2026-08-26 8:54 ` [PATCH v3 04/51] net/sxe2: fix MSIX register width in PF map table liujie5
@ 2026-08-26 8:54 ` liujie5
2026-08-26 8:54 ` [PATCH v3 06/51] net/sxe2: fix VSI lifecycle management liujie5
` (45 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:54 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_func_caps_get() never assigns adapter->pf_idx from the device
capabilities, leaving it at its zero-initialized value. Switchdev
requests and representor setup that use pf_idx then report the wrong
PF index on multi-PF configurations.
Restore the pf_idx and port_idx assignments in sxe2_func_caps_get()
and drop the now-redundant port_idx assignment from
sxe2_drv_dev_caps_set().
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 5d8cfca6cf..2e14c372f8 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1284,8 +1284,6 @@ void sxe2_eth_uinit(struct rte_eth_dev *dev __rte_unused)
static void sxe2_drv_dev_caps_set(struct sxe2_adapter *adapter,
struct sxe2_drv_dev_caps_resp *dev_caps)
{
- adapter->port_idx = dev_caps->port_idx;
-
adapter->cap_flags = 0;
if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_L2)
@@ -1344,6 +1342,8 @@ static int32_t sxe2_func_caps_get(struct sxe2_adapter *adapter)
goto l_end;
adapter->dev_type = dev_caps.dev_type;
+ adapter->port_idx = dev_caps.port_idx;
+ adapter->pf_idx = dev_caps.pf_idx;
sxe2_drv_dev_caps_set(adapter, &dev_caps);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 06/51] net/sxe2: fix VSI lifecycle management
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (5 preceding siblings ...)
2026-08-26 8:54 ` [PATCH v3 05/51] net/sxe2: restore pf and port index caps assignment liujie5
@ 2026-08-26 8:54 ` liujie5
2026-08-26 8:54 ` [PATCH v3 07/51] net/sxe2: initialize stats in representor device init liujie5
` (44 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:54 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Fix several VSI create/destroy issues introduced by VF representor
support:
- Initialize other_vsi_list with TAILQ_INIT in sxe2_vsi_init before
any VSI is inserted into it.
- Treat -EPERM as a non-fatal error when destroying VSIs, since the
kernel may have already removed the VSI.
- Set main_vsi to NULL after destroy/free to avoid a dangling pointer
if the VSI is destroyed again.
Fixes: 635084db5d ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_vsi.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_vsi.c b/drivers/net/sxe2/sxe2_vsi.c
index d29480b931..ba4cc7414e 100644
--- a/drivers/net/sxe2/sxe2_vsi.c
+++ b/drivers/net/sxe2/sxe2_vsi.c
@@ -230,7 +230,7 @@ int32_t sxe2_vsi_init(struct rte_eth_dev *dev)
uint16_t srcvsi_cnt;
PMD_INIT_FUNC_TRACE();
-
+ TAILQ_INIT(&adapter->vsi_ctxt.other_vsi_list);
ret = sxe2_main_vsi_create(adapter);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to create main VSI, ret=%d", ret);
@@ -283,13 +283,14 @@ void sxe2_vsi_uninit(struct rte_eth_dev *dev)
l_free:
ret = sxe2_vsi_destroy(adapter, adapter->vsi_ctxt.main_vsi);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
goto l_end;
}
+ adapter->vsi_ctxt.main_vsi = NULL;
RTE_TAILQ_FOREACH_SAFE(var, &adapter->vsi_ctxt.other_vsi_list, next, tvar) {
ret = sxe2_vsi_destroy(adapter, var);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
break;
}
@@ -357,4 +358,5 @@ void sxe2_vsi_repr_main_vsi_destroy(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
sxe2_vsi_node_free(adapter->vsi_ctxt.main_vsi);
+ adapter->vsi_ctxt.main_vsi = NULL;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 07/51] net/sxe2: initialize stats in representor device init
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (6 preceding siblings ...)
2026-08-26 8:54 ` [PATCH v3 06/51] net/sxe2: fix VSI lifecycle management liujie5
@ 2026-08-26 8:54 ` liujie5
2026-08-26 8:54 ` [PATCH v3 08/51] net/sxe2: use base device name for representor naming liujie5
` (43 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:54 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add sxe2_stats_init() call in sxe2_repr_dev_init to set up the
statistics infrastructure for representor devices, and add the
l_init_irq_ctxt_err error path to uninitialize the software irq
context if stats initialization fails.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev_repr.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index f32318b731..c698baafe0 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -483,8 +483,16 @@ int32_t sxe2_repr_dev_init(struct rte_eth_dev *dev,
goto l_init_sw_err;
}
+ ret = sxe2_stats_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize stats, ret=[%d]", ret);
+ goto l_init_irq_ctxt_err;
+ }
+
goto l_end;
+l_init_irq_ctxt_err:
+ sxe2_sw_irq_ctxt_uninit(dev);
l_init_sw_err:
sxe2_eth_uinit(dev);
l_init_eth_err:
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 08/51] net/sxe2: use base device name for representor naming
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (7 preceding siblings ...)
2026-08-26 8:54 ` [PATCH v3 07/51] net/sxe2: initialize stats in representor device init liujie5
@ 2026-08-26 8:54 ` liujie5
2026-08-26 8:54 ` [PATCH v3 09/51] net/sxe2: propagate LSC event to VF representors liujie5
` (42 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:54 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Update the representor device naming to use the base device name
prefix, and set the numa_node from the parent device data so that
representor devices are allocated on the same NUMA node.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev_repr.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index c698baafe0..b7096f5927 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -552,8 +552,8 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
}
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- snprintf(name, sizeof(name), "sxe2_representor_c%dpf%d%s%u",
- adapter->pf_idx, adapter->pf_idx,
+ snprintf(name, sizeof(name), "%s_representor_%s%u",
+ adapter->cdev->dev->name,
"vf",
req_eth_da->representor_ports[repr_idx]);
@@ -562,6 +562,7 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
ret = -ENOMEM;
goto l_release_port;
}
+ eth_dev->data->numa_node = adapter->dev_info.dev_data->numa_node;
eth_dev->data->dev_private = rte_zmalloc_socket(name,
sizeof(struct sxe2_adapter),
RTE_CACHE_LINE_SIZE,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 09/51] net/sxe2: propagate LSC event to VF representors
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (8 preceding siblings ...)
2026-08-26 8:54 ` [PATCH v3 08/51] net/sxe2: use base device name for representor naming liujie5
@ 2026-08-26 8:54 ` liujie5
2026-08-26 8:54 ` [PATCH v3 10/51] net/sxe2: validate IPsec key length against maximum limit liujie5
` (41 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:54 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
When the PF link state changes in switchdev mode, refresh the link
status of every VF representor and trigger the RTE_ETH_EVENT_INTR_LSC
callback on each, so applications receive link events on representor
ports. Also log OICR in hexadecimal for better readability.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index 3306504761..53d49a4246 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -77,14 +77,32 @@ static int32_t sxe2_fc_state_callback(struct rte_eth_dev *dev)
static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t oicr)
{
struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
+ struct rte_eth_dev *repr_eth_dev;
+ struct sxe2_adapter *repr_adapter;
+ uint8_t vf_id;
if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
- PMD_DEV_LOG_INFO(adapter, DRV, "OICR=%" PRIu64, oicr);
+ PMD_DEV_LOG_INFO(adapter, DRV, "OICR=0x%" PRIx64, oicr);
(void)sxe2_drv_mac_link_status_get(adapter);
- if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_LSC,
NULL);
+ }
+ if (adapter->switchdev_info.is_switchdev) {
+ for (vf_id = 0; vf_id < adapter->repr_ctxt.nb_repr_vf; vf_id++) {
+ repr_eth_dev = adapter->repr_ctxt.vf_rep_eth_dev[vf_id];
+ if (!repr_eth_dev)
+ continue;
+ repr_adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(repr_eth_dev);
+ (void)sxe2_drv_mac_link_status_get(repr_adapter);
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ rte_eth_dev_callback_process(repr_eth_dev,
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL);
+ }
+ }
+ }
}
if (oicr & RTE_BIT32(SXE2_COM_SW_MODE_SWITCHDEV)) {
PMD_DEV_LOG_INFO(adapter, DRV, "event notify switchdev");
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 10/51] net/sxe2: validate IPsec key length against maximum limit
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (9 preceding siblings ...)
2026-08-26 8:54 ` [PATCH v3 09/51] net/sxe2: propagate LSC event to VF representors liujie5
@ 2026-08-26 8:54 ` liujie5
2026-08-26 8:54 ` [PATCH v3 11/51] net/sxe2: rename representor VSI ID fields liujie5
` (40 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:54 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add validation in sxe2_security_valid_key to ensure the source key
length does not exceed SXE2_IPSEC_MAX_KEY_LEN, preventing potential
buffer overflows when processing keys longer than the supported
maximum. Also clear the security context pointer after releasing the
security session during uninit.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ipsec.c | 5 +++++
drivers/net/sxe2/sxe2_security.c | 1 +
2 files changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ipsec.c b/drivers/net/sxe2/sxe2_ipsec.c
index e783a51b85..622fd1adfe 100644
--- a/drivers/net/sxe2/sxe2_ipsec.c
+++ b/drivers/net/sxe2/sxe2_ipsec.c
@@ -254,6 +254,11 @@ static bool sxe2_security_valid_key(uint16_t src_key, uint16_t max_key,
goto l_end;
}
+ if (src_key > SXE2_IPSEC_MAX_KEY_LEN) {
+ is_valid = false;
+ goto l_end;
+ }
+
is_valid = true;
l_end:
diff --git a/drivers/net/sxe2/sxe2_security.c b/drivers/net/sxe2/sxe2_security.c
index bc59d1b880..8f31067942 100644
--- a/drivers/net/sxe2/sxe2_security.c
+++ b/drivers/net/sxe2/sxe2_security.c
@@ -326,6 +326,7 @@ void sxe2_security_uinit(struct rte_eth_dev *dev)
if (sctx != NULL) {
rte_free(sctx);
sctx = NULL;
+ dev->security_ctx = NULL;
}
sxe2_ipsec_uinit(adapter);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 11/51] net/sxe2: rename representor VSI ID fields
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (10 preceding siblings ...)
2026-08-26 8:54 ` [PATCH v3 10/51] net/sxe2: validate IPsec key length against maximum limit liujie5
@ 2026-08-26 8:54 ` liujie5
2026-08-26 8:54 ` [PATCH v3 12/51] net/sxe2: clean up duplicate function declarations liujie5
` (39 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:54 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Rename repr_vf_k_vsi_id/repr_vf_u_vsi_id to
repr_vf_primary_vsi_id/repr_vf_backup_vsi_id in
sxe2_repr_private_data and update all references.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_dump.c | 8 ++++----
drivers/net/sxe2/sxe2_ethdev.h | 4 ++--
drivers/net/sxe2/sxe2_flow.c | 4 ++--
drivers/net/sxe2/sxe2_switchdev.c | 4 ++--
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index d43473e083..590219f502 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -211,16 +211,16 @@ sxe2_dump_switchdev_info(FILE *file, struct rte_eth_dev *dev)
"\t -- repr_pf_id: %u\n"
"\t -- repr_vf_id: %u\n"
"\t -- repr_vf_vsi_id: %u\n"
- "\t -- repr_vf_k_vsi_id: %s\n"
- "\t -- repr_vf_u_vsi_id: %s\n",
+ "\t -- repr_vf_primary_vsi_id: %s\n"
+ "\t -- repr_vf_backup_vsi_id: %s\n",
adapter->repr_priv_data->repr_id,
adapter->repr_priv_data->repr_q_id,
adapter->repr_priv_data->repr_pf_id,
adapter->repr_priv_data->repr_vf_id,
adapter->repr_priv_data->repr_vf_vsi_id,
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_k_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_primary_vsi_id,
k_vsi_buf, sizeof(k_vsi_buf)),
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_u_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_backup_vsi_id,
u_vsi_buf, sizeof(u_vsi_buf)));
goto l_end;
}
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index c54e8a435e..158198d74b 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -263,8 +263,8 @@ struct sxe2_repr_private_data {
uint16_t repr_pf_id;
uint16_t repr_vf_id;
uint16_t repr_vf_vsi_id;
- uint16_t repr_vf_k_vsi_id;
- uint16_t repr_vf_u_vsi_id;
+ uint16_t repr_vf_primary_vsi_id;
+ uint16_t repr_vf_backup_vsi_id;
};
struct sxe2_sched_hw_cap {
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index 63cfc36968..cf54803301 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -380,9 +380,9 @@ static int32_t sxe2_flow_src_split_proc(struct rte_eth_dev *dev,
if (adapter->switchdev_info.is_switchdev && adapter->is_dev_repr) {
flow_bond_num = 1;
flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] =
- adapter->repr_priv_data->repr_vf_u_vsi_id;
+ adapter->repr_priv_data->repr_vf_backup_vsi_id;
flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] =
- adapter->repr_priv_data->repr_vf_k_vsi_id;
+ adapter->repr_priv_data->repr_vf_primary_vsi_id;
}
for (idx = 0; idx < flow_bond_num; idx++) {
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index 44703cfb5c..efb1468b91 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -312,9 +312,9 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_q_id = repr_id;
repr_priv_data->repr_pf_id = parent_adapter->pf_idx;
repr_priv_data->repr_vf_id = repr_id;
- repr_priv_data->repr_vf_k_vsi_id =
+ repr_priv_data->repr_vf_primary_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
- repr_priv_data->repr_vf_u_vsi_id =
+ repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
repr_priv_data->repr_vf_vsi_id =
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 12/51] net/sxe2: clean up duplicate function declarations
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (11 preceding siblings ...)
2026-08-26 8:54 ` [PATCH v3 11/51] net/sxe2: rename representor VSI ID fields liujie5
@ 2026-08-26 8:54 ` liujie5
2026-08-26 8:54 ` [PATCH v3 13/51] net/sxe2: fix null VSI dereference in device info liujie5
` (38 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:54 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Remove duplicate function declarations from the sxe2 driver headers:
- sxe2_drv_promisc_config, sxe2_drv_vsi_info_get and
sxe2_drv_rxq_mapping_set in sxe2_cmd_chnl.h
- sxe2_dev_pci_seg_unmap in sxe2_ethdev.h
- sxe2_rx_pkts_scattered in sxe2_txrx_poll.h
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.h | 6 ------
drivers/net/sxe2/sxe2_ethdev.h | 2 --
drivers/net/sxe2/sxe2_txrx_poll.h | 2 --
3 files changed, 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index d63caad526..294ac15db4 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -65,8 +65,6 @@ int32_t sxe2_drv_ipsec_rxsa_delete(struct sxe2_adapter *adapter,
int32_t sxe2_drv_ipsec_txsa_delete(struct sxe2_adapter *adapter,
uint16_t sa_id);
-int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set);
-
int32_t sxe2_drv_udp_tunnel_add(struct sxe2_adapter *adapter,
enum sxe2_udp_tunnel_protocol tunnel_proto,
uint16_t udp_port);
@@ -84,8 +82,6 @@ int32_t sxe2_drv_get_udp_tunnel_port(struct sxe2_adapter *adapter,
int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-
int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter);
int32_t sxe2_drv_get_mac_stats(struct sxe2_adapter *adapter);
@@ -110,8 +106,6 @@ int32_t sxe2_drv_mapping_reset(struct rte_eth_dev *eth_dev);
int32_t sxe2_drv_mapping_stats_info_clear(struct rte_eth_dev *eth_dev);
-int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t pool_idx);
-
int32_t sxe2_drv_allmulti_config(struct sxe2_adapter *adapter, bool set);
int32_t sxe2_drv_uc_config(struct sxe2_adapter *adapter, struct rte_ether_addr *addr, bool add);
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 158198d74b..1409be74d3 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -385,8 +385,6 @@ void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
int32_t sxe2_dev_pci_map_init(struct rte_eth_dev *dev);
-void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
-
int32_t sxe2_udp_tunnel_port_del_common(struct sxe2_adapter *ad,
enum sxe2_udp_tunnel_protocol tunnel_proto, uint16_t udp_port);
diff --git a/drivers/net/sxe2/sxe2_txrx_poll.h b/drivers/net/sxe2/sxe2_txrx_poll.h
index 708e3839d7..bfa099c097 100644
--- a/drivers/net/sxe2/sxe2_txrx_poll.h
+++ b/drivers/net/sxe2/sxe2_txrx_poll.h
@@ -13,8 +13,6 @@ uint16_t sxe2_tx_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t
uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-
uint16_t sxe2_rx_pkts_scattered_split(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
#endif /* SXE2_TXRX_POLL_H */
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 13/51] net/sxe2: fix null VSI dereference in device info
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (12 preceding siblings ...)
2026-08-26 8:54 ` [PATCH v3 12/51] net/sxe2: clean up duplicate function declarations liujie5
@ 2026-08-26 8:54 ` liujie5
2026-08-26 8:55 ` [PATCH v3 14/51] net/sxe2: fill MAC and queue counts " liujie5
` (37 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:54 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_infos_get() dereferences adapter->vsi_ctxt.main_vsi without
checking for NULL, which can crash when the main VSI has not been
created yet.
Add an early NULL check on vsi and return -EINVAL.
Fixes: d8e4e075ac ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 2e14c372f8..02f9ce3d32 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -781,6 +781,10 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
+ if (unlikely(vsi == NULL)) {
+ PMD_LOG_ERR(INIT, "main vsi is NULL");
+ return -EINVAL;
+ }
dev_info->max_rx_queues = vsi->rxqs.q_cnt;
dev_info->max_tx_queues = vsi->txqs.q_cnt;
dev_info->min_rx_bufsize = SXE2_MIN_BUF_SIZE;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 14/51] net/sxe2: fill MAC and queue counts in device info
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (13 preceding siblings ...)
2026-08-26 8:54 ` [PATCH v3 13/51] net/sxe2: fix null VSI dereference in device info liujie5
@ 2026-08-26 8:55 ` liujie5
2026-08-26 8:55 ` [PATCH v3 15/51] net/sxe2: fix QinQ and RSS offload capability report liujie5
` (36 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:55 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Fill max_mac_addrs, nb_rx_queues and nb_tx_queues in
sxe2_dev_infos_get() so applications can query the maximum number of
MAC addresses and the queue counts.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 02f9ce3d32..e85dee6b2c 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -792,6 +792,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->max_lro_pkt_size = SXE2_FRAME_SIZE_MAX * SXE2_RX_LRO_DESC_MAX_NUM;
dev_info->max_mtu = dev_info->max_rx_pktlen - SXE2_ETH_OVERHEAD;
dev_info->min_mtu = RTE_ETHER_MIN_MTU;
+ dev_info->max_mac_addrs = SXE2_NUM_MACADDR_MAX;
dev_info->rx_offload_capa =
RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
@@ -912,6 +913,8 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->speed_capa = RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G |
RTE_ETH_LINK_SPEED_50G | RTE_ETH_LINK_SPEED_100G;
+ dev_info->nb_rx_queues = dev->data->nb_rx_queues;
+ dev_info->nb_tx_queues = dev->data->nb_tx_queues;
dev_info->default_rxportconf.burst_size = SXE2_RX_MAX_BURST;
dev_info->default_txportconf.burst_size = SXE2_TX_MAX_BURST;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 15/51] net/sxe2: fix QinQ and RSS offload capability report
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (14 preceding siblings ...)
2026-08-26 8:55 ` [PATCH v3 14/51] net/sxe2: fill MAC and queue counts " liujie5
@ 2026-08-26 8:55 ` liujie5
2026-08-26 8:55 ` [PATCH v3 16/51] net/sxe2: use regular write for mapped registers liujie5
` (35 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:55 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Make the QINQ offload capabilities conditional on the port VLAN
setting: only advertise RTE_ETH_TX_OFFLOAD_QINQ_INSERT,
RTE_ETH_RX_OFFLOAD_QINQ_STRIP and RTE_ETH_RX_OFFLOAD_VLAN_FILTER
when no port VLAN is configured. Advertise RTE_ETH_RX_OFFLOAD_RSS_HASH
unconditionally and report the buffer split supported header ptypes
count in sxe2_buffer_split_supported_hdr_ptypes_get().
Fixes: a2b79a9351 ("net/sxe2: support L2 filtering and MAC config")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index e85dee6b2c..a8e16cdd0a 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -804,11 +804,9 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_RX_OFFLOAD_SCTP_CKSUM |
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT |
-#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
- RTE_ETH_RX_OFFLOAD_QINQ_STRIP |
-#endif
RTE_ETH_RX_OFFLOAD_VLAN_EXTEND |
- RTE_ETH_RX_OFFLOAD_TCP_LRO;
+ RTE_ETH_RX_OFFLOAD_TCP_LRO |
+ RTE_ETH_RX_OFFLOAD_RSS_HASH;
dev_info->tx_offload_capa =
RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
@@ -855,14 +853,22 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
- if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
- dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
-
if (sxe2_ipsec_supported(adapter)) {
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
}
+ if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
+
+ if (!sxe2_dev_port_vlan_check(dev)) {
+ dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
+#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
+#endif
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
+ }
+
if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_RSS) {
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
dev_info->flow_type_rss_offloads |= SXE2_RSS_HF_SUPPORT_ALL;
@@ -936,7 +942,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
static const uint32_t *
sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
- size_t *no_of_elements __rte_unused)
+ size_t *no_of_elements)
{
static const uint32_t ptypes[] = {
RTE_PTYPE_L2_ETHER,
@@ -974,6 +980,7 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
RTE_PTYPE_UNKNOWN
};
+ *no_of_elements = RTE_DIM(ptypes);
return ptypes;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 16/51] net/sxe2: use regular write for mapped registers
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (15 preceding siblings ...)
2026-08-26 8:55 ` [PATCH v3 15/51] net/sxe2: fix QinQ and RSS offload capability report liujie5
@ 2026-08-26 8:55 ` liujie5
2026-08-26 8:55 ` [PATCH v3 17/51] net/sxe2: move PCI register read macro to common header liujie5
` (34 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:55 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_pci_map_write_reg() uses the write-combined store
(SXE2_PCI_REG_WRITE_WC) to write control registers, which is intended
for doorbell/tail writes and can be lossy or delayed for ordering
sensitive register updates.
Add SXE2_PCI_REG_WRITE macro using a regular rte_write32() and use it
in sxe2_pci_map_write_reg().
Fixes: 8cebf80f1e ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
drivers/net/sxe2/sxe2_ethdev.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index a8e16cdd0a..09f5daa715 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1443,7 +1443,7 @@ void sxe2_pci_map_write_reg(struct sxe2_adapter *adapter,
goto l_ret;
}
- SXE2_PCI_REG_WRITE_WC(reg_addr, value);
+ SXE2_PCI_REG_WRITE(reg_addr, value);
l_ret:
return;
}
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 1409be74d3..cf1104144c 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -355,6 +355,8 @@ struct sxe2_adapter {
#define SXE2_DEV_PRIVATE_TO_ADAPTER(dev) \
((struct sxe2_adapter *)(dev)->data->dev_private)
+#define SXE2_PCI_REG_WRITE(reg, value) rte_write32((rte_cpu_to_le_32(value)), (reg))
+
void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
enum sxe2_pci_map_resource res_type,
uint16_t idx_in_func);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 17/51] net/sxe2: move PCI register read macro to common header
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (16 preceding siblings ...)
2026-08-26 8:55 ` [PATCH v3 16/51] net/sxe2: use regular write for mapped registers liujie5
@ 2026-08-26 8:55 ` liujie5
2026-08-26 8:55 ` [PATCH v3 18/51] net/sxe2: validate PCI map resource type liujie5
` (33 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:55 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move SXE2_PCI_REG_READ to sxe2_ethdev.h so the PCI register access
macros are kept together in the common header, matching
SXE2_PCI_REG_WRITE.
Fixes: d8e4e075ac ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_queue.h | 2 --
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index cf1104144c..f2557b28c3 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -356,6 +356,7 @@ struct sxe2_adapter {
((struct sxe2_adapter *)(dev)->data->dev_private)
#define SXE2_PCI_REG_WRITE(reg, value) rte_write32((rte_cpu_to_le_32(value)), (reg))
+#define SXE2_PCI_REG_READ(reg) rte_read32(reg)
void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
enum sxe2_pci_map_resource res_type,
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index a300b66771..10bdaf5b8d 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -12,8 +12,6 @@
#include "sxe2_drv_cmd.h"
#include "sxe2_txrx_common.h"
-#define SXE2_PCI_REG_READ(reg) \
- rte_read32(reg)
#define SXE2_PCI_REG_WRITE_WC(reg, value) \
rte_write32_wc((rte_cpu_to_le_32(value)), reg)
#define SXE2_PCI_REG_WRITE_WC_RELAXED(reg, value) \
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 18/51] net/sxe2: validate PCI map resource type
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (17 preceding siblings ...)
2026-08-26 8:55 ` [PATCH v3 17/51] net/sxe2: move PCI register read macro to common header liujie5
@ 2026-08-26 8:55 ` liujie5
2026-08-26 8:55 ` [PATCH v3 19/51] net/sxe2: guard PCI BAR unmap when not initialized liujie5
` (32 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:55 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_pci_res_seg_map() indexes adapter->map_ctxt.addr_info[] with
res_type without bounds checking, which can access out of bounds when
an invalid resource type is passed.
Add a bounds check on res_type and return -EINVAL.
Fixes: 66a10eb60e ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 09f5daa715..f76d4db6f7 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1556,6 +1556,12 @@ int32_t sxe2_dev_pci_res_seg_map(struct sxe2_adapter *adapter,
struct sxe2_pci_map_addr_info *addr_info = NULL;
int32_t ret = 0;
+ if (unlikely(res_type >= SXE2_PCI_MAP_RES_MAX_COUNT)) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Invalid resource type %u", res_type);
+ ret = -EINVAL;
+ goto l_end;
+ }
+
addr_info = &adapter->map_ctxt.addr_info[res_type];
if (!addr_info || addr_info->bar_idx == SXE2_PCI_MAP_BAR_INVALID) {
PMD_DEV_LOG_ERR(adapter, INIT, "Invalid bar index with resource type %d", res_type);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 19/51] net/sxe2: guard PCI BAR unmap when not initialized
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (18 preceding siblings ...)
2026-08-26 8:55 ` [PATCH v3 18/51] net/sxe2: validate PCI map resource type liujie5
@ 2026-08-26 8:55 ` liujie5
2026-08-26 8:55 ` [PATCH v3 20/51] net/sxe2: fix null dereference in dev uninit liujie5
` (31 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:55 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_pci_map_uinit() calls sxe2_dev_pci_seg_unmap() and walks
bar_info unconditionally. Only perform the unmap and free when
bar_info has been allocated, so an uninitialized map context is
handled cleanly.
Fixes: 66a10eb60e ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index f76d4db6f7..7e3eb6432c 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1777,14 +1777,13 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
uint8_t i = 0;
PMD_INIT_FUNC_TRACE();
+ if (map_ctxt->bar_info != NULL) {
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
-
- if (map_ctxt != NULL && map_ctxt->bar_info != NULL) {
for (i = 0; i < map_ctxt->bar_cnt; i++) {
bar_info = &map_ctxt->bar_info[i];
if (bar_info != NULL && bar_info->seg_info != NULL) {
@@ -1795,7 +1794,6 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
rte_free(map_ctxt->bar_info);
map_ctxt->bar_info = NULL;
}
-
adapter->dev_info.dev_data = NULL;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 20/51] net/sxe2: fix null dereference in dev uninit
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (19 preceding siblings ...)
2026-08-26 8:55 ` [PATCH v3 19/51] net/sxe2: guard PCI BAR unmap when not initialized liujie5
@ 2026-08-26 8:55 ` liujie5
2026-08-26 8:55 ` [PATCH v3 21/51] net/sxe2: fix duplicated cleanup in dev close liujie5
` (30 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:55 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_uninit() calls rep_dev->dev_ops->dev_close() for each VF
representor without checking that dev_ops or dev_close is present,
which can crash when the representor device is not fully initialized.
Guard the call with NULL checks.
Fixes: 635084db5d ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 7e3eb6432c..575ad299f1 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2078,9 +2078,11 @@ static int32_t sxe2_dev_uninit(struct rte_eth_dev *dev)
for (i = 0; i < adapter->repr_ctxt.nb_repr_vf; i++) {
rep_dev = adapter->repr_ctxt.vf_rep_eth_dev[i];
if (rep_dev) {
- ret = rep_dev->dev_ops->dev_close(rep_dev);
- if (ret)
- goto l_end;
+ if (rep_dev->dev_ops && rep_dev->dev_ops->dev_close) {
+ ret = rep_dev->dev_ops->dev_close(rep_dev);
+ if (ret)
+ goto l_end;
+ }
if (rep_dev->intr_handle)
rte_intr_instance_free(rep_dev->intr_handle);
ret = rte_eth_dev_release_port(rep_dev);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 21/51] net/sxe2: fix duplicated cleanup in dev close
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (20 preceding siblings ...)
2026-08-26 8:55 ` [PATCH v3 20/51] net/sxe2: fix null dereference in dev uninit liujie5
@ 2026-08-26 8:55 ` liujie5
2026-08-26 8:55 ` [PATCH v3 22/51] net/sxe2: align dev init and cleanup order liujie5
` (29 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:55 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_close() calls sxe2_switchdev_uninit() and
sxe2_dev_pci_map_uinit() twice, and releases resources in an order
that does not match the initialization sequence.
Remove the duplicated calls and align the teardown order with the
device init order.
Fixes: 8cebf80f1e ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 575ad299f1..ce1e1cae34 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2045,17 +2045,15 @@ static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
(void)sxe2_queues_release(dev);
sxe2_mp_uninit(dev);
(void)sxe2_sched_uinit(dev);
- (void)sxe2_rss_disable(dev);
(void)sxe2_flow_uninit(dev);
+ (void)sxe2_rss_disable(dev);
(void)sxe2_udp_tunnel_port_clear(dev);
- sxe2_vsi_uninit(dev);
sxe2_security_uinit(dev);
sxe2_intr_uninit(dev);
(void)sxe2_switchdev_uninit(dev);
sxe2_sw_uninit(dev);
- (void)sxe2_switchdev_uninit(dev);
- sxe2_dev_pci_map_uinit(dev);
sxe2_eth_uinit(dev);
+ sxe2_vsi_uninit(dev);
sxe2_dev_pci_map_uinit(dev);
sxe2_free_repr_info(dev);
sxe2_fc_state_uinit(dev);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 22/51] net/sxe2: align dev init and cleanup order
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (21 preceding siblings ...)
2026-08-26 8:55 ` [PATCH v3 21/51] net/sxe2: fix duplicated cleanup in dev close liujie5
@ 2026-08-26 8:55 ` liujie5
2026-08-26 8:55 ` [PATCH v3 23/51] net/sxe2: simplify switchdev representor matching liujie5
` (28 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:55 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move sxe2_eth_init() to be called before sxe2_sw_init() and
rearrange the error cleanup labels so that resources are torn down
in the reverse order of initialization.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index ce1e1cae34..7787f5435e 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1946,6 +1946,12 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_switchdev_err;
}
+ ret = sxe2_eth_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
+ goto init_eth_err;
+ }
+
ret = sxe2_sw_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize sw parameters, ret=[%d]", ret);
@@ -1958,12 +1964,6 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_irq_err;
}
- ret = sxe2_eth_init(dev);
- if (ret) {
- PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
- goto init_eth_err;
- }
-
ret = sxe2_security_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize security, ret=%d", ret);
@@ -2015,15 +2015,15 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
init_fc_state_err:
(void)sxe2_flow_uninit(dev);
init_flow_err:
-init_rss_err:
sxe2_security_uinit(dev);
+init_rss_err:
init_security_err:
- sxe2_eth_uinit(dev);
-init_eth_err:
sxe2_intr_uninit(dev);
init_irq_err:
sxe2_sw_uninit(dev);
init_sw_err:
+ sxe2_eth_uinit(dev);
+init_eth_err:
(void)sxe2_switchdev_uninit(dev);
init_switchdev_err:
init_dev_info_err:
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 23/51] net/sxe2: simplify switchdev representor matching
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (22 preceding siblings ...)
2026-08-26 8:55 ` [PATCH v3 22/51] net/sxe2: align dev init and cleanup order liujie5
@ 2026-08-26 8:55 ` liujie5
2026-08-26 8:55 ` [PATCH v3 24/51] net/sxe2: probe all requested PF ports liujie5
` (27 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:55 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_switchdev_repr_match() encodes the kernel representor ID and
compares it against each requested port, which is fragile. Match the
PF number and VF ID directly against the switchdev representor info
instead, and drop the sxe2_switchdev_repr_id_encode_get() helper.
Fixes: 635084db5d ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 68 +++++++++++++++++-----------------
drivers/net/sxe2/sxe2_ethdev.h | 3 --
2 files changed, 33 insertions(+), 38 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 7787f5435e..1dd10cd515 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2153,42 +2153,25 @@ static int32_t sxe2_fw_version_string_get(struct rte_eth_dev *dev, char *fw_vers
return ret;
}
-static uint16_t sxe2_switchdev_repr_id_encode_get(struct sxe2_switchdev_info *switchdev_info)
-{
- enum rte_eth_representor_type type;
- uint16_t repr = switchdev_info->vf_num;
- uint32_t pf = switchdev_info->pf_num;
-
- switch (switchdev_info->port_name_type) {
- case SXE2_PHYS_PORT_NAME_TYPE_UPLINK:
- if (!switchdev_info->representor)
- return UINT16_MAX;
- type = RTE_ETH_REPRESENTOR_PF;
- pf = switchdev_info->mpesw_owner;
- break;
- case SXE2_PHYS_PORT_NAME_TYPE_PFVF:
- default:
- type = RTE_ETH_REPRESENTOR_VF;
- break;
- }
-
- return SXE2_REPRESENTOR_ID(pf, type, repr);
-}
-
static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
struct rte_eth_devargs *req_eth_da)
{
- uint32_t port_idx = 0;
- uint32_t repr_idx;
- uint16_t kernel_repr_id = sxe2_switchdev_repr_id_encode_get(&adapter->switchdev_info);
- uint16_t repr_id;
+ uint16_t port_idx = UINT16_MAX;
+ uint16_t repr_idx;
+ uint16_t vf_id;
+ uint16_t i;
switch (req_eth_da->type) {
case RTE_ETH_REPRESENTOR_PF:
+ if (adapter->switchdev_info.port_name_type !=
+ SXE2_PHYS_PORT_NAME_TYPE_UPLINK) {
+ rte_errno = EBUSY;
+ return false;
+ }
break;
case RTE_ETH_REPRESENTOR_VF:
if (adapter->switchdev_info.port_name_type !=
- SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
+ SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
rte_errno = EBUSY;
return false;
}
@@ -2201,15 +2184,30 @@ static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
return false;
}
+ for (port_idx = 0; port_idx < req_eth_da->nb_ports; ++port_idx) {
+ if (adapter->switchdev_info.pf_num != req_eth_da->ports[port_idx]) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev pf %u not match req pf %u",
+ adapter->switchdev_info.pf_num, req_eth_da->ports[port_idx]);
+ rte_errno = EBUSY;
+ return false;
+ }
+ }
+
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- repr_id = SXE2_REPRESENTOR_ID(req_eth_da->ports[port_idx],
- req_eth_da->type,
- req_eth_da->representor_ports[repr_idx]);
- if (repr_id == kernel_repr_id)
- return true;
- }
- rte_errno = EBUSY;
- return false;
+ for (i = 0; i < adapter->repr_ctxt.nb_vf; ++i) {
+ vf_id = rte_le_to_cpu_16(adapter->repr_ctxt.repr_vf_id[i].func_id);
+ if (vf_id == req_eth_da->representor_ports[repr_idx])
+ break;
+ }
+ if (i == adapter->repr_ctxt.nb_vf) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev vf %u not match req vf(cnt:%u)",
+ req_eth_da->representor_ports[repr_idx], adapter->repr_ctxt.nb_vf);
+ rte_errno = EBUSY;
+ return false;
+ }
+ }
+
+ return true;
}
static int32_t sxe2_eth_pmd_probe_pf(struct sxe2_common_device *cdev,
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index f2557b28c3..e818578319 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -65,9 +65,6 @@ enum sxe2_fnav_tunnel_flag_type {
#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
#define lower_32_bits(n) ((uint32_t)((n) & 0xffffffff))
-#define SXE2_REPRESENTOR_ID(pf, type, repr) \
- (((pf) << 14) + ((type) << 12) + ((repr) & 0xfff))
-
#define SXE2_I2C_EEPROM_DEV_ADDR 0xA0
#define SXE2_I2C_EEPROM_DEV_ADDR2 0xA2
#define SXE2_MODULE_TYPE_SFP 0x03
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 24/51] net/sxe2: probe all requested PF ports
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (23 preceding siblings ...)
2026-08-26 8:55 ` [PATCH v3 23/51] net/sxe2: simplify switchdev representor matching liujie5
@ 2026-08-26 8:55 ` liujie5
2026-08-26 8:56 ` [PATCH v3 25/51] net/sxe2: rename fnav cid manager symbols to flow liujie5
` (26 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:55 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_eth_pmd_probe() always probes a single PF port (index 0) even
when multiple ports are requested in the device arguments, so
additional PF ports are never created.
Loop over eth_da.nb_ports and probe each requested port, falling
back to a single probe when no ports are specified.
Fixes: d8e4e075ac ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 1dd10cd515..8e3afd6eed 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2325,6 +2325,7 @@ static int32_t sxe2_eth_pmd_probe(struct sxe2_common_device *cdev,
{
struct rte_eth_devargs eth_da = { .nb_ports = 0 };
int32_t ret = 0;
+ uint16_t port;
ret = sxe2_parse_eth_devargs(cdev->dev, ð_da);
if (ret != 0) {
@@ -2332,7 +2333,18 @@ static int32_t sxe2_eth_pmd_probe(struct sxe2_common_device *cdev,
goto l_end;
}
- ret = sxe2_eth_pmd_probe_pf(cdev, ð_da, 0, kvargs);
+ if (eth_da.nb_ports > 0) {
+ for (port = 0; port < eth_da.nb_ports; port++) {
+ ret = sxe2_eth_pmd_probe_pf(cdev, ð_da, port, kvargs);
+ if (ret != 0) {
+ PMD_LOG_ERR(INIT, "sxe2 eth pmd probe failed, ret=%d", ret);
+ (void)sxe2_eth_pmd_remove(cdev);
+ goto l_end;
+ }
+ }
+ } else {
+ ret = sxe2_eth_pmd_probe_pf(cdev, ð_da, 0, kvargs);
+ }
l_end:
return ret;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 25/51] net/sxe2: rename fnav cid manager symbols to flow
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (24 preceding siblings ...)
2026-08-26 8:55 ` [PATCH v3 24/51] net/sxe2: probe all requested PF ports liujie5
@ 2026-08-26 8:56 ` liujie5
2026-08-26 8:56 ` [PATCH v3 26/51] net/sxe2: move tunnel port helpers into flow module liujie5
` (25 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:56 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Rename the sxe2_fnav_cid_mgr, sxe2_fnav_cid_mgr_list_t,
sxe2_fnav_count_resource and sxe2_fnav_get_filter_cid symbols to the
sxe2_flow_* prefix for consistency with the flow module naming.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 2 +-
drivers/net/sxe2/sxe2_cmd_chnl.h | 2 +-
drivers/net/sxe2/sxe2_flow.c | 46 ++++++++++++++---------------
drivers/net/sxe2/sxe2_flow.h | 6 ++--
drivers/net/sxe2/sxe2_flow_define.h | 12 ++++----
5 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b09989fe50..3229c72597 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1800,7 +1800,7 @@ int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat
}
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr)
+ struct sxe2_flow_cid_mgr *mgr)
{
struct sxe2_drv_flow_fnav_query_stat_req req = { 0 };
struct sxe2_drv_flow_fnav_query_stat_resp resp = { 0 };
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index 294ac15db4..cfea1a1f0e 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -159,7 +159,7 @@ int32_t sxe2_drv_flow_fnav_get_stat_id(struct sxe2_adapter *adapter, uint32_t *s
int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr);
+ struct sxe2_flow_cid_mgr *mgr);
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set);
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index cf54803301..a33b8606df 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -857,7 +857,7 @@ static int32_t sxe2_flow_rte_list_free(struct sxe2_adapter *adapter,
struct rte_flow *flow_temp = NULL;
struct sxe2_flow *hw_flow = NULL;
struct sxe2_flow *hw_flow_temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
rte_spinlock_lock(&adapter->flow_ctxt.flow_list_lock);
TAILQ_FOREACH(flow_temp, &adapter->flow_ctxt.rte_flow_list, next) {
if (flow_temp == flow)
@@ -1028,7 +1028,7 @@ static struct rte_flow *sxe2_flow_create(struct rte_eth_dev *dev,
goto l_free_flow;
TAILQ_FOREACH(flow, &flow_list->sxe2_flow_list, next) {
- ret = sxe2_fnav_get_filter_cid(adapter, flow);
+ ret = sxe2_flow_get_filter_cid(adapter, flow);
if (ret != 0) {
PMD_LOG_ERR(DRV, "fnav get stats id failed, ret:%d", ret);
rte_flow_error_set(error, EIO,
@@ -1088,16 +1088,16 @@ static int32_t sxe2_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e
return ret;
}
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
user_id = flow->action.count.user_id;
@@ -1112,7 +1112,7 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
}
if (mgr == NULL) {
mgr = rte_zmalloc("sxe2_fnav_cid_mgr",
- sizeof(struct sxe2_fnav_cid_mgr), 0);
+ sizeof(struct sxe2_flow_cid_mgr), 0);
if (!mgr) {
PMD_LOG_ERR(DRV,
"Failed to alloc sxe2vf_fnav_cid_mgr memory.");
@@ -1143,13 +1143,13 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *mgr = *mgr_ptr;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *mgr = *mgr_ptr;
uint32_t user_id = flow->action.count.user_id;
if (user_id == 0) {
TAILQ_REMOVE(cid_mgr_list, mgr, next);
@@ -1170,14 +1170,14 @@ int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
uint32_t user_id = flow->action.count.user_id;
uint32_t driver_id = flow->action.count.driver_id;
@@ -1218,7 +1218,7 @@ static int32_t sxe2_flow_query_count(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
switch (flow->action.count.stat_ctrl) {
case SXE2_FNAV_STAT_ENA_NONE:
count->hits_set = 0;
@@ -1348,7 +1348,7 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
int32_t ret = 0;
TAILQ_INIT(&adapter->flow_ctxt.rte_flow_list);
- TAILQ_INIT(&adapter->flow_ctxt.hw_res.fnav_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.hw_res.flow_cid_mgr_list);
if (adapter->devargs.fnav_stat_type)
adapter->flow_ctxt.hw_res.count_type =
adapter->devargs.fnav_stat_type;
@@ -1370,10 +1370,10 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
int32_t ret = 0;
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct rte_flow_error error;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
ret = sxe2_flow_flush(dev, &error);
if (ret)
diff --git a/drivers/net/sxe2/sxe2_flow.h b/drivers/net/sxe2/sxe2_flow.h
index daaeedd4dc..8d47b11ff4 100644
--- a/drivers/net/sxe2/sxe2_flow.h
+++ b/drivers/net/sxe2/sxe2_flow.h
@@ -14,16 +14,16 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev);
int32_t sxe2_flow_uninit(struct rte_eth_dev *dev);
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev);
diff --git a/drivers/net/sxe2/sxe2_flow_define.h b/drivers/net/sxe2/sxe2_flow_define.h
index 263a573f04..8a5d871978 100644
--- a/drivers/net/sxe2/sxe2_flow_define.h
+++ b/drivers/net/sxe2/sxe2_flow_define.h
@@ -98,8 +98,8 @@ struct rte_flow {
};
TAILQ_HEAD(rte_flow_list_t, rte_flow);
-struct sxe2_fnav_cid_mgr {
- TAILQ_ENTRY(sxe2_fnav_cid_mgr) next;
+struct sxe2_flow_cid_mgr {
+ TAILQ_ENTRY(sxe2_flow_cid_mgr) next;
uint16_t stat_index;
uint32_t user_id;
uint32_t driver_id;
@@ -107,18 +107,18 @@ struct sxe2_fnav_cid_mgr {
uint64_t hits;
uint64_t bytes;
};
-TAILQ_HEAD(sxe2_fnav_cid_mgr_list_t, sxe2_fnav_cid_mgr);
+TAILQ_HEAD(sxe2_flow_cid_mgr_list_t, sxe2_flow_cid_mgr);
-struct sxe2_fnav_count_resource {
+struct sxe2_flow_count_resource {
uint32_t count_type;
uint32_t global_index;
- struct sxe2_fnav_cid_mgr_list_t fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t flow_cid_mgr_list;
};
struct sxe2_flow_context {
struct rte_flow_list_t rte_flow_list;
rte_spinlock_t flow_list_lock;
- struct sxe2_fnav_count_resource hw_res;
+ struct sxe2_flow_count_resource hw_res;
uint16_t tunnel_port_list[SXE2_FLOW_UDP_TUNNEL_MAX];
uint32_t fnav_inited;
};
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 26/51] net/sxe2: move tunnel port helpers into flow module
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (25 preceding siblings ...)
2026-08-26 8:56 ` [PATCH v3 25/51] net/sxe2: rename fnav cid manager symbols to flow liujie5
@ 2026-08-26 8:56 ` liujie5
2026-08-26 8:56 ` [PATCH v3 27/51] net/sxe2: add ACL engine event statistics support liujie5
` (24 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:56 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move sxe2_flow_parse_pattern_ipip, sxe2_flow_add_udp_tunnel_port and
sxe2_flow_add_tunnel_port from sxe2_flow_parse_pattern.c into
sxe2_flow.c as static helpers, and drop the public declaration of
sxe2_flow_add_tunnel_port from the header, keeping the tunnel port
handling internal to the flow module.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_flow.c | 113 +++++++++++++++++++++
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ---------------------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 6 --
3 files changed, 113 insertions(+), 119 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index a33b8606df..cd39385340 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -550,6 +550,119 @@ int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev)
return ret;
}
+static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
+ enum sxe2_flow_udp_tunnel_protocol proto,
+ struct sxe2_flow *flow,
+ BITMAP_TYPE *flow_type)
+{
+ int32_t ret = 0;
+ uint16_t tun_port;
+
+ tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
+ if (tun_port == 0xffff || tun_port == 0) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
+ goto l_end;
+ }
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP must be over tunnel");
+ goto l_end;
+ }
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
+ flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
+l_end:
+ return ret;
+}
+
+static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
+{
+ sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ }
+ return 0;
+}
+
+static int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
+ struct rte_flow_error *error,
+ struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
+ enum sxe2_flow_tunnel_type tunnel_type)
+{
+ int32_t ret = 0;
+ enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
+ struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
+ switch (tunnel_type) {
+ case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
+ } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
+ sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GTPU:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GRE:
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
+ }
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_IPIP:
+ ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
+ break;
+ default:
+ break;
+ }
+ if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
+ ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
+ if (ret != 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ NULL, "Failed to add udp port for tunnel.");
+ PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
+ goto l_end;
+ }
+ }
+ if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
+ sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
+ }
+l_end:
+ return ret;
+}
+
static int32_t sxe2_flowlist_add_tunnel_port(struct rte_eth_dev *dev,
struct rte_flow *flow_list,
struct rte_flow_error *error)
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.c b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
index f5bf8922c6..189abb1a33 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
@@ -1637,119 +1637,6 @@ static int32_t sxe2_flow_parse_pattern_vxlan_gpe(const struct rte_flow_item *ite
return ret;
}
-static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
-{
- sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- }
- return 0;
-}
-
-static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
- enum sxe2_flow_udp_tunnel_protocol proto,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type)
-{
- int32_t ret = 0;
- uint16_t tun_port;
-
- tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
- if (tun_port == 0xffff || tun_port == 0) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
- goto l_end;
- }
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP must be over tunnel");
- goto l_end;
- }
- sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
- flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
-l_end:
- return ret;
-}
-
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type)
-{
- int32_t ret = 0;
- enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
- struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
- struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
- switch (tunnel_type) {
- case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
- } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
- sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GTPU:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GRE:
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
- }
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_IPIP:
- ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
- break;
- default:
- break;
- }
- if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
- ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
- if (ret != 0) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- NULL, "Failed to add udp port for tunnel.");
- PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
- goto l_end;
- }
- }
- if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
- sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
- }
-l_end:
- return ret;
-}
-
struct sxe2_flow_parse_pattern_ops sxe2_flow_parse_pattern_list[] = {
[SXE2_EXPANSION_OUTER_ETH] = {
.is_inner = false,
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.h b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
index 8442c35cae..69d83a6ea6 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.h
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
@@ -37,10 +37,4 @@ int32_t sxe2_flow_parse_pattern(struct rte_eth_dev *dev,
struct rte_flow_error *error,
struct sxe2_flow *flow);
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type);
-
#endif /* SXE2_FLOW_PARSE_PATTERN_H_ */
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 27/51] net/sxe2: add ACL engine event statistics support
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (26 preceding siblings ...)
2026-08-26 8:56 ` [PATCH v3 26/51] net/sxe2: move tunnel port helpers into flow module liujie5
@ 2026-08-26 8:56 ` liujie5
2026-08-26 8:56 ` [PATCH v3 28/51] net/sxe2: guard Rx queue event FD free in unregister liujie5
` (23 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:56 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add statistics support for the ACL flow engine to track packet hits
and bytes, enabling flow aging and traffic monitoring for ACL rules.
- Add acl-stat-type devarg to configure the statistics type
- Implement sxe2_drv_flow_acl_get_stat_id/free_stat/query_stat
- Handle the ACL engine in flow create/destroy/query paths
- Add fnav_hw_res and acl_hw_res count resources
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
doc/guides/nics/sxe2.rst | 11 +++
drivers/net/sxe2/sxe2_cmd_chnl.c | 71 +++++++++++++++++++
drivers/net/sxe2/sxe2_cmd_chnl.h | 7 ++
drivers/net/sxe2/sxe2_drv_cmd.h | 17 +++++
drivers/net/sxe2/sxe2_dump.c | 2 +
drivers/net/sxe2/sxe2_ethdev.c | 23 +++++--
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_flow.c | 83 ++++++++++++++++++-----
drivers/net/sxe2/sxe2_flow_define.h | 3 +-
drivers/net/sxe2/sxe2_flow_parse_action.c | 25 +++++--
drivers/net/sxe2/sxe2_queue.c | 2 +
11 files changed, 215 insertions(+), 30 deletions(-)
diff --git a/doc/guides/nics/sxe2.rst b/doc/guides/nics/sxe2.rst
index 8278a5f108..c5b400a8ba 100644
--- a/doc/guides/nics/sxe2.rst
+++ b/doc/guides/nics/sxe2.rst
@@ -98,6 +98,17 @@ Runtime Configuration
Default value is 3 (count both packets and bytes).
+- ``acl-stat-type`` parameter [int]
+
+ This parameter controls the ACL flow engine statistics type
+ used for flow rule hit counting (via ``rte_flow_query``).
+
+ - 1: Only count the number of packets.
+ - 2: Only count the number of bytes.
+ - 3: Count both packets and bytes (default).
+
+ Default value is 3 (count both packets and bytes).
+
- ``drv-sw-stats`` parameter [int]
This parameter controls whether per-packet software statistics (SW stats)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 3229c72597..16a2c3fea4 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1829,6 +1829,77 @@ int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
return ret;
}
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id)
+{
+ struct sxe2_drv_flow_fnav_get_stat_id_req req = { 0 };
+ struct sxe2_drv_flow_fnav_get_stat_id_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC,
+ &req, sizeof(req),
+ &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+ *stat_id = resp.stat_id;
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id)
+{
+ struct sxe2_drv_flow_fnav_free_stat_id_req req = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = stat_id;
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_FREE,
+ &req, sizeof(req),
+ NULL, 0);
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to free acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr)
+{
+ struct sxe2_drv_acl_query_stat_req req = { 0 };
+ struct sxe2_drv_acl_query_stat_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = mgr->stat_index;
+ req.stat_ctrl = mgr->count_type;
+ req.is_clear = 1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY,
+ &req, sizeof(req), &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to query ACL stat, stat id: %u, ret: %d.",
+ req.stat_id, ret);
+ goto l_end;
+ }
+ mgr->hits += resp.stat_hits;
+ mgr->bytes += resp.stat_bytes;
+
+l_end:
+ return ret;
+}
+
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set)
{
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index cfea1a1f0e..7d07068bfc 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -161,6 +161,13 @@ int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
struct sxe2_flow_cid_mgr *mgr);
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id);
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr);
+
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set);
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index 03ef3b315d..d332d15980 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -668,6 +668,18 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_fc_get_resp {
uint8_t rsv[3];
} __rte_packed_end;
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_req {
+ uint32_t stat_id;
+ uint32_t stat_ctrl;
+ uint32_t is_clear;
+} __rte_packed_end;
+
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_resp {
+ uint32_t stat_index;
+ uint64_t stat_hits;
+ uint64_t stat_bytes;
+} __rte_packed_end;
+
enum sxe2_drv_cmd_module {
SXE2_DRV_CMD_MODULE_HANDSHAKE = 0,
SXE2_DRV_CMD_MODULE_DEV = 1,
@@ -824,6 +836,11 @@ enum sxe2_drv_cmd_code {
SXE2_DRV_CMD_OPT_EEP_GET =
SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_OPT, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC,
+ SXE2_DRV_CMD_FLOW_ACL_STAT_FREE,
+
};
#endif /* SXE2_DRV_CMD_H */
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index 590219f502..31f7d6ba61 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -80,12 +80,14 @@ sxe2_dump_dev_args_info(FILE *file, struct rte_eth_dev *dev)
"\t -- no_sched_mode: %s\n"
"\t -- flow-duplicate-pattern: %u\n"
"\t -- fnav-stat-type: %u\n"
+ "\t -- acl-stat-type: %u\n"
"\t -- sched_layer_mode: %u\n"
"\t -- rx_low_latency: %s\n"
"\t -- function-flow-direct: %s\n",
adapter->devargs.no_sched_mode ? "On" : "Off",
adapter->devargs.flow_dup_pattern_mode,
adapter->devargs.fnav_stat_type,
+ adapter->devargs.acl_stat_type,
adapter->devargs.sched_layer_mode,
adapter->devargs.rx_low_latency ? "On" : "Off",
adapter->devargs.func_flow_direct_en ? "On" : "Off");
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 8e3afd6eed..5735dd0ff3 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -72,6 +72,7 @@ static const struct rte_pci_id pci_id_sxe2_tbl[] = {
#define SXE2_DEVARG_FLOW_DUP_PATTERN_MODE "flow-duplicate-pattern"
#define SXE2_DEVARG_FUNC_FLOW_DIRCT "function-flow-direct"
#define SXE2_DEVARG_FNAV_STAT_TYPE "fnav-stat-type"
+#define SXE2_DEVARG_ACL_STAT_TYPE "acl-stat-type"
#define SXE2_DEVARG_NO_SCHED_MODE "no-sched-mode"
#define SXE2_DEVARG_SCHED_LAYER_MODE "sched-layer-mode"
#define SXE2_DEVARG_RX_LOW_LATENCY "rx-low-latency"
@@ -985,11 +986,11 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
return ptypes;
}
-static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, void *args)
+static int32_t sxe2_parse_stat_type(const char *key, const char *value, void *args)
{
int32_t ret = -EINVAL;
uint8_t *num = (uint8_t *)args;
- unsigned long fnav_stat_type;
+ unsigned long stat_type;
char *endptr = NULL;
if (value == NULL || args == NULL) {
@@ -997,19 +998,19 @@ static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, voi
goto l_end;
}
errno = 0;
- fnav_stat_type = strtoul(value, &endptr, 10);
+ stat_type = strtoul(value, &endptr, 10);
if (errno != 0 || endptr == value || *endptr != '\0') {
PMD_LOG_WARN(INIT, "%s: \"%s\" is not a valid int value.",
key, value);
goto l_end;
}
- if (fnav_stat_type > SXE2_FNAV_STAT_ENA_ALL ||
- fnav_stat_type == SXE2_FNAV_STAT_ENA_NONE) {
+ if (stat_type > SXE2_FNAV_STAT_ENA_ALL ||
+ stat_type == SXE2_FNAV_STAT_ENA_NONE) {
PMD_LOG_ERR(INIT, "%s: \"%s\" out of range [1-3].",
key, value);
goto l_end;
}
- *num = (uint8_t)fnav_stat_type;
+ *num = (uint8_t)stat_type;
ret = 0;
l_end:
return ret;
@@ -1191,13 +1192,20 @@ static int32_t sxe2_args_parse(struct rte_eth_dev *dev, struct sxe2_dev_kvargs_i
if (kvargs == NULL)
goto l_end;
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_FNAV_STAT_TYPE,
- &sxe2_parse_fnav_stat_type,
+ &sxe2_parse_stat_type,
&adapter->devargs.fnav_stat_type);
if (ret) {
PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse fnav stat type, ret:%d", ret);
goto l_end;
}
+ ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_ACL_STAT_TYPE,
+ &sxe2_parse_stat_type, &adapter->devargs.acl_stat_type);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse acl stat type, ret:%d", ret);
+ goto l_end;
+ }
+
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_NO_SCHED_MODE,
&sxe2_parse_bool,
&adapter->devargs.no_sched_mode);
@@ -2378,6 +2386,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_sxe2,
"flow-duplicate-pattern=<0|1|2> "
"function-flow-direct=<0|1> "
"fnav-stat-type=<1|2|3> "
+ "acl-stat-type=<1|2|3> "
"no-sched-mode=<0|1> "
"sched-layer-mode=<0-3> "
"rx-low-latency=<0|1>");
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index e818578319..e9f78fe57f 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -135,6 +135,7 @@ struct sxe2_devargs {
uint8_t flow_dup_pattern_mode;
uint8_t func_flow_direct_en;
uint8_t fnav_stat_type;
+ uint8_t acl_stat_type;
uint8_t no_sched_mode;
uint8_t sched_layer_mode;
uint8_t rx_low_latency;
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index cd39385340..46f5763f62 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -1204,13 +1204,23 @@ static int32_t sxe2_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e
int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
struct sxe2_flow_cid_mgr *temp = NULL;
struct sxe2_flow_cid_mgr *mgr = NULL;
+ uint32_t count_type;
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.fnav_hw_res.count_type;
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.acl_hw_res.count_type;
+ } else {
+ goto l_end;
+ }
if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
user_id = flow->action.count.user_id;
@@ -1233,7 +1243,10 @@ int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
goto l_end;
}
- ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ ret = sxe2_drv_flow_acl_get_stat_id(adapter, &stat_index);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to alloc fw count id.");
rte_free(mgr);
@@ -1244,7 +1257,7 @@ int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
mgr->user_id = user_id;
mgr->driver_id = driver_id;
mgr->stat_index = stat_index;
- mgr->count_type = adapter->flow_ctxt.hw_res.count_type;
+ mgr->count_type = count_type;
}
flow->action.count.stat_index = mgr->stat_index;
flow->action.count.stat_ctrl = mgr->count_type;
@@ -1260,13 +1273,20 @@ int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
struct sxe2_flow_cid_mgr *mgr = *mgr_ptr;
uint32_t user_id = flow->action.count.user_id;
- if (user_id == 0) {
- TAILQ_REMOVE(cid_mgr_list, mgr, next);
- ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+
+ if (user_id == 0 && mgr) {
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+ }
if (ret) {
rte_flow_error_set(error, EIO,
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
@@ -1287,13 +1307,19 @@ int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
struct sxe2_flow_cid_mgr *temp = NULL;
struct sxe2_flow_cid_mgr *mgr = NULL;
uint32_t user_id = flow->action.count.user_id;
uint32_t driver_id = flow->action.count.driver_id;
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ else
+ goto l_end;
+
TAILQ_FOREACH(temp, cid_mgr_list, next) {
if (temp->user_id == user_id &&
temp->driver_id == driver_id) {
@@ -1310,7 +1336,15 @@ int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
ret = -EINVAL;
goto l_end;
}
- ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ ret = sxe2_drv_flow_acl_query_stat(adapter, mgr);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+ } else {
+ PMD_LOG_ERR(DRV, "query flow engine neither FNAV nor ACL");
+ ret = -ENOTSUP;
+ }
if (ret) {
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM, NULL,
@@ -1461,12 +1495,18 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
int32_t ret = 0;
TAILQ_INIT(&adapter->flow_ctxt.rte_flow_list);
- TAILQ_INIT(&adapter->flow_ctxt.hw_res.flow_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list);
if (adapter->devargs.fnav_stat_type)
- adapter->flow_ctxt.hw_res.count_type =
+ adapter->flow_ctxt.fnav_hw_res.count_type =
adapter->devargs.fnav_stat_type;
else
- adapter->flow_ctxt.hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+ adapter->flow_ctxt.fnav_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+
+ if (adapter->devargs.acl_stat_type)
+ adapter->flow_ctxt.acl_hw_res.count_type = adapter->devargs.acl_stat_type;
+ else
+ adapter->flow_ctxt.acl_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
adapter->flow_ctxt.fnav_inited = 1;
rte_spinlock_init(&adapter->flow_ctxt.flow_list_lock);
@@ -1485,13 +1525,13 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
struct rte_flow_error error;
struct sxe2_flow_cid_mgr *mgr = NULL;
struct sxe2_flow_cid_mgr *temp = NULL;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
ret = sxe2_flow_flush(dev, &error);
if (ret)
PMD_LOG_ERR(DRV, "Failed to flush flow, ret: %d.", ret);
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
TAILQ_REMOVE(cid_mgr_list, mgr, next);
ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
@@ -1500,5 +1540,14 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
"Failed to free fnav stat id, ret: %d.", ret);
rte_free(mgr);
}
+
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ if (ret)
+ PMD_LOG_ERR(DRV, "Failed to free acl stat id, ret: %d.", ret);
+ rte_free(mgr);
+ }
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_flow_define.h b/drivers/net/sxe2/sxe2_flow_define.h
index 8a5d871978..f56f687dc7 100644
--- a/drivers/net/sxe2/sxe2_flow_define.h
+++ b/drivers/net/sxe2/sxe2_flow_define.h
@@ -118,7 +118,8 @@ struct sxe2_flow_count_resource {
struct sxe2_flow_context {
struct rte_flow_list_t rte_flow_list;
rte_spinlock_t flow_list_lock;
- struct sxe2_flow_count_resource hw_res;
+ struct sxe2_flow_count_resource fnav_hw_res;
+ struct sxe2_flow_count_resource acl_hw_res;
uint16_t tunnel_port_list[SXE2_FLOW_UDP_TUNNEL_MAX];
uint32_t fnav_inited;
};
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index a9559e2d7e..db70b146c6 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -953,7 +953,8 @@ static int32_t sxe2_flow_check_actions(struct rte_eth_dev *dev __rte_unused, str
}
}
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
if (vsi_num) {
flow->action.q_region.q_index = 0;
flow->action.q_region.region = 7;
@@ -988,7 +989,8 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
case RTE_FLOW_ACTION_TYPE_VOID:
break;
case RTE_FLOW_ACTION_TYPE_PASSTHRU:
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
sxe2_set_bit(SXE2_FLOW_ACTION_PASSTHRU, flow->action.act_types);
action_num[SXE2_FLOW_ACTION_PASSTHRU]++;
} else {
@@ -1037,11 +1039,24 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
act_count = action->conf;
- flow->action.count.user_id = act_count->id;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
+ flow->action.count.driver_id = 0;
+ if (flow->action.count.user_id == 0) {
+ flow->action.count.driver_id =
+ ++adapter->flow_ctxt.fnav_hw_res.global_index;
+ }
+ action_num[SXE2_FLOW_ACTION_COUNT]++;
+ } else if (engine_type == SXE2_FLOW_ENGINE_ACL) {
+ sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
+ act_count = action->conf;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
flow->action.count.driver_id = 0;
- if (flow->action.count.user_id == 0)
+ if (flow->action.count.user_id == 0) {
flow->action.count.driver_id =
- ++adapter->flow_ctxt.hw_res.global_index;
+ ++adapter->flow_ctxt.acl_hw_res.global_index;
+ }
action_num[SXE2_FLOW_ACTION_COUNT]++;
} else {
rte_flow_error_set(error, ENOTSUP,
diff --git a/drivers/net/sxe2/sxe2_queue.c b/drivers/net/sxe2/sxe2_queue.c
index afb2681b72..3aaa14c685 100644
--- a/drivers/net/sxe2/sxe2_queue.c
+++ b/drivers/net/sxe2/sxe2_queue.c
@@ -39,6 +39,8 @@ int32_t sxe2_queues_init(struct rte_eth_dev *dev)
rxq->rx_buf_len = RTE_MIN(rxq->rx_buf_len, SXE2_RX_MAX_DATA_BUF_SIZE);
if (frame_size > rxq->rx_buf_len)
dev->data->scattered_rx = 1;
+ if (adapter->flow_ctxt.fnav_inited)
+ rxq->fnav_enable = true;
}
adapter->ptp_ctxt.mbuf_rx_ts_offset = -1;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 28/51] net/sxe2: guard Rx queue event FD free in unregister
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (27 preceding siblings ...)
2026-08-26 8:56 ` [PATCH v3 27/51] net/sxe2: add ACL engine event statistics support liujie5
@ 2026-08-26 8:56 ` liujie5
2026-08-26 8:56 ` [PATCH v3 29/51] net/sxe2: refactor primary process MP message handling liujie5
` (22 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:56 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_rxq_intr_unregister() frees irq_ctxt->rxq_event_fd outside the
rxq_event_fd NULL check. Move the free and NULL assignment inside the
guard so the buffer is only released when it was allocated.
Fixes: 8cebf80f1e ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index 53d49a4246..7fe500b229 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -881,12 +881,11 @@ static void sxe2_rxq_intr_unregister(struct rte_eth_dev *dev)
(void)sxe2_drv_dev_rxq_irq_set(adapter->cdev, i, &efd, 1);
sxe2_rxq_intr_efd_free(irq_ctxt->rxq_event_fd[i]);
}
+ rte_free(irq_ctxt->rxq_event_fd);
+ irq_ctxt->rxq_event_fd = NULL;
}
- rte_free(irq_ctxt->rxq_event_fd);
- irq_ctxt->rxq_event_fd = NULL;
rte_intr_vec_list_free(intr_handle);
-
rte_intr_nb_efd_set(intr_handle, 0);
rte_intr_max_intr_set(intr_handle, 0);
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 29/51] net/sxe2: refactor primary process MP message handling
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (28 preceding siblings ...)
2026-08-26 8:56 ` [PATCH v3 28/51] net/sxe2: guard Rx queue event FD free in unregister liujie5
@ 2026-08-26 8:56 ` liujie5
2026-08-26 8:56 ` [PATCH v3 30/51] net/sxe2: refactor Tx queue reset operations liujie5
` (21 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:56 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Extract the multi-process work logic into the sxe2_mp_do_primary_work
helper and operate on a copy of the request in the primary handler so
the original message is not modified. Simplify the reply construction
and return -ENOENT instead of -EINVAL when no response is received
from the primary process.
Fixes: 5db446ba97b0 ("net/sxe2: support statistics and multi-process")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_mp.c | 59 ++++++++++++++++++++++----------------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_mp.c b/drivers/net/sxe2/sxe2_mp.c
index a4a5c76495..93a11150a9 100644
--- a/drivers/net/sxe2/sxe2_mp.c
+++ b/drivers/net/sxe2/sxe2_mp.c
@@ -29,16 +29,11 @@ static int32_t sxe2_mp_secondary_handle(const struct rte_mp_msg *mp_msg,
const void *peer);
static int32_t
-sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+sxe2_mp_do_primary_work(struct sxe2_mp_param *param)
{
- struct rte_mp_msg reply;
- const struct sxe2_mp_param *param =
- (const struct sxe2_mp_param *)mp_msg->param;
- struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
struct rte_eth_dev *dev;
- int32_t ret = 0;
struct sxe2_mp_shared_data *mz_data;
- int32_t send_reply = 0;
+ int32_t ret = 0;
int32_t cnt = 0;
if (!rte_eth_dev_is_valid_port(param->port_id)) {
@@ -49,24 +44,21 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
}
dev = &rte_eth_devices[param->port_id];
- sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+
if (sxe2_mp_mz == NULL) {
- PMD_LOG_ERR(DRV, "Failed to lookup memzone %s", SXE2_MP_MZ_NAME);
- ret = -ENOENT;
- goto out;
+ sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+ if (sxe2_mp_mz == NULL) {
+ PMD_LOG_ERR(DRV, "Failed to lookup memzone %s",
+ SXE2_MP_MZ_NAME);
+ ret = -ENOENT;
+ goto out;
+ }
}
mz_data = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
- send_reply = 1;
-
- memset(&reply, 0, sizeof(reply));
- (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
- reply.len_param = sizeof(*reply_param);
-
switch (param->type) {
case SXE2_MP_REQ_GET_STATS:
- ret = sxe2_stats_info_get(dev,
- &mz_data->payload.stats_blk.stats,
+ ret = sxe2_stats_info_get(dev, &mz_data->payload.stats_blk.stats,
&mz_data->payload.stats_blk.qstats);
break;
case SXE2_MP_REQ_GET_XSTATS:
@@ -88,15 +80,32 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
default:
PMD_LOG_ERR(DRV, "primary process: unrecognized msg type: %d",
param->type);
- send_reply = false;
ret = -EINVAL;
- goto out;
+ break;
}
+
out:
- if (!send_reply)
- return ret;
+ param->result = ret;
+ return ret;
+}
- reply_param->result = ret;
+static int32_t
+sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+{
+ struct rte_mp_msg reply;
+ struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
+ const struct sxe2_mp_param *param =
+ (const struct sxe2_mp_param *)mp_msg->param;
+ struct sxe2_mp_param param_copy;
+
+ memset(&reply, 0, sizeof(reply));
+ (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
+ reply.len_param = sizeof(*reply_param);
+
+ param_copy = *param;
+ (void)sxe2_mp_do_primary_work(¶m_copy);
+
+ reply_param->result = param_copy.result;
reply_param->type = param->type;
reply_param->port_id = param->port_id;
@@ -275,7 +284,7 @@ int32_t sxe2_mp_request_simple(struct rte_eth_dev *dev,
if (reply.nb_received == 0) {
PMD_LOG_ERR(DRV, "No response received from primary for type=%d, port %u",
type, dev->data->port_id);
- ret = -EINVAL;
+ ret = -ENOENT;
goto out;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 30/51] net/sxe2: refactor Tx queue reset operations
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (29 preceding siblings ...)
2026-08-26 8:56 ` [PATCH v3 29/51] net/sxe2: refactor primary process MP message handling liujie5
@ 2026-08-26 8:56 ` liujie5
2026-08-26 8:56 ` [PATCH v3 31/51] net/sxe2: unify vectorized Tx buffer handling liujie5
` (20 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:56 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Extract the descriptor ring reset loop into a sxe2_tx_queue_desc_ring_reset
helper and reuse it from both the scalar and vectorized queue reset paths.
Add a sxe2_tx_queue_reset_vec entry point for vectorized queues, export
sxe2_tx_buffer_ring_free for reuse outside the module (clearing the buffer
ring pointer after freeing it), and add sxe2_tx_vec_ops_get to build the
vectorized Tx queue operations table used by the vector path setup.
Fixes: e2a4ee85a5bd ("net/sxe2: add queue setup and control")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_tx.c | 42 +++++++++++++++++++++++---------
drivers/net/sxe2/sxe2_tx.h | 4 +++
drivers/net/sxe2/sxe2_txrx_vec.c | 16 +++++++++++-
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
4 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_tx.c b/drivers/net/sxe2/sxe2_tx.c
index f49238ceef..94a6e9afc7 100644
--- a/drivers/net/sxe2/sxe2_tx.c
+++ b/drivers/net/sxe2/sxe2_tx.c
@@ -19,6 +19,17 @@ static void *sxe2_tx_doorbell_addr_get(struct sxe2_adapter *adapter, uint16_t qu
queue_id);
}
+static void sxe2_tx_queue_desc_ring_reset(struct sxe2_tx_queue *txq)
+{
+ uint16_t i;
+ static const union sxe2_tx_data_desc zeroed_desc = {{0}};
+
+ for (i = 0; i < txq->ring_depth; i++) {
+ txq->desc_ring[i] = zeroed_desc;
+ txq->desc_ring[i].wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
+ }
+}
+
static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue *txq)
{
txq->tdt_reg_addr = sxe2_tx_doorbell_addr_get(adapter, txq->queue_id);
@@ -28,20 +39,12 @@ static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
{
uint16_t prev, i;
- volatile union sxe2_tx_data_desc *txd;
- static const union sxe2_tx_data_desc zeroed_desc = {{0}};
struct sxe2_tx_buffer *tx_buffer = txq->buffer_ring;
- for (i = 0; i < txq->ring_depth; i++)
- txq->desc_ring[i] = zeroed_desc;
+ sxe2_tx_queue_desc_ring_reset(txq);
prev = txq->ring_depth - 1;
for (i = 0; i < txq->ring_depth; i++) {
- txd = &txq->desc_ring[i];
- if (txd == NULL)
- continue;
-
- txd->wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
tx_buffer[i].mbuf = NULL;
tx_buffer[i].last_id = i;
tx_buffer[prev].next_id = i;
@@ -56,6 +59,21 @@ void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
txq->next_rs = txq->rs_thresh - 1;
}
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq)
+{
+ sxe2_tx_queue_desc_ring_reset(txq);
+
+ memset(txq->buffer_ring, 0,
+ sizeof(struct sxe2_tx_buffer) * txq->ring_depth);
+
+ txq->desc_used_num = 0;
+ txq->desc_free_num = txq->ring_depth - 1;
+ txq->next_use = 0;
+ txq->next_clean = txq->ring_depth - 1;
+ txq->next_dd = txq->rs_thresh - 1;
+ txq->next_rs = txq->rs_thresh - 1;
+}
+
void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
{
uint32_t i;
@@ -70,10 +88,12 @@ void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
}
}
-static void sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
{
- if (txq != NULL && txq->buffer_ring != NULL)
+ if (txq != NULL && txq->buffer_ring != NULL) {
rte_free(txq->buffer_ring);
+ txq->buffer_ring = NULL;
+ }
}
const struct sxe2_txq_ops sxe2_default_txq_ops = {
diff --git a/drivers/net/sxe2/sxe2_tx.h b/drivers/net/sxe2/sxe2_tx.h
index f4823126b3..bc5ff1c2bc 100644
--- a/drivers/net/sxe2/sxe2_tx.h
+++ b/drivers/net/sxe2/sxe2_tx.h
@@ -9,6 +9,10 @@
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq);
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq);
+
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq);
+
int32_t __rte_cold sxe2_tx_queue_start(struct rte_eth_dev *dev, uint16_t queue_id);
void sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.c b/drivers/net/sxe2/sxe2_txrx_vec.c
index cf004f5eb2..9cfa565548 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec.c
@@ -8,6 +8,19 @@
#include "sxe2_ethdev.h"
#include "sxe2_common_log.h"
+static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq);
+
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void)
+{
+ static const struct sxe2_txq_ops ops = {
+ .queue_reset = sxe2_tx_queue_reset_vec,
+ .mbufs_release = sxe2_tx_queue_mbufs_release_vec,
+ .buffer_ring_free = sxe2_tx_buffer_ring_free,
+ };
+
+ return ops;
+}
+
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags)
{
struct sxe2_rx_queue *rxq;
@@ -233,7 +246,8 @@ int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev)
PMD_LOG_INFO(TX, "Failed to prepare tx queue, txq[%d] is NULL", i);
continue;
}
- txq->ops.mbufs_release = sxe2_tx_queue_mbufs_release_vec;
+ txq->ops = sxe2_tx_vec_ops_get();
+ txq->ops.queue_reset(txq);
}
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.h b/drivers/net/sxe2/sxe2_txrx_vec.h
index c139aed776..b9bc4f9c27 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec.h
@@ -89,6 +89,7 @@ uint16_t sxe2_rx_pkts_scattered_vec_neon_offload(void *rx_queue, struct rte_mbuf
uint16_t sxe2_tx_pkts_vec_neon_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
#endif
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void);
int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev);
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 31/51] net/sxe2: unify vectorized Tx buffer handling
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (30 preceding siblings ...)
2026-08-26 8:56 ` [PATCH v3 30/51] net/sxe2: refactor Tx queue reset operations liujie5
@ 2026-08-26 8:56 ` liujie5
2026-08-26 8:56 ` [PATCH v3 32/51] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
` (19 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:56 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add a union of the scalar and vectorized buffer ring pointers to the
Tx queue structure so the vectorized path can use sxe2_tx_buffer_vec
directly. Rename the mbuf fill helper to sxe2_tx_pkts_mbuf_fill_vec,
switch the vectorized Tx burst and mbuf release paths to the
buffer_ring_vec member, and drop the AVX512-specific fill handling and
conditional branching.
Fixes: ac60f302cb ("net/sxe2: add vectorized Rx and Tx")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_queue.h | 5 +-
drivers/net/sxe2/sxe2_txrx_vec.c | 63 ++-----
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 133 +-------------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 9 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 219 ++++++++++++++++--------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
7 files changed, 179 insertions(+), 270 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index 10bdaf5b8d..e53a1ce852 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -62,7 +62,10 @@ struct sxe2_txq_ops {
};
struct sxe2_tx_queue {
volatile union sxe2_tx_data_desc *desc_ring;
- struct sxe2_tx_buffer *buffer_ring;
+ union {
+ struct sxe2_tx_buffer *buffer_ring;
+ struct sxe2_tx_buffer_vec *buffer_ring_vec;
+ };
volatile uint32_t *tdt_reg_addr;
uint64_t offloads;
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.c b/drivers/net/sxe2/sxe2_txrx_vec.c
index 9cfa565548..05940c8cb5 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec.c
@@ -170,67 +170,28 @@ int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *
static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq)
{
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer_vec;
uint16_t i;
- if (unlikely(txq == NULL || txq->buffer_ring == NULL)) {
+ if (unlikely(txq == NULL || txq->buffer_ring_vec == NULL)) {
PMD_LOG_ERR(TX, "Tx release mbufs vec, invalid params.");
return;
}
- i = txq->next_dd - (txq->rs_thresh - 1);
-#ifdef CC_AVX512_SUPPORT
- struct rte_eth_dev *dev;
- struct sxe2_tx_buffer_vec *buffer_vec;
-
- dev = &rte_eth_devices[txq->port_id];
- if (dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512 ||
- dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512_simple) {
- buffer_vec = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ i = txq->next_dd - (txq->rs_thresh - 1);
+ buffer_vec = txq->buffer_ring_vec;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer_vec[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
- buffer_vec[i].mbuf = NULL;
- }
- }
- i = 0;
- }
- for ( ; i < txq->next_use; ++i) {
- if (buffer_vec[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
- buffer_vec[i].mbuf = NULL;
- }
- }
- } else {
-#endif
- buffer = txq->buffer_ring;
- buffer = txq->buffer_ring;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
- i = 0;
+ if (txq->next_use < i) {
+ for ( ; i < txq->ring_depth; ++i) {
+ rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
+ buffer_vec[i].mbuf = NULL;
}
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
-#ifdef CC_AVX512_SUPPORT
+ i = 0;
}
-#endif
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
+ for ( ; i < txq->next_use; ++i) {
+ rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
+ buffer_vec[i].mbuf = NULL;
}
}
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
index 0618e6d988..da96ca3064 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
@@ -115,7 +115,7 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -134,14 +134,14 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -157,10 +157,10 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
index a830c7a33b..6c8415ee5a 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
@@ -1,8 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
*/
-
-#ifndef SXE2_TEST
#include <rte_vect.h>
#include "sxe2_ethdev.h"
@@ -12,114 +10,6 @@
#include "sxe2_txrx_vec_common.h"
#include "sxe2_vsi.h"
-static __rte_always_inline int32_t sxe2_tx_bufs_free_vec_avx512(struct sxe2_tx_queue *txq)
-{
- struct sxe2_tx_buffer_vec *buffer;
- struct rte_mbuf *mbuf;
- struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC];
- struct rte_mempool *mp;
- struct rte_mempool_cache *cache;
- void **cache_objs;
- uint32_t copied;
- uint32_t i;
- int32_t ret;
- uint16_t rs_thresh;
- uint16_t free_num;
-
- if (rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE) !=
- (txq->desc_ring[txq->next_dd].wb.dd &
- rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK))) {
- ret = 0;
- goto l_end;
- }
-
- rs_thresh = txq->rs_thresh;
-
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += txq->next_dd - (rs_thresh - 1);
-
- if ((txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) &&
- (rs_thresh & 31) == 0) {
- mp = buffer[0].mbuf->pool;
- cache = rte_mempool_default_cache(mp, rte_lcore_id());
-
- if (cache == NULL || cache->len)
- goto normal;
-
- if (rs_thresh > RTE_MEMPOOL_CACHE_MAX_SIZE) {
- (void)rte_mempool_ops_enqueue_bulk(mp, (void *)buffer, rs_thresh);
- goto done;
- }
- cache_objs = &cache->objs[cache->len];
-
- copied = 0;
- while (copied < rs_thresh) {
- const __m512i objs0 = _mm512_loadu_si512(&buffer[copied]);
- const __m512i objs1 = _mm512_loadu_si512(&buffer[copied + 8]);
- const __m512i objs2 = _mm512_loadu_si512(&buffer[copied + 16]);
- const __m512i objs3 = _mm512_loadu_si512(&buffer[copied + 24]);
-
- _mm512_storeu_si512(&cache_objs[copied], objs0);
- _mm512_storeu_si512(&cache_objs[copied + 8], objs1);
- _mm512_storeu_si512(&cache_objs[copied + 16], objs2);
- _mm512_storeu_si512(&cache_objs[copied + 24], objs3);
- copied += 32;
- }
- cache->len += rs_thresh;
-
- if (cache->len >= cache->flushthresh) {
- (void)rte_mempool_ops_enqueue_bulk(mp,
- &cache->objs[cache->size], cache->len - cache->size);
- cache->len = cache->size;
- }
- goto done;
- }
-
-normal:
- mbuf = rte_pktmbuf_prefree_seg(buffer[0].mbuf);
-
- if (likely(mbuf)) {
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
-
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
-
- if (likely(mbuf)) {
- if (likely(mbuf->pool == mbuf_free_arr[0]->pool)) {
- mbuf_free_arr[free_num] = mbuf;
- free_num++;
- } else {
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
-
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
- }
- }
- }
-
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
- } else {
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
- if (mbuf != NULL)
- rte_mempool_put(mbuf->pool, mbuf);
- }
- }
-
-done:
- txq->desc_free_num += txq->rs_thresh;
- txq->next_dd += txq->rs_thresh;
- if (txq->next_dd >= txq->ring_depth)
- txq->next_dd = txq->rs_thresh - 1;
- ret = rs_thresh;
-
-l_end:
- return ret;
-}
-
static __rte_always_inline void
sxe2_tx_desc_fill_one_avx512(volatile union sxe2_tx_data_desc *desc, struct rte_mbuf *pkt,
uint64_t desc_cmd, bool with_offloads)
@@ -207,16 +97,6 @@ void sxe2_tx_desc_fill_avx512(volatile union sxe2_tx_data_desc *desc, struct rte
}
}
-static __rte_always_inline void
-sxe2_tx_pkts_mbuf_fill_avx512(struct sxe2_tx_buffer_vec *buffer,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
- uint16_t i;
-
- for (i = 0; i < nb_pkts; ++i)
- buffer[i].mbuf = tx_pkts[i];
-}
-
static __rte_always_inline uint16_t
sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool with_offloads)
@@ -228,7 +108,7 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
uint16_t tx_num;
if (txq->desc_free_num < txq->free_thresh)
- (void)sxe2_tx_bufs_free_vec_avx512(txq);
+ (void)sxe2_tx_bufs_free_vec(txq);
nb_pkts = RTE_MIN(txq->desc_free_num, nb_pkts);
if (unlikely(nb_pkts == 0)) {
@@ -241,15 +121,14 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += next_use;
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -265,10 +144,10 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = txq->desc_ring;
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -863,5 +742,3 @@ uint16_t sxe2_rx_pkts_scattered_vec_avx512_offload(void *rx_queue,
return sxe2_rx_pkts_scattered_common_vec_avx512(rx_queue,
rx_pkts, nb_pkts, true);
}
-
-#endif
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_common.h b/drivers/net/sxe2/sxe2_txrx_vec_common.h
index 9ac99cf0fa..ede4c236b1 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_common.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec_common.h
@@ -25,10 +25,11 @@
#define SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC 64
static __rte_always_inline void
-sxe2_tx_pkts_mbuf_fill(struct sxe2_tx_buffer *buffer,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+sxe2_tx_pkts_mbuf_fill_vec(struct sxe2_tx_buffer_vec *buffer,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
uint16_t i;
+
for (i = 0; i < nb_pkts; ++i)
buffer[i].mbuf = tx_pkts[i];
}
@@ -36,7 +37,7 @@ sxe2_tx_pkts_mbuf_fill(struct sxe2_tx_buffer *buffer,
static __rte_always_inline int32_t
sxe2_tx_bufs_free_vec(struct sxe2_tx_queue *txq)
{
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
struct rte_mbuf *mbuf;
struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC];
int32_t ret;
@@ -50,7 +51,7 @@ sxe2_tx_bufs_free_vec(struct sxe2_tx_queue *txq)
goto l_end;
}
rs_thresh = txq->rs_thresh;
- buffer = &txq->buffer_ring[txq->next_dd - (rs_thresh - 1)];
+ buffer = &txq->buffer_ring_vec[txq->next_dd - (rs_thresh - 1)];
mbuf = rte_pktmbuf_prefree_seg(buffer[0].mbuf);
if (likely(mbuf)) {
mbuf_free_arr[0] = mbuf;
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_neon.c b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
index 4e5cb87cd5..0b139b8269 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_neon.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
@@ -34,12 +34,58 @@ sxe2_tx_desc_fill_one_neon(volatile union sxe2_tx_data_desc *desc,
vst1q_u64(RTE_CAST_PTR(uint64_t *, desc), data_desc);
}
+static __rte_always_inline void
+sxe2_tx_desc_fill_4_neon_simple(volatile union sxe2_tx_data_desc *desc,
+ struct rte_mbuf **pkts)
+{
+ uint64x2_t d0, d1, d2, d3;
+ uint64x2x4_t v;
+ const uint64_t cmd_base = ((uint64_t)SXE2_TX_DESC_DTYPE_DATA) |
+ ((uint64_t)SXE2_TX_DATA_DESC_CMD_EOP) <<
+ SXE2_TX_DATA_DESC_CMD_SHIFT;
+
+ d0 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[0]),
+ cmd_base |
+ ((uint64_t)pkts[0]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[0]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d1 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[1]),
+ cmd_base |
+ ((uint64_t)pkts[1]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[1]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d2 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[2]),
+ cmd_base |
+ ((uint64_t)pkts[2]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[2]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d3 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[3]),
+ cmd_base |
+ ((uint64_t)pkts[3]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[3]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+
+ v.val[0] = d0;
+ v.val[1] = d1;
+ v.val[2] = d2;
+ v.val[3] = d3;
+ vst1q_u64_x4(RTE_CAST_PTR(uint64_t *, desc), v);
+}
+
static __rte_always_inline uint16_t
sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -59,18 +105,26 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
-
- for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
+ if (with_offloads) {
+ for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ }
+ } else {
+ for (i = 0; i + 3 < res_num - 1; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
sxe2_tx_desc_fill_one_neon(desc, *tx_pkts++,
@@ -82,14 +136,23 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
- for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ if (with_offloads) {
+ for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, true);
+ }
+ } else {
+ for (i = 0; i + 3 < tx_num; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
next_use += tx_num;
@@ -150,22 +213,24 @@ uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue,
}
static __rte_always_inline void
-sxe2_rx_desc_ptype_fill_neon(uint16x8_t staterr, struct rte_mbuf **__rte_restrict rx_pkts)
+sxe2_rx_desc_ptype_fill_neon(uint32x4_t desc_lo,
+ struct rte_mbuf **__rte_restrict rx_pkts,
+ const uint32_t *__rte_restrict ptype_tbl)
{
- uint16x8_t ptype_mask = {
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
+ const uint32x4_t ptype_mask = {
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
};
uint16x8_t ptype_all;
- ptype_all = vandq_u16(staterr, ptype_mask);
+ ptype_all = vreinterpretq_u16_u32(vandq_u32(desc_lo, ptype_mask));
- rx_pkts[3]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
- rx_pkts[2]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
- rx_pkts[1]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
- rx_pkts[0]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[0]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
+ rx_pkts[1]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
+ rx_pkts[2]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[3]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
}
static __rte_always_inline uint32x4_t
@@ -208,9 +273,10 @@ sxe2_rx_desc_fnav_flags_neon(uint64x2_t descs_arr[4])
static __rte_always_inline void
sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
volatile union sxe2_rx_desc *desc,
- uint64x2_t descs[4], struct rte_mbuf **rx_pkts)
+ uint64x2_t descs[4], uint32x4_t desc_lo, uint32x4_t desc_hi,
+ struct rte_mbuf **rx_pkts)
{
- uint32x4_t desc_lo, desc_hi, flags, tmp_flags;
+ uint32x4_t flags, tmp_flags;
const uint64x2_t mbuf_init = {rxq->mbuf_init_value, 0};
uint64x2_t rearm0, rearm1, rearm2, rearm3;
@@ -267,23 +333,6 @@ sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
0, 0, 0, 0, 0, 0, 0, 0
};
- {
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint64x2_t f64, t64;
-
- flags = vzip2q_u32(d1, d0);
- tmp_flags = vzip2q_u32(d3, d2);
- f64 = vreinterpretq_u64_u32(flags);
- t64 = vreinterpretq_u64_u32(tmp_flags);
- desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(f64),
- vget_low_u64(t64)));
- desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(f64),
- vget_high_u64(t64)));
- }
-
desc_lo = vandq_u32(desc_lo, desc_msk);
desc_hi = vandq_u32(desc_hi, rss_msk);
@@ -442,25 +491,39 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
uint64x2_t descs[SXE2_RX_NUM_PER_LOOP_NEON];
uint8x16_t pkt_mb1, pkt_mb2, pkt_mb3, pkt_mb4;
uint64x2_t mbp1, mbp2;
+ uint32x4_t desc_lo, desc_hi;
uint16x8_t staterr;
uint16x8_t tmp;
uint16_t bit_num;
descs[3] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 3));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[2] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 2));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[1] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 1));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[0] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc));
rte_atomic_thread_fence(rte_memory_order_acquire);
-
descs[3] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 3), descs[3], 0);
descs[2] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 2), descs[2], 0);
descs[1] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 1), descs[1], 0);
descs[0] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc), descs[0], 0);
+ {
+ uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
+ uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
+ uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
+ uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
+
+ uint32x4_t q1_01 = vzip2q_u32(d0, d1);
+ uint32x4_t q1_23 = vzip2q_u32(d2, d3);
+ uint64x2_t q1_01_64 = vreinterpretq_u64_u32(q1_01);
+ uint64x2_t q1_23_64 = vreinterpretq_u64_u32(q1_23);
+
+ desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(q1_01_64),
+ vget_low_u64(q1_23_64)));
+ desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(q1_01_64),
+ vget_high_u64(q1_23_64)));
+ }
+
mbp1 = vld1q_u64((uint64_t *)&buffer[i]);
mbp2 = vld1q_u64((uint64_t *)&buffer[i + 2]);
@@ -480,7 +543,8 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
pkt_mb1 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[0]), rvp_shuf_mask);
if (do_offload) {
- sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, &rx_pkts[i]);
+ sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, desc_lo,
+ desc_hi, &rx_pkts[i]);
} else {
const uint64x2_t mbuf_init = {
rxq->mbuf_init_value,
@@ -515,55 +579,48 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
rte_prefetch_non_temporal(desc + SXE2_RX_NUM_PER_LOOP_NEON);
{
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint32x4_t sterr_tmp1 = vzip2q_u32(d1, d0);
- uint32x4_t sterr_tmp2 = vzip2q_u32(d3, d2);
- uint32x4_t sterr_u32 = vzip1q_u32(sterr_tmp1, sterr_tmp2);
-
- staterr = vreinterpretq_u16_u32(sterr_u32);
+ uint16x8_t sterr_tmp1 = vzip2q_u16(vreinterpretq_u16_u64(descs[0]),
+ vreinterpretq_u16_u64(descs[2]));
+ uint16x8_t sterr_tmp2 = vzip2q_u16(vreinterpretq_u16_u64(descs[1]),
+ vreinterpretq_u16_u64(descs[3]));
+ staterr = vzip1q_u16(sterr_tmp1, sterr_tmp2);
}
- sxe2_rx_desc_ptype_fill_neon(staterr, &rx_pkts[i]);
+ sxe2_rx_desc_ptype_fill_neon(desc_lo, &rx_pkts[i], sxe2_ptype_tbl);
if (umbcast_flags != NULL) {
- uint32x4_t umbcast_mask = {
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- };
-
+ const uint32x4_t umbcast_mask =
+ vdupq_n_u32(SXE2_RX_DESC_STATUS_UMBCAST_MASK);
uint8x16_t umbcast_shuf_mask = {
- 0x0B, 0x03, 0x0F, 0x07,
+ 3, 7, 11, 15,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
};
uint8x16_t umbcast_bits =
- vreinterpretq_u8_u32(vandq_u32(vreinterpretq_u32_u16(staterr),
- umbcast_mask));
+ vreinterpretq_u8_u32(vandq_u32(desc_lo, umbcast_mask));
umbcast_bits = vqtbl1q_u8(umbcast_bits, umbcast_shuf_mask);
- vst1q_lane_u32((uint32_t *)umbcast_flags,
- vreinterpretq_u32_u8(umbcast_bits), 0);
+ *(uint32_t *)umbcast_flags =
+ vgetq_lane_u32(vreinterpretq_u32_u8(umbcast_bits), 0);
umbcast_flags += SXE2_RX_NUM_PER_LOOP_NEON;
}
if (split_rxe_flags) {
uint8x16_t eop_shuf_mask = {
- 0x08, 0x00, 0x0C, 0x04,
+ 0, 2, 4, 6,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF};
uint8x16_t eop_bits;
uint32x4_t rxe_mask = {
- 0x2080, 0x2080, 0x2080, 0x2080
+ 0x20802080, 0x20802080, 0x20802080, 0x20802080
};
uint32x4_t rxe_bits;
uint32x4_t eop_mask;
- eop_mask = vshlq_n_u32(vdupq_n_u32(1), SXE2_RX_DESC_STATUS_EOP_SHIFT);
+ eop_mask = vdupq_n_u32((1U << SXE2_RX_DESC_STATUS_EOP_SHIFT) |
+ (1U << (SXE2_RX_DESC_STATUS_EOP_SHIFT + 16)));
eop_bits = vandq_u8(vmvnq_u8(vreinterpretq_u8_u16(staterr)),
vreinterpretq_u8_u32(eop_mask));
@@ -587,12 +644,22 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
}
{
- uint32x4_t dd_mask = vdupq_n_u32(1);
- uint32x4_t sterr_dd = vandq_u32(vreinterpretq_u32_u16(staterr), dd_mask);
- uint16x4_t packed_lo = vmovn_u32(sterr_dd);
- uint64_t dd64 = vget_lane_u64(vreinterpret_u64_u16(packed_lo), 0);
-
- bit_num = (uint16_t)rte_popcount64(dd64);
+ const uint16x8_t dd_check = {
+ 0x0001, 0x0001, 0x0001, 0x0001,
+ 0, 0, 0, 0
+ };
+ uint16x8_t sterr_dd;
+ uint64_t stat;
+ sterr_dd = vandq_u16(staterr, dd_check);
+ sterr_dd = vshlq_n_u16(sterr_dd, 15);
+ sterr_dd =
+ vreinterpretq_u16_s16(vshrq_n_s16(vreinterpretq_s16_u16(sterr_dd),
+ 15));
+ stat = ~vgetq_lane_u64(vreinterpretq_u64_u16(sterr_dd), 0);
+ if (likely(stat == 0))
+ bit_num = SXE2_RX_NUM_PER_LOOP_NEON;
+ else
+ bit_num = (uint16_t)(rte_ctz64(stat) / 16);
}
done_num += bit_num;
if (likely(bit_num != SXE2_RX_NUM_PER_LOOP_NEON))
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_sse.c b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
index c3e8a2983b..181bb40041 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_sse.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
@@ -40,7 +40,7 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -57,11 +57,11 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
tx_num = nb_pkts;
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
@@ -74,9 +74,9 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 32/51] net/sxe2: refine vectorized Tx/Rx mode setup
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (31 preceding siblings ...)
2026-08-26 8:56 ` [PATCH v3 31/51] net/sxe2: unify vectorized Tx buffer handling liujie5
@ 2026-08-26 8:56 ` liujie5
2026-08-26 8:56 ` [PATCH v3 33/51] net/sxe2: fix RSS action attribute validation liujie5
` (18 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:56 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Set rte_eth_tx_pkt_prepare_dummy for the simple and vectorized Tx paths
instead of leaving the prepare callback unset, and split the NEON
simple/offload mode selection based on the offload flag. Log the selected
Tx/Rx mode flags and apply the default Rx free threshold when the
configured value is zero.
Fixes: ac60f302cb ("net/sxe2: add vectorized Rx and Tx")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_rx.c | 3 ++-
drivers/net/sxe2/sxe2_txrx.c | 19 +++++++++++++------
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_rx.c b/drivers/net/sxe2/sxe2_rx.c
index d700c60083..3830c676d7 100644
--- a/drivers/net/sxe2/sxe2_rx.c
+++ b/drivers/net/sxe2/sxe2_rx.c
@@ -319,7 +319,8 @@ int32_t __rte_cold sxe2_rx_queue_setup(struct rte_eth_dev *dev,
rxq->mb_pool = mp;
}
- rxq->rx_free_thresh = rx_conf->rx_free_thresh;
+ rxq->rx_free_thresh = (rx_conf->rx_free_thresh == 0) ?
+ SXE2_DEFAULT_RX_FREE_THRESH : rx_conf->rx_free_thresh;
rxq->port_id = dev->data->port_id;
rxq->offloads = offloads;
if (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
diff --git a/drivers/net/sxe2/sxe2_txrx.c b/drivers/net/sxe2/sxe2_txrx.c
index 79870866d1..d27d2ce630 100644
--- a/drivers/net/sxe2/sxe2_txrx.c
+++ b/drivers/net/sxe2/sxe2_txrx.c
@@ -358,7 +358,7 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
if (tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
#ifdef RTE_ARCH_X86
if (tx_mode_flags & SXE2_TX_MODE_VEC_AVX512) {
#ifdef CC_AVX512_SUPPORT
@@ -386,21 +386,25 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
#elif defined(RTE_ARCH_ARM64)
if (tx_mode_flags & SXE2_TX_MODE_VEC_NEON) {
- dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
- } else {
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ if (tx_mode_flags & SXE2_TX_MODE_VEC_OFFLOAD) {
+ dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
+ } else {
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ }
}
#endif
} else {
if (tx_mode_flags & SXE2_TX_MODE_SIMPLE_BATCH) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
dev->tx_pkt_burst = sxe2_tx_pkts_simple;
} else {
dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
dev->tx_pkt_burst = sxe2_tx_pkts;
}
}
+ PMD_LOG_DEBUG(TX, "Tx mode flags:0x%016x port_id:%u.",
+ tx_mode_flags, dev->data->port_id);
}
static const struct {
@@ -582,6 +586,9 @@ void sxe2_rx_mode_func_set(struct rte_eth_dev *dev)
dev->rx_pkt_burst = sxe2_rx_pkts_scattered_split;
else
dev->rx_pkt_burst = sxe2_rx_pkts_scattered;
+
+ PMD_LOG_DEBUG(RX, "Rx mode flags:0x%016x port_id:%u.",
+ rx_mode_flags, dev->data->port_id);
}
static const struct {
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 33/51] net/sxe2: fix RSS action attribute validation
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (32 preceding siblings ...)
2026-08-26 8:56 ` [PATCH v3 32/51] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
@ 2026-08-26 8:56 ` liujie5
2026-08-26 8:56 ` [PATCH v3 34/51] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
` (17 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:56 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The rss->level/key_len/queue_num checks only set the rte_flow_error
but still return 0 (success), so invalid RSS configurations are
accepted instead of being rejected with ENOTSUP.
Return the error code from the validation checks, matching the
behavior in the V3 implementation.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_flow_parse_action.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index db70b146c6..867d90ae1d 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -25,15 +25,21 @@ static int32_t sxe2_flow_check_rss_action_attr(const struct rte_flow_action_rss
goto l_end;
}
- if (rss->level > 2)
+ if (rss->level > 2) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"RSS level is could not be greater than 2");
- if (rss->key_len)
+ goto l_end;
+ }
+ if (rss->key_len) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a nonzero RSS key_len is not supported");
- if (rss->queue_num)
+ goto l_end;
+ }
+ if (rss->queue_num) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a non-NULL RSS queue is not supported");
+ goto l_end;
+ }
ret = 0;
l_end:
return ret;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 34/51] net/sxe2: restore PF-only guard in udp tunnel port add
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (33 preceding siblings ...)
2026-08-26 8:56 ` [PATCH v3 33/51] net/sxe2: fix RSS action attribute validation liujie5
@ 2026-08-26 8:56 ` liujie5
2026-08-26 8:57 ` [PATCH v3 35/51] net/sxe2: align flow meta proc priority handling with V3 liujie5
` (16 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:56 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_udp_tunnel_port_add_common() lost the check that restricts
UDP tunnel port configuration to PF devices (not VF or
representor), so VF/representor devices can now attempt to add
UDP tunnel ports, which the hardware does not support.
Restore the PF-only guard returning -ENOTSUP, matching the V3
implementation.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 5735dd0ff3..88fe43298a 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -630,6 +630,10 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
struct sxe2_udp_tunnel_cfg *tunnel_config;
int32_t ret = -1;
+ if (ad->dev_type != SXE2_DEV_T_PF || ad->is_dev_repr) {
+ ret = -ENOTSUP;
+ goto l_end;
+ }
rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
tunnel_config = &ad->udp_tunnel_ctx.tunnel_conf[tunnel_proto];
@@ -659,6 +663,7 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
l_unlock_end:
rte_spinlock_unlock(&ad->udp_tunnel_ctx.lock);
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 35/51] net/sxe2: align flow meta proc priority handling with V3
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (34 preceding siblings ...)
2026-08-26 8:56 ` [PATCH v3 34/51] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
@ 2026-08-26 8:57 ` liujie5
2026-08-26 8:57 ` [PATCH v3 36/51] net/sxe2: restore link update call in status query liujie5
` (15 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:57 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_flow_meta_proc() uses a flat else-if chain for the priority
check, while the V3 implementation nests the switchdev mode check
inside the else branch. Align the structure with V3 for consistency.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_flow.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index 46f5763f62..037d9e6f9c 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -285,14 +285,16 @@ static int32_t sxe2_flow_meta_proc(struct rte_eth_dev *dev,
attr, "Only support priority 0.");
ret = -rte_errno;
goto l_end;
- } else if (!adapter->switchdev_info.is_switchdev) {
- PMD_LOG_ERR(DRV, "Legacy mode only support priority 0.");
- rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
- attr, "Legacy mode only priority 0.");
- ret = -rte_errno;
- goto l_end;
} else {
- flow->meta.flow_prio = attr->priority;
+ if (!adapter->switchdev_info.is_switchdev) {
+ PMD_LOG_ERR(DRV, "Legacy mode only support priority 0.");
+ rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
+ attr, "Legacy mode only priority 0.");
+ ret = -rte_errno;
+ goto l_end;
+ } else {
+ flow->meta.flow_prio = attr->priority;
+ }
}
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 36/51] net/sxe2: restore link update call in status query
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (35 preceding siblings ...)
2026-08-26 8:57 ` [PATCH v3 35/51] net/sxe2: align flow meta proc priority handling with V3 liujie5
@ 2026-08-26 8:57 ` liujie5
2026-08-26 8:57 ` [PATCH v3 37/51] net/sxe2: validate representor ID against VF count liujie5
` (14 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:57 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_mac_link_status_get() no longer calls sxe2_link_update()
after refreshing the link context, so the ethdev link state is only
refreshed during device init (sxe2_link_update_init) and never
updated when link status is queried at runtime, including on LSC
interrupt events.
Move the sxe2_link_update() call back into
sxe2_drv_mac_link_status_get() and simplify sxe2_link_update_init()
accordingly, matching the V3 implementation.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 2 ++
drivers/net/sxe2/sxe2_mac.c | 9 +--------
2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 16a2c3fea4..705d259412 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -412,6 +412,7 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
{
int32_t ret = 0;
struct sxe2_common_device *cdev = adapter->cdev;
+ struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
struct sxe2_drv_cmd_params param = {0};
struct sxe2_drv_link_info_resp resp = {0};
@@ -425,6 +426,7 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
}
adapter->link_ctxt.speed = resp.speed;
adapter->link_ctxt.link_up = resp.status;
+ (void)sxe2_link_update(dev, 0);
l_end:
return ret;
diff --git a/drivers/net/sxe2/sxe2_mac.c b/drivers/net/sxe2/sxe2_mac.c
index 729c804ac3..7dbea92670 100644
--- a/drivers/net/sxe2/sxe2_mac.c
+++ b/drivers/net/sxe2/sxe2_mac.c
@@ -448,18 +448,11 @@ int32_t sxe2_link_update_init(struct rte_eth_dev *dev)
int32_t ret;
PMD_INIT_FUNC_TRACE();
-
rte_spinlock_init(&adapter->link_ctxt.link_lock);
-
ret = sxe2_drv_mac_link_status_get(adapter);
- if (ret) {
+ if (ret)
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get link status, ret=%d", ret);
- goto l_end;
- }
- (void)sxe2_link_update(dev, 0);
-
-l_end:
return ret;
}
int32_t sxe2_link_update(struct rte_eth_dev *dev, __rte_unused int32_t wait_to_complete)
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 37/51] net/sxe2: validate representor ID against VF count
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (36 preceding siblings ...)
2026-08-26 8:57 ` [PATCH v3 36/51] net/sxe2: restore link update call in status query liujie5
@ 2026-08-26 8:57 ` liujie5
2026-08-26 8:57 ` [PATCH v3 38/51] net/sxe2: use primary VSI ID for representor VSI liujie5
` (13 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:57 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_switchdev_repr_private_data_init() indexes
parent_adapter->repr_ctxt.repr_vf_id[repr_id] without checking that
repr_id is within the number of configured VFs, which can access out
of bounds when an invalid representor ID is passed.
Add a bounds check on repr_id against repr_ctxt.nb_vf and return
-EINVAL on the error path.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_switchdev.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index efb1468b91..d0304ccc94 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -312,6 +312,12 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_q_id = repr_id;
repr_priv_data->repr_pf_id = parent_adapter->pf_idx;
repr_priv_data->repr_vf_id = repr_id;
+ if (repr_id >= parent_adapter->repr_ctxt.nb_vf) {
+ PMD_LOG_ERR(INIT, "repr_id %u exceed max vf %u",
+ repr_id, parent_adapter->repr_ctxt.nb_vf);
+ ret = -EINVAL;
+ goto l_free;
+ }
repr_priv_data->repr_vf_primary_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
repr_priv_data->repr_vf_backup_vsi_id =
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 38/51] net/sxe2: use primary VSI ID for representor VSI
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (37 preceding siblings ...)
2026-08-26 8:57 ` [PATCH v3 37/51] net/sxe2: validate representor ID against VF count liujie5
@ 2026-08-26 8:57 ` liujie5
2026-08-26 8:57 ` [PATCH v3 39/51] net/sxe2: wrap command params fill debug log in macro liujie5
` (12 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:57 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
repr_priv_data->repr_vf_vsi_id is assigned with a ternary that falls
back to the backup (dpdk) VSI ID when the kernel VSI ID is invalid.
The V3 implementation assigns it directly from
repr_vf_primary_vsi_id.
Align with the V3 implementation by assigning repr_vf_vsi_id from
repr_vf_primary_vsi_id.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_switchdev.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index d0304ccc94..81ced7b855 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -323,11 +323,7 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
- repr_priv_data->repr_vf_vsi_id =
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id !=
- SXE2_INVALID_VSI_ID ?
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id :
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
+ repr_priv_data->repr_vf_vsi_id = repr_priv_data->repr_vf_primary_vsi_id;
adapter->repr_priv_data = repr_priv_data;
goto l_end;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 39/51] net/sxe2: wrap command params fill debug log in macro
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (38 preceding siblings ...)
2026-08-26 8:57 ` [PATCH v3 38/51] net/sxe2: use primary VSI ID for representor VSI liujie5
@ 2026-08-26 8:57 ` liujie5
2026-08-26 8:57 ` [PATCH v3 40/51] net/sxe2: restore Rx queue buffer split fill support liujie5
` (11 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:57 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_cmd_params_fill() passes the opcode string as a parameter to
__sxe2_drv_cmd_params_fill() just to emit a debug log, and the debug
log is executed unconditionally on every command fill.
Move the PMD_DEV_LOG_DEBUG into the macro body wrapped in a do/while
block, dropping the opc_str parameter so the opcode stringization is
performed at the call site and the macro is a proper multi-statement
block.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 705d259412..b17d80d917 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -26,10 +26,9 @@ static void sxe2_drv_trace_id_alloc(uint64_t *trace_id)
}
static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
- struct sxe2_drv_cmd_params *cmd, uint32_t opc, const char *opc_str,
+ struct sxe2_drv_cmd_params *cmd, uint32_t opc,
void *in_data, uint32_t in_len, void *out_data, uint32_t out_len)
{
- PMD_DEV_LOG_DEBUG(adapter, DRV, "cmd opcode:%s", opc_str);
cmd->timeout = SXE2_DRV_CMD_DFLT_TIMEOUT;
cmd->opcode = opc;
cmd->vsi_id = adapter->vsi_ctxt.dpdk_vsi_id;
@@ -44,8 +43,10 @@ static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
}
#define sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len) \
- __sxe2_drv_cmd_params_fill(adapter, cmd, opc, #opc, in_data, in_len, out_data, out_len)
-
+ do { \
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "cmd opcode:%s", #opc); \
+ __sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len); \
+ } while (0)
int32_t sxe2_drv_dev_caps_get(struct sxe2_adapter *adapter, struct sxe2_drv_dev_caps_resp *dev_caps)
{
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 40/51] net/sxe2: restore Rx queue buffer split fill support
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (39 preceding siblings ...)
2026-08-26 8:57 ` [PATCH v3 39/51] net/sxe2: wrap command params fill debug log in macro liujie5
@ 2026-08-26 8:57 ` liujie5
2026-08-26 8:57 ` [PATCH v3 41/51] net/sxe2: skip tunnel config fill on get failure liujie5
` (10 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:57 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The V4 branch dropped sxe2_rxq_buf_split_fill() and the buffer split
handling in sxe2_rxq_ctxt_cfg_fill(), so the Rx buffer split offload
(RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) is advertised in device info but
the per-queue context never configures split_en/split_type_mask/
hdr_len, and buffer split packets are not handled correctly.
Restore the sxe2_rxq_buf_split_fill() helper and the buffer split
branch in sxe2_rxq_ctxt_cfg_fill(), matching the V3 implementation.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 106 +++++++++++++++++++++++++++++++
1 file changed, 106 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b17d80d917..5102890107 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -194,6 +194,102 @@ int32_t sxe2_drv_vsi_del(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi)
#define SXE2_RXQ_CTXT_CFG_BUF_LEN_ALIGN (1 << 7)
#define SXE2_RX_HDR_SIZE 256
+static int32_t sxe2_rxq_buf_split_fill(struct sxe2_rx_queue *rxq,
+ struct sxe2_drv_rxq_ctxt *ctxt)
+{
+ int32_t ret = 0;
+ uint32_t proto_hdr;
+
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
+ proto_hdr = rxq->rx_seg[0].proto_hdr;
+ if (proto_hdr == RTE_PTYPE_UNKNOWN) {
+ PMD_LOG_ERR(RX, "Buffer split protocol must be configured");
+ ret = -1;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L4_MASK) {
+ case RTE_PTYPE_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_TCP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_UDP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_SCTP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L3_MASK) {
+ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV4;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV6;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L2_MASK) {
+ case RTE_PTYPE_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_L2_ETHER;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L4_MASK) {
+ case RTE_PTYPE_INNER_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_TCP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_UDP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_SCTP;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L3_MASK) {
+ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV4;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV6;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L2_MASK) {
+ case RTE_PTYPE_INNER_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L2_ETHER;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_TUNNEL_MASK) {
+ case RTE_PTYPE_TUNNEL_GRENAT:
+ ctxt->split_type_mask = SXE2_PTYPE_TUNNEL_GRENAT;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ goto l_end;
+ }
+ PMD_LOG_ERR(RX, "Buffer split protocol is not supported");
+ ret = -1;
+ } else {
+ ctxt->hdr_len = 0;
+ ctxt->split_type_mask = 0;
+ }
+l_end:
+ return ret;
+}
+
static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
struct sxe2_drv_rxq_cfg_req *req, uint16_t rxq_cnt)
{
@@ -227,7 +323,17 @@ static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
else
ctxt->keep_crc_en = 0;
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
+ ret = sxe2_rxq_buf_split_fill(rxq, ctxt);
+ if (ret)
+ goto l_end;
+ ctxt->split_en = 1;
+ } else {
+ ctxt->split_en = 0;
+ }
+
ctxt->desc_size = sizeof(union sxe2_rx_desc);
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 41/51] net/sxe2: skip tunnel config fill on get failure
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (40 preceding siblings ...)
2026-08-26 8:57 ` [PATCH v3 40/51] net/sxe2: restore Rx queue buffer split fill support liujie5
@ 2026-08-26 8:57 ` liujie5
2026-08-26 8:57 ` [PATCH v3 42/51] net/sxe2: skip flow id assignment on filter add failure liujie5
` (9 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:57 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_udp_tunnel_get() fills tunnel_config fields even when the
firmware command fails, so a failed get overwrites the config with
the (zero-initialized) response data instead of leaving it intact.
Return early with the error code when sxe2_drv_cmd_exec() fails,
matching the V3 implementation.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 5102890107..8c45554637 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1669,15 +1669,17 @@ int32_t sxe2_drv_udp_tunnel_get(struct sxe2_adapter *adapter,
&req, sizeof(req),
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_LOG_ERR(DRV, "Failed to get udp proto %d port, ret=%d", req.type, ret);
+ goto l_end;
+ }
tunnel_config->fw_port = resp.port;
tunnel_config->fw_status = resp.enable;
tunnel_config->fw_dst_en = resp.dst;
tunnel_config->fw_src_en = resp.src;
tunnel_config->fw_used = resp.fw_used;
-
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 42/51] net/sxe2: skip flow id assignment on filter add failure
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (41 preceding siblings ...)
2026-08-26 8:57 ` [PATCH v3 41/51] net/sxe2: skip tunnel config fill on get failure liujie5
@ 2026-08-26 8:57 ` liujie5
2026-08-26 8:57 ` [PATCH v3 43/51] net/sxe2: fix command channel log messages liujie5
` (8 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:57 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_flow_filter_add() assigns flow->flow_id from the response
even when the firmware command fails, overwriting any previously
set flow id with the zero-initialized response value.
Return early on command failure so flow->flow_id is preserved, and
set flow->create_err on both the success and error paths.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 8c45554637..e0c45ae0e3 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1837,9 +1837,13 @@ int32_t sxe2_drv_flow_filter_add(struct sxe2_adapter *adapter, struct sxe2_flow
sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_FILTER_ADD, &req,
sizeof(req), &resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to add flow filter, ret: %d.", ret);
+ goto l_end;
+ }
flow->flow_id = resp.flow_id;
+
+l_end:
flow->create_err = ret;
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 43/51] net/sxe2: fix command channel log messages
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (42 preceding siblings ...)
2026-08-26 8:57 ` [PATCH v3 42/51] net/sxe2: skip flow id assignment on filter add failure liujie5
@ 2026-08-26 8:57 ` liujie5
2026-08-26 8:57 ` [PATCH v3 44/51] net/sxe2: align command structs with historical kernel layout liujie5
` (7 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:57 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Several error/warning messages in sxe2_cmd_chnl.c are inaccurate or
lost context:
- vsi_info_get: message lost the vsi id; restore it
- rxq_bind_irq/rxq_unbind_irq: message lost the rxq index; restore it
- promisc_config: fix "promic" typo in the message
- queue_info_get_update/rxq_mapping_set: incorrect "get queue info
map"/"get dev caps" wording; use "rx queue mapping failed"
- txq_mapping_set: "Rx queue" should read "Tx queue"; incorrect
"get dev caps" wording should read "tx queue mapping failed"
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index e0c45ae0e3..b4f8b337b5 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -498,7 +498,7 @@ int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi
&vsi_info_get_resp, sizeof(vsi_info_get_resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_DEV_LOG_ERR(adapter, DRV, "switchdev cpvsi info get failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "vsi %u info get failed, ret=%d", vsi->vsi_id, ret);
goto l_end;
}
@@ -556,7 +556,7 @@ int32_t sxe2_drv_rxq_bind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx, ui
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq bind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u bind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -576,7 +576,7 @@ int32_t sxe2_drv_rxq_unbind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx)
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq unbind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u unbind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -777,7 +777,7 @@ int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set)
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_WARN(adapter, DRV, "promic config failed, ret=%d", ret);
+ PMD_DEV_LOG_WARN(adapter, DRV, "promisc config failed, ret=%d", ret);
return ret;
}
@@ -1702,7 +1702,7 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_LOG_ERR(DRV, "get queue info map failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
goto l_end;
}
@@ -1746,7 +1746,7 @@ int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
l_end:
return ret;
@@ -1763,7 +1763,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
txq = eth_dev->data->tx_queues[queue_id];
if (txq == NULL) {
- PMD_LOG_ERR(DRV, "Rx queue %u is not available or setup", queue_id);
+ PMD_LOG_ERR(DRV, "Tx queue %u is not available or setup", queue_id);
ret = -EINVAL;
goto l_end;
}
@@ -1777,7 +1777,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "tx queue mapping failed, ret=%d", ret);
l_end:
return ret;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 44/51] net/sxe2: align command structs with historical kernel layout
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (43 preceding siblings ...)
2026-08-26 8:57 ` [PATCH v3 43/51] net/sxe2: fix command channel log messages liujie5
@ 2026-08-26 8:57 ` liujie5
2026-08-26 8:58 ` [PATCH v3 45/51] common/sxe2: fix ioctl channel log and close handling liujie5
` (6 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:57 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The sxe2_drv_cmd.h command structures must match the layout used by
historical SXE2 kernel versions so the same firmware command ABI is
shared. Several structures were declared with __rte_packed_begin/
__rte_packed_end and extra rsv padding that the kernel layout does
not have:
- sxe2_drv_link_info_resp: drop rsv[3] padding
- sxe2_tm_res: drop rsv[2] padding and packed attribute
- sxe2_tm_info: drop packed attribute
- sxe2_tm_add_mid_msg: drop packed attribute
- sxe2_tm_add_queue_msg: drop packed attribute
- sxe2_drv_sfp_req: drop packed attribute
- sxe2_drv_sfp_resp: drop packed attribute
Keep the structure members as-is so the command ABI is compatible
with the historical kernel driver.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_drv_cmd.h | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index d332d15980..f66b574e83 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -230,7 +230,6 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_info_get_resp {
struct __rte_aligned(4) __rte_packed_begin sxe2_drv_link_info_resp {
uint32_t speed;
uint8_t status;
- uint8_t rsv[3];
} __rte_packed_end;
struct __rte_aligned(4) __rte_packed_begin sxe2_switchdev_info {
@@ -348,31 +347,30 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_rss_hf_req {
uint8_t rsv1[3];
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_res {
+struct sxe2_tm_res {
uint16_t teid;
- uint8_t rsv[2];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_info {
+struct sxe2_tm_info {
uint32_t committed;
uint32_t peak;
uint8_t priority;
uint8_t reserve;
uint16_t weight;
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_add_mid_msg {
+struct sxe2_tm_add_mid_msg {
uint16_t parent_teid;
uint8_t adj_lvl;
struct sxe2_tm_info info;
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_add_queue_msg {
+struct sxe2_tm_add_queue_msg {
uint16_t parent_teid;
uint16_t queue_id;
uint8_t adj_lvl;
struct sxe2_tm_info info;
-} __rte_packed_end;
+};
struct __rte_aligned(4) __rte_packed_begin sxe2_drv_ipsec_capa_resq {
uint16_t tx_sa_cnt;
@@ -633,7 +631,7 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_udp_tunnel_resp {
uint8_t rsv;
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
+struct sxe2_drv_sfp_req {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t bus_addr;
@@ -642,14 +640,14 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
uint16_t data_len;
uint16_t rvd;
uint8_t data[];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_resp {
+struct sxe2_drv_sfp_resp {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t data_len;
uint8_t data[];
-} __rte_packed_end;
+};
enum sxe2_fc_type {
SXE2_FC_T_DIS = 0,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 45/51] common/sxe2: fix ioctl channel log and close handling
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (44 preceding siblings ...)
2026-08-26 8:57 ` [PATCH v3 44/51] net/sxe2: align command structs with historical kernel layout liujie5
@ 2026-08-26 8:58 ` liujie5
2026-08-26 8:58 ` [PATCH v3 46/51] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (5 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:58 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Compare sxe2_ioctl_chnl.c against the reference implementation and
fix the following discrepancies:
- sxe2_drv_dev_close: only log the closed fd when it is valid, move
PMD_LOG_INFO inside the fd >= 0 check
- sxe2_drv_dev_mmap: fix swapped format arguments in the debug log
(cmd_fd and bar_idx were passed in the wrong order)
- sxe2_drv_dev_dma_unmap: use PMD_LOG_ERR instead of PMD_LOG_INFO
for the ioctl failure message
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_ioctl_chnl.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index 3e2fbf572f..e62ca42a8f 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -107,9 +107,11 @@ sxe2_drv_dev_close(struct sxe2_common_device *cdev)
{
int32_t fd = SXE2_CDEV_TO_CMD_FD(cdev);
- if (fd >= 0)
+ if (fd >= 0) {
close(fd);
- PMD_LOG_INFO(COM, "closed device fd=%d", fd);
+ PMD_LOG_INFO(COM, "closed device fd=%d", fd);
+ }
+
SXE2_CDEV_TO_CMD_FD(cdev) = SXE2_CMD_FD_INVALID;
}
@@ -350,7 +352,7 @@ void
}
PMD_LOG_DEBUG(COM, "fd=%d, bar idx=%d, len=%"PRIu64", src=0x%"PRIx64", offset=0x%"PRIx64"",
- bar_idx, cmd_fd, len, offset, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
+ cmd_fd, bar_idx, len, offset, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
virt = mmap(NULL, len, PROT_READ | PROT_WRITE,
MAP_SHARED, cmd_fd, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
@@ -477,7 +479,7 @@ sxe2_drv_dev_dma_unmap(struct sxe2_common_device *cdev, uint64_t iova)
pthread_mutex_lock(&cdev->config.lock);
ret = ioctl(cmd_fd, SXE2_COM_CMD_DMA_UNMAP, &cmd_params);
if (ret < 0) {
- PMD_LOG_INFO(COM, "Failed to dma unmap, fd=%d, ret=%d, err:%s",
+ PMD_LOG_ERR(COM, "Failed to dma unmap, fd=%d, ret=%d, err:%s",
cmd_fd, ret, strerror(errno));
ret = -EIO;
pthread_mutex_unlock(&cdev->config.lock);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 46/51] doc/sxe2: remove drv-sw-stats parameter documentation
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (45 preceding siblings ...)
2026-08-26 8:58 ` [PATCH v3 45/51] common/sxe2: fix ioctl channel log and close handling liujie5
@ 2026-08-26 8:58 ` liujie5
2026-08-26 8:58 ` [PATCH v3 47/51] net/sxe2: harden ACL flow count resource handling liujie5
` (4 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:58 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The drv-sw-stats devarg and the software receive statistics xstats
that depend on it are no longer supported. Remove the parameter
description from the Runtime Configuration section and the
corresponding "Receive Software Statistics" subsection under
Extended Statistics to keep the documentation consistent.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
doc/guides/nics/sxe2.rst | 49 ----------------------------------------
1 file changed, 49 deletions(-)
diff --git a/doc/guides/nics/sxe2.rst b/doc/guides/nics/sxe2.rst
index c5b400a8ba..d9be5ab693 100644
--- a/doc/guides/nics/sxe2.rst
+++ b/doc/guides/nics/sxe2.rst
@@ -109,30 +109,6 @@ Runtime Configuration
Default value is 3 (count both packets and bytes).
-- ``drv-sw-stats`` parameter [int]
-
- This parameter controls whether per-packet software statistics (SW stats)
- are collected in the Rx data path.
-
- Hardware packet statistic counters may be inaccurate for certain packet types
- due to hardware design limitations.
- When accuracy of Rx packet classification statistics is critical,
- enabling this parameter allows the driver to accumulate statistics in software
- as packets are received, providing an alternative statistical path
- that bypasses hardware counter inaccuracies.
-
- - 0: Disable software statistics collection (default).
- The basic port statistics (``ipackets``, ``ibytes``) are reported
- from the hardware counters.
- - 1: Enable software statistics collection.
- Per-packet software statistics are accumulated for unicast,
- multicast, broadcast, and dropped packets in the Rx data path.
-
- When enabled, the following extended statistics (xstats) are available:
- ``rx_sw_unicast_packets``, ``rx_sw_multicast_packets``,
- ``rx_sw_broadcast_packets``, ``rx_sw_drop_packets``,
- and ``rx_sw_drop_bytes``.
-
- ``no-sched-mode`` parameter [int]
This parameter enables non-scheduling mode (no-sched mode).
@@ -197,31 +173,6 @@ Runtime Configuration
Extended Statistics (xstats)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The PMD provides the following extended statistics (xstats)
-for detailed monitoring of receive-side packet classification
-and software-level accounting.
-The software statistics path is provided as a workaround
-for hardware counter inaccuracies on certain packet types ---
-it accumulates per-packet statistics directly in the Rx data path,
-ensuring that unicast, multicast, broadcast, and drop counts
-reflect the actual packets processed by the driver.
-
-Receive Software Statistics
- These counters are collected in the Rx data path
- when ``drv-sw-stats=1`` is configured (see the ``drv-sw-stats`` devarg above).
- When ``drv-sw-stats`` is disabled (default), these xstats report zero.
-
- - ``rx_sw_unicast_packets``: Number of unicast packets received.
- - ``rx_sw_multicast_packets``: Number of multicast packets received.
- - ``rx_sw_broadcast_packets``: Number of broadcast packets received.
- - ``rx_sw_drop_packets``: Number of packets dropped in the Rx data path.
- - ``rx_sw_drop_bytes``: Number of bytes dropped in the Rx data path.
-
- When ``drv-sw-stats`` is enabled, the basic counters
- ``ipackets`` and ``ibytes`` (from ``rte_eth_stats``)
- also reflect the software-accumulated packet and byte counts.
- Otherwise, they are reported from hardware counters.
-
Fnav Flow Engine Statistics
The Fnav flow engine statistics type is controlled by
the ``fnav-stat-type`` devarg (see above).
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 47/51] net/sxe2: harden ACL flow count resource handling
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (46 preceding siblings ...)
2026-08-26 8:58 ` [PATCH v3 46/51] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
@ 2026-08-26 8:58 ` liujie5
2026-08-26 8:58 ` [PATCH v3 48/51] net/sxe2: fix device init and representor matching issues liujie5
` (3 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:58 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Fix issues found in the ACL flow count (statistics) support:
- sxe2_flow_free_mgr(): when the flow engine type is neither ACL nor
FNAV, the code skipped the TAILQ_REMOVE but still called rte_free()
on the manager, leaving a freed pointer on the list. Return -ENOTSUP
for an unknown engine type instead.
- sxe2_flow_cid_mgr.stat_index is uint16_t while the firmware returns
and consumes a uint32_t stat id; widen it to uint32_t to avoid silent
truncation.
- sxe2_drv_cmd_code: write the ACL STAT_ALLOC/STAT_FREE entries with an
explicit SXE2_MK_DRV_CMD() value instead of relying on implicit
increment over the encoded QUERY value.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_drv_cmd.h | 6 ++++--
drivers/net/sxe2/sxe2_flow.c | 6 ++++++
drivers/net/sxe2/sxe2_flow_define.h | 2 +-
3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index f66b574e83..8d907b3843 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -836,8 +836,10 @@ enum sxe2_drv_cmd_code {
SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY =
SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 1),
- SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC,
- SXE2_DRV_CMD_FLOW_ACL_STAT_FREE,
+ SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 2),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_FREE =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 3),
};
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index 037d9e6f9c..45ace5b848 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -1288,6 +1288,12 @@ int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
TAILQ_REMOVE(cid_mgr_list, mgr, next);
ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+ } else {
+ PMD_LOG_ERR(DRV,
+ "Failed to free flow count, unknown engine type: %d.",
+ flow->engine_type);
+ ret = -ENOTSUP;
+ return ret;
}
if (ret) {
rte_flow_error_set(error, EIO,
diff --git a/drivers/net/sxe2/sxe2_flow_define.h b/drivers/net/sxe2/sxe2_flow_define.h
index f56f687dc7..d04499f5cb 100644
--- a/drivers/net/sxe2/sxe2_flow_define.h
+++ b/drivers/net/sxe2/sxe2_flow_define.h
@@ -100,7 +100,7 @@ TAILQ_HEAD(rte_flow_list_t, rte_flow);
struct sxe2_flow_cid_mgr {
TAILQ_ENTRY(sxe2_flow_cid_mgr) next;
- uint16_t stat_index;
+ uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
uint32_t count_type;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 48/51] net/sxe2: fix device init and representor matching issues
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (47 preceding siblings ...)
2026-08-26 8:58 ` [PATCH v3 47/51] net/sxe2: harden ACL flow count resource handling liujie5
@ 2026-08-26 8:58 ` liujie5
2026-08-26 8:58 ` [PATCH v3 49/51] net/sxe2: use correct loop counter type for representor LSC liujie5
` (2 subsequent siblings)
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:58 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
- sxe2_dev_init(): move the init_rss_err label above
sxe2_security_uinit() so an RSS init failure still unwinds the
security context instead of leaking it.
- sxe2_buffer_split_supported_hdr_ptypes_get(): exclude the trailing
RTE_PTYPE_UNKNOWN terminator from no_of_elements so applications do
not receive a bogus ptype entry.
- sxe2_switchdev_repr_match(): match the PF when the adapter's pf_num
is among the requested ports instead of requiring every requested
port to equal pf_num, which could never succeed with multiple ports.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 88fe43298a..f4e65852d4 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -986,7 +986,7 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
RTE_PTYPE_UNKNOWN
};
- *no_of_elements = RTE_DIM(ptypes);
+ *no_of_elements = RTE_DIM(ptypes) - 1;
return ptypes;
}
@@ -2028,8 +2028,8 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
init_fc_state_err:
(void)sxe2_flow_uninit(dev);
init_flow_err:
- sxe2_security_uinit(dev);
init_rss_err:
+ sxe2_security_uinit(dev);
init_security_err:
sxe2_intr_uninit(dev);
init_irq_err:
@@ -2198,12 +2198,14 @@ static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
}
for (port_idx = 0; port_idx < req_eth_da->nb_ports; ++port_idx) {
- if (adapter->switchdev_info.pf_num != req_eth_da->ports[port_idx]) {
- PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev pf %u not match req pf %u",
- adapter->switchdev_info.pf_num, req_eth_da->ports[port_idx]);
- rte_errno = EBUSY;
- return false;
- }
+ if (adapter->switchdev_info.pf_num == req_eth_da->ports[port_idx])
+ break;
+ }
+ if (port_idx == req_eth_da->nb_ports) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev pf %u not match req pf",
+ adapter->switchdev_info.pf_num);
+ rte_errno = EBUSY;
+ return false;
}
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 49/51] net/sxe2: use correct loop counter type for representor LSC
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (48 preceding siblings ...)
2026-08-26 8:58 ` [PATCH v3 48/51] net/sxe2: fix device init and representor matching issues liujie5
@ 2026-08-26 8:58 ` liujie5
2026-08-26 8:58 ` [PATCH v3 50/51] net/sxe2: restore NULL check in vectorized Tx mbuf release liujie5
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:58 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The LSC propagation loop uses uint8_t vf_id as the loop counter while
adapter->repr_ctxt.nb_repr_vf is uint16_t. When more than 255 VFs are
present, vf_id wraps and the loop runs forever.
Use uint16_t for vf_id to match the nb_repr_vf type.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index 7fe500b229..4e5339e24b 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -79,7 +79,7 @@ static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t
struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
struct rte_eth_dev *repr_eth_dev;
struct sxe2_adapter *repr_adapter;
- uint8_t vf_id;
+ uint16_t vf_id;
if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
PMD_DEV_LOG_INFO(adapter, DRV, "OICR=0x%" PRIx64, oicr);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 50/51] net/sxe2: restore NULL check in vectorized Tx mbuf release
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (49 preceding siblings ...)
2026-08-26 8:58 ` [PATCH v3 49/51] net/sxe2: use correct loop counter type for representor LSC liujie5
@ 2026-08-26 8:58 ` liujie5
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
51 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:58 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_tx_queue_mbufs_release_vec() calls rte_pktmbuf_free_seg() on each
buffer entry without checking for NULL. rte_pktmbuf_free_seg() does not
tolerate NULL and dereferences its argument, so a stop/start cycle or
any unwritten slot in the release range can crash.
Restore the NULL check before freeing each mbuf.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_txrx_vec.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.c b/drivers/net/sxe2/sxe2_txrx_vec.c
index 05940c8cb5..7c5da33dd5 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec.c
@@ -183,15 +183,19 @@ static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq)
if (txq->next_use < i) {
for ( ; i < txq->ring_depth; ++i) {
- rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
- buffer_vec[i].mbuf = NULL;
+ if (buffer_vec[i].mbuf != NULL) {
+ rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
+ buffer_vec[i].mbuf = NULL;
+ }
}
i = 0;
}
for ( ; i < txq->next_use; ++i) {
- rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
- buffer_vec[i].mbuf = NULL;
+ if (buffer_vec[i].mbuf != NULL) {
+ rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
+ buffer_vec[i].mbuf = NULL;
+ }
}
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
` (50 preceding siblings ...)
2026-08-26 8:58 ` [PATCH v3 50/51] net/sxe2: restore NULL check in vectorized Tx mbuf release liujie5
@ 2026-08-26 8:58 ` liujie5
2026-08-27 2:36 ` [PATCH v4 00/44] net/sxe2: add Stars SXE2 net driver with fixes liujie5
` (44 more replies)
51 siblings, 45 replies; 207+ messages in thread
From: liujie5 @ 2026-08-26 8:58 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_rxq_buf_split_fill() re-tests the RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT
offload flag even though the caller already guarantees it, leaving the
else branch dead. It also returns -1 on failure instead of a standard
errno.
Drop the redundant flag test and dead else branch, set hdr_len once
after the switch chain, and return -EINVAL for an unconfigured split
protocol and -ENOTSUP for an unsupported one.
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 142 ++++++++++++++-----------------
1 file changed, 62 insertions(+), 80 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b4f8b337b5..9bd6e3355f 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -197,97 +197,79 @@ int32_t sxe2_drv_vsi_del(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi)
static int32_t sxe2_rxq_buf_split_fill(struct sxe2_rx_queue *rxq,
struct sxe2_drv_rxq_ctxt *ctxt)
{
- int32_t ret = 0;
uint32_t proto_hdr;
- if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
- proto_hdr = rxq->rx_seg[0].proto_hdr;
- if (proto_hdr == RTE_PTYPE_UNKNOWN) {
- PMD_LOG_ERR(RX, "Buffer split protocol must be configured");
- ret = -1;
- goto l_end;
- }
+ proto_hdr = rxq->rx_seg[0].proto_hdr;
+ if (proto_hdr == RTE_PTYPE_UNKNOWN) {
+ PMD_LOG_ERR(RX, "Buffer split protocol must be configured");
+ return -EINVAL;
+ }
- switch (proto_hdr & RTE_PTYPE_L4_MASK) {
- case RTE_PTYPE_L4_TCP:
- ctxt->split_type_mask = SXE2_PTYPE_L4_TCP;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- case RTE_PTYPE_L4_UDP:
- ctxt->split_type_mask = SXE2_PTYPE_L4_UDP;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- case RTE_PTYPE_L4_SCTP:
- ctxt->split_type_mask = SXE2_PTYPE_L4_SCTP;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- }
+ switch (proto_hdr & RTE_PTYPE_L4_MASK) {
+ case RTE_PTYPE_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_TCP;
+ goto l_end;
+ case RTE_PTYPE_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_UDP;
+ goto l_end;
+ case RTE_PTYPE_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_SCTP;
+ goto l_end;
+ }
- switch (proto_hdr & RTE_PTYPE_L3_MASK) {
- case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
- ctxt->split_type_mask = SXE2_PTYPE_L3_IPV4;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
- ctxt->split_type_mask = SXE2_PTYPE_L3_IPV6;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- }
+ switch (proto_hdr & RTE_PTYPE_L3_MASK) {
+ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV4;
+ goto l_end;
+ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV6;
+ goto l_end;
+ }
- switch (proto_hdr & RTE_PTYPE_L2_MASK) {
- case RTE_PTYPE_L2_ETHER:
- ctxt->split_type_mask = SXE2_PTYPE_L2_ETHER;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- }
+ switch (proto_hdr & RTE_PTYPE_L2_MASK) {
+ case RTE_PTYPE_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_L2_ETHER;
+ goto l_end;
+ }
- switch (proto_hdr & RTE_PTYPE_INNER_L4_MASK) {
- case RTE_PTYPE_INNER_L4_TCP:
- ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_TCP;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- case RTE_PTYPE_INNER_L4_UDP:
- ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_UDP;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- case RTE_PTYPE_INNER_L4_SCTP:
- ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_SCTP;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- }
+ switch (proto_hdr & RTE_PTYPE_INNER_L4_MASK) {
+ case RTE_PTYPE_INNER_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_TCP;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_UDP;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_SCTP;
+ goto l_end;
+ }
- switch (proto_hdr & RTE_PTYPE_INNER_L3_MASK) {
- case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
- ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV4;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
- ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV6;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- }
+ switch (proto_hdr & RTE_PTYPE_INNER_L3_MASK) {
+ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV4;
+ goto l_end;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV6;
+ goto l_end;
+ }
- switch (proto_hdr & RTE_PTYPE_INNER_L2_MASK) {
- case RTE_PTYPE_INNER_L2_ETHER:
- ctxt->split_type_mask = SXE2_PTYPE_INNER_L2_ETHER;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- }
+ switch (proto_hdr & RTE_PTYPE_INNER_L2_MASK) {
+ case RTE_PTYPE_INNER_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L2_ETHER;
+ goto l_end;
+ }
- switch (proto_hdr & RTE_PTYPE_TUNNEL_MASK) {
- case RTE_PTYPE_TUNNEL_GRENAT:
- ctxt->split_type_mask = SXE2_PTYPE_TUNNEL_GRENAT;
- ctxt->hdr_len = SXE2_RX_HDR_SIZE;
- goto l_end;
- }
- PMD_LOG_ERR(RX, "Buffer split protocol is not supported");
- ret = -1;
- } else {
- ctxt->hdr_len = 0;
- ctxt->split_type_mask = 0;
+ switch (proto_hdr & RTE_PTYPE_TUNNEL_MASK) {
+ case RTE_PTYPE_TUNNEL_GRENAT:
+ ctxt->split_type_mask = SXE2_PTYPE_TUNNEL_GRENAT;
+ goto l_end;
}
+
+ PMD_LOG_ERR(RX, "Buffer split protocol is not supported");
+ return -ENOTSUP;
l_end:
- return ret;
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ return 0;
}
static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* Re: [PATCH v3 00/51] net/sxe2: add Stars SXE2 net driver with fixes
2026-08-26 8:53 ` [PATCH v3 00/51] net/sxe2: add Stars SXE2 net driver with fixes liujie5
@ 2026-08-26 17:07 ` Stephen Hemminger
0 siblings, 0 replies; 207+ messages in thread
From: Stephen Hemminger @ 2026-08-26 17:07 UTC (permalink / raw)
To: liujie5; +Cc: dev
On Wed, 26 Aug 2026 16:53:32 +0800
liujie5@linkdatatechnology.com wrote:
> From: Jie Liu <liujie5@linkdatatechnology.com>
>
> This series adds the Stars SXE2 (Wuxi Stars Micro System) Ethernet
> driver, including the common driver (drivers/common/sxe2), the net
> driver (drivers/net/sxe2), and its documentation.
>
> The driver supports:
> - Legacy and switchdev modes with VF representors
> - Scalar and vectorized (SSE/AVX2/AVX512/NEON) Rx/Tx paths
> - FNAV and ACL flow engines with per-flow statistics
> - RSS, QinQ, IPsec, Traffic Management and multi-process support
>
> In addition to the driver functionality, the series fixes a number of
> correctness issues found during review, including a security context
> leak in the device init error path, a NULL dereference in the
> vectorized Tx mbuf release path, an out-of-bounds representor ID
> access, and a representor LSC loop counter type mismatch. The command
> channel log messages and ioctl channel handling are also aligned with
> the reference implementation.
>
> This is v3 of the series, incorporating review feedback. All patches
> build independently and no ABI changes are introduced.
Although I appreciate having each part broken into a patch for review;
this large a series gets a little hard to review.
You are posting large series where one patch is fixing a bug which was
introduced by an earlier patch. That is a good way to do development but
is not best practice for final submission. Please consolidate and reorder
patches so that each patch builds, and after each patch there are no
new bugs.
The more verbose (sorry) AI review highlights this.
Findings below come from applying the series and reading the
resulting source. Numbers are the v3 patch numbers.
Patches that fix earlier patches in the same series
---------------------------------------------------
09/51 fixed by 49/51 uint8_t vf_id vs uint16_t nb_repr_vf
15/51 fixed by 48/51 no_of_elements counts the terminator
22/51 fixed by 48/51 init_rss_err label placement
23/51 fixed by 48/51 PF match: all ports vs any port
27/51 fixed by 47/51 stat_index truncation, list handling
31/51 fixed by 50/51 NULL check in vec Tx mbuf release
40/51 fixed by 51/51 sxe2_rxq_buf_split_fill rewritten
Please squash each fix into the patch that introduced the bug.
48/51 mixes three unrelated fixes, so split it first.
Errors
------
24/51 probe all requested PF ports
sxe2_eth_pmd_probe_pf() has "uint16_t owner_id __rte_unused".
The new loop calls it N times with nothing varying. The
function calls rte_eth_dev_pci_allocate(pci_dev, ...), which
derives the port name from the PCI device, so iteration 2
fails with -ENOMEM. The error path then calls
sxe2_eth_pmd_remove(cdev), destroying the port that did probe.
Multi-port devargs go from working to failing. Use owner_id,
or drop the patch.
33/51 fix RSS action attribute validation
sxe2_flow_check_rss_action_attr() starts with
"int32_t ret = ENOTSUP" (no minus), so the three new goto
l_end paths return a positive errno. The default: case above
returns -EINVAL. Use -ENOTSUP.
44/51 align command structs with historical kernel layout
Removing __rte_packed_begin moves fields in wire structures:
sxe2_tm_add_mid_msg info offset 3 -> 4
sxe2_tm_add_queue_msg info offset 5 -> 8
sxe2_tm_res size 4 -> 2
The commit says members are kept as-is, but offsets change.
If these are the offsets firmware expects, put the numbers in
the commit message. Otherwise this breaks TM commands.
46/51 remove drv-sw-stats parameter documentation
Removing the drv-sw-stats devarg text is right, the devarg is
gone. Removing the "Receive Software Statistics" section is
not: sxe2_stats.c still registers rx_sw_unicast_packets,
rx_sw_broadcast_packets, rx_sw_multicast_packets,
rx_sw_drop_packets and rx_sw_drop_bytes, and
sxe2_rx_sw_stats_update() still runs. Keep that section, or
remove the xstats too.
Warnings
--------
Tags
20 patches have Cc: stable with no Fixes: tag (05/51, and
33/51 through 51/51). sxe2 shipped in 26.07, so stable is
correct, but each needs a Fixes: line.
Seven Fixes: hashes are 10 characters; DPDK requires 12. All
resolve to real commits:
635084db5d -> 635084db5d57 ac60f302cb -> ac60f302cbef
66a10eb60e -> 66a10eb60ebe d8e4e075ac -> d8e4e075acb4
83866f8d76 -> 83866f8d7638 8cebf80f1e -> 8cebf80f1eda
a2b79a9351 -> a2b79a93515e
17/51, 30/51 and 39/51 are refactors carrying Fixes: and
Cc: stable. They are not bug fixes; drop the tags.
35/51 has no functional change (else if -> nested else { if }).
Please drop the patch.
Commit message does not match the diff
31/51 describes a buffer ring union and a rename. It also
removes #ifndef SXE2_TEST from the AVX512 file, deletes the
AVX512 bulk free path, rewrites the NEON Rx path (ptype
extraction, staterr, DD counting, shuffle masks) and adds
sxe2_tx_desc_fill_4_neon_simple(). It also drops the per-load
rte_atomic_thread_fence() calls in the NEON Rx loop. The
result matches the ixgbe/i40e NEON idiom and looks correct,
but a fast path memory ordering change must be described.
This is four or more patches.
27/51 also sets rxq->fnav_enable in sxe2_queue.c, which is
unrelated to ACL statistics.
32/51 bundles four changes: tx_pkt_prepare_dummy, the NEON
simple/offload split, two debug logs, and the rx_free_thresh
default.
Other
27/51 is a new feature (acl-stat-type devarg) inside a fix
series and has no release notes. No patch in the series
touches doc/guides/rel_notes/.
15/51 sets RTE_ETH_RX_OFFLOAD_RSS_HASH twice: unconditionally,
then again under SXE2_DEV_CAPS_OFFLOAD_RSS. One is dead. The
same patch moves the PTP block below the IPsec block with no
effect.
14/51 sets dev_info->nb_rx_queues and nb_tx_queues, but
rte_eth_dev_info_get() overwrites both right after the PMD
callback (lib/ethdev/rte_ethdev.c:4146). Keep the
max_mac_addrs part, drop the queue counts.
Info
----
08/51 "vf" is passed as a %s argument; put it in the format
string. Keying the name on cdev->dev->name means two
PF ports on one PCI function would collide.
23/51 port_idx = UINT16_MAX is overwritten by the for loop.
25/51 rename left "sxe2_fnav_cid_mgr" in rte_zmalloc() and
"sxe2vf_fnav_cid_mgr" in a log message.
27/51 the ACL devarg is range checked against
SXE2_FNAV_STAT_ENA_*, and reuses the fnav req/resp
structs.
31/51 continuation lines in sxe2_rx_desc_ptype_fill_neon()
use tabs for alignment. DPDK uses tabs to indent and
spaces to align.
32/51 0x%016x on a uint32_t is misleading.
36/51 sxe2_drv_mac_link_status_get() now reaches into
rte_eth_devices[] and calls sxe2_link_update() from the
command channel. It is safe, but it inverts layering.
sxe2.ini lists only x86-32 and x86-64, although
sxe2_txrx_vec_neon.c is built on arm. Pre-existing, but this
series reworks NEON heavily.
Several commit messages justify a change as "matching the V3
implementation". Reviewers cannot see V3. Please state what
the code should do and why.
^ permalink raw reply [flat|nested] 207+ messages in thread
* [PATCH v4 00/44] net/sxe2: add Stars SXE2 net driver with fixes
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
@ 2026-08-27 2:36 ` liujie5
2026-08-27 15:14 ` Stephen Hemminger
2026-08-27 2:36 ` [PATCH v4 01/44] common/sxe2: fix null pointer in class driver remove liujie5
` (43 subsequent siblings)
44 siblings, 1 reply; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:36 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
This series adds the Stars SXE2 network driver together with a set of
fixes accumulated while validating the driver against the historical
kernel implementation and reviewing the code.
This is the v4 revision. Changes since v3 address the community review
of the v3 series:
- Drop the "probe all requested PF ports" change. rte_eth_dev_pci_allocate()
derives the port name from the PCI device and creates a single ethdev per
PCI device, so probing multiple PF ports from one probe call is not
supported.
- Fix RSS action attribute validation to return the negative error code
(-ENOTSUP) instead of a positive value so invalid RSS configurations are
rejected.
- Keep the packed attribute on sxe2_tm_add_mid_msg and
sxe2_tm_add_queue_msg so the firmware command wire offsets (tm info
offset, tm queue info offset) are preserved. Only drop the packed
attribute and padding from the structs that do not have it in the
historical kernel layout.
- Keep the "Receive Software Statistics" xstats documentation section.
The rx_sw_* counters are still accumulated in the Rx data path and
reported through rte_eth_xstats_get(); only the removed drv-sw-stats
devarg text is dropped.
- Consolidate fix-on-fix commits into the commits that introduced the
bugs so the series does not contain standalone fix patches for
regressions introduced earlier in the same series.
- Expand Fixes: hashes to the 12-character form and add the missing
Fixes: tags on patches carrying Cc: stable@dpdk.org.
- Drop a commit that only realigned code structure without any
functional change.
Jie Liu (44):
common/sxe2: fix null pointer in class driver remove
common/sxe2: allow munmap during kernel reset
net/sxe2: fix VF PCI device ID
net/sxe2: fix MSIX register width in PF map table
net/sxe2: restore pf and port index caps assignment
net/sxe2: fix VSI lifecycle management
net/sxe2: initialize stats in representor device init
net/sxe2: use base device name for representor naming
net/sxe2: propagate LSC event to VF representors
net/sxe2: validate IPsec key length against maximum limit
net/sxe2: rename representor VSI ID fields
net/sxe2: clean up duplicate function declarations
net/sxe2: fix null VSI dereference in device info
net/sxe2: fill MAC and queue counts in device info
net/sxe2: fix QinQ and RSS offload capability report
net/sxe2: use regular write for mapped registers
net/sxe2: move PCI register read macro to common header
net/sxe2: validate PCI map resource type
net/sxe2: guard PCI BAR unmap when not initialized
net/sxe2: fix null dereference in dev uninit
net/sxe2: fix duplicated cleanup in dev close
net/sxe2: align dev init and cleanup order
net/sxe2: simplify switchdev representor matching
net/sxe2: rename fnav cid manager symbols to flow
net/sxe2: move tunnel port helpers into flow module
net/sxe2: add ACL engine event statistics support
net/sxe2: guard Rx queue event FD free in unregister
net/sxe2: refactor primary process MP message handling
net/sxe2: refactor Tx queue reset operations
net/sxe2: unify vectorized Tx buffer handling
net/sxe2: refine vectorized Tx/Rx mode setup
net/sxe2: fix RSS action attribute validation
net/sxe2: restore PF-only guard in udp tunnel port add
net/sxe2: restore link update call in status query
net/sxe2: validate representor ID against VF count
net/sxe2: use primary VSI ID for representor VSI
net/sxe2: wrap command params fill debug log in macro
net/sxe2: restore Rx queue buffer split fill support
net/sxe2: skip tunnel config fill on get failure
net/sxe2: skip flow id assignment on filter add failure
net/sxe2: fix command channel log messages
net/sxe2: align command structs with historical kernel layout
common/sxe2: fix ioctl channel log and close handling
doc/sxe2: remove drv-sw-stats parameter documentation
doc/guides/nics/sxe2.rst | 40 ++--
drivers/common/sxe2/sxe2_common.c | 6 +-
drivers/common/sxe2/sxe2_ioctl_chnl.c | 18 +-
drivers/net/sxe2/sxe2_cmd_chnl.c | 200 ++++++++++++++++--
drivers/net/sxe2/sxe2_cmd_chnl.h | 15 +-
drivers/net/sxe2/sxe2_drv_cmd.h | 37 +++-
drivers/net/sxe2/sxe2_dump.c | 10 +-
drivers/net/sxe2/sxe2_ethdev.c | 188 ++++++++++-------
drivers/net/sxe2/sxe2_ethdev.h | 13 +-
drivers/net/sxe2/sxe2_ethdev_repr.c | 13 +-
drivers/net/sxe2/sxe2_flow.c | 234 ++++++++++++++++++---
drivers/net/sxe2/sxe2_flow.h | 6 +-
drivers/net/sxe2/sxe2_flow_define.h | 15 +-
drivers/net/sxe2/sxe2_flow_parse_action.c | 39 +++-
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ----------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 6 -
drivers/net/sxe2/sxe2_ipsec.c | 5 +
drivers/net/sxe2/sxe2_irq.c | 27 ++-
drivers/net/sxe2/sxe2_mac.c | 9 +-
drivers/net/sxe2/sxe2_mp.c | 59 +++---
drivers/net/sxe2/sxe2_queue.c | 2 +
drivers/net/sxe2/sxe2_queue.h | 7 +-
drivers/net/sxe2/sxe2_rx.c | 3 +-
drivers/net/sxe2/sxe2_security.c | 1 +
drivers/net/sxe2/sxe2_switchdev.c | 16 +-
drivers/net/sxe2/sxe2_tx.c | 42 +++-
drivers/net/sxe2/sxe2_tx.h | 4 +
drivers/net/sxe2/sxe2_txrx.c | 19 +-
drivers/net/sxe2/sxe2_txrx_poll.h | 2 -
drivers/net/sxe2/sxe2_txrx_vec.c | 73 +++----
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 133 +-----------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 9 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 219 ++++++++++++-------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
drivers/net/sxe2/sxe2_vsi.c | 8 +-
37 files changed, 941 insertions(+), 671 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 207+ messages in thread
* [PATCH v4 01/44] common/sxe2: fix null pointer in class driver remove
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
2026-08-27 2:36 ` [PATCH v4 00/44] net/sxe2: add Stars SXE2 net driver with fixes liujie5
@ 2026-08-27 2:36 ` liujie5
2026-08-27 2:36 ` [PATCH v4 02/44] common/sxe2: allow munmap during kernel reset liujie5
` (42 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:36 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_classes_driver_remove() calls cdrv->remove(cdev) without
checking whether cdrv or cdrv->remove is NULL. If the class driver
was never probed, cdev->cdrv remains NULL, and the unconditional
call dereferences a NULL pointer, crashing during device removal.
Add NULL checks for cdrv and cdrv->remove, returning 0 when either
is NULL.
Fixes: 83866f8d7638 ("common/sxe2: add base driver skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_common.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/common/sxe2/sxe2_common.c b/drivers/common/sxe2/sxe2_common.c
index 5c5db85f29..6e387a8a73 100644
--- a/drivers/common/sxe2/sxe2_common.c
+++ b/drivers/common/sxe2/sxe2_common.c
@@ -465,8 +465,12 @@ static int32_t sxe2_classes_driver_probe(struct sxe2_common_device *cdev,
static int32_t sxe2_classes_driver_remove(struct sxe2_common_device *cdev)
{
struct sxe2_class_driver *cdrv = cdev->cdrv;
+ int32_t ret = 0;
+
+ if (cdrv != NULL && cdrv->remove != NULL)
+ ret = cdrv->remove(cdev);
- return cdrv->remove(cdev);
+ return ret;
}
static int32_t sxe2_kvargs_validate(struct sxe2_dev_kvargs_info *kv_info)
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 02/44] common/sxe2: allow munmap during kernel reset
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
2026-08-27 2:36 ` [PATCH v4 00/44] net/sxe2: add Stars SXE2 net driver with fixes liujie5
2026-08-27 2:36 ` [PATCH v4 01/44] common/sxe2: fix null pointer in class driver remove liujie5
@ 2026-08-27 2:36 ` liujie5
2026-08-27 2:36 ` [PATCH v4 03/44] net/sxe2: fix VF PCI device ID liujie5
` (41 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:36 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_dev_munmap() refuses to unmap the BAR region when
cdev->config.kernel_reset is set, returning -EPERM. After a kernel
reset the application still needs to release the previously mapped
regions during cleanup; blocking munmap leaves stale mappings and
prevents a clean teardown.
Remove the kernel_reset check from sxe2_drv_dev_munmap() so the
mapping is always released. The cdev parameter is no longer used,
so mark it __rte_unused.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_ioctl_chnl.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index a233a78136..3e2fbf572f 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -367,16 +367,10 @@ void
RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_munmap)
int32_t
-sxe2_drv_dev_munmap(struct sxe2_common_device *cdev, void *virt, uint64_t len)
+sxe2_drv_dev_munmap(struct sxe2_common_device *cdev __rte_unused, void *virt, uint64_t len)
{
int32_t ret = 0;
- if (cdev->config.kernel_reset) {
- ret = -EPERM;
- PMD_LOG_WARN(COM, "kernel reset, need restart app.");
- goto l_end;
- }
-
PMD_LOG_DEBUG(COM, "Munmap virt=%p, len=0x%"PRIx64"",
virt, len);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 03/44] net/sxe2: fix VF PCI device ID
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (2 preceding siblings ...)
2026-08-27 2:36 ` [PATCH v4 02/44] common/sxe2: allow munmap during kernel reset liujie5
@ 2026-08-27 2:36 ` liujie5
2026-08-27 2:36 ` [PATCH v4 04/44] net/sxe2: fix MSIX register width in PF map table liujie5
` (40 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:36 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The VF PCI device ID is defined as 0x10b2 per the hardware specification,
but the code incorrectly uses 0x10b.
As a result, the VF driver never binds to the device, making VF
functionality completely unusable.
Fix this by changing SXE2_PCI_DEVICE_ID_VF_1 from 0x10b to 0x10b2.
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 8bbfdc3a15..ec376b76dc 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -44,7 +44,7 @@
#define SXE2_PCI_VENDOR_ID_1 0x1ff2
#define SXE2_PCI_DEVICE_ID_PF_1 0x10b1
-#define SXE2_PCI_DEVICE_ID_VF_1 0x10b
+#define SXE2_PCI_DEVICE_ID_VF_1 0x10b2
#define SXE2_PCI_VENDOR_ID_2 0x1d94
#define SXE2_PCI_DEVICE_ID_PF_2 0x1260
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 04/44] net/sxe2: fix MSIX register width in PF map table
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (3 preceding siblings ...)
2026-08-27 2:36 ` [PATCH v4 03/44] net/sxe2: fix VF PCI device ID liujie5
@ 2026-08-27 2:36 ` liujie5
2026-08-27 2:36 ` [PATCH v4 05/44] net/sxe2: restore pf and port index caps assignment liujie5
` (39 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:36 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The MSIX entry in sxe2_net_map_addr_info_pf sets a register width
of 10 (decimal), but each PCIe MSIX table entry is 16 bytes (0x10).
The VF map table already uses 0x10.
Since reg_width is used as the stride between MSIX entries in
sxe2_dev_pci_seg_map(), the wrong value makes the mapped region too
short and places the entries at incorrect offsets.
Change .reg_width from 10 to 0x10 for the SXE2_PCI_MAP_RES_IRQ_MSIX
entry to match the VF table.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index ec376b76dc..5d8cfca6cf 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -94,7 +94,7 @@ static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_pf[SXE2_PCI_MAP_RES_
.reg_width = 4},
[SXE2_PCI_MAP_RES_IRQ_MSIX] = {.addr_base = SXE2_BAR4_MSIX_CTL(0),
.bar_idx = 4,
- .reg_width = 10},
+ .reg_width = 0x10},
};
static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_vf[SXE2_PCI_MAP_RES_MAX_COUNT] = {
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 05/44] net/sxe2: restore pf and port index caps assignment
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (4 preceding siblings ...)
2026-08-27 2:36 ` [PATCH v4 04/44] net/sxe2: fix MSIX register width in PF map table liujie5
@ 2026-08-27 2:36 ` liujie5
2026-08-27 2:36 ` [PATCH v4 06/44] net/sxe2: fix VSI lifecycle management liujie5
` (38 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:36 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_func_caps_get() never assigns adapter->pf_idx from the device
capabilities, leaving it at its zero-initialized value. Switchdev
requests and representor setup that use pf_idx then report the wrong
PF index on multi-PF configurations.
Restore the pf_idx and port_idx assignments in sxe2_func_caps_get()
and drop the now-redundant port_idx assignment from
sxe2_drv_dev_caps_set().
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 5d8cfca6cf..2e14c372f8 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1284,8 +1284,6 @@ void sxe2_eth_uinit(struct rte_eth_dev *dev __rte_unused)
static void sxe2_drv_dev_caps_set(struct sxe2_adapter *adapter,
struct sxe2_drv_dev_caps_resp *dev_caps)
{
- adapter->port_idx = dev_caps->port_idx;
-
adapter->cap_flags = 0;
if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_L2)
@@ -1344,6 +1342,8 @@ static int32_t sxe2_func_caps_get(struct sxe2_adapter *adapter)
goto l_end;
adapter->dev_type = dev_caps.dev_type;
+ adapter->port_idx = dev_caps.port_idx;
+ adapter->pf_idx = dev_caps.pf_idx;
sxe2_drv_dev_caps_set(adapter, &dev_caps);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 06/44] net/sxe2: fix VSI lifecycle management
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (5 preceding siblings ...)
2026-08-27 2:36 ` [PATCH v4 05/44] net/sxe2: restore pf and port index caps assignment liujie5
@ 2026-08-27 2:36 ` liujie5
2026-08-27 2:37 ` [PATCH v4 07/44] net/sxe2: initialize stats in representor device init liujie5
` (37 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:36 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Fix several VSI create/destroy issues introduced by VF representor
support:
- Initialize other_vsi_list with TAILQ_INIT in sxe2_vsi_init before
any VSI is inserted into it.
- Treat -EPERM as a non-fatal error when destroying VSIs, since the
kernel may have already removed the VSI.
- Set main_vsi to NULL after destroy/free to avoid a dangling pointer
if the VSI is destroyed again.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_vsi.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_vsi.c b/drivers/net/sxe2/sxe2_vsi.c
index d29480b931..ba4cc7414e 100644
--- a/drivers/net/sxe2/sxe2_vsi.c
+++ b/drivers/net/sxe2/sxe2_vsi.c
@@ -230,7 +230,7 @@ int32_t sxe2_vsi_init(struct rte_eth_dev *dev)
uint16_t srcvsi_cnt;
PMD_INIT_FUNC_TRACE();
-
+ TAILQ_INIT(&adapter->vsi_ctxt.other_vsi_list);
ret = sxe2_main_vsi_create(adapter);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to create main VSI, ret=%d", ret);
@@ -283,13 +283,14 @@ void sxe2_vsi_uninit(struct rte_eth_dev *dev)
l_free:
ret = sxe2_vsi_destroy(adapter, adapter->vsi_ctxt.main_vsi);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
goto l_end;
}
+ adapter->vsi_ctxt.main_vsi = NULL;
RTE_TAILQ_FOREACH_SAFE(var, &adapter->vsi_ctxt.other_vsi_list, next, tvar) {
ret = sxe2_vsi_destroy(adapter, var);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
break;
}
@@ -357,4 +358,5 @@ void sxe2_vsi_repr_main_vsi_destroy(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
sxe2_vsi_node_free(adapter->vsi_ctxt.main_vsi);
+ adapter->vsi_ctxt.main_vsi = NULL;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 07/44] net/sxe2: initialize stats in representor device init
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (6 preceding siblings ...)
2026-08-27 2:36 ` [PATCH v4 06/44] net/sxe2: fix VSI lifecycle management liujie5
@ 2026-08-27 2:37 ` liujie5
2026-08-27 2:37 ` [PATCH v4 08/44] net/sxe2: use base device name for representor naming liujie5
` (36 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add sxe2_stats_init() call in sxe2_repr_dev_init to set up the
statistics infrastructure for representor devices, and add the
l_init_irq_ctxt_err error path to uninitialize the software irq
context if stats initialization fails.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev_repr.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index f32318b731..c698baafe0 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -483,8 +483,16 @@ int32_t sxe2_repr_dev_init(struct rte_eth_dev *dev,
goto l_init_sw_err;
}
+ ret = sxe2_stats_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize stats, ret=[%d]", ret);
+ goto l_init_irq_ctxt_err;
+ }
+
goto l_end;
+l_init_irq_ctxt_err:
+ sxe2_sw_irq_ctxt_uninit(dev);
l_init_sw_err:
sxe2_eth_uinit(dev);
l_init_eth_err:
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 08/44] net/sxe2: use base device name for representor naming
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (7 preceding siblings ...)
2026-08-27 2:37 ` [PATCH v4 07/44] net/sxe2: initialize stats in representor device init liujie5
@ 2026-08-27 2:37 ` liujie5
2026-08-27 2:37 ` [PATCH v4 09/44] net/sxe2: propagate LSC event to VF representors liujie5
` (35 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Update the representor device naming to use the base device name
prefix, and set the numa_node from the parent device data so that
representor devices are allocated on the same NUMA node.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev_repr.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index c698baafe0..b7096f5927 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -552,8 +552,8 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
}
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- snprintf(name, sizeof(name), "sxe2_representor_c%dpf%d%s%u",
- adapter->pf_idx, adapter->pf_idx,
+ snprintf(name, sizeof(name), "%s_representor_%s%u",
+ adapter->cdev->dev->name,
"vf",
req_eth_da->representor_ports[repr_idx]);
@@ -562,6 +562,7 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
ret = -ENOMEM;
goto l_release_port;
}
+ eth_dev->data->numa_node = adapter->dev_info.dev_data->numa_node;
eth_dev->data->dev_private = rte_zmalloc_socket(name,
sizeof(struct sxe2_adapter),
RTE_CACHE_LINE_SIZE,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 09/44] net/sxe2: propagate LSC event to VF representors
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (8 preceding siblings ...)
2026-08-27 2:37 ` [PATCH v4 08/44] net/sxe2: use base device name for representor naming liujie5
@ 2026-08-27 2:37 ` liujie5
2026-08-27 2:37 ` [PATCH v4 10/44] net/sxe2: validate IPsec key length against maximum limit liujie5
` (34 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
When the PF link state changes in switchdev mode, refresh the link
status of every VF representor and trigger the RTE_ETH_EVENT_INTR_LSC
callback on each, so applications receive link events on representor
ports. Also log OICR in hexadecimal for better readability.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index 3306504761..ba764dd5e4 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -77,14 +77,32 @@ static int32_t sxe2_fc_state_callback(struct rte_eth_dev *dev)
static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t oicr)
{
struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
+ struct rte_eth_dev *repr_eth_dev;
+ struct sxe2_adapter *repr_adapter;
+ uint16_t vf_id;
if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
- PMD_DEV_LOG_INFO(adapter, DRV, "OICR=%" PRIu64, oicr);
+ PMD_DEV_LOG_INFO(adapter, DRV, "OICR=0x%" PRIx64, oicr);
(void)sxe2_drv_mac_link_status_get(adapter);
- if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_LSC,
NULL);
+ }
+ if (adapter->switchdev_info.is_switchdev) {
+ for (vf_id = 0; vf_id < adapter->repr_ctxt.nb_repr_vf; vf_id++) {
+ repr_eth_dev = adapter->repr_ctxt.vf_rep_eth_dev[vf_id];
+ if (!repr_eth_dev)
+ continue;
+ repr_adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(repr_eth_dev);
+ (void)sxe2_drv_mac_link_status_get(repr_adapter);
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ rte_eth_dev_callback_process(repr_eth_dev,
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL);
+ }
+ }
+ }
}
if (oicr & RTE_BIT32(SXE2_COM_SW_MODE_SWITCHDEV)) {
PMD_DEV_LOG_INFO(adapter, DRV, "event notify switchdev");
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 10/44] net/sxe2: validate IPsec key length against maximum limit
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (9 preceding siblings ...)
2026-08-27 2:37 ` [PATCH v4 09/44] net/sxe2: propagate LSC event to VF representors liujie5
@ 2026-08-27 2:37 ` liujie5
2026-08-27 2:37 ` [PATCH v4 11/44] net/sxe2: rename representor VSI ID fields liujie5
` (33 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add validation in sxe2_security_valid_key to ensure the source key
length does not exceed SXE2_IPSEC_MAX_KEY_LEN, preventing potential
buffer overflows when processing keys longer than the supported
maximum. Also clear the security context pointer after releasing the
security session during uninit.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ipsec.c | 5 +++++
drivers/net/sxe2/sxe2_security.c | 1 +
2 files changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ipsec.c b/drivers/net/sxe2/sxe2_ipsec.c
index e783a51b85..622fd1adfe 100644
--- a/drivers/net/sxe2/sxe2_ipsec.c
+++ b/drivers/net/sxe2/sxe2_ipsec.c
@@ -254,6 +254,11 @@ static bool sxe2_security_valid_key(uint16_t src_key, uint16_t max_key,
goto l_end;
}
+ if (src_key > SXE2_IPSEC_MAX_KEY_LEN) {
+ is_valid = false;
+ goto l_end;
+ }
+
is_valid = true;
l_end:
diff --git a/drivers/net/sxe2/sxe2_security.c b/drivers/net/sxe2/sxe2_security.c
index bc59d1b880..8f31067942 100644
--- a/drivers/net/sxe2/sxe2_security.c
+++ b/drivers/net/sxe2/sxe2_security.c
@@ -326,6 +326,7 @@ void sxe2_security_uinit(struct rte_eth_dev *dev)
if (sctx != NULL) {
rte_free(sctx);
sctx = NULL;
+ dev->security_ctx = NULL;
}
sxe2_ipsec_uinit(adapter);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 11/44] net/sxe2: rename representor VSI ID fields
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (10 preceding siblings ...)
2026-08-27 2:37 ` [PATCH v4 10/44] net/sxe2: validate IPsec key length against maximum limit liujie5
@ 2026-08-27 2:37 ` liujie5
2026-08-27 2:37 ` [PATCH v4 12/44] net/sxe2: clean up duplicate function declarations liujie5
` (32 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Rename repr_vf_k_vsi_id/repr_vf_u_vsi_id to
repr_vf_primary_vsi_id/repr_vf_backup_vsi_id in
sxe2_repr_private_data and update all references.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_dump.c | 8 ++++----
drivers/net/sxe2/sxe2_ethdev.h | 4 ++--
drivers/net/sxe2/sxe2_flow.c | 4 ++--
drivers/net/sxe2/sxe2_switchdev.c | 4 ++--
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index d43473e083..590219f502 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -211,16 +211,16 @@ sxe2_dump_switchdev_info(FILE *file, struct rte_eth_dev *dev)
"\t -- repr_pf_id: %u\n"
"\t -- repr_vf_id: %u\n"
"\t -- repr_vf_vsi_id: %u\n"
- "\t -- repr_vf_k_vsi_id: %s\n"
- "\t -- repr_vf_u_vsi_id: %s\n",
+ "\t -- repr_vf_primary_vsi_id: %s\n"
+ "\t -- repr_vf_backup_vsi_id: %s\n",
adapter->repr_priv_data->repr_id,
adapter->repr_priv_data->repr_q_id,
adapter->repr_priv_data->repr_pf_id,
adapter->repr_priv_data->repr_vf_id,
adapter->repr_priv_data->repr_vf_vsi_id,
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_k_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_primary_vsi_id,
k_vsi_buf, sizeof(k_vsi_buf)),
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_u_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_backup_vsi_id,
u_vsi_buf, sizeof(u_vsi_buf)));
goto l_end;
}
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index c54e8a435e..158198d74b 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -263,8 +263,8 @@ struct sxe2_repr_private_data {
uint16_t repr_pf_id;
uint16_t repr_vf_id;
uint16_t repr_vf_vsi_id;
- uint16_t repr_vf_k_vsi_id;
- uint16_t repr_vf_u_vsi_id;
+ uint16_t repr_vf_primary_vsi_id;
+ uint16_t repr_vf_backup_vsi_id;
};
struct sxe2_sched_hw_cap {
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index 63cfc36968..cf54803301 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -380,9 +380,9 @@ static int32_t sxe2_flow_src_split_proc(struct rte_eth_dev *dev,
if (adapter->switchdev_info.is_switchdev && adapter->is_dev_repr) {
flow_bond_num = 1;
flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] =
- adapter->repr_priv_data->repr_vf_u_vsi_id;
+ adapter->repr_priv_data->repr_vf_backup_vsi_id;
flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] =
- adapter->repr_priv_data->repr_vf_k_vsi_id;
+ adapter->repr_priv_data->repr_vf_primary_vsi_id;
}
for (idx = 0; idx < flow_bond_num; idx++) {
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index 44703cfb5c..efb1468b91 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -312,9 +312,9 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_q_id = repr_id;
repr_priv_data->repr_pf_id = parent_adapter->pf_idx;
repr_priv_data->repr_vf_id = repr_id;
- repr_priv_data->repr_vf_k_vsi_id =
+ repr_priv_data->repr_vf_primary_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
- repr_priv_data->repr_vf_u_vsi_id =
+ repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
repr_priv_data->repr_vf_vsi_id =
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 12/44] net/sxe2: clean up duplicate function declarations
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (11 preceding siblings ...)
2026-08-27 2:37 ` [PATCH v4 11/44] net/sxe2: rename representor VSI ID fields liujie5
@ 2026-08-27 2:37 ` liujie5
2026-08-27 2:37 ` [PATCH v4 13/44] net/sxe2: fix null VSI dereference in device info liujie5
` (31 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Remove duplicate function declarations from the sxe2 driver headers:
- sxe2_drv_promisc_config, sxe2_drv_vsi_info_get and
sxe2_drv_rxq_mapping_set in sxe2_cmd_chnl.h
- sxe2_dev_pci_seg_unmap in sxe2_ethdev.h
- sxe2_rx_pkts_scattered in sxe2_txrx_poll.h
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.h | 6 ------
drivers/net/sxe2/sxe2_ethdev.h | 2 --
drivers/net/sxe2/sxe2_txrx_poll.h | 2 --
3 files changed, 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index d63caad526..294ac15db4 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -65,8 +65,6 @@ int32_t sxe2_drv_ipsec_rxsa_delete(struct sxe2_adapter *adapter,
int32_t sxe2_drv_ipsec_txsa_delete(struct sxe2_adapter *adapter,
uint16_t sa_id);
-int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set);
-
int32_t sxe2_drv_udp_tunnel_add(struct sxe2_adapter *adapter,
enum sxe2_udp_tunnel_protocol tunnel_proto,
uint16_t udp_port);
@@ -84,8 +82,6 @@ int32_t sxe2_drv_get_udp_tunnel_port(struct sxe2_adapter *adapter,
int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-
int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter);
int32_t sxe2_drv_get_mac_stats(struct sxe2_adapter *adapter);
@@ -110,8 +106,6 @@ int32_t sxe2_drv_mapping_reset(struct rte_eth_dev *eth_dev);
int32_t sxe2_drv_mapping_stats_info_clear(struct rte_eth_dev *eth_dev);
-int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t pool_idx);
-
int32_t sxe2_drv_allmulti_config(struct sxe2_adapter *adapter, bool set);
int32_t sxe2_drv_uc_config(struct sxe2_adapter *adapter, struct rte_ether_addr *addr, bool add);
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 158198d74b..1409be74d3 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -385,8 +385,6 @@ void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
int32_t sxe2_dev_pci_map_init(struct rte_eth_dev *dev);
-void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
-
int32_t sxe2_udp_tunnel_port_del_common(struct sxe2_adapter *ad,
enum sxe2_udp_tunnel_protocol tunnel_proto, uint16_t udp_port);
diff --git a/drivers/net/sxe2/sxe2_txrx_poll.h b/drivers/net/sxe2/sxe2_txrx_poll.h
index 708e3839d7..bfa099c097 100644
--- a/drivers/net/sxe2/sxe2_txrx_poll.h
+++ b/drivers/net/sxe2/sxe2_txrx_poll.h
@@ -13,8 +13,6 @@ uint16_t sxe2_tx_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t
uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-
uint16_t sxe2_rx_pkts_scattered_split(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
#endif /* SXE2_TXRX_POLL_H */
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 13/44] net/sxe2: fix null VSI dereference in device info
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (12 preceding siblings ...)
2026-08-27 2:37 ` [PATCH v4 12/44] net/sxe2: clean up duplicate function declarations liujie5
@ 2026-08-27 2:37 ` liujie5
2026-08-27 2:37 ` [PATCH v4 14/44] net/sxe2: fill MAC and queue counts " liujie5
` (30 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_infos_get() dereferences adapter->vsi_ctxt.main_vsi without
checking for NULL, which can crash when the main VSI has not been
created yet.
Add an early NULL check on vsi and return -EINVAL.
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 2e14c372f8..02f9ce3d32 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -781,6 +781,10 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
+ if (unlikely(vsi == NULL)) {
+ PMD_LOG_ERR(INIT, "main vsi is NULL");
+ return -EINVAL;
+ }
dev_info->max_rx_queues = vsi->rxqs.q_cnt;
dev_info->max_tx_queues = vsi->txqs.q_cnt;
dev_info->min_rx_bufsize = SXE2_MIN_BUF_SIZE;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 14/44] net/sxe2: fill MAC and queue counts in device info
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (13 preceding siblings ...)
2026-08-27 2:37 ` [PATCH v4 13/44] net/sxe2: fix null VSI dereference in device info liujie5
@ 2026-08-27 2:37 ` liujie5
2026-08-27 2:37 ` [PATCH v4 15/44] net/sxe2: fix QinQ and RSS offload capability report liujie5
` (29 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Fill max_mac_addrs, nb_rx_queues and nb_tx_queues in
sxe2_dev_infos_get() so applications can query the maximum number of
MAC addresses and the queue counts.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 02f9ce3d32..e85dee6b2c 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -792,6 +792,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->max_lro_pkt_size = SXE2_FRAME_SIZE_MAX * SXE2_RX_LRO_DESC_MAX_NUM;
dev_info->max_mtu = dev_info->max_rx_pktlen - SXE2_ETH_OVERHEAD;
dev_info->min_mtu = RTE_ETHER_MIN_MTU;
+ dev_info->max_mac_addrs = SXE2_NUM_MACADDR_MAX;
dev_info->rx_offload_capa =
RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
@@ -912,6 +913,8 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->speed_capa = RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G |
RTE_ETH_LINK_SPEED_50G | RTE_ETH_LINK_SPEED_100G;
+ dev_info->nb_rx_queues = dev->data->nb_rx_queues;
+ dev_info->nb_tx_queues = dev->data->nb_tx_queues;
dev_info->default_rxportconf.burst_size = SXE2_RX_MAX_BURST;
dev_info->default_txportconf.burst_size = SXE2_TX_MAX_BURST;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 15/44] net/sxe2: fix QinQ and RSS offload capability report
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (14 preceding siblings ...)
2026-08-27 2:37 ` [PATCH v4 14/44] net/sxe2: fill MAC and queue counts " liujie5
@ 2026-08-27 2:37 ` liujie5
2026-08-27 2:37 ` [PATCH v4 16/44] net/sxe2: use regular write for mapped registers liujie5
` (28 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Make the QINQ offload capabilities conditional on the port VLAN
setting: only advertise RTE_ETH_TX_OFFLOAD_QINQ_INSERT,
RTE_ETH_RX_OFFLOAD_QINQ_STRIP and RTE_ETH_RX_OFFLOAD_VLAN_FILTER
when no port VLAN is configured. Advertise RTE_ETH_RX_OFFLOAD_RSS_HASH
unconditionally and report the buffer split supported header ptypes
count in sxe2_buffer_split_supported_hdr_ptypes_get().
Fixes: a2b79a93515e ("net/sxe2: support L2 filtering and MAC config")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index e85dee6b2c..fb7f14fd44 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -804,11 +804,9 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_RX_OFFLOAD_SCTP_CKSUM |
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT |
-#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
- RTE_ETH_RX_OFFLOAD_QINQ_STRIP |
-#endif
RTE_ETH_RX_OFFLOAD_VLAN_EXTEND |
- RTE_ETH_RX_OFFLOAD_TCP_LRO;
+ RTE_ETH_RX_OFFLOAD_TCP_LRO |
+ RTE_ETH_RX_OFFLOAD_RSS_HASH;
dev_info->tx_offload_capa =
RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
@@ -855,14 +853,22 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
- if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
- dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
-
if (sxe2_ipsec_supported(adapter)) {
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
}
+ if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
+
+ if (!sxe2_dev_port_vlan_check(dev)) {
+ dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
+#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
+#endif
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
+ }
+
if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_RSS) {
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
dev_info->flow_type_rss_offloads |= SXE2_RSS_HF_SUPPORT_ALL;
@@ -936,7 +942,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
static const uint32_t *
sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
- size_t *no_of_elements __rte_unused)
+ size_t *no_of_elements)
{
static const uint32_t ptypes[] = {
RTE_PTYPE_L2_ETHER,
@@ -974,6 +980,7 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
RTE_PTYPE_UNKNOWN
};
+ *no_of_elements = RTE_DIM(ptypes) - 1;
return ptypes;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 16/44] net/sxe2: use regular write for mapped registers
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (15 preceding siblings ...)
2026-08-27 2:37 ` [PATCH v4 15/44] net/sxe2: fix QinQ and RSS offload capability report liujie5
@ 2026-08-27 2:37 ` liujie5
2026-08-27 2:37 ` [PATCH v4 17/44] net/sxe2: move PCI register read macro to common header liujie5
` (27 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_pci_map_write_reg() uses the write-combined store
(SXE2_PCI_REG_WRITE_WC) to write control registers, which is intended
for doorbell/tail writes and can be lossy or delayed for ordering
sensitive register updates.
Add SXE2_PCI_REG_WRITE macro using a regular rte_write32() and use it
in sxe2_pci_map_write_reg().
Fixes: 8cebf80f1eda ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
drivers/net/sxe2/sxe2_ethdev.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index fb7f14fd44..96b437c6a9 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1443,7 +1443,7 @@ void sxe2_pci_map_write_reg(struct sxe2_adapter *adapter,
goto l_ret;
}
- SXE2_PCI_REG_WRITE_WC(reg_addr, value);
+ SXE2_PCI_REG_WRITE(reg_addr, value);
l_ret:
return;
}
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 1409be74d3..cf1104144c 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -355,6 +355,8 @@ struct sxe2_adapter {
#define SXE2_DEV_PRIVATE_TO_ADAPTER(dev) \
((struct sxe2_adapter *)(dev)->data->dev_private)
+#define SXE2_PCI_REG_WRITE(reg, value) rte_write32((rte_cpu_to_le_32(value)), (reg))
+
void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
enum sxe2_pci_map_resource res_type,
uint16_t idx_in_func);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 17/44] net/sxe2: move PCI register read macro to common header
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (16 preceding siblings ...)
2026-08-27 2:37 ` [PATCH v4 16/44] net/sxe2: use regular write for mapped registers liujie5
@ 2026-08-27 2:37 ` liujie5
2026-08-27 2:38 ` [PATCH v4 18/44] net/sxe2: validate PCI map resource type liujie5
` (26 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move SXE2_PCI_REG_READ to sxe2_ethdev.h so the PCI register access
macros are kept together in the common header, matching
SXE2_PCI_REG_WRITE.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_queue.h | 2 --
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index cf1104144c..f2557b28c3 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -356,6 +356,7 @@ struct sxe2_adapter {
((struct sxe2_adapter *)(dev)->data->dev_private)
#define SXE2_PCI_REG_WRITE(reg, value) rte_write32((rte_cpu_to_le_32(value)), (reg))
+#define SXE2_PCI_REG_READ(reg) rte_read32(reg)
void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
enum sxe2_pci_map_resource res_type,
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index a300b66771..10bdaf5b8d 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -12,8 +12,6 @@
#include "sxe2_drv_cmd.h"
#include "sxe2_txrx_common.h"
-#define SXE2_PCI_REG_READ(reg) \
- rte_read32(reg)
#define SXE2_PCI_REG_WRITE_WC(reg, value) \
rte_write32_wc((rte_cpu_to_le_32(value)), reg)
#define SXE2_PCI_REG_WRITE_WC_RELAXED(reg, value) \
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 18/44] net/sxe2: validate PCI map resource type
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (17 preceding siblings ...)
2026-08-27 2:37 ` [PATCH v4 17/44] net/sxe2: move PCI register read macro to common header liujie5
@ 2026-08-27 2:38 ` liujie5
2026-08-27 2:38 ` [PATCH v4 19/44] net/sxe2: guard PCI BAR unmap when not initialized liujie5
` (25 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_pci_res_seg_map() indexes adapter->map_ctxt.addr_info[] with
res_type without bounds checking, which can access out of bounds when
an invalid resource type is passed.
Add a bounds check on res_type and return -EINVAL.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 96b437c6a9..7646f6b309 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1556,6 +1556,12 @@ int32_t sxe2_dev_pci_res_seg_map(struct sxe2_adapter *adapter,
struct sxe2_pci_map_addr_info *addr_info = NULL;
int32_t ret = 0;
+ if (unlikely(res_type >= SXE2_PCI_MAP_RES_MAX_COUNT)) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Invalid resource type %u", res_type);
+ ret = -EINVAL;
+ goto l_end;
+ }
+
addr_info = &adapter->map_ctxt.addr_info[res_type];
if (!addr_info || addr_info->bar_idx == SXE2_PCI_MAP_BAR_INVALID) {
PMD_DEV_LOG_ERR(adapter, INIT, "Invalid bar index with resource type %d", res_type);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 19/44] net/sxe2: guard PCI BAR unmap when not initialized
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (18 preceding siblings ...)
2026-08-27 2:38 ` [PATCH v4 18/44] net/sxe2: validate PCI map resource type liujie5
@ 2026-08-27 2:38 ` liujie5
2026-08-27 2:38 ` [PATCH v4 20/44] net/sxe2: fix null dereference in dev uninit liujie5
` (24 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_pci_map_uinit() calls sxe2_dev_pci_seg_unmap() and walks
bar_info unconditionally. Only perform the unmap and free when
bar_info has been allocated, so an uninitialized map context is
handled cleanly.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 7646f6b309..05a57548e7 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1777,14 +1777,13 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
uint8_t i = 0;
PMD_INIT_FUNC_TRACE();
+ if (map_ctxt->bar_info != NULL) {
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
-
- if (map_ctxt != NULL && map_ctxt->bar_info != NULL) {
for (i = 0; i < map_ctxt->bar_cnt; i++) {
bar_info = &map_ctxt->bar_info[i];
if (bar_info != NULL && bar_info->seg_info != NULL) {
@@ -1795,7 +1794,6 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
rte_free(map_ctxt->bar_info);
map_ctxt->bar_info = NULL;
}
-
adapter->dev_info.dev_data = NULL;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 20/44] net/sxe2: fix null dereference in dev uninit
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (19 preceding siblings ...)
2026-08-27 2:38 ` [PATCH v4 19/44] net/sxe2: guard PCI BAR unmap when not initialized liujie5
@ 2026-08-27 2:38 ` liujie5
2026-08-27 2:38 ` [PATCH v4 21/44] net/sxe2: fix duplicated cleanup in dev close liujie5
` (23 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_uninit() calls rep_dev->dev_ops->dev_close() for each VF
representor without checking that dev_ops or dev_close is present,
which can crash when the representor device is not fully initialized.
Guard the call with NULL checks.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 05a57548e7..6222a319af 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2078,9 +2078,11 @@ static int32_t sxe2_dev_uninit(struct rte_eth_dev *dev)
for (i = 0; i < adapter->repr_ctxt.nb_repr_vf; i++) {
rep_dev = adapter->repr_ctxt.vf_rep_eth_dev[i];
if (rep_dev) {
- ret = rep_dev->dev_ops->dev_close(rep_dev);
- if (ret)
- goto l_end;
+ if (rep_dev->dev_ops && rep_dev->dev_ops->dev_close) {
+ ret = rep_dev->dev_ops->dev_close(rep_dev);
+ if (ret)
+ goto l_end;
+ }
if (rep_dev->intr_handle)
rte_intr_instance_free(rep_dev->intr_handle);
ret = rte_eth_dev_release_port(rep_dev);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 21/44] net/sxe2: fix duplicated cleanup in dev close
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (20 preceding siblings ...)
2026-08-27 2:38 ` [PATCH v4 20/44] net/sxe2: fix null dereference in dev uninit liujie5
@ 2026-08-27 2:38 ` liujie5
2026-08-27 2:38 ` [PATCH v4 22/44] net/sxe2: align dev init and cleanup order liujie5
` (22 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_close() calls sxe2_switchdev_uninit() and
sxe2_dev_pci_map_uinit() twice, and releases resources in an order
that does not match the initialization sequence.
Remove the duplicated calls and align the teardown order with the
device init order.
Fixes: 8cebf80f1eda ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 6222a319af..1ffaf9cb9f 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2045,17 +2045,15 @@ static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
(void)sxe2_queues_release(dev);
sxe2_mp_uninit(dev);
(void)sxe2_sched_uinit(dev);
- (void)sxe2_rss_disable(dev);
(void)sxe2_flow_uninit(dev);
+ (void)sxe2_rss_disable(dev);
(void)sxe2_udp_tunnel_port_clear(dev);
- sxe2_vsi_uninit(dev);
sxe2_security_uinit(dev);
sxe2_intr_uninit(dev);
(void)sxe2_switchdev_uninit(dev);
sxe2_sw_uninit(dev);
- (void)sxe2_switchdev_uninit(dev);
- sxe2_dev_pci_map_uinit(dev);
sxe2_eth_uinit(dev);
+ sxe2_vsi_uninit(dev);
sxe2_dev_pci_map_uinit(dev);
sxe2_free_repr_info(dev);
sxe2_fc_state_uinit(dev);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 22/44] net/sxe2: align dev init and cleanup order
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (21 preceding siblings ...)
2026-08-27 2:38 ` [PATCH v4 21/44] net/sxe2: fix duplicated cleanup in dev close liujie5
@ 2026-08-27 2:38 ` liujie5
2026-08-27 2:38 ` [PATCH v4 23/44] net/sxe2: simplify switchdev representor matching liujie5
` (21 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move sxe2_eth_init() to be called before sxe2_sw_init() and
rearrange the error cleanup labels so that resources are torn down
in the reverse order of initialization.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 1ffaf9cb9f..72aae84ae3 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1946,6 +1946,12 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_switchdev_err;
}
+ ret = sxe2_eth_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
+ goto init_eth_err;
+ }
+
ret = sxe2_sw_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize sw parameters, ret=[%d]", ret);
@@ -1958,12 +1964,6 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_irq_err;
}
- ret = sxe2_eth_init(dev);
- if (ret) {
- PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
- goto init_eth_err;
- }
-
ret = sxe2_security_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize security, ret=%d", ret);
@@ -2018,12 +2018,12 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
init_rss_err:
sxe2_security_uinit(dev);
init_security_err:
- sxe2_eth_uinit(dev);
-init_eth_err:
sxe2_intr_uninit(dev);
init_irq_err:
sxe2_sw_uninit(dev);
init_sw_err:
+ sxe2_eth_uinit(dev);
+init_eth_err:
(void)sxe2_switchdev_uninit(dev);
init_switchdev_err:
init_dev_info_err:
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 23/44] net/sxe2: simplify switchdev representor matching
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (22 preceding siblings ...)
2026-08-27 2:38 ` [PATCH v4 22/44] net/sxe2: align dev init and cleanup order liujie5
@ 2026-08-27 2:38 ` liujie5
2026-08-27 2:38 ` [PATCH v4 24/44] net/sxe2: rename fnav cid manager symbols to flow liujie5
` (20 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_switchdev_repr_match() encodes the kernel representor ID and
compares it against each requested port, which is fragile. Match the
PF number and VF ID directly against the switchdev representor info
instead, and drop the sxe2_switchdev_repr_id_encode_get() helper.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 70 +++++++++++++++++-----------------
drivers/net/sxe2/sxe2_ethdev.h | 3 --
2 files changed, 35 insertions(+), 38 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 72aae84ae3..7ba73aea6f 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2153,42 +2153,25 @@ static int32_t sxe2_fw_version_string_get(struct rte_eth_dev *dev, char *fw_vers
return ret;
}
-static uint16_t sxe2_switchdev_repr_id_encode_get(struct sxe2_switchdev_info *switchdev_info)
-{
- enum rte_eth_representor_type type;
- uint16_t repr = switchdev_info->vf_num;
- uint32_t pf = switchdev_info->pf_num;
-
- switch (switchdev_info->port_name_type) {
- case SXE2_PHYS_PORT_NAME_TYPE_UPLINK:
- if (!switchdev_info->representor)
- return UINT16_MAX;
- type = RTE_ETH_REPRESENTOR_PF;
- pf = switchdev_info->mpesw_owner;
- break;
- case SXE2_PHYS_PORT_NAME_TYPE_PFVF:
- default:
- type = RTE_ETH_REPRESENTOR_VF;
- break;
- }
-
- return SXE2_REPRESENTOR_ID(pf, type, repr);
-}
-
static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
struct rte_eth_devargs *req_eth_da)
{
- uint32_t port_idx = 0;
- uint32_t repr_idx;
- uint16_t kernel_repr_id = sxe2_switchdev_repr_id_encode_get(&adapter->switchdev_info);
- uint16_t repr_id;
+ uint16_t port_idx = UINT16_MAX;
+ uint16_t repr_idx;
+ uint16_t vf_id;
+ uint16_t i;
switch (req_eth_da->type) {
case RTE_ETH_REPRESENTOR_PF:
+ if (adapter->switchdev_info.port_name_type !=
+ SXE2_PHYS_PORT_NAME_TYPE_UPLINK) {
+ rte_errno = EBUSY;
+ return false;
+ }
break;
case RTE_ETH_REPRESENTOR_VF:
if (adapter->switchdev_info.port_name_type !=
- SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
+ SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
rte_errno = EBUSY;
return false;
}
@@ -2201,15 +2184,32 @@ static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
return false;
}
+ for (port_idx = 0; port_idx < req_eth_da->nb_ports; ++port_idx) {
+ if (adapter->switchdev_info.pf_num == req_eth_da->ports[port_idx])
+ break;
+ }
+ if (port_idx == req_eth_da->nb_ports) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev pf %u not match req pf",
+ adapter->switchdev_info.pf_num);
+ rte_errno = EBUSY;
+ return false;
+ }
+
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- repr_id = SXE2_REPRESENTOR_ID(req_eth_da->ports[port_idx],
- req_eth_da->type,
- req_eth_da->representor_ports[repr_idx]);
- if (repr_id == kernel_repr_id)
- return true;
- }
- rte_errno = EBUSY;
- return false;
+ for (i = 0; i < adapter->repr_ctxt.nb_vf; ++i) {
+ vf_id = rte_le_to_cpu_16(adapter->repr_ctxt.repr_vf_id[i].func_id);
+ if (vf_id == req_eth_da->representor_ports[repr_idx])
+ break;
+ }
+ if (i == adapter->repr_ctxt.nb_vf) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev vf %u not match req vf(cnt:%u)",
+ req_eth_da->representor_ports[repr_idx], adapter->repr_ctxt.nb_vf);
+ rte_errno = EBUSY;
+ return false;
+ }
+ }
+
+ return true;
}
static int32_t sxe2_eth_pmd_probe_pf(struct sxe2_common_device *cdev,
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index f2557b28c3..e818578319 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -65,9 +65,6 @@ enum sxe2_fnav_tunnel_flag_type {
#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
#define lower_32_bits(n) ((uint32_t)((n) & 0xffffffff))
-#define SXE2_REPRESENTOR_ID(pf, type, repr) \
- (((pf) << 14) + ((type) << 12) + ((repr) & 0xfff))
-
#define SXE2_I2C_EEPROM_DEV_ADDR 0xA0
#define SXE2_I2C_EEPROM_DEV_ADDR2 0xA2
#define SXE2_MODULE_TYPE_SFP 0x03
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 24/44] net/sxe2: rename fnav cid manager symbols to flow
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (23 preceding siblings ...)
2026-08-27 2:38 ` [PATCH v4 23/44] net/sxe2: simplify switchdev representor matching liujie5
@ 2026-08-27 2:38 ` liujie5
2026-08-27 2:38 ` [PATCH v4 25/44] net/sxe2: move tunnel port helpers into flow module liujie5
` (19 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Rename the sxe2_fnav_cid_mgr, sxe2_fnav_cid_mgr_list_t,
sxe2_fnav_count_resource and sxe2_fnav_get_filter_cid symbols to the
sxe2_flow_* prefix for consistency with the flow module naming.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 2 +-
drivers/net/sxe2/sxe2_cmd_chnl.h | 2 +-
drivers/net/sxe2/sxe2_flow.c | 46 ++++++++++++++---------------
drivers/net/sxe2/sxe2_flow.h | 6 ++--
drivers/net/sxe2/sxe2_flow_define.h | 12 ++++----
5 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b09989fe50..3229c72597 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1800,7 +1800,7 @@ int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat
}
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr)
+ struct sxe2_flow_cid_mgr *mgr)
{
struct sxe2_drv_flow_fnav_query_stat_req req = { 0 };
struct sxe2_drv_flow_fnav_query_stat_resp resp = { 0 };
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index 294ac15db4..cfea1a1f0e 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -159,7 +159,7 @@ int32_t sxe2_drv_flow_fnav_get_stat_id(struct sxe2_adapter *adapter, uint32_t *s
int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr);
+ struct sxe2_flow_cid_mgr *mgr);
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set);
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index cf54803301..a33b8606df 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -857,7 +857,7 @@ static int32_t sxe2_flow_rte_list_free(struct sxe2_adapter *adapter,
struct rte_flow *flow_temp = NULL;
struct sxe2_flow *hw_flow = NULL;
struct sxe2_flow *hw_flow_temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
rte_spinlock_lock(&adapter->flow_ctxt.flow_list_lock);
TAILQ_FOREACH(flow_temp, &adapter->flow_ctxt.rte_flow_list, next) {
if (flow_temp == flow)
@@ -1028,7 +1028,7 @@ static struct rte_flow *sxe2_flow_create(struct rte_eth_dev *dev,
goto l_free_flow;
TAILQ_FOREACH(flow, &flow_list->sxe2_flow_list, next) {
- ret = sxe2_fnav_get_filter_cid(adapter, flow);
+ ret = sxe2_flow_get_filter_cid(adapter, flow);
if (ret != 0) {
PMD_LOG_ERR(DRV, "fnav get stats id failed, ret:%d", ret);
rte_flow_error_set(error, EIO,
@@ -1088,16 +1088,16 @@ static int32_t sxe2_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e
return ret;
}
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
user_id = flow->action.count.user_id;
@@ -1112,7 +1112,7 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
}
if (mgr == NULL) {
mgr = rte_zmalloc("sxe2_fnav_cid_mgr",
- sizeof(struct sxe2_fnav_cid_mgr), 0);
+ sizeof(struct sxe2_flow_cid_mgr), 0);
if (!mgr) {
PMD_LOG_ERR(DRV,
"Failed to alloc sxe2vf_fnav_cid_mgr memory.");
@@ -1143,13 +1143,13 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *mgr = *mgr_ptr;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *mgr = *mgr_ptr;
uint32_t user_id = flow->action.count.user_id;
if (user_id == 0) {
TAILQ_REMOVE(cid_mgr_list, mgr, next);
@@ -1170,14 +1170,14 @@ int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
uint32_t user_id = flow->action.count.user_id;
uint32_t driver_id = flow->action.count.driver_id;
@@ -1218,7 +1218,7 @@ static int32_t sxe2_flow_query_count(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
switch (flow->action.count.stat_ctrl) {
case SXE2_FNAV_STAT_ENA_NONE:
count->hits_set = 0;
@@ -1348,7 +1348,7 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
int32_t ret = 0;
TAILQ_INIT(&adapter->flow_ctxt.rte_flow_list);
- TAILQ_INIT(&adapter->flow_ctxt.hw_res.fnav_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.hw_res.flow_cid_mgr_list);
if (adapter->devargs.fnav_stat_type)
adapter->flow_ctxt.hw_res.count_type =
adapter->devargs.fnav_stat_type;
@@ -1370,10 +1370,10 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
int32_t ret = 0;
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct rte_flow_error error;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
ret = sxe2_flow_flush(dev, &error);
if (ret)
diff --git a/drivers/net/sxe2/sxe2_flow.h b/drivers/net/sxe2/sxe2_flow.h
index daaeedd4dc..8d47b11ff4 100644
--- a/drivers/net/sxe2/sxe2_flow.h
+++ b/drivers/net/sxe2/sxe2_flow.h
@@ -14,16 +14,16 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev);
int32_t sxe2_flow_uninit(struct rte_eth_dev *dev);
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev);
diff --git a/drivers/net/sxe2/sxe2_flow_define.h b/drivers/net/sxe2/sxe2_flow_define.h
index 263a573f04..8a5d871978 100644
--- a/drivers/net/sxe2/sxe2_flow_define.h
+++ b/drivers/net/sxe2/sxe2_flow_define.h
@@ -98,8 +98,8 @@ struct rte_flow {
};
TAILQ_HEAD(rte_flow_list_t, rte_flow);
-struct sxe2_fnav_cid_mgr {
- TAILQ_ENTRY(sxe2_fnav_cid_mgr) next;
+struct sxe2_flow_cid_mgr {
+ TAILQ_ENTRY(sxe2_flow_cid_mgr) next;
uint16_t stat_index;
uint32_t user_id;
uint32_t driver_id;
@@ -107,18 +107,18 @@ struct sxe2_fnav_cid_mgr {
uint64_t hits;
uint64_t bytes;
};
-TAILQ_HEAD(sxe2_fnav_cid_mgr_list_t, sxe2_fnav_cid_mgr);
+TAILQ_HEAD(sxe2_flow_cid_mgr_list_t, sxe2_flow_cid_mgr);
-struct sxe2_fnav_count_resource {
+struct sxe2_flow_count_resource {
uint32_t count_type;
uint32_t global_index;
- struct sxe2_fnav_cid_mgr_list_t fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t flow_cid_mgr_list;
};
struct sxe2_flow_context {
struct rte_flow_list_t rte_flow_list;
rte_spinlock_t flow_list_lock;
- struct sxe2_fnav_count_resource hw_res;
+ struct sxe2_flow_count_resource hw_res;
uint16_t tunnel_port_list[SXE2_FLOW_UDP_TUNNEL_MAX];
uint32_t fnav_inited;
};
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 25/44] net/sxe2: move tunnel port helpers into flow module
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (24 preceding siblings ...)
2026-08-27 2:38 ` [PATCH v4 24/44] net/sxe2: rename fnav cid manager symbols to flow liujie5
@ 2026-08-27 2:38 ` liujie5
2026-08-27 2:38 ` [PATCH v4 26/44] net/sxe2: add ACL engine event statistics support liujie5
` (18 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move sxe2_flow_parse_pattern_ipip, sxe2_flow_add_udp_tunnel_port and
sxe2_flow_add_tunnel_port from sxe2_flow_parse_pattern.c into
sxe2_flow.c as static helpers, and drop the public declaration of
sxe2_flow_add_tunnel_port from the header, keeping the tunnel port
handling internal to the flow module.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_flow.c | 113 +++++++++++++++++++++
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ---------------------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 6 --
3 files changed, 113 insertions(+), 119 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index a33b8606df..cd39385340 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -550,6 +550,119 @@ int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev)
return ret;
}
+static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
+ enum sxe2_flow_udp_tunnel_protocol proto,
+ struct sxe2_flow *flow,
+ BITMAP_TYPE *flow_type)
+{
+ int32_t ret = 0;
+ uint16_t tun_port;
+
+ tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
+ if (tun_port == 0xffff || tun_port == 0) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
+ goto l_end;
+ }
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP must be over tunnel");
+ goto l_end;
+ }
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
+ flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
+l_end:
+ return ret;
+}
+
+static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
+{
+ sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ }
+ return 0;
+}
+
+static int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
+ struct rte_flow_error *error,
+ struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
+ enum sxe2_flow_tunnel_type tunnel_type)
+{
+ int32_t ret = 0;
+ enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
+ struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
+ switch (tunnel_type) {
+ case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
+ } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
+ sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GTPU:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GRE:
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
+ }
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_IPIP:
+ ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
+ break;
+ default:
+ break;
+ }
+ if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
+ ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
+ if (ret != 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ NULL, "Failed to add udp port for tunnel.");
+ PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
+ goto l_end;
+ }
+ }
+ if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
+ sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
+ }
+l_end:
+ return ret;
+}
+
static int32_t sxe2_flowlist_add_tunnel_port(struct rte_eth_dev *dev,
struct rte_flow *flow_list,
struct rte_flow_error *error)
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.c b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
index f5bf8922c6..189abb1a33 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
@@ -1637,119 +1637,6 @@ static int32_t sxe2_flow_parse_pattern_vxlan_gpe(const struct rte_flow_item *ite
return ret;
}
-static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
-{
- sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- }
- return 0;
-}
-
-static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
- enum sxe2_flow_udp_tunnel_protocol proto,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type)
-{
- int32_t ret = 0;
- uint16_t tun_port;
-
- tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
- if (tun_port == 0xffff || tun_port == 0) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
- goto l_end;
- }
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP must be over tunnel");
- goto l_end;
- }
- sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
- flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
-l_end:
- return ret;
-}
-
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type)
-{
- int32_t ret = 0;
- enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
- struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
- struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
- switch (tunnel_type) {
- case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
- } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
- sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GTPU:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GRE:
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
- }
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_IPIP:
- ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
- break;
- default:
- break;
- }
- if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
- ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
- if (ret != 0) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- NULL, "Failed to add udp port for tunnel.");
- PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
- goto l_end;
- }
- }
- if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
- sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
- }
-l_end:
- return ret;
-}
-
struct sxe2_flow_parse_pattern_ops sxe2_flow_parse_pattern_list[] = {
[SXE2_EXPANSION_OUTER_ETH] = {
.is_inner = false,
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.h b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
index 8442c35cae..69d83a6ea6 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.h
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
@@ -37,10 +37,4 @@ int32_t sxe2_flow_parse_pattern(struct rte_eth_dev *dev,
struct rte_flow_error *error,
struct sxe2_flow *flow);
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type);
-
#endif /* SXE2_FLOW_PARSE_PATTERN_H_ */
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 26/44] net/sxe2: add ACL engine event statistics support
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (25 preceding siblings ...)
2026-08-27 2:38 ` [PATCH v4 25/44] net/sxe2: move tunnel port helpers into flow module liujie5
@ 2026-08-27 2:38 ` liujie5
2026-08-27 2:38 ` [PATCH v4 27/44] net/sxe2: guard Rx queue event FD free in unregister liujie5
` (17 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add statistics support for the ACL flow engine to track packet hits
and bytes, enabling flow aging and traffic monitoring for ACL rules.
- Add acl-stat-type devarg to configure the statistics type
- Implement sxe2_drv_flow_acl_get_stat_id/free_stat/query_stat
- Handle the ACL engine in flow create/destroy/query paths
- Add fnav_hw_res and acl_hw_res count resources
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
doc/guides/nics/sxe2.rst | 11 +++
drivers/net/sxe2/sxe2_cmd_chnl.c | 71 ++++++++++++++++++
drivers/net/sxe2/sxe2_cmd_chnl.h | 7 ++
drivers/net/sxe2/sxe2_drv_cmd.h | 19 +++++
drivers/net/sxe2/sxe2_dump.c | 2 +
drivers/net/sxe2/sxe2_ethdev.c | 23 ++++--
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_flow.c | 89 ++++++++++++++++++-----
drivers/net/sxe2/sxe2_flow_define.h | 5 +-
drivers/net/sxe2/sxe2_flow_parse_action.c | 25 +++++--
drivers/net/sxe2/sxe2_queue.c | 2 +
11 files changed, 224 insertions(+), 31 deletions(-)
diff --git a/doc/guides/nics/sxe2.rst b/doc/guides/nics/sxe2.rst
index 8278a5f108..c5b400a8ba 100644
--- a/doc/guides/nics/sxe2.rst
+++ b/doc/guides/nics/sxe2.rst
@@ -98,6 +98,17 @@ Runtime Configuration
Default value is 3 (count both packets and bytes).
+- ``acl-stat-type`` parameter [int]
+
+ This parameter controls the ACL flow engine statistics type
+ used for flow rule hit counting (via ``rte_flow_query``).
+
+ - 1: Only count the number of packets.
+ - 2: Only count the number of bytes.
+ - 3: Count both packets and bytes (default).
+
+ Default value is 3 (count both packets and bytes).
+
- ``drv-sw-stats`` parameter [int]
This parameter controls whether per-packet software statistics (SW stats)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 3229c72597..16a2c3fea4 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1829,6 +1829,77 @@ int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
return ret;
}
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id)
+{
+ struct sxe2_drv_flow_fnav_get_stat_id_req req = { 0 };
+ struct sxe2_drv_flow_fnav_get_stat_id_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC,
+ &req, sizeof(req),
+ &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+ *stat_id = resp.stat_id;
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id)
+{
+ struct sxe2_drv_flow_fnav_free_stat_id_req req = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = stat_id;
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_FREE,
+ &req, sizeof(req),
+ NULL, 0);
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to free acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr)
+{
+ struct sxe2_drv_acl_query_stat_req req = { 0 };
+ struct sxe2_drv_acl_query_stat_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = mgr->stat_index;
+ req.stat_ctrl = mgr->count_type;
+ req.is_clear = 1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY,
+ &req, sizeof(req), &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to query ACL stat, stat id: %u, ret: %d.",
+ req.stat_id, ret);
+ goto l_end;
+ }
+ mgr->hits += resp.stat_hits;
+ mgr->bytes += resp.stat_bytes;
+
+l_end:
+ return ret;
+}
+
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set)
{
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index cfea1a1f0e..7d07068bfc 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -161,6 +161,13 @@ int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
struct sxe2_flow_cid_mgr *mgr);
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id);
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr);
+
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set);
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index 03ef3b315d..cc71e2364e 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -668,6 +668,18 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_fc_get_resp {
uint8_t rsv[3];
} __rte_packed_end;
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_req {
+ uint32_t stat_id;
+ uint32_t stat_ctrl;
+ uint32_t is_clear;
+} __rte_packed_end;
+
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_resp {
+ uint32_t stat_index;
+ uint64_t stat_hits;
+ uint64_t stat_bytes;
+} __rte_packed_end;
+
enum sxe2_drv_cmd_module {
SXE2_DRV_CMD_MODULE_HANDSHAKE = 0,
SXE2_DRV_CMD_MODULE_DEV = 1,
@@ -824,6 +836,13 @@ enum sxe2_drv_cmd_code {
SXE2_DRV_CMD_OPT_EEP_GET =
SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_OPT, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 2),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_FREE =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 3),
+
};
#endif /* SXE2_DRV_CMD_H */
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index 590219f502..31f7d6ba61 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -80,12 +80,14 @@ sxe2_dump_dev_args_info(FILE *file, struct rte_eth_dev *dev)
"\t -- no_sched_mode: %s\n"
"\t -- flow-duplicate-pattern: %u\n"
"\t -- fnav-stat-type: %u\n"
+ "\t -- acl-stat-type: %u\n"
"\t -- sched_layer_mode: %u\n"
"\t -- rx_low_latency: %s\n"
"\t -- function-flow-direct: %s\n",
adapter->devargs.no_sched_mode ? "On" : "Off",
adapter->devargs.flow_dup_pattern_mode,
adapter->devargs.fnav_stat_type,
+ adapter->devargs.acl_stat_type,
adapter->devargs.sched_layer_mode,
adapter->devargs.rx_low_latency ? "On" : "Off",
adapter->devargs.func_flow_direct_en ? "On" : "Off");
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 7ba73aea6f..19f81f47c9 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -72,6 +72,7 @@ static const struct rte_pci_id pci_id_sxe2_tbl[] = {
#define SXE2_DEVARG_FLOW_DUP_PATTERN_MODE "flow-duplicate-pattern"
#define SXE2_DEVARG_FUNC_FLOW_DIRCT "function-flow-direct"
#define SXE2_DEVARG_FNAV_STAT_TYPE "fnav-stat-type"
+#define SXE2_DEVARG_ACL_STAT_TYPE "acl-stat-type"
#define SXE2_DEVARG_NO_SCHED_MODE "no-sched-mode"
#define SXE2_DEVARG_SCHED_LAYER_MODE "sched-layer-mode"
#define SXE2_DEVARG_RX_LOW_LATENCY "rx-low-latency"
@@ -985,11 +986,11 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
return ptypes;
}
-static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, void *args)
+static int32_t sxe2_parse_stat_type(const char *key, const char *value, void *args)
{
int32_t ret = -EINVAL;
uint8_t *num = (uint8_t *)args;
- unsigned long fnav_stat_type;
+ unsigned long stat_type;
char *endptr = NULL;
if (value == NULL || args == NULL) {
@@ -997,19 +998,19 @@ static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, voi
goto l_end;
}
errno = 0;
- fnav_stat_type = strtoul(value, &endptr, 10);
+ stat_type = strtoul(value, &endptr, 10);
if (errno != 0 || endptr == value || *endptr != '\0') {
PMD_LOG_WARN(INIT, "%s: \"%s\" is not a valid int value.",
key, value);
goto l_end;
}
- if (fnav_stat_type > SXE2_FNAV_STAT_ENA_ALL ||
- fnav_stat_type == SXE2_FNAV_STAT_ENA_NONE) {
+ if (stat_type > SXE2_FNAV_STAT_ENA_ALL ||
+ stat_type == SXE2_FNAV_STAT_ENA_NONE) {
PMD_LOG_ERR(INIT, "%s: \"%s\" out of range [1-3].",
key, value);
goto l_end;
}
- *num = (uint8_t)fnav_stat_type;
+ *num = (uint8_t)stat_type;
ret = 0;
l_end:
return ret;
@@ -1191,13 +1192,20 @@ static int32_t sxe2_args_parse(struct rte_eth_dev *dev, struct sxe2_dev_kvargs_i
if (kvargs == NULL)
goto l_end;
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_FNAV_STAT_TYPE,
- &sxe2_parse_fnav_stat_type,
+ &sxe2_parse_stat_type,
&adapter->devargs.fnav_stat_type);
if (ret) {
PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse fnav stat type, ret:%d", ret);
goto l_end;
}
+ ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_ACL_STAT_TYPE,
+ &sxe2_parse_stat_type, &adapter->devargs.acl_stat_type);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse acl stat type, ret:%d", ret);
+ goto l_end;
+ }
+
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_NO_SCHED_MODE,
&sxe2_parse_bool,
&adapter->devargs.no_sched_mode);
@@ -2368,6 +2376,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_sxe2,
"flow-duplicate-pattern=<0|1|2> "
"function-flow-direct=<0|1> "
"fnav-stat-type=<1|2|3> "
+ "acl-stat-type=<1|2|3> "
"no-sched-mode=<0|1> "
"sched-layer-mode=<0-3> "
"rx-low-latency=<0|1>");
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index e818578319..e9f78fe57f 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -135,6 +135,7 @@ struct sxe2_devargs {
uint8_t flow_dup_pattern_mode;
uint8_t func_flow_direct_en;
uint8_t fnav_stat_type;
+ uint8_t acl_stat_type;
uint8_t no_sched_mode;
uint8_t sched_layer_mode;
uint8_t rx_low_latency;
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index cd39385340..d82d3bbd02 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -1204,13 +1204,23 @@ static int32_t sxe2_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e
int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
struct sxe2_flow_cid_mgr *temp = NULL;
struct sxe2_flow_cid_mgr *mgr = NULL;
+ uint32_t count_type;
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.fnav_hw_res.count_type;
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.acl_hw_res.count_type;
+ } else {
+ goto l_end;
+ }
if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
user_id = flow->action.count.user_id;
@@ -1233,7 +1243,10 @@ int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
goto l_end;
}
- ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ ret = sxe2_drv_flow_acl_get_stat_id(adapter, &stat_index);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to alloc fw count id.");
rte_free(mgr);
@@ -1244,7 +1257,7 @@ int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
mgr->user_id = user_id;
mgr->driver_id = driver_id;
mgr->stat_index = stat_index;
- mgr->count_type = adapter->flow_ctxt.hw_res.count_type;
+ mgr->count_type = count_type;
}
flow->action.count.stat_index = mgr->stat_index;
flow->action.count.stat_ctrl = mgr->count_type;
@@ -1260,13 +1273,26 @@ int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
struct sxe2_flow_cid_mgr *mgr = *mgr_ptr;
uint32_t user_id = flow->action.count.user_id;
- if (user_id == 0) {
- TAILQ_REMOVE(cid_mgr_list, mgr, next);
- ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+
+ if (user_id == 0 && mgr) {
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+ } else {
+ PMD_LOG_ERR(DRV,
+ "Failed to free flow count, unknown engine type: %d.",
+ flow->engine_type);
+ ret = -ENOTSUP;
+ return ret;
+ }
if (ret) {
rte_flow_error_set(error, EIO,
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
@@ -1287,13 +1313,19 @@ int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
struct sxe2_flow_cid_mgr *temp = NULL;
struct sxe2_flow_cid_mgr *mgr = NULL;
uint32_t user_id = flow->action.count.user_id;
uint32_t driver_id = flow->action.count.driver_id;
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ else
+ goto l_end;
+
TAILQ_FOREACH(temp, cid_mgr_list, next) {
if (temp->user_id == user_id &&
temp->driver_id == driver_id) {
@@ -1310,7 +1342,15 @@ int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
ret = -EINVAL;
goto l_end;
}
- ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ ret = sxe2_drv_flow_acl_query_stat(adapter, mgr);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+ } else {
+ PMD_LOG_ERR(DRV, "query flow engine neither FNAV nor ACL");
+ ret = -ENOTSUP;
+ }
if (ret) {
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM, NULL,
@@ -1461,12 +1501,18 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
int32_t ret = 0;
TAILQ_INIT(&adapter->flow_ctxt.rte_flow_list);
- TAILQ_INIT(&adapter->flow_ctxt.hw_res.flow_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list);
if (adapter->devargs.fnav_stat_type)
- adapter->flow_ctxt.hw_res.count_type =
+ adapter->flow_ctxt.fnav_hw_res.count_type =
adapter->devargs.fnav_stat_type;
else
- adapter->flow_ctxt.hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+ adapter->flow_ctxt.fnav_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+
+ if (adapter->devargs.acl_stat_type)
+ adapter->flow_ctxt.acl_hw_res.count_type = adapter->devargs.acl_stat_type;
+ else
+ adapter->flow_ctxt.acl_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
adapter->flow_ctxt.fnav_inited = 1;
rte_spinlock_init(&adapter->flow_ctxt.flow_list_lock);
@@ -1485,13 +1531,13 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
struct rte_flow_error error;
struct sxe2_flow_cid_mgr *mgr = NULL;
struct sxe2_flow_cid_mgr *temp = NULL;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
ret = sxe2_flow_flush(dev, &error);
if (ret)
PMD_LOG_ERR(DRV, "Failed to flush flow, ret: %d.", ret);
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
TAILQ_REMOVE(cid_mgr_list, mgr, next);
ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
@@ -1500,5 +1546,14 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
"Failed to free fnav stat id, ret: %d.", ret);
rte_free(mgr);
}
+
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ if (ret)
+ PMD_LOG_ERR(DRV, "Failed to free acl stat id, ret: %d.", ret);
+ rte_free(mgr);
+ }
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_flow_define.h b/drivers/net/sxe2/sxe2_flow_define.h
index 8a5d871978..d04499f5cb 100644
--- a/drivers/net/sxe2/sxe2_flow_define.h
+++ b/drivers/net/sxe2/sxe2_flow_define.h
@@ -100,7 +100,7 @@ TAILQ_HEAD(rte_flow_list_t, rte_flow);
struct sxe2_flow_cid_mgr {
TAILQ_ENTRY(sxe2_flow_cid_mgr) next;
- uint16_t stat_index;
+ uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
uint32_t count_type;
@@ -118,7 +118,8 @@ struct sxe2_flow_count_resource {
struct sxe2_flow_context {
struct rte_flow_list_t rte_flow_list;
rte_spinlock_t flow_list_lock;
- struct sxe2_flow_count_resource hw_res;
+ struct sxe2_flow_count_resource fnav_hw_res;
+ struct sxe2_flow_count_resource acl_hw_res;
uint16_t tunnel_port_list[SXE2_FLOW_UDP_TUNNEL_MAX];
uint32_t fnav_inited;
};
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index a9559e2d7e..db70b146c6 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -953,7 +953,8 @@ static int32_t sxe2_flow_check_actions(struct rte_eth_dev *dev __rte_unused, str
}
}
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
if (vsi_num) {
flow->action.q_region.q_index = 0;
flow->action.q_region.region = 7;
@@ -988,7 +989,8 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
case RTE_FLOW_ACTION_TYPE_VOID:
break;
case RTE_FLOW_ACTION_TYPE_PASSTHRU:
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
sxe2_set_bit(SXE2_FLOW_ACTION_PASSTHRU, flow->action.act_types);
action_num[SXE2_FLOW_ACTION_PASSTHRU]++;
} else {
@@ -1037,11 +1039,24 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
act_count = action->conf;
- flow->action.count.user_id = act_count->id;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
+ flow->action.count.driver_id = 0;
+ if (flow->action.count.user_id == 0) {
+ flow->action.count.driver_id =
+ ++adapter->flow_ctxt.fnav_hw_res.global_index;
+ }
+ action_num[SXE2_FLOW_ACTION_COUNT]++;
+ } else if (engine_type == SXE2_FLOW_ENGINE_ACL) {
+ sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
+ act_count = action->conf;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
flow->action.count.driver_id = 0;
- if (flow->action.count.user_id == 0)
+ if (flow->action.count.user_id == 0) {
flow->action.count.driver_id =
- ++adapter->flow_ctxt.hw_res.global_index;
+ ++adapter->flow_ctxt.acl_hw_res.global_index;
+ }
action_num[SXE2_FLOW_ACTION_COUNT]++;
} else {
rte_flow_error_set(error, ENOTSUP,
diff --git a/drivers/net/sxe2/sxe2_queue.c b/drivers/net/sxe2/sxe2_queue.c
index afb2681b72..3aaa14c685 100644
--- a/drivers/net/sxe2/sxe2_queue.c
+++ b/drivers/net/sxe2/sxe2_queue.c
@@ -39,6 +39,8 @@ int32_t sxe2_queues_init(struct rte_eth_dev *dev)
rxq->rx_buf_len = RTE_MIN(rxq->rx_buf_len, SXE2_RX_MAX_DATA_BUF_SIZE);
if (frame_size > rxq->rx_buf_len)
dev->data->scattered_rx = 1;
+ if (adapter->flow_ctxt.fnav_inited)
+ rxq->fnav_enable = true;
}
adapter->ptp_ctxt.mbuf_rx_ts_offset = -1;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 27/44] net/sxe2: guard Rx queue event FD free in unregister
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (26 preceding siblings ...)
2026-08-27 2:38 ` [PATCH v4 26/44] net/sxe2: add ACL engine event statistics support liujie5
@ 2026-08-27 2:38 ` liujie5
2026-08-27 2:39 ` [PATCH v4 28/44] net/sxe2: refactor primary process MP message handling liujie5
` (16 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_rxq_intr_unregister() frees irq_ctxt->rxq_event_fd outside the
rxq_event_fd NULL check. Move the free and NULL assignment inside the
guard so the buffer is only released when it was allocated.
Fixes: 8cebf80f1eda ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index ba764dd5e4..4e5339e24b 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -881,12 +881,11 @@ static void sxe2_rxq_intr_unregister(struct rte_eth_dev *dev)
(void)sxe2_drv_dev_rxq_irq_set(adapter->cdev, i, &efd, 1);
sxe2_rxq_intr_efd_free(irq_ctxt->rxq_event_fd[i]);
}
+ rte_free(irq_ctxt->rxq_event_fd);
+ irq_ctxt->rxq_event_fd = NULL;
}
- rte_free(irq_ctxt->rxq_event_fd);
- irq_ctxt->rxq_event_fd = NULL;
rte_intr_vec_list_free(intr_handle);
-
rte_intr_nb_efd_set(intr_handle, 0);
rte_intr_max_intr_set(intr_handle, 0);
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 28/44] net/sxe2: refactor primary process MP message handling
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (27 preceding siblings ...)
2026-08-27 2:38 ` [PATCH v4 27/44] net/sxe2: guard Rx queue event FD free in unregister liujie5
@ 2026-08-27 2:39 ` liujie5
2026-08-27 2:39 ` [PATCH v4 29/44] net/sxe2: refactor Tx queue reset operations liujie5
` (15 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Extract the multi-process work logic into the sxe2_mp_do_primary_work
helper and operate on a copy of the request in the primary handler so
the original message is not modified. Simplify the reply construction
and return -ENOENT instead of -EINVAL when no response is received
from the primary process.
Fixes: 5db446ba97b0 ("net/sxe2: support statistics and multi-process")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_mp.c | 59 ++++++++++++++++++++++----------------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_mp.c b/drivers/net/sxe2/sxe2_mp.c
index a4a5c76495..93a11150a9 100644
--- a/drivers/net/sxe2/sxe2_mp.c
+++ b/drivers/net/sxe2/sxe2_mp.c
@@ -29,16 +29,11 @@ static int32_t sxe2_mp_secondary_handle(const struct rte_mp_msg *mp_msg,
const void *peer);
static int32_t
-sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+sxe2_mp_do_primary_work(struct sxe2_mp_param *param)
{
- struct rte_mp_msg reply;
- const struct sxe2_mp_param *param =
- (const struct sxe2_mp_param *)mp_msg->param;
- struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
struct rte_eth_dev *dev;
- int32_t ret = 0;
struct sxe2_mp_shared_data *mz_data;
- int32_t send_reply = 0;
+ int32_t ret = 0;
int32_t cnt = 0;
if (!rte_eth_dev_is_valid_port(param->port_id)) {
@@ -49,24 +44,21 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
}
dev = &rte_eth_devices[param->port_id];
- sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+
if (sxe2_mp_mz == NULL) {
- PMD_LOG_ERR(DRV, "Failed to lookup memzone %s", SXE2_MP_MZ_NAME);
- ret = -ENOENT;
- goto out;
+ sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+ if (sxe2_mp_mz == NULL) {
+ PMD_LOG_ERR(DRV, "Failed to lookup memzone %s",
+ SXE2_MP_MZ_NAME);
+ ret = -ENOENT;
+ goto out;
+ }
}
mz_data = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
- send_reply = 1;
-
- memset(&reply, 0, sizeof(reply));
- (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
- reply.len_param = sizeof(*reply_param);
-
switch (param->type) {
case SXE2_MP_REQ_GET_STATS:
- ret = sxe2_stats_info_get(dev,
- &mz_data->payload.stats_blk.stats,
+ ret = sxe2_stats_info_get(dev, &mz_data->payload.stats_blk.stats,
&mz_data->payload.stats_blk.qstats);
break;
case SXE2_MP_REQ_GET_XSTATS:
@@ -88,15 +80,32 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
default:
PMD_LOG_ERR(DRV, "primary process: unrecognized msg type: %d",
param->type);
- send_reply = false;
ret = -EINVAL;
- goto out;
+ break;
}
+
out:
- if (!send_reply)
- return ret;
+ param->result = ret;
+ return ret;
+}
- reply_param->result = ret;
+static int32_t
+sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+{
+ struct rte_mp_msg reply;
+ struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
+ const struct sxe2_mp_param *param =
+ (const struct sxe2_mp_param *)mp_msg->param;
+ struct sxe2_mp_param param_copy;
+
+ memset(&reply, 0, sizeof(reply));
+ (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
+ reply.len_param = sizeof(*reply_param);
+
+ param_copy = *param;
+ (void)sxe2_mp_do_primary_work(¶m_copy);
+
+ reply_param->result = param_copy.result;
reply_param->type = param->type;
reply_param->port_id = param->port_id;
@@ -275,7 +284,7 @@ int32_t sxe2_mp_request_simple(struct rte_eth_dev *dev,
if (reply.nb_received == 0) {
PMD_LOG_ERR(DRV, "No response received from primary for type=%d, port %u",
type, dev->data->port_id);
- ret = -EINVAL;
+ ret = -ENOENT;
goto out;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 29/44] net/sxe2: refactor Tx queue reset operations
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (28 preceding siblings ...)
2026-08-27 2:39 ` [PATCH v4 28/44] net/sxe2: refactor primary process MP message handling liujie5
@ 2026-08-27 2:39 ` liujie5
2026-08-27 2:39 ` [PATCH v4 30/44] net/sxe2: unify vectorized Tx buffer handling liujie5
` (14 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Extract the descriptor ring reset loop into a sxe2_tx_queue_desc_ring_reset
helper and reuse it from both the scalar and vectorized queue reset paths.
Add a sxe2_tx_queue_reset_vec entry point for vectorized queues, export
sxe2_tx_buffer_ring_free for reuse outside the module (clearing the buffer
ring pointer after freeing it), and add sxe2_tx_vec_ops_get to build the
vectorized Tx queue operations table used by the vector path setup.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_tx.c | 42 +++++++++++++++++++++++---------
drivers/net/sxe2/sxe2_tx.h | 4 +++
drivers/net/sxe2/sxe2_txrx_vec.c | 16 +++++++++++-
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
4 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_tx.c b/drivers/net/sxe2/sxe2_tx.c
index f49238ceef..94a6e9afc7 100644
--- a/drivers/net/sxe2/sxe2_tx.c
+++ b/drivers/net/sxe2/sxe2_tx.c
@@ -19,6 +19,17 @@ static void *sxe2_tx_doorbell_addr_get(struct sxe2_adapter *adapter, uint16_t qu
queue_id);
}
+static void sxe2_tx_queue_desc_ring_reset(struct sxe2_tx_queue *txq)
+{
+ uint16_t i;
+ static const union sxe2_tx_data_desc zeroed_desc = {{0}};
+
+ for (i = 0; i < txq->ring_depth; i++) {
+ txq->desc_ring[i] = zeroed_desc;
+ txq->desc_ring[i].wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
+ }
+}
+
static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue *txq)
{
txq->tdt_reg_addr = sxe2_tx_doorbell_addr_get(adapter, txq->queue_id);
@@ -28,20 +39,12 @@ static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
{
uint16_t prev, i;
- volatile union sxe2_tx_data_desc *txd;
- static const union sxe2_tx_data_desc zeroed_desc = {{0}};
struct sxe2_tx_buffer *tx_buffer = txq->buffer_ring;
- for (i = 0; i < txq->ring_depth; i++)
- txq->desc_ring[i] = zeroed_desc;
+ sxe2_tx_queue_desc_ring_reset(txq);
prev = txq->ring_depth - 1;
for (i = 0; i < txq->ring_depth; i++) {
- txd = &txq->desc_ring[i];
- if (txd == NULL)
- continue;
-
- txd->wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
tx_buffer[i].mbuf = NULL;
tx_buffer[i].last_id = i;
tx_buffer[prev].next_id = i;
@@ -56,6 +59,21 @@ void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
txq->next_rs = txq->rs_thresh - 1;
}
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq)
+{
+ sxe2_tx_queue_desc_ring_reset(txq);
+
+ memset(txq->buffer_ring, 0,
+ sizeof(struct sxe2_tx_buffer) * txq->ring_depth);
+
+ txq->desc_used_num = 0;
+ txq->desc_free_num = txq->ring_depth - 1;
+ txq->next_use = 0;
+ txq->next_clean = txq->ring_depth - 1;
+ txq->next_dd = txq->rs_thresh - 1;
+ txq->next_rs = txq->rs_thresh - 1;
+}
+
void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
{
uint32_t i;
@@ -70,10 +88,12 @@ void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
}
}
-static void sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
{
- if (txq != NULL && txq->buffer_ring != NULL)
+ if (txq != NULL && txq->buffer_ring != NULL) {
rte_free(txq->buffer_ring);
+ txq->buffer_ring = NULL;
+ }
}
const struct sxe2_txq_ops sxe2_default_txq_ops = {
diff --git a/drivers/net/sxe2/sxe2_tx.h b/drivers/net/sxe2/sxe2_tx.h
index f4823126b3..bc5ff1c2bc 100644
--- a/drivers/net/sxe2/sxe2_tx.h
+++ b/drivers/net/sxe2/sxe2_tx.h
@@ -9,6 +9,10 @@
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq);
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq);
+
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq);
+
int32_t __rte_cold sxe2_tx_queue_start(struct rte_eth_dev *dev, uint16_t queue_id);
void sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.c b/drivers/net/sxe2/sxe2_txrx_vec.c
index cf004f5eb2..9cfa565548 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec.c
@@ -8,6 +8,19 @@
#include "sxe2_ethdev.h"
#include "sxe2_common_log.h"
+static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq);
+
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void)
+{
+ static const struct sxe2_txq_ops ops = {
+ .queue_reset = sxe2_tx_queue_reset_vec,
+ .mbufs_release = sxe2_tx_queue_mbufs_release_vec,
+ .buffer_ring_free = sxe2_tx_buffer_ring_free,
+ };
+
+ return ops;
+}
+
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags)
{
struct sxe2_rx_queue *rxq;
@@ -233,7 +246,8 @@ int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev)
PMD_LOG_INFO(TX, "Failed to prepare tx queue, txq[%d] is NULL", i);
continue;
}
- txq->ops.mbufs_release = sxe2_tx_queue_mbufs_release_vec;
+ txq->ops = sxe2_tx_vec_ops_get();
+ txq->ops.queue_reset(txq);
}
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.h b/drivers/net/sxe2/sxe2_txrx_vec.h
index c139aed776..b9bc4f9c27 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec.h
@@ -89,6 +89,7 @@ uint16_t sxe2_rx_pkts_scattered_vec_neon_offload(void *rx_queue, struct rte_mbuf
uint16_t sxe2_tx_pkts_vec_neon_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
#endif
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void);
int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev);
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 30/44] net/sxe2: unify vectorized Tx buffer handling
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (29 preceding siblings ...)
2026-08-27 2:39 ` [PATCH v4 29/44] net/sxe2: refactor Tx queue reset operations liujie5
@ 2026-08-27 2:39 ` liujie5
2026-08-27 2:39 ` [PATCH v4 31/44] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
` (13 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add a union of the scalar and vectorized buffer ring pointers to the
Tx queue structure so the vectorized path can use sxe2_tx_buffer_vec
directly. Rename the mbuf fill helper to sxe2_tx_pkts_mbuf_fill_vec,
switch the vectorized Tx burst and mbuf release paths to the
buffer_ring_vec member, and drop the AVX512-specific fill handling and
conditional branching.
Fixes: ac60f302cbef ("net/sxe2: add vectorized Rx and Tx")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_queue.h | 5 +-
drivers/net/sxe2/sxe2_txrx_vec.c | 57 ++----
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 133 +-------------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 9 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 219 ++++++++++++++++--------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
7 files changed, 178 insertions(+), 265 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index 10bdaf5b8d..e53a1ce852 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -62,7 +62,10 @@ struct sxe2_txq_ops {
};
struct sxe2_tx_queue {
volatile union sxe2_tx_data_desc *desc_ring;
- struct sxe2_tx_buffer *buffer_ring;
+ union {
+ struct sxe2_tx_buffer *buffer_ring;
+ struct sxe2_tx_buffer_vec *buffer_ring_vec;
+ };
volatile uint32_t *tdt_reg_addr;
uint64_t offloads;
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.c b/drivers/net/sxe2/sxe2_txrx_vec.c
index 9cfa565548..7c5da33dd5 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec.c
@@ -170,66 +170,31 @@ int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *
static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq)
{
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer_vec;
uint16_t i;
- if (unlikely(txq == NULL || txq->buffer_ring == NULL)) {
+ if (unlikely(txq == NULL || txq->buffer_ring_vec == NULL)) {
PMD_LOG_ERR(TX, "Tx release mbufs vec, invalid params.");
return;
}
- i = txq->next_dd - (txq->rs_thresh - 1);
-#ifdef CC_AVX512_SUPPORT
- struct rte_eth_dev *dev;
- struct sxe2_tx_buffer_vec *buffer_vec;
- dev = &rte_eth_devices[txq->port_id];
-
- if (dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512 ||
- dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512_simple) {
- buffer_vec = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ i = txq->next_dd - (txq->rs_thresh - 1);
+ buffer_vec = txq->buffer_ring_vec;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer_vec[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
- buffer_vec[i].mbuf = NULL;
- }
- }
- i = 0;
- }
- for ( ; i < txq->next_use; ++i) {
+ if (txq->next_use < i) {
+ for ( ; i < txq->ring_depth; ++i) {
if (buffer_vec[i].mbuf != NULL) {
rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
buffer_vec[i].mbuf = NULL;
}
}
- } else {
-#endif
- buffer = txq->buffer_ring;
- buffer = txq->buffer_ring;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
- i = 0;
- }
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
-#ifdef CC_AVX512_SUPPORT
+ i = 0;
}
-#endif
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
+ for ( ; i < txq->next_use; ++i) {
+ if (buffer_vec[i].mbuf != NULL) {
+ rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
+ buffer_vec[i].mbuf = NULL;
}
}
}
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
index 0618e6d988..da96ca3064 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
@@ -115,7 +115,7 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -134,14 +134,14 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -157,10 +157,10 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
index a830c7a33b..6c8415ee5a 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
@@ -1,8 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
*/
-
-#ifndef SXE2_TEST
#include <rte_vect.h>
#include "sxe2_ethdev.h"
@@ -12,114 +10,6 @@
#include "sxe2_txrx_vec_common.h"
#include "sxe2_vsi.h"
-static __rte_always_inline int32_t sxe2_tx_bufs_free_vec_avx512(struct sxe2_tx_queue *txq)
-{
- struct sxe2_tx_buffer_vec *buffer;
- struct rte_mbuf *mbuf;
- struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC];
- struct rte_mempool *mp;
- struct rte_mempool_cache *cache;
- void **cache_objs;
- uint32_t copied;
- uint32_t i;
- int32_t ret;
- uint16_t rs_thresh;
- uint16_t free_num;
-
- if (rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE) !=
- (txq->desc_ring[txq->next_dd].wb.dd &
- rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK))) {
- ret = 0;
- goto l_end;
- }
-
- rs_thresh = txq->rs_thresh;
-
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += txq->next_dd - (rs_thresh - 1);
-
- if ((txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) &&
- (rs_thresh & 31) == 0) {
- mp = buffer[0].mbuf->pool;
- cache = rte_mempool_default_cache(mp, rte_lcore_id());
-
- if (cache == NULL || cache->len)
- goto normal;
-
- if (rs_thresh > RTE_MEMPOOL_CACHE_MAX_SIZE) {
- (void)rte_mempool_ops_enqueue_bulk(mp, (void *)buffer, rs_thresh);
- goto done;
- }
- cache_objs = &cache->objs[cache->len];
-
- copied = 0;
- while (copied < rs_thresh) {
- const __m512i objs0 = _mm512_loadu_si512(&buffer[copied]);
- const __m512i objs1 = _mm512_loadu_si512(&buffer[copied + 8]);
- const __m512i objs2 = _mm512_loadu_si512(&buffer[copied + 16]);
- const __m512i objs3 = _mm512_loadu_si512(&buffer[copied + 24]);
-
- _mm512_storeu_si512(&cache_objs[copied], objs0);
- _mm512_storeu_si512(&cache_objs[copied + 8], objs1);
- _mm512_storeu_si512(&cache_objs[copied + 16], objs2);
- _mm512_storeu_si512(&cache_objs[copied + 24], objs3);
- copied += 32;
- }
- cache->len += rs_thresh;
-
- if (cache->len >= cache->flushthresh) {
- (void)rte_mempool_ops_enqueue_bulk(mp,
- &cache->objs[cache->size], cache->len - cache->size);
- cache->len = cache->size;
- }
- goto done;
- }
-
-normal:
- mbuf = rte_pktmbuf_prefree_seg(buffer[0].mbuf);
-
- if (likely(mbuf)) {
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
-
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
-
- if (likely(mbuf)) {
- if (likely(mbuf->pool == mbuf_free_arr[0]->pool)) {
- mbuf_free_arr[free_num] = mbuf;
- free_num++;
- } else {
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
-
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
- }
- }
- }
-
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
- } else {
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
- if (mbuf != NULL)
- rte_mempool_put(mbuf->pool, mbuf);
- }
- }
-
-done:
- txq->desc_free_num += txq->rs_thresh;
- txq->next_dd += txq->rs_thresh;
- if (txq->next_dd >= txq->ring_depth)
- txq->next_dd = txq->rs_thresh - 1;
- ret = rs_thresh;
-
-l_end:
- return ret;
-}
-
static __rte_always_inline void
sxe2_tx_desc_fill_one_avx512(volatile union sxe2_tx_data_desc *desc, struct rte_mbuf *pkt,
uint64_t desc_cmd, bool with_offloads)
@@ -207,16 +97,6 @@ void sxe2_tx_desc_fill_avx512(volatile union sxe2_tx_data_desc *desc, struct rte
}
}
-static __rte_always_inline void
-sxe2_tx_pkts_mbuf_fill_avx512(struct sxe2_tx_buffer_vec *buffer,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
- uint16_t i;
-
- for (i = 0; i < nb_pkts; ++i)
- buffer[i].mbuf = tx_pkts[i];
-}
-
static __rte_always_inline uint16_t
sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool with_offloads)
@@ -228,7 +108,7 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
uint16_t tx_num;
if (txq->desc_free_num < txq->free_thresh)
- (void)sxe2_tx_bufs_free_vec_avx512(txq);
+ (void)sxe2_tx_bufs_free_vec(txq);
nb_pkts = RTE_MIN(txq->desc_free_num, nb_pkts);
if (unlikely(nb_pkts == 0)) {
@@ -241,15 +121,14 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += next_use;
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -265,10 +144,10 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = txq->desc_ring;
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -863,5 +742,3 @@ uint16_t sxe2_rx_pkts_scattered_vec_avx512_offload(void *rx_queue,
return sxe2_rx_pkts_scattered_common_vec_avx512(rx_queue,
rx_pkts, nb_pkts, true);
}
-
-#endif
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_common.h b/drivers/net/sxe2/sxe2_txrx_vec_common.h
index 9ac99cf0fa..ede4c236b1 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_common.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec_common.h
@@ -25,10 +25,11 @@
#define SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC 64
static __rte_always_inline void
-sxe2_tx_pkts_mbuf_fill(struct sxe2_tx_buffer *buffer,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+sxe2_tx_pkts_mbuf_fill_vec(struct sxe2_tx_buffer_vec *buffer,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
uint16_t i;
+
for (i = 0; i < nb_pkts; ++i)
buffer[i].mbuf = tx_pkts[i];
}
@@ -36,7 +37,7 @@ sxe2_tx_pkts_mbuf_fill(struct sxe2_tx_buffer *buffer,
static __rte_always_inline int32_t
sxe2_tx_bufs_free_vec(struct sxe2_tx_queue *txq)
{
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
struct rte_mbuf *mbuf;
struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC];
int32_t ret;
@@ -50,7 +51,7 @@ sxe2_tx_bufs_free_vec(struct sxe2_tx_queue *txq)
goto l_end;
}
rs_thresh = txq->rs_thresh;
- buffer = &txq->buffer_ring[txq->next_dd - (rs_thresh - 1)];
+ buffer = &txq->buffer_ring_vec[txq->next_dd - (rs_thresh - 1)];
mbuf = rte_pktmbuf_prefree_seg(buffer[0].mbuf);
if (likely(mbuf)) {
mbuf_free_arr[0] = mbuf;
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_neon.c b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
index 4e5cb87cd5..0b139b8269 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_neon.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
@@ -34,12 +34,58 @@ sxe2_tx_desc_fill_one_neon(volatile union sxe2_tx_data_desc *desc,
vst1q_u64(RTE_CAST_PTR(uint64_t *, desc), data_desc);
}
+static __rte_always_inline void
+sxe2_tx_desc_fill_4_neon_simple(volatile union sxe2_tx_data_desc *desc,
+ struct rte_mbuf **pkts)
+{
+ uint64x2_t d0, d1, d2, d3;
+ uint64x2x4_t v;
+ const uint64_t cmd_base = ((uint64_t)SXE2_TX_DESC_DTYPE_DATA) |
+ ((uint64_t)SXE2_TX_DATA_DESC_CMD_EOP) <<
+ SXE2_TX_DATA_DESC_CMD_SHIFT;
+
+ d0 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[0]),
+ cmd_base |
+ ((uint64_t)pkts[0]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[0]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d1 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[1]),
+ cmd_base |
+ ((uint64_t)pkts[1]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[1]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d2 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[2]),
+ cmd_base |
+ ((uint64_t)pkts[2]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[2]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d3 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[3]),
+ cmd_base |
+ ((uint64_t)pkts[3]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[3]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+
+ v.val[0] = d0;
+ v.val[1] = d1;
+ v.val[2] = d2;
+ v.val[3] = d3;
+ vst1q_u64_x4(RTE_CAST_PTR(uint64_t *, desc), v);
+}
+
static __rte_always_inline uint16_t
sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -59,18 +105,26 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
-
- for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
+ if (with_offloads) {
+ for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ }
+ } else {
+ for (i = 0; i + 3 < res_num - 1; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
sxe2_tx_desc_fill_one_neon(desc, *tx_pkts++,
@@ -82,14 +136,23 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
- for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ if (with_offloads) {
+ for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, true);
+ }
+ } else {
+ for (i = 0; i + 3 < tx_num; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
next_use += tx_num;
@@ -150,22 +213,24 @@ uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue,
}
static __rte_always_inline void
-sxe2_rx_desc_ptype_fill_neon(uint16x8_t staterr, struct rte_mbuf **__rte_restrict rx_pkts)
+sxe2_rx_desc_ptype_fill_neon(uint32x4_t desc_lo,
+ struct rte_mbuf **__rte_restrict rx_pkts,
+ const uint32_t *__rte_restrict ptype_tbl)
{
- uint16x8_t ptype_mask = {
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
+ const uint32x4_t ptype_mask = {
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
};
uint16x8_t ptype_all;
- ptype_all = vandq_u16(staterr, ptype_mask);
+ ptype_all = vreinterpretq_u16_u32(vandq_u32(desc_lo, ptype_mask));
- rx_pkts[3]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
- rx_pkts[2]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
- rx_pkts[1]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
- rx_pkts[0]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[0]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
+ rx_pkts[1]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
+ rx_pkts[2]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[3]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
}
static __rte_always_inline uint32x4_t
@@ -208,9 +273,10 @@ sxe2_rx_desc_fnav_flags_neon(uint64x2_t descs_arr[4])
static __rte_always_inline void
sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
volatile union sxe2_rx_desc *desc,
- uint64x2_t descs[4], struct rte_mbuf **rx_pkts)
+ uint64x2_t descs[4], uint32x4_t desc_lo, uint32x4_t desc_hi,
+ struct rte_mbuf **rx_pkts)
{
- uint32x4_t desc_lo, desc_hi, flags, tmp_flags;
+ uint32x4_t flags, tmp_flags;
const uint64x2_t mbuf_init = {rxq->mbuf_init_value, 0};
uint64x2_t rearm0, rearm1, rearm2, rearm3;
@@ -267,23 +333,6 @@ sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
0, 0, 0, 0, 0, 0, 0, 0
};
- {
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint64x2_t f64, t64;
-
- flags = vzip2q_u32(d1, d0);
- tmp_flags = vzip2q_u32(d3, d2);
- f64 = vreinterpretq_u64_u32(flags);
- t64 = vreinterpretq_u64_u32(tmp_flags);
- desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(f64),
- vget_low_u64(t64)));
- desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(f64),
- vget_high_u64(t64)));
- }
-
desc_lo = vandq_u32(desc_lo, desc_msk);
desc_hi = vandq_u32(desc_hi, rss_msk);
@@ -442,25 +491,39 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
uint64x2_t descs[SXE2_RX_NUM_PER_LOOP_NEON];
uint8x16_t pkt_mb1, pkt_mb2, pkt_mb3, pkt_mb4;
uint64x2_t mbp1, mbp2;
+ uint32x4_t desc_lo, desc_hi;
uint16x8_t staterr;
uint16x8_t tmp;
uint16_t bit_num;
descs[3] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 3));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[2] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 2));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[1] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 1));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[0] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc));
rte_atomic_thread_fence(rte_memory_order_acquire);
-
descs[3] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 3), descs[3], 0);
descs[2] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 2), descs[2], 0);
descs[1] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 1), descs[1], 0);
descs[0] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc), descs[0], 0);
+ {
+ uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
+ uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
+ uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
+ uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
+
+ uint32x4_t q1_01 = vzip2q_u32(d0, d1);
+ uint32x4_t q1_23 = vzip2q_u32(d2, d3);
+ uint64x2_t q1_01_64 = vreinterpretq_u64_u32(q1_01);
+ uint64x2_t q1_23_64 = vreinterpretq_u64_u32(q1_23);
+
+ desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(q1_01_64),
+ vget_low_u64(q1_23_64)));
+ desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(q1_01_64),
+ vget_high_u64(q1_23_64)));
+ }
+
mbp1 = vld1q_u64((uint64_t *)&buffer[i]);
mbp2 = vld1q_u64((uint64_t *)&buffer[i + 2]);
@@ -480,7 +543,8 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
pkt_mb1 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[0]), rvp_shuf_mask);
if (do_offload) {
- sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, &rx_pkts[i]);
+ sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, desc_lo,
+ desc_hi, &rx_pkts[i]);
} else {
const uint64x2_t mbuf_init = {
rxq->mbuf_init_value,
@@ -515,55 +579,48 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
rte_prefetch_non_temporal(desc + SXE2_RX_NUM_PER_LOOP_NEON);
{
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint32x4_t sterr_tmp1 = vzip2q_u32(d1, d0);
- uint32x4_t sterr_tmp2 = vzip2q_u32(d3, d2);
- uint32x4_t sterr_u32 = vzip1q_u32(sterr_tmp1, sterr_tmp2);
-
- staterr = vreinterpretq_u16_u32(sterr_u32);
+ uint16x8_t sterr_tmp1 = vzip2q_u16(vreinterpretq_u16_u64(descs[0]),
+ vreinterpretq_u16_u64(descs[2]));
+ uint16x8_t sterr_tmp2 = vzip2q_u16(vreinterpretq_u16_u64(descs[1]),
+ vreinterpretq_u16_u64(descs[3]));
+ staterr = vzip1q_u16(sterr_tmp1, sterr_tmp2);
}
- sxe2_rx_desc_ptype_fill_neon(staterr, &rx_pkts[i]);
+ sxe2_rx_desc_ptype_fill_neon(desc_lo, &rx_pkts[i], sxe2_ptype_tbl);
if (umbcast_flags != NULL) {
- uint32x4_t umbcast_mask = {
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- };
-
+ const uint32x4_t umbcast_mask =
+ vdupq_n_u32(SXE2_RX_DESC_STATUS_UMBCAST_MASK);
uint8x16_t umbcast_shuf_mask = {
- 0x0B, 0x03, 0x0F, 0x07,
+ 3, 7, 11, 15,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
};
uint8x16_t umbcast_bits =
- vreinterpretq_u8_u32(vandq_u32(vreinterpretq_u32_u16(staterr),
- umbcast_mask));
+ vreinterpretq_u8_u32(vandq_u32(desc_lo, umbcast_mask));
umbcast_bits = vqtbl1q_u8(umbcast_bits, umbcast_shuf_mask);
- vst1q_lane_u32((uint32_t *)umbcast_flags,
- vreinterpretq_u32_u8(umbcast_bits), 0);
+ *(uint32_t *)umbcast_flags =
+ vgetq_lane_u32(vreinterpretq_u32_u8(umbcast_bits), 0);
umbcast_flags += SXE2_RX_NUM_PER_LOOP_NEON;
}
if (split_rxe_flags) {
uint8x16_t eop_shuf_mask = {
- 0x08, 0x00, 0x0C, 0x04,
+ 0, 2, 4, 6,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF};
uint8x16_t eop_bits;
uint32x4_t rxe_mask = {
- 0x2080, 0x2080, 0x2080, 0x2080
+ 0x20802080, 0x20802080, 0x20802080, 0x20802080
};
uint32x4_t rxe_bits;
uint32x4_t eop_mask;
- eop_mask = vshlq_n_u32(vdupq_n_u32(1), SXE2_RX_DESC_STATUS_EOP_SHIFT);
+ eop_mask = vdupq_n_u32((1U << SXE2_RX_DESC_STATUS_EOP_SHIFT) |
+ (1U << (SXE2_RX_DESC_STATUS_EOP_SHIFT + 16)));
eop_bits = vandq_u8(vmvnq_u8(vreinterpretq_u8_u16(staterr)),
vreinterpretq_u8_u32(eop_mask));
@@ -587,12 +644,22 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
}
{
- uint32x4_t dd_mask = vdupq_n_u32(1);
- uint32x4_t sterr_dd = vandq_u32(vreinterpretq_u32_u16(staterr), dd_mask);
- uint16x4_t packed_lo = vmovn_u32(sterr_dd);
- uint64_t dd64 = vget_lane_u64(vreinterpret_u64_u16(packed_lo), 0);
-
- bit_num = (uint16_t)rte_popcount64(dd64);
+ const uint16x8_t dd_check = {
+ 0x0001, 0x0001, 0x0001, 0x0001,
+ 0, 0, 0, 0
+ };
+ uint16x8_t sterr_dd;
+ uint64_t stat;
+ sterr_dd = vandq_u16(staterr, dd_check);
+ sterr_dd = vshlq_n_u16(sterr_dd, 15);
+ sterr_dd =
+ vreinterpretq_u16_s16(vshrq_n_s16(vreinterpretq_s16_u16(sterr_dd),
+ 15));
+ stat = ~vgetq_lane_u64(vreinterpretq_u64_u16(sterr_dd), 0);
+ if (likely(stat == 0))
+ bit_num = SXE2_RX_NUM_PER_LOOP_NEON;
+ else
+ bit_num = (uint16_t)(rte_ctz64(stat) / 16);
}
done_num += bit_num;
if (likely(bit_num != SXE2_RX_NUM_PER_LOOP_NEON))
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_sse.c b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
index c3e8a2983b..181bb40041 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_sse.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
@@ -40,7 +40,7 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -57,11 +57,11 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
tx_num = nb_pkts;
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
@@ -74,9 +74,9 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 31/44] net/sxe2: refine vectorized Tx/Rx mode setup
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (30 preceding siblings ...)
2026-08-27 2:39 ` [PATCH v4 30/44] net/sxe2: unify vectorized Tx buffer handling liujie5
@ 2026-08-27 2:39 ` liujie5
2026-08-27 2:39 ` [PATCH v4 32/44] net/sxe2: fix RSS action attribute validation liujie5
` (12 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Set rte_eth_tx_pkt_prepare_dummy for the simple and vectorized Tx paths
instead of leaving the prepare callback unset, and split the NEON
simple/offload mode selection based on the offload flag. Log the selected
Tx/Rx mode flags and apply the default Rx free threshold when the
configured value is zero.
Fixes: ac60f302cbef ("net/sxe2: add vectorized Rx and Tx")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_rx.c | 3 ++-
drivers/net/sxe2/sxe2_txrx.c | 19 +++++++++++++------
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_rx.c b/drivers/net/sxe2/sxe2_rx.c
index d700c60083..3830c676d7 100644
--- a/drivers/net/sxe2/sxe2_rx.c
+++ b/drivers/net/sxe2/sxe2_rx.c
@@ -319,7 +319,8 @@ int32_t __rte_cold sxe2_rx_queue_setup(struct rte_eth_dev *dev,
rxq->mb_pool = mp;
}
- rxq->rx_free_thresh = rx_conf->rx_free_thresh;
+ rxq->rx_free_thresh = (rx_conf->rx_free_thresh == 0) ?
+ SXE2_DEFAULT_RX_FREE_THRESH : rx_conf->rx_free_thresh;
rxq->port_id = dev->data->port_id;
rxq->offloads = offloads;
if (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
diff --git a/drivers/net/sxe2/sxe2_txrx.c b/drivers/net/sxe2/sxe2_txrx.c
index 79870866d1..d27d2ce630 100644
--- a/drivers/net/sxe2/sxe2_txrx.c
+++ b/drivers/net/sxe2/sxe2_txrx.c
@@ -358,7 +358,7 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
if (tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
#ifdef RTE_ARCH_X86
if (tx_mode_flags & SXE2_TX_MODE_VEC_AVX512) {
#ifdef CC_AVX512_SUPPORT
@@ -386,21 +386,25 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
#elif defined(RTE_ARCH_ARM64)
if (tx_mode_flags & SXE2_TX_MODE_VEC_NEON) {
- dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
- } else {
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ if (tx_mode_flags & SXE2_TX_MODE_VEC_OFFLOAD) {
+ dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
+ } else {
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ }
}
#endif
} else {
if (tx_mode_flags & SXE2_TX_MODE_SIMPLE_BATCH) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
dev->tx_pkt_burst = sxe2_tx_pkts_simple;
} else {
dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
dev->tx_pkt_burst = sxe2_tx_pkts;
}
}
+ PMD_LOG_DEBUG(TX, "Tx mode flags:0x%016x port_id:%u.",
+ tx_mode_flags, dev->data->port_id);
}
static const struct {
@@ -582,6 +586,9 @@ void sxe2_rx_mode_func_set(struct rte_eth_dev *dev)
dev->rx_pkt_burst = sxe2_rx_pkts_scattered_split;
else
dev->rx_pkt_burst = sxe2_rx_pkts_scattered;
+
+ PMD_LOG_DEBUG(RX, "Rx mode flags:0x%016x port_id:%u.",
+ rx_mode_flags, dev->data->port_id);
}
static const struct {
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 32/44] net/sxe2: fix RSS action attribute validation
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (31 preceding siblings ...)
2026-08-27 2:39 ` [PATCH v4 31/44] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
@ 2026-08-27 2:39 ` liujie5
2026-08-27 2:39 ` [PATCH v4 33/44] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
` (11 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The rss->level/key_len/queue_num checks only set the rte_flow_error
but still return 0 (success), so invalid RSS configurations are
accepted instead of being rejected with ENOTSUP.
Return the error code from the validation checks, matching the
behavior in the V3 implementation.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_flow_parse_action.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index db70b146c6..b0275321be 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -12,7 +12,7 @@
static int32_t sxe2_flow_check_rss_action_attr(const struct rte_flow_action_rss *rss,
struct rte_flow_error *error)
{
- int32_t ret = ENOTSUP;
+ int32_t ret = -ENOTSUP;
switch (rss->func) {
case RTE_ETH_HASH_FUNCTION_DEFAULT:
case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
@@ -25,15 +25,21 @@ static int32_t sxe2_flow_check_rss_action_attr(const struct rte_flow_action_rss
goto l_end;
}
- if (rss->level > 2)
+ if (rss->level > 2) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"RSS level is could not be greater than 2");
- if (rss->key_len)
+ goto l_end;
+ }
+ if (rss->key_len) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a nonzero RSS key_len is not supported");
- if (rss->queue_num)
+ goto l_end;
+ }
+ if (rss->queue_num) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a non-NULL RSS queue is not supported");
+ goto l_end;
+ }
ret = 0;
l_end:
return ret;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 33/44] net/sxe2: restore PF-only guard in udp tunnel port add
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (32 preceding siblings ...)
2026-08-27 2:39 ` [PATCH v4 32/44] net/sxe2: fix RSS action attribute validation liujie5
@ 2026-08-27 2:39 ` liujie5
2026-08-27 2:39 ` [PATCH v4 34/44] net/sxe2: restore link update call in status query liujie5
` (10 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_udp_tunnel_port_add_common() lost the check that restricts
UDP tunnel port configuration to PF devices (not VF or
representor), so VF/representor devices can now attempt to add
UDP tunnel ports, which the hardware does not support.
Restore the PF-only guard returning -ENOTSUP, matching the V3
implementation.
Fixes: fff24885f70a ("net/sxe2: support custom UDP tunnel ports")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 19f81f47c9..0ddc0e1e0e 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -630,6 +630,10 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
struct sxe2_udp_tunnel_cfg *tunnel_config;
int32_t ret = -1;
+ if (ad->dev_type != SXE2_DEV_T_PF || ad->is_dev_repr) {
+ ret = -ENOTSUP;
+ goto l_end;
+ }
rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
tunnel_config = &ad->udp_tunnel_ctx.tunnel_conf[tunnel_proto];
@@ -659,6 +663,7 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
l_unlock_end:
rte_spinlock_unlock(&ad->udp_tunnel_ctx.lock);
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 34/44] net/sxe2: restore link update call in status query
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (33 preceding siblings ...)
2026-08-27 2:39 ` [PATCH v4 33/44] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
@ 2026-08-27 2:39 ` liujie5
2026-08-27 2:39 ` [PATCH v4 35/44] net/sxe2: validate representor ID against VF count liujie5
` (9 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_mac_link_status_get() no longer calls sxe2_link_update()
after refreshing the link context, so the ethdev link state is only
refreshed during device init (sxe2_link_update_init) and never
updated when link status is queried at runtime, including on LSC
interrupt events.
Move the sxe2_link_update() call back into
sxe2_drv_mac_link_status_get() and simplify sxe2_link_update_init()
accordingly, matching the V3 implementation.
Fixes: 1d7fd921beef ("net/sxe2: support link update")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 2 ++
drivers/net/sxe2/sxe2_mac.c | 9 +--------
2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 16a2c3fea4..705d259412 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -412,6 +412,7 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
{
int32_t ret = 0;
struct sxe2_common_device *cdev = adapter->cdev;
+ struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
struct sxe2_drv_cmd_params param = {0};
struct sxe2_drv_link_info_resp resp = {0};
@@ -425,6 +426,7 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
}
adapter->link_ctxt.speed = resp.speed;
adapter->link_ctxt.link_up = resp.status;
+ (void)sxe2_link_update(dev, 0);
l_end:
return ret;
diff --git a/drivers/net/sxe2/sxe2_mac.c b/drivers/net/sxe2/sxe2_mac.c
index 729c804ac3..7dbea92670 100644
--- a/drivers/net/sxe2/sxe2_mac.c
+++ b/drivers/net/sxe2/sxe2_mac.c
@@ -448,18 +448,11 @@ int32_t sxe2_link_update_init(struct rte_eth_dev *dev)
int32_t ret;
PMD_INIT_FUNC_TRACE();
-
rte_spinlock_init(&adapter->link_ctxt.link_lock);
-
ret = sxe2_drv_mac_link_status_get(adapter);
- if (ret) {
+ if (ret)
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get link status, ret=%d", ret);
- goto l_end;
- }
- (void)sxe2_link_update(dev, 0);
-
-l_end:
return ret;
}
int32_t sxe2_link_update(struct rte_eth_dev *dev, __rte_unused int32_t wait_to_complete)
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 35/44] net/sxe2: validate representor ID against VF count
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (34 preceding siblings ...)
2026-08-27 2:39 ` [PATCH v4 34/44] net/sxe2: restore link update call in status query liujie5
@ 2026-08-27 2:39 ` liujie5
2026-08-27 2:39 ` [PATCH v4 36/44] net/sxe2: use primary VSI ID for representor VSI liujie5
` (8 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_switchdev_repr_private_data_init() indexes
parent_adapter->repr_ctxt.repr_vf_id[repr_id] without checking that
repr_id is within the number of configured VFs, which can access out
of bounds when an invalid representor ID is passed.
Add a bounds check on repr_id against repr_ctxt.nb_vf and return
-EINVAL on the error path.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_switchdev.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index efb1468b91..d0304ccc94 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -312,6 +312,12 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_q_id = repr_id;
repr_priv_data->repr_pf_id = parent_adapter->pf_idx;
repr_priv_data->repr_vf_id = repr_id;
+ if (repr_id >= parent_adapter->repr_ctxt.nb_vf) {
+ PMD_LOG_ERR(INIT, "repr_id %u exceed max vf %u",
+ repr_id, parent_adapter->repr_ctxt.nb_vf);
+ ret = -EINVAL;
+ goto l_free;
+ }
repr_priv_data->repr_vf_primary_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
repr_priv_data->repr_vf_backup_vsi_id =
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 36/44] net/sxe2: use primary VSI ID for representor VSI
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (35 preceding siblings ...)
2026-08-27 2:39 ` [PATCH v4 35/44] net/sxe2: validate representor ID against VF count liujie5
@ 2026-08-27 2:39 ` liujie5
2026-08-27 2:39 ` [PATCH v4 37/44] net/sxe2: wrap command params fill debug log in macro liujie5
` (7 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
repr_priv_data->repr_vf_vsi_id is assigned with a ternary that falls
back to the backup (dpdk) VSI ID when the kernel VSI ID is invalid.
The V3 implementation assigns it directly from
repr_vf_primary_vsi_id.
Align with the V3 implementation by assigning repr_vf_vsi_id from
repr_vf_primary_vsi_id.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_switchdev.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index d0304ccc94..81ced7b855 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -323,11 +323,7 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
- repr_priv_data->repr_vf_vsi_id =
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id !=
- SXE2_INVALID_VSI_ID ?
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id :
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
+ repr_priv_data->repr_vf_vsi_id = repr_priv_data->repr_vf_primary_vsi_id;
adapter->repr_priv_data = repr_priv_data;
goto l_end;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 37/44] net/sxe2: wrap command params fill debug log in macro
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (36 preceding siblings ...)
2026-08-27 2:39 ` [PATCH v4 36/44] net/sxe2: use primary VSI ID for representor VSI liujie5
@ 2026-08-27 2:39 ` liujie5
2026-08-27 2:40 ` [PATCH v4 38/44] net/sxe2: restore Rx queue buffer split fill support liujie5
` (6 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_cmd_params_fill() passes the opcode string as a parameter to
__sxe2_drv_cmd_params_fill() just to emit a debug log, and the debug
log is executed unconditionally on every command fill.
Move the PMD_DEV_LOG_DEBUG into the macro body wrapped in a do/while
block, dropping the opc_str parameter so the opcode stringization is
performed at the call site and the macro is a proper multi-statement
block.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 705d259412..b17d80d917 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -26,10 +26,9 @@ static void sxe2_drv_trace_id_alloc(uint64_t *trace_id)
}
static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
- struct sxe2_drv_cmd_params *cmd, uint32_t opc, const char *opc_str,
+ struct sxe2_drv_cmd_params *cmd, uint32_t opc,
void *in_data, uint32_t in_len, void *out_data, uint32_t out_len)
{
- PMD_DEV_LOG_DEBUG(adapter, DRV, "cmd opcode:%s", opc_str);
cmd->timeout = SXE2_DRV_CMD_DFLT_TIMEOUT;
cmd->opcode = opc;
cmd->vsi_id = adapter->vsi_ctxt.dpdk_vsi_id;
@@ -44,8 +43,10 @@ static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
}
#define sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len) \
- __sxe2_drv_cmd_params_fill(adapter, cmd, opc, #opc, in_data, in_len, out_data, out_len)
-
+ do { \
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "cmd opcode:%s", #opc); \
+ __sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len); \
+ } while (0)
int32_t sxe2_drv_dev_caps_get(struct sxe2_adapter *adapter, struct sxe2_drv_dev_caps_resp *dev_caps)
{
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 38/44] net/sxe2: restore Rx queue buffer split fill support
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (37 preceding siblings ...)
2026-08-27 2:39 ` [PATCH v4 37/44] net/sxe2: wrap command params fill debug log in macro liujie5
@ 2026-08-27 2:40 ` liujie5
2026-08-27 2:40 ` [PATCH v4 39/44] net/sxe2: skip tunnel config fill on get failure liujie5
` (5 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The V4 branch dropped sxe2_rxq_buf_split_fill() and the buffer split
handling in sxe2_rxq_ctxt_cfg_fill(), so the Rx buffer split offload
(RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) is advertised in device info but
the per-queue context never configures split_en/split_type_mask/
hdr_len, and buffer split packets are not handled correctly.
Restore the sxe2_rxq_buf_split_fill() helper and the buffer split
branch in sxe2_rxq_ctxt_cfg_fill(), matching the V3 implementation.
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 88 ++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b17d80d917..ce74af87cc 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -194,6 +194,84 @@ int32_t sxe2_drv_vsi_del(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi)
#define SXE2_RXQ_CTXT_CFG_BUF_LEN_ALIGN (1 << 7)
#define SXE2_RX_HDR_SIZE 256
+static int32_t sxe2_rxq_buf_split_fill(struct sxe2_rx_queue *rxq,
+ struct sxe2_drv_rxq_ctxt *ctxt)
+{
+ uint32_t proto_hdr;
+
+ proto_hdr = rxq->rx_seg[0].proto_hdr;
+ if (proto_hdr == RTE_PTYPE_UNKNOWN) {
+ PMD_LOG_ERR(RX, "Buffer split protocol must be configured");
+ return -EINVAL;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L4_MASK) {
+ case RTE_PTYPE_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_TCP;
+ goto l_end;
+ case RTE_PTYPE_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_UDP;
+ goto l_end;
+ case RTE_PTYPE_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_SCTP;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L3_MASK) {
+ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV4;
+ goto l_end;
+ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV6;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L2_MASK) {
+ case RTE_PTYPE_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_L2_ETHER;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L4_MASK) {
+ case RTE_PTYPE_INNER_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_TCP;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_UDP;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_SCTP;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L3_MASK) {
+ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV4;
+ goto l_end;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV6;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L2_MASK) {
+ case RTE_PTYPE_INNER_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L2_ETHER;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_TUNNEL_MASK) {
+ case RTE_PTYPE_TUNNEL_GRENAT:
+ ctxt->split_type_mask = SXE2_PTYPE_TUNNEL_GRENAT;
+ goto l_end;
+ }
+
+ PMD_LOG_ERR(RX, "Buffer split protocol is not supported");
+ return -ENOTSUP;
+l_end:
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ return 0;
+}
+
static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
struct sxe2_drv_rxq_cfg_req *req, uint16_t rxq_cnt)
{
@@ -227,7 +305,17 @@ static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
else
ctxt->keep_crc_en = 0;
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
+ ret = sxe2_rxq_buf_split_fill(rxq, ctxt);
+ if (ret)
+ goto l_end;
+ ctxt->split_en = 1;
+ } else {
+ ctxt->split_en = 0;
+ }
+
ctxt->desc_size = sizeof(union sxe2_rx_desc);
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 39/44] net/sxe2: skip tunnel config fill on get failure
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (38 preceding siblings ...)
2026-08-27 2:40 ` [PATCH v4 38/44] net/sxe2: restore Rx queue buffer split fill support liujie5
@ 2026-08-27 2:40 ` liujie5
2026-08-27 2:40 ` [PATCH v4 40/44] net/sxe2: skip flow id assignment on filter add failure liujie5
` (4 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_udp_tunnel_get() fills tunnel_config fields even when the
firmware command fails, so a failed get overwrites the config with
the (zero-initialized) response data instead of leaving it intact.
Return early with the error code when sxe2_drv_cmd_exec() fails,
matching the V3 implementation.
Fixes: fff24885f70a ("net/sxe2: support custom UDP tunnel ports")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index ce74af87cc..c5bd73244b 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1651,15 +1651,17 @@ int32_t sxe2_drv_udp_tunnel_get(struct sxe2_adapter *adapter,
&req, sizeof(req),
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_LOG_ERR(DRV, "Failed to get udp proto %d port, ret=%d", req.type, ret);
+ goto l_end;
+ }
tunnel_config->fw_port = resp.port;
tunnel_config->fw_status = resp.enable;
tunnel_config->fw_dst_en = resp.dst;
tunnel_config->fw_src_en = resp.src;
tunnel_config->fw_used = resp.fw_used;
-
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 40/44] net/sxe2: skip flow id assignment on filter add failure
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (39 preceding siblings ...)
2026-08-27 2:40 ` [PATCH v4 39/44] net/sxe2: skip tunnel config fill on get failure liujie5
@ 2026-08-27 2:40 ` liujie5
2026-08-27 2:40 ` [PATCH v4 41/44] net/sxe2: fix command channel log messages liujie5
` (3 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_flow_filter_add() assigns flow->flow_id from the response
even when the firmware command fails, overwriting any previously
set flow id with the zero-initialized response value.
Return early on command failure so flow->flow_id is preserved, and
set flow->create_err on both the success and error paths.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index c5bd73244b..fa73b8a8b7 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1819,9 +1819,13 @@ int32_t sxe2_drv_flow_filter_add(struct sxe2_adapter *adapter, struct sxe2_flow
sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_FILTER_ADD, &req,
sizeof(req), &resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to add flow filter, ret: %d.", ret);
+ goto l_end;
+ }
flow->flow_id = resp.flow_id;
+
+l_end:
flow->create_err = ret;
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 41/44] net/sxe2: fix command channel log messages
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (40 preceding siblings ...)
2026-08-27 2:40 ` [PATCH v4 40/44] net/sxe2: skip flow id assignment on filter add failure liujie5
@ 2026-08-27 2:40 ` liujie5
2026-08-27 2:40 ` [PATCH v4 42/44] net/sxe2: align command structs with historical kernel layout liujie5
` (2 subsequent siblings)
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Several error/warning messages in sxe2_cmd_chnl.c are inaccurate or
lost context:
- vsi_info_get: message lost the vsi id; restore it
- rxq_bind_irq/rxq_unbind_irq: message lost the rxq index; restore it
- promisc_config: fix "promic" typo in the message
- queue_info_get_update/rxq_mapping_set: incorrect "get queue info
map"/"get dev caps" wording; use "rx queue mapping failed"
- txq_mapping_set: "Rx queue" should read "Tx queue"; incorrect
"get dev caps" wording should read "tx queue mapping failed"
Fixes: a2b79a93515e ("net/sxe2: support L2 filtering and MAC config")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index fa73b8a8b7..9bd6e3355f 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -480,7 +480,7 @@ int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi
&vsi_info_get_resp, sizeof(vsi_info_get_resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_DEV_LOG_ERR(adapter, DRV, "switchdev cpvsi info get failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "vsi %u info get failed, ret=%d", vsi->vsi_id, ret);
goto l_end;
}
@@ -538,7 +538,7 @@ int32_t sxe2_drv_rxq_bind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx, ui
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq bind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u bind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -558,7 +558,7 @@ int32_t sxe2_drv_rxq_unbind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx)
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq unbind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u unbind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -759,7 +759,7 @@ int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set)
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_WARN(adapter, DRV, "promic config failed, ret=%d", ret);
+ PMD_DEV_LOG_WARN(adapter, DRV, "promisc config failed, ret=%d", ret);
return ret;
}
@@ -1684,7 +1684,7 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_LOG_ERR(DRV, "get queue info map failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
goto l_end;
}
@@ -1728,7 +1728,7 @@ int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
l_end:
return ret;
@@ -1745,7 +1745,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
txq = eth_dev->data->tx_queues[queue_id];
if (txq == NULL) {
- PMD_LOG_ERR(DRV, "Rx queue %u is not available or setup", queue_id);
+ PMD_LOG_ERR(DRV, "Tx queue %u is not available or setup", queue_id);
ret = -EINVAL;
goto l_end;
}
@@ -1759,7 +1759,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "tx queue mapping failed, ret=%d", ret);
l_end:
return ret;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 42/44] net/sxe2: align command structs with historical kernel layout
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (41 preceding siblings ...)
2026-08-27 2:40 ` [PATCH v4 41/44] net/sxe2: fix command channel log messages liujie5
@ 2026-08-27 2:40 ` liujie5
2026-08-27 2:40 ` [PATCH v4 43/44] common/sxe2: fix ioctl channel log and close handling liujie5
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The sxe2_drv_cmd.h command structures must match the layout used by
historical SXE2 kernel versions so the same firmware command ABI is
shared. Several structures were declared with __rte_packed_begin/
__rte_packed_end and extra rsv padding that the kernel layout does
not have:
- sxe2_drv_link_info_resp: drop rsv[3] padding
- sxe2_tm_res: drop rsv[2] padding and packed attribute
- sxe2_tm_info: drop packed attribute
- sxe2_tm_add_mid_msg: drop packed attribute
- sxe2_tm_add_queue_msg: drop packed attribute
- sxe2_drv_sfp_req: drop packed attribute
- sxe2_drv_sfp_resp: drop packed attribute
Keep the structure members as-is so the command ABI is compatible
with the historical kernel driver.
Fixes: 9c894f75113f ("net/sxe2: support TM hierarchy and shaping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_drv_cmd.h | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index cc71e2364e..5274b59a6a 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -230,7 +230,6 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_info_get_resp {
struct __rte_aligned(4) __rte_packed_begin sxe2_drv_link_info_resp {
uint32_t speed;
uint8_t status;
- uint8_t rsv[3];
} __rte_packed_end;
struct __rte_aligned(4) __rte_packed_begin sxe2_switchdev_info {
@@ -348,18 +347,17 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_rss_hf_req {
uint8_t rsv1[3];
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_res {
+struct sxe2_tm_res {
uint16_t teid;
- uint8_t rsv[2];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_info {
+struct sxe2_tm_info {
uint32_t committed;
uint32_t peak;
uint8_t priority;
uint8_t reserve;
uint16_t weight;
-} __rte_packed_end;
+};
struct __rte_aligned(4) __rte_packed_begin sxe2_tm_add_mid_msg {
uint16_t parent_teid;
@@ -633,7 +631,7 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_udp_tunnel_resp {
uint8_t rsv;
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
+struct sxe2_drv_sfp_req {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t bus_addr;
@@ -642,14 +640,14 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
uint16_t data_len;
uint16_t rvd;
uint8_t data[];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_resp {
+struct sxe2_drv_sfp_resp {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t data_len;
uint8_t data[];
-} __rte_packed_end;
+};
enum sxe2_fc_type {
SXE2_FC_T_DIS = 0,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 43/44] common/sxe2: fix ioctl channel log and close handling
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (42 preceding siblings ...)
2026-08-27 2:40 ` [PATCH v4 42/44] net/sxe2: align command structs with historical kernel layout liujie5
@ 2026-08-27 2:40 ` liujie5
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
44 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Compare sxe2_ioctl_chnl.c against the reference implementation and
fix the following discrepancies:
- sxe2_drv_dev_close: only log the closed fd when it is valid, move
PMD_LOG_INFO inside the fd >= 0 check
- sxe2_drv_dev_mmap: fix swapped format arguments in the debug log
(cmd_fd and bar_idx were passed in the wrong order)
- sxe2_drv_dev_dma_unmap: use PMD_LOG_ERR instead of PMD_LOG_INFO
for the ioctl failure message
Fixes: 83866f8d7638 ("common/sxe2: add base driver skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_ioctl_chnl.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index 3e2fbf572f..e62ca42a8f 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -107,9 +107,11 @@ sxe2_drv_dev_close(struct sxe2_common_device *cdev)
{
int32_t fd = SXE2_CDEV_TO_CMD_FD(cdev);
- if (fd >= 0)
+ if (fd >= 0) {
close(fd);
- PMD_LOG_INFO(COM, "closed device fd=%d", fd);
+ PMD_LOG_INFO(COM, "closed device fd=%d", fd);
+ }
+
SXE2_CDEV_TO_CMD_FD(cdev) = SXE2_CMD_FD_INVALID;
}
@@ -350,7 +352,7 @@ void
}
PMD_LOG_DEBUG(COM, "fd=%d, bar idx=%d, len=%"PRIu64", src=0x%"PRIx64", offset=0x%"PRIx64"",
- bar_idx, cmd_fd, len, offset, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
+ cmd_fd, bar_idx, len, offset, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
virt = mmap(NULL, len, PROT_READ | PROT_WRITE,
MAP_SHARED, cmd_fd, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
@@ -477,7 +479,7 @@ sxe2_drv_dev_dma_unmap(struct sxe2_common_device *cdev, uint64_t iova)
pthread_mutex_lock(&cdev->config.lock);
ret = ioctl(cmd_fd, SXE2_COM_CMD_DMA_UNMAP, &cmd_params);
if (ret < 0) {
- PMD_LOG_INFO(COM, "Failed to dma unmap, fd=%d, ret=%d, err:%s",
+ PMD_LOG_ERR(COM, "Failed to dma unmap, fd=%d, ret=%d, err:%s",
cmd_fd, ret, strerror(errno));
ret = -EIO;
pthread_mutex_unlock(&cdev->config.lock);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
` (43 preceding siblings ...)
2026-08-27 2:40 ` [PATCH v4 43/44] common/sxe2: fix ioctl channel log and close handling liujie5
@ 2026-08-27 2:40 ` liujie5
2026-08-28 3:23 ` [PATCH v5 00/45] net/sxe2: add Stars SXE2 net driver with fixes liujie5
` (45 more replies)
44 siblings, 46 replies; 207+ messages in thread
From: liujie5 @ 2026-08-27 2:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The drv-sw-stats devarg is no longer supported. Remove its
parameter description from the Runtime Configuration section.
The "Receive Software Statistics" xstats section is kept because
the rx_sw_* counters are still accumulated in the Rx data path
and reported through rte_eth_xstats_get().
Fixes: 9e95b2b3859c ("doc: update sxe2 guide and features")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
doc/guides/nics/sxe2.rst | 31 ++-----------------------------
1 file changed, 2 insertions(+), 29 deletions(-)
diff --git a/doc/guides/nics/sxe2.rst b/doc/guides/nics/sxe2.rst
index c5b400a8ba..fe4f9f916b 100644
--- a/doc/guides/nics/sxe2.rst
+++ b/doc/guides/nics/sxe2.rst
@@ -109,30 +109,6 @@ Runtime Configuration
Default value is 3 (count both packets and bytes).
-- ``drv-sw-stats`` parameter [int]
-
- This parameter controls whether per-packet software statistics (SW stats)
- are collected in the Rx data path.
-
- Hardware packet statistic counters may be inaccurate for certain packet types
- due to hardware design limitations.
- When accuracy of Rx packet classification statistics is critical,
- enabling this parameter allows the driver to accumulate statistics in software
- as packets are received, providing an alternative statistical path
- that bypasses hardware counter inaccuracies.
-
- - 0: Disable software statistics collection (default).
- The basic port statistics (``ipackets``, ``ibytes``) are reported
- from the hardware counters.
- - 1: Enable software statistics collection.
- Per-packet software statistics are accumulated for unicast,
- multicast, broadcast, and dropped packets in the Rx data path.
-
- When enabled, the following extended statistics (xstats) are available:
- ``rx_sw_unicast_packets``, ``rx_sw_multicast_packets``,
- ``rx_sw_broadcast_packets``, ``rx_sw_drop_packets``,
- and ``rx_sw_drop_bytes``.
-
- ``no-sched-mode`` parameter [int]
This parameter enables non-scheduling mode (no-sched mode).
@@ -208,8 +184,7 @@ reflect the actual packets processed by the driver.
Receive Software Statistics
These counters are collected in the Rx data path
- when ``drv-sw-stats=1`` is configured (see the ``drv-sw-stats`` devarg above).
- When ``drv-sw-stats`` is disabled (default), these xstats report zero.
+ on every received packet.
- ``rx_sw_unicast_packets``: Number of unicast packets received.
- ``rx_sw_multicast_packets``: Number of multicast packets received.
@@ -217,10 +192,8 @@ Receive Software Statistics
- ``rx_sw_drop_packets``: Number of packets dropped in the Rx data path.
- ``rx_sw_drop_bytes``: Number of bytes dropped in the Rx data path.
- When ``drv-sw-stats`` is enabled, the basic counters
- ``ipackets`` and ``ibytes`` (from ``rte_eth_stats``)
+ The basic counters ``ipackets`` and ``ibytes`` (from ``rte_eth_stats``)
also reflect the software-accumulated packet and byte counts.
- Otherwise, they are reported from hardware counters.
Fnav Flow Engine Statistics
The Fnav flow engine statistics type is controlled by
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* Re: [PATCH v4 00/44] net/sxe2: add Stars SXE2 net driver with fixes
2026-08-27 2:36 ` [PATCH v4 00/44] net/sxe2: add Stars SXE2 net driver with fixes liujie5
@ 2026-08-27 15:14 ` Stephen Hemminger
0 siblings, 0 replies; 207+ messages in thread
From: Stephen Hemminger @ 2026-08-27 15:14 UTC (permalink / raw)
To: liujie5; +Cc: dev
On Thu, 27 Aug 2026 10:36:18 +0800
liujie5@linkdatatechnology.com wrote:
> From: Jie Liu <liujie5@linkdatatechnology.com>
>
> This series adds the Stars SXE2 network driver together with a set of
> fixes accumulated while validating the driver against the historical
> kernel implementation and reviewing the code.
>
> This is the v4 revision.
This is in much closer to being ready, AI still has some useful
feedback. You don't have to address all of it but it is informative
and helpful.
Review of [PATCH v4 00/44] net/sxe2 fixes and improvements
Reviewed against the series applied with git am on top of
d55ccd4 ("pci: remove deprecated catch-all flag"). Findings are
against the post-apply tree, not the diffs in isolation. Patches
with no findings are omitted.
Patch 06/44 - net/sxe2: fix VSI lifecycle management
Warning: the patch fixes the dangling main_vsi pointer but leaves the
same problem on other_vsi_list. sxe2_vsi_destroy() frees list members
with a bare rte_free() and never unlinks them. The unlink lives in
sxe2_vsi_node_free(), which only fires for SXE2_VSI_T_ESW:
if (vsi->vsi_type == SXE2_VSI_T_ESW)
TAILQ_REMOVE(&adapter->vsi_ctxt.other_vsi_list, vsi, next);
but sxe2_other_vsi_create() inserts nodes as SXE2_VSI_T_DPDK_ESW, and
SXE2_VSI_T_ESW is never assigned anywhere in the driver. So the
removal never happens, and after sxe2_vsi_uninit() the list head still
points at freed memory. sxe2_switchdev_repr_private_data_init() reads
that head via TAILQ_FIRST().
Either add TAILQ_REMOVE() to sxe2_vsi_destroy() for list members, or
fix the type test in sxe2_vsi_node_free() to SXE2_VSI_T_DPDK_ESW.
Patch 10/44 - net/sxe2: validate IPsec key length against maximum limit
Error: the added check is dead code. sxe2_security_valid_key() already
tests the same condition as its first statement in the base tree:
static bool sxe2_security_valid_key(uint16_t src_key, ...)
{
bool is_valid = false;
if (src_key > SXE2_IPSEC_MAX_KEY_LEN) { <-- pre-existing
is_valid = false;
goto l_end;
}
...
The new copy is placed after the increment check, where src_key has
already been proven <= SXE2_IPSEC_MAX_KEY_LEN, so the branch can never
be taken. The patch is a no-op and the buffer-overflow protection it
describes is already present. Drop the patch.
Patch 14/44 - net/sxe2: fill MAC and queue counts in device info
Info: nb_rx_queues and nb_tx_queues are overwritten by ethdev
immediately after the PMD callback returns:
lib/ethdev/rte_ethdev.c:4146
dev_info->nb_rx_queues = dev->data->nb_rx_queues;
dev_info->nb_tx_queues = dev->data->nb_tx_queues;
Those two lines have no effect. max_mac_addrs is the useful part of
the patch; consider dropping the queue-count hunk and adjusting the
commit message.
Patch 15/44 - net/sxe2: fix QinQ and RSS offload capability report
Error: neither capability the patch claims to gate is actually gated.
RTE_ETH_TX_OFFLOAD_QINQ_INSERT is still in the unconditional
tx_offload_capa initialiser and is OR'd in again inside the port-VLAN
branch, so it is always advertised:
dev_info->tx_offload_capa =
RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
RTE_ETH_TX_OFFLOAD_QINQ_INSERT | <-- still here
...
if (!sxe2_dev_port_vlan_check(dev)) {
dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
RTE_ETH_RX_OFFLOAD_RSS_HASH is added unconditionally to the base list
and is still set under the capability test, which now cannot make any
difference:
dev_info->rx_offload_capa = ... | RTE_ETH_RX_OFFLOAD_RSS_HASH;
...
if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_RSS) {
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
Advertising RSS_HASH when SXE2_DEV_CAPS_OFFLOAD_RSS is clear tells the
application the PMD can deliver an RSS hash on a device that has no RSS
capability. Remove QINQ_INSERT from the base tx list, and pick one
place for RSS_HASH.
The RTE_ETH_RX_OFFLOAD_QINQ_STRIP hunk is correct - it is removed from
the base list and only added under the guard.
Patches 21/44 and 22/44 - dev close / dev init ordering
Warning: after both patches the two teardown paths still disagree on
switchdev, and dev_close does not follow reverse-init order for
fc_state.
sxe2_dev_init() error unwind:
sw_uninit -> eth_uinit -> switchdev_uninit -> vsi_uninit
sxe2_dev_close():
switchdev_uninit -> sw_uninit -> eth_uinit -> vsi_uninit
sxe2_fc_state_init() runs before sxe2_sched_init() in dev_init, so
reverse order puts sxe2_fc_state_uinit() right after sxe2_sched_uinit()
in close; it is currently the last call in the function.
Since 21/44 is specifically "align dev init and cleanup order", it
would be good to finish the job so the two paths are identical.
Patch 23/44 - net/sxe2: simplify switchdev representor matching
Error: this breaks the common representor devarg form. The new PF
match loop is:
for (port_idx = 0; port_idx < req_eth_da->nb_ports; ++port_idx)
if (adapter->switchdev_info.pf_num ==
req_eth_da->ports[port_idx])
break;
if (port_idx == req_eth_da->nb_ports) {
rte_errno = EBUSY;
return false;
}
rte_eth_devargs_parse_representor_ports() only fills eth_da->ports and
nb_ports when the devarg carries a "pf#" prefix (see
lib/ethdev/ethdev_private.c). For "representor=vf0",
"representor=[0-3]" and the legacy bare-number form, nb_ports stays 0.
The loop body then never executes, port_idx == 0 == nb_ports, and the
function returns false. sxe2_eth_pmd_probe_pf() turns that into
-ENOTSUP and no representor is ever created.
The old code read ports[0] (zero when unset), so it happened to work.
The fix needs to treat nb_ports == 0 as "no PF constraint given" and
skip the check.
Warning: the RTE_ETH_REPRESENTOR_PF case now falls through to the same
loop that matches representor_ports[] against repr_vf_id[i].func_id.
For a PF representor those entries are PF indices, not VF function IDs,
so the comparison is against the wrong table. The driver only ever
creates VF representors (sxe2_switchdev_repr_devs_init() formats names
as "..._representor_vf%u"), so it may be simpler to reject
RTE_ETH_REPRESENTOR_PF outright.
Info: dead store.
uint16_t port_idx = UINT16_MAX;
is unconditionally overwritten by the for loop initialiser on the next
use. Drop the initialiser.
Patch 26/44 - net/sxe2: add ACL engine event statistics support
Warning: two unrelated changes are bundled in.
First, the act_count NULL guard is applied to the existing FNAV path,
not just the new ACL path:
act_count = action->conf;
flow->action.count.user_id = (act_count == NULL) ? 0 : act_count->id;
That is a NULL-dereference fix for RTE_FLOW_ACTION_TYPE_COUNT with a
NULL conf, and it belongs in its own patch with a Fixes: tag and
Cc: stable@dpdk.org.
Second, the sxe2_queue.c hunk
if (adapter->flow_ctxt.fnav_inited)
rxq->fnav_enable = true;
has nothing to do with ACL statistics and is not mentioned in the
commit message.
Info: widening sxe2_flow_cid_mgr.stat_index from uint16_t to uint32_t
fixes a real truncation on the existing FNAV path, since
sxe2_drv_flow_fnav_get_stat_id() returns a uint32_t stat id. Worth
calling out in the commit message (or splitting out) rather than
folding it in silently.
Info: sxe2_drv_acl_query_stat_req and sxe2_drv_acl_query_stat_resp are
byte-for-byte identical to the existing
sxe2_drv_flow_fnav_query_stat_req and
sxe2_drv_flow_fnav_query_stat_resp. Reuse the existing types, or
give them a neutral name shared by both engines.
Info: the FNAV and ACL arms in sxe2_flow_parse_action() are ten-line
copies of each other differing only in fnav_hw_res vs acl_hw_res.
Select the resource pointer first and share the body.
Patch 30/44 - net/sxe2: unify vectorized Tx buffer handling
Warning: the subject and commit message describe Tx buffer handling
only, but the patch also rewrites a large part of the NEON Rx data
path:
- sxe2_rx_desc_ptype_fill_neon() changes signature, input vector and
packet-to-lane mapping
- the staterr construction changes from vzip2q_u32 on 32-bit lanes to
vzip2q_u16 on 16-bit lanes
- the DD count changes from rte_popcount64() of the DD bits to
rte_ctz64() of the inverted mask, which changes the result when DD
bits are not contiguous
- the eop, umbcast and rxe shuffle masks and constants all change
- three rte_atomic_thread_fence(rte_memory_order_acquire) calls
between the descriptor loads are removed
- the #ifndef SXE2_TEST guard around the whole AVX512 file is dropped
Several of these look like genuine fixes, and dropping the fences does
match what ixgbe's NEON path does, but none of it is described and none
of it can be reviewed as part of a Tx patch. Please split the NEON Rx
work into its own patch (or patches) with its own rationale, especially
the fence removal and the DD-count change.
Info: sxe2_tx_desc_fill_4_neon_simple() uses vst1q_u64_x4(), which is
not used anywhere else in DPDK. It is aarch64-only and needs a
reasonably recent toolchain; worth confirming against the oldest
supported ARM compilers.
Info:
*(uint32_t *)umbcast_flags =
vgetq_lane_u32(vreinterpretq_u32_u8(umbcast_bits), 0);
replaces vst1q_lane_u32(). The plain store through a cast pointer
assumes umbcast_flags is 4-byte aligned; the NEON store did not. If
the alignment is not guaranteed, keep vst1q_lane_u32().
Patch 31/44 - net/sxe2: refine vectorized Tx/Rx mode setup
Warning: on arm64 the reworked NEON branch can leave tx_pkt_burst
unset. sxe2_tx_vec_support_check() unconditionally sets
*vec_flags = SXE2_TX_MODE_VEC_SIMPLE;
on success, and SXE2_TX_MODE_VEC_SIMPLE is part of
SXE2_TX_MODE_VEC_SET_MASK. So tx_mode_flags can satisfy
if (tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK)
without SXE2_TX_MODE_VEC_NEON being set, because NEON is only OR'd in
when rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON) == 1. Before the
patch the else arm caught that case and installed
sxe2_tx_pkts_vec_neon_simple(); now the whole block is skipped,
tx_pkt_prepare is set to the dummy, and tx_pkt_burst keeps whatever it
had. Restore a fallback for the non-NEON case, or make the x86 style
"else" explicit.
Info: the rx_free_thresh change is a separate bug fix. With
rx_free_thresh == 0, sxe2_rx_queue_init() computes
rxq->batch_alloc_trigger = rxq->rx_free_thresh - 1;
which underflows to 65535. That deserves its own patch with a Fixes:
tag rather than being folded into a mode-setup patch.
Info: tx_mode_flags and rx_mode_flags are uint32_t, so "0x%016x" prints
a 32-bit value zero-padded to 16 digits. "%#x" or "0x%08x" would be
clearer.
Patch 33/44 - net/sxe2: restore PF-only guard in udp tunnel port add
Warning: the guard is asymmetric. sxe2_udp_tunnel_port_del_common()
and sxe2_udp_tunnel_port_clear() have no equivalent check, so a VF or
representor can still reach sxe2_drv_udp_tunnel_del() through
.udp_tunnel_port_del and through sxe2_dev_close(). Either add the same
guard there, or hoist it into the sxe2_udp_tunnel_port_add() /
sxe2_udp_tunnel_port_del() dev_ops wrappers where both paths pass
through.
Patch 34/44 - net/sxe2: restore link update call in status query
Warning: layering. sxe2_drv_mac_link_status_get() is a command-channel
function in sxe2_cmd_chnl.c; it now indexes the global rte_eth_devices
array and calls the ethdev-level sxe2_link_update():
struct rte_eth_dev *dev =
&rte_eth_devices[adapter->dev_info.dev_data->port_id];
...
(void)sxe2_link_update(dev, 0);
The underlying problem is real - the LSC handler updates link_ctxt but
never pushes it into rte_eth_link, so callbacks fire with a stale
link - but the fix reads better in the two callers. Calling
sxe2_link_update() from sxe2_event_irq_common_handler() (which already
has the rte_eth_dev) and from sxe2_link_update_init() keeps the command
layer free of ethdev side effects and avoids the global lookup.
Note also that the unconditional dereference of
adapter->dev_info.dev_data at the top of the function is reachable
after sxe2_dev_pci_map_uinit() sets that pointer to NULL (patch 19/44).
Info: the patch removes two unrelated blank lines in
sxe2_link_update_init(). Unnecessary churn in a fix patch.
Patch 37/44 - net/sxe2: wrap command params fill debug log in macro
Info: the commit message says "the debug log is executed
unconditionally on every command fill", implying the change avoids
that. It does not - PMD_DEV_LOG_DEBUG is level-gated either way, and
moving it into the macro leaves the call frequency unchanged. The
actual effect is that #opc is stringized at the call site and the
helper loses a parameter. Please reword.
Info: adapter is now evaluated twice by the macro (once in the log,
once in the call). All current callers pass a plain variable, so this
is latent, but it is worth a comment or an inline helper.
Patch 42/44 - net/sxe2: align command structs with historical kernel
layout
Warning: sxe2_tm_res changes size from 4 to 2 bytes, and it is used as
both request and response buffer with sizeof():
struct sxe2_tm_res tm_resp;
sxe2_drv_cmd_params_fill(adapter, ¶m,
SXE2_DRV_CMD_SCHED_ROOT_TREE_ALLOC,
NULL, 0, &tm_resp, sizeof(tm_resp));
out_len for ROOT_TREE_ALLOC and for SCHED_TM_ADD_MID_NODE /
SCHED_TM_ADD_QUEUE_NODE drops from 4 to 2. If the firmware still
writes the historical 4 bytes this overruns a stack object. Please
confirm against the firmware side and say so in the commit message,
since this is the one hunk in the patch that changes anything
observable.
Note that tm_resp in sxe2_drv_root_tree_alloc() is the only one of the
four sxe2_tm_res objects left uninitialized; the other three use
"= {0}". Worth making consistent while touching this.
Warning: the commit message lists
- sxe2_tm_add_mid_msg: drop packed attribute
- sxe2_tm_add_queue_msg: drop packed attribute
but the patch does not touch either struct. Both still carry
__rte_aligned(4) __rte_packed_begin / __rte_packed_end in the applied
tree. Drop those two bullets, or make the change.
Info: the sxe2_drv_link_info_resp, sxe2_tm_info, sxe2_drv_sfp_req and
sxe2_drv_sfp_resp hunks do not change any member offset or any struct
size. For sxe2_drv_link_info_resp the retained __rte_aligned(4) pads
the size back to 8 after rsv[3] is removed; for the other three the
packed and unpacked layouts are already identical because every member
is naturally aligned. Saying this in the commit message would make
clear that sxe2_tm_res is the only hunk that needs testing.
Patch 43/44 - common/sxe2: fix ioctl channel log and close handling
Info: the cmd_fd/bar_idx swap is fixed, but the remaining two
conversions are still mislabelled - "src=" prints the raw offset and
"offset=" prints SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset):
PMD_LOG_DEBUG(COM, "fd=%d, bar idx=%d, len=%"PRIu64
", src=0x%"PRIx64", offset=0x%"PRIx64"",
cmd_fd, bar_idx, len, offset,
SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
"offset=" and "pci_offset=" would read correctly.
Patches with no findings: 01, 02, 03, 04, 05, 07, 08, 09, 11, 12, 13,
16, 17, 18, 19, 20, 24, 25, 27, 28, 29, 32, 35, 36, 38, 39, 40, 41, 44.
^ permalink raw reply [flat|nested] 207+ messages in thread
* [PATCH v5 00/45] net/sxe2: add Stars SXE2 net driver with fixes
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
@ 2026-08-28 3:23 ` liujie5
2026-08-28 3:23 ` [PATCH v5 01/45] common/sxe2: fix null pointer in class driver remove liujie5
` (44 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:23 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
This series adds the Stars SXE2 network driver together with a set of
fixes accumulated while validating the driver against the historical
kernel implementation and reviewing the code.
This is the v5 revision. Changes since v4 address the community review
of the v4 series:
- Drop the ineffective IPsec key length check in
sxe2_security_valid_key() (the same limit is already enforced at the
top of the function) and keep only the security context pointer
cleanup, which is now its own commit.
- Make the QinQ and RSS offload capability gating actually effective:
RTE_ETH_TX_OFFLOAD_QINQ_INSERT is removed from the unconditional
capability list and only advertised when no port VLAN is configured;
RTE_ETH_RX_OFFLOAD_RSS_HASH is advertised only when the RSS offload
capability flag is set.
- Fix switchdev representor matching so the common devarg forms
(e.g. "representor=vf0", bare-number form) that leave nb_ports == 0
are treated as "no PF constraint" instead of being rejected.
- Fix the representor VSI teardown: sxe2_vsi_destroy() now unlinks
SXE2_VSI_T_DPDK_ESW nodes from other_vsi_list before freeing them.
- Restore a scalar Tx fallback on arm64 when NEON is not available so
tx_pkt_burst is always installed.
- Add the same PF-only guard to the UDP tunnel port delete and clear
paths that add already has.
- Move sxe2_link_update() out of the command-channel link status query
into the two callers, keeping the command layer free of ethdev side
effects and avoiding the dev_data dereference.
- Evaluate the adapter argument exactly once in the command params fill
macro.
- Remove ineffective nb_rx_queues/nb_tx_queues assignments from device
info (ethdev overwrites them after the PMD callback) and from the
representor device info (new commit with a Fixes: tag).
- Fix the ioctl mmap debug log labels and reword the commit messages
for the security context, command fill macro and command struct
alignment commits.
Patch 30/44 of the v4 series still bundles unrelated NEON Rx data path
changes into the vectorized Tx commit, and patches 21/22 still leave
the dev_close and dev_init teardown orders slightly different; these
are left for a follow-up.
Jie Liu (45):
common/sxe2: fix null pointer in class driver remove
common/sxe2: allow munmap during kernel reset
net/sxe2: fix VF PCI device ID
net/sxe2: fix MSIX register width in PF map table
net/sxe2: restore pf and port index caps assignment
net/sxe2: fix VSI lifecycle management
net/sxe2: initialize stats in representor device init
net/sxe2: use base device name for representor naming
net/sxe2: propagate LSC event to VF representors
net/sxe2: clear security context pointer on uninit
net/sxe2: rename representor VSI ID fields
net/sxe2: clean up duplicate function declarations
net/sxe2: fix null VSI dereference in device info
net/sxe2: fill MAC and queue counts in device info
net/sxe2: fix QinQ and RSS offload capability report
net/sxe2: use regular write for mapped registers
net/sxe2: move PCI register read macro to common header
net/sxe2: validate PCI map resource type
net/sxe2: guard PCI BAR unmap when not initialized
net/sxe2: fix null dereference in dev uninit
net/sxe2: fix duplicated cleanup in dev close
net/sxe2: align dev init and cleanup order
net/sxe2: simplify switchdev representor matching
net/sxe2: rename fnav cid manager symbols to flow
net/sxe2: move tunnel port helpers into flow module
net/sxe2: add ACL engine event statistics support
net/sxe2: guard Rx queue event FD free in unregister
net/sxe2: refactor primary process MP message handling
net/sxe2: refactor Tx queue reset operations
net/sxe2: unify vectorized Tx buffer handling
net/sxe2: refine vectorized Tx/Rx mode setup
net/sxe2: fix RSS action attribute validation
net/sxe2: restore PF-only guard in udp tunnel port add
net/sxe2: restore link update call in status query
net/sxe2: validate representor ID against VF count
net/sxe2: use primary VSI ID for representor VSI
net/sxe2: wrap command params fill debug log in macro
net/sxe2: restore Rx queue buffer split fill support
net/sxe2: skip tunnel config fill on get failure
net/sxe2: skip flow id assignment on filter add failure
net/sxe2: fix command channel log messages
net/sxe2: align command structs with historical kernel layout
common/sxe2: fix ioctl channel log and close handling
doc/sxe2: remove drv-sw-stats parameter documentation
net/sxe2: remove ineffective queue counts in representor info
doc/guides/nics/sxe2.rst | 40 ++--
drivers/common/sxe2/sxe2_common.c | 6 +-
drivers/common/sxe2/sxe2_ioctl_chnl.c | 20 +-
drivers/net/sxe2/sxe2_cmd_chnl.c | 199 ++++++++++++++++--
drivers/net/sxe2/sxe2_cmd_chnl.h | 15 +-
drivers/net/sxe2/sxe2_drv_cmd.h | 37 +++-
drivers/net/sxe2/sxe2_dump.c | 10 +-
drivers/net/sxe2/sxe2_ethdev.c | 192 ++++++++++-------
drivers/net/sxe2/sxe2_ethdev.h | 13 +-
drivers/net/sxe2/sxe2_ethdev_repr.c | 15 +-
drivers/net/sxe2/sxe2_flow.c | 234 ++++++++++++++++++---
drivers/net/sxe2/sxe2_flow.h | 6 +-
drivers/net/sxe2/sxe2_flow_define.h | 15 +-
drivers/net/sxe2/sxe2_flow_parse_action.c | 39 +++-
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ----------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 6 -
drivers/net/sxe2/sxe2_irq.c | 29 ++-
drivers/net/sxe2/sxe2_mac.c | 11 +-
drivers/net/sxe2/sxe2_mp.c | 59 +++---
drivers/net/sxe2/sxe2_queue.c | 2 +
drivers/net/sxe2/sxe2_queue.h | 7 +-
drivers/net/sxe2/sxe2_rx.c | 3 +-
drivers/net/sxe2/sxe2_security.c | 1 +
drivers/net/sxe2/sxe2_switchdev.c | 16 +-
drivers/net/sxe2/sxe2_tx.c | 42 +++-
drivers/net/sxe2/sxe2_tx.h | 4 +
drivers/net/sxe2/sxe2_txrx.c | 20 +-
drivers/net/sxe2/sxe2_txrx_poll.h | 2 -
drivers/net/sxe2/sxe2_txrx_vec.c | 73 +++----
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 133 +-----------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 9 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 219 ++++++++++++-------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
drivers/net/sxe2/sxe2_vsi.c | 10 +-
36 files changed, 948 insertions(+), 673 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 207+ messages in thread
* [PATCH v5 01/45] common/sxe2: fix null pointer in class driver remove
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
2026-08-28 3:23 ` [PATCH v5 00/45] net/sxe2: add Stars SXE2 net driver with fixes liujie5
@ 2026-08-28 3:23 ` liujie5
2026-08-28 3:23 ` [PATCH v5 02/45] common/sxe2: allow munmap during kernel reset liujie5
` (43 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:23 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_classes_driver_remove() calls cdrv->remove(cdev) without
checking whether cdrv or cdrv->remove is NULL. If the class driver
was never probed, cdev->cdrv remains NULL, and the unconditional
call dereferences a NULL pointer, crashing during device removal.
Add NULL checks for cdrv and cdrv->remove, returning 0 when either
is NULL.
Fixes: 83866f8d7638 ("common/sxe2: add base driver skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_common.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/common/sxe2/sxe2_common.c b/drivers/common/sxe2/sxe2_common.c
index 5c5db85f29..6e387a8a73 100644
--- a/drivers/common/sxe2/sxe2_common.c
+++ b/drivers/common/sxe2/sxe2_common.c
@@ -465,8 +465,12 @@ static int32_t sxe2_classes_driver_probe(struct sxe2_common_device *cdev,
static int32_t sxe2_classes_driver_remove(struct sxe2_common_device *cdev)
{
struct sxe2_class_driver *cdrv = cdev->cdrv;
+ int32_t ret = 0;
+
+ if (cdrv != NULL && cdrv->remove != NULL)
+ ret = cdrv->remove(cdev);
- return cdrv->remove(cdev);
+ return ret;
}
static int32_t sxe2_kvargs_validate(struct sxe2_dev_kvargs_info *kv_info)
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 02/45] common/sxe2: allow munmap during kernel reset
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
2026-08-28 3:23 ` [PATCH v5 00/45] net/sxe2: add Stars SXE2 net driver with fixes liujie5
2026-08-28 3:23 ` [PATCH v5 01/45] common/sxe2: fix null pointer in class driver remove liujie5
@ 2026-08-28 3:23 ` liujie5
2026-08-28 3:23 ` [PATCH v5 03/45] net/sxe2: fix VF PCI device ID liujie5
` (42 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:23 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_dev_munmap() refuses to unmap the BAR region when
cdev->config.kernel_reset is set, returning -EPERM. After a kernel
reset the application still needs to release the previously mapped
regions during cleanup; blocking munmap leaves stale mappings and
prevents a clean teardown.
Remove the kernel_reset check from sxe2_drv_dev_munmap() so the
mapping is always released. The cdev parameter is no longer used,
so mark it __rte_unused.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_ioctl_chnl.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index a233a78136..3e2fbf572f 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -367,16 +367,10 @@ void
RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_munmap)
int32_t
-sxe2_drv_dev_munmap(struct sxe2_common_device *cdev, void *virt, uint64_t len)
+sxe2_drv_dev_munmap(struct sxe2_common_device *cdev __rte_unused, void *virt, uint64_t len)
{
int32_t ret = 0;
- if (cdev->config.kernel_reset) {
- ret = -EPERM;
- PMD_LOG_WARN(COM, "kernel reset, need restart app.");
- goto l_end;
- }
-
PMD_LOG_DEBUG(COM, "Munmap virt=%p, len=0x%"PRIx64"",
virt, len);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 03/45] net/sxe2: fix VF PCI device ID
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (2 preceding siblings ...)
2026-08-28 3:23 ` [PATCH v5 02/45] common/sxe2: allow munmap during kernel reset liujie5
@ 2026-08-28 3:23 ` liujie5
2026-08-28 3:23 ` [PATCH v5 04/45] net/sxe2: fix MSIX register width in PF map table liujie5
` (41 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:23 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The VF PCI device ID is defined as 0x10b2 per the hardware specification,
but the code incorrectly uses 0x10b.
As a result, the VF driver never binds to the device, making VF
functionality completely unusable.
Fix this by changing SXE2_PCI_DEVICE_ID_VF_1 from 0x10b to 0x10b2.
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 8bbfdc3a15..ec376b76dc 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -44,7 +44,7 @@
#define SXE2_PCI_VENDOR_ID_1 0x1ff2
#define SXE2_PCI_DEVICE_ID_PF_1 0x10b1
-#define SXE2_PCI_DEVICE_ID_VF_1 0x10b
+#define SXE2_PCI_DEVICE_ID_VF_1 0x10b2
#define SXE2_PCI_VENDOR_ID_2 0x1d94
#define SXE2_PCI_DEVICE_ID_PF_2 0x1260
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 04/45] net/sxe2: fix MSIX register width in PF map table
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (3 preceding siblings ...)
2026-08-28 3:23 ` [PATCH v5 03/45] net/sxe2: fix VF PCI device ID liujie5
@ 2026-08-28 3:23 ` liujie5
2026-08-28 3:23 ` [PATCH v5 05/45] net/sxe2: restore pf and port index caps assignment liujie5
` (40 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:23 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The MSIX entry in sxe2_net_map_addr_info_pf sets a register width
of 10 (decimal), but each PCIe MSIX table entry is 16 bytes (0x10).
The VF map table already uses 0x10.
Since reg_width is used as the stride between MSIX entries in
sxe2_dev_pci_seg_map(), the wrong value makes the mapped region too
short and places the entries at incorrect offsets.
Change .reg_width from 10 to 0x10 for the SXE2_PCI_MAP_RES_IRQ_MSIX
entry to match the VF table.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index ec376b76dc..5d8cfca6cf 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -94,7 +94,7 @@ static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_pf[SXE2_PCI_MAP_RES_
.reg_width = 4},
[SXE2_PCI_MAP_RES_IRQ_MSIX] = {.addr_base = SXE2_BAR4_MSIX_CTL(0),
.bar_idx = 4,
- .reg_width = 10},
+ .reg_width = 0x10},
};
static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_vf[SXE2_PCI_MAP_RES_MAX_COUNT] = {
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 05/45] net/sxe2: restore pf and port index caps assignment
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (4 preceding siblings ...)
2026-08-28 3:23 ` [PATCH v5 04/45] net/sxe2: fix MSIX register width in PF map table liujie5
@ 2026-08-28 3:23 ` liujie5
2026-08-28 3:23 ` [PATCH v5 06/45] net/sxe2: fix VSI lifecycle management liujie5
` (39 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:23 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_func_caps_get() never assigns adapter->pf_idx from the device
capabilities, leaving it at its zero-initialized value. Switchdev
requests and representor setup that use pf_idx then report the wrong
PF index on multi-PF configurations.
Restore the pf_idx and port_idx assignments in sxe2_func_caps_get()
and drop the now-redundant port_idx assignment from
sxe2_drv_dev_caps_set().
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 5d8cfca6cf..2e14c372f8 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1284,8 +1284,6 @@ void sxe2_eth_uinit(struct rte_eth_dev *dev __rte_unused)
static void sxe2_drv_dev_caps_set(struct sxe2_adapter *adapter,
struct sxe2_drv_dev_caps_resp *dev_caps)
{
- adapter->port_idx = dev_caps->port_idx;
-
adapter->cap_flags = 0;
if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_L2)
@@ -1344,6 +1342,8 @@ static int32_t sxe2_func_caps_get(struct sxe2_adapter *adapter)
goto l_end;
adapter->dev_type = dev_caps.dev_type;
+ adapter->port_idx = dev_caps.port_idx;
+ adapter->pf_idx = dev_caps.pf_idx;
sxe2_drv_dev_caps_set(adapter, &dev_caps);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 06/45] net/sxe2: fix VSI lifecycle management
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (5 preceding siblings ...)
2026-08-28 3:23 ` [PATCH v5 05/45] net/sxe2: restore pf and port index caps assignment liujie5
@ 2026-08-28 3:23 ` liujie5
2026-08-28 3:23 ` [PATCH v5 07/45] net/sxe2: initialize stats in representor device init liujie5
` (38 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:23 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Fix several VSI create/destroy issues introduced by VF representor
support:
- Initialize other_vsi_list with TAILQ_INIT in sxe2_vsi_init before
any VSI is inserted into it.
- Treat -EPERM as a non-fatal error when destroying VSIs, since the
kernel may have already removed the VSI.
- Set main_vsi to NULL after destroy/free to avoid a dangling pointer
if the VSI is destroyed again.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_vsi.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_vsi.c b/drivers/net/sxe2/sxe2_vsi.c
index d29480b931..dea3f58997 100644
--- a/drivers/net/sxe2/sxe2_vsi.c
+++ b/drivers/net/sxe2/sxe2_vsi.c
@@ -131,6 +131,8 @@ static int32_t sxe2_vsi_destroy(struct sxe2_adapter *adapter, struct sxe2_vsi *v
}
l_free:
+ if (vsi->vsi_type == SXE2_VSI_T_DPDK_ESW)
+ TAILQ_REMOVE(&adapter->vsi_ctxt.other_vsi_list, vsi, next);
rte_free(vsi);
vsi = NULL;
@@ -230,7 +232,7 @@ int32_t sxe2_vsi_init(struct rte_eth_dev *dev)
uint16_t srcvsi_cnt;
PMD_INIT_FUNC_TRACE();
-
+ TAILQ_INIT(&adapter->vsi_ctxt.other_vsi_list);
ret = sxe2_main_vsi_create(adapter);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to create main VSI, ret=%d", ret);
@@ -283,13 +285,14 @@ void sxe2_vsi_uninit(struct rte_eth_dev *dev)
l_free:
ret = sxe2_vsi_destroy(adapter, adapter->vsi_ctxt.main_vsi);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
goto l_end;
}
+ adapter->vsi_ctxt.main_vsi = NULL;
RTE_TAILQ_FOREACH_SAFE(var, &adapter->vsi_ctxt.other_vsi_list, next, tvar) {
ret = sxe2_vsi_destroy(adapter, var);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
break;
}
@@ -357,4 +360,5 @@ void sxe2_vsi_repr_main_vsi_destroy(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
sxe2_vsi_node_free(adapter->vsi_ctxt.main_vsi);
+ adapter->vsi_ctxt.main_vsi = NULL;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 07/45] net/sxe2: initialize stats in representor device init
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (6 preceding siblings ...)
2026-08-28 3:23 ` [PATCH v5 06/45] net/sxe2: fix VSI lifecycle management liujie5
@ 2026-08-28 3:23 ` liujie5
2026-08-28 3:23 ` [PATCH v5 08/45] net/sxe2: use base device name for representor naming liujie5
` (37 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:23 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add sxe2_stats_init() call in sxe2_repr_dev_init to set up the
statistics infrastructure for representor devices, and add the
l_init_irq_ctxt_err error path to uninitialize the software irq
context if stats initialization fails.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev_repr.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index f32318b731..c698baafe0 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -483,8 +483,16 @@ int32_t sxe2_repr_dev_init(struct rte_eth_dev *dev,
goto l_init_sw_err;
}
+ ret = sxe2_stats_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize stats, ret=[%d]", ret);
+ goto l_init_irq_ctxt_err;
+ }
+
goto l_end;
+l_init_irq_ctxt_err:
+ sxe2_sw_irq_ctxt_uninit(dev);
l_init_sw_err:
sxe2_eth_uinit(dev);
l_init_eth_err:
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 08/45] net/sxe2: use base device name for representor naming
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (7 preceding siblings ...)
2026-08-28 3:23 ` [PATCH v5 07/45] net/sxe2: initialize stats in representor device init liujie5
@ 2026-08-28 3:23 ` liujie5
2026-08-28 3:23 ` [PATCH v5 09/45] net/sxe2: propagate LSC event to VF representors liujie5
` (36 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:23 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Update the representor device naming to use the base device name
prefix, and set the numa_node from the parent device data so that
representor devices are allocated on the same NUMA node.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev_repr.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index c698baafe0..b7096f5927 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -552,8 +552,8 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
}
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- snprintf(name, sizeof(name), "sxe2_representor_c%dpf%d%s%u",
- adapter->pf_idx, adapter->pf_idx,
+ snprintf(name, sizeof(name), "%s_representor_%s%u",
+ adapter->cdev->dev->name,
"vf",
req_eth_da->representor_ports[repr_idx]);
@@ -562,6 +562,7 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
ret = -ENOMEM;
goto l_release_port;
}
+ eth_dev->data->numa_node = adapter->dev_info.dev_data->numa_node;
eth_dev->data->dev_private = rte_zmalloc_socket(name,
sizeof(struct sxe2_adapter),
RTE_CACHE_LINE_SIZE,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 09/45] net/sxe2: propagate LSC event to VF representors
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (8 preceding siblings ...)
2026-08-28 3:23 ` [PATCH v5 08/45] net/sxe2: use base device name for representor naming liujie5
@ 2026-08-28 3:23 ` liujie5
2026-08-28 3:24 ` [PATCH v5 10/45] net/sxe2: clear security context pointer on uninit liujie5
` (35 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:23 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
When the PF link state changes in switchdev mode, refresh the link
status of every VF representor and trigger the RTE_ETH_EVENT_INTR_LSC
callback on each, so applications receive link events on representor
ports. Also log OICR in hexadecimal for better readability.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index 3306504761..ba764dd5e4 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -77,14 +77,32 @@ static int32_t sxe2_fc_state_callback(struct rte_eth_dev *dev)
static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t oicr)
{
struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
+ struct rte_eth_dev *repr_eth_dev;
+ struct sxe2_adapter *repr_adapter;
+ uint16_t vf_id;
if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
- PMD_DEV_LOG_INFO(adapter, DRV, "OICR=%" PRIu64, oicr);
+ PMD_DEV_LOG_INFO(adapter, DRV, "OICR=0x%" PRIx64, oicr);
(void)sxe2_drv_mac_link_status_get(adapter);
- if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_LSC,
NULL);
+ }
+ if (adapter->switchdev_info.is_switchdev) {
+ for (vf_id = 0; vf_id < adapter->repr_ctxt.nb_repr_vf; vf_id++) {
+ repr_eth_dev = adapter->repr_ctxt.vf_rep_eth_dev[vf_id];
+ if (!repr_eth_dev)
+ continue;
+ repr_adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(repr_eth_dev);
+ (void)sxe2_drv_mac_link_status_get(repr_adapter);
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ rte_eth_dev_callback_process(repr_eth_dev,
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL);
+ }
+ }
+ }
}
if (oicr & RTE_BIT32(SXE2_COM_SW_MODE_SWITCHDEV)) {
PMD_DEV_LOG_INFO(adapter, DRV, "event notify switchdev");
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 10/45] net/sxe2: clear security context pointer on uninit
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (9 preceding siblings ...)
2026-08-28 3:23 ` [PATCH v5 09/45] net/sxe2: propagate LSC event to VF representors liujie5
@ 2026-08-28 3:24 ` liujie5
2026-08-28 3:24 ` [PATCH v5 11/45] net/sxe2: rename representor VSI ID fields liujie5
` (34 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:24 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_security_uinit() frees the security session but leaves
dev->security_ctx pointing at the freed memory. Set
dev->security_ctx to NULL after releasing the security context
so a later access does not dereference a dangling pointer.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_security.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/sxe2/sxe2_security.c b/drivers/net/sxe2/sxe2_security.c
index bc59d1b880..8f31067942 100644
--- a/drivers/net/sxe2/sxe2_security.c
+++ b/drivers/net/sxe2/sxe2_security.c
@@ -326,6 +326,7 @@ void sxe2_security_uinit(struct rte_eth_dev *dev)
if (sctx != NULL) {
rte_free(sctx);
sctx = NULL;
+ dev->security_ctx = NULL;
}
sxe2_ipsec_uinit(adapter);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 11/45] net/sxe2: rename representor VSI ID fields
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (10 preceding siblings ...)
2026-08-28 3:24 ` [PATCH v5 10/45] net/sxe2: clear security context pointer on uninit liujie5
@ 2026-08-28 3:24 ` liujie5
2026-08-28 3:24 ` [PATCH v5 12/45] net/sxe2: clean up duplicate function declarations liujie5
` (33 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:24 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Rename repr_vf_k_vsi_id/repr_vf_u_vsi_id to
repr_vf_primary_vsi_id/repr_vf_backup_vsi_id in
sxe2_repr_private_data and update all references.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_dump.c | 8 ++++----
drivers/net/sxe2/sxe2_ethdev.h | 4 ++--
drivers/net/sxe2/sxe2_flow.c | 4 ++--
drivers/net/sxe2/sxe2_switchdev.c | 4 ++--
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index d43473e083..590219f502 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -211,16 +211,16 @@ sxe2_dump_switchdev_info(FILE *file, struct rte_eth_dev *dev)
"\t -- repr_pf_id: %u\n"
"\t -- repr_vf_id: %u\n"
"\t -- repr_vf_vsi_id: %u\n"
- "\t -- repr_vf_k_vsi_id: %s\n"
- "\t -- repr_vf_u_vsi_id: %s\n",
+ "\t -- repr_vf_primary_vsi_id: %s\n"
+ "\t -- repr_vf_backup_vsi_id: %s\n",
adapter->repr_priv_data->repr_id,
adapter->repr_priv_data->repr_q_id,
adapter->repr_priv_data->repr_pf_id,
adapter->repr_priv_data->repr_vf_id,
adapter->repr_priv_data->repr_vf_vsi_id,
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_k_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_primary_vsi_id,
k_vsi_buf, sizeof(k_vsi_buf)),
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_u_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_backup_vsi_id,
u_vsi_buf, sizeof(u_vsi_buf)));
goto l_end;
}
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index c54e8a435e..158198d74b 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -263,8 +263,8 @@ struct sxe2_repr_private_data {
uint16_t repr_pf_id;
uint16_t repr_vf_id;
uint16_t repr_vf_vsi_id;
- uint16_t repr_vf_k_vsi_id;
- uint16_t repr_vf_u_vsi_id;
+ uint16_t repr_vf_primary_vsi_id;
+ uint16_t repr_vf_backup_vsi_id;
};
struct sxe2_sched_hw_cap {
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index 63cfc36968..cf54803301 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -380,9 +380,9 @@ static int32_t sxe2_flow_src_split_proc(struct rte_eth_dev *dev,
if (adapter->switchdev_info.is_switchdev && adapter->is_dev_repr) {
flow_bond_num = 1;
flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] =
- adapter->repr_priv_data->repr_vf_u_vsi_id;
+ adapter->repr_priv_data->repr_vf_backup_vsi_id;
flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] =
- adapter->repr_priv_data->repr_vf_k_vsi_id;
+ adapter->repr_priv_data->repr_vf_primary_vsi_id;
}
for (idx = 0; idx < flow_bond_num; idx++) {
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index 44703cfb5c..efb1468b91 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -312,9 +312,9 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_q_id = repr_id;
repr_priv_data->repr_pf_id = parent_adapter->pf_idx;
repr_priv_data->repr_vf_id = repr_id;
- repr_priv_data->repr_vf_k_vsi_id =
+ repr_priv_data->repr_vf_primary_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
- repr_priv_data->repr_vf_u_vsi_id =
+ repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
repr_priv_data->repr_vf_vsi_id =
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 12/45] net/sxe2: clean up duplicate function declarations
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (11 preceding siblings ...)
2026-08-28 3:24 ` [PATCH v5 11/45] net/sxe2: rename representor VSI ID fields liujie5
@ 2026-08-28 3:24 ` liujie5
2026-08-28 3:24 ` [PATCH v5 13/45] net/sxe2: fix null VSI dereference in device info liujie5
` (32 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:24 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Remove duplicate function declarations from the sxe2 driver headers:
- sxe2_drv_promisc_config, sxe2_drv_vsi_info_get and
sxe2_drv_rxq_mapping_set in sxe2_cmd_chnl.h
- sxe2_dev_pci_seg_unmap in sxe2_ethdev.h
- sxe2_rx_pkts_scattered in sxe2_txrx_poll.h
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.h | 6 ------
drivers/net/sxe2/sxe2_ethdev.h | 2 --
drivers/net/sxe2/sxe2_txrx_poll.h | 2 --
3 files changed, 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index d63caad526..294ac15db4 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -65,8 +65,6 @@ int32_t sxe2_drv_ipsec_rxsa_delete(struct sxe2_adapter *adapter,
int32_t sxe2_drv_ipsec_txsa_delete(struct sxe2_adapter *adapter,
uint16_t sa_id);
-int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set);
-
int32_t sxe2_drv_udp_tunnel_add(struct sxe2_adapter *adapter,
enum sxe2_udp_tunnel_protocol tunnel_proto,
uint16_t udp_port);
@@ -84,8 +82,6 @@ int32_t sxe2_drv_get_udp_tunnel_port(struct sxe2_adapter *adapter,
int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-
int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter);
int32_t sxe2_drv_get_mac_stats(struct sxe2_adapter *adapter);
@@ -110,8 +106,6 @@ int32_t sxe2_drv_mapping_reset(struct rte_eth_dev *eth_dev);
int32_t sxe2_drv_mapping_stats_info_clear(struct rte_eth_dev *eth_dev);
-int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t pool_idx);
-
int32_t sxe2_drv_allmulti_config(struct sxe2_adapter *adapter, bool set);
int32_t sxe2_drv_uc_config(struct sxe2_adapter *adapter, struct rte_ether_addr *addr, bool add);
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 158198d74b..1409be74d3 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -385,8 +385,6 @@ void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
int32_t sxe2_dev_pci_map_init(struct rte_eth_dev *dev);
-void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
-
int32_t sxe2_udp_tunnel_port_del_common(struct sxe2_adapter *ad,
enum sxe2_udp_tunnel_protocol tunnel_proto, uint16_t udp_port);
diff --git a/drivers/net/sxe2/sxe2_txrx_poll.h b/drivers/net/sxe2/sxe2_txrx_poll.h
index 708e3839d7..bfa099c097 100644
--- a/drivers/net/sxe2/sxe2_txrx_poll.h
+++ b/drivers/net/sxe2/sxe2_txrx_poll.h
@@ -13,8 +13,6 @@ uint16_t sxe2_tx_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t
uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-
uint16_t sxe2_rx_pkts_scattered_split(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
#endif /* SXE2_TXRX_POLL_H */
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 13/45] net/sxe2: fix null VSI dereference in device info
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (12 preceding siblings ...)
2026-08-28 3:24 ` [PATCH v5 12/45] net/sxe2: clean up duplicate function declarations liujie5
@ 2026-08-28 3:24 ` liujie5
2026-08-28 3:24 ` [PATCH v5 14/45] net/sxe2: fill MAC and queue counts " liujie5
` (31 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:24 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_infos_get() dereferences adapter->vsi_ctxt.main_vsi without
checking for NULL, which can crash when the main VSI has not been
created yet.
Add an early NULL check on vsi and return -EINVAL.
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 2e14c372f8..02f9ce3d32 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -781,6 +781,10 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
+ if (unlikely(vsi == NULL)) {
+ PMD_LOG_ERR(INIT, "main vsi is NULL");
+ return -EINVAL;
+ }
dev_info->max_rx_queues = vsi->rxqs.q_cnt;
dev_info->max_tx_queues = vsi->txqs.q_cnt;
dev_info->min_rx_bufsize = SXE2_MIN_BUF_SIZE;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 14/45] net/sxe2: fill MAC and queue counts in device info
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (13 preceding siblings ...)
2026-08-28 3:24 ` [PATCH v5 13/45] net/sxe2: fix null VSI dereference in device info liujie5
@ 2026-08-28 3:24 ` liujie5
2026-08-28 3:24 ` [PATCH v5 15/45] net/sxe2: fix QinQ and RSS offload capability report liujie5
` (30 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:24 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Fill max_mac_addrs, nb_rx_queues and nb_tx_queues in
sxe2_dev_infos_get() so applications can query the maximum number of
MAC addresses and the queue counts.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 02f9ce3d32..e85e34aa1a 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -792,6 +792,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->max_lro_pkt_size = SXE2_FRAME_SIZE_MAX * SXE2_RX_LRO_DESC_MAX_NUM;
dev_info->max_mtu = dev_info->max_rx_pktlen - SXE2_ETH_OVERHEAD;
dev_info->min_mtu = RTE_ETHER_MIN_MTU;
+ dev_info->max_mac_addrs = SXE2_NUM_MACADDR_MAX;
dev_info->rx_offload_capa =
RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 15/45] net/sxe2: fix QinQ and RSS offload capability report
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (14 preceding siblings ...)
2026-08-28 3:24 ` [PATCH v5 14/45] net/sxe2: fill MAC and queue counts " liujie5
@ 2026-08-28 3:24 ` liujie5
2026-08-28 3:24 ` [PATCH v5 16/45] net/sxe2: use regular write for mapped registers liujie5
` (29 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:24 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Make the QINQ offload capabilities conditional on the port VLAN
setting: only advertise RTE_ETH_TX_OFFLOAD_QINQ_INSERT,
RTE_ETH_RX_OFFLOAD_QINQ_STRIP and RTE_ETH_RX_OFFLOAD_VLAN_FILTER
when no port VLAN is configured. Advertise RTE_ETH_RX_OFFLOAD_RSS_HASH
unconditionally and report the buffer split supported header ptypes
count in sxe2_buffer_split_supported_hdr_ptypes_get().
Fixes: a2b79a93515e ("net/sxe2: support L2 filtering and MAC config")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index e85e34aa1a..7a11a93dff 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -804,15 +804,11 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_RX_OFFLOAD_SCTP_CKSUM |
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT |
-#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
- RTE_ETH_RX_OFFLOAD_QINQ_STRIP |
-#endif
RTE_ETH_RX_OFFLOAD_VLAN_EXTEND |
RTE_ETH_RX_OFFLOAD_TCP_LRO;
dev_info->tx_offload_capa =
RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
- RTE_ETH_TX_OFFLOAD_QINQ_INSERT |
RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE |
RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
@@ -855,14 +851,22 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
- if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
- dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
-
if (sxe2_ipsec_supported(adapter)) {
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
}
+ if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
+
+ if (!sxe2_dev_port_vlan_check(dev)) {
+ dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
+#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
+#endif
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
+ }
+
if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_RSS) {
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
dev_info->flow_type_rss_offloads |= SXE2_RSS_HF_SUPPORT_ALL;
@@ -934,7 +938,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
static const uint32_t *
sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
- size_t *no_of_elements __rte_unused)
+ size_t *no_of_elements)
{
static const uint32_t ptypes[] = {
RTE_PTYPE_L2_ETHER,
@@ -972,6 +976,7 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
RTE_PTYPE_UNKNOWN
};
+ *no_of_elements = RTE_DIM(ptypes) - 1;
return ptypes;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 16/45] net/sxe2: use regular write for mapped registers
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (15 preceding siblings ...)
2026-08-28 3:24 ` [PATCH v5 15/45] net/sxe2: fix QinQ and RSS offload capability report liujie5
@ 2026-08-28 3:24 ` liujie5
2026-08-28 3:24 ` [PATCH v5 17/45] net/sxe2: move PCI register read macro to common header liujie5
` (28 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:24 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_pci_map_write_reg() uses the write-combined store
(SXE2_PCI_REG_WRITE_WC) to write control registers, which is intended
for doorbell/tail writes and can be lossy or delayed for ordering
sensitive register updates.
Add SXE2_PCI_REG_WRITE macro using a regular rte_write32() and use it
in sxe2_pci_map_write_reg().
Fixes: 8cebf80f1eda ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
drivers/net/sxe2/sxe2_ethdev.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 7a11a93dff..589f09c113 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1439,7 +1439,7 @@ void sxe2_pci_map_write_reg(struct sxe2_adapter *adapter,
goto l_ret;
}
- SXE2_PCI_REG_WRITE_WC(reg_addr, value);
+ SXE2_PCI_REG_WRITE(reg_addr, value);
l_ret:
return;
}
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 1409be74d3..cf1104144c 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -355,6 +355,8 @@ struct sxe2_adapter {
#define SXE2_DEV_PRIVATE_TO_ADAPTER(dev) \
((struct sxe2_adapter *)(dev)->data->dev_private)
+#define SXE2_PCI_REG_WRITE(reg, value) rte_write32((rte_cpu_to_le_32(value)), (reg))
+
void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
enum sxe2_pci_map_resource res_type,
uint16_t idx_in_func);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 17/45] net/sxe2: move PCI register read macro to common header
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (16 preceding siblings ...)
2026-08-28 3:24 ` [PATCH v5 16/45] net/sxe2: use regular write for mapped registers liujie5
@ 2026-08-28 3:24 ` liujie5
2026-08-28 3:24 ` [PATCH v5 18/45] net/sxe2: validate PCI map resource type liujie5
` (27 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:24 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move SXE2_PCI_REG_READ to sxe2_ethdev.h so the PCI register access
macros are kept together in the common header, matching
SXE2_PCI_REG_WRITE.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_queue.h | 2 --
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index cf1104144c..f2557b28c3 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -356,6 +356,7 @@ struct sxe2_adapter {
((struct sxe2_adapter *)(dev)->data->dev_private)
#define SXE2_PCI_REG_WRITE(reg, value) rte_write32((rte_cpu_to_le_32(value)), (reg))
+#define SXE2_PCI_REG_READ(reg) rte_read32(reg)
void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
enum sxe2_pci_map_resource res_type,
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index a300b66771..10bdaf5b8d 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -12,8 +12,6 @@
#include "sxe2_drv_cmd.h"
#include "sxe2_txrx_common.h"
-#define SXE2_PCI_REG_READ(reg) \
- rte_read32(reg)
#define SXE2_PCI_REG_WRITE_WC(reg, value) \
rte_write32_wc((rte_cpu_to_le_32(value)), reg)
#define SXE2_PCI_REG_WRITE_WC_RELAXED(reg, value) \
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 18/45] net/sxe2: validate PCI map resource type
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (17 preceding siblings ...)
2026-08-28 3:24 ` [PATCH v5 17/45] net/sxe2: move PCI register read macro to common header liujie5
@ 2026-08-28 3:24 ` liujie5
2026-08-28 3:24 ` [PATCH v5 19/45] net/sxe2: guard PCI BAR unmap when not initialized liujie5
` (26 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:24 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_pci_res_seg_map() indexes adapter->map_ctxt.addr_info[] with
res_type without bounds checking, which can access out of bounds when
an invalid resource type is passed.
Add a bounds check on res_type and return -EINVAL.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 589f09c113..9ef93b8076 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1552,6 +1552,12 @@ int32_t sxe2_dev_pci_res_seg_map(struct sxe2_adapter *adapter,
struct sxe2_pci_map_addr_info *addr_info = NULL;
int32_t ret = 0;
+ if (unlikely(res_type >= SXE2_PCI_MAP_RES_MAX_COUNT)) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Invalid resource type %u", res_type);
+ ret = -EINVAL;
+ goto l_end;
+ }
+
addr_info = &adapter->map_ctxt.addr_info[res_type];
if (!addr_info || addr_info->bar_idx == SXE2_PCI_MAP_BAR_INVALID) {
PMD_DEV_LOG_ERR(adapter, INIT, "Invalid bar index with resource type %d", res_type);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 19/45] net/sxe2: guard PCI BAR unmap when not initialized
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (18 preceding siblings ...)
2026-08-28 3:24 ` [PATCH v5 18/45] net/sxe2: validate PCI map resource type liujie5
@ 2026-08-28 3:24 ` liujie5
2026-08-28 3:25 ` [PATCH v5 20/45] net/sxe2: fix null dereference in dev uninit liujie5
` (25 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:24 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_pci_map_uinit() calls sxe2_dev_pci_seg_unmap() and walks
bar_info unconditionally. Only perform the unmap and free when
bar_info has been allocated, so an uninitialized map context is
handled cleanly.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 9ef93b8076..fdff4ae10f 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1773,14 +1773,13 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
uint8_t i = 0;
PMD_INIT_FUNC_TRACE();
+ if (map_ctxt->bar_info != NULL) {
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
-
- if (map_ctxt != NULL && map_ctxt->bar_info != NULL) {
for (i = 0; i < map_ctxt->bar_cnt; i++) {
bar_info = &map_ctxt->bar_info[i];
if (bar_info != NULL && bar_info->seg_info != NULL) {
@@ -1791,7 +1790,6 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
rte_free(map_ctxt->bar_info);
map_ctxt->bar_info = NULL;
}
-
adapter->dev_info.dev_data = NULL;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 20/45] net/sxe2: fix null dereference in dev uninit
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (19 preceding siblings ...)
2026-08-28 3:24 ` [PATCH v5 19/45] net/sxe2: guard PCI BAR unmap when not initialized liujie5
@ 2026-08-28 3:25 ` liujie5
2026-08-28 3:25 ` [PATCH v5 21/45] net/sxe2: fix duplicated cleanup in dev close liujie5
` (24 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:25 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_uninit() calls rep_dev->dev_ops->dev_close() for each VF
representor without checking that dev_ops or dev_close is present,
which can crash when the representor device is not fully initialized.
Guard the call with NULL checks.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index fdff4ae10f..41ea67a607 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2074,9 +2074,11 @@ static int32_t sxe2_dev_uninit(struct rte_eth_dev *dev)
for (i = 0; i < adapter->repr_ctxt.nb_repr_vf; i++) {
rep_dev = adapter->repr_ctxt.vf_rep_eth_dev[i];
if (rep_dev) {
- ret = rep_dev->dev_ops->dev_close(rep_dev);
- if (ret)
- goto l_end;
+ if (rep_dev->dev_ops && rep_dev->dev_ops->dev_close) {
+ ret = rep_dev->dev_ops->dev_close(rep_dev);
+ if (ret)
+ goto l_end;
+ }
if (rep_dev->intr_handle)
rte_intr_instance_free(rep_dev->intr_handle);
ret = rte_eth_dev_release_port(rep_dev);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 21/45] net/sxe2: fix duplicated cleanup in dev close
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (20 preceding siblings ...)
2026-08-28 3:25 ` [PATCH v5 20/45] net/sxe2: fix null dereference in dev uninit liujie5
@ 2026-08-28 3:25 ` liujie5
2026-08-28 3:25 ` [PATCH v5 22/45] net/sxe2: align dev init and cleanup order liujie5
` (23 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:25 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_close() calls sxe2_switchdev_uninit() and
sxe2_dev_pci_map_uinit() twice, and releases resources in an order
that does not match the initialization sequence.
Remove the duplicated calls and align the teardown order with the
device init order.
Fixes: 8cebf80f1eda ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 41ea67a607..5d14e28d96 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2041,17 +2041,15 @@ static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
(void)sxe2_queues_release(dev);
sxe2_mp_uninit(dev);
(void)sxe2_sched_uinit(dev);
- (void)sxe2_rss_disable(dev);
(void)sxe2_flow_uninit(dev);
+ (void)sxe2_rss_disable(dev);
(void)sxe2_udp_tunnel_port_clear(dev);
- sxe2_vsi_uninit(dev);
sxe2_security_uinit(dev);
sxe2_intr_uninit(dev);
(void)sxe2_switchdev_uninit(dev);
sxe2_sw_uninit(dev);
- (void)sxe2_switchdev_uninit(dev);
- sxe2_dev_pci_map_uinit(dev);
sxe2_eth_uinit(dev);
+ sxe2_vsi_uninit(dev);
sxe2_dev_pci_map_uinit(dev);
sxe2_free_repr_info(dev);
sxe2_fc_state_uinit(dev);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 22/45] net/sxe2: align dev init and cleanup order
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (21 preceding siblings ...)
2026-08-28 3:25 ` [PATCH v5 21/45] net/sxe2: fix duplicated cleanup in dev close liujie5
@ 2026-08-28 3:25 ` liujie5
2026-08-28 3:25 ` [PATCH v5 23/45] net/sxe2: simplify switchdev representor matching liujie5
` (22 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:25 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move sxe2_eth_init() to be called before sxe2_sw_init() and
rearrange the error cleanup labels so that resources are torn down
in the reverse order of initialization.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 5d14e28d96..5bce710b29 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1942,6 +1942,12 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_switchdev_err;
}
+ ret = sxe2_eth_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
+ goto init_eth_err;
+ }
+
ret = sxe2_sw_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize sw parameters, ret=[%d]", ret);
@@ -1954,12 +1960,6 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_irq_err;
}
- ret = sxe2_eth_init(dev);
- if (ret) {
- PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
- goto init_eth_err;
- }
-
ret = sxe2_security_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize security, ret=%d", ret);
@@ -2014,12 +2014,12 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
init_rss_err:
sxe2_security_uinit(dev);
init_security_err:
- sxe2_eth_uinit(dev);
-init_eth_err:
sxe2_intr_uninit(dev);
init_irq_err:
sxe2_sw_uninit(dev);
init_sw_err:
+ sxe2_eth_uinit(dev);
+init_eth_err:
(void)sxe2_switchdev_uninit(dev);
init_switchdev_err:
init_dev_info_err:
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 23/45] net/sxe2: simplify switchdev representor matching
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (22 preceding siblings ...)
2026-08-28 3:25 ` [PATCH v5 22/45] net/sxe2: align dev init and cleanup order liujie5
@ 2026-08-28 3:25 ` liujie5
2026-08-28 3:25 ` [PATCH v5 24/45] net/sxe2: rename fnav cid manager symbols to flow liujie5
` (21 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:25 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_switchdev_repr_match() encodes the kernel representor ID and
compares it against each requested port, which is fragile. Match the
PF number and VF ID directly against the switchdev representor info
instead, and drop the sxe2_switchdev_repr_id_encode_get() helper.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 72 +++++++++++++++++-----------------
drivers/net/sxe2/sxe2_ethdev.h | 3 --
2 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 5bce710b29..08986e384f 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2149,42 +2149,25 @@ static int32_t sxe2_fw_version_string_get(struct rte_eth_dev *dev, char *fw_vers
return ret;
}
-static uint16_t sxe2_switchdev_repr_id_encode_get(struct sxe2_switchdev_info *switchdev_info)
-{
- enum rte_eth_representor_type type;
- uint16_t repr = switchdev_info->vf_num;
- uint32_t pf = switchdev_info->pf_num;
-
- switch (switchdev_info->port_name_type) {
- case SXE2_PHYS_PORT_NAME_TYPE_UPLINK:
- if (!switchdev_info->representor)
- return UINT16_MAX;
- type = RTE_ETH_REPRESENTOR_PF;
- pf = switchdev_info->mpesw_owner;
- break;
- case SXE2_PHYS_PORT_NAME_TYPE_PFVF:
- default:
- type = RTE_ETH_REPRESENTOR_VF;
- break;
- }
-
- return SXE2_REPRESENTOR_ID(pf, type, repr);
-}
-
static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
struct rte_eth_devargs *req_eth_da)
{
- uint32_t port_idx = 0;
- uint32_t repr_idx;
- uint16_t kernel_repr_id = sxe2_switchdev_repr_id_encode_get(&adapter->switchdev_info);
- uint16_t repr_id;
+ uint16_t port_idx;
+ uint16_t repr_idx;
+ uint16_t vf_id;
+ uint16_t i;
switch (req_eth_da->type) {
case RTE_ETH_REPRESENTOR_PF:
+ if (adapter->switchdev_info.port_name_type !=
+ SXE2_PHYS_PORT_NAME_TYPE_UPLINK) {
+ rte_errno = EBUSY;
+ return false;
+ }
break;
case RTE_ETH_REPRESENTOR_VF:
if (adapter->switchdev_info.port_name_type !=
- SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
+ SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
rte_errno = EBUSY;
return false;
}
@@ -2197,15 +2180,34 @@ static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
return false;
}
+ if (req_eth_da->nb_ports > 0) {
+ for (port_idx = 0; port_idx < req_eth_da->nb_ports; ++port_idx) {
+ if (adapter->switchdev_info.pf_num == req_eth_da->ports[port_idx])
+ break;
+ }
+ if (port_idx == req_eth_da->nb_ports) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev pf %u not match req pf",
+ adapter->switchdev_info.pf_num);
+ rte_errno = EBUSY;
+ return false;
+ }
+ }
+
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- repr_id = SXE2_REPRESENTOR_ID(req_eth_da->ports[port_idx],
- req_eth_da->type,
- req_eth_da->representor_ports[repr_idx]);
- if (repr_id == kernel_repr_id)
- return true;
- }
- rte_errno = EBUSY;
- return false;
+ for (i = 0; i < adapter->repr_ctxt.nb_vf; ++i) {
+ vf_id = rte_le_to_cpu_16(adapter->repr_ctxt.repr_vf_id[i].func_id);
+ if (vf_id == req_eth_da->representor_ports[repr_idx])
+ break;
+ }
+ if (i == adapter->repr_ctxt.nb_vf) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev vf %u not match req vf(cnt:%u)",
+ req_eth_da->representor_ports[repr_idx], adapter->repr_ctxt.nb_vf);
+ rte_errno = EBUSY;
+ return false;
+ }
+ }
+
+ return true;
}
static int32_t sxe2_eth_pmd_probe_pf(struct sxe2_common_device *cdev,
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index f2557b28c3..e818578319 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -65,9 +65,6 @@ enum sxe2_fnav_tunnel_flag_type {
#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
#define lower_32_bits(n) ((uint32_t)((n) & 0xffffffff))
-#define SXE2_REPRESENTOR_ID(pf, type, repr) \
- (((pf) << 14) + ((type) << 12) + ((repr) & 0xfff))
-
#define SXE2_I2C_EEPROM_DEV_ADDR 0xA0
#define SXE2_I2C_EEPROM_DEV_ADDR2 0xA2
#define SXE2_MODULE_TYPE_SFP 0x03
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 24/45] net/sxe2: rename fnav cid manager symbols to flow
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (23 preceding siblings ...)
2026-08-28 3:25 ` [PATCH v5 23/45] net/sxe2: simplify switchdev representor matching liujie5
@ 2026-08-28 3:25 ` liujie5
2026-08-28 3:25 ` [PATCH v5 25/45] net/sxe2: move tunnel port helpers into flow module liujie5
` (20 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:25 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Rename the sxe2_fnav_cid_mgr, sxe2_fnav_cid_mgr_list_t,
sxe2_fnav_count_resource and sxe2_fnav_get_filter_cid symbols to the
sxe2_flow_* prefix for consistency with the flow module naming.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 2 +-
drivers/net/sxe2/sxe2_cmd_chnl.h | 2 +-
drivers/net/sxe2/sxe2_flow.c | 46 ++++++++++++++---------------
drivers/net/sxe2/sxe2_flow.h | 6 ++--
drivers/net/sxe2/sxe2_flow_define.h | 12 ++++----
5 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b09989fe50..3229c72597 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1800,7 +1800,7 @@ int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat
}
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr)
+ struct sxe2_flow_cid_mgr *mgr)
{
struct sxe2_drv_flow_fnav_query_stat_req req = { 0 };
struct sxe2_drv_flow_fnav_query_stat_resp resp = { 0 };
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index 294ac15db4..cfea1a1f0e 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -159,7 +159,7 @@ int32_t sxe2_drv_flow_fnav_get_stat_id(struct sxe2_adapter *adapter, uint32_t *s
int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr);
+ struct sxe2_flow_cid_mgr *mgr);
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set);
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index cf54803301..a33b8606df 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -857,7 +857,7 @@ static int32_t sxe2_flow_rte_list_free(struct sxe2_adapter *adapter,
struct rte_flow *flow_temp = NULL;
struct sxe2_flow *hw_flow = NULL;
struct sxe2_flow *hw_flow_temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
rte_spinlock_lock(&adapter->flow_ctxt.flow_list_lock);
TAILQ_FOREACH(flow_temp, &adapter->flow_ctxt.rte_flow_list, next) {
if (flow_temp == flow)
@@ -1028,7 +1028,7 @@ static struct rte_flow *sxe2_flow_create(struct rte_eth_dev *dev,
goto l_free_flow;
TAILQ_FOREACH(flow, &flow_list->sxe2_flow_list, next) {
- ret = sxe2_fnav_get_filter_cid(adapter, flow);
+ ret = sxe2_flow_get_filter_cid(adapter, flow);
if (ret != 0) {
PMD_LOG_ERR(DRV, "fnav get stats id failed, ret:%d", ret);
rte_flow_error_set(error, EIO,
@@ -1088,16 +1088,16 @@ static int32_t sxe2_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e
return ret;
}
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
user_id = flow->action.count.user_id;
@@ -1112,7 +1112,7 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
}
if (mgr == NULL) {
mgr = rte_zmalloc("sxe2_fnav_cid_mgr",
- sizeof(struct sxe2_fnav_cid_mgr), 0);
+ sizeof(struct sxe2_flow_cid_mgr), 0);
if (!mgr) {
PMD_LOG_ERR(DRV,
"Failed to alloc sxe2vf_fnav_cid_mgr memory.");
@@ -1143,13 +1143,13 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *mgr = *mgr_ptr;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *mgr = *mgr_ptr;
uint32_t user_id = flow->action.count.user_id;
if (user_id == 0) {
TAILQ_REMOVE(cid_mgr_list, mgr, next);
@@ -1170,14 +1170,14 @@ int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
uint32_t user_id = flow->action.count.user_id;
uint32_t driver_id = flow->action.count.driver_id;
@@ -1218,7 +1218,7 @@ static int32_t sxe2_flow_query_count(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
switch (flow->action.count.stat_ctrl) {
case SXE2_FNAV_STAT_ENA_NONE:
count->hits_set = 0;
@@ -1348,7 +1348,7 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
int32_t ret = 0;
TAILQ_INIT(&adapter->flow_ctxt.rte_flow_list);
- TAILQ_INIT(&adapter->flow_ctxt.hw_res.fnav_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.hw_res.flow_cid_mgr_list);
if (adapter->devargs.fnav_stat_type)
adapter->flow_ctxt.hw_res.count_type =
adapter->devargs.fnav_stat_type;
@@ -1370,10 +1370,10 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
int32_t ret = 0;
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct rte_flow_error error;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
ret = sxe2_flow_flush(dev, &error);
if (ret)
diff --git a/drivers/net/sxe2/sxe2_flow.h b/drivers/net/sxe2/sxe2_flow.h
index daaeedd4dc..8d47b11ff4 100644
--- a/drivers/net/sxe2/sxe2_flow.h
+++ b/drivers/net/sxe2/sxe2_flow.h
@@ -14,16 +14,16 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev);
int32_t sxe2_flow_uninit(struct rte_eth_dev *dev);
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev);
diff --git a/drivers/net/sxe2/sxe2_flow_define.h b/drivers/net/sxe2/sxe2_flow_define.h
index 263a573f04..8a5d871978 100644
--- a/drivers/net/sxe2/sxe2_flow_define.h
+++ b/drivers/net/sxe2/sxe2_flow_define.h
@@ -98,8 +98,8 @@ struct rte_flow {
};
TAILQ_HEAD(rte_flow_list_t, rte_flow);
-struct sxe2_fnav_cid_mgr {
- TAILQ_ENTRY(sxe2_fnav_cid_mgr) next;
+struct sxe2_flow_cid_mgr {
+ TAILQ_ENTRY(sxe2_flow_cid_mgr) next;
uint16_t stat_index;
uint32_t user_id;
uint32_t driver_id;
@@ -107,18 +107,18 @@ struct sxe2_fnav_cid_mgr {
uint64_t hits;
uint64_t bytes;
};
-TAILQ_HEAD(sxe2_fnav_cid_mgr_list_t, sxe2_fnav_cid_mgr);
+TAILQ_HEAD(sxe2_flow_cid_mgr_list_t, sxe2_flow_cid_mgr);
-struct sxe2_fnav_count_resource {
+struct sxe2_flow_count_resource {
uint32_t count_type;
uint32_t global_index;
- struct sxe2_fnav_cid_mgr_list_t fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t flow_cid_mgr_list;
};
struct sxe2_flow_context {
struct rte_flow_list_t rte_flow_list;
rte_spinlock_t flow_list_lock;
- struct sxe2_fnav_count_resource hw_res;
+ struct sxe2_flow_count_resource hw_res;
uint16_t tunnel_port_list[SXE2_FLOW_UDP_TUNNEL_MAX];
uint32_t fnav_inited;
};
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 25/45] net/sxe2: move tunnel port helpers into flow module
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (24 preceding siblings ...)
2026-08-28 3:25 ` [PATCH v5 24/45] net/sxe2: rename fnav cid manager symbols to flow liujie5
@ 2026-08-28 3:25 ` liujie5
2026-08-28 3:25 ` [PATCH v5 26/45] net/sxe2: add ACL engine event statistics support liujie5
` (19 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:25 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move sxe2_flow_parse_pattern_ipip, sxe2_flow_add_udp_tunnel_port and
sxe2_flow_add_tunnel_port from sxe2_flow_parse_pattern.c into
sxe2_flow.c as static helpers, and drop the public declaration of
sxe2_flow_add_tunnel_port from the header, keeping the tunnel port
handling internal to the flow module.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_flow.c | 113 +++++++++++++++++++++
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ---------------------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 6 --
3 files changed, 113 insertions(+), 119 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index a33b8606df..cd39385340 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -550,6 +550,119 @@ int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev)
return ret;
}
+static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
+ enum sxe2_flow_udp_tunnel_protocol proto,
+ struct sxe2_flow *flow,
+ BITMAP_TYPE *flow_type)
+{
+ int32_t ret = 0;
+ uint16_t tun_port;
+
+ tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
+ if (tun_port == 0xffff || tun_port == 0) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
+ goto l_end;
+ }
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP must be over tunnel");
+ goto l_end;
+ }
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
+ flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
+l_end:
+ return ret;
+}
+
+static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
+{
+ sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ }
+ return 0;
+}
+
+static int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
+ struct rte_flow_error *error,
+ struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
+ enum sxe2_flow_tunnel_type tunnel_type)
+{
+ int32_t ret = 0;
+ enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
+ struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
+ switch (tunnel_type) {
+ case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
+ } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
+ sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GTPU:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GRE:
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
+ }
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_IPIP:
+ ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
+ break;
+ default:
+ break;
+ }
+ if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
+ ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
+ if (ret != 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ NULL, "Failed to add udp port for tunnel.");
+ PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
+ goto l_end;
+ }
+ }
+ if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
+ sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
+ }
+l_end:
+ return ret;
+}
+
static int32_t sxe2_flowlist_add_tunnel_port(struct rte_eth_dev *dev,
struct rte_flow *flow_list,
struct rte_flow_error *error)
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.c b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
index f5bf8922c6..189abb1a33 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
@@ -1637,119 +1637,6 @@ static int32_t sxe2_flow_parse_pattern_vxlan_gpe(const struct rte_flow_item *ite
return ret;
}
-static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
-{
- sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- }
- return 0;
-}
-
-static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
- enum sxe2_flow_udp_tunnel_protocol proto,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type)
-{
- int32_t ret = 0;
- uint16_t tun_port;
-
- tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
- if (tun_port == 0xffff || tun_port == 0) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
- goto l_end;
- }
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP must be over tunnel");
- goto l_end;
- }
- sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
- flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
-l_end:
- return ret;
-}
-
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type)
-{
- int32_t ret = 0;
- enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
- struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
- struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
- switch (tunnel_type) {
- case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
- } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
- sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GTPU:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GRE:
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
- }
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_IPIP:
- ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
- break;
- default:
- break;
- }
- if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
- ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
- if (ret != 0) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- NULL, "Failed to add udp port for tunnel.");
- PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
- goto l_end;
- }
- }
- if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
- sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
- }
-l_end:
- return ret;
-}
-
struct sxe2_flow_parse_pattern_ops sxe2_flow_parse_pattern_list[] = {
[SXE2_EXPANSION_OUTER_ETH] = {
.is_inner = false,
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.h b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
index 8442c35cae..69d83a6ea6 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.h
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
@@ -37,10 +37,4 @@ int32_t sxe2_flow_parse_pattern(struct rte_eth_dev *dev,
struct rte_flow_error *error,
struct sxe2_flow *flow);
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type);
-
#endif /* SXE2_FLOW_PARSE_PATTERN_H_ */
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 26/45] net/sxe2: add ACL engine event statistics support
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (25 preceding siblings ...)
2026-08-28 3:25 ` [PATCH v5 25/45] net/sxe2: move tunnel port helpers into flow module liujie5
@ 2026-08-28 3:25 ` liujie5
2026-08-28 3:25 ` [PATCH v5 27/45] net/sxe2: guard Rx queue event FD free in unregister liujie5
` (18 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:25 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add statistics support for the ACL flow engine to track packet hits
and bytes, enabling flow aging and traffic monitoring for ACL rules.
- Add acl-stat-type devarg to configure the statistics type
- Implement sxe2_drv_flow_acl_get_stat_id/free_stat/query_stat
- Handle the ACL engine in flow create/destroy/query paths
- Add fnav_hw_res and acl_hw_res count resources
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
doc/guides/nics/sxe2.rst | 11 +++
drivers/net/sxe2/sxe2_cmd_chnl.c | 71 ++++++++++++++++++
drivers/net/sxe2/sxe2_cmd_chnl.h | 7 ++
drivers/net/sxe2/sxe2_drv_cmd.h | 19 +++++
drivers/net/sxe2/sxe2_dump.c | 2 +
drivers/net/sxe2/sxe2_ethdev.c | 23 ++++--
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_flow.c | 89 ++++++++++++++++++-----
drivers/net/sxe2/sxe2_flow_define.h | 5 +-
drivers/net/sxe2/sxe2_flow_parse_action.c | 25 +++++--
drivers/net/sxe2/sxe2_queue.c | 2 +
11 files changed, 224 insertions(+), 31 deletions(-)
diff --git a/doc/guides/nics/sxe2.rst b/doc/guides/nics/sxe2.rst
index 8278a5f108..c5b400a8ba 100644
--- a/doc/guides/nics/sxe2.rst
+++ b/doc/guides/nics/sxe2.rst
@@ -98,6 +98,17 @@ Runtime Configuration
Default value is 3 (count both packets and bytes).
+- ``acl-stat-type`` parameter [int]
+
+ This parameter controls the ACL flow engine statistics type
+ used for flow rule hit counting (via ``rte_flow_query``).
+
+ - 1: Only count the number of packets.
+ - 2: Only count the number of bytes.
+ - 3: Count both packets and bytes (default).
+
+ Default value is 3 (count both packets and bytes).
+
- ``drv-sw-stats`` parameter [int]
This parameter controls whether per-packet software statistics (SW stats)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 3229c72597..16a2c3fea4 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1829,6 +1829,77 @@ int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
return ret;
}
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id)
+{
+ struct sxe2_drv_flow_fnav_get_stat_id_req req = { 0 };
+ struct sxe2_drv_flow_fnav_get_stat_id_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC,
+ &req, sizeof(req),
+ &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+ *stat_id = resp.stat_id;
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id)
+{
+ struct sxe2_drv_flow_fnav_free_stat_id_req req = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = stat_id;
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_FREE,
+ &req, sizeof(req),
+ NULL, 0);
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to free acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr)
+{
+ struct sxe2_drv_acl_query_stat_req req = { 0 };
+ struct sxe2_drv_acl_query_stat_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = mgr->stat_index;
+ req.stat_ctrl = mgr->count_type;
+ req.is_clear = 1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY,
+ &req, sizeof(req), &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to query ACL stat, stat id: %u, ret: %d.",
+ req.stat_id, ret);
+ goto l_end;
+ }
+ mgr->hits += resp.stat_hits;
+ mgr->bytes += resp.stat_bytes;
+
+l_end:
+ return ret;
+}
+
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set)
{
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index cfea1a1f0e..7d07068bfc 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -161,6 +161,13 @@ int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
struct sxe2_flow_cid_mgr *mgr);
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id);
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr);
+
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set);
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index 03ef3b315d..cc71e2364e 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -668,6 +668,18 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_fc_get_resp {
uint8_t rsv[3];
} __rte_packed_end;
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_req {
+ uint32_t stat_id;
+ uint32_t stat_ctrl;
+ uint32_t is_clear;
+} __rte_packed_end;
+
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_resp {
+ uint32_t stat_index;
+ uint64_t stat_hits;
+ uint64_t stat_bytes;
+} __rte_packed_end;
+
enum sxe2_drv_cmd_module {
SXE2_DRV_CMD_MODULE_HANDSHAKE = 0,
SXE2_DRV_CMD_MODULE_DEV = 1,
@@ -824,6 +836,13 @@ enum sxe2_drv_cmd_code {
SXE2_DRV_CMD_OPT_EEP_GET =
SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_OPT, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 2),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_FREE =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 3),
+
};
#endif /* SXE2_DRV_CMD_H */
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index 590219f502..31f7d6ba61 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -80,12 +80,14 @@ sxe2_dump_dev_args_info(FILE *file, struct rte_eth_dev *dev)
"\t -- no_sched_mode: %s\n"
"\t -- flow-duplicate-pattern: %u\n"
"\t -- fnav-stat-type: %u\n"
+ "\t -- acl-stat-type: %u\n"
"\t -- sched_layer_mode: %u\n"
"\t -- rx_low_latency: %s\n"
"\t -- function-flow-direct: %s\n",
adapter->devargs.no_sched_mode ? "On" : "Off",
adapter->devargs.flow_dup_pattern_mode,
adapter->devargs.fnav_stat_type,
+ adapter->devargs.acl_stat_type,
adapter->devargs.sched_layer_mode,
adapter->devargs.rx_low_latency ? "On" : "Off",
adapter->devargs.func_flow_direct_en ? "On" : "Off");
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 08986e384f..77a31eb8a1 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -72,6 +72,7 @@ static const struct rte_pci_id pci_id_sxe2_tbl[] = {
#define SXE2_DEVARG_FLOW_DUP_PATTERN_MODE "flow-duplicate-pattern"
#define SXE2_DEVARG_FUNC_FLOW_DIRCT "function-flow-direct"
#define SXE2_DEVARG_FNAV_STAT_TYPE "fnav-stat-type"
+#define SXE2_DEVARG_ACL_STAT_TYPE "acl-stat-type"
#define SXE2_DEVARG_NO_SCHED_MODE "no-sched-mode"
#define SXE2_DEVARG_SCHED_LAYER_MODE "sched-layer-mode"
#define SXE2_DEVARG_RX_LOW_LATENCY "rx-low-latency"
@@ -981,11 +982,11 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
return ptypes;
}
-static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, void *args)
+static int32_t sxe2_parse_stat_type(const char *key, const char *value, void *args)
{
int32_t ret = -EINVAL;
uint8_t *num = (uint8_t *)args;
- unsigned long fnav_stat_type;
+ unsigned long stat_type;
char *endptr = NULL;
if (value == NULL || args == NULL) {
@@ -993,19 +994,19 @@ static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, voi
goto l_end;
}
errno = 0;
- fnav_stat_type = strtoul(value, &endptr, 10);
+ stat_type = strtoul(value, &endptr, 10);
if (errno != 0 || endptr == value || *endptr != '\0') {
PMD_LOG_WARN(INIT, "%s: \"%s\" is not a valid int value.",
key, value);
goto l_end;
}
- if (fnav_stat_type > SXE2_FNAV_STAT_ENA_ALL ||
- fnav_stat_type == SXE2_FNAV_STAT_ENA_NONE) {
+ if (stat_type > SXE2_FNAV_STAT_ENA_ALL ||
+ stat_type == SXE2_FNAV_STAT_ENA_NONE) {
PMD_LOG_ERR(INIT, "%s: \"%s\" out of range [1-3].",
key, value);
goto l_end;
}
- *num = (uint8_t)fnav_stat_type;
+ *num = (uint8_t)stat_type;
ret = 0;
l_end:
return ret;
@@ -1187,13 +1188,20 @@ static int32_t sxe2_args_parse(struct rte_eth_dev *dev, struct sxe2_dev_kvargs_i
if (kvargs == NULL)
goto l_end;
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_FNAV_STAT_TYPE,
- &sxe2_parse_fnav_stat_type,
+ &sxe2_parse_stat_type,
&adapter->devargs.fnav_stat_type);
if (ret) {
PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse fnav stat type, ret:%d", ret);
goto l_end;
}
+ ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_ACL_STAT_TYPE,
+ &sxe2_parse_stat_type, &adapter->devargs.acl_stat_type);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse acl stat type, ret:%d", ret);
+ goto l_end;
+ }
+
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_NO_SCHED_MODE,
&sxe2_parse_bool,
&adapter->devargs.no_sched_mode);
@@ -2366,6 +2374,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_sxe2,
"flow-duplicate-pattern=<0|1|2> "
"function-flow-direct=<0|1> "
"fnav-stat-type=<1|2|3> "
+ "acl-stat-type=<1|2|3> "
"no-sched-mode=<0|1> "
"sched-layer-mode=<0-3> "
"rx-low-latency=<0|1>");
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index e818578319..e9f78fe57f 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -135,6 +135,7 @@ struct sxe2_devargs {
uint8_t flow_dup_pattern_mode;
uint8_t func_flow_direct_en;
uint8_t fnav_stat_type;
+ uint8_t acl_stat_type;
uint8_t no_sched_mode;
uint8_t sched_layer_mode;
uint8_t rx_low_latency;
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index cd39385340..d82d3bbd02 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -1204,13 +1204,23 @@ static int32_t sxe2_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e
int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
struct sxe2_flow_cid_mgr *temp = NULL;
struct sxe2_flow_cid_mgr *mgr = NULL;
+ uint32_t count_type;
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.fnav_hw_res.count_type;
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.acl_hw_res.count_type;
+ } else {
+ goto l_end;
+ }
if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
user_id = flow->action.count.user_id;
@@ -1233,7 +1243,10 @@ int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
goto l_end;
}
- ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ ret = sxe2_drv_flow_acl_get_stat_id(adapter, &stat_index);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to alloc fw count id.");
rte_free(mgr);
@@ -1244,7 +1257,7 @@ int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
mgr->user_id = user_id;
mgr->driver_id = driver_id;
mgr->stat_index = stat_index;
- mgr->count_type = adapter->flow_ctxt.hw_res.count_type;
+ mgr->count_type = count_type;
}
flow->action.count.stat_index = mgr->stat_index;
flow->action.count.stat_ctrl = mgr->count_type;
@@ -1260,13 +1273,26 @@ int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
struct sxe2_flow_cid_mgr *mgr = *mgr_ptr;
uint32_t user_id = flow->action.count.user_id;
- if (user_id == 0) {
- TAILQ_REMOVE(cid_mgr_list, mgr, next);
- ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+
+ if (user_id == 0 && mgr) {
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+ } else {
+ PMD_LOG_ERR(DRV,
+ "Failed to free flow count, unknown engine type: %d.",
+ flow->engine_type);
+ ret = -ENOTSUP;
+ return ret;
+ }
if (ret) {
rte_flow_error_set(error, EIO,
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
@@ -1287,13 +1313,19 @@ int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
struct sxe2_flow_cid_mgr *temp = NULL;
struct sxe2_flow_cid_mgr *mgr = NULL;
uint32_t user_id = flow->action.count.user_id;
uint32_t driver_id = flow->action.count.driver_id;
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ else
+ goto l_end;
+
TAILQ_FOREACH(temp, cid_mgr_list, next) {
if (temp->user_id == user_id &&
temp->driver_id == driver_id) {
@@ -1310,7 +1342,15 @@ int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
ret = -EINVAL;
goto l_end;
}
- ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ ret = sxe2_drv_flow_acl_query_stat(adapter, mgr);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+ } else {
+ PMD_LOG_ERR(DRV, "query flow engine neither FNAV nor ACL");
+ ret = -ENOTSUP;
+ }
if (ret) {
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM, NULL,
@@ -1461,12 +1501,18 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
int32_t ret = 0;
TAILQ_INIT(&adapter->flow_ctxt.rte_flow_list);
- TAILQ_INIT(&adapter->flow_ctxt.hw_res.flow_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list);
if (adapter->devargs.fnav_stat_type)
- adapter->flow_ctxt.hw_res.count_type =
+ adapter->flow_ctxt.fnav_hw_res.count_type =
adapter->devargs.fnav_stat_type;
else
- adapter->flow_ctxt.hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+ adapter->flow_ctxt.fnav_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+
+ if (adapter->devargs.acl_stat_type)
+ adapter->flow_ctxt.acl_hw_res.count_type = adapter->devargs.acl_stat_type;
+ else
+ adapter->flow_ctxt.acl_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
adapter->flow_ctxt.fnav_inited = 1;
rte_spinlock_init(&adapter->flow_ctxt.flow_list_lock);
@@ -1485,13 +1531,13 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
struct rte_flow_error error;
struct sxe2_flow_cid_mgr *mgr = NULL;
struct sxe2_flow_cid_mgr *temp = NULL;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
ret = sxe2_flow_flush(dev, &error);
if (ret)
PMD_LOG_ERR(DRV, "Failed to flush flow, ret: %d.", ret);
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
TAILQ_REMOVE(cid_mgr_list, mgr, next);
ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
@@ -1500,5 +1546,14 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
"Failed to free fnav stat id, ret: %d.", ret);
rte_free(mgr);
}
+
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ if (ret)
+ PMD_LOG_ERR(DRV, "Failed to free acl stat id, ret: %d.", ret);
+ rte_free(mgr);
+ }
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_flow_define.h b/drivers/net/sxe2/sxe2_flow_define.h
index 8a5d871978..d04499f5cb 100644
--- a/drivers/net/sxe2/sxe2_flow_define.h
+++ b/drivers/net/sxe2/sxe2_flow_define.h
@@ -100,7 +100,7 @@ TAILQ_HEAD(rte_flow_list_t, rte_flow);
struct sxe2_flow_cid_mgr {
TAILQ_ENTRY(sxe2_flow_cid_mgr) next;
- uint16_t stat_index;
+ uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
uint32_t count_type;
@@ -118,7 +118,8 @@ struct sxe2_flow_count_resource {
struct sxe2_flow_context {
struct rte_flow_list_t rte_flow_list;
rte_spinlock_t flow_list_lock;
- struct sxe2_flow_count_resource hw_res;
+ struct sxe2_flow_count_resource fnav_hw_res;
+ struct sxe2_flow_count_resource acl_hw_res;
uint16_t tunnel_port_list[SXE2_FLOW_UDP_TUNNEL_MAX];
uint32_t fnav_inited;
};
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index a9559e2d7e..db70b146c6 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -953,7 +953,8 @@ static int32_t sxe2_flow_check_actions(struct rte_eth_dev *dev __rte_unused, str
}
}
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
if (vsi_num) {
flow->action.q_region.q_index = 0;
flow->action.q_region.region = 7;
@@ -988,7 +989,8 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
case RTE_FLOW_ACTION_TYPE_VOID:
break;
case RTE_FLOW_ACTION_TYPE_PASSTHRU:
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
sxe2_set_bit(SXE2_FLOW_ACTION_PASSTHRU, flow->action.act_types);
action_num[SXE2_FLOW_ACTION_PASSTHRU]++;
} else {
@@ -1037,11 +1039,24 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
act_count = action->conf;
- flow->action.count.user_id = act_count->id;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
+ flow->action.count.driver_id = 0;
+ if (flow->action.count.user_id == 0) {
+ flow->action.count.driver_id =
+ ++adapter->flow_ctxt.fnav_hw_res.global_index;
+ }
+ action_num[SXE2_FLOW_ACTION_COUNT]++;
+ } else if (engine_type == SXE2_FLOW_ENGINE_ACL) {
+ sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
+ act_count = action->conf;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
flow->action.count.driver_id = 0;
- if (flow->action.count.user_id == 0)
+ if (flow->action.count.user_id == 0) {
flow->action.count.driver_id =
- ++adapter->flow_ctxt.hw_res.global_index;
+ ++adapter->flow_ctxt.acl_hw_res.global_index;
+ }
action_num[SXE2_FLOW_ACTION_COUNT]++;
} else {
rte_flow_error_set(error, ENOTSUP,
diff --git a/drivers/net/sxe2/sxe2_queue.c b/drivers/net/sxe2/sxe2_queue.c
index afb2681b72..3aaa14c685 100644
--- a/drivers/net/sxe2/sxe2_queue.c
+++ b/drivers/net/sxe2/sxe2_queue.c
@@ -39,6 +39,8 @@ int32_t sxe2_queues_init(struct rte_eth_dev *dev)
rxq->rx_buf_len = RTE_MIN(rxq->rx_buf_len, SXE2_RX_MAX_DATA_BUF_SIZE);
if (frame_size > rxq->rx_buf_len)
dev->data->scattered_rx = 1;
+ if (adapter->flow_ctxt.fnav_inited)
+ rxq->fnav_enable = true;
}
adapter->ptp_ctxt.mbuf_rx_ts_offset = -1;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 27/45] net/sxe2: guard Rx queue event FD free in unregister
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (26 preceding siblings ...)
2026-08-28 3:25 ` [PATCH v5 26/45] net/sxe2: add ACL engine event statistics support liujie5
@ 2026-08-28 3:25 ` liujie5
2026-08-28 3:25 ` [PATCH v5 28/45] net/sxe2: refactor primary process MP message handling liujie5
` (17 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:25 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_rxq_intr_unregister() frees irq_ctxt->rxq_event_fd outside the
rxq_event_fd NULL check. Move the free and NULL assignment inside the
guard so the buffer is only released when it was allocated.
Fixes: 8cebf80f1eda ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index ba764dd5e4..4e5339e24b 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -881,12 +881,11 @@ static void sxe2_rxq_intr_unregister(struct rte_eth_dev *dev)
(void)sxe2_drv_dev_rxq_irq_set(adapter->cdev, i, &efd, 1);
sxe2_rxq_intr_efd_free(irq_ctxt->rxq_event_fd[i]);
}
+ rte_free(irq_ctxt->rxq_event_fd);
+ irq_ctxt->rxq_event_fd = NULL;
}
- rte_free(irq_ctxt->rxq_event_fd);
- irq_ctxt->rxq_event_fd = NULL;
rte_intr_vec_list_free(intr_handle);
-
rte_intr_nb_efd_set(intr_handle, 0);
rte_intr_max_intr_set(intr_handle, 0);
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 28/45] net/sxe2: refactor primary process MP message handling
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (27 preceding siblings ...)
2026-08-28 3:25 ` [PATCH v5 27/45] net/sxe2: guard Rx queue event FD free in unregister liujie5
@ 2026-08-28 3:25 ` liujie5
2026-08-28 3:25 ` [PATCH v5 29/45] net/sxe2: refactor Tx queue reset operations liujie5
` (16 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:25 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Extract the multi-process work logic into the sxe2_mp_do_primary_work
helper and operate on a copy of the request in the primary handler so
the original message is not modified. Simplify the reply construction
and return -ENOENT instead of -EINVAL when no response is received
from the primary process.
Fixes: 5db446ba97b0 ("net/sxe2: support statistics and multi-process")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_mp.c | 59 ++++++++++++++++++++++----------------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_mp.c b/drivers/net/sxe2/sxe2_mp.c
index a4a5c76495..93a11150a9 100644
--- a/drivers/net/sxe2/sxe2_mp.c
+++ b/drivers/net/sxe2/sxe2_mp.c
@@ -29,16 +29,11 @@ static int32_t sxe2_mp_secondary_handle(const struct rte_mp_msg *mp_msg,
const void *peer);
static int32_t
-sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+sxe2_mp_do_primary_work(struct sxe2_mp_param *param)
{
- struct rte_mp_msg reply;
- const struct sxe2_mp_param *param =
- (const struct sxe2_mp_param *)mp_msg->param;
- struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
struct rte_eth_dev *dev;
- int32_t ret = 0;
struct sxe2_mp_shared_data *mz_data;
- int32_t send_reply = 0;
+ int32_t ret = 0;
int32_t cnt = 0;
if (!rte_eth_dev_is_valid_port(param->port_id)) {
@@ -49,24 +44,21 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
}
dev = &rte_eth_devices[param->port_id];
- sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+
if (sxe2_mp_mz == NULL) {
- PMD_LOG_ERR(DRV, "Failed to lookup memzone %s", SXE2_MP_MZ_NAME);
- ret = -ENOENT;
- goto out;
+ sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+ if (sxe2_mp_mz == NULL) {
+ PMD_LOG_ERR(DRV, "Failed to lookup memzone %s",
+ SXE2_MP_MZ_NAME);
+ ret = -ENOENT;
+ goto out;
+ }
}
mz_data = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
- send_reply = 1;
-
- memset(&reply, 0, sizeof(reply));
- (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
- reply.len_param = sizeof(*reply_param);
-
switch (param->type) {
case SXE2_MP_REQ_GET_STATS:
- ret = sxe2_stats_info_get(dev,
- &mz_data->payload.stats_blk.stats,
+ ret = sxe2_stats_info_get(dev, &mz_data->payload.stats_blk.stats,
&mz_data->payload.stats_blk.qstats);
break;
case SXE2_MP_REQ_GET_XSTATS:
@@ -88,15 +80,32 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
default:
PMD_LOG_ERR(DRV, "primary process: unrecognized msg type: %d",
param->type);
- send_reply = false;
ret = -EINVAL;
- goto out;
+ break;
}
+
out:
- if (!send_reply)
- return ret;
+ param->result = ret;
+ return ret;
+}
- reply_param->result = ret;
+static int32_t
+sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+{
+ struct rte_mp_msg reply;
+ struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
+ const struct sxe2_mp_param *param =
+ (const struct sxe2_mp_param *)mp_msg->param;
+ struct sxe2_mp_param param_copy;
+
+ memset(&reply, 0, sizeof(reply));
+ (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
+ reply.len_param = sizeof(*reply_param);
+
+ param_copy = *param;
+ (void)sxe2_mp_do_primary_work(¶m_copy);
+
+ reply_param->result = param_copy.result;
reply_param->type = param->type;
reply_param->port_id = param->port_id;
@@ -275,7 +284,7 @@ int32_t sxe2_mp_request_simple(struct rte_eth_dev *dev,
if (reply.nb_received == 0) {
PMD_LOG_ERR(DRV, "No response received from primary for type=%d, port %u",
type, dev->data->port_id);
- ret = -EINVAL;
+ ret = -ENOENT;
goto out;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 29/45] net/sxe2: refactor Tx queue reset operations
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (28 preceding siblings ...)
2026-08-28 3:25 ` [PATCH v5 28/45] net/sxe2: refactor primary process MP message handling liujie5
@ 2026-08-28 3:25 ` liujie5
2026-08-28 3:26 ` [PATCH v5 30/45] net/sxe2: unify vectorized Tx buffer handling liujie5
` (15 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:25 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Extract the descriptor ring reset loop into a sxe2_tx_queue_desc_ring_reset
helper and reuse it from both the scalar and vectorized queue reset paths.
Add a sxe2_tx_queue_reset_vec entry point for vectorized queues, export
sxe2_tx_buffer_ring_free for reuse outside the module (clearing the buffer
ring pointer after freeing it), and add sxe2_tx_vec_ops_get to build the
vectorized Tx queue operations table used by the vector path setup.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_tx.c | 42 +++++++++++++++++++++++---------
drivers/net/sxe2/sxe2_tx.h | 4 +++
drivers/net/sxe2/sxe2_txrx_vec.c | 16 +++++++++++-
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
4 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_tx.c b/drivers/net/sxe2/sxe2_tx.c
index f49238ceef..94a6e9afc7 100644
--- a/drivers/net/sxe2/sxe2_tx.c
+++ b/drivers/net/sxe2/sxe2_tx.c
@@ -19,6 +19,17 @@ static void *sxe2_tx_doorbell_addr_get(struct sxe2_adapter *adapter, uint16_t qu
queue_id);
}
+static void sxe2_tx_queue_desc_ring_reset(struct sxe2_tx_queue *txq)
+{
+ uint16_t i;
+ static const union sxe2_tx_data_desc zeroed_desc = {{0}};
+
+ for (i = 0; i < txq->ring_depth; i++) {
+ txq->desc_ring[i] = zeroed_desc;
+ txq->desc_ring[i].wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
+ }
+}
+
static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue *txq)
{
txq->tdt_reg_addr = sxe2_tx_doorbell_addr_get(adapter, txq->queue_id);
@@ -28,20 +39,12 @@ static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
{
uint16_t prev, i;
- volatile union sxe2_tx_data_desc *txd;
- static const union sxe2_tx_data_desc zeroed_desc = {{0}};
struct sxe2_tx_buffer *tx_buffer = txq->buffer_ring;
- for (i = 0; i < txq->ring_depth; i++)
- txq->desc_ring[i] = zeroed_desc;
+ sxe2_tx_queue_desc_ring_reset(txq);
prev = txq->ring_depth - 1;
for (i = 0; i < txq->ring_depth; i++) {
- txd = &txq->desc_ring[i];
- if (txd == NULL)
- continue;
-
- txd->wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
tx_buffer[i].mbuf = NULL;
tx_buffer[i].last_id = i;
tx_buffer[prev].next_id = i;
@@ -56,6 +59,21 @@ void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
txq->next_rs = txq->rs_thresh - 1;
}
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq)
+{
+ sxe2_tx_queue_desc_ring_reset(txq);
+
+ memset(txq->buffer_ring, 0,
+ sizeof(struct sxe2_tx_buffer) * txq->ring_depth);
+
+ txq->desc_used_num = 0;
+ txq->desc_free_num = txq->ring_depth - 1;
+ txq->next_use = 0;
+ txq->next_clean = txq->ring_depth - 1;
+ txq->next_dd = txq->rs_thresh - 1;
+ txq->next_rs = txq->rs_thresh - 1;
+}
+
void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
{
uint32_t i;
@@ -70,10 +88,12 @@ void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
}
}
-static void sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
{
- if (txq != NULL && txq->buffer_ring != NULL)
+ if (txq != NULL && txq->buffer_ring != NULL) {
rte_free(txq->buffer_ring);
+ txq->buffer_ring = NULL;
+ }
}
const struct sxe2_txq_ops sxe2_default_txq_ops = {
diff --git a/drivers/net/sxe2/sxe2_tx.h b/drivers/net/sxe2/sxe2_tx.h
index f4823126b3..bc5ff1c2bc 100644
--- a/drivers/net/sxe2/sxe2_tx.h
+++ b/drivers/net/sxe2/sxe2_tx.h
@@ -9,6 +9,10 @@
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq);
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq);
+
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq);
+
int32_t __rte_cold sxe2_tx_queue_start(struct rte_eth_dev *dev, uint16_t queue_id);
void sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.c b/drivers/net/sxe2/sxe2_txrx_vec.c
index cf004f5eb2..9cfa565548 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec.c
@@ -8,6 +8,19 @@
#include "sxe2_ethdev.h"
#include "sxe2_common_log.h"
+static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq);
+
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void)
+{
+ static const struct sxe2_txq_ops ops = {
+ .queue_reset = sxe2_tx_queue_reset_vec,
+ .mbufs_release = sxe2_tx_queue_mbufs_release_vec,
+ .buffer_ring_free = sxe2_tx_buffer_ring_free,
+ };
+
+ return ops;
+}
+
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags)
{
struct sxe2_rx_queue *rxq;
@@ -233,7 +246,8 @@ int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev)
PMD_LOG_INFO(TX, "Failed to prepare tx queue, txq[%d] is NULL", i);
continue;
}
- txq->ops.mbufs_release = sxe2_tx_queue_mbufs_release_vec;
+ txq->ops = sxe2_tx_vec_ops_get();
+ txq->ops.queue_reset(txq);
}
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.h b/drivers/net/sxe2/sxe2_txrx_vec.h
index c139aed776..b9bc4f9c27 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec.h
@@ -89,6 +89,7 @@ uint16_t sxe2_rx_pkts_scattered_vec_neon_offload(void *rx_queue, struct rte_mbuf
uint16_t sxe2_tx_pkts_vec_neon_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
#endif
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void);
int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev);
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 30/45] net/sxe2: unify vectorized Tx buffer handling
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (29 preceding siblings ...)
2026-08-28 3:25 ` [PATCH v5 29/45] net/sxe2: refactor Tx queue reset operations liujie5
@ 2026-08-28 3:26 ` liujie5
2026-08-28 3:26 ` [PATCH v5 31/45] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
` (14 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:26 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add a union of the scalar and vectorized buffer ring pointers to the
Tx queue structure so the vectorized path can use sxe2_tx_buffer_vec
directly. Rename the mbuf fill helper to sxe2_tx_pkts_mbuf_fill_vec,
switch the vectorized Tx burst and mbuf release paths to the
buffer_ring_vec member, and drop the AVX512-specific fill handling and
conditional branching.
Fixes: ac60f302cbef ("net/sxe2: add vectorized Rx and Tx")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_queue.h | 5 +-
drivers/net/sxe2/sxe2_txrx_vec.c | 57 ++----
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 133 +-------------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 9 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 219 ++++++++++++++++--------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
7 files changed, 178 insertions(+), 265 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index 10bdaf5b8d..e53a1ce852 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -62,7 +62,10 @@ struct sxe2_txq_ops {
};
struct sxe2_tx_queue {
volatile union sxe2_tx_data_desc *desc_ring;
- struct sxe2_tx_buffer *buffer_ring;
+ union {
+ struct sxe2_tx_buffer *buffer_ring;
+ struct sxe2_tx_buffer_vec *buffer_ring_vec;
+ };
volatile uint32_t *tdt_reg_addr;
uint64_t offloads;
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.c b/drivers/net/sxe2/sxe2_txrx_vec.c
index 9cfa565548..7c5da33dd5 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec.c
@@ -170,66 +170,31 @@ int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *
static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq)
{
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer_vec;
uint16_t i;
- if (unlikely(txq == NULL || txq->buffer_ring == NULL)) {
+ if (unlikely(txq == NULL || txq->buffer_ring_vec == NULL)) {
PMD_LOG_ERR(TX, "Tx release mbufs vec, invalid params.");
return;
}
- i = txq->next_dd - (txq->rs_thresh - 1);
-#ifdef CC_AVX512_SUPPORT
- struct rte_eth_dev *dev;
- struct sxe2_tx_buffer_vec *buffer_vec;
- dev = &rte_eth_devices[txq->port_id];
-
- if (dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512 ||
- dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512_simple) {
- buffer_vec = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ i = txq->next_dd - (txq->rs_thresh - 1);
+ buffer_vec = txq->buffer_ring_vec;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer_vec[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
- buffer_vec[i].mbuf = NULL;
- }
- }
- i = 0;
- }
- for ( ; i < txq->next_use; ++i) {
+ if (txq->next_use < i) {
+ for ( ; i < txq->ring_depth; ++i) {
if (buffer_vec[i].mbuf != NULL) {
rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
buffer_vec[i].mbuf = NULL;
}
}
- } else {
-#endif
- buffer = txq->buffer_ring;
- buffer = txq->buffer_ring;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
- i = 0;
- }
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
-#ifdef CC_AVX512_SUPPORT
+ i = 0;
}
-#endif
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
+ for ( ; i < txq->next_use; ++i) {
+ if (buffer_vec[i].mbuf != NULL) {
+ rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
+ buffer_vec[i].mbuf = NULL;
}
}
}
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
index 0618e6d988..da96ca3064 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
@@ -115,7 +115,7 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -134,14 +134,14 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -157,10 +157,10 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
index a830c7a33b..6c8415ee5a 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
@@ -1,8 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
*/
-
-#ifndef SXE2_TEST
#include <rte_vect.h>
#include "sxe2_ethdev.h"
@@ -12,114 +10,6 @@
#include "sxe2_txrx_vec_common.h"
#include "sxe2_vsi.h"
-static __rte_always_inline int32_t sxe2_tx_bufs_free_vec_avx512(struct sxe2_tx_queue *txq)
-{
- struct sxe2_tx_buffer_vec *buffer;
- struct rte_mbuf *mbuf;
- struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC];
- struct rte_mempool *mp;
- struct rte_mempool_cache *cache;
- void **cache_objs;
- uint32_t copied;
- uint32_t i;
- int32_t ret;
- uint16_t rs_thresh;
- uint16_t free_num;
-
- if (rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE) !=
- (txq->desc_ring[txq->next_dd].wb.dd &
- rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK))) {
- ret = 0;
- goto l_end;
- }
-
- rs_thresh = txq->rs_thresh;
-
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += txq->next_dd - (rs_thresh - 1);
-
- if ((txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) &&
- (rs_thresh & 31) == 0) {
- mp = buffer[0].mbuf->pool;
- cache = rte_mempool_default_cache(mp, rte_lcore_id());
-
- if (cache == NULL || cache->len)
- goto normal;
-
- if (rs_thresh > RTE_MEMPOOL_CACHE_MAX_SIZE) {
- (void)rte_mempool_ops_enqueue_bulk(mp, (void *)buffer, rs_thresh);
- goto done;
- }
- cache_objs = &cache->objs[cache->len];
-
- copied = 0;
- while (copied < rs_thresh) {
- const __m512i objs0 = _mm512_loadu_si512(&buffer[copied]);
- const __m512i objs1 = _mm512_loadu_si512(&buffer[copied + 8]);
- const __m512i objs2 = _mm512_loadu_si512(&buffer[copied + 16]);
- const __m512i objs3 = _mm512_loadu_si512(&buffer[copied + 24]);
-
- _mm512_storeu_si512(&cache_objs[copied], objs0);
- _mm512_storeu_si512(&cache_objs[copied + 8], objs1);
- _mm512_storeu_si512(&cache_objs[copied + 16], objs2);
- _mm512_storeu_si512(&cache_objs[copied + 24], objs3);
- copied += 32;
- }
- cache->len += rs_thresh;
-
- if (cache->len >= cache->flushthresh) {
- (void)rte_mempool_ops_enqueue_bulk(mp,
- &cache->objs[cache->size], cache->len - cache->size);
- cache->len = cache->size;
- }
- goto done;
- }
-
-normal:
- mbuf = rte_pktmbuf_prefree_seg(buffer[0].mbuf);
-
- if (likely(mbuf)) {
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
-
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
-
- if (likely(mbuf)) {
- if (likely(mbuf->pool == mbuf_free_arr[0]->pool)) {
- mbuf_free_arr[free_num] = mbuf;
- free_num++;
- } else {
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
-
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
- }
- }
- }
-
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
- } else {
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
- if (mbuf != NULL)
- rte_mempool_put(mbuf->pool, mbuf);
- }
- }
-
-done:
- txq->desc_free_num += txq->rs_thresh;
- txq->next_dd += txq->rs_thresh;
- if (txq->next_dd >= txq->ring_depth)
- txq->next_dd = txq->rs_thresh - 1;
- ret = rs_thresh;
-
-l_end:
- return ret;
-}
-
static __rte_always_inline void
sxe2_tx_desc_fill_one_avx512(volatile union sxe2_tx_data_desc *desc, struct rte_mbuf *pkt,
uint64_t desc_cmd, bool with_offloads)
@@ -207,16 +97,6 @@ void sxe2_tx_desc_fill_avx512(volatile union sxe2_tx_data_desc *desc, struct rte
}
}
-static __rte_always_inline void
-sxe2_tx_pkts_mbuf_fill_avx512(struct sxe2_tx_buffer_vec *buffer,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
- uint16_t i;
-
- for (i = 0; i < nb_pkts; ++i)
- buffer[i].mbuf = tx_pkts[i];
-}
-
static __rte_always_inline uint16_t
sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool with_offloads)
@@ -228,7 +108,7 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
uint16_t tx_num;
if (txq->desc_free_num < txq->free_thresh)
- (void)sxe2_tx_bufs_free_vec_avx512(txq);
+ (void)sxe2_tx_bufs_free_vec(txq);
nb_pkts = RTE_MIN(txq->desc_free_num, nb_pkts);
if (unlikely(nb_pkts == 0)) {
@@ -241,15 +121,14 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += next_use;
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -265,10 +144,10 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = txq->desc_ring;
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -863,5 +742,3 @@ uint16_t sxe2_rx_pkts_scattered_vec_avx512_offload(void *rx_queue,
return sxe2_rx_pkts_scattered_common_vec_avx512(rx_queue,
rx_pkts, nb_pkts, true);
}
-
-#endif
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_common.h b/drivers/net/sxe2/sxe2_txrx_vec_common.h
index 9ac99cf0fa..ede4c236b1 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_common.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec_common.h
@@ -25,10 +25,11 @@
#define SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC 64
static __rte_always_inline void
-sxe2_tx_pkts_mbuf_fill(struct sxe2_tx_buffer *buffer,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+sxe2_tx_pkts_mbuf_fill_vec(struct sxe2_tx_buffer_vec *buffer,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
uint16_t i;
+
for (i = 0; i < nb_pkts; ++i)
buffer[i].mbuf = tx_pkts[i];
}
@@ -36,7 +37,7 @@ sxe2_tx_pkts_mbuf_fill(struct sxe2_tx_buffer *buffer,
static __rte_always_inline int32_t
sxe2_tx_bufs_free_vec(struct sxe2_tx_queue *txq)
{
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
struct rte_mbuf *mbuf;
struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC];
int32_t ret;
@@ -50,7 +51,7 @@ sxe2_tx_bufs_free_vec(struct sxe2_tx_queue *txq)
goto l_end;
}
rs_thresh = txq->rs_thresh;
- buffer = &txq->buffer_ring[txq->next_dd - (rs_thresh - 1)];
+ buffer = &txq->buffer_ring_vec[txq->next_dd - (rs_thresh - 1)];
mbuf = rte_pktmbuf_prefree_seg(buffer[0].mbuf);
if (likely(mbuf)) {
mbuf_free_arr[0] = mbuf;
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_neon.c b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
index 4e5cb87cd5..0b139b8269 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_neon.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
@@ -34,12 +34,58 @@ sxe2_tx_desc_fill_one_neon(volatile union sxe2_tx_data_desc *desc,
vst1q_u64(RTE_CAST_PTR(uint64_t *, desc), data_desc);
}
+static __rte_always_inline void
+sxe2_tx_desc_fill_4_neon_simple(volatile union sxe2_tx_data_desc *desc,
+ struct rte_mbuf **pkts)
+{
+ uint64x2_t d0, d1, d2, d3;
+ uint64x2x4_t v;
+ const uint64_t cmd_base = ((uint64_t)SXE2_TX_DESC_DTYPE_DATA) |
+ ((uint64_t)SXE2_TX_DATA_DESC_CMD_EOP) <<
+ SXE2_TX_DATA_DESC_CMD_SHIFT;
+
+ d0 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[0]),
+ cmd_base |
+ ((uint64_t)pkts[0]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[0]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d1 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[1]),
+ cmd_base |
+ ((uint64_t)pkts[1]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[1]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d2 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[2]),
+ cmd_base |
+ ((uint64_t)pkts[2]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[2]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d3 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[3]),
+ cmd_base |
+ ((uint64_t)pkts[3]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[3]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+
+ v.val[0] = d0;
+ v.val[1] = d1;
+ v.val[2] = d2;
+ v.val[3] = d3;
+ vst1q_u64_x4(RTE_CAST_PTR(uint64_t *, desc), v);
+}
+
static __rte_always_inline uint16_t
sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -59,18 +105,26 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
-
- for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
+ if (with_offloads) {
+ for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ }
+ } else {
+ for (i = 0; i + 3 < res_num - 1; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
sxe2_tx_desc_fill_one_neon(desc, *tx_pkts++,
@@ -82,14 +136,23 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
- for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ if (with_offloads) {
+ for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, true);
+ }
+ } else {
+ for (i = 0; i + 3 < tx_num; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
next_use += tx_num;
@@ -150,22 +213,24 @@ uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue,
}
static __rte_always_inline void
-sxe2_rx_desc_ptype_fill_neon(uint16x8_t staterr, struct rte_mbuf **__rte_restrict rx_pkts)
+sxe2_rx_desc_ptype_fill_neon(uint32x4_t desc_lo,
+ struct rte_mbuf **__rte_restrict rx_pkts,
+ const uint32_t *__rte_restrict ptype_tbl)
{
- uint16x8_t ptype_mask = {
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
+ const uint32x4_t ptype_mask = {
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
};
uint16x8_t ptype_all;
- ptype_all = vandq_u16(staterr, ptype_mask);
+ ptype_all = vreinterpretq_u16_u32(vandq_u32(desc_lo, ptype_mask));
- rx_pkts[3]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
- rx_pkts[2]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
- rx_pkts[1]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
- rx_pkts[0]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[0]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
+ rx_pkts[1]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
+ rx_pkts[2]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[3]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
}
static __rte_always_inline uint32x4_t
@@ -208,9 +273,10 @@ sxe2_rx_desc_fnav_flags_neon(uint64x2_t descs_arr[4])
static __rte_always_inline void
sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
volatile union sxe2_rx_desc *desc,
- uint64x2_t descs[4], struct rte_mbuf **rx_pkts)
+ uint64x2_t descs[4], uint32x4_t desc_lo, uint32x4_t desc_hi,
+ struct rte_mbuf **rx_pkts)
{
- uint32x4_t desc_lo, desc_hi, flags, tmp_flags;
+ uint32x4_t flags, tmp_flags;
const uint64x2_t mbuf_init = {rxq->mbuf_init_value, 0};
uint64x2_t rearm0, rearm1, rearm2, rearm3;
@@ -267,23 +333,6 @@ sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
0, 0, 0, 0, 0, 0, 0, 0
};
- {
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint64x2_t f64, t64;
-
- flags = vzip2q_u32(d1, d0);
- tmp_flags = vzip2q_u32(d3, d2);
- f64 = vreinterpretq_u64_u32(flags);
- t64 = vreinterpretq_u64_u32(tmp_flags);
- desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(f64),
- vget_low_u64(t64)));
- desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(f64),
- vget_high_u64(t64)));
- }
-
desc_lo = vandq_u32(desc_lo, desc_msk);
desc_hi = vandq_u32(desc_hi, rss_msk);
@@ -442,25 +491,39 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
uint64x2_t descs[SXE2_RX_NUM_PER_LOOP_NEON];
uint8x16_t pkt_mb1, pkt_mb2, pkt_mb3, pkt_mb4;
uint64x2_t mbp1, mbp2;
+ uint32x4_t desc_lo, desc_hi;
uint16x8_t staterr;
uint16x8_t tmp;
uint16_t bit_num;
descs[3] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 3));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[2] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 2));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[1] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 1));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[0] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc));
rte_atomic_thread_fence(rte_memory_order_acquire);
-
descs[3] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 3), descs[3], 0);
descs[2] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 2), descs[2], 0);
descs[1] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 1), descs[1], 0);
descs[0] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc), descs[0], 0);
+ {
+ uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
+ uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
+ uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
+ uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
+
+ uint32x4_t q1_01 = vzip2q_u32(d0, d1);
+ uint32x4_t q1_23 = vzip2q_u32(d2, d3);
+ uint64x2_t q1_01_64 = vreinterpretq_u64_u32(q1_01);
+ uint64x2_t q1_23_64 = vreinterpretq_u64_u32(q1_23);
+
+ desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(q1_01_64),
+ vget_low_u64(q1_23_64)));
+ desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(q1_01_64),
+ vget_high_u64(q1_23_64)));
+ }
+
mbp1 = vld1q_u64((uint64_t *)&buffer[i]);
mbp2 = vld1q_u64((uint64_t *)&buffer[i + 2]);
@@ -480,7 +543,8 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
pkt_mb1 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[0]), rvp_shuf_mask);
if (do_offload) {
- sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, &rx_pkts[i]);
+ sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, desc_lo,
+ desc_hi, &rx_pkts[i]);
} else {
const uint64x2_t mbuf_init = {
rxq->mbuf_init_value,
@@ -515,55 +579,48 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
rte_prefetch_non_temporal(desc + SXE2_RX_NUM_PER_LOOP_NEON);
{
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint32x4_t sterr_tmp1 = vzip2q_u32(d1, d0);
- uint32x4_t sterr_tmp2 = vzip2q_u32(d3, d2);
- uint32x4_t sterr_u32 = vzip1q_u32(sterr_tmp1, sterr_tmp2);
-
- staterr = vreinterpretq_u16_u32(sterr_u32);
+ uint16x8_t sterr_tmp1 = vzip2q_u16(vreinterpretq_u16_u64(descs[0]),
+ vreinterpretq_u16_u64(descs[2]));
+ uint16x8_t sterr_tmp2 = vzip2q_u16(vreinterpretq_u16_u64(descs[1]),
+ vreinterpretq_u16_u64(descs[3]));
+ staterr = vzip1q_u16(sterr_tmp1, sterr_tmp2);
}
- sxe2_rx_desc_ptype_fill_neon(staterr, &rx_pkts[i]);
+ sxe2_rx_desc_ptype_fill_neon(desc_lo, &rx_pkts[i], sxe2_ptype_tbl);
if (umbcast_flags != NULL) {
- uint32x4_t umbcast_mask = {
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- };
-
+ const uint32x4_t umbcast_mask =
+ vdupq_n_u32(SXE2_RX_DESC_STATUS_UMBCAST_MASK);
uint8x16_t umbcast_shuf_mask = {
- 0x0B, 0x03, 0x0F, 0x07,
+ 3, 7, 11, 15,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
};
uint8x16_t umbcast_bits =
- vreinterpretq_u8_u32(vandq_u32(vreinterpretq_u32_u16(staterr),
- umbcast_mask));
+ vreinterpretq_u8_u32(vandq_u32(desc_lo, umbcast_mask));
umbcast_bits = vqtbl1q_u8(umbcast_bits, umbcast_shuf_mask);
- vst1q_lane_u32((uint32_t *)umbcast_flags,
- vreinterpretq_u32_u8(umbcast_bits), 0);
+ *(uint32_t *)umbcast_flags =
+ vgetq_lane_u32(vreinterpretq_u32_u8(umbcast_bits), 0);
umbcast_flags += SXE2_RX_NUM_PER_LOOP_NEON;
}
if (split_rxe_flags) {
uint8x16_t eop_shuf_mask = {
- 0x08, 0x00, 0x0C, 0x04,
+ 0, 2, 4, 6,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF};
uint8x16_t eop_bits;
uint32x4_t rxe_mask = {
- 0x2080, 0x2080, 0x2080, 0x2080
+ 0x20802080, 0x20802080, 0x20802080, 0x20802080
};
uint32x4_t rxe_bits;
uint32x4_t eop_mask;
- eop_mask = vshlq_n_u32(vdupq_n_u32(1), SXE2_RX_DESC_STATUS_EOP_SHIFT);
+ eop_mask = vdupq_n_u32((1U << SXE2_RX_DESC_STATUS_EOP_SHIFT) |
+ (1U << (SXE2_RX_DESC_STATUS_EOP_SHIFT + 16)));
eop_bits = vandq_u8(vmvnq_u8(vreinterpretq_u8_u16(staterr)),
vreinterpretq_u8_u32(eop_mask));
@@ -587,12 +644,22 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
}
{
- uint32x4_t dd_mask = vdupq_n_u32(1);
- uint32x4_t sterr_dd = vandq_u32(vreinterpretq_u32_u16(staterr), dd_mask);
- uint16x4_t packed_lo = vmovn_u32(sterr_dd);
- uint64_t dd64 = vget_lane_u64(vreinterpret_u64_u16(packed_lo), 0);
-
- bit_num = (uint16_t)rte_popcount64(dd64);
+ const uint16x8_t dd_check = {
+ 0x0001, 0x0001, 0x0001, 0x0001,
+ 0, 0, 0, 0
+ };
+ uint16x8_t sterr_dd;
+ uint64_t stat;
+ sterr_dd = vandq_u16(staterr, dd_check);
+ sterr_dd = vshlq_n_u16(sterr_dd, 15);
+ sterr_dd =
+ vreinterpretq_u16_s16(vshrq_n_s16(vreinterpretq_s16_u16(sterr_dd),
+ 15));
+ stat = ~vgetq_lane_u64(vreinterpretq_u64_u16(sterr_dd), 0);
+ if (likely(stat == 0))
+ bit_num = SXE2_RX_NUM_PER_LOOP_NEON;
+ else
+ bit_num = (uint16_t)(rte_ctz64(stat) / 16);
}
done_num += bit_num;
if (likely(bit_num != SXE2_RX_NUM_PER_LOOP_NEON))
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_sse.c b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
index c3e8a2983b..181bb40041 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_sse.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
@@ -40,7 +40,7 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -57,11 +57,11 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
tx_num = nb_pkts;
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
@@ -74,9 +74,9 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 31/45] net/sxe2: refine vectorized Tx/Rx mode setup
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (30 preceding siblings ...)
2026-08-28 3:26 ` [PATCH v5 30/45] net/sxe2: unify vectorized Tx buffer handling liujie5
@ 2026-08-28 3:26 ` liujie5
2026-08-28 3:26 ` [PATCH v5 32/45] net/sxe2: fix RSS action attribute validation liujie5
` (13 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:26 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Set rte_eth_tx_pkt_prepare_dummy for the simple and vectorized Tx paths
instead of leaving the prepare callback unset, and split the NEON
simple/offload mode selection based on the offload flag. Log the selected
Tx/Rx mode flags and apply the default Rx free threshold when the
configured value is zero.
Fixes: ac60f302cbef ("net/sxe2: add vectorized Rx and Tx")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_rx.c | 3 ++-
drivers/net/sxe2/sxe2_txrx.c | 20 +++++++++++++++-----
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_rx.c b/drivers/net/sxe2/sxe2_rx.c
index d700c60083..3830c676d7 100644
--- a/drivers/net/sxe2/sxe2_rx.c
+++ b/drivers/net/sxe2/sxe2_rx.c
@@ -319,7 +319,8 @@ int32_t __rte_cold sxe2_rx_queue_setup(struct rte_eth_dev *dev,
rxq->mb_pool = mp;
}
- rxq->rx_free_thresh = rx_conf->rx_free_thresh;
+ rxq->rx_free_thresh = (rx_conf->rx_free_thresh == 0) ?
+ SXE2_DEFAULT_RX_FREE_THRESH : rx_conf->rx_free_thresh;
rxq->port_id = dev->data->port_id;
rxq->offloads = offloads;
if (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
diff --git a/drivers/net/sxe2/sxe2_txrx.c b/drivers/net/sxe2/sxe2_txrx.c
index 79870866d1..f7276f6a19 100644
--- a/drivers/net/sxe2/sxe2_txrx.c
+++ b/drivers/net/sxe2/sxe2_txrx.c
@@ -358,7 +358,7 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
if (tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
#ifdef RTE_ARCH_X86
if (tx_mode_flags & SXE2_TX_MODE_VEC_AVX512) {
#ifdef CC_AVX512_SUPPORT
@@ -386,21 +386,28 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
#elif defined(RTE_ARCH_ARM64)
if (tx_mode_flags & SXE2_TX_MODE_VEC_NEON) {
- dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
+ if (tx_mode_flags & SXE2_TX_MODE_VEC_OFFLOAD) {
+ dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
+ } else {
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ }
} else {
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
+ dev->tx_pkt_burst = sxe2_tx_pkts;
}
#endif
} else {
if (tx_mode_flags & SXE2_TX_MODE_SIMPLE_BATCH) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
dev->tx_pkt_burst = sxe2_tx_pkts_simple;
} else {
dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
dev->tx_pkt_burst = sxe2_tx_pkts;
}
}
+ PMD_LOG_DEBUG(TX, "Tx mode flags:0x%016x port_id:%u.",
+ tx_mode_flags, dev->data->port_id);
}
static const struct {
@@ -582,6 +589,9 @@ void sxe2_rx_mode_func_set(struct rte_eth_dev *dev)
dev->rx_pkt_burst = sxe2_rx_pkts_scattered_split;
else
dev->rx_pkt_burst = sxe2_rx_pkts_scattered;
+
+ PMD_LOG_DEBUG(RX, "Rx mode flags:0x%016x port_id:%u.",
+ rx_mode_flags, dev->data->port_id);
}
static const struct {
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 32/45] net/sxe2: fix RSS action attribute validation
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (31 preceding siblings ...)
2026-08-28 3:26 ` [PATCH v5 31/45] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
@ 2026-08-28 3:26 ` liujie5
2026-08-28 3:26 ` [PATCH v5 33/45] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
` (12 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:26 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The rss->level/key_len/queue_num checks only set the rte_flow_error
but still return 0 (success), so invalid RSS configurations are
accepted instead of being rejected with ENOTSUP.
Return the error code from the validation checks, matching the
behavior in the V3 implementation.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_flow_parse_action.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index db70b146c6..b0275321be 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -12,7 +12,7 @@
static int32_t sxe2_flow_check_rss_action_attr(const struct rte_flow_action_rss *rss,
struct rte_flow_error *error)
{
- int32_t ret = ENOTSUP;
+ int32_t ret = -ENOTSUP;
switch (rss->func) {
case RTE_ETH_HASH_FUNCTION_DEFAULT:
case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
@@ -25,15 +25,21 @@ static int32_t sxe2_flow_check_rss_action_attr(const struct rte_flow_action_rss
goto l_end;
}
- if (rss->level > 2)
+ if (rss->level > 2) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"RSS level is could not be greater than 2");
- if (rss->key_len)
+ goto l_end;
+ }
+ if (rss->key_len) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a nonzero RSS key_len is not supported");
- if (rss->queue_num)
+ goto l_end;
+ }
+ if (rss->queue_num) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a non-NULL RSS queue is not supported");
+ goto l_end;
+ }
ret = 0;
l_end:
return ret;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 33/45] net/sxe2: restore PF-only guard in udp tunnel port add
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (32 preceding siblings ...)
2026-08-28 3:26 ` [PATCH v5 32/45] net/sxe2: fix RSS action attribute validation liujie5
@ 2026-08-28 3:26 ` liujie5
2026-08-28 3:26 ` [PATCH v5 34/45] net/sxe2: restore link update call in status query liujie5
` (11 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:26 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_udp_tunnel_port_add_common() lost the check that restricts
UDP tunnel port configuration to PF devices (not VF or
representor), so VF/representor devices can now attempt to add
UDP tunnel ports, which the hardware does not support.
Restore the PF-only guard returning -ENOTSUP, matching the V3
implementation.
Fixes: fff24885f70a ("net/sxe2: support custom UDP tunnel ports")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 77a31eb8a1..8c60c9cfde 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -630,6 +630,10 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
struct sxe2_udp_tunnel_cfg *tunnel_config;
int32_t ret = -1;
+ if (ad->dev_type != SXE2_DEV_T_PF || ad->is_dev_repr) {
+ ret = -ENOTSUP;
+ goto l_end;
+ }
rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
tunnel_config = &ad->udp_tunnel_ctx.tunnel_conf[tunnel_proto];
@@ -659,6 +663,7 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
l_unlock_end:
rte_spinlock_unlock(&ad->udp_tunnel_ctx.lock);
+l_end:
return ret;
}
@@ -669,6 +674,9 @@ int32_t sxe2_udp_tunnel_port_del_common(struct sxe2_adapter *ad,
struct sxe2_udp_tunnel_cfg *tunnel_config;
int32_t ret = -1;
+ if (ad->dev_type != SXE2_DEV_T_PF || ad->is_dev_repr)
+ return -ENOTSUP;
+
rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
tunnel_config = &ad->udp_tunnel_ctx.tunnel_conf[tunnel_proto];
@@ -703,6 +711,9 @@ static int32_t sxe2_udp_tunnel_port_clear(struct rte_eth_dev *dev)
int32_t ret = 0;
uint16_t tunnel_proto = 0;
+ if (ad->dev_type != SXE2_DEV_T_PF || ad->is_dev_repr)
+ return -ENOTSUP;
+
rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
for (tunnel_proto = 0; tunnel_proto < SXE2_UDP_TUNNEL_MAX; tunnel_proto++) {
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 34/45] net/sxe2: restore link update call in status query
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (33 preceding siblings ...)
2026-08-28 3:26 ` [PATCH v5 33/45] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
@ 2026-08-28 3:26 ` liujie5
2026-08-28 3:26 ` [PATCH v5 35/45] net/sxe2: validate representor ID against VF count liujie5
` (10 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:26 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_mac_link_status_get() no longer calls sxe2_link_update()
after refreshing the link context, so the ethdev link state is only
refreshed during device init (sxe2_link_update_init) and never
updated when link status is queried at runtime, including on LSC
interrupt events.
Move the sxe2_link_update() call back into
sxe2_drv_mac_link_status_get() and simplify sxe2_link_update_init()
accordingly, matching the V3 implementation.
Fixes: 1d7fd921beef ("net/sxe2: support link update")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 2 ++
drivers/net/sxe2/sxe2_mac.c | 11 +++--------
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index 4e5339e24b..b0e1552d5f 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -84,6 +84,7 @@ static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t
if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
PMD_DEV_LOG_INFO(adapter, DRV, "OICR=0x%" PRIx64, oicr);
(void)sxe2_drv_mac_link_status_get(adapter);
+ (void)sxe2_link_update(dev, 0);
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_LSC,
@@ -96,6 +97,7 @@ static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t
continue;
repr_adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(repr_eth_dev);
(void)sxe2_drv_mac_link_status_get(repr_adapter);
+ (void)sxe2_link_update(repr_eth_dev, 0);
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
rte_eth_dev_callback_process(repr_eth_dev,
RTE_ETH_EVENT_INTR_LSC,
diff --git a/drivers/net/sxe2/sxe2_mac.c b/drivers/net/sxe2/sxe2_mac.c
index 729c804ac3..ab9bd5355b 100644
--- a/drivers/net/sxe2/sxe2_mac.c
+++ b/drivers/net/sxe2/sxe2_mac.c
@@ -448,18 +448,13 @@ int32_t sxe2_link_update_init(struct rte_eth_dev *dev)
int32_t ret;
PMD_INIT_FUNC_TRACE();
-
rte_spinlock_init(&adapter->link_ctxt.link_lock);
-
ret = sxe2_drv_mac_link_status_get(adapter);
- if (ret) {
+ if (ret)
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get link status, ret=%d", ret);
- goto l_end;
- }
-
- (void)sxe2_link_update(dev, 0);
+ else
+ (void)sxe2_link_update(dev, 0);
-l_end:
return ret;
}
int32_t sxe2_link_update(struct rte_eth_dev *dev, __rte_unused int32_t wait_to_complete)
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 35/45] net/sxe2: validate representor ID against VF count
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (34 preceding siblings ...)
2026-08-28 3:26 ` [PATCH v5 34/45] net/sxe2: restore link update call in status query liujie5
@ 2026-08-28 3:26 ` liujie5
2026-08-28 3:26 ` [PATCH v5 36/45] net/sxe2: use primary VSI ID for representor VSI liujie5
` (9 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:26 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_switchdev_repr_private_data_init() indexes
parent_adapter->repr_ctxt.repr_vf_id[repr_id] without checking that
repr_id is within the number of configured VFs, which can access out
of bounds when an invalid representor ID is passed.
Add a bounds check on repr_id against repr_ctxt.nb_vf and return
-EINVAL on the error path.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_switchdev.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index efb1468b91..d0304ccc94 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -312,6 +312,12 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_q_id = repr_id;
repr_priv_data->repr_pf_id = parent_adapter->pf_idx;
repr_priv_data->repr_vf_id = repr_id;
+ if (repr_id >= parent_adapter->repr_ctxt.nb_vf) {
+ PMD_LOG_ERR(INIT, "repr_id %u exceed max vf %u",
+ repr_id, parent_adapter->repr_ctxt.nb_vf);
+ ret = -EINVAL;
+ goto l_free;
+ }
repr_priv_data->repr_vf_primary_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
repr_priv_data->repr_vf_backup_vsi_id =
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 36/45] net/sxe2: use primary VSI ID for representor VSI
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (35 preceding siblings ...)
2026-08-28 3:26 ` [PATCH v5 35/45] net/sxe2: validate representor ID against VF count liujie5
@ 2026-08-28 3:26 ` liujie5
2026-08-28 3:26 ` [PATCH v5 37/45] net/sxe2: wrap command params fill debug log in macro liujie5
` (8 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:26 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
repr_priv_data->repr_vf_vsi_id is assigned with a ternary that falls
back to the backup (dpdk) VSI ID when the kernel VSI ID is invalid.
The V3 implementation assigns it directly from
repr_vf_primary_vsi_id.
Align with the V3 implementation by assigning repr_vf_vsi_id from
repr_vf_primary_vsi_id.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_switchdev.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index d0304ccc94..81ced7b855 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -323,11 +323,7 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
- repr_priv_data->repr_vf_vsi_id =
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id !=
- SXE2_INVALID_VSI_ID ?
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id :
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
+ repr_priv_data->repr_vf_vsi_id = repr_priv_data->repr_vf_primary_vsi_id;
adapter->repr_priv_data = repr_priv_data;
goto l_end;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 37/45] net/sxe2: wrap command params fill debug log in macro
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (36 preceding siblings ...)
2026-08-28 3:26 ` [PATCH v5 36/45] net/sxe2: use primary VSI ID for representor VSI liujie5
@ 2026-08-28 3:26 ` liujie5
2026-08-28 3:26 ` [PATCH v5 38/45] net/sxe2: restore Rx queue buffer split fill support liujie5
` (7 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:26 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_cmd_params_fill() passes the opcode string as a
parameter to __sxe2_drv_cmd_params_fill() just to emit a debug
log. The debug log is level-gated by PMD_DEV_LOG_DEBUG either
way; moving it into the macro body only consolidates the call
sites.
Wrap the log and the fill helper in a do/while block, dropping
the opc_str parameter so the opcode stringization happens at
the call site. Evaluate the adapter argument exactly once
through a local variable.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 16a2c3fea4..84fe401ec4 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -26,10 +26,9 @@ static void sxe2_drv_trace_id_alloc(uint64_t *trace_id)
}
static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
- struct sxe2_drv_cmd_params *cmd, uint32_t opc, const char *opc_str,
+ struct sxe2_drv_cmd_params *cmd, uint32_t opc,
void *in_data, uint32_t in_len, void *out_data, uint32_t out_len)
{
- PMD_DEV_LOG_DEBUG(adapter, DRV, "cmd opcode:%s", opc_str);
cmd->timeout = SXE2_DRV_CMD_DFLT_TIMEOUT;
cmd->opcode = opc;
cmd->vsi_id = adapter->vsi_ctxt.dpdk_vsi_id;
@@ -44,8 +43,11 @@ static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
}
#define sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len) \
- __sxe2_drv_cmd_params_fill(adapter, cmd, opc, #opc, in_data, in_len, out_data, out_len)
-
+ do { \
+ struct sxe2_adapter *__adapter = (adapter); \
+ PMD_DEV_LOG_DEBUG(__adapter, DRV, "cmd opcode:%s", #opc); \
+ __sxe2_drv_cmd_params_fill(__adapter, cmd, opc, in_data, in_len, out_data, out_len); \
+ } while (0)
int32_t sxe2_drv_dev_caps_get(struct sxe2_adapter *adapter, struct sxe2_drv_dev_caps_resp *dev_caps)
{
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 38/45] net/sxe2: restore Rx queue buffer split fill support
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (37 preceding siblings ...)
2026-08-28 3:26 ` [PATCH v5 37/45] net/sxe2: wrap command params fill debug log in macro liujie5
@ 2026-08-28 3:26 ` liujie5
2026-08-28 3:26 ` [PATCH v5 39/45] net/sxe2: skip tunnel config fill on get failure liujie5
` (6 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:26 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The V4 branch dropped sxe2_rxq_buf_split_fill() and the buffer split
handling in sxe2_rxq_ctxt_cfg_fill(), so the Rx buffer split offload
(RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) is advertised in device info but
the per-queue context never configures split_en/split_type_mask/
hdr_len, and buffer split packets are not handled correctly.
Restore the sxe2_rxq_buf_split_fill() helper and the buffer split
branch in sxe2_rxq_ctxt_cfg_fill(), matching the V3 implementation.
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 88 ++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 84fe401ec4..3998309bb1 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -195,6 +195,84 @@ int32_t sxe2_drv_vsi_del(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi)
#define SXE2_RXQ_CTXT_CFG_BUF_LEN_ALIGN (1 << 7)
#define SXE2_RX_HDR_SIZE 256
+static int32_t sxe2_rxq_buf_split_fill(struct sxe2_rx_queue *rxq,
+ struct sxe2_drv_rxq_ctxt *ctxt)
+{
+ uint32_t proto_hdr;
+
+ proto_hdr = rxq->rx_seg[0].proto_hdr;
+ if (proto_hdr == RTE_PTYPE_UNKNOWN) {
+ PMD_LOG_ERR(RX, "Buffer split protocol must be configured");
+ return -EINVAL;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L4_MASK) {
+ case RTE_PTYPE_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_TCP;
+ goto l_end;
+ case RTE_PTYPE_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_UDP;
+ goto l_end;
+ case RTE_PTYPE_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_SCTP;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L3_MASK) {
+ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV4;
+ goto l_end;
+ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV6;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L2_MASK) {
+ case RTE_PTYPE_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_L2_ETHER;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L4_MASK) {
+ case RTE_PTYPE_INNER_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_TCP;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_UDP;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_SCTP;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L3_MASK) {
+ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV4;
+ goto l_end;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV6;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L2_MASK) {
+ case RTE_PTYPE_INNER_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L2_ETHER;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_TUNNEL_MASK) {
+ case RTE_PTYPE_TUNNEL_GRENAT:
+ ctxt->split_type_mask = SXE2_PTYPE_TUNNEL_GRENAT;
+ goto l_end;
+ }
+
+ PMD_LOG_ERR(RX, "Buffer split protocol is not supported");
+ return -ENOTSUP;
+l_end:
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ return 0;
+}
+
static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
struct sxe2_drv_rxq_cfg_req *req, uint16_t rxq_cnt)
{
@@ -228,7 +306,17 @@ static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
else
ctxt->keep_crc_en = 0;
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
+ ret = sxe2_rxq_buf_split_fill(rxq, ctxt);
+ if (ret)
+ goto l_end;
+ ctxt->split_en = 1;
+ } else {
+ ctxt->split_en = 0;
+ }
+
ctxt->desc_size = sizeof(union sxe2_rx_desc);
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 39/45] net/sxe2: skip tunnel config fill on get failure
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (38 preceding siblings ...)
2026-08-28 3:26 ` [PATCH v5 38/45] net/sxe2: restore Rx queue buffer split fill support liujie5
@ 2026-08-28 3:26 ` liujie5
2026-08-28 3:27 ` [PATCH v5 40/45] net/sxe2: skip flow id assignment on filter add failure liujie5
` (5 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:26 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_udp_tunnel_get() fills tunnel_config fields even when the
firmware command fails, so a failed get overwrites the config with
the (zero-initialized) response data instead of leaving it intact.
Return early with the error code when sxe2_drv_cmd_exec() fails,
matching the V3 implementation.
Fixes: fff24885f70a ("net/sxe2: support custom UDP tunnel ports")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 3998309bb1..581026e81d 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1650,15 +1650,17 @@ int32_t sxe2_drv_udp_tunnel_get(struct sxe2_adapter *adapter,
&req, sizeof(req),
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_LOG_ERR(DRV, "Failed to get udp proto %d port, ret=%d", req.type, ret);
+ goto l_end;
+ }
tunnel_config->fw_port = resp.port;
tunnel_config->fw_status = resp.enable;
tunnel_config->fw_dst_en = resp.dst;
tunnel_config->fw_src_en = resp.src;
tunnel_config->fw_used = resp.fw_used;
-
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 40/45] net/sxe2: skip flow id assignment on filter add failure
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (39 preceding siblings ...)
2026-08-28 3:26 ` [PATCH v5 39/45] net/sxe2: skip tunnel config fill on get failure liujie5
@ 2026-08-28 3:27 ` liujie5
2026-08-28 3:27 ` [PATCH v5 41/45] net/sxe2: fix command channel log messages liujie5
` (4 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:27 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_flow_filter_add() assigns flow->flow_id from the response
even when the firmware command fails, overwriting any previously
set flow id with the zero-initialized response value.
Return early on command failure so flow->flow_id is preserved, and
set flow->create_err on both the success and error paths.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 581026e81d..89829f29be 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1818,9 +1818,13 @@ int32_t sxe2_drv_flow_filter_add(struct sxe2_adapter *adapter, struct sxe2_flow
sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_FILTER_ADD, &req,
sizeof(req), &resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to add flow filter, ret: %d.", ret);
+ goto l_end;
+ }
flow->flow_id = resp.flow_id;
+
+l_end:
flow->create_err = ret;
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 41/45] net/sxe2: fix command channel log messages
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (40 preceding siblings ...)
2026-08-28 3:27 ` [PATCH v5 40/45] net/sxe2: skip flow id assignment on filter add failure liujie5
@ 2026-08-28 3:27 ` liujie5
2026-08-28 3:27 ` [PATCH v5 42/45] net/sxe2: align command structs with historical kernel layout liujie5
` (3 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:27 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Several error/warning messages in sxe2_cmd_chnl.c are inaccurate or
lost context:
- vsi_info_get: message lost the vsi id; restore it
- rxq_bind_irq/rxq_unbind_irq: message lost the rxq index; restore it
- promisc_config: fix "promic" typo in the message
- queue_info_get_update/rxq_mapping_set: incorrect "get queue info
map"/"get dev caps" wording; use "rx queue mapping failed"
- txq_mapping_set: "Rx queue" should read "Tx queue"; incorrect
"get dev caps" wording should read "tx queue mapping failed"
Fixes: a2b79a93515e ("net/sxe2: support L2 filtering and MAC config")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 89829f29be..0d81da542e 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -481,7 +481,7 @@ int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi
&vsi_info_get_resp, sizeof(vsi_info_get_resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_DEV_LOG_ERR(adapter, DRV, "switchdev cpvsi info get failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "vsi %u info get failed, ret=%d", vsi->vsi_id, ret);
goto l_end;
}
@@ -537,7 +537,7 @@ int32_t sxe2_drv_rxq_bind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx, ui
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq bind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u bind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -557,7 +557,7 @@ int32_t sxe2_drv_rxq_unbind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx)
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq unbind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u unbind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -758,7 +758,7 @@ int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set)
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_WARN(adapter, DRV, "promic config failed, ret=%d", ret);
+ PMD_DEV_LOG_WARN(adapter, DRV, "promisc config failed, ret=%d", ret);
return ret;
}
@@ -1683,7 +1683,7 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_LOG_ERR(DRV, "get queue info map failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
goto l_end;
}
@@ -1727,7 +1727,7 @@ int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
l_end:
return ret;
@@ -1744,7 +1744,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
txq = eth_dev->data->tx_queues[queue_id];
if (txq == NULL) {
- PMD_LOG_ERR(DRV, "Rx queue %u is not available or setup", queue_id);
+ PMD_LOG_ERR(DRV, "Tx queue %u is not available or setup", queue_id);
ret = -EINVAL;
goto l_end;
}
@@ -1758,7 +1758,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "tx queue mapping failed, ret=%d", ret);
l_end:
return ret;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 42/45] net/sxe2: align command structs with historical kernel layout
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (41 preceding siblings ...)
2026-08-28 3:27 ` [PATCH v5 41/45] net/sxe2: fix command channel log messages liujie5
@ 2026-08-28 3:27 ` liujie5
2026-08-28 3:27 ` [PATCH v5 43/45] common/sxe2: fix ioctl channel log and close handling liujie5
` (2 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:27 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The sxe2_drv_cmd.h command structures must match the layout
used by historical SXE2 kernel versions so the same firmware
command ABI is shared. Several structures were declared with
__rte_packed_begin/__rte_packed_end and extra rsv padding that
the kernel layout does not have:
- sxe2_drv_link_info_resp: drop rsv[3] padding
- sxe2_tm_res: drop rsv[2] padding and packed attribute
- sxe2_tm_info: drop packed attribute
- sxe2_drv_sfp_req: drop packed attribute
- sxe2_drv_sfp_resp: drop packed attribute
sxe2_tm_add_mid_msg and sxe2_tm_add_queue_msg keep the packed
attribute so the firmware command wire offsets (tm info offset,
tm queue info offset) are preserved.
Keep the structure members as-is so the command ABI is
compatible with the historical kernel driver.
Fixes: 9c894f75113f ("net/sxe2: support TM hierarchy and shaping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_drv_cmd.h | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index cc71e2364e..5274b59a6a 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -230,7 +230,6 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_info_get_resp {
struct __rte_aligned(4) __rte_packed_begin sxe2_drv_link_info_resp {
uint32_t speed;
uint8_t status;
- uint8_t rsv[3];
} __rte_packed_end;
struct __rte_aligned(4) __rte_packed_begin sxe2_switchdev_info {
@@ -348,18 +347,17 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_rss_hf_req {
uint8_t rsv1[3];
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_res {
+struct sxe2_tm_res {
uint16_t teid;
- uint8_t rsv[2];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_info {
+struct sxe2_tm_info {
uint32_t committed;
uint32_t peak;
uint8_t priority;
uint8_t reserve;
uint16_t weight;
-} __rte_packed_end;
+};
struct __rte_aligned(4) __rte_packed_begin sxe2_tm_add_mid_msg {
uint16_t parent_teid;
@@ -633,7 +631,7 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_udp_tunnel_resp {
uint8_t rsv;
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
+struct sxe2_drv_sfp_req {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t bus_addr;
@@ -642,14 +640,14 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
uint16_t data_len;
uint16_t rvd;
uint8_t data[];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_resp {
+struct sxe2_drv_sfp_resp {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t data_len;
uint8_t data[];
-} __rte_packed_end;
+};
enum sxe2_fc_type {
SXE2_FC_T_DIS = 0,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 43/45] common/sxe2: fix ioctl channel log and close handling
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (42 preceding siblings ...)
2026-08-28 3:27 ` [PATCH v5 42/45] net/sxe2: align command structs with historical kernel layout liujie5
@ 2026-08-28 3:27 ` liujie5
2026-08-28 3:27 ` [PATCH v5 44/45] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:27 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Compare sxe2_ioctl_chnl.c against the reference implementation and
fix the following discrepancies:
- sxe2_drv_dev_close: only log the closed fd when it is valid, move
PMD_LOG_INFO inside the fd >= 0 check
- sxe2_drv_dev_mmap: fix swapped format arguments in the debug log
(cmd_fd and bar_idx were passed in the wrong order)
- sxe2_drv_dev_dma_unmap: use PMD_LOG_ERR instead of PMD_LOG_INFO
for the ioctl failure message
Fixes: 83866f8d7638 ("common/sxe2: add base driver skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_ioctl_chnl.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index 3e2fbf572f..b006e296c6 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -107,9 +107,11 @@ sxe2_drv_dev_close(struct sxe2_common_device *cdev)
{
int32_t fd = SXE2_CDEV_TO_CMD_FD(cdev);
- if (fd >= 0)
+ if (fd >= 0) {
close(fd);
- PMD_LOG_INFO(COM, "closed device fd=%d", fd);
+ PMD_LOG_INFO(COM, "closed device fd=%d", fd);
+ }
+
SXE2_CDEV_TO_CMD_FD(cdev) = SXE2_CMD_FD_INVALID;
}
@@ -349,8 +351,8 @@ void
goto l_err;
}
- PMD_LOG_DEBUG(COM, "fd=%d, bar idx=%d, len=%"PRIu64", src=0x%"PRIx64", offset=0x%"PRIx64"",
- bar_idx, cmd_fd, len, offset, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
+ PMD_LOG_DEBUG(COM, "fd=%d, bar idx=%d, len=%"PRIu64", offset=0x%"PRIx64", pci_offset=0x%"PRIx64"",
+ cmd_fd, bar_idx, len, offset, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
virt = mmap(NULL, len, PROT_READ | PROT_WRITE,
MAP_SHARED, cmd_fd, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
@@ -477,7 +479,7 @@ sxe2_drv_dev_dma_unmap(struct sxe2_common_device *cdev, uint64_t iova)
pthread_mutex_lock(&cdev->config.lock);
ret = ioctl(cmd_fd, SXE2_COM_CMD_DMA_UNMAP, &cmd_params);
if (ret < 0) {
- PMD_LOG_INFO(COM, "Failed to dma unmap, fd=%d, ret=%d, err:%s",
+ PMD_LOG_ERR(COM, "Failed to dma unmap, fd=%d, ret=%d, err:%s",
cmd_fd, ret, strerror(errno));
ret = -EIO;
pthread_mutex_unlock(&cdev->config.lock);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 44/45] doc/sxe2: remove drv-sw-stats parameter documentation
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (43 preceding siblings ...)
2026-08-28 3:27 ` [PATCH v5 43/45] common/sxe2: fix ioctl channel log and close handling liujie5
@ 2026-08-28 3:27 ` liujie5
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:27 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The drv-sw-stats devarg is no longer supported. Remove its
parameter description from the Runtime Configuration section.
The "Receive Software Statistics" xstats section is kept because
the rx_sw_* counters are still accumulated in the Rx data path
and reported through rte_eth_xstats_get().
Fixes: 9e95b2b3859c ("doc: update sxe2 guide and features")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
doc/guides/nics/sxe2.rst | 31 ++-----------------------------
1 file changed, 2 insertions(+), 29 deletions(-)
diff --git a/doc/guides/nics/sxe2.rst b/doc/guides/nics/sxe2.rst
index c5b400a8ba..fe4f9f916b 100644
--- a/doc/guides/nics/sxe2.rst
+++ b/doc/guides/nics/sxe2.rst
@@ -109,30 +109,6 @@ Runtime Configuration
Default value is 3 (count both packets and bytes).
-- ``drv-sw-stats`` parameter [int]
-
- This parameter controls whether per-packet software statistics (SW stats)
- are collected in the Rx data path.
-
- Hardware packet statistic counters may be inaccurate for certain packet types
- due to hardware design limitations.
- When accuracy of Rx packet classification statistics is critical,
- enabling this parameter allows the driver to accumulate statistics in software
- as packets are received, providing an alternative statistical path
- that bypasses hardware counter inaccuracies.
-
- - 0: Disable software statistics collection (default).
- The basic port statistics (``ipackets``, ``ibytes``) are reported
- from the hardware counters.
- - 1: Enable software statistics collection.
- Per-packet software statistics are accumulated for unicast,
- multicast, broadcast, and dropped packets in the Rx data path.
-
- When enabled, the following extended statistics (xstats) are available:
- ``rx_sw_unicast_packets``, ``rx_sw_multicast_packets``,
- ``rx_sw_broadcast_packets``, ``rx_sw_drop_packets``,
- and ``rx_sw_drop_bytes``.
-
- ``no-sched-mode`` parameter [int]
This parameter enables non-scheduling mode (no-sched mode).
@@ -208,8 +184,7 @@ reflect the actual packets processed by the driver.
Receive Software Statistics
These counters are collected in the Rx data path
- when ``drv-sw-stats=1`` is configured (see the ``drv-sw-stats`` devarg above).
- When ``drv-sw-stats`` is disabled (default), these xstats report zero.
+ on every received packet.
- ``rx_sw_unicast_packets``: Number of unicast packets received.
- ``rx_sw_multicast_packets``: Number of multicast packets received.
@@ -217,10 +192,8 @@ Receive Software Statistics
- ``rx_sw_drop_packets``: Number of packets dropped in the Rx data path.
- ``rx_sw_drop_bytes``: Number of bytes dropped in the Rx data path.
- When ``drv-sw-stats`` is enabled, the basic counters
- ``ipackets`` and ``ibytes`` (from ``rte_eth_stats``)
+ The basic counters ``ipackets`` and ``ibytes`` (from ``rte_eth_stats``)
also reflect the software-accumulated packet and byte counts.
- Otherwise, they are reported from hardware counters.
Fnav Flow Engine Statistics
The Fnav flow engine statistics type is controlled by
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
` (44 preceding siblings ...)
2026-08-28 3:27 ` [PATCH v5 44/45] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
@ 2026-08-28 3:27 ` liujie5
2026-08-28 7:36 ` [PATCH v6 00/45] net/sxe2: update SXE2 poll mode driver liujie5
` (45 more replies)
45 siblings, 46 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 3:27 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
rte_eth_dev_info_get() overwrites dev_info->nb_rx_queues and
dev_info->nb_tx_queues from dev->data after the PMD dev_infos_get
callback returns, so assigning them in sxe2_repr_dev_infos_get() has
no effect. Remove the ineffective assignments.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev_repr.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index b7096f5927..5490fea10b 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -195,8 +195,6 @@ static int32_t sxe2_repr_dev_infos_get(struct rte_eth_dev *dev,
dev_info->speed_capa = RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G |
RTE_ETH_LINK_SPEED_50G | RTE_ETH_LINK_SPEED_100G;
- dev_info->nb_rx_queues = dev->data->nb_rx_queues;
- dev_info->nb_tx_queues = dev->data->nb_tx_queues;
dev_info->default_rxportconf.burst_size = SXE2_RX_MAX_BURST;
dev_info->default_txportconf.burst_size = SXE2_TX_MAX_BURST;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 00/45] net/sxe2: update SXE2 poll mode driver
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
@ 2026-08-28 7:36 ` liujie5
2026-08-28 16:49 ` Stephen Hemminger
2026-08-28 7:36 ` [PATCH v6 01/45] common/sxe2: fix null pointer in class driver remove liujie5
` (44 subsequent siblings)
45 siblings, 1 reply; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:36 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
This series updates the SXE2 poll mode driver (drivers/net/sxe2) and
its common library (drivers/common/sxe2), fixing issues found in the
previous versions and re-aligning the driver with the reference
implementation.
- common/sxe2: fix null pointer and munmap handling, fix ioctl channel
log and close handling
- net/sxe2: fix VF PCI device ID and MSIX register width, restore PF
and port index caps assignment
- net/sxe2: fix VSI lifecycle and representor handling
- net/sxe2: restore Rx queue buffer split fill support, fix RSS action
attribute validation
- net/sxe2: fix command channel log messages, align command structs
with the historical kernel layout
- net/sxe2: add ACL engine event statistics support
- net/sxe2: unify and refine the vectorized Tx/Rx path
- doc/sxe2: remove stale drv-sw-stats parameter documentation
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
Jie Liu (45):
common/sxe2: fix null pointer in class driver remove
common/sxe2: allow munmap during kernel reset
net/sxe2: fix VF PCI device ID
net/sxe2: fix MSIX register width in PF map table
net/sxe2: restore pf and port index caps assignment
net/sxe2: fix VSI lifecycle management
net/sxe2: initialize stats in representor device init
net/sxe2: use base device name for representor naming
net/sxe2: propagate LSC event to VF representors
net/sxe2: clear security context pointer on uninit
net/sxe2: rename representor VSI ID fields
net/sxe2: clean up duplicate function declarations
net/sxe2: fix null VSI dereference in device info
net/sxe2: fill MAC and queue counts in device info
net/sxe2: fix QinQ and RSS offload capability report
net/sxe2: use regular write for mapped registers
net/sxe2: move PCI register read macro to common header
net/sxe2: validate PCI map resource type
net/sxe2: guard PCI BAR unmap when not initialized
net/sxe2: fix null dereference in dev uninit
net/sxe2: fix duplicated cleanup in dev close
net/sxe2: align dev init and cleanup order
net/sxe2: simplify switchdev representor matching
net/sxe2: rename fnav cid manager symbols to flow
net/sxe2: move tunnel port helpers into flow module
net/sxe2: add ACL engine event statistics support
net/sxe2: guard Rx queue event FD free in unregister
net/sxe2: refactor primary process MP message handling
net/sxe2: refactor Tx queue reset operations
net/sxe2: unify vectorized Tx buffer handling
net/sxe2: refine vectorized Tx/Rx mode setup
net/sxe2: fix RSS action attribute validation
net/sxe2: restore PF-only guard in udp tunnel port add
net/sxe2: restore link update call in status query
net/sxe2: validate representor ID against VF count
net/sxe2: use primary VSI ID for representor VSI
net/sxe2: wrap command params fill debug log in macro
net/sxe2: restore Rx queue buffer split fill support
net/sxe2: skip tunnel config fill on get failure
net/sxe2: skip flow id assignment on filter add failure
net/sxe2: fix command channel log messages
net/sxe2: align command structs with historical kernel layout
common/sxe2: fix ioctl channel log and close handling
doc/sxe2: remove drv-sw-stats parameter documentation
net/sxe2: remove ineffective queue counts in representor info
doc/guides/nics/sxe2.rst | 40 ++--
drivers/common/sxe2/sxe2_common.c | 6 +-
drivers/common/sxe2/sxe2_ioctl_chnl.c | 20 +-
drivers/net/sxe2/sxe2_cmd_chnl.c | 199 ++++++++++++++++--
drivers/net/sxe2/sxe2_cmd_chnl.h | 15 +-
drivers/net/sxe2/sxe2_drv_cmd.h | 37 +++-
drivers/net/sxe2/sxe2_dump.c | 10 +-
drivers/net/sxe2/sxe2_ethdev.c | 192 ++++++++++-------
drivers/net/sxe2/sxe2_ethdev.h | 13 +-
drivers/net/sxe2/sxe2_ethdev_repr.c | 17 +-
drivers/net/sxe2/sxe2_flow.c | 234 ++++++++++++++++++---
drivers/net/sxe2/sxe2_flow.h | 6 +-
drivers/net/sxe2/sxe2_flow_define.h | 15 +-
drivers/net/sxe2/sxe2_flow_parse_action.c | 39 +++-
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ----------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 6 -
drivers/net/sxe2/sxe2_irq.c | 29 ++-
drivers/net/sxe2/sxe2_mac.c | 11 +-
drivers/net/sxe2/sxe2_mp.c | 59 +++---
drivers/net/sxe2/sxe2_queue.c | 2 +
drivers/net/sxe2/sxe2_queue.h | 7 +-
drivers/net/sxe2/sxe2_rx.c | 3 +-
drivers/net/sxe2/sxe2_security.c | 1 +
drivers/net/sxe2/sxe2_switchdev.c | 16 +-
drivers/net/sxe2/sxe2_tx.c | 42 +++-
drivers/net/sxe2/sxe2_tx.h | 4 +
drivers/net/sxe2/sxe2_txrx.c | 20 +-
drivers/net/sxe2/sxe2_txrx_poll.h | 2 -
drivers/net/sxe2/sxe2_txrx_vec.c | 73 +++----
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 133 +-----------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 9 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 219 ++++++++++++-------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
drivers/net/sxe2/sxe2_vsi.c | 10 +-
36 files changed, 949 insertions(+), 674 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 207+ messages in thread
* [PATCH v6 01/45] common/sxe2: fix null pointer in class driver remove
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
2026-08-28 7:36 ` [PATCH v6 00/45] net/sxe2: update SXE2 poll mode driver liujie5
@ 2026-08-28 7:36 ` liujie5
2026-08-28 7:36 ` [PATCH v6 02/45] common/sxe2: allow munmap during kernel reset liujie5
` (43 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:36 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_classes_driver_remove() calls cdrv->remove(cdev) without
checking whether cdrv or cdrv->remove is NULL. If the class driver
was never probed, cdev->cdrv remains NULL, and the unconditional
call dereferences a NULL pointer, crashing during device removal.
Add NULL checks for cdrv and cdrv->remove, returning 0 when either
is NULL.
Fixes: 83866f8d7638 ("common/sxe2: add base driver skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_common.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/common/sxe2/sxe2_common.c b/drivers/common/sxe2/sxe2_common.c
index 5c5db85f29..6e387a8a73 100644
--- a/drivers/common/sxe2/sxe2_common.c
+++ b/drivers/common/sxe2/sxe2_common.c
@@ -465,8 +465,12 @@ static int32_t sxe2_classes_driver_probe(struct sxe2_common_device *cdev,
static int32_t sxe2_classes_driver_remove(struct sxe2_common_device *cdev)
{
struct sxe2_class_driver *cdrv = cdev->cdrv;
+ int32_t ret = 0;
+
+ if (cdrv != NULL && cdrv->remove != NULL)
+ ret = cdrv->remove(cdev);
- return cdrv->remove(cdev);
+ return ret;
}
static int32_t sxe2_kvargs_validate(struct sxe2_dev_kvargs_info *kv_info)
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 02/45] common/sxe2: allow munmap during kernel reset
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
2026-08-28 7:36 ` [PATCH v6 00/45] net/sxe2: update SXE2 poll mode driver liujie5
2026-08-28 7:36 ` [PATCH v6 01/45] common/sxe2: fix null pointer in class driver remove liujie5
@ 2026-08-28 7:36 ` liujie5
2026-08-28 7:36 ` [PATCH v6 03/45] net/sxe2: fix VF PCI device ID liujie5
` (42 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:36 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_dev_munmap() refuses to unmap the BAR region when
cdev->config.kernel_reset is set, returning -EPERM. After a kernel
reset the application still needs to release the previously mapped
regions during cleanup; blocking munmap leaves stale mappings and
prevents a clean teardown.
Remove the kernel_reset check from sxe2_drv_dev_munmap() so the
mapping is always released. The cdev parameter is no longer used,
so mark it __rte_unused.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_ioctl_chnl.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index a233a78136..3e2fbf572f 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -367,16 +367,10 @@ void
RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_munmap)
int32_t
-sxe2_drv_dev_munmap(struct sxe2_common_device *cdev, void *virt, uint64_t len)
+sxe2_drv_dev_munmap(struct sxe2_common_device *cdev __rte_unused, void *virt, uint64_t len)
{
int32_t ret = 0;
- if (cdev->config.kernel_reset) {
- ret = -EPERM;
- PMD_LOG_WARN(COM, "kernel reset, need restart app.");
- goto l_end;
- }
-
PMD_LOG_DEBUG(COM, "Munmap virt=%p, len=0x%"PRIx64"",
virt, len);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 03/45] net/sxe2: fix VF PCI device ID
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (2 preceding siblings ...)
2026-08-28 7:36 ` [PATCH v6 02/45] common/sxe2: allow munmap during kernel reset liujie5
@ 2026-08-28 7:36 ` liujie5
2026-08-28 7:37 ` [PATCH v6 04/45] net/sxe2: fix MSIX register width in PF map table liujie5
` (41 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:36 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The VF PCI device ID is defined as 0x10b2 per the hardware specification,
but the code incorrectly uses 0x10b.
As a result, the VF driver never binds to the device, making VF
functionality completely unusable.
Fix this by changing SXE2_PCI_DEVICE_ID_VF_1 from 0x10b to 0x10b2.
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 8bbfdc3a15..ec376b76dc 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -44,7 +44,7 @@
#define SXE2_PCI_VENDOR_ID_1 0x1ff2
#define SXE2_PCI_DEVICE_ID_PF_1 0x10b1
-#define SXE2_PCI_DEVICE_ID_VF_1 0x10b
+#define SXE2_PCI_DEVICE_ID_VF_1 0x10b2
#define SXE2_PCI_VENDOR_ID_2 0x1d94
#define SXE2_PCI_DEVICE_ID_PF_2 0x1260
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 04/45] net/sxe2: fix MSIX register width in PF map table
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (3 preceding siblings ...)
2026-08-28 7:36 ` [PATCH v6 03/45] net/sxe2: fix VF PCI device ID liujie5
@ 2026-08-28 7:37 ` liujie5
2026-08-28 7:37 ` [PATCH v6 05/45] net/sxe2: restore pf and port index caps assignment liujie5
` (40 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The MSIX entry in sxe2_net_map_addr_info_pf sets a register width
of 10 (decimal), but each PCIe MSIX table entry is 16 bytes (0x10).
The VF map table already uses 0x10.
Since reg_width is used as the stride between MSIX entries in
sxe2_dev_pci_seg_map(), the wrong value makes the mapped region too
short and places the entries at incorrect offsets.
Change .reg_width from 10 to 0x10 for the SXE2_PCI_MAP_RES_IRQ_MSIX
entry to match the VF table.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index ec376b76dc..5d8cfca6cf 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -94,7 +94,7 @@ static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_pf[SXE2_PCI_MAP_RES_
.reg_width = 4},
[SXE2_PCI_MAP_RES_IRQ_MSIX] = {.addr_base = SXE2_BAR4_MSIX_CTL(0),
.bar_idx = 4,
- .reg_width = 10},
+ .reg_width = 0x10},
};
static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_vf[SXE2_PCI_MAP_RES_MAX_COUNT] = {
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 05/45] net/sxe2: restore pf and port index caps assignment
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (4 preceding siblings ...)
2026-08-28 7:37 ` [PATCH v6 04/45] net/sxe2: fix MSIX register width in PF map table liujie5
@ 2026-08-28 7:37 ` liujie5
2026-08-28 7:37 ` [PATCH v6 06/45] net/sxe2: fix VSI lifecycle management liujie5
` (39 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_func_caps_get() never assigns adapter->pf_idx from the device
capabilities, leaving it at its zero-initialized value. Switchdev
requests and representor setup that use pf_idx then report the wrong
PF index on multi-PF configurations.
Restore the pf_idx and port_idx assignments in sxe2_func_caps_get()
and drop the now-redundant port_idx assignment from
sxe2_drv_dev_caps_set().
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 5d8cfca6cf..2e14c372f8 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1284,8 +1284,6 @@ void sxe2_eth_uinit(struct rte_eth_dev *dev __rte_unused)
static void sxe2_drv_dev_caps_set(struct sxe2_adapter *adapter,
struct sxe2_drv_dev_caps_resp *dev_caps)
{
- adapter->port_idx = dev_caps->port_idx;
-
adapter->cap_flags = 0;
if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_L2)
@@ -1344,6 +1342,8 @@ static int32_t sxe2_func_caps_get(struct sxe2_adapter *adapter)
goto l_end;
adapter->dev_type = dev_caps.dev_type;
+ adapter->port_idx = dev_caps.port_idx;
+ adapter->pf_idx = dev_caps.pf_idx;
sxe2_drv_dev_caps_set(adapter, &dev_caps);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 06/45] net/sxe2: fix VSI lifecycle management
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (5 preceding siblings ...)
2026-08-28 7:37 ` [PATCH v6 05/45] net/sxe2: restore pf and port index caps assignment liujie5
@ 2026-08-28 7:37 ` liujie5
2026-08-28 7:37 ` [PATCH v6 07/45] net/sxe2: initialize stats in representor device init liujie5
` (38 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Fix several VSI create/destroy issues introduced by VF representor
support:
- Initialize other_vsi_list with TAILQ_INIT in sxe2_vsi_init before
any VSI is inserted into it.
- Treat -EPERM as a non-fatal error when destroying VSIs, since the
kernel may have already removed the VSI.
- Set main_vsi to NULL after destroy/free to avoid a dangling pointer
if the VSI is destroyed again.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_vsi.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_vsi.c b/drivers/net/sxe2/sxe2_vsi.c
index d29480b931..dea3f58997 100644
--- a/drivers/net/sxe2/sxe2_vsi.c
+++ b/drivers/net/sxe2/sxe2_vsi.c
@@ -131,6 +131,8 @@ static int32_t sxe2_vsi_destroy(struct sxe2_adapter *adapter, struct sxe2_vsi *v
}
l_free:
+ if (vsi->vsi_type == SXE2_VSI_T_DPDK_ESW)
+ TAILQ_REMOVE(&adapter->vsi_ctxt.other_vsi_list, vsi, next);
rte_free(vsi);
vsi = NULL;
@@ -230,7 +232,7 @@ int32_t sxe2_vsi_init(struct rte_eth_dev *dev)
uint16_t srcvsi_cnt;
PMD_INIT_FUNC_TRACE();
-
+ TAILQ_INIT(&adapter->vsi_ctxt.other_vsi_list);
ret = sxe2_main_vsi_create(adapter);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to create main VSI, ret=%d", ret);
@@ -283,13 +285,14 @@ void sxe2_vsi_uninit(struct rte_eth_dev *dev)
l_free:
ret = sxe2_vsi_destroy(adapter, adapter->vsi_ctxt.main_vsi);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
goto l_end;
}
+ adapter->vsi_ctxt.main_vsi = NULL;
RTE_TAILQ_FOREACH_SAFE(var, &adapter->vsi_ctxt.other_vsi_list, next, tvar) {
ret = sxe2_vsi_destroy(adapter, var);
- if (ret) {
+ if (ret && ret != -EPERM) {
PMD_LOG_ERR(DRV, "Failed to del vsi from fw, ret=%d", ret);
break;
}
@@ -357,4 +360,5 @@ void sxe2_vsi_repr_main_vsi_destroy(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
sxe2_vsi_node_free(adapter->vsi_ctxt.main_vsi);
+ adapter->vsi_ctxt.main_vsi = NULL;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 07/45] net/sxe2: initialize stats in representor device init
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (6 preceding siblings ...)
2026-08-28 7:37 ` [PATCH v6 06/45] net/sxe2: fix VSI lifecycle management liujie5
@ 2026-08-28 7:37 ` liujie5
2026-08-28 7:37 ` [PATCH v6 08/45] net/sxe2: use base device name for representor naming liujie5
` (37 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add sxe2_stats_init() call in sxe2_repr_dev_init to set up the
statistics infrastructure for representor devices, and add the
l_init_irq_ctxt_err error path to uninitialize the software irq
context if stats initialization fails.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev_repr.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index f32318b731..c698baafe0 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -483,8 +483,16 @@ int32_t sxe2_repr_dev_init(struct rte_eth_dev *dev,
goto l_init_sw_err;
}
+ ret = sxe2_stats_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize stats, ret=[%d]", ret);
+ goto l_init_irq_ctxt_err;
+ }
+
goto l_end;
+l_init_irq_ctxt_err:
+ sxe2_sw_irq_ctxt_uninit(dev);
l_init_sw_err:
sxe2_eth_uinit(dev);
l_init_eth_err:
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 08/45] net/sxe2: use base device name for representor naming
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (7 preceding siblings ...)
2026-08-28 7:37 ` [PATCH v6 07/45] net/sxe2: initialize stats in representor device init liujie5
@ 2026-08-28 7:37 ` liujie5
2026-08-28 7:37 ` [PATCH v6 09/45] net/sxe2: propagate LSC event to VF representors liujie5
` (36 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Update the representor device naming to use the base device name
prefix, and set the numa_node from the parent device data so that
representor devices are allocated on the same NUMA node.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev_repr.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index c698baafe0..b7096f5927 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -552,8 +552,8 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
}
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- snprintf(name, sizeof(name), "sxe2_representor_c%dpf%d%s%u",
- adapter->pf_idx, adapter->pf_idx,
+ snprintf(name, sizeof(name), "%s_representor_%s%u",
+ adapter->cdev->dev->name,
"vf",
req_eth_da->representor_ports[repr_idx]);
@@ -562,6 +562,7 @@ int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
ret = -ENOMEM;
goto l_release_port;
}
+ eth_dev->data->numa_node = adapter->dev_info.dev_data->numa_node;
eth_dev->data->dev_private = rte_zmalloc_socket(name,
sizeof(struct sxe2_adapter),
RTE_CACHE_LINE_SIZE,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 09/45] net/sxe2: propagate LSC event to VF representors
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (8 preceding siblings ...)
2026-08-28 7:37 ` [PATCH v6 08/45] net/sxe2: use base device name for representor naming liujie5
@ 2026-08-28 7:37 ` liujie5
2026-08-28 7:37 ` [PATCH v6 10/45] net/sxe2: clear security context pointer on uninit liujie5
` (35 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
When the PF link state changes in switchdev mode, refresh the link
status of every VF representor and trigger the RTE_ETH_EVENT_INTR_LSC
callback on each, so applications receive link events on representor
ports. Also log OICR in hexadecimal for better readability.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index 3306504761..ba764dd5e4 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -77,14 +77,32 @@ static int32_t sxe2_fc_state_callback(struct rte_eth_dev *dev)
static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t oicr)
{
struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
+ struct rte_eth_dev *repr_eth_dev;
+ struct sxe2_adapter *repr_adapter;
+ uint16_t vf_id;
if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
- PMD_DEV_LOG_INFO(adapter, DRV, "OICR=%" PRIu64, oicr);
+ PMD_DEV_LOG_INFO(adapter, DRV, "OICR=0x%" PRIx64, oicr);
(void)sxe2_drv_mac_link_status_get(adapter);
- if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_LSC,
NULL);
+ }
+ if (adapter->switchdev_info.is_switchdev) {
+ for (vf_id = 0; vf_id < adapter->repr_ctxt.nb_repr_vf; vf_id++) {
+ repr_eth_dev = adapter->repr_ctxt.vf_rep_eth_dev[vf_id];
+ if (!repr_eth_dev)
+ continue;
+ repr_adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(repr_eth_dev);
+ (void)sxe2_drv_mac_link_status_get(repr_adapter);
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ rte_eth_dev_callback_process(repr_eth_dev,
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL);
+ }
+ }
+ }
}
if (oicr & RTE_BIT32(SXE2_COM_SW_MODE_SWITCHDEV)) {
PMD_DEV_LOG_INFO(adapter, DRV, "event notify switchdev");
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 10/45] net/sxe2: clear security context pointer on uninit
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (9 preceding siblings ...)
2026-08-28 7:37 ` [PATCH v6 09/45] net/sxe2: propagate LSC event to VF representors liujie5
@ 2026-08-28 7:37 ` liujie5
2026-08-28 7:37 ` [PATCH v6 11/45] net/sxe2: rename representor VSI ID fields liujie5
` (34 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_security_uinit() frees the security session but leaves
dev->security_ctx pointing at the freed memory. Set
dev->security_ctx to NULL after releasing the security context
so a later access does not dereference a dangling pointer.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_security.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/sxe2/sxe2_security.c b/drivers/net/sxe2/sxe2_security.c
index bc59d1b880..8f31067942 100644
--- a/drivers/net/sxe2/sxe2_security.c
+++ b/drivers/net/sxe2/sxe2_security.c
@@ -326,6 +326,7 @@ void sxe2_security_uinit(struct rte_eth_dev *dev)
if (sctx != NULL) {
rte_free(sctx);
sctx = NULL;
+ dev->security_ctx = NULL;
}
sxe2_ipsec_uinit(adapter);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 11/45] net/sxe2: rename representor VSI ID fields
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (10 preceding siblings ...)
2026-08-28 7:37 ` [PATCH v6 10/45] net/sxe2: clear security context pointer on uninit liujie5
@ 2026-08-28 7:37 ` liujie5
2026-08-28 7:37 ` [PATCH v6 12/45] net/sxe2: clean up duplicate function declarations liujie5
` (33 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Rename repr_vf_k_vsi_id/repr_vf_u_vsi_id to
repr_vf_primary_vsi_id/repr_vf_backup_vsi_id in
sxe2_repr_private_data and update all references.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_dump.c | 8 ++++----
drivers/net/sxe2/sxe2_ethdev.h | 4 ++--
drivers/net/sxe2/sxe2_flow.c | 4 ++--
drivers/net/sxe2/sxe2_switchdev.c | 4 ++--
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index d43473e083..590219f502 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -211,16 +211,16 @@ sxe2_dump_switchdev_info(FILE *file, struct rte_eth_dev *dev)
"\t -- repr_pf_id: %u\n"
"\t -- repr_vf_id: %u\n"
"\t -- repr_vf_vsi_id: %u\n"
- "\t -- repr_vf_k_vsi_id: %s\n"
- "\t -- repr_vf_u_vsi_id: %s\n",
+ "\t -- repr_vf_primary_vsi_id: %s\n"
+ "\t -- repr_vf_backup_vsi_id: %s\n",
adapter->repr_priv_data->repr_id,
adapter->repr_priv_data->repr_q_id,
adapter->repr_priv_data->repr_pf_id,
adapter->repr_priv_data->repr_vf_id,
adapter->repr_priv_data->repr_vf_vsi_id,
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_k_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_primary_vsi_id,
k_vsi_buf, sizeof(k_vsi_buf)),
- sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_u_vsi_id,
+ sxe2_vsi_id_str(adapter->repr_priv_data->repr_vf_backup_vsi_id,
u_vsi_buf, sizeof(u_vsi_buf)));
goto l_end;
}
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index c54e8a435e..158198d74b 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -263,8 +263,8 @@ struct sxe2_repr_private_data {
uint16_t repr_pf_id;
uint16_t repr_vf_id;
uint16_t repr_vf_vsi_id;
- uint16_t repr_vf_k_vsi_id;
- uint16_t repr_vf_u_vsi_id;
+ uint16_t repr_vf_primary_vsi_id;
+ uint16_t repr_vf_backup_vsi_id;
};
struct sxe2_sched_hw_cap {
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index 63cfc36968..cf54803301 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -380,9 +380,9 @@ static int32_t sxe2_flow_src_split_proc(struct rte_eth_dev *dev,
if (adapter->switchdev_info.is_switchdev && adapter->is_dev_repr) {
flow_bond_num = 1;
flow_src_vsi[SXE2_MAX_DRV_TYPE_DPDK][0] =
- adapter->repr_priv_data->repr_vf_u_vsi_id;
+ adapter->repr_priv_data->repr_vf_backup_vsi_id;
flow_src_vsi[SXE2_MAX_DRV_TYPE_KERNEL][0] =
- adapter->repr_priv_data->repr_vf_k_vsi_id;
+ adapter->repr_priv_data->repr_vf_primary_vsi_id;
}
for (idx = 0; idx < flow_bond_num; idx++) {
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index 44703cfb5c..efb1468b91 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -312,9 +312,9 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_q_id = repr_id;
repr_priv_data->repr_pf_id = parent_adapter->pf_idx;
repr_priv_data->repr_vf_id = repr_id;
- repr_priv_data->repr_vf_k_vsi_id =
+ repr_priv_data->repr_vf_primary_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
- repr_priv_data->repr_vf_u_vsi_id =
+ repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
repr_priv_data->repr_vf_vsi_id =
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 12/45] net/sxe2: clean up duplicate function declarations
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (11 preceding siblings ...)
2026-08-28 7:37 ` [PATCH v6 11/45] net/sxe2: rename representor VSI ID fields liujie5
@ 2026-08-28 7:37 ` liujie5
2026-08-28 7:37 ` [PATCH v6 13/45] net/sxe2: fix null VSI dereference in device info liujie5
` (32 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Remove duplicate function declarations from the sxe2 driver headers:
- sxe2_drv_promisc_config, sxe2_drv_vsi_info_get and
sxe2_drv_rxq_mapping_set in sxe2_cmd_chnl.h
- sxe2_dev_pci_seg_unmap in sxe2_ethdev.h
- sxe2_rx_pkts_scattered in sxe2_txrx_poll.h
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.h | 6 ------
drivers/net/sxe2/sxe2_ethdev.h | 2 --
drivers/net/sxe2/sxe2_txrx_poll.h | 2 --
3 files changed, 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index d63caad526..294ac15db4 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -65,8 +65,6 @@ int32_t sxe2_drv_ipsec_rxsa_delete(struct sxe2_adapter *adapter,
int32_t sxe2_drv_ipsec_txsa_delete(struct sxe2_adapter *adapter,
uint16_t sa_id);
-int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set);
-
int32_t sxe2_drv_udp_tunnel_add(struct sxe2_adapter *adapter,
enum sxe2_udp_tunnel_protocol tunnel_proto,
uint16_t udp_port);
@@ -84,8 +82,6 @@ int32_t sxe2_drv_get_udp_tunnel_port(struct sxe2_adapter *adapter,
int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi);
-
int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter);
int32_t sxe2_drv_get_mac_stats(struct sxe2_adapter *adapter);
@@ -110,8 +106,6 @@ int32_t sxe2_drv_mapping_reset(struct rte_eth_dev *eth_dev);
int32_t sxe2_drv_mapping_stats_info_clear(struct rte_eth_dev *eth_dev);
-int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t pool_idx);
-
int32_t sxe2_drv_allmulti_config(struct sxe2_adapter *adapter, bool set);
int32_t sxe2_drv_uc_config(struct sxe2_adapter *adapter, struct rte_ether_addr *addr, bool add);
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 158198d74b..1409be74d3 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -385,8 +385,6 @@ void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
int32_t sxe2_dev_pci_map_init(struct rte_eth_dev *dev);
-void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
-
int32_t sxe2_udp_tunnel_port_del_common(struct sxe2_adapter *ad,
enum sxe2_udp_tunnel_protocol tunnel_proto, uint16_t udp_port);
diff --git a/drivers/net/sxe2/sxe2_txrx_poll.h b/drivers/net/sxe2/sxe2_txrx_poll.h
index 708e3839d7..bfa099c097 100644
--- a/drivers/net/sxe2/sxe2_txrx_poll.h
+++ b/drivers/net/sxe2/sxe2_txrx_poll.h
@@ -13,8 +13,6 @@ uint16_t sxe2_tx_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t
uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
-
uint16_t sxe2_rx_pkts_scattered_split(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
#endif /* SXE2_TXRX_POLL_H */
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 13/45] net/sxe2: fix null VSI dereference in device info
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (12 preceding siblings ...)
2026-08-28 7:37 ` [PATCH v6 12/45] net/sxe2: clean up duplicate function declarations liujie5
@ 2026-08-28 7:37 ` liujie5
2026-08-28 7:37 ` [PATCH v6 14/45] net/sxe2: fill MAC and queue counts " liujie5
` (31 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_infos_get() dereferences adapter->vsi_ctxt.main_vsi without
checking for NULL, which can crash when the main VSI has not been
created yet.
Add an early NULL check on vsi and return -EINVAL.
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 2e14c372f8..02f9ce3d32 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -781,6 +781,10 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
+ if (unlikely(vsi == NULL)) {
+ PMD_LOG_ERR(INIT, "main vsi is NULL");
+ return -EINVAL;
+ }
dev_info->max_rx_queues = vsi->rxqs.q_cnt;
dev_info->max_tx_queues = vsi->txqs.q_cnt;
dev_info->min_rx_bufsize = SXE2_MIN_BUF_SIZE;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 14/45] net/sxe2: fill MAC and queue counts in device info
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (13 preceding siblings ...)
2026-08-28 7:37 ` [PATCH v6 13/45] net/sxe2: fix null VSI dereference in device info liujie5
@ 2026-08-28 7:37 ` liujie5
2026-08-28 7:38 ` [PATCH v6 15/45] net/sxe2: fix QinQ and RSS offload capability report liujie5
` (30 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:37 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Fill max_mac_addrs, nb_rx_queues and nb_tx_queues in
sxe2_dev_infos_get() so applications can query the maximum number of
MAC addresses and the queue counts.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 02f9ce3d32..e85e34aa1a 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -792,6 +792,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
dev_info->max_lro_pkt_size = SXE2_FRAME_SIZE_MAX * SXE2_RX_LRO_DESC_MAX_NUM;
dev_info->max_mtu = dev_info->max_rx_pktlen - SXE2_ETH_OVERHEAD;
dev_info->min_mtu = RTE_ETHER_MIN_MTU;
+ dev_info->max_mac_addrs = SXE2_NUM_MACADDR_MAX;
dev_info->rx_offload_capa =
RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 15/45] net/sxe2: fix QinQ and RSS offload capability report
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (14 preceding siblings ...)
2026-08-28 7:37 ` [PATCH v6 14/45] net/sxe2: fill MAC and queue counts " liujie5
@ 2026-08-28 7:38 ` liujie5
2026-08-28 7:38 ` [PATCH v6 16/45] net/sxe2: use regular write for mapped registers liujie5
` (29 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Make the QINQ offload capabilities conditional on the port VLAN
setting: only advertise RTE_ETH_TX_OFFLOAD_QINQ_INSERT,
RTE_ETH_RX_OFFLOAD_QINQ_STRIP and RTE_ETH_RX_OFFLOAD_VLAN_FILTER
when no port VLAN is configured. Advertise RTE_ETH_RX_OFFLOAD_RSS_HASH
unconditionally and report the buffer split supported header ptypes
count in sxe2_buffer_split_supported_hdr_ptypes_get().
Fixes: a2b79a93515e ("net/sxe2: support L2 filtering and MAC config")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index e85e34aa1a..7a11a93dff 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -804,15 +804,11 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_RX_OFFLOAD_SCTP_CKSUM |
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT |
-#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
- RTE_ETH_RX_OFFLOAD_QINQ_STRIP |
-#endif
RTE_ETH_RX_OFFLOAD_VLAN_EXTEND |
RTE_ETH_RX_OFFLOAD_TCP_LRO;
dev_info->tx_offload_capa =
RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
- RTE_ETH_TX_OFFLOAD_QINQ_INSERT |
RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE |
RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
@@ -855,14 +851,22 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
- if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
- dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
-
if (sxe2_ipsec_supported(adapter)) {
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
}
+ if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
+
+ if (!sxe2_dev_port_vlan_check(dev)) {
+ dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_QINQ_INSERT;
+#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
+#endif
+ dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
+ }
+
if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_RSS) {
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
dev_info->flow_type_rss_offloads |= SXE2_RSS_HF_SUPPORT_ALL;
@@ -934,7 +938,7 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
static const uint32_t *
sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
- size_t *no_of_elements __rte_unused)
+ size_t *no_of_elements)
{
static const uint32_t ptypes[] = {
RTE_PTYPE_L2_ETHER,
@@ -972,6 +976,7 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
RTE_PTYPE_UNKNOWN
};
+ *no_of_elements = RTE_DIM(ptypes) - 1;
return ptypes;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 16/45] net/sxe2: use regular write for mapped registers
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (15 preceding siblings ...)
2026-08-28 7:38 ` [PATCH v6 15/45] net/sxe2: fix QinQ and RSS offload capability report liujie5
@ 2026-08-28 7:38 ` liujie5
2026-08-28 7:38 ` [PATCH v6 17/45] net/sxe2: move PCI register read macro to common header liujie5
` (28 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_pci_map_write_reg() uses the write-combined store
(SXE2_PCI_REG_WRITE_WC) to write control registers, which is intended
for doorbell/tail writes and can be lossy or delayed for ordering
sensitive register updates.
Add SXE2_PCI_REG_WRITE macro using a regular rte_write32() and use it
in sxe2_pci_map_write_reg().
Fixes: 8cebf80f1eda ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 2 +-
drivers/net/sxe2/sxe2_ethdev.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 7a11a93dff..589f09c113 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1439,7 +1439,7 @@ void sxe2_pci_map_write_reg(struct sxe2_adapter *adapter,
goto l_ret;
}
- SXE2_PCI_REG_WRITE_WC(reg_addr, value);
+ SXE2_PCI_REG_WRITE(reg_addr, value);
l_ret:
return;
}
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 1409be74d3..cf1104144c 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -355,6 +355,8 @@ struct sxe2_adapter {
#define SXE2_DEV_PRIVATE_TO_ADAPTER(dev) \
((struct sxe2_adapter *)(dev)->data->dev_private)
+#define SXE2_PCI_REG_WRITE(reg, value) rte_write32((rte_cpu_to_le_32(value)), (reg))
+
void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
enum sxe2_pci_map_resource res_type,
uint16_t idx_in_func);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 17/45] net/sxe2: move PCI register read macro to common header
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (16 preceding siblings ...)
2026-08-28 7:38 ` [PATCH v6 16/45] net/sxe2: use regular write for mapped registers liujie5
@ 2026-08-28 7:38 ` liujie5
2026-08-28 7:38 ` [PATCH v6 18/45] net/sxe2: validate PCI map resource type liujie5
` (27 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move SXE2_PCI_REG_READ to sxe2_ethdev.h so the PCI register access
macros are kept together in the common header, matching
SXE2_PCI_REG_WRITE.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_queue.h | 2 --
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index cf1104144c..f2557b28c3 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -356,6 +356,7 @@ struct sxe2_adapter {
((struct sxe2_adapter *)(dev)->data->dev_private)
#define SXE2_PCI_REG_WRITE(reg, value) rte_write32((rte_cpu_to_le_32(value)), (reg))
+#define SXE2_PCI_REG_READ(reg) rte_read32(reg)
void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
enum sxe2_pci_map_resource res_type,
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index a300b66771..10bdaf5b8d 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -12,8 +12,6 @@
#include "sxe2_drv_cmd.h"
#include "sxe2_txrx_common.h"
-#define SXE2_PCI_REG_READ(reg) \
- rte_read32(reg)
#define SXE2_PCI_REG_WRITE_WC(reg, value) \
rte_write32_wc((rte_cpu_to_le_32(value)), reg)
#define SXE2_PCI_REG_WRITE_WC_RELAXED(reg, value) \
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 18/45] net/sxe2: validate PCI map resource type
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (17 preceding siblings ...)
2026-08-28 7:38 ` [PATCH v6 17/45] net/sxe2: move PCI register read macro to common header liujie5
@ 2026-08-28 7:38 ` liujie5
2026-08-28 7:38 ` [PATCH v6 19/45] net/sxe2: guard PCI BAR unmap when not initialized liujie5
` (26 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_pci_res_seg_map() indexes adapter->map_ctxt.addr_info[] with
res_type without bounds checking, which can access out of bounds when
an invalid resource type is passed.
Add a bounds check on res_type and return -EINVAL.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 589f09c113..9ef93b8076 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1552,6 +1552,12 @@ int32_t sxe2_dev_pci_res_seg_map(struct sxe2_adapter *adapter,
struct sxe2_pci_map_addr_info *addr_info = NULL;
int32_t ret = 0;
+ if (unlikely(res_type >= SXE2_PCI_MAP_RES_MAX_COUNT)) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Invalid resource type %u", res_type);
+ ret = -EINVAL;
+ goto l_end;
+ }
+
addr_info = &adapter->map_ctxt.addr_info[res_type];
if (!addr_info || addr_info->bar_idx == SXE2_PCI_MAP_BAR_INVALID) {
PMD_DEV_LOG_ERR(adapter, INIT, "Invalid bar index with resource type %d", res_type);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 19/45] net/sxe2: guard PCI BAR unmap when not initialized
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (18 preceding siblings ...)
2026-08-28 7:38 ` [PATCH v6 18/45] net/sxe2: validate PCI map resource type liujie5
@ 2026-08-28 7:38 ` liujie5
2026-08-28 7:38 ` [PATCH v6 20/45] net/sxe2: fix null dereference in dev uninit liujie5
` (25 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_pci_map_uinit() calls sxe2_dev_pci_seg_unmap() and walks
bar_info unconditionally. Only perform the unmap and free when
bar_info has been allocated, so an uninitialized map context is
handled cleanly.
Fixes: 66a10eb60ebe ("net/sxe2: add PCI BAR mapping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 9ef93b8076..fdff4ae10f 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1773,14 +1773,13 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
uint8_t i = 0;
PMD_INIT_FUNC_TRACE();
+ if (map_ctxt->bar_info != NULL) {
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
+ (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
- (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
-
- if (map_ctxt != NULL && map_ctxt->bar_info != NULL) {
for (i = 0; i < map_ctxt->bar_cnt; i++) {
bar_info = &map_ctxt->bar_info[i];
if (bar_info != NULL && bar_info->seg_info != NULL) {
@@ -1791,7 +1790,6 @@ void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
rte_free(map_ctxt->bar_info);
map_ctxt->bar_info = NULL;
}
-
adapter->dev_info.dev_data = NULL;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 20/45] net/sxe2: fix null dereference in dev uninit
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (19 preceding siblings ...)
2026-08-28 7:38 ` [PATCH v6 19/45] net/sxe2: guard PCI BAR unmap when not initialized liujie5
@ 2026-08-28 7:38 ` liujie5
2026-08-28 7:38 ` [PATCH v6 21/45] net/sxe2: fix duplicated cleanup in dev close liujie5
` (24 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_uninit() calls rep_dev->dev_ops->dev_close() for each VF
representor without checking that dev_ops or dev_close is present,
which can crash when the representor device is not fully initialized.
Guard the call with NULL checks.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index fdff4ae10f..41ea67a607 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2074,9 +2074,11 @@ static int32_t sxe2_dev_uninit(struct rte_eth_dev *dev)
for (i = 0; i < adapter->repr_ctxt.nb_repr_vf; i++) {
rep_dev = adapter->repr_ctxt.vf_rep_eth_dev[i];
if (rep_dev) {
- ret = rep_dev->dev_ops->dev_close(rep_dev);
- if (ret)
- goto l_end;
+ if (rep_dev->dev_ops && rep_dev->dev_ops->dev_close) {
+ ret = rep_dev->dev_ops->dev_close(rep_dev);
+ if (ret)
+ goto l_end;
+ }
if (rep_dev->intr_handle)
rte_intr_instance_free(rep_dev->intr_handle);
ret = rte_eth_dev_release_port(rep_dev);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 21/45] net/sxe2: fix duplicated cleanup in dev close
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (20 preceding siblings ...)
2026-08-28 7:38 ` [PATCH v6 20/45] net/sxe2: fix null dereference in dev uninit liujie5
@ 2026-08-28 7:38 ` liujie5
2026-08-28 7:38 ` [PATCH v6 22/45] net/sxe2: align dev init and cleanup order liujie5
` (23 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_dev_close() calls sxe2_switchdev_uninit() and
sxe2_dev_pci_map_uinit() twice, and releases resources in an order
that does not match the initialization sequence.
Remove the duplicated calls and align the teardown order with the
device init order.
Fixes: 8cebf80f1eda ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 41ea67a607..5d14e28d96 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2041,17 +2041,15 @@ static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
(void)sxe2_queues_release(dev);
sxe2_mp_uninit(dev);
(void)sxe2_sched_uinit(dev);
- (void)sxe2_rss_disable(dev);
(void)sxe2_flow_uninit(dev);
+ (void)sxe2_rss_disable(dev);
(void)sxe2_udp_tunnel_port_clear(dev);
- sxe2_vsi_uninit(dev);
sxe2_security_uinit(dev);
sxe2_intr_uninit(dev);
(void)sxe2_switchdev_uninit(dev);
sxe2_sw_uninit(dev);
- (void)sxe2_switchdev_uninit(dev);
- sxe2_dev_pci_map_uinit(dev);
sxe2_eth_uinit(dev);
+ sxe2_vsi_uninit(dev);
sxe2_dev_pci_map_uinit(dev);
sxe2_free_repr_info(dev);
sxe2_fc_state_uinit(dev);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 22/45] net/sxe2: align dev init and cleanup order
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (21 preceding siblings ...)
2026-08-28 7:38 ` [PATCH v6 21/45] net/sxe2: fix duplicated cleanup in dev close liujie5
@ 2026-08-28 7:38 ` liujie5
2026-08-28 7:38 ` [PATCH v6 23/45] net/sxe2: simplify switchdev representor matching liujie5
` (22 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move sxe2_eth_init() to be called before sxe2_sw_init() and
rearrange the error cleanup labels so that resources are torn down
in the reverse order of initialization.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 5d14e28d96..5bce710b29 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -1942,6 +1942,12 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_switchdev_err;
}
+ ret = sxe2_eth_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
+ goto init_eth_err;
+ }
+
ret = sxe2_sw_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize sw parameters, ret=[%d]", ret);
@@ -1954,12 +1960,6 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_irq_err;
}
- ret = sxe2_eth_init(dev);
- if (ret) {
- PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
- goto init_eth_err;
- }
-
ret = sxe2_security_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize security, ret=%d", ret);
@@ -2014,12 +2014,12 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
init_rss_err:
sxe2_security_uinit(dev);
init_security_err:
- sxe2_eth_uinit(dev);
-init_eth_err:
sxe2_intr_uninit(dev);
init_irq_err:
sxe2_sw_uninit(dev);
init_sw_err:
+ sxe2_eth_uinit(dev);
+init_eth_err:
(void)sxe2_switchdev_uninit(dev);
init_switchdev_err:
init_dev_info_err:
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 23/45] net/sxe2: simplify switchdev representor matching
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (22 preceding siblings ...)
2026-08-28 7:38 ` [PATCH v6 22/45] net/sxe2: align dev init and cleanup order liujie5
@ 2026-08-28 7:38 ` liujie5
2026-08-28 7:38 ` [PATCH v6 24/45] net/sxe2: rename fnav cid manager symbols to flow liujie5
` (21 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_switchdev_repr_match() encodes the kernel representor ID and
compares it against each requested port, which is fragile. Match the
PF number and VF ID directly against the switchdev representor info
instead, and drop the sxe2_switchdev_repr_id_encode_get() helper.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 72 +++++++++++++++++-----------------
drivers/net/sxe2/sxe2_ethdev.h | 3 --
2 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 5bce710b29..08986e384f 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -2149,42 +2149,25 @@ static int32_t sxe2_fw_version_string_get(struct rte_eth_dev *dev, char *fw_vers
return ret;
}
-static uint16_t sxe2_switchdev_repr_id_encode_get(struct sxe2_switchdev_info *switchdev_info)
-{
- enum rte_eth_representor_type type;
- uint16_t repr = switchdev_info->vf_num;
- uint32_t pf = switchdev_info->pf_num;
-
- switch (switchdev_info->port_name_type) {
- case SXE2_PHYS_PORT_NAME_TYPE_UPLINK:
- if (!switchdev_info->representor)
- return UINT16_MAX;
- type = RTE_ETH_REPRESENTOR_PF;
- pf = switchdev_info->mpesw_owner;
- break;
- case SXE2_PHYS_PORT_NAME_TYPE_PFVF:
- default:
- type = RTE_ETH_REPRESENTOR_VF;
- break;
- }
-
- return SXE2_REPRESENTOR_ID(pf, type, repr);
-}
-
static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
struct rte_eth_devargs *req_eth_da)
{
- uint32_t port_idx = 0;
- uint32_t repr_idx;
- uint16_t kernel_repr_id = sxe2_switchdev_repr_id_encode_get(&adapter->switchdev_info);
- uint16_t repr_id;
+ uint16_t port_idx;
+ uint16_t repr_idx;
+ uint16_t vf_id;
+ uint16_t i;
switch (req_eth_da->type) {
case RTE_ETH_REPRESENTOR_PF:
+ if (adapter->switchdev_info.port_name_type !=
+ SXE2_PHYS_PORT_NAME_TYPE_UPLINK) {
+ rte_errno = EBUSY;
+ return false;
+ }
break;
case RTE_ETH_REPRESENTOR_VF:
if (adapter->switchdev_info.port_name_type !=
- SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
+ SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
rte_errno = EBUSY;
return false;
}
@@ -2197,15 +2180,34 @@ static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
return false;
}
+ if (req_eth_da->nb_ports > 0) {
+ for (port_idx = 0; port_idx < req_eth_da->nb_ports; ++port_idx) {
+ if (adapter->switchdev_info.pf_num == req_eth_da->ports[port_idx])
+ break;
+ }
+ if (port_idx == req_eth_da->nb_ports) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev pf %u not match req pf",
+ adapter->switchdev_info.pf_num);
+ rte_errno = EBUSY;
+ return false;
+ }
+ }
+
for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
- repr_id = SXE2_REPRESENTOR_ID(req_eth_da->ports[port_idx],
- req_eth_da->type,
- req_eth_da->representor_ports[repr_idx]);
- if (repr_id == kernel_repr_id)
- return true;
- }
- rte_errno = EBUSY;
- return false;
+ for (i = 0; i < adapter->repr_ctxt.nb_vf; ++i) {
+ vf_id = rte_le_to_cpu_16(adapter->repr_ctxt.repr_vf_id[i].func_id);
+ if (vf_id == req_eth_da->representor_ports[repr_idx])
+ break;
+ }
+ if (i == adapter->repr_ctxt.nb_vf) {
+ PMD_DEV_LOG_DEBUG(adapter, DRV, "switchdev vf %u not match req vf(cnt:%u)",
+ req_eth_da->representor_ports[repr_idx], adapter->repr_ctxt.nb_vf);
+ rte_errno = EBUSY;
+ return false;
+ }
+ }
+
+ return true;
}
static int32_t sxe2_eth_pmd_probe_pf(struct sxe2_common_device *cdev,
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index f2557b28c3..e818578319 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -65,9 +65,6 @@ enum sxe2_fnav_tunnel_flag_type {
#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
#define lower_32_bits(n) ((uint32_t)((n) & 0xffffffff))
-#define SXE2_REPRESENTOR_ID(pf, type, repr) \
- (((pf) << 14) + ((type) << 12) + ((repr) & 0xfff))
-
#define SXE2_I2C_EEPROM_DEV_ADDR 0xA0
#define SXE2_I2C_EEPROM_DEV_ADDR2 0xA2
#define SXE2_MODULE_TYPE_SFP 0x03
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 24/45] net/sxe2: rename fnav cid manager symbols to flow
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (23 preceding siblings ...)
2026-08-28 7:38 ` [PATCH v6 23/45] net/sxe2: simplify switchdev representor matching liujie5
@ 2026-08-28 7:38 ` liujie5
2026-08-28 7:39 ` [PATCH v6 25/45] net/sxe2: move tunnel port helpers into flow module liujie5
` (20 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:38 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Rename the sxe2_fnav_cid_mgr, sxe2_fnav_cid_mgr_list_t,
sxe2_fnav_count_resource and sxe2_fnav_get_filter_cid symbols to the
sxe2_flow_* prefix for consistency with the flow module naming.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 2 +-
drivers/net/sxe2/sxe2_cmd_chnl.h | 2 +-
drivers/net/sxe2/sxe2_flow.c | 46 ++++++++++++++---------------
drivers/net/sxe2/sxe2_flow.h | 6 ++--
drivers/net/sxe2/sxe2_flow_define.h | 12 ++++----
5 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b09989fe50..3229c72597 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1800,7 +1800,7 @@ int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat
}
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr)
+ struct sxe2_flow_cid_mgr *mgr)
{
struct sxe2_drv_flow_fnav_query_stat_req req = { 0 };
struct sxe2_drv_flow_fnav_query_stat_resp resp = { 0 };
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index 294ac15db4..cfea1a1f0e 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -159,7 +159,7 @@ int32_t sxe2_drv_flow_fnav_get_stat_id(struct sxe2_adapter *adapter, uint32_t *s
int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
- struct sxe2_fnav_cid_mgr *mgr);
+ struct sxe2_flow_cid_mgr *mgr);
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set);
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index cf54803301..a33b8606df 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -857,7 +857,7 @@ static int32_t sxe2_flow_rte_list_free(struct sxe2_adapter *adapter,
struct rte_flow *flow_temp = NULL;
struct sxe2_flow *hw_flow = NULL;
struct sxe2_flow *hw_flow_temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
rte_spinlock_lock(&adapter->flow_ctxt.flow_list_lock);
TAILQ_FOREACH(flow_temp, &adapter->flow_ctxt.rte_flow_list, next) {
if (flow_temp == flow)
@@ -1028,7 +1028,7 @@ static struct rte_flow *sxe2_flow_create(struct rte_eth_dev *dev,
goto l_free_flow;
TAILQ_FOREACH(flow, &flow_list->sxe2_flow_list, next) {
- ret = sxe2_fnav_get_filter_cid(adapter, flow);
+ ret = sxe2_flow_get_filter_cid(adapter, flow);
if (ret != 0) {
PMD_LOG_ERR(DRV, "fnav get stats id failed, ret:%d", ret);
rte_flow_error_set(error, EIO,
@@ -1088,16 +1088,16 @@ static int32_t sxe2_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e
return ret;
}
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
user_id = flow->action.count.user_id;
@@ -1112,7 +1112,7 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
}
if (mgr == NULL) {
mgr = rte_zmalloc("sxe2_fnav_cid_mgr",
- sizeof(struct sxe2_fnav_cid_mgr), 0);
+ sizeof(struct sxe2_flow_cid_mgr), 0);
if (!mgr) {
PMD_LOG_ERR(DRV,
"Failed to alloc sxe2vf_fnav_cid_mgr memory.");
@@ -1143,13 +1143,13 @@ int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *mgr = *mgr_ptr;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *mgr = *mgr_ptr;
uint32_t user_id = flow->action.count.user_id;
if (user_id == 0) {
TAILQ_REMOVE(cid_mgr_list, mgr, next);
@@ -1170,14 +1170,14 @@ int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
uint32_t user_id = flow->action.count.user_id;
uint32_t driver_id = flow->action.count.driver_id;
@@ -1218,7 +1218,7 @@ static int32_t sxe2_flow_query_count(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
switch (flow->action.count.stat_ctrl) {
case SXE2_FNAV_STAT_ENA_NONE:
count->hits_set = 0;
@@ -1348,7 +1348,7 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
int32_t ret = 0;
TAILQ_INIT(&adapter->flow_ctxt.rte_flow_list);
- TAILQ_INIT(&adapter->flow_ctxt.hw_res.fnav_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.hw_res.flow_cid_mgr_list);
if (adapter->devargs.fnav_stat_type)
adapter->flow_ctxt.hw_res.count_type =
adapter->devargs.fnav_stat_type;
@@ -1370,10 +1370,10 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
int32_t ret = 0;
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
struct rte_flow_error error;
- struct sxe2_fnav_cid_mgr *mgr = NULL;
- struct sxe2_fnav_cid_mgr *temp = NULL;
- struct sxe2_fnav_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr *mgr = NULL;
+ struct sxe2_flow_cid_mgr *temp = NULL;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
+ &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
ret = sxe2_flow_flush(dev, &error);
if (ret)
diff --git a/drivers/net/sxe2/sxe2_flow.h b/drivers/net/sxe2/sxe2_flow.h
index daaeedd4dc..8d47b11ff4 100644
--- a/drivers/net/sxe2/sxe2_flow.h
+++ b/drivers/net/sxe2/sxe2_flow.h
@@ -14,16 +14,16 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev);
int32_t sxe2_flow_uninit(struct rte_eth_dev *dev);
-int32_t sxe2_fnav_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
+int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow);
int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct sxe2_flow *flow,
- struct sxe2_fnav_cid_mgr **mgr_ptr,
+ struct sxe2_flow_cid_mgr **mgr_ptr,
struct rte_flow_error *error);
int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev);
diff --git a/drivers/net/sxe2/sxe2_flow_define.h b/drivers/net/sxe2/sxe2_flow_define.h
index 263a573f04..8a5d871978 100644
--- a/drivers/net/sxe2/sxe2_flow_define.h
+++ b/drivers/net/sxe2/sxe2_flow_define.h
@@ -98,8 +98,8 @@ struct rte_flow {
};
TAILQ_HEAD(rte_flow_list_t, rte_flow);
-struct sxe2_fnav_cid_mgr {
- TAILQ_ENTRY(sxe2_fnav_cid_mgr) next;
+struct sxe2_flow_cid_mgr {
+ TAILQ_ENTRY(sxe2_flow_cid_mgr) next;
uint16_t stat_index;
uint32_t user_id;
uint32_t driver_id;
@@ -107,18 +107,18 @@ struct sxe2_fnav_cid_mgr {
uint64_t hits;
uint64_t bytes;
};
-TAILQ_HEAD(sxe2_fnav_cid_mgr_list_t, sxe2_fnav_cid_mgr);
+TAILQ_HEAD(sxe2_flow_cid_mgr_list_t, sxe2_flow_cid_mgr);
-struct sxe2_fnav_count_resource {
+struct sxe2_flow_count_resource {
uint32_t count_type;
uint32_t global_index;
- struct sxe2_fnav_cid_mgr_list_t fnav_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t flow_cid_mgr_list;
};
struct sxe2_flow_context {
struct rte_flow_list_t rte_flow_list;
rte_spinlock_t flow_list_lock;
- struct sxe2_fnav_count_resource hw_res;
+ struct sxe2_flow_count_resource hw_res;
uint16_t tunnel_port_list[SXE2_FLOW_UDP_TUNNEL_MAX];
uint32_t fnav_inited;
};
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 25/45] net/sxe2: move tunnel port helpers into flow module
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (24 preceding siblings ...)
2026-08-28 7:38 ` [PATCH v6 24/45] net/sxe2: rename fnav cid manager symbols to flow liujie5
@ 2026-08-28 7:39 ` liujie5
2026-08-28 7:39 ` [PATCH v6 26/45] net/sxe2: add ACL engine event statistics support liujie5
` (19 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Move sxe2_flow_parse_pattern_ipip, sxe2_flow_add_udp_tunnel_port and
sxe2_flow_add_tunnel_port from sxe2_flow_parse_pattern.c into
sxe2_flow.c as static helpers, and drop the public declaration of
sxe2_flow_add_tunnel_port from the header, keeping the tunnel port
handling internal to the flow module.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_flow.c | 113 +++++++++++++++++++++
drivers/net/sxe2/sxe2_flow_parse_pattern.c | 113 ---------------------
drivers/net/sxe2/sxe2_flow_parse_pattern.h | 6 --
3 files changed, 113 insertions(+), 119 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index a33b8606df..cd39385340 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -550,6 +550,119 @@ int32_t sxe2_flow_init_udp_tunnel_port(struct rte_eth_dev *dev)
return ret;
}
+static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
+ enum sxe2_flow_udp_tunnel_protocol proto,
+ struct sxe2_flow *flow,
+ BITMAP_TYPE *flow_type)
+{
+ int32_t ret = 0;
+ uint16_t tun_port;
+
+ tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
+ if (tun_port == 0xffff || tun_port == 0) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
+ goto l_end;
+ }
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ ret = -EINVAL;
+ PMD_LOG_ERR(DRV, "UDP must be over tunnel");
+ goto l_end;
+ }
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
+ flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
+l_end:
+ return ret;
+}
+
+static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
+{
+ sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV4;
+ if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
+ flow->pattern_outer.item_spec.ipv6.nexthdr =
+ SXE2_FLOW_IP_PROTOCOL_IPV6;
+ }
+ }
+ return 0;
+}
+
+static int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
+ struct rte_flow_error *error,
+ struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
+ enum sxe2_flow_tunnel_type tunnel_type)
+{
+ int32_t ret = 0;
+ enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
+ struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
+ switch (tunnel_type) {
+ case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
+ if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
+ } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
+ sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GTPU:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_GRE:
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
+ proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
+ } else {
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
+ pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
+ }
+ if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
+ pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
+ sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
+ }
+ }
+ break;
+ case SXE2_FLOW_TUNNEL_TYPE_IPIP:
+ ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
+ break;
+ default:
+ break;
+ }
+ if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
+ ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
+ if (ret != 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ NULL, "Failed to add udp port for tunnel.");
+ PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
+ goto l_end;
+ }
+ }
+ if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
+ if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
+ sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
+ }
+l_end:
+ return ret;
+}
+
static int32_t sxe2_flowlist_add_tunnel_port(struct rte_eth_dev *dev,
struct rte_flow *flow_list,
struct rte_flow_error *error)
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.c b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
index f5bf8922c6..189abb1a33 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.c
@@ -1637,119 +1637,6 @@ static int32_t sxe2_flow_parse_pattern_vxlan_gpe(const struct rte_flow_item *ite
return ret;
}
-static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type)
-{
- sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type);
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec);
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV4;
- if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type))
- flow->pattern_outer.item_spec.ipv6.nexthdr =
- SXE2_FLOW_IP_PROTOCOL_IPV6;
- }
- }
- return 0;
-}
-
-static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter,
- enum sxe2_flow_udp_tunnel_protocol proto,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type)
-{
- int32_t ret = 0;
- uint16_t tun_port;
-
- tun_port = adapter->flow_ctxt.tunnel_port_list[proto];
- if (tun_port == 0xffff || tun_port == 0) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto);
- goto l_end;
- }
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- ret = -EINVAL;
- PMD_LOG_ERR(DRV, "UDP must be over tunnel");
- goto l_end;
- }
- sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec);
- flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port);
-l_end:
- return ret;
-}
-
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow, BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type)
-{
- int32_t ret = 0;
- enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX;
- struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
- struct sxe2_flow_pattern *pattern = &flow->pattern_outer;
- switch (tunnel_type) {
- case SXE2_FLOW_TUNNEL_TYPE_VXLAN:
- if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN;
- } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) ||
- sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE;
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GTPU:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GENEVE:
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE;
- break;
- case SXE2_FLOW_TUNNEL_TYPE_GRE:
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) {
- proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE;
- } else {
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) {
- pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec);
- }
- if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) {
- pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE;
- sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec);
- }
- }
- break;
- case SXE2_FLOW_TUNNEL_TYPE_IPIP:
- ret = sxe2_flow_parse_pattern_ipip(flow, flow_type);
- break;
- default:
- break;
- }
- if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) {
- ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type);
- if (ret != 0) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM,
- NULL, "Failed to add udp port for tunnel.");
- PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret);
- goto l_end;
- }
- }
- if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) {
- if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type))
- sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs);
- }
-l_end:
- return ret;
-}
-
struct sxe2_flow_parse_pattern_ops sxe2_flow_parse_pattern_list[] = {
[SXE2_EXPANSION_OUTER_ETH] = {
.is_inner = false,
diff --git a/drivers/net/sxe2/sxe2_flow_parse_pattern.h b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
index 8442c35cae..69d83a6ea6 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_pattern.h
+++ b/drivers/net/sxe2/sxe2_flow_parse_pattern.h
@@ -37,10 +37,4 @@ int32_t sxe2_flow_parse_pattern(struct rte_eth_dev *dev,
struct rte_flow_error *error,
struct sxe2_flow *flow);
-int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev,
- struct rte_flow_error *error,
- struct sxe2_flow *flow,
- BITMAP_TYPE *flow_type,
- enum sxe2_flow_tunnel_type tunnel_type);
-
#endif /* SXE2_FLOW_PARSE_PATTERN_H_ */
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 26/45] net/sxe2: add ACL engine event statistics support
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (25 preceding siblings ...)
2026-08-28 7:39 ` [PATCH v6 25/45] net/sxe2: move tunnel port helpers into flow module liujie5
@ 2026-08-28 7:39 ` liujie5
2026-08-28 7:39 ` [PATCH v6 27/45] net/sxe2: guard Rx queue event FD free in unregister liujie5
` (18 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add statistics support for the ACL flow engine to track packet hits
and bytes, enabling flow aging and traffic monitoring for ACL rules.
- Add acl-stat-type devarg to configure the statistics type
- Implement sxe2_drv_flow_acl_get_stat_id/free_stat/query_stat
- Handle the ACL engine in flow create/destroy/query paths
- Add fnav_hw_res and acl_hw_res count resources
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
doc/guides/nics/sxe2.rst | 11 +++
drivers/net/sxe2/sxe2_cmd_chnl.c | 71 ++++++++++++++++++
drivers/net/sxe2/sxe2_cmd_chnl.h | 7 ++
drivers/net/sxe2/sxe2_drv_cmd.h | 19 +++++
drivers/net/sxe2/sxe2_dump.c | 2 +
drivers/net/sxe2/sxe2_ethdev.c | 23 ++++--
drivers/net/sxe2/sxe2_ethdev.h | 1 +
drivers/net/sxe2/sxe2_flow.c | 89 ++++++++++++++++++-----
drivers/net/sxe2/sxe2_flow_define.h | 5 +-
drivers/net/sxe2/sxe2_flow_parse_action.c | 25 +++++--
drivers/net/sxe2/sxe2_queue.c | 2 +
11 files changed, 224 insertions(+), 31 deletions(-)
diff --git a/doc/guides/nics/sxe2.rst b/doc/guides/nics/sxe2.rst
index 8278a5f108..c5b400a8ba 100644
--- a/doc/guides/nics/sxe2.rst
+++ b/doc/guides/nics/sxe2.rst
@@ -98,6 +98,17 @@ Runtime Configuration
Default value is 3 (count both packets and bytes).
+- ``acl-stat-type`` parameter [int]
+
+ This parameter controls the ACL flow engine statistics type
+ used for flow rule hit counting (via ``rte_flow_query``).
+
+ - 1: Only count the number of packets.
+ - 2: Only count the number of bytes.
+ - 3: Count both packets and bytes (default).
+
+ Default value is 3 (count both packets and bytes).
+
- ``drv-sw-stats`` parameter [int]
This parameter controls whether per-packet software statistics (SW stats)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 3229c72597..16a2c3fea4 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1829,6 +1829,77 @@ int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
return ret;
}
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id)
+{
+ struct sxe2_drv_flow_fnav_get_stat_id_req req = { 0 };
+ struct sxe2_drv_flow_fnav_get_stat_id_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC,
+ &req, sizeof(req),
+ &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+ *stat_id = resp.stat_id;
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id)
+{
+ struct sxe2_drv_flow_fnav_free_stat_id_req req = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = stat_id;
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_FREE,
+ &req, sizeof(req),
+ NULL, 0);
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to free acl stat id, ret: %d.", ret);
+ goto l_end;
+ }
+
+l_end:
+ return ret;
+}
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr)
+{
+ struct sxe2_drv_acl_query_stat_req req = { 0 };
+ struct sxe2_drv_acl_query_stat_resp resp = { 0 };
+ struct sxe2_drv_cmd_params cmd = { 0 };
+ struct sxe2_common_device *cdev = adapter->cdev;
+ int32_t ret = -1;
+
+ req.stat_id = mgr->stat_index;
+ req.stat_ctrl = mgr->count_type;
+ req.is_clear = 1;
+
+ sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY,
+ &req, sizeof(req), &resp, sizeof(resp));
+ ret = sxe2_drv_cmd_exec(cdev, &cmd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "Failed to query ACL stat, stat id: %u, ret: %d.",
+ req.stat_id, ret);
+ goto l_end;
+ }
+ mgr->hits += resp.stat_hits;
+ mgr->bytes += resp.stat_bytes;
+
+l_end:
+ return ret;
+}
+
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set)
{
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index cfea1a1f0e..7d07068bfc 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -161,6 +161,13 @@ int32_t sxe2_drv_flow_fnav_free_stat(struct sxe2_adapter *adapter, uint32_t stat
int32_t sxe2_drv_flow_fnav_query_stat(struct sxe2_adapter *adapter,
struct sxe2_flow_cid_mgr *mgr);
+int32_t sxe2_drv_flow_acl_get_stat_id(struct sxe2_adapter *adapter, uint32_t *stat_id);
+
+int32_t sxe2_drv_flow_acl_free_stat(struct sxe2_adapter *adapter, uint32_t stat_id);
+
+int32_t sxe2_drv_flow_acl_query_stat(struct sxe2_adapter *adapter,
+ struct sxe2_flow_cid_mgr *mgr);
+
int32_t sxe2_drv_srcvsi_prune_config(struct sxe2_adapter *adapter,
uint16_t *vsi_list, uint16_t vsi_cnt, bool set);
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index 03ef3b315d..cc71e2364e 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -668,6 +668,18 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_fc_get_resp {
uint8_t rsv[3];
} __rte_packed_end;
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_req {
+ uint32_t stat_id;
+ uint32_t stat_ctrl;
+ uint32_t is_clear;
+} __rte_packed_end;
+
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_acl_query_stat_resp {
+ uint32_t stat_index;
+ uint64_t stat_hits;
+ uint64_t stat_bytes;
+} __rte_packed_end;
+
enum sxe2_drv_cmd_module {
SXE2_DRV_CMD_MODULE_HANDSHAKE = 0,
SXE2_DRV_CMD_MODULE_DEV = 1,
@@ -824,6 +836,13 @@ enum sxe2_drv_cmd_code {
SXE2_DRV_CMD_OPT_EEP_GET =
SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_OPT, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_QUERY =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 1),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_ALLOC =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 2),
+ SXE2_DRV_CMD_FLOW_ACL_STAT_FREE =
+ SXE2_MK_DRV_CMD(SXE2_DRV_CMD_MODULE_ACL, 3),
+
};
#endif /* SXE2_DRV_CMD_H */
diff --git a/drivers/net/sxe2/sxe2_dump.c b/drivers/net/sxe2/sxe2_dump.c
index 590219f502..31f7d6ba61 100644
--- a/drivers/net/sxe2/sxe2_dump.c
+++ b/drivers/net/sxe2/sxe2_dump.c
@@ -80,12 +80,14 @@ sxe2_dump_dev_args_info(FILE *file, struct rte_eth_dev *dev)
"\t -- no_sched_mode: %s\n"
"\t -- flow-duplicate-pattern: %u\n"
"\t -- fnav-stat-type: %u\n"
+ "\t -- acl-stat-type: %u\n"
"\t -- sched_layer_mode: %u\n"
"\t -- rx_low_latency: %s\n"
"\t -- function-flow-direct: %s\n",
adapter->devargs.no_sched_mode ? "On" : "Off",
adapter->devargs.flow_dup_pattern_mode,
adapter->devargs.fnav_stat_type,
+ adapter->devargs.acl_stat_type,
adapter->devargs.sched_layer_mode,
adapter->devargs.rx_low_latency ? "On" : "Off",
adapter->devargs.func_flow_direct_en ? "On" : "Off");
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 08986e384f..77a31eb8a1 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -72,6 +72,7 @@ static const struct rte_pci_id pci_id_sxe2_tbl[] = {
#define SXE2_DEVARG_FLOW_DUP_PATTERN_MODE "flow-duplicate-pattern"
#define SXE2_DEVARG_FUNC_FLOW_DIRCT "function-flow-direct"
#define SXE2_DEVARG_FNAV_STAT_TYPE "fnav-stat-type"
+#define SXE2_DEVARG_ACL_STAT_TYPE "acl-stat-type"
#define SXE2_DEVARG_NO_SCHED_MODE "no-sched-mode"
#define SXE2_DEVARG_SCHED_LAYER_MODE "sched-layer-mode"
#define SXE2_DEVARG_RX_LOW_LATENCY "rx-low-latency"
@@ -981,11 +982,11 @@ sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
return ptypes;
}
-static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, void *args)
+static int32_t sxe2_parse_stat_type(const char *key, const char *value, void *args)
{
int32_t ret = -EINVAL;
uint8_t *num = (uint8_t *)args;
- unsigned long fnav_stat_type;
+ unsigned long stat_type;
char *endptr = NULL;
if (value == NULL || args == NULL) {
@@ -993,19 +994,19 @@ static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, voi
goto l_end;
}
errno = 0;
- fnav_stat_type = strtoul(value, &endptr, 10);
+ stat_type = strtoul(value, &endptr, 10);
if (errno != 0 || endptr == value || *endptr != '\0') {
PMD_LOG_WARN(INIT, "%s: \"%s\" is not a valid int value.",
key, value);
goto l_end;
}
- if (fnav_stat_type > SXE2_FNAV_STAT_ENA_ALL ||
- fnav_stat_type == SXE2_FNAV_STAT_ENA_NONE) {
+ if (stat_type > SXE2_FNAV_STAT_ENA_ALL ||
+ stat_type == SXE2_FNAV_STAT_ENA_NONE) {
PMD_LOG_ERR(INIT, "%s: \"%s\" out of range [1-3].",
key, value);
goto l_end;
}
- *num = (uint8_t)fnav_stat_type;
+ *num = (uint8_t)stat_type;
ret = 0;
l_end:
return ret;
@@ -1187,13 +1188,20 @@ static int32_t sxe2_args_parse(struct rte_eth_dev *dev, struct sxe2_dev_kvargs_i
if (kvargs == NULL)
goto l_end;
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_FNAV_STAT_TYPE,
- &sxe2_parse_fnav_stat_type,
+ &sxe2_parse_stat_type,
&adapter->devargs.fnav_stat_type);
if (ret) {
PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse fnav stat type, ret:%d", ret);
goto l_end;
}
+ ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_ACL_STAT_TYPE,
+ &sxe2_parse_stat_type, &adapter->devargs.acl_stat_type);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse acl stat type, ret:%d", ret);
+ goto l_end;
+ }
+
ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_NO_SCHED_MODE,
&sxe2_parse_bool,
&adapter->devargs.no_sched_mode);
@@ -2366,6 +2374,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_sxe2,
"flow-duplicate-pattern=<0|1|2> "
"function-flow-direct=<0|1> "
"fnav-stat-type=<1|2|3> "
+ "acl-stat-type=<1|2|3> "
"no-sched-mode=<0|1> "
"sched-layer-mode=<0-3> "
"rx-low-latency=<0|1>");
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index e818578319..e9f78fe57f 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -135,6 +135,7 @@ struct sxe2_devargs {
uint8_t flow_dup_pattern_mode;
uint8_t func_flow_direct_en;
uint8_t fnav_stat_type;
+ uint8_t acl_stat_type;
uint8_t no_sched_mode;
uint8_t sched_layer_mode;
uint8_t rx_low_latency;
diff --git a/drivers/net/sxe2/sxe2_flow.c b/drivers/net/sxe2/sxe2_flow.c
index cd39385340..d82d3bbd02 100644
--- a/drivers/net/sxe2/sxe2_flow.c
+++ b/drivers/net/sxe2/sxe2_flow.c
@@ -1204,13 +1204,23 @@ static int32_t sxe2_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e
int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
struct sxe2_flow_cid_mgr *temp = NULL;
struct sxe2_flow_cid_mgr *mgr = NULL;
+ uint32_t count_type;
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.fnav_hw_res.count_type;
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ count_type = adapter->flow_ctxt.acl_hw_res.count_type;
+ } else {
+ goto l_end;
+ }
if (sxe2_test_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types)) {
user_id = flow->action.count.user_id;
@@ -1233,7 +1243,10 @@ int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
goto l_end;
}
- ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ ret = sxe2_drv_flow_fnav_get_stat_id(adapter, &stat_index);
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ ret = sxe2_drv_flow_acl_get_stat_id(adapter, &stat_index);
if (ret) {
PMD_LOG_ERR(DRV, "Failed to alloc fw count id.");
rte_free(mgr);
@@ -1244,7 +1257,7 @@ int32_t sxe2_flow_get_filter_cid(struct sxe2_adapter *adapter, struct sxe2_flow
mgr->user_id = user_id;
mgr->driver_id = driver_id;
mgr->stat_index = stat_index;
- mgr->count_type = adapter->flow_ctxt.hw_res.count_type;
+ mgr->count_type = count_type;
}
flow->action.count.stat_index = mgr->stat_index;
flow->action.count.stat_ctrl = mgr->count_type;
@@ -1260,13 +1273,26 @@ int32_t sxe2_flow_free_mgr(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
struct sxe2_flow_cid_mgr *mgr = *mgr_ptr;
uint32_t user_id = flow->action.count.user_id;
- if (user_id == 0) {
- TAILQ_REMOVE(cid_mgr_list, mgr, next);
- ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+
+ if (user_id == 0 && mgr) {
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
+ } else {
+ PMD_LOG_ERR(DRV,
+ "Failed to free flow count, unknown engine type: %d.",
+ flow->engine_type);
+ ret = -ENOTSUP;
+ return ret;
+ }
if (ret) {
rte_flow_error_set(error, EIO,
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
@@ -1287,13 +1313,19 @@ int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
struct rte_flow_error *error)
{
int32_t ret = 0;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
struct sxe2_flow_cid_mgr *temp = NULL;
struct sxe2_flow_cid_mgr *mgr = NULL;
uint32_t user_id = flow->action.count.user_id;
uint32_t driver_id = flow->action.count.driver_id;
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL)
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV)
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
+ else
+ goto l_end;
+
TAILQ_FOREACH(temp, cid_mgr_list, next) {
if (temp->user_id == user_id &&
temp->driver_id == driver_id) {
@@ -1310,7 +1342,15 @@ int32_t sxe2_flow_query_mgr(struct sxe2_adapter *adapter,
ret = -EINVAL;
goto l_end;
}
- ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+
+ if (flow->engine_type == SXE2_FLOW_ENGINE_ACL) {
+ ret = sxe2_drv_flow_acl_query_stat(adapter, mgr);
+ } else if (flow->engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ ret = sxe2_drv_flow_fnav_query_stat(adapter, mgr);
+ } else {
+ PMD_LOG_ERR(DRV, "query flow engine neither FNAV nor ACL");
+ ret = -ENOTSUP;
+ }
if (ret) {
rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM, NULL,
@@ -1461,12 +1501,18 @@ int32_t sxe2_flow_init(struct rte_eth_dev *dev)
struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
int32_t ret = 0;
TAILQ_INIT(&adapter->flow_ctxt.rte_flow_list);
- TAILQ_INIT(&adapter->flow_ctxt.hw_res.flow_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list);
+ TAILQ_INIT(&adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list);
if (adapter->devargs.fnav_stat_type)
- adapter->flow_ctxt.hw_res.count_type =
+ adapter->flow_ctxt.fnav_hw_res.count_type =
adapter->devargs.fnav_stat_type;
else
- adapter->flow_ctxt.hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+ adapter->flow_ctxt.fnav_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
+
+ if (adapter->devargs.acl_stat_type)
+ adapter->flow_ctxt.acl_hw_res.count_type = adapter->devargs.acl_stat_type;
+ else
+ adapter->flow_ctxt.acl_hw_res.count_type = SXE2_FNAV_STAT_ENA_ALL;
adapter->flow_ctxt.fnav_inited = 1;
rte_spinlock_init(&adapter->flow_ctxt.flow_list_lock);
@@ -1485,13 +1531,13 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
struct rte_flow_error error;
struct sxe2_flow_cid_mgr *mgr = NULL;
struct sxe2_flow_cid_mgr *temp = NULL;
- struct sxe2_flow_cid_mgr_list_t *cid_mgr_list =
- &adapter->flow_ctxt.hw_res.flow_cid_mgr_list;
+ struct sxe2_flow_cid_mgr_list_t *cid_mgr_list = NULL;
ret = sxe2_flow_flush(dev, &error);
if (ret)
PMD_LOG_ERR(DRV, "Failed to flush flow, ret: %d.", ret);
+ cid_mgr_list = &adapter->flow_ctxt.fnav_hw_res.flow_cid_mgr_list;
TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
TAILQ_REMOVE(cid_mgr_list, mgr, next);
ret = sxe2_drv_flow_fnav_free_stat(adapter, mgr->stat_index);
@@ -1500,5 +1546,14 @@ int32_t sxe2_flow_uninit(struct rte_eth_dev *dev)
"Failed to free fnav stat id, ret: %d.", ret);
rte_free(mgr);
}
+
+ cid_mgr_list = &adapter->flow_ctxt.acl_hw_res.flow_cid_mgr_list;
+ TAILQ_FOREACH_SAFE(mgr, cid_mgr_list, next, temp) {
+ TAILQ_REMOVE(cid_mgr_list, mgr, next);
+ ret = sxe2_drv_flow_acl_free_stat(adapter, mgr->stat_index);
+ if (ret)
+ PMD_LOG_ERR(DRV, "Failed to free acl stat id, ret: %d.", ret);
+ rte_free(mgr);
+ }
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_flow_define.h b/drivers/net/sxe2/sxe2_flow_define.h
index 8a5d871978..d04499f5cb 100644
--- a/drivers/net/sxe2/sxe2_flow_define.h
+++ b/drivers/net/sxe2/sxe2_flow_define.h
@@ -100,7 +100,7 @@ TAILQ_HEAD(rte_flow_list_t, rte_flow);
struct sxe2_flow_cid_mgr {
TAILQ_ENTRY(sxe2_flow_cid_mgr) next;
- uint16_t stat_index;
+ uint32_t stat_index;
uint32_t user_id;
uint32_t driver_id;
uint32_t count_type;
@@ -118,7 +118,8 @@ struct sxe2_flow_count_resource {
struct sxe2_flow_context {
struct rte_flow_list_t rte_flow_list;
rte_spinlock_t flow_list_lock;
- struct sxe2_flow_count_resource hw_res;
+ struct sxe2_flow_count_resource fnav_hw_res;
+ struct sxe2_flow_count_resource acl_hw_res;
uint16_t tunnel_port_list[SXE2_FLOW_UDP_TUNNEL_MAX];
uint32_t fnav_inited;
};
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index a9559e2d7e..db70b146c6 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -953,7 +953,8 @@ static int32_t sxe2_flow_check_actions(struct rte_eth_dev *dev __rte_unused, str
}
}
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
if (vsi_num) {
flow->action.q_region.q_index = 0;
flow->action.q_region.region = 7;
@@ -988,7 +989,8 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
case RTE_FLOW_ACTION_TYPE_VOID:
break;
case RTE_FLOW_ACTION_TYPE_PASSTHRU:
- if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
+ if (engine_type == SXE2_FLOW_ENGINE_FNAV ||
+ engine_type == SXE2_FLOW_ENGINE_ACL) {
sxe2_set_bit(SXE2_FLOW_ACTION_PASSTHRU, flow->action.act_types);
action_num[SXE2_FLOW_ACTION_PASSTHRU]++;
} else {
@@ -1037,11 +1039,24 @@ int32_t sxe2_flow_parse_action(struct rte_eth_dev *dev,
if (engine_type == SXE2_FLOW_ENGINE_FNAV) {
sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
act_count = action->conf;
- flow->action.count.user_id = act_count->id;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
+ flow->action.count.driver_id = 0;
+ if (flow->action.count.user_id == 0) {
+ flow->action.count.driver_id =
+ ++adapter->flow_ctxt.fnav_hw_res.global_index;
+ }
+ action_num[SXE2_FLOW_ACTION_COUNT]++;
+ } else if (engine_type == SXE2_FLOW_ENGINE_ACL) {
+ sxe2_set_bit(SXE2_FLOW_ACTION_COUNT, flow->action.act_types);
+ act_count = action->conf;
+ flow->action.count.user_id =
+ (act_count == NULL) ? 0 : act_count->id;
flow->action.count.driver_id = 0;
- if (flow->action.count.user_id == 0)
+ if (flow->action.count.user_id == 0) {
flow->action.count.driver_id =
- ++adapter->flow_ctxt.hw_res.global_index;
+ ++adapter->flow_ctxt.acl_hw_res.global_index;
+ }
action_num[SXE2_FLOW_ACTION_COUNT]++;
} else {
rte_flow_error_set(error, ENOTSUP,
diff --git a/drivers/net/sxe2/sxe2_queue.c b/drivers/net/sxe2/sxe2_queue.c
index afb2681b72..3aaa14c685 100644
--- a/drivers/net/sxe2/sxe2_queue.c
+++ b/drivers/net/sxe2/sxe2_queue.c
@@ -39,6 +39,8 @@ int32_t sxe2_queues_init(struct rte_eth_dev *dev)
rxq->rx_buf_len = RTE_MIN(rxq->rx_buf_len, SXE2_RX_MAX_DATA_BUF_SIZE);
if (frame_size > rxq->rx_buf_len)
dev->data->scattered_rx = 1;
+ if (adapter->flow_ctxt.fnav_inited)
+ rxq->fnav_enable = true;
}
adapter->ptp_ctxt.mbuf_rx_ts_offset = -1;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 27/45] net/sxe2: guard Rx queue event FD free in unregister
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (26 preceding siblings ...)
2026-08-28 7:39 ` [PATCH v6 26/45] net/sxe2: add ACL engine event statistics support liujie5
@ 2026-08-28 7:39 ` liujie5
2026-08-28 7:39 ` [PATCH v6 28/45] net/sxe2: refactor primary process MP message handling liujie5
` (17 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_rxq_intr_unregister() frees irq_ctxt->rxq_event_fd outside the
rxq_event_fd NULL check. Move the free and NULL assignment inside the
guard so the buffer is only released when it was allocated.
Fixes: 8cebf80f1eda ("net/sxe2: support Rx interrupt")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index ba764dd5e4..4e5339e24b 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -881,12 +881,11 @@ static void sxe2_rxq_intr_unregister(struct rte_eth_dev *dev)
(void)sxe2_drv_dev_rxq_irq_set(adapter->cdev, i, &efd, 1);
sxe2_rxq_intr_efd_free(irq_ctxt->rxq_event_fd[i]);
}
+ rte_free(irq_ctxt->rxq_event_fd);
+ irq_ctxt->rxq_event_fd = NULL;
}
- rte_free(irq_ctxt->rxq_event_fd);
- irq_ctxt->rxq_event_fd = NULL;
rte_intr_vec_list_free(intr_handle);
-
rte_intr_nb_efd_set(intr_handle, 0);
rte_intr_max_intr_set(intr_handle, 0);
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 28/45] net/sxe2: refactor primary process MP message handling
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (27 preceding siblings ...)
2026-08-28 7:39 ` [PATCH v6 27/45] net/sxe2: guard Rx queue event FD free in unregister liujie5
@ 2026-08-28 7:39 ` liujie5
2026-08-28 7:39 ` [PATCH v6 29/45] net/sxe2: refactor Tx queue reset operations liujie5
` (16 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Extract the multi-process work logic into the sxe2_mp_do_primary_work
helper and operate on a copy of the request in the primary handler so
the original message is not modified. Simplify the reply construction
and return -ENOENT instead of -EINVAL when no response is received
from the primary process.
Fixes: 5db446ba97b0 ("net/sxe2: support statistics and multi-process")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_mp.c | 59 ++++++++++++++++++++++----------------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_mp.c b/drivers/net/sxe2/sxe2_mp.c
index a4a5c76495..93a11150a9 100644
--- a/drivers/net/sxe2/sxe2_mp.c
+++ b/drivers/net/sxe2/sxe2_mp.c
@@ -29,16 +29,11 @@ static int32_t sxe2_mp_secondary_handle(const struct rte_mp_msg *mp_msg,
const void *peer);
static int32_t
-sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+sxe2_mp_do_primary_work(struct sxe2_mp_param *param)
{
- struct rte_mp_msg reply;
- const struct sxe2_mp_param *param =
- (const struct sxe2_mp_param *)mp_msg->param;
- struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
struct rte_eth_dev *dev;
- int32_t ret = 0;
struct sxe2_mp_shared_data *mz_data;
- int32_t send_reply = 0;
+ int32_t ret = 0;
int32_t cnt = 0;
if (!rte_eth_dev_is_valid_port(param->port_id)) {
@@ -49,24 +44,21 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
}
dev = &rte_eth_devices[param->port_id];
- sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+
if (sxe2_mp_mz == NULL) {
- PMD_LOG_ERR(DRV, "Failed to lookup memzone %s", SXE2_MP_MZ_NAME);
- ret = -ENOENT;
- goto out;
+ sxe2_mp_mz = rte_memzone_lookup(SXE2_MP_MZ_NAME);
+ if (sxe2_mp_mz == NULL) {
+ PMD_LOG_ERR(DRV, "Failed to lookup memzone %s",
+ SXE2_MP_MZ_NAME);
+ ret = -ENOENT;
+ goto out;
+ }
}
mz_data = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
- send_reply = 1;
-
- memset(&reply, 0, sizeof(reply));
- (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
- reply.len_param = sizeof(*reply_param);
-
switch (param->type) {
case SXE2_MP_REQ_GET_STATS:
- ret = sxe2_stats_info_get(dev,
- &mz_data->payload.stats_blk.stats,
+ ret = sxe2_stats_info_get(dev, &mz_data->payload.stats_blk.stats,
&mz_data->payload.stats_blk.qstats);
break;
case SXE2_MP_REQ_GET_XSTATS:
@@ -88,15 +80,32 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
default:
PMD_LOG_ERR(DRV, "primary process: unrecognized msg type: %d",
param->type);
- send_reply = false;
ret = -EINVAL;
- goto out;
+ break;
}
+
out:
- if (!send_reply)
- return ret;
+ param->result = ret;
+ return ret;
+}
- reply_param->result = ret;
+static int32_t
+sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
+{
+ struct rte_mp_msg reply;
+ struct sxe2_mp_param *reply_param = (struct sxe2_mp_param *)reply.param;
+ const struct sxe2_mp_param *param =
+ (const struct sxe2_mp_param *)mp_msg->param;
+ struct sxe2_mp_param param_copy;
+
+ memset(&reply, 0, sizeof(reply));
+ (void)strlcpy(reply.name, SXE2_MP_NAME, sizeof(reply.name));
+ reply.len_param = sizeof(*reply_param);
+
+ param_copy = *param;
+ (void)sxe2_mp_do_primary_work(¶m_copy);
+
+ reply_param->result = param_copy.result;
reply_param->type = param->type;
reply_param->port_id = param->port_id;
@@ -275,7 +284,7 @@ int32_t sxe2_mp_request_simple(struct rte_eth_dev *dev,
if (reply.nb_received == 0) {
PMD_LOG_ERR(DRV, "No response received from primary for type=%d, port %u",
type, dev->data->port_id);
- ret = -EINVAL;
+ ret = -ENOENT;
goto out;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 29/45] net/sxe2: refactor Tx queue reset operations
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (28 preceding siblings ...)
2026-08-28 7:39 ` [PATCH v6 28/45] net/sxe2: refactor primary process MP message handling liujie5
@ 2026-08-28 7:39 ` liujie5
2026-08-28 7:39 ` [PATCH v6 30/45] net/sxe2: unify vectorized Tx buffer handling liujie5
` (15 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Extract the descriptor ring reset loop into a sxe2_tx_queue_desc_ring_reset
helper and reuse it from both the scalar and vectorized queue reset paths.
Add a sxe2_tx_queue_reset_vec entry point for vectorized queues, export
sxe2_tx_buffer_ring_free for reuse outside the module (clearing the buffer
ring pointer after freeing it), and add sxe2_tx_vec_ops_get to build the
vectorized Tx queue operations table used by the vector path setup.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_tx.c | 42 +++++++++++++++++++++++---------
drivers/net/sxe2/sxe2_tx.h | 4 +++
drivers/net/sxe2/sxe2_txrx_vec.c | 16 +++++++++++-
drivers/net/sxe2/sxe2_txrx_vec.h | 1 +
4 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_tx.c b/drivers/net/sxe2/sxe2_tx.c
index f49238ceef..94a6e9afc7 100644
--- a/drivers/net/sxe2/sxe2_tx.c
+++ b/drivers/net/sxe2/sxe2_tx.c
@@ -19,6 +19,17 @@ static void *sxe2_tx_doorbell_addr_get(struct sxe2_adapter *adapter, uint16_t qu
queue_id);
}
+static void sxe2_tx_queue_desc_ring_reset(struct sxe2_tx_queue *txq)
+{
+ uint16_t i;
+ static const union sxe2_tx_data_desc zeroed_desc = {{0}};
+
+ for (i = 0; i < txq->ring_depth; i++) {
+ txq->desc_ring[i] = zeroed_desc;
+ txq->desc_ring[i].wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
+ }
+}
+
static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue *txq)
{
txq->tdt_reg_addr = sxe2_tx_doorbell_addr_get(adapter, txq->queue_id);
@@ -28,20 +39,12 @@ static void sxe2_tx_tail_init(struct sxe2_adapter *adapter, struct sxe2_tx_queue
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
{
uint16_t prev, i;
- volatile union sxe2_tx_data_desc *txd;
- static const union sxe2_tx_data_desc zeroed_desc = {{0}};
struct sxe2_tx_buffer *tx_buffer = txq->buffer_ring;
- for (i = 0; i < txq->ring_depth; i++)
- txq->desc_ring[i] = zeroed_desc;
+ sxe2_tx_queue_desc_ring_reset(txq);
prev = txq->ring_depth - 1;
for (i = 0; i < txq->ring_depth; i++) {
- txd = &txq->desc_ring[i];
- if (txd == NULL)
- continue;
-
- txd->wb.dd = rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE);
tx_buffer[i].mbuf = NULL;
tx_buffer[i].last_id = i;
tx_buffer[prev].next_id = i;
@@ -56,6 +59,21 @@ void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq)
txq->next_rs = txq->rs_thresh - 1;
}
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq)
+{
+ sxe2_tx_queue_desc_ring_reset(txq);
+
+ memset(txq->buffer_ring, 0,
+ sizeof(struct sxe2_tx_buffer) * txq->ring_depth);
+
+ txq->desc_used_num = 0;
+ txq->desc_free_num = txq->ring_depth - 1;
+ txq->next_use = 0;
+ txq->next_clean = txq->ring_depth - 1;
+ txq->next_dd = txq->rs_thresh - 1;
+ txq->next_rs = txq->rs_thresh - 1;
+}
+
void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
{
uint32_t i;
@@ -70,10 +88,12 @@ void __rte_cold sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq)
}
}
-static void sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq)
{
- if (txq != NULL && txq->buffer_ring != NULL)
+ if (txq != NULL && txq->buffer_ring != NULL) {
rte_free(txq->buffer_ring);
+ txq->buffer_ring = NULL;
+ }
}
const struct sxe2_txq_ops sxe2_default_txq_ops = {
diff --git a/drivers/net/sxe2/sxe2_tx.h b/drivers/net/sxe2/sxe2_tx.h
index f4823126b3..bc5ff1c2bc 100644
--- a/drivers/net/sxe2/sxe2_tx.h
+++ b/drivers/net/sxe2/sxe2_tx.h
@@ -9,6 +9,10 @@
void __rte_cold sxe2_tx_queue_reset(struct sxe2_tx_queue *txq);
+void __rte_cold sxe2_tx_queue_reset_vec(struct sxe2_tx_queue *txq);
+
+void __rte_cold sxe2_tx_buffer_ring_free(struct sxe2_tx_queue *txq);
+
int32_t __rte_cold sxe2_tx_queue_start(struct rte_eth_dev *dev, uint16_t queue_id);
void sxe2_tx_queue_mbufs_release(struct sxe2_tx_queue *txq);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.c b/drivers/net/sxe2/sxe2_txrx_vec.c
index cf004f5eb2..9cfa565548 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec.c
@@ -8,6 +8,19 @@
#include "sxe2_ethdev.h"
#include "sxe2_common_log.h"
+static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq);
+
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void)
+{
+ static const struct sxe2_txq_ops ops = {
+ .queue_reset = sxe2_tx_queue_reset_vec,
+ .mbufs_release = sxe2_tx_queue_mbufs_release_vec,
+ .buffer_ring_free = sxe2_tx_buffer_ring_free,
+ };
+
+ return ops;
+}
+
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags)
{
struct sxe2_rx_queue *rxq;
@@ -233,7 +246,8 @@ int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev)
PMD_LOG_INFO(TX, "Failed to prepare tx queue, txq[%d] is NULL", i);
continue;
}
- txq->ops.mbufs_release = sxe2_tx_queue_mbufs_release_vec;
+ txq->ops = sxe2_tx_vec_ops_get();
+ txq->ops.queue_reset(txq);
}
return ret;
}
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.h b/drivers/net/sxe2/sxe2_txrx_vec.h
index c139aed776..b9bc4f9c27 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec.h
@@ -89,6 +89,7 @@ uint16_t sxe2_rx_pkts_scattered_vec_neon_offload(void *rx_queue, struct rte_mbuf
uint16_t sxe2_tx_pkts_vec_neon_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
#endif
+struct sxe2_txq_ops sxe2_tx_vec_ops_get(void);
int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
int32_t __rte_cold sxe2_tx_queues_vec_prepare(struct rte_eth_dev *dev);
int32_t __rte_cold sxe2_rx_vec_support_check(struct rte_eth_dev *dev, uint32_t *vec_flags);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 30/45] net/sxe2: unify vectorized Tx buffer handling
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (29 preceding siblings ...)
2026-08-28 7:39 ` [PATCH v6 29/45] net/sxe2: refactor Tx queue reset operations liujie5
@ 2026-08-28 7:39 ` liujie5
2026-08-28 7:39 ` [PATCH v6 31/45] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
` (14 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Add a union of the scalar and vectorized buffer ring pointers to the
Tx queue structure so the vectorized path can use sxe2_tx_buffer_vec
directly. Rename the mbuf fill helper to sxe2_tx_pkts_mbuf_fill_vec,
switch the vectorized Tx burst and mbuf release paths to the
buffer_ring_vec member, and drop the AVX512-specific fill handling and
conditional branching.
Fixes: ac60f302cbef ("net/sxe2: add vectorized Rx and Tx")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_queue.h | 5 +-
drivers/net/sxe2/sxe2_txrx_vec.c | 57 ++----
drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 10 +-
drivers/net/sxe2/sxe2_txrx_vec_avx512.c | 133 +-------------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 9 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 219 ++++++++++++++++--------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
7 files changed, 178 insertions(+), 265 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_queue.h b/drivers/net/sxe2/sxe2_queue.h
index 10bdaf5b8d..e53a1ce852 100644
--- a/drivers/net/sxe2/sxe2_queue.h
+++ b/drivers/net/sxe2/sxe2_queue.h
@@ -62,7 +62,10 @@ struct sxe2_txq_ops {
};
struct sxe2_tx_queue {
volatile union sxe2_tx_data_desc *desc_ring;
- struct sxe2_tx_buffer *buffer_ring;
+ union {
+ struct sxe2_tx_buffer *buffer_ring;
+ struct sxe2_tx_buffer_vec *buffer_ring_vec;
+ };
volatile uint32_t *tdt_reg_addr;
uint64_t offloads;
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.c b/drivers/net/sxe2/sxe2_txrx_vec.c
index 9cfa565548..7c5da33dd5 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec.c
@@ -170,66 +170,31 @@ int32_t __rte_cold sxe2_tx_vec_support_check(struct rte_eth_dev *dev, uint32_t *
static void sxe2_tx_queue_mbufs_release_vec(struct sxe2_tx_queue *txq)
{
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer_vec;
uint16_t i;
- if (unlikely(txq == NULL || txq->buffer_ring == NULL)) {
+ if (unlikely(txq == NULL || txq->buffer_ring_vec == NULL)) {
PMD_LOG_ERR(TX, "Tx release mbufs vec, invalid params.");
return;
}
- i = txq->next_dd - (txq->rs_thresh - 1);
-#ifdef CC_AVX512_SUPPORT
- struct rte_eth_dev *dev;
- struct sxe2_tx_buffer_vec *buffer_vec;
- dev = &rte_eth_devices[txq->port_id];
-
- if (dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512 ||
- dev->tx_pkt_burst == sxe2_tx_pkts_vec_avx512_simple) {
- buffer_vec = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ i = txq->next_dd - (txq->rs_thresh - 1);
+ buffer_vec = txq->buffer_ring_vec;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer_vec[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
- buffer_vec[i].mbuf = NULL;
- }
- }
- i = 0;
- }
- for ( ; i < txq->next_use; ++i) {
+ if (txq->next_use < i) {
+ for ( ; i < txq->ring_depth; ++i) {
if (buffer_vec[i].mbuf != NULL) {
rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
buffer_vec[i].mbuf = NULL;
}
}
- } else {
-#endif
- buffer = txq->buffer_ring;
- buffer = txq->buffer_ring;
- if (txq->next_use < i) {
- for ( ; i < txq->ring_depth; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
- i = 0;
- }
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
- }
- }
-#ifdef CC_AVX512_SUPPORT
+ i = 0;
}
-#endif
- for (; i < txq->next_use; ++i) {
- if (buffer[i].mbuf != NULL) {
- rte_pktmbuf_free_seg(buffer[i].mbuf);
- buffer[i].mbuf = NULL;
+ for ( ; i < txq->next_use; ++i) {
+ if (buffer_vec[i].mbuf != NULL) {
+ rte_pktmbuf_free_seg(buffer_vec[i].mbuf);
+ buffer_vec[i].mbuf = NULL;
}
}
}
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
index 0618e6d988..da96ca3064 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
@@ -115,7 +115,7 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -134,14 +134,14 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -157,10 +157,10 @@ sxe2_tx_pkts_vec_avx2_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx2(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
index a830c7a33b..6c8415ee5a 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx512.c
@@ -1,8 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
*/
-
-#ifndef SXE2_TEST
#include <rte_vect.h>
#include "sxe2_ethdev.h"
@@ -12,114 +10,6 @@
#include "sxe2_txrx_vec_common.h"
#include "sxe2_vsi.h"
-static __rte_always_inline int32_t sxe2_tx_bufs_free_vec_avx512(struct sxe2_tx_queue *txq)
-{
- struct sxe2_tx_buffer_vec *buffer;
- struct rte_mbuf *mbuf;
- struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC];
- struct rte_mempool *mp;
- struct rte_mempool_cache *cache;
- void **cache_objs;
- uint32_t copied;
- uint32_t i;
- int32_t ret;
- uint16_t rs_thresh;
- uint16_t free_num;
-
- if (rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE) !=
- (txq->desc_ring[txq->next_dd].wb.dd &
- rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK))) {
- ret = 0;
- goto l_end;
- }
-
- rs_thresh = txq->rs_thresh;
-
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += txq->next_dd - (rs_thresh - 1);
-
- if ((txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) &&
- (rs_thresh & 31) == 0) {
- mp = buffer[0].mbuf->pool;
- cache = rte_mempool_default_cache(mp, rte_lcore_id());
-
- if (cache == NULL || cache->len)
- goto normal;
-
- if (rs_thresh > RTE_MEMPOOL_CACHE_MAX_SIZE) {
- (void)rte_mempool_ops_enqueue_bulk(mp, (void *)buffer, rs_thresh);
- goto done;
- }
- cache_objs = &cache->objs[cache->len];
-
- copied = 0;
- while (copied < rs_thresh) {
- const __m512i objs0 = _mm512_loadu_si512(&buffer[copied]);
- const __m512i objs1 = _mm512_loadu_si512(&buffer[copied + 8]);
- const __m512i objs2 = _mm512_loadu_si512(&buffer[copied + 16]);
- const __m512i objs3 = _mm512_loadu_si512(&buffer[copied + 24]);
-
- _mm512_storeu_si512(&cache_objs[copied], objs0);
- _mm512_storeu_si512(&cache_objs[copied + 8], objs1);
- _mm512_storeu_si512(&cache_objs[copied + 16], objs2);
- _mm512_storeu_si512(&cache_objs[copied + 24], objs3);
- copied += 32;
- }
- cache->len += rs_thresh;
-
- if (cache->len >= cache->flushthresh) {
- (void)rte_mempool_ops_enqueue_bulk(mp,
- &cache->objs[cache->size], cache->len - cache->size);
- cache->len = cache->size;
- }
- goto done;
- }
-
-normal:
- mbuf = rte_pktmbuf_prefree_seg(buffer[0].mbuf);
-
- if (likely(mbuf)) {
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
-
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
-
- if (likely(mbuf)) {
- if (likely(mbuf->pool == mbuf_free_arr[0]->pool)) {
- mbuf_free_arr[free_num] = mbuf;
- free_num++;
- } else {
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
-
- mbuf_free_arr[0] = mbuf;
- free_num = 1;
- }
- }
- }
-
- rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
- (void *)mbuf_free_arr, free_num);
- } else {
- for (i = 1; i < rs_thresh; ++i) {
- mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
- if (mbuf != NULL)
- rte_mempool_put(mbuf->pool, mbuf);
- }
- }
-
-done:
- txq->desc_free_num += txq->rs_thresh;
- txq->next_dd += txq->rs_thresh;
- if (txq->next_dd >= txq->ring_depth)
- txq->next_dd = txq->rs_thresh - 1;
- ret = rs_thresh;
-
-l_end:
- return ret;
-}
-
static __rte_always_inline void
sxe2_tx_desc_fill_one_avx512(volatile union sxe2_tx_data_desc *desc, struct rte_mbuf *pkt,
uint64_t desc_cmd, bool with_offloads)
@@ -207,16 +97,6 @@ void sxe2_tx_desc_fill_avx512(volatile union sxe2_tx_data_desc *desc, struct rte
}
}
-static __rte_always_inline void
-sxe2_tx_pkts_mbuf_fill_avx512(struct sxe2_tx_buffer_vec *buffer,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
- uint16_t i;
-
- for (i = 0; i < nb_pkts; ++i)
- buffer[i].mbuf = tx_pkts[i];
-}
-
static __rte_always_inline uint16_t
sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool with_offloads)
@@ -228,7 +108,7 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
uint16_t tx_num;
if (txq->desc_free_num < txq->free_thresh)
- (void)sxe2_tx_bufs_free_vec_avx512(txq);
+ (void)sxe2_tx_bufs_free_vec(txq);
nb_pkts = RTE_MIN(txq->desc_free_num, nb_pkts);
if (unlikely(nb_pkts == 0)) {
@@ -241,15 +121,14 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
- buffer += next_use;
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, res_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -265,10 +144,10 @@ sxe2_tx_pkts_vec_avx512_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pk
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = txq->desc_ring;
- buffer = (struct sxe2_tx_buffer_vec *)txq->buffer_ring;
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill_avx512(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
sxe2_tx_desc_fill_avx512(desc, tx_pkts, tx_num,
SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
@@ -863,5 +742,3 @@ uint16_t sxe2_rx_pkts_scattered_vec_avx512_offload(void *rx_queue,
return sxe2_rx_pkts_scattered_common_vec_avx512(rx_queue,
rx_pkts, nb_pkts, true);
}
-
-#endif
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_common.h b/drivers/net/sxe2/sxe2_txrx_vec_common.h
index 9ac99cf0fa..ede4c236b1 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_common.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec_common.h
@@ -25,10 +25,11 @@
#define SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC 64
static __rte_always_inline void
-sxe2_tx_pkts_mbuf_fill(struct sxe2_tx_buffer *buffer,
- struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+sxe2_tx_pkts_mbuf_fill_vec(struct sxe2_tx_buffer_vec *buffer,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
uint16_t i;
+
for (i = 0; i < nb_pkts; ++i)
buffer[i].mbuf = tx_pkts[i];
}
@@ -36,7 +37,7 @@ sxe2_tx_pkts_mbuf_fill(struct sxe2_tx_buffer *buffer,
static __rte_always_inline int32_t
sxe2_tx_bufs_free_vec(struct sxe2_tx_queue *txq)
{
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
struct rte_mbuf *mbuf;
struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC];
int32_t ret;
@@ -50,7 +51,7 @@ sxe2_tx_bufs_free_vec(struct sxe2_tx_queue *txq)
goto l_end;
}
rs_thresh = txq->rs_thresh;
- buffer = &txq->buffer_ring[txq->next_dd - (rs_thresh - 1)];
+ buffer = &txq->buffer_ring_vec[txq->next_dd - (rs_thresh - 1)];
mbuf = rte_pktmbuf_prefree_seg(buffer[0].mbuf);
if (likely(mbuf)) {
mbuf_free_arr[0] = mbuf;
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_neon.c b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
index 4e5cb87cd5..0b139b8269 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_neon.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_neon.c
@@ -34,12 +34,58 @@ sxe2_tx_desc_fill_one_neon(volatile union sxe2_tx_data_desc *desc,
vst1q_u64(RTE_CAST_PTR(uint64_t *, desc), data_desc);
}
+static __rte_always_inline void
+sxe2_tx_desc_fill_4_neon_simple(volatile union sxe2_tx_data_desc *desc,
+ struct rte_mbuf **pkts)
+{
+ uint64x2_t d0, d1, d2, d3;
+ uint64x2x4_t v;
+ const uint64_t cmd_base = ((uint64_t)SXE2_TX_DESC_DTYPE_DATA) |
+ ((uint64_t)SXE2_TX_DATA_DESC_CMD_EOP) <<
+ SXE2_TX_DATA_DESC_CMD_SHIFT;
+
+ d0 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[0]),
+ cmd_base |
+ ((uint64_t)pkts[0]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[0]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d1 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[1]),
+ cmd_base |
+ ((uint64_t)pkts[1]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[1]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d2 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[2]),
+ cmd_base |
+ ((uint64_t)pkts[2]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[2]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+ d3 = (uint64x2_t){
+ rte_pktmbuf_iova(pkts[3]),
+ cmd_base |
+ ((uint64_t)pkts[3]->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT |
+ ((uint64_t)SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[3]->l2_len))
+ << SXE2_TX_DATA_DESC_OFFSET_SHIFT
+ };
+
+ v.val[0] = d0;
+ v.val[1] = d1;
+ v.val[2] = d2;
+ v.val[3] = d3;
+ vst1q_u64_x4(RTE_CAST_PTR(uint64_t *, desc), v);
+}
+
static __rte_always_inline uint16_t
sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -59,18 +105,26 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
-
- for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
+ if (with_offloads) {
+ for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ }
+ } else {
+ for (i = 0; i + 3 < res_num - 1; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
sxe2_tx_desc_fill_one_neon(desc, *tx_pkts++,
@@ -82,14 +136,23 @@ sxe2_tx_pkts_vec_neon_batch(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
- for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
- sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
- SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+ if (with_offloads) {
+ for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, true);
+ }
+ } else {
+ for (i = 0; i + 3 < tx_num; i += 4, tx_pkts += 4, desc += 4)
+ sxe2_tx_desc_fill_4_neon_simple(desc, tx_pkts);
+ for (; i < tx_num; ++i, ++tx_pkts, ++desc) {
+ sxe2_tx_desc_fill_one_neon(desc, *tx_pkts,
+ SXE2_TX_DATA_DESC_CMD_EOP, false);
+ }
}
next_use += tx_num;
@@ -150,22 +213,24 @@ uint16_t sxe2_tx_pkts_vec_neon(void *tx_queue,
}
static __rte_always_inline void
-sxe2_rx_desc_ptype_fill_neon(uint16x8_t staterr, struct rte_mbuf **__rte_restrict rx_pkts)
+sxe2_rx_desc_ptype_fill_neon(uint32x4_t desc_lo,
+ struct rte_mbuf **__rte_restrict rx_pkts,
+ const uint32_t *__rte_restrict ptype_tbl)
{
- uint16x8_t ptype_mask = {
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
- 0, 0x3FFULL,
+ const uint32x4_t ptype_mask = {
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
+ SXE2_RX_DESC_PTYPE_MASK_NO_SHIFT << 16,
};
uint16x8_t ptype_all;
- ptype_all = vandq_u16(staterr, ptype_mask);
+ ptype_all = vreinterpretq_u16_u32(vandq_u32(desc_lo, ptype_mask));
- rx_pkts[3]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
- rx_pkts[2]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
- rx_pkts[1]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
- rx_pkts[0]->packet_type = sxe2_ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[0]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 1)];
+ rx_pkts[1]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 3)];
+ rx_pkts[2]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 5)];
+ rx_pkts[3]->packet_type = ptype_tbl[vgetq_lane_u16(ptype_all, 7)];
}
static __rte_always_inline uint32x4_t
@@ -208,9 +273,10 @@ sxe2_rx_desc_fnav_flags_neon(uint64x2_t descs_arr[4])
static __rte_always_inline void
sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
volatile union sxe2_rx_desc *desc,
- uint64x2_t descs[4], struct rte_mbuf **rx_pkts)
+ uint64x2_t descs[4], uint32x4_t desc_lo, uint32x4_t desc_hi,
+ struct rte_mbuf **rx_pkts)
{
- uint32x4_t desc_lo, desc_hi, flags, tmp_flags;
+ uint32x4_t flags, tmp_flags;
const uint64x2_t mbuf_init = {rxq->mbuf_init_value, 0};
uint64x2_t rearm0, rearm1, rearm2, rearm3;
@@ -267,23 +333,6 @@ sxe2_rx_desc_offloads_para_fill_neon(struct sxe2_rx_queue *rxq,
0, 0, 0, 0, 0, 0, 0, 0
};
- {
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint64x2_t f64, t64;
-
- flags = vzip2q_u32(d1, d0);
- tmp_flags = vzip2q_u32(d3, d2);
- f64 = vreinterpretq_u64_u32(flags);
- t64 = vreinterpretq_u64_u32(tmp_flags);
- desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(f64),
- vget_low_u64(t64)));
- desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(f64),
- vget_high_u64(t64)));
- }
-
desc_lo = vandq_u32(desc_lo, desc_msk);
desc_hi = vandq_u32(desc_hi, rss_msk);
@@ -442,25 +491,39 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
uint64x2_t descs[SXE2_RX_NUM_PER_LOOP_NEON];
uint8x16_t pkt_mb1, pkt_mb2, pkt_mb3, pkt_mb4;
uint64x2_t mbp1, mbp2;
+ uint32x4_t desc_lo, desc_hi;
uint16x8_t staterr;
uint16x8_t tmp;
uint16_t bit_num;
descs[3] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 3));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[2] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 2));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[1] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc + 1));
- rte_atomic_thread_fence(rte_memory_order_acquire);
descs[0] = vld1q_u64(RTE_CAST_PTR(uint64_t *, desc));
rte_atomic_thread_fence(rte_memory_order_acquire);
-
descs[3] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 3), descs[3], 0);
descs[2] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 2), descs[2], 0);
descs[1] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc + 1), descs[1], 0);
descs[0] = vld1q_lane_u64(RTE_CAST_PTR(uint64_t *, desc), descs[0], 0);
+ {
+ uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
+ uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
+ uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
+ uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
+
+ uint32x4_t q1_01 = vzip2q_u32(d0, d1);
+ uint32x4_t q1_23 = vzip2q_u32(d2, d3);
+ uint64x2_t q1_01_64 = vreinterpretq_u64_u32(q1_01);
+ uint64x2_t q1_23_64 = vreinterpretq_u64_u32(q1_23);
+
+ desc_lo = vreinterpretq_u32_u64(vcombine_u64(vget_low_u64(q1_01_64),
+ vget_low_u64(q1_23_64)));
+ desc_hi = vreinterpretq_u32_u64(vcombine_u64(vget_high_u64(q1_01_64),
+ vget_high_u64(q1_23_64)));
+ }
+
mbp1 = vld1q_u64((uint64_t *)&buffer[i]);
mbp2 = vld1q_u64((uint64_t *)&buffer[i + 2]);
@@ -480,7 +543,8 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
pkt_mb1 = vqtbl1q_u8(vreinterpretq_u8_u64(descs[0]), rvp_shuf_mask);
if (do_offload) {
- sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, &rx_pkts[i]);
+ sxe2_rx_desc_offloads_para_fill_neon(rxq, desc, descs, desc_lo,
+ desc_hi, &rx_pkts[i]);
} else {
const uint64x2_t mbuf_init = {
rxq->mbuf_init_value,
@@ -515,55 +579,48 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
rte_prefetch_non_temporal(desc + SXE2_RX_NUM_PER_LOOP_NEON);
{
- uint32x4_t d0 = vreinterpretq_u32_u64(descs[0]);
- uint32x4_t d1 = vreinterpretq_u32_u64(descs[1]);
- uint32x4_t d2 = vreinterpretq_u32_u64(descs[2]);
- uint32x4_t d3 = vreinterpretq_u32_u64(descs[3]);
- uint32x4_t sterr_tmp1 = vzip2q_u32(d1, d0);
- uint32x4_t sterr_tmp2 = vzip2q_u32(d3, d2);
- uint32x4_t sterr_u32 = vzip1q_u32(sterr_tmp1, sterr_tmp2);
-
- staterr = vreinterpretq_u16_u32(sterr_u32);
+ uint16x8_t sterr_tmp1 = vzip2q_u16(vreinterpretq_u16_u64(descs[0]),
+ vreinterpretq_u16_u64(descs[2]));
+ uint16x8_t sterr_tmp2 = vzip2q_u16(vreinterpretq_u16_u64(descs[1]),
+ vreinterpretq_u16_u64(descs[3]));
+ staterr = vzip1q_u16(sterr_tmp1, sterr_tmp2);
}
- sxe2_rx_desc_ptype_fill_neon(staterr, &rx_pkts[i]);
+ sxe2_rx_desc_ptype_fill_neon(desc_lo, &rx_pkts[i], sxe2_ptype_tbl);
if (umbcast_flags != NULL) {
- uint32x4_t umbcast_mask = {
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- SXE2_RX_DESC_STATUS_UMBCAST_MASK, SXE2_RX_DESC_STATUS_UMBCAST_MASK,
- };
-
+ const uint32x4_t umbcast_mask =
+ vdupq_n_u32(SXE2_RX_DESC_STATUS_UMBCAST_MASK);
uint8x16_t umbcast_shuf_mask = {
- 0x0B, 0x03, 0x0F, 0x07,
+ 3, 7, 11, 15,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
};
uint8x16_t umbcast_bits =
- vreinterpretq_u8_u32(vandq_u32(vreinterpretq_u32_u16(staterr),
- umbcast_mask));
+ vreinterpretq_u8_u32(vandq_u32(desc_lo, umbcast_mask));
umbcast_bits = vqtbl1q_u8(umbcast_bits, umbcast_shuf_mask);
- vst1q_lane_u32((uint32_t *)umbcast_flags,
- vreinterpretq_u32_u8(umbcast_bits), 0);
+ *(uint32_t *)umbcast_flags =
+ vgetq_lane_u32(vreinterpretq_u32_u8(umbcast_bits), 0);
umbcast_flags += SXE2_RX_NUM_PER_LOOP_NEON;
}
if (split_rxe_flags) {
uint8x16_t eop_shuf_mask = {
- 0x08, 0x00, 0x0C, 0x04,
+ 0, 2, 4, 6,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF};
uint8x16_t eop_bits;
uint32x4_t rxe_mask = {
- 0x2080, 0x2080, 0x2080, 0x2080
+ 0x20802080, 0x20802080, 0x20802080, 0x20802080
};
uint32x4_t rxe_bits;
uint32x4_t eop_mask;
- eop_mask = vshlq_n_u32(vdupq_n_u32(1), SXE2_RX_DESC_STATUS_EOP_SHIFT);
+ eop_mask = vdupq_n_u32((1U << SXE2_RX_DESC_STATUS_EOP_SHIFT) |
+ (1U << (SXE2_RX_DESC_STATUS_EOP_SHIFT + 16)));
eop_bits = vandq_u8(vmvnq_u8(vreinterpretq_u8_u16(staterr)),
vreinterpretq_u8_u32(eop_mask));
@@ -587,12 +644,22 @@ sxe2_rx_pkts_common_vec_neon(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkt
}
{
- uint32x4_t dd_mask = vdupq_n_u32(1);
- uint32x4_t sterr_dd = vandq_u32(vreinterpretq_u32_u16(staterr), dd_mask);
- uint16x4_t packed_lo = vmovn_u32(sterr_dd);
- uint64_t dd64 = vget_lane_u64(vreinterpret_u64_u16(packed_lo), 0);
-
- bit_num = (uint16_t)rte_popcount64(dd64);
+ const uint16x8_t dd_check = {
+ 0x0001, 0x0001, 0x0001, 0x0001,
+ 0, 0, 0, 0
+ };
+ uint16x8_t sterr_dd;
+ uint64_t stat;
+ sterr_dd = vandq_u16(staterr, dd_check);
+ sterr_dd = vshlq_n_u16(sterr_dd, 15);
+ sterr_dd =
+ vreinterpretq_u16_s16(vshrq_n_s16(vreinterpretq_s16_u16(sterr_dd),
+ 15));
+ stat = ~vgetq_lane_u64(vreinterpretq_u64_u16(sterr_dd), 0);
+ if (likely(stat == 0))
+ bit_num = SXE2_RX_NUM_PER_LOOP_NEON;
+ else
+ bit_num = (uint16_t)(rte_ctz64(stat) / 16);
}
done_num += bit_num;
if (likely(bit_num != SXE2_RX_NUM_PER_LOOP_NEON))
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_sse.c b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
index c3e8a2983b..181bb40041 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec_sse.c
+++ b/drivers/net/sxe2/sxe2_txrx_vec_sse.c
@@ -40,7 +40,7 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
uint16_t nb_pkts, bool with_offloads)
{
volatile union sxe2_tx_data_desc *desc;
- struct sxe2_tx_buffer *buffer;
+ struct sxe2_tx_buffer_vec *buffer;
uint16_t next_use;
uint16_t res_num;
uint16_t tx_num;
@@ -57,11 +57,11 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
tx_num = nb_pkts;
next_use = txq->next_use;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
txq->desc_free_num -= nb_pkts;
res_num = txq->ring_depth - txq->next_use;
if (tx_num >= res_num) {
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, res_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, res_num);
for (i = 0; i < res_num - 1; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
@@ -74,9 +74,9 @@ sxe2_tx_pkts_vec_sse_batch(struct sxe2_tx_queue *txq,
next_use = 0;
txq->next_rs = txq->rs_thresh - 1;
desc = &txq->desc_ring[next_use];
- buffer = &txq->buffer_ring[next_use];
+ buffer = &txq->buffer_ring_vec[next_use];
}
- sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+ sxe2_tx_pkts_mbuf_fill_vec(buffer, tx_pkts, tx_num);
for (i = 0; i < tx_num; ++i, ++tx_pkts, ++desc) {
sxe2_tx_desc_fill_one_sse(desc, *tx_pkts,
SXE2_TX_DATA_DESC_CMD_EOP,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 31/45] net/sxe2: refine vectorized Tx/Rx mode setup
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (30 preceding siblings ...)
2026-08-28 7:39 ` [PATCH v6 30/45] net/sxe2: unify vectorized Tx buffer handling liujie5
@ 2026-08-28 7:39 ` liujie5
2026-08-28 7:39 ` [PATCH v6 32/45] net/sxe2: fix RSS action attribute validation liujie5
` (13 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Set rte_eth_tx_pkt_prepare_dummy for the simple and vectorized Tx paths
instead of leaving the prepare callback unset, and split the NEON
simple/offload mode selection based on the offload flag. Log the selected
Tx/Rx mode flags and apply the default Rx free threshold when the
configured value is zero.
Fixes: ac60f302cbef ("net/sxe2: add vectorized Rx and Tx")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_rx.c | 3 ++-
drivers/net/sxe2/sxe2_txrx.c | 20 +++++++++++++++-----
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_rx.c b/drivers/net/sxe2/sxe2_rx.c
index d700c60083..3830c676d7 100644
--- a/drivers/net/sxe2/sxe2_rx.c
+++ b/drivers/net/sxe2/sxe2_rx.c
@@ -319,7 +319,8 @@ int32_t __rte_cold sxe2_rx_queue_setup(struct rte_eth_dev *dev,
rxq->mb_pool = mp;
}
- rxq->rx_free_thresh = rx_conf->rx_free_thresh;
+ rxq->rx_free_thresh = (rx_conf->rx_free_thresh == 0) ?
+ SXE2_DEFAULT_RX_FREE_THRESH : rx_conf->rx_free_thresh;
rxq->port_id = dev->data->port_id;
rxq->offloads = offloads;
if (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
diff --git a/drivers/net/sxe2/sxe2_txrx.c b/drivers/net/sxe2/sxe2_txrx.c
index 79870866d1..f7276f6a19 100644
--- a/drivers/net/sxe2/sxe2_txrx.c
+++ b/drivers/net/sxe2/sxe2_txrx.c
@@ -358,7 +358,7 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
if (tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
#ifdef RTE_ARCH_X86
if (tx_mode_flags & SXE2_TX_MODE_VEC_AVX512) {
#ifdef CC_AVX512_SUPPORT
@@ -386,21 +386,28 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
}
#elif defined(RTE_ARCH_ARM64)
if (tx_mode_flags & SXE2_TX_MODE_VEC_NEON) {
- dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
+ if (tx_mode_flags & SXE2_TX_MODE_VEC_OFFLOAD) {
+ dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon;
+ } else {
+ dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ }
} else {
- dev->tx_pkt_burst = sxe2_tx_pkts_vec_neon_simple;
+ dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
+ dev->tx_pkt_burst = sxe2_tx_pkts;
}
#endif
} else {
if (tx_mode_flags & SXE2_TX_MODE_SIMPLE_BATCH) {
- dev->tx_pkt_prepare = NULL;
+ dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;
dev->tx_pkt_burst = sxe2_tx_pkts_simple;
} else {
dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
dev->tx_pkt_burst = sxe2_tx_pkts;
}
}
+ PMD_LOG_DEBUG(TX, "Tx mode flags:0x%016x port_id:%u.",
+ tx_mode_flags, dev->data->port_id);
}
static const struct {
@@ -582,6 +589,9 @@ void sxe2_rx_mode_func_set(struct rte_eth_dev *dev)
dev->rx_pkt_burst = sxe2_rx_pkts_scattered_split;
else
dev->rx_pkt_burst = sxe2_rx_pkts_scattered;
+
+ PMD_LOG_DEBUG(RX, "Rx mode flags:0x%016x port_id:%u.",
+ rx_mode_flags, dev->data->port_id);
}
static const struct {
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 32/45] net/sxe2: fix RSS action attribute validation
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (31 preceding siblings ...)
2026-08-28 7:39 ` [PATCH v6 31/45] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
@ 2026-08-28 7:39 ` liujie5
2026-08-28 7:39 ` [PATCH v6 33/45] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
` (12 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The rss->level/key_len/queue_num checks only set the rte_flow_error
but still return 0 (success), so invalid RSS configurations are
accepted instead of being rejected with ENOTSUP.
Return the error code from the validation checks, matching the
behavior in the V3 implementation.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_flow_parse_action.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_flow_parse_action.c b/drivers/net/sxe2/sxe2_flow_parse_action.c
index db70b146c6..b0275321be 100644
--- a/drivers/net/sxe2/sxe2_flow_parse_action.c
+++ b/drivers/net/sxe2/sxe2_flow_parse_action.c
@@ -12,7 +12,7 @@
static int32_t sxe2_flow_check_rss_action_attr(const struct rte_flow_action_rss *rss,
struct rte_flow_error *error)
{
- int32_t ret = ENOTSUP;
+ int32_t ret = -ENOTSUP;
switch (rss->func) {
case RTE_ETH_HASH_FUNCTION_DEFAULT:
case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
@@ -25,15 +25,21 @@ static int32_t sxe2_flow_check_rss_action_attr(const struct rte_flow_action_rss
goto l_end;
}
- if (rss->level > 2)
+ if (rss->level > 2) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"RSS level is could not be greater than 2");
- if (rss->key_len)
+ goto l_end;
+ }
+ if (rss->key_len) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a nonzero RSS key_len is not supported");
- if (rss->queue_num)
+ goto l_end;
+ }
+ if (rss->queue_num) {
rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL,
"a non-NULL RSS queue is not supported");
+ goto l_end;
+ }
ret = 0;
l_end:
return ret;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 33/45] net/sxe2: restore PF-only guard in udp tunnel port add
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (32 preceding siblings ...)
2026-08-28 7:39 ` [PATCH v6 32/45] net/sxe2: fix RSS action attribute validation liujie5
@ 2026-08-28 7:39 ` liujie5
2026-08-28 7:39 ` [PATCH v6 34/45] net/sxe2: restore link update call in status query liujie5
` (11 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_udp_tunnel_port_add_common() lost the check that restricts
UDP tunnel port configuration to PF devices (not VF or
representor), so VF/representor devices can now attempt to add
UDP tunnel ports, which the hardware does not support.
Restore the PF-only guard returning -ENOTSUP, matching the V3
implementation.
Fixes: fff24885f70a ("net/sxe2: support custom UDP tunnel ports")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 77a31eb8a1..8c60c9cfde 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -630,6 +630,10 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
struct sxe2_udp_tunnel_cfg *tunnel_config;
int32_t ret = -1;
+ if (ad->dev_type != SXE2_DEV_T_PF || ad->is_dev_repr) {
+ ret = -ENOTSUP;
+ goto l_end;
+ }
rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
tunnel_config = &ad->udp_tunnel_ctx.tunnel_conf[tunnel_proto];
@@ -659,6 +663,7 @@ int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
l_unlock_end:
rte_spinlock_unlock(&ad->udp_tunnel_ctx.lock);
+l_end:
return ret;
}
@@ -669,6 +674,9 @@ int32_t sxe2_udp_tunnel_port_del_common(struct sxe2_adapter *ad,
struct sxe2_udp_tunnel_cfg *tunnel_config;
int32_t ret = -1;
+ if (ad->dev_type != SXE2_DEV_T_PF || ad->is_dev_repr)
+ return -ENOTSUP;
+
rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
tunnel_config = &ad->udp_tunnel_ctx.tunnel_conf[tunnel_proto];
@@ -703,6 +711,9 @@ static int32_t sxe2_udp_tunnel_port_clear(struct rte_eth_dev *dev)
int32_t ret = 0;
uint16_t tunnel_proto = 0;
+ if (ad->dev_type != SXE2_DEV_T_PF || ad->is_dev_repr)
+ return -ENOTSUP;
+
rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
for (tunnel_proto = 0; tunnel_proto < SXE2_UDP_TUNNEL_MAX; tunnel_proto++) {
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 34/45] net/sxe2: restore link update call in status query
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (33 preceding siblings ...)
2026-08-28 7:39 ` [PATCH v6 33/45] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
@ 2026-08-28 7:39 ` liujie5
2026-08-28 7:39 ` [PATCH v6 35/45] net/sxe2: validate representor ID against VF count liujie5
` (10 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_mac_link_status_get() no longer calls sxe2_link_update()
after refreshing the link context, so the ethdev link state is only
refreshed during device init (sxe2_link_update_init) and never
updated when link status is queried at runtime, including on LSC
interrupt events.
Move the sxe2_link_update() call back into
sxe2_drv_mac_link_status_get() and simplify sxe2_link_update_init()
accordingly, matching the V3 implementation.
Fixes: 1d7fd921beef ("net/sxe2: support link update")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_irq.c | 2 ++
drivers/net/sxe2/sxe2_mac.c | 11 +++--------
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
index 4e5339e24b..b0e1552d5f 100644
--- a/drivers/net/sxe2/sxe2_irq.c
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -84,6 +84,7 @@ static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t
if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
PMD_DEV_LOG_INFO(adapter, DRV, "OICR=0x%" PRIx64, oicr);
(void)sxe2_drv_mac_link_status_get(adapter);
+ (void)sxe2_link_update(dev, 0);
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_LSC,
@@ -96,6 +97,7 @@ static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t
continue;
repr_adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(repr_eth_dev);
(void)sxe2_drv_mac_link_status_get(repr_adapter);
+ (void)sxe2_link_update(repr_eth_dev, 0);
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
rte_eth_dev_callback_process(repr_eth_dev,
RTE_ETH_EVENT_INTR_LSC,
diff --git a/drivers/net/sxe2/sxe2_mac.c b/drivers/net/sxe2/sxe2_mac.c
index 729c804ac3..ab9bd5355b 100644
--- a/drivers/net/sxe2/sxe2_mac.c
+++ b/drivers/net/sxe2/sxe2_mac.c
@@ -448,18 +448,13 @@ int32_t sxe2_link_update_init(struct rte_eth_dev *dev)
int32_t ret;
PMD_INIT_FUNC_TRACE();
-
rte_spinlock_init(&adapter->link_ctxt.link_lock);
-
ret = sxe2_drv_mac_link_status_get(adapter);
- if (ret) {
+ if (ret)
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to get link status, ret=%d", ret);
- goto l_end;
- }
-
- (void)sxe2_link_update(dev, 0);
+ else
+ (void)sxe2_link_update(dev, 0);
-l_end:
return ret;
}
int32_t sxe2_link_update(struct rte_eth_dev *dev, __rte_unused int32_t wait_to_complete)
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 35/45] net/sxe2: validate representor ID against VF count
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (34 preceding siblings ...)
2026-08-28 7:39 ` [PATCH v6 34/45] net/sxe2: restore link update call in status query liujie5
@ 2026-08-28 7:39 ` liujie5
2026-08-28 7:40 ` [PATCH v6 36/45] net/sxe2: use primary VSI ID for representor VSI liujie5
` (9 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:39 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_switchdev_repr_private_data_init() indexes
parent_adapter->repr_ctxt.repr_vf_id[repr_id] without checking that
repr_id is within the number of configured VFs, which can access out
of bounds when an invalid representor ID is passed.
Add a bounds check on repr_id against repr_ctxt.nb_vf and return
-EINVAL on the error path.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_switchdev.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index efb1468b91..d0304ccc94 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -312,6 +312,12 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_q_id = repr_id;
repr_priv_data->repr_pf_id = parent_adapter->pf_idx;
repr_priv_data->repr_vf_id = repr_id;
+ if (repr_id >= parent_adapter->repr_ctxt.nb_vf) {
+ PMD_LOG_ERR(INIT, "repr_id %u exceed max vf %u",
+ repr_id, parent_adapter->repr_ctxt.nb_vf);
+ ret = -EINVAL;
+ goto l_free;
+ }
repr_priv_data->repr_vf_primary_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id;
repr_priv_data->repr_vf_backup_vsi_id =
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 36/45] net/sxe2: use primary VSI ID for representor VSI
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (35 preceding siblings ...)
2026-08-28 7:39 ` [PATCH v6 35/45] net/sxe2: validate representor ID against VF count liujie5
@ 2026-08-28 7:40 ` liujie5
2026-08-28 7:40 ` [PATCH v6 37/45] net/sxe2: wrap command params fill debug log in macro liujie5
` (8 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
repr_priv_data->repr_vf_vsi_id is assigned with a ternary that falls
back to the backup (dpdk) VSI ID when the kernel VSI ID is invalid.
The V3 implementation assigns it directly from
repr_vf_primary_vsi_id.
Align with the V3 implementation by assigning repr_vf_vsi_id from
repr_vf_primary_vsi_id.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_switchdev.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_switchdev.c b/drivers/net/sxe2/sxe2_switchdev.c
index d0304ccc94..81ced7b855 100644
--- a/drivers/net/sxe2/sxe2_switchdev.c
+++ b/drivers/net/sxe2/sxe2_switchdev.c
@@ -323,11 +323,7 @@ int32_t sxe2_switchdev_repr_private_data_init(struct rte_eth_dev *dev,
repr_priv_data->repr_vf_backup_vsi_id =
parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
- repr_priv_data->repr_vf_vsi_id =
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id !=
- SXE2_INVALID_VSI_ID ?
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].kernel_vsi_id :
- parent_adapter->repr_ctxt.repr_vf_id[repr_id].dpdk_vsi_id;
+ repr_priv_data->repr_vf_vsi_id = repr_priv_data->repr_vf_primary_vsi_id;
adapter->repr_priv_data = repr_priv_data;
goto l_end;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 37/45] net/sxe2: wrap command params fill debug log in macro
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (36 preceding siblings ...)
2026-08-28 7:40 ` [PATCH v6 36/45] net/sxe2: use primary VSI ID for representor VSI liujie5
@ 2026-08-28 7:40 ` liujie5
2026-08-28 7:40 ` [PATCH v6 38/45] net/sxe2: restore Rx queue buffer split fill support liujie5
` (7 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_cmd_params_fill() passes the opcode string as a
parameter to __sxe2_drv_cmd_params_fill() just to emit a debug
log. The debug log is level-gated by PMD_DEV_LOG_DEBUG either
way; moving it into the macro body only consolidates the call
sites.
Wrap the log and the fill helper in a do/while block, dropping
the opc_str parameter so the opcode stringization happens at
the call site. Evaluate the adapter argument exactly once
through a local variable.
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 16a2c3fea4..84fe401ec4 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -26,10 +26,9 @@ static void sxe2_drv_trace_id_alloc(uint64_t *trace_id)
}
static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
- struct sxe2_drv_cmd_params *cmd, uint32_t opc, const char *opc_str,
+ struct sxe2_drv_cmd_params *cmd, uint32_t opc,
void *in_data, uint32_t in_len, void *out_data, uint32_t out_len)
{
- PMD_DEV_LOG_DEBUG(adapter, DRV, "cmd opcode:%s", opc_str);
cmd->timeout = SXE2_DRV_CMD_DFLT_TIMEOUT;
cmd->opcode = opc;
cmd->vsi_id = adapter->vsi_ctxt.dpdk_vsi_id;
@@ -44,8 +43,11 @@ static void __sxe2_drv_cmd_params_fill(struct sxe2_adapter *adapter,
}
#define sxe2_drv_cmd_params_fill(adapter, cmd, opc, in_data, in_len, out_data, out_len) \
- __sxe2_drv_cmd_params_fill(adapter, cmd, opc, #opc, in_data, in_len, out_data, out_len)
-
+ do { \
+ struct sxe2_adapter *__adapter = (adapter); \
+ PMD_DEV_LOG_DEBUG(__adapter, DRV, "cmd opcode:%s", #opc); \
+ __sxe2_drv_cmd_params_fill(__adapter, cmd, opc, in_data, in_len, out_data, out_len); \
+ } while (0)
int32_t sxe2_drv_dev_caps_get(struct sxe2_adapter *adapter, struct sxe2_drv_dev_caps_resp *dev_caps)
{
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 38/45] net/sxe2: restore Rx queue buffer split fill support
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (37 preceding siblings ...)
2026-08-28 7:40 ` [PATCH v6 37/45] net/sxe2: wrap command params fill debug log in macro liujie5
@ 2026-08-28 7:40 ` liujie5
2026-08-28 7:40 ` [PATCH v6 39/45] net/sxe2: skip tunnel config fill on get failure liujie5
` (6 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The V4 branch dropped sxe2_rxq_buf_split_fill() and the buffer split
handling in sxe2_rxq_ctxt_cfg_fill(), so the Rx buffer split offload
(RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) is advertised in device info but
the per-queue context never configures split_en/split_type_mask/
hdr_len, and buffer split packets are not handled correctly.
Restore the sxe2_rxq_buf_split_fill() helper and the buffer split
branch in sxe2_rxq_ctxt_cfg_fill(), matching the V3 implementation.
Fixes: d8e4e075acb4 ("net/sxe2: add probing skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 88 ++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 84fe401ec4..3998309bb1 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -195,6 +195,84 @@ int32_t sxe2_drv_vsi_del(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi)
#define SXE2_RXQ_CTXT_CFG_BUF_LEN_ALIGN (1 << 7)
#define SXE2_RX_HDR_SIZE 256
+static int32_t sxe2_rxq_buf_split_fill(struct sxe2_rx_queue *rxq,
+ struct sxe2_drv_rxq_ctxt *ctxt)
+{
+ uint32_t proto_hdr;
+
+ proto_hdr = rxq->rx_seg[0].proto_hdr;
+ if (proto_hdr == RTE_PTYPE_UNKNOWN) {
+ PMD_LOG_ERR(RX, "Buffer split protocol must be configured");
+ return -EINVAL;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L4_MASK) {
+ case RTE_PTYPE_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_TCP;
+ goto l_end;
+ case RTE_PTYPE_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_UDP;
+ goto l_end;
+ case RTE_PTYPE_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_L4_SCTP;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L3_MASK) {
+ case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV4;
+ goto l_end;
+ case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_L3_IPV6;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_L2_MASK) {
+ case RTE_PTYPE_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_L2_ETHER;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L4_MASK) {
+ case RTE_PTYPE_INNER_L4_TCP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_TCP;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_UDP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_UDP;
+ goto l_end;
+ case RTE_PTYPE_INNER_L4_SCTP:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L4_SCTP;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L3_MASK) {
+ case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV4;
+ goto l_end;
+ case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L3_IPV6;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_INNER_L2_MASK) {
+ case RTE_PTYPE_INNER_L2_ETHER:
+ ctxt->split_type_mask = SXE2_PTYPE_INNER_L2_ETHER;
+ goto l_end;
+ }
+
+ switch (proto_hdr & RTE_PTYPE_TUNNEL_MASK) {
+ case RTE_PTYPE_TUNNEL_GRENAT:
+ ctxt->split_type_mask = SXE2_PTYPE_TUNNEL_GRENAT;
+ goto l_end;
+ }
+
+ PMD_LOG_ERR(RX, "Buffer split protocol is not supported");
+ return -ENOTSUP;
+l_end:
+ ctxt->hdr_len = SXE2_RX_HDR_SIZE;
+ return 0;
+}
+
static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
struct sxe2_drv_rxq_cfg_req *req, uint16_t rxq_cnt)
{
@@ -228,7 +306,17 @@ static int32_t sxe2_rxq_ctxt_cfg_fill(struct sxe2_rx_queue *rxq,
else
ctxt->keep_crc_en = 0;
+ if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
+ ret = sxe2_rxq_buf_split_fill(rxq, ctxt);
+ if (ret)
+ goto l_end;
+ ctxt->split_en = 1;
+ } else {
+ ctxt->split_en = 0;
+ }
+
ctxt->desc_size = sizeof(union sxe2_rx_desc);
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 39/45] net/sxe2: skip tunnel config fill on get failure
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (38 preceding siblings ...)
2026-08-28 7:40 ` [PATCH v6 38/45] net/sxe2: restore Rx queue buffer split fill support liujie5
@ 2026-08-28 7:40 ` liujie5
2026-08-28 7:40 ` [PATCH v6 40/45] net/sxe2: skip flow id assignment on filter add failure liujie5
` (5 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_udp_tunnel_get() fills tunnel_config fields even when the
firmware command fails, so a failed get overwrites the config with
the (zero-initialized) response data instead of leaving it intact.
Return early with the error code when sxe2_drv_cmd_exec() fails,
matching the V3 implementation.
Fixes: fff24885f70a ("net/sxe2: support custom UDP tunnel ports")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 3998309bb1..581026e81d 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1650,15 +1650,17 @@ int32_t sxe2_drv_udp_tunnel_get(struct sxe2_adapter *adapter,
&req, sizeof(req),
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_LOG_ERR(DRV, "Failed to get udp proto %d port, ret=%d", req.type, ret);
+ goto l_end;
+ }
tunnel_config->fw_port = resp.port;
tunnel_config->fw_status = resp.enable;
tunnel_config->fw_dst_en = resp.dst;
tunnel_config->fw_src_en = resp.src;
tunnel_config->fw_used = resp.fw_used;
-
+l_end:
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 40/45] net/sxe2: skip flow id assignment on filter add failure
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (39 preceding siblings ...)
2026-08-28 7:40 ` [PATCH v6 39/45] net/sxe2: skip tunnel config fill on get failure liujie5
@ 2026-08-28 7:40 ` liujie5
2026-08-28 7:40 ` [PATCH v6 41/45] net/sxe2: fix command channel log messages liujie5
` (4 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
sxe2_drv_flow_filter_add() assigns flow->flow_id from the response
even when the firmware command fails, overwriting any previously
set flow id with the zero-initialized response value.
Return early on command failure so flow->flow_id is preserved, and
set flow->create_err on both the success and error paths.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 581026e81d..89829f29be 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1818,9 +1818,13 @@ int32_t sxe2_drv_flow_filter_add(struct sxe2_adapter *adapter, struct sxe2_flow
sxe2_drv_cmd_params_fill(adapter, &cmd, SXE2_DRV_CMD_FLOW_FILTER_ADD, &req,
sizeof(req), &resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, &cmd);
- if (ret)
+ if (ret) {
PMD_DEV_LOG_ERR(adapter, DRV, "Failed to add flow filter, ret: %d.", ret);
+ goto l_end;
+ }
flow->flow_id = resp.flow_id;
+
+l_end:
flow->create_err = ret;
return ret;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 41/45] net/sxe2: fix command channel log messages
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (40 preceding siblings ...)
2026-08-28 7:40 ` [PATCH v6 40/45] net/sxe2: skip flow id assignment on filter add failure liujie5
@ 2026-08-28 7:40 ` liujie5
2026-08-28 7:40 ` [PATCH v6 42/45] net/sxe2: align command structs with historical kernel layout liujie5
` (3 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Several error/warning messages in sxe2_cmd_chnl.c are inaccurate or
lost context:
- vsi_info_get: message lost the vsi id; restore it
- rxq_bind_irq/rxq_unbind_irq: message lost the rxq index; restore it
- promisc_config: fix "promic" typo in the message
- queue_info_get_update/rxq_mapping_set: incorrect "get queue info
map"/"get dev caps" wording; use "rx queue mapping failed"
- txq_mapping_set: "Rx queue" should read "Tx queue"; incorrect
"get dev caps" wording should read "tx queue mapping failed"
Fixes: a2b79a93515e ("net/sxe2: support L2 filtering and MAC config")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_cmd_chnl.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 89829f29be..0d81da542e 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -481,7 +481,7 @@ int32_t sxe2_drv_vsi_info_get(struct sxe2_adapter *adapter, struct sxe2_vsi *vsi
&vsi_info_get_resp, sizeof(vsi_info_get_resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_DEV_LOG_ERR(adapter, DRV, "switchdev cpvsi info get failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "vsi %u info get failed, ret=%d", vsi->vsi_id, ret);
goto l_end;
}
@@ -537,7 +537,7 @@ int32_t sxe2_drv_rxq_bind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx, ui
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq bind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u bind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -557,7 +557,7 @@ int32_t sxe2_drv_rxq_unbind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx)
NULL, 0);
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_ERR(adapter, DRV, "rxq unbind irq failed, ret=%d", ret);
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq %u unbind irq failed, ret=%d", rxq_idx, ret);
return ret;
}
@@ -758,7 +758,7 @@ int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set)
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_DEV_LOG_WARN(adapter, DRV, "promic config failed, ret=%d", ret);
+ PMD_DEV_LOG_WARN(adapter, DRV, "promisc config failed, ret=%d", ret);
return ret;
}
@@ -1683,7 +1683,7 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_
&resp, sizeof(resp));
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret) {
- PMD_LOG_ERR(DRV, "get queue info map failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
goto l_end;
}
@@ -1727,7 +1727,7 @@ int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
l_end:
return ret;
@@ -1744,7 +1744,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
txq = eth_dev->data->tx_queues[queue_id];
if (txq == NULL) {
- PMD_LOG_ERR(DRV, "Rx queue %u is not available or setup", queue_id);
+ PMD_LOG_ERR(DRV, "Tx queue %u is not available or setup", queue_id);
ret = -EINVAL;
goto l_end;
}
@@ -1758,7 +1758,7 @@ int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id,
ret = sxe2_drv_cmd_exec(cdev, ¶m);
if (ret)
- PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+ PMD_LOG_ERR(DRV, "tx queue mapping failed, ret=%d", ret);
l_end:
return ret;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 42/45] net/sxe2: align command structs with historical kernel layout
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (41 preceding siblings ...)
2026-08-28 7:40 ` [PATCH v6 41/45] net/sxe2: fix command channel log messages liujie5
@ 2026-08-28 7:40 ` liujie5
2026-08-28 7:40 ` [PATCH v6 43/45] common/sxe2: fix ioctl channel log and close handling liujie5
` (2 subsequent siblings)
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The sxe2_drv_cmd.h command structures must match the layout
used by historical SXE2 kernel versions so the same firmware
command ABI is shared. Several structures were declared with
__rte_packed_begin/__rte_packed_end and extra rsv padding that
the kernel layout does not have:
- sxe2_drv_link_info_resp: drop rsv[3] padding
- sxe2_tm_res: drop rsv[2] padding and packed attribute
- sxe2_tm_info: drop packed attribute
- sxe2_drv_sfp_req: drop packed attribute
- sxe2_drv_sfp_resp: drop packed attribute
sxe2_tm_add_mid_msg and sxe2_tm_add_queue_msg keep the packed
attribute so the firmware command wire offsets (tm info offset,
tm queue info offset) are preserved.
Keep the structure members as-is so the command ABI is
compatible with the historical kernel driver.
Fixes: 9c894f75113f ("net/sxe2: support TM hierarchy and shaping")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_drv_cmd.h | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index cc71e2364e..5274b59a6a 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -230,7 +230,6 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_vsi_info_get_resp {
struct __rte_aligned(4) __rte_packed_begin sxe2_drv_link_info_resp {
uint32_t speed;
uint8_t status;
- uint8_t rsv[3];
} __rte_packed_end;
struct __rte_aligned(4) __rte_packed_begin sxe2_switchdev_info {
@@ -348,18 +347,17 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_rss_hf_req {
uint8_t rsv1[3];
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_res {
+struct sxe2_tm_res {
uint16_t teid;
- uint8_t rsv[2];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_tm_info {
+struct sxe2_tm_info {
uint32_t committed;
uint32_t peak;
uint8_t priority;
uint8_t reserve;
uint16_t weight;
-} __rte_packed_end;
+};
struct __rte_aligned(4) __rte_packed_begin sxe2_tm_add_mid_msg {
uint16_t parent_teid;
@@ -633,7 +631,7 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_udp_tunnel_resp {
uint8_t rsv;
} __rte_packed_end;
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
+struct sxe2_drv_sfp_req {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t bus_addr;
@@ -642,14 +640,14 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_req {
uint16_t data_len;
uint16_t rvd;
uint8_t data[];
-} __rte_packed_end;
+};
-struct __rte_aligned(4) __rte_packed_begin sxe2_drv_sfp_resp {
+struct sxe2_drv_sfp_resp {
uint8_t is_wr;
uint8_t is_qsfp;
uint16_t data_len;
uint8_t data[];
-} __rte_packed_end;
+};
enum sxe2_fc_type {
SXE2_FC_T_DIS = 0,
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 43/45] common/sxe2: fix ioctl channel log and close handling
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (42 preceding siblings ...)
2026-08-28 7:40 ` [PATCH v6 42/45] net/sxe2: align command structs with historical kernel layout liujie5
@ 2026-08-28 7:40 ` liujie5
2026-08-28 7:40 ` [PATCH v6 44/45] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
2026-08-28 7:40 ` [PATCH v6 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
Compare sxe2_ioctl_chnl.c against the reference implementation and
fix the following discrepancies:
- sxe2_drv_dev_close: only log the closed fd when it is valid, move
PMD_LOG_INFO inside the fd >= 0 check
- sxe2_drv_dev_mmap: fix swapped format arguments in the debug log
(cmd_fd and bar_idx were passed in the wrong order)
- sxe2_drv_dev_dma_unmap: use PMD_LOG_ERR instead of PMD_LOG_INFO
for the ioctl failure message
Fixes: 83866f8d7638 ("common/sxe2: add base driver skeleton")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_ioctl_chnl.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index 3e2fbf572f..b006e296c6 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -107,9 +107,11 @@ sxe2_drv_dev_close(struct sxe2_common_device *cdev)
{
int32_t fd = SXE2_CDEV_TO_CMD_FD(cdev);
- if (fd >= 0)
+ if (fd >= 0) {
close(fd);
- PMD_LOG_INFO(COM, "closed device fd=%d", fd);
+ PMD_LOG_INFO(COM, "closed device fd=%d", fd);
+ }
+
SXE2_CDEV_TO_CMD_FD(cdev) = SXE2_CMD_FD_INVALID;
}
@@ -349,8 +351,8 @@ void
goto l_err;
}
- PMD_LOG_DEBUG(COM, "fd=%d, bar idx=%d, len=%"PRIu64", src=0x%"PRIx64", offset=0x%"PRIx64"",
- bar_idx, cmd_fd, len, offset, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
+ PMD_LOG_DEBUG(COM, "fd=%d, bar idx=%d, len=%"PRIu64", offset=0x%"PRIx64", pci_offset=0x%"PRIx64"",
+ cmd_fd, bar_idx, len, offset, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
virt = mmap(NULL, len, PROT_READ | PROT_WRITE,
MAP_SHARED, cmd_fd, SXE2_COM_PCI_OFFSET_GEN(bar_idx, offset));
@@ -477,7 +479,7 @@ sxe2_drv_dev_dma_unmap(struct sxe2_common_device *cdev, uint64_t iova)
pthread_mutex_lock(&cdev->config.lock);
ret = ioctl(cmd_fd, SXE2_COM_CMD_DMA_UNMAP, &cmd_params);
if (ret < 0) {
- PMD_LOG_INFO(COM, "Failed to dma unmap, fd=%d, ret=%d, err:%s",
+ PMD_LOG_ERR(COM, "Failed to dma unmap, fd=%d, ret=%d, err:%s",
cmd_fd, ret, strerror(errno));
ret = -EIO;
pthread_mutex_unlock(&cdev->config.lock);
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 44/45] doc/sxe2: remove drv-sw-stats parameter documentation
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (43 preceding siblings ...)
2026-08-28 7:40 ` [PATCH v6 43/45] common/sxe2: fix ioctl channel log and close handling liujie5
@ 2026-08-28 7:40 ` liujie5
2026-08-28 7:40 ` [PATCH v6 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
The drv-sw-stats devarg is no longer supported. Remove its
parameter description from the Runtime Configuration section.
The "Receive Software Statistics" xstats section is kept because
the rx_sw_* counters are still accumulated in the Rx data path
and reported through rte_eth_xstats_get().
Fixes: 9e95b2b3859c ("doc: update sxe2 guide and features")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
doc/guides/nics/sxe2.rst | 31 ++-----------------------------
1 file changed, 2 insertions(+), 29 deletions(-)
diff --git a/doc/guides/nics/sxe2.rst b/doc/guides/nics/sxe2.rst
index c5b400a8ba..fe4f9f916b 100644
--- a/doc/guides/nics/sxe2.rst
+++ b/doc/guides/nics/sxe2.rst
@@ -109,30 +109,6 @@ Runtime Configuration
Default value is 3 (count both packets and bytes).
-- ``drv-sw-stats`` parameter [int]
-
- This parameter controls whether per-packet software statistics (SW stats)
- are collected in the Rx data path.
-
- Hardware packet statistic counters may be inaccurate for certain packet types
- due to hardware design limitations.
- When accuracy of Rx packet classification statistics is critical,
- enabling this parameter allows the driver to accumulate statistics in software
- as packets are received, providing an alternative statistical path
- that bypasses hardware counter inaccuracies.
-
- - 0: Disable software statistics collection (default).
- The basic port statistics (``ipackets``, ``ibytes``) are reported
- from the hardware counters.
- - 1: Enable software statistics collection.
- Per-packet software statistics are accumulated for unicast,
- multicast, broadcast, and dropped packets in the Rx data path.
-
- When enabled, the following extended statistics (xstats) are available:
- ``rx_sw_unicast_packets``, ``rx_sw_multicast_packets``,
- ``rx_sw_broadcast_packets``, ``rx_sw_drop_packets``,
- and ``rx_sw_drop_bytes``.
-
- ``no-sched-mode`` parameter [int]
This parameter enables non-scheduling mode (no-sched mode).
@@ -208,8 +184,7 @@ reflect the actual packets processed by the driver.
Receive Software Statistics
These counters are collected in the Rx data path
- when ``drv-sw-stats=1`` is configured (see the ``drv-sw-stats`` devarg above).
- When ``drv-sw-stats`` is disabled (default), these xstats report zero.
+ on every received packet.
- ``rx_sw_unicast_packets``: Number of unicast packets received.
- ``rx_sw_multicast_packets``: Number of multicast packets received.
@@ -217,10 +192,8 @@ Receive Software Statistics
- ``rx_sw_drop_packets``: Number of packets dropped in the Rx data path.
- ``rx_sw_drop_bytes``: Number of bytes dropped in the Rx data path.
- When ``drv-sw-stats`` is enabled, the basic counters
- ``ipackets`` and ``ibytes`` (from ``rte_eth_stats``)
+ The basic counters ``ipackets`` and ``ibytes`` (from ``rte_eth_stats``)
also reflect the software-accumulated packet and byte counts.
- Otherwise, they are reported from hardware counters.
Fnav Flow Engine Statistics
The Fnav flow engine statistics type is controlled by
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* [PATCH v6 45/45] net/sxe2: remove ineffective queue counts in representor info
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
` (44 preceding siblings ...)
2026-08-28 7:40 ` [PATCH v6 44/45] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
@ 2026-08-28 7:40 ` liujie5
45 siblings, 0 replies; 207+ messages in thread
From: liujie5 @ 2026-08-28 7:40 UTC (permalink / raw)
To: stephen; +Cc: dev
From: Jie Liu <liujie5@linkdatatechnology.com>
rte_eth_dev_info_get() overwrites dev_info->nb_rx_queues and
dev_info->nb_tx_queues from dev->data after the PMD dev_infos_get
callback returns, so assigning them in sxe2_repr_dev_infos_get() has
no effect. Remove the ineffective assignments.
Fixes: 635084db5d57 ("net/sxe2: support VF representors")
Cc: stable@dpdk.org
Cc: stephen@networkplumber.org
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/net/sxe2/sxe2_ethdev_repr.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/sxe2/sxe2_ethdev_repr.c b/drivers/net/sxe2/sxe2_ethdev_repr.c
index b7096f5927..ec45187dc9 100644
--- a/drivers/net/sxe2/sxe2_ethdev_repr.c
+++ b/drivers/net/sxe2/sxe2_ethdev_repr.c
@@ -127,7 +127,7 @@ static int32_t sxe2_repr_dev_close(struct rte_eth_dev *dev)
return 0;
}
-static int32_t sxe2_repr_dev_infos_get(struct rte_eth_dev *dev,
+static int32_t sxe2_repr_dev_infos_get(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info)
{
dev_info->max_rx_queues = 1;
@@ -195,8 +195,6 @@ static int32_t sxe2_repr_dev_infos_get(struct rte_eth_dev *dev,
dev_info->speed_capa = RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G |
RTE_ETH_LINK_SPEED_50G | RTE_ETH_LINK_SPEED_100G;
- dev_info->nb_rx_queues = dev->data->nb_rx_queues;
- dev_info->nb_tx_queues = dev->data->nb_tx_queues;
dev_info->default_rxportconf.burst_size = SXE2_RX_MAX_BURST;
dev_info->default_txportconf.burst_size = SXE2_TX_MAX_BURST;
--
2.52.0
^ permalink raw reply related [flat|nested] 207+ messages in thread
* Re: [PATCH v6 00/45] net/sxe2: update SXE2 poll mode driver
2026-08-28 7:36 ` [PATCH v6 00/45] net/sxe2: update SXE2 poll mode driver liujie5
@ 2026-08-28 16:49 ` Stephen Hemminger
0 siblings, 0 replies; 207+ messages in thread
From: Stephen Hemminger @ 2026-08-28 16:49 UTC (permalink / raw)
To: liujie5; +Cc: dev
On Fri, 28 Aug 2026 15:36:33 +0800
liujie5@linkdatatechnology.com wrote:
> From: Jie Liu <liujie5@linkdatatechnology.com>
>
> This series updates the SXE2 poll mode driver (drivers/net/sxe2) and
> its common library (drivers/common/sxe2), fixing issues found in the
> previous versions and re-aligning the driver with the reference
> implementation.
Looking good, AI review is mostly happy (with Claude Opus).
But still a couple of nits worth resolving in commit messages.
Review of v6 sxe2 series (45 patches)
=====================================
Series applies cleanly on current main. All findings below were
verified against the post-apply tree rather than the diffs alone.
All v5 findings are resolved in code: the dead IPsec key-length
hunk is gone (10/45), the representor nb_ports==0 case is handled
(23/45), sxe2_vsi_destroy() now unlinks DPDK_ESW nodes (6/45), the
ineffective queue-count assignments are dropped (14/45), and the
duplicate unconditional RSS_HASH is gone (15/45). Two of those
patches still carry commit messages describing the old code; see
below.
Patch 14/45: fill MAC and queue counts in device info
-----------------------------------------------------
Warning: the commit message no longer matches the patch. It says
"Fill max_mac_addrs, nb_rx_queues and nb_tx_queues ... so
applications can query the maximum number of MAC addresses and the
queue counts", but the diff now adds only max_mac_addrs. Please
retitle and rewrite the body to describe just that.
Patch 15/45: fix QinQ and RSS offload capability report
--------------------------------------------------------
Warning: same problem. The body still says "Advertise
RTE_ETH_RX_OFFLOAD_RSS_HASH unconditionally", but the code keeps
the capability-gated form:
if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_RSS) {
dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
which is the correct behaviour. Drop that sentence.
Patch 6/45: fix VSI lifecycle management
-----------------------------------------
Info: with sxe2_vsi_destroy() now doing the unlink, the test left
in sxe2_vsi_node_free() is dead:
if (vsi->vsi_type == SXE2_VSI_T_ESW)
TAILQ_REMOVE(&adapter->vsi_ctxt.other_vsi_list, vsi, next);
Both sites that insert into other_vsi_list use SXE2_VSI_T_DPDK_ESW
(sxe2_vsi.c:193 and :218), so SXE2_VSI_T_ESW never appears on that
list. Every caller of sxe2_vsi_node_free() passes a node that is
not linked. Because this now sits next to the almost-identical
DPDK_ESW test in sxe2_vsi_destroy(), a reader will take it for the
list-removal path and the two can drift. Suggest deleting it.
Patch 26/45: add ACL engine event statistics support
-----------------------------------------------------
Warning: the two new command structures are byte-for-byte copies of
the existing fnav ones:
struct sxe2_drv_acl_query_stat_req
{ stat_id, stat_ctrl, is_clear }
struct sxe2_drv_flow_fnav_query_stat_req
{ stat_id, stat_ctrl, is_clear }
and likewise for _resp. The same patch already reuses
sxe2_drv_flow_fnav_get_stat_id_req and
sxe2_drv_flow_fnav_free_stat_id_req for the ACL alloc and free
commands, so the query path is the odd one out. Either reuse the
fnav structs throughout or add ACL variants throughout; as written
it adds command-ABI surface for no benefit.
Info: sxe2_flow_get_filter_cid() silently succeeds on an unknown
engine type. The new prologue does
} else {
goto l_end;
}
with ret still 0, jumping past the SXE2_FLOW_ACTION_COUNT block. A
flow carrying a COUNT action then returns success without
stat_index ever being set. sxe2_flow_free_mgr() and
sxe2_flow_query_mgr() both return -ENOTSUP in the same situation;
this one should too.
Info: the FNAV and ACL arms added to RTE_FLOW_ACTION_TYPE_COUNT in
sxe2_flow_parse_action() are identical apart from which
hw_res.global_index is incremented. Picking the resource struct
first and sharing one body would halve it.
Patch 27/45: guard Rx queue event FD free in unregister
--------------------------------------------------------
Warning: this does not fix a bug. rte_free(NULL) is a documented
no-op, so the pre-patch code was already safe when
rxq_event_fd was NULL; moving the call inside the existing
"if (irq_ctxt->rxq_event_fd)" guard changes nothing observable.
The commit message claims "the buffer is only released when it was
allocated", which was already true. Please drop the Fixes: and
Cc: stable@dpdk.org tags, or drop the patch.
Patch 29/45: refactor Tx queue reset operations
------------------------------------------------
Info: sxe2_tx_vec_ops_get() builds and returns a three-pointer
struct by value on every call. The scalar side already uses the
simpler form:
const struct sxe2_txq_ops sxe2_default_txq_ops = { ... };
A file-scope "static const struct sxe2_txq_ops sxe2_tx_vec_ops"
plus "txq->ops = sxe2_tx_vec_ops;" would match it and keep the
table in .rodata.
Info: sxe2_tx_queues_vec_prepare() still returns 0 on every path,
so the caller's
ret = sxe2_tx_queues_vec_prepare(dev);
if (ret != 0)
tx_mode_flags &= ~SXE2_TX_MODE_VEC_SET_MASK;
is dead. Either make the NULL-txq case an error or make the
function void.
Patch 30/45: unify vectorized Tx buffer handling
--------------------------------------------------
The core fix is real and worth having: the old
sxe2_tx_queue_mbufs_release_vec() left "buffer" unassigned on the
AVX512 branch and then dereferenced it in the trailing loop, and it
also contained a duplicated "buffer = txq->buffer_ring;". Both go
away with the union.
Warning: the patch is far wider than its commit message, and all of
it is going to stable. Beyond the buffer_ring/buffer_ring_vec
unification it also:
- deletes sxe2_tx_bufs_free_vec_avx512(), which implemented the
RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE bulk path with
_mm512_loadu_si512 into the mempool cache. AVX512 Tx now uses
the generic sxe2_tx_bufs_free_vec(). That is a performance
regression, not a fix.
- adds sxe2_tx_desc_fill_4_neon_simple(), a new four-wide
descriptor fill using vst1q_u64_x4 and uint64x2x4_t. This is a
new optimisation. (The descriptor words it produces do match
sxe2_tx_desc_fill_one_neon() with with_offloads=false, and the
"i + 3 < n" bounds are correct.)
- changes the Rx packet_type lane mapping in
sxe2_rx_desc_ptype_fill_neon() from
pkt0/1/2/3 <- lane 5/1/7/3 to lane 1/3/5/7, and switches the
input from staterr to desc_lo with a different mask.
- removes three of the four rte_atomic_thread_fence(acquire)
calls between descriptor loads in
sxe2_rx_pkts_common_vec_neon().
The last two are Rx correctness and memory-ordering changes in the
fast path and are not mentioned anywhere in the commit message.
Please split: the union fix (with the Fixes:/stable tags) in one
patch, the NEON Tx optimisation in another, and the NEON Rx ptype
and fence changes in a third with their own justification. If the
AVX512 fast-free removal is intentional, say so and why.
Patch 36/45: use primary VSI ID for representor VSI
-----------------------------------------------------
Error: this drops the guard against an invalid kernel VSI.
- repr_priv_data->repr_vf_vsi_id =
- ...kernel_vsi_id != SXE2_INVALID_VSI_ID ?
- ...kernel_vsi_id : ...dpdk_vsi_id;
+ repr_priv_data->repr_vf_vsi_id =
+ repr_priv_data->repr_vf_primary_vsi_id;
repr_vf_primary_vsi_id is kernel_vsi_id, so repr_vf_vsi_id can now
hold SXE2_INVALID_VSI_ID. No consumer tests for it:
sxe2_txrx_poll.c:506 (repr_vf_vsi_id & 0x3FFULL) is written
straight into a Tx descriptor field
sxe2_flow.c:317 flow->meta.flow_src_vsi = repr_vf_vsi_id
sxe2_flow_parse_action.c:240
*vsi_index = repr_vf_vsi_id
kernel_vsi_id is genuinely optional -- sxe2_vsi_uninit() tests
"kernel_vsi_id != SXE2_INVALID_VSI_ID" before using it -- and the
ternary being removed is direct evidence the author expected the
invalid case. repr_vf_backup_vsi_id (the dpdk_vsi_id) is still
stored and still used at sxe2_flow.c:383, so the backup ID has not
become redundant.
"Matching the V3 implementation" is not sufficient justification
here. Either keep the fallback, or explain why kernel_vsi_id is
guaranteed valid for a representor and drop repr_vf_backup_vsi_id
too.
Patch 37/45: wrap command params fill debug log in macro
----------------------------------------------------------
Warning: __adapter is a reserved identifier. C11 7.1.3 reserves
all identifiers beginning with two underscores for the
implementation, in every scope. Rename it, e.g.
do { \
struct sxe2_adapter *_ad = (adapter); \
PMD_DEV_LOG_DEBUG(_ad, DRV, "cmd opcode:%s", #opc); \
__sxe2_drv_cmd_params_fill(_ad, cmd, opc, ...); \
} while (0)
Patch 41/45: fix command channel log messages
-----------------------------------------------
Info: one of the replacements is less accurate than what it
replaces. sxe2_drv_queue_info_get_update() issues
SXE2_DRV_CMD_TX_RX_MAP_GET and fills both q_ipackets/q_ibytes and
q_opackets/q_obytes, but the message became
PMD_LOG_ERR(DRV, "rx queue mapping failed, ret=%d", ret);
The old "get queue info map failed" covered both directions.
Something like "tx/rx queue map get failed" would be better.
Warning: this is a pure log-wording patch tagged Fixes: and
Cc: stable@dpdk.org. Log text corrections do not warrant a stable
backport; please drop those tags.
Patch 42/45: align command structs with historical kernel layout
-----------------------------------------------------------------
Error: sxe2_tm_res changes size, which changes the payload length
of four live firmware commands. I compiled the before and after
definitions to be sure:
sxe2_drv_link_info_resp 8 -> 8 (unchanged)
sxe2_tm_res 4 -> 2 (CHANGED)
sxe2_tm_info 12 -> 12 (unchanged)
sxe2_tm_add_mid_msg 16 -> 16 (info still at offset 3)
sxe2_tm_add_queue_msg 20 -> 20 (info still at offset 5)
sizeof(struct sxe2_tm_res) is passed directly as the command in/out
length at four call sites in sxe2_cmd_chnl.c:
1226 SCHED_ROOT_TREE_ALLOC out_len 4 -> 2
1250 SCHED_ROOT_TREE_RELEASE in_len 4 -> 2
1292 (sxe2_drv_tm_commit_node)
1354 SCHED_ROOT_CHILDREN_DELETE in_len 4 -> 2
The commit message says "Keep the structure members as-is so the
command ABI is compatible with the historical kernel driver", which
contradicts what the patch does to this one structure. Either the
message is wrong and the length change is the intended fix -- in
which case say so explicitly, since it is the only behavioural
change in the patch -- or sxe2_tm_res should keep its rsv[2] and
__rte_aligned(4).
For the record, the other four structures are genuinely no-ops.
Removing rsv[3] from sxe2_drv_link_info_resp does not shrink it,
because __rte_aligned(4) still rounds 5 bytes up to 8; the padding
is merely implicit now, which for a wire format is a readability
step backwards. The sfp structures keep the same offsets and sizes
without the packed attribute.
Positive note: dropping __rte_aligned(4) from sxe2_tm_info removes
two -Wpacked-not-aligned warnings, since info sits at offset 3 and
5 inside the packed message structures. That is worth mentioning
in the commit message, as it is the clearest benefit of the patch.
Verified clean
--------------
1-5, 7-13, 16-25, 28, 31-35, 38-40, 43-45.
Some of these I checked specifically rather than by inspection:
31/45 rte_eth_tx_pkt_prepare_dummy is in ethdev_driver.h and is
the right thing for a PMD to install;
SXE2_DEFAULT_RX_FREE_THRESH (32) matches the
default_rxconf advertised in dev_info. The ARM64 fallback
fix is correct -- the old else branch installed
sxe2_tx_pkts_vec_neon_simple when NEON was not detected.
33/45 sxe2_udp_tunnel_port_clear() returning -ENOTSUP for
representors is harmless; its only caller discards the
result with a (void) cast.
35/45 the bounds check is placed before the first
repr_vf_id[repr_id] dereference.
44/45 drv-sw-stats is genuinely absent from the code -- not in
RTE_PMD_REGISTER_PARAM_STRING, no parse callback -- and
the sw_stats counters really are updated on every packet,
so the reworded xstats section matches the code.
Things I checked and found not to be problems, in case they come up
again: the memset in sxe2_tx_queue_reset_vec() is in bounds, since
the buffer ring is always allocated at the larger
sizeof(struct sxe2_tx_buffer) stride regardless of mode;
mbuf_free_arr[64] cannot overflow because sxe2_tx_vec_support_check()
rejects rs_thresh > SXE2_TX_FREE_BUFFER_SIZE_MAX_VEC before vector
mode is selected; and sxe2_tx_queues_vec_prepare() is reached only
on the RTE_PROC_PRIMARY path from sxe2_dev_start(), after
sxe2_queues_init() and before the queues are started, so the new
queue_reset() call cannot disturb a running datapath.
^ permalink raw reply [flat|nested] 207+ messages in thread
end of thread, other threads:[~2026-08-28 16:49 UTC | newest]
Thread overview: 207+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-18 2:15 [PATCH v1 00/13] net/sxe2: fix bugs liujie5
2026-08-18 2:15 ` [PATCH v1 01/13] net/sxe2: add Rx queue buffer split fill support liujie5
2026-08-18 2:15 ` [PATCH v1 02/13] net/sxe2: update switchdev repr VSI ID display format liujie5
2026-08-18 2:15 ` [PATCH v1 03/13] net/sxe2: add ACL engine event statistics support liujie5
2026-08-18 2:15 ` [PATCH v1 04/13] net/sxe2: enhance device cap and res management liujie5
2026-08-18 2:15 ` [PATCH v1 05/13] net/sxe2: improve representor device initialization liujie5
2026-08-18 2:15 ` [PATCH v1 06/13] net/sxe2: refactor flow tunnel port handling liujie5
2026-08-18 2:15 ` [PATCH v1 07/13] net/sxe2: validate IPsec key length against maximum limit liujie5
2026-08-18 2:15 ` [PATCH v1 08/13] net/sxe2: enhance repr event handling and MP code liujie5
2026-08-18 2:15 ` [PATCH v1 09/13] net/sxe2: optimize vectorized Tx/Rx path liujie5
2026-08-18 2:15 ` [PATCH v1 10/13] common/sxe2: allow munmap during kernel reset liujie5
2026-08-18 2:15 ` [PATCH v1 11/13] net/sxe2: clean up duplicate function declarations liujie5
2026-08-18 2:15 ` [PATCH v1 12/13] net/sxe2: clean up structure definitions liujie5
2026-08-18 2:15 ` [PATCH v1 13/13] doc/sxe2: add acl-stat-type parameter documentation liujie5
2026-08-26 8:53 ` [PATCH v3 00/51] net/sxe2: add Stars SXE2 net driver with fixes liujie5
2026-08-26 17:07 ` Stephen Hemminger
2026-08-26 8:53 ` [PATCH v3 01/51] common/sxe2: fix null pointer in class driver remove liujie5
2026-08-26 8:53 ` [PATCH v3 02/51] common/sxe2: allow munmap during kernel reset liujie5
2026-08-26 8:53 ` [PATCH v3 03/51] net/sxe2: fix VF PCI device ID liujie5
2026-08-26 8:54 ` [PATCH v3 04/51] net/sxe2: fix MSIX register width in PF map table liujie5
2026-08-26 8:54 ` [PATCH v3 05/51] net/sxe2: restore pf and port index caps assignment liujie5
2026-08-26 8:54 ` [PATCH v3 06/51] net/sxe2: fix VSI lifecycle management liujie5
2026-08-26 8:54 ` [PATCH v3 07/51] net/sxe2: initialize stats in representor device init liujie5
2026-08-26 8:54 ` [PATCH v3 08/51] net/sxe2: use base device name for representor naming liujie5
2026-08-26 8:54 ` [PATCH v3 09/51] net/sxe2: propagate LSC event to VF representors liujie5
2026-08-26 8:54 ` [PATCH v3 10/51] net/sxe2: validate IPsec key length against maximum limit liujie5
2026-08-26 8:54 ` [PATCH v3 11/51] net/sxe2: rename representor VSI ID fields liujie5
2026-08-26 8:54 ` [PATCH v3 12/51] net/sxe2: clean up duplicate function declarations liujie5
2026-08-26 8:54 ` [PATCH v3 13/51] net/sxe2: fix null VSI dereference in device info liujie5
2026-08-26 8:55 ` [PATCH v3 14/51] net/sxe2: fill MAC and queue counts " liujie5
2026-08-26 8:55 ` [PATCH v3 15/51] net/sxe2: fix QinQ and RSS offload capability report liujie5
2026-08-26 8:55 ` [PATCH v3 16/51] net/sxe2: use regular write for mapped registers liujie5
2026-08-26 8:55 ` [PATCH v3 17/51] net/sxe2: move PCI register read macro to common header liujie5
2026-08-26 8:55 ` [PATCH v3 18/51] net/sxe2: validate PCI map resource type liujie5
2026-08-26 8:55 ` [PATCH v3 19/51] net/sxe2: guard PCI BAR unmap when not initialized liujie5
2026-08-26 8:55 ` [PATCH v3 20/51] net/sxe2: fix null dereference in dev uninit liujie5
2026-08-26 8:55 ` [PATCH v3 21/51] net/sxe2: fix duplicated cleanup in dev close liujie5
2026-08-26 8:55 ` [PATCH v3 22/51] net/sxe2: align dev init and cleanup order liujie5
2026-08-26 8:55 ` [PATCH v3 23/51] net/sxe2: simplify switchdev representor matching liujie5
2026-08-26 8:55 ` [PATCH v3 24/51] net/sxe2: probe all requested PF ports liujie5
2026-08-26 8:56 ` [PATCH v3 25/51] net/sxe2: rename fnav cid manager symbols to flow liujie5
2026-08-26 8:56 ` [PATCH v3 26/51] net/sxe2: move tunnel port helpers into flow module liujie5
2026-08-26 8:56 ` [PATCH v3 27/51] net/sxe2: add ACL engine event statistics support liujie5
2026-08-26 8:56 ` [PATCH v3 28/51] net/sxe2: guard Rx queue event FD free in unregister liujie5
2026-08-26 8:56 ` [PATCH v3 29/51] net/sxe2: refactor primary process MP message handling liujie5
2026-08-26 8:56 ` [PATCH v3 30/51] net/sxe2: refactor Tx queue reset operations liujie5
2026-08-26 8:56 ` [PATCH v3 31/51] net/sxe2: unify vectorized Tx buffer handling liujie5
2026-08-26 8:56 ` [PATCH v3 32/51] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
2026-08-26 8:56 ` [PATCH v3 33/51] net/sxe2: fix RSS action attribute validation liujie5
2026-08-26 8:56 ` [PATCH v3 34/51] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
2026-08-26 8:57 ` [PATCH v3 35/51] net/sxe2: align flow meta proc priority handling with V3 liujie5
2026-08-26 8:57 ` [PATCH v3 36/51] net/sxe2: restore link update call in status query liujie5
2026-08-26 8:57 ` [PATCH v3 37/51] net/sxe2: validate representor ID against VF count liujie5
2026-08-26 8:57 ` [PATCH v3 38/51] net/sxe2: use primary VSI ID for representor VSI liujie5
2026-08-26 8:57 ` [PATCH v3 39/51] net/sxe2: wrap command params fill debug log in macro liujie5
2026-08-26 8:57 ` [PATCH v3 40/51] net/sxe2: restore Rx queue buffer split fill support liujie5
2026-08-26 8:57 ` [PATCH v3 41/51] net/sxe2: skip tunnel config fill on get failure liujie5
2026-08-26 8:57 ` [PATCH v3 42/51] net/sxe2: skip flow id assignment on filter add failure liujie5
2026-08-26 8:57 ` [PATCH v3 43/51] net/sxe2: fix command channel log messages liujie5
2026-08-26 8:57 ` [PATCH v3 44/51] net/sxe2: align command structs with historical kernel layout liujie5
2026-08-26 8:58 ` [PATCH v3 45/51] common/sxe2: fix ioctl channel log and close handling liujie5
2026-08-26 8:58 ` [PATCH v3 46/51] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
2026-08-26 8:58 ` [PATCH v3 47/51] net/sxe2: harden ACL flow count resource handling liujie5
2026-08-26 8:58 ` [PATCH v3 48/51] net/sxe2: fix device init and representor matching issues liujie5
2026-08-26 8:58 ` [PATCH v3 49/51] net/sxe2: use correct loop counter type for representor LSC liujie5
2026-08-26 8:58 ` [PATCH v3 50/51] net/sxe2: restore NULL check in vectorized Tx mbuf release liujie5
2026-08-26 8:58 ` [PATCH v3 51/51] net/sxe2: simplify Rx queue buffer split fill helper liujie5
2026-08-27 2:36 ` [PATCH v4 00/44] net/sxe2: add Stars SXE2 net driver with fixes liujie5
2026-08-27 15:14 ` Stephen Hemminger
2026-08-27 2:36 ` [PATCH v4 01/44] common/sxe2: fix null pointer in class driver remove liujie5
2026-08-27 2:36 ` [PATCH v4 02/44] common/sxe2: allow munmap during kernel reset liujie5
2026-08-27 2:36 ` [PATCH v4 03/44] net/sxe2: fix VF PCI device ID liujie5
2026-08-27 2:36 ` [PATCH v4 04/44] net/sxe2: fix MSIX register width in PF map table liujie5
2026-08-27 2:36 ` [PATCH v4 05/44] net/sxe2: restore pf and port index caps assignment liujie5
2026-08-27 2:36 ` [PATCH v4 06/44] net/sxe2: fix VSI lifecycle management liujie5
2026-08-27 2:37 ` [PATCH v4 07/44] net/sxe2: initialize stats in representor device init liujie5
2026-08-27 2:37 ` [PATCH v4 08/44] net/sxe2: use base device name for representor naming liujie5
2026-08-27 2:37 ` [PATCH v4 09/44] net/sxe2: propagate LSC event to VF representors liujie5
2026-08-27 2:37 ` [PATCH v4 10/44] net/sxe2: validate IPsec key length against maximum limit liujie5
2026-08-27 2:37 ` [PATCH v4 11/44] net/sxe2: rename representor VSI ID fields liujie5
2026-08-27 2:37 ` [PATCH v4 12/44] net/sxe2: clean up duplicate function declarations liujie5
2026-08-27 2:37 ` [PATCH v4 13/44] net/sxe2: fix null VSI dereference in device info liujie5
2026-08-27 2:37 ` [PATCH v4 14/44] net/sxe2: fill MAC and queue counts " liujie5
2026-08-27 2:37 ` [PATCH v4 15/44] net/sxe2: fix QinQ and RSS offload capability report liujie5
2026-08-27 2:37 ` [PATCH v4 16/44] net/sxe2: use regular write for mapped registers liujie5
2026-08-27 2:37 ` [PATCH v4 17/44] net/sxe2: move PCI register read macro to common header liujie5
2026-08-27 2:38 ` [PATCH v4 18/44] net/sxe2: validate PCI map resource type liujie5
2026-08-27 2:38 ` [PATCH v4 19/44] net/sxe2: guard PCI BAR unmap when not initialized liujie5
2026-08-27 2:38 ` [PATCH v4 20/44] net/sxe2: fix null dereference in dev uninit liujie5
2026-08-27 2:38 ` [PATCH v4 21/44] net/sxe2: fix duplicated cleanup in dev close liujie5
2026-08-27 2:38 ` [PATCH v4 22/44] net/sxe2: align dev init and cleanup order liujie5
2026-08-27 2:38 ` [PATCH v4 23/44] net/sxe2: simplify switchdev representor matching liujie5
2026-08-27 2:38 ` [PATCH v4 24/44] net/sxe2: rename fnav cid manager symbols to flow liujie5
2026-08-27 2:38 ` [PATCH v4 25/44] net/sxe2: move tunnel port helpers into flow module liujie5
2026-08-27 2:38 ` [PATCH v4 26/44] net/sxe2: add ACL engine event statistics support liujie5
2026-08-27 2:38 ` [PATCH v4 27/44] net/sxe2: guard Rx queue event FD free in unregister liujie5
2026-08-27 2:39 ` [PATCH v4 28/44] net/sxe2: refactor primary process MP message handling liujie5
2026-08-27 2:39 ` [PATCH v4 29/44] net/sxe2: refactor Tx queue reset operations liujie5
2026-08-27 2:39 ` [PATCH v4 30/44] net/sxe2: unify vectorized Tx buffer handling liujie5
2026-08-27 2:39 ` [PATCH v4 31/44] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
2026-08-27 2:39 ` [PATCH v4 32/44] net/sxe2: fix RSS action attribute validation liujie5
2026-08-27 2:39 ` [PATCH v4 33/44] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
2026-08-27 2:39 ` [PATCH v4 34/44] net/sxe2: restore link update call in status query liujie5
2026-08-27 2:39 ` [PATCH v4 35/44] net/sxe2: validate representor ID against VF count liujie5
2026-08-27 2:39 ` [PATCH v4 36/44] net/sxe2: use primary VSI ID for representor VSI liujie5
2026-08-27 2:39 ` [PATCH v4 37/44] net/sxe2: wrap command params fill debug log in macro liujie5
2026-08-27 2:40 ` [PATCH v4 38/44] net/sxe2: restore Rx queue buffer split fill support liujie5
2026-08-27 2:40 ` [PATCH v4 39/44] net/sxe2: skip tunnel config fill on get failure liujie5
2026-08-27 2:40 ` [PATCH v4 40/44] net/sxe2: skip flow id assignment on filter add failure liujie5
2026-08-27 2:40 ` [PATCH v4 41/44] net/sxe2: fix command channel log messages liujie5
2026-08-27 2:40 ` [PATCH v4 42/44] net/sxe2: align command structs with historical kernel layout liujie5
2026-08-27 2:40 ` [PATCH v4 43/44] common/sxe2: fix ioctl channel log and close handling liujie5
2026-08-27 2:40 ` [PATCH v4 44/44] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
2026-08-28 3:23 ` [PATCH v5 00/45] net/sxe2: add Stars SXE2 net driver with fixes liujie5
2026-08-28 3:23 ` [PATCH v5 01/45] common/sxe2: fix null pointer in class driver remove liujie5
2026-08-28 3:23 ` [PATCH v5 02/45] common/sxe2: allow munmap during kernel reset liujie5
2026-08-28 3:23 ` [PATCH v5 03/45] net/sxe2: fix VF PCI device ID liujie5
2026-08-28 3:23 ` [PATCH v5 04/45] net/sxe2: fix MSIX register width in PF map table liujie5
2026-08-28 3:23 ` [PATCH v5 05/45] net/sxe2: restore pf and port index caps assignment liujie5
2026-08-28 3:23 ` [PATCH v5 06/45] net/sxe2: fix VSI lifecycle management liujie5
2026-08-28 3:23 ` [PATCH v5 07/45] net/sxe2: initialize stats in representor device init liujie5
2026-08-28 3:23 ` [PATCH v5 08/45] net/sxe2: use base device name for representor naming liujie5
2026-08-28 3:23 ` [PATCH v5 09/45] net/sxe2: propagate LSC event to VF representors liujie5
2026-08-28 3:24 ` [PATCH v5 10/45] net/sxe2: clear security context pointer on uninit liujie5
2026-08-28 3:24 ` [PATCH v5 11/45] net/sxe2: rename representor VSI ID fields liujie5
2026-08-28 3:24 ` [PATCH v5 12/45] net/sxe2: clean up duplicate function declarations liujie5
2026-08-28 3:24 ` [PATCH v5 13/45] net/sxe2: fix null VSI dereference in device info liujie5
2026-08-28 3:24 ` [PATCH v5 14/45] net/sxe2: fill MAC and queue counts " liujie5
2026-08-28 3:24 ` [PATCH v5 15/45] net/sxe2: fix QinQ and RSS offload capability report liujie5
2026-08-28 3:24 ` [PATCH v5 16/45] net/sxe2: use regular write for mapped registers liujie5
2026-08-28 3:24 ` [PATCH v5 17/45] net/sxe2: move PCI register read macro to common header liujie5
2026-08-28 3:24 ` [PATCH v5 18/45] net/sxe2: validate PCI map resource type liujie5
2026-08-28 3:24 ` [PATCH v5 19/45] net/sxe2: guard PCI BAR unmap when not initialized liujie5
2026-08-28 3:25 ` [PATCH v5 20/45] net/sxe2: fix null dereference in dev uninit liujie5
2026-08-28 3:25 ` [PATCH v5 21/45] net/sxe2: fix duplicated cleanup in dev close liujie5
2026-08-28 3:25 ` [PATCH v5 22/45] net/sxe2: align dev init and cleanup order liujie5
2026-08-28 3:25 ` [PATCH v5 23/45] net/sxe2: simplify switchdev representor matching liujie5
2026-08-28 3:25 ` [PATCH v5 24/45] net/sxe2: rename fnav cid manager symbols to flow liujie5
2026-08-28 3:25 ` [PATCH v5 25/45] net/sxe2: move tunnel port helpers into flow module liujie5
2026-08-28 3:25 ` [PATCH v5 26/45] net/sxe2: add ACL engine event statistics support liujie5
2026-08-28 3:25 ` [PATCH v5 27/45] net/sxe2: guard Rx queue event FD free in unregister liujie5
2026-08-28 3:25 ` [PATCH v5 28/45] net/sxe2: refactor primary process MP message handling liujie5
2026-08-28 3:25 ` [PATCH v5 29/45] net/sxe2: refactor Tx queue reset operations liujie5
2026-08-28 3:26 ` [PATCH v5 30/45] net/sxe2: unify vectorized Tx buffer handling liujie5
2026-08-28 3:26 ` [PATCH v5 31/45] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
2026-08-28 3:26 ` [PATCH v5 32/45] net/sxe2: fix RSS action attribute validation liujie5
2026-08-28 3:26 ` [PATCH v5 33/45] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
2026-08-28 3:26 ` [PATCH v5 34/45] net/sxe2: restore link update call in status query liujie5
2026-08-28 3:26 ` [PATCH v5 35/45] net/sxe2: validate representor ID against VF count liujie5
2026-08-28 3:26 ` [PATCH v5 36/45] net/sxe2: use primary VSI ID for representor VSI liujie5
2026-08-28 3:26 ` [PATCH v5 37/45] net/sxe2: wrap command params fill debug log in macro liujie5
2026-08-28 3:26 ` [PATCH v5 38/45] net/sxe2: restore Rx queue buffer split fill support liujie5
2026-08-28 3:26 ` [PATCH v5 39/45] net/sxe2: skip tunnel config fill on get failure liujie5
2026-08-28 3:27 ` [PATCH v5 40/45] net/sxe2: skip flow id assignment on filter add failure liujie5
2026-08-28 3:27 ` [PATCH v5 41/45] net/sxe2: fix command channel log messages liujie5
2026-08-28 3:27 ` [PATCH v5 42/45] net/sxe2: align command structs with historical kernel layout liujie5
2026-08-28 3:27 ` [PATCH v5 43/45] common/sxe2: fix ioctl channel log and close handling liujie5
2026-08-28 3:27 ` [PATCH v5 44/45] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
2026-08-28 3:27 ` [PATCH v5 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
2026-08-28 7:36 ` [PATCH v6 00/45] net/sxe2: update SXE2 poll mode driver liujie5
2026-08-28 16:49 ` Stephen Hemminger
2026-08-28 7:36 ` [PATCH v6 01/45] common/sxe2: fix null pointer in class driver remove liujie5
2026-08-28 7:36 ` [PATCH v6 02/45] common/sxe2: allow munmap during kernel reset liujie5
2026-08-28 7:36 ` [PATCH v6 03/45] net/sxe2: fix VF PCI device ID liujie5
2026-08-28 7:37 ` [PATCH v6 04/45] net/sxe2: fix MSIX register width in PF map table liujie5
2026-08-28 7:37 ` [PATCH v6 05/45] net/sxe2: restore pf and port index caps assignment liujie5
2026-08-28 7:37 ` [PATCH v6 06/45] net/sxe2: fix VSI lifecycle management liujie5
2026-08-28 7:37 ` [PATCH v6 07/45] net/sxe2: initialize stats in representor device init liujie5
2026-08-28 7:37 ` [PATCH v6 08/45] net/sxe2: use base device name for representor naming liujie5
2026-08-28 7:37 ` [PATCH v6 09/45] net/sxe2: propagate LSC event to VF representors liujie5
2026-08-28 7:37 ` [PATCH v6 10/45] net/sxe2: clear security context pointer on uninit liujie5
2026-08-28 7:37 ` [PATCH v6 11/45] net/sxe2: rename representor VSI ID fields liujie5
2026-08-28 7:37 ` [PATCH v6 12/45] net/sxe2: clean up duplicate function declarations liujie5
2026-08-28 7:37 ` [PATCH v6 13/45] net/sxe2: fix null VSI dereference in device info liujie5
2026-08-28 7:37 ` [PATCH v6 14/45] net/sxe2: fill MAC and queue counts " liujie5
2026-08-28 7:38 ` [PATCH v6 15/45] net/sxe2: fix QinQ and RSS offload capability report liujie5
2026-08-28 7:38 ` [PATCH v6 16/45] net/sxe2: use regular write for mapped registers liujie5
2026-08-28 7:38 ` [PATCH v6 17/45] net/sxe2: move PCI register read macro to common header liujie5
2026-08-28 7:38 ` [PATCH v6 18/45] net/sxe2: validate PCI map resource type liujie5
2026-08-28 7:38 ` [PATCH v6 19/45] net/sxe2: guard PCI BAR unmap when not initialized liujie5
2026-08-28 7:38 ` [PATCH v6 20/45] net/sxe2: fix null dereference in dev uninit liujie5
2026-08-28 7:38 ` [PATCH v6 21/45] net/sxe2: fix duplicated cleanup in dev close liujie5
2026-08-28 7:38 ` [PATCH v6 22/45] net/sxe2: align dev init and cleanup order liujie5
2026-08-28 7:38 ` [PATCH v6 23/45] net/sxe2: simplify switchdev representor matching liujie5
2026-08-28 7:38 ` [PATCH v6 24/45] net/sxe2: rename fnav cid manager symbols to flow liujie5
2026-08-28 7:39 ` [PATCH v6 25/45] net/sxe2: move tunnel port helpers into flow module liujie5
2026-08-28 7:39 ` [PATCH v6 26/45] net/sxe2: add ACL engine event statistics support liujie5
2026-08-28 7:39 ` [PATCH v6 27/45] net/sxe2: guard Rx queue event FD free in unregister liujie5
2026-08-28 7:39 ` [PATCH v6 28/45] net/sxe2: refactor primary process MP message handling liujie5
2026-08-28 7:39 ` [PATCH v6 29/45] net/sxe2: refactor Tx queue reset operations liujie5
2026-08-28 7:39 ` [PATCH v6 30/45] net/sxe2: unify vectorized Tx buffer handling liujie5
2026-08-28 7:39 ` [PATCH v6 31/45] net/sxe2: refine vectorized Tx/Rx mode setup liujie5
2026-08-28 7:39 ` [PATCH v6 32/45] net/sxe2: fix RSS action attribute validation liujie5
2026-08-28 7:39 ` [PATCH v6 33/45] net/sxe2: restore PF-only guard in udp tunnel port add liujie5
2026-08-28 7:39 ` [PATCH v6 34/45] net/sxe2: restore link update call in status query liujie5
2026-08-28 7:39 ` [PATCH v6 35/45] net/sxe2: validate representor ID against VF count liujie5
2026-08-28 7:40 ` [PATCH v6 36/45] net/sxe2: use primary VSI ID for representor VSI liujie5
2026-08-28 7:40 ` [PATCH v6 37/45] net/sxe2: wrap command params fill debug log in macro liujie5
2026-08-28 7:40 ` [PATCH v6 38/45] net/sxe2: restore Rx queue buffer split fill support liujie5
2026-08-28 7:40 ` [PATCH v6 39/45] net/sxe2: skip tunnel config fill on get failure liujie5
2026-08-28 7:40 ` [PATCH v6 40/45] net/sxe2: skip flow id assignment on filter add failure liujie5
2026-08-28 7:40 ` [PATCH v6 41/45] net/sxe2: fix command channel log messages liujie5
2026-08-28 7:40 ` [PATCH v6 42/45] net/sxe2: align command structs with historical kernel layout liujie5
2026-08-28 7:40 ` [PATCH v6 43/45] common/sxe2: fix ioctl channel log and close handling liujie5
2026-08-28 7:40 ` [PATCH v6 44/45] doc/sxe2: remove drv-sw-stats parameter documentation liujie5
2026-08-28 7:40 ` [PATCH v6 45/45] net/sxe2: remove ineffective queue counts in representor info liujie5
2026-08-18 14:22 ` [PATCH v1 00/13] net/sxe2: fix bugs Stephen Hemminger
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).