* [PATCH v1 00/13] net/sxe2: fix bugs
@ 2026-08-14 12:21 liujie5
2026-08-14 18:44 ` Stephen Hemminger
0 siblings, 1 reply; 17+ messages in thread
From: liujie5 @ 2026-08-14 12:21 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 repre 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 | 65 +++---
drivers/net/sxe2/sxe2_mp.h | 3 +-
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_stats.c | 10 +-
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 | 77 +++---
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 | 123 +---------
drivers/net/sxe2/sxe2_txrx_vec_common.h | 5 +-
drivers/net/sxe2/sxe2_txrx_vec_neon.c | 215 +++++++++++------
drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
drivers/net/sxe2/sxe2_vsi.c | 8 +-
39 files changed, 993 insertions(+), 692 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v1 00/13] net/sxe2: fix bugs
2026-08-14 12:21 liujie5
@ 2026-08-14 18:44 ` Stephen Hemminger
0 siblings, 0 replies; 17+ messages in thread
From: Stephen Hemminger @ 2026-08-14 18:44 UTC (permalink / raw)
To: liujie5; +Cc: dev
On Fri, 14 Aug 2026 20:21:51 +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 repre 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 | 65 +++---
> drivers/net/sxe2/sxe2_mp.h | 3 +-
> 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_stats.c | 10 +-
> 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 | 77 +++---
> 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 | 123 +---------
> drivers/net/sxe2/sxe2_txrx_vec_common.h | 5 +-
> drivers/net/sxe2/sxe2_txrx_vec_neon.c | 215 +++++++++++------
> drivers/net/sxe2/sxe2_txrx_vec_sse.c | 10 +-
> drivers/net/sxe2/sxe2_vsi.c | 8 +-
> 39 files changed, 993 insertions(+), 692 deletions(-)
>
Claude Opus 5 AI review found lots of things to address.
It stopped after the first 5.
Overall: the series is titled as bug fixes but most patches mix feature
work, renames, log-message rewording, and unrelated fixes into single
commits. Several of the real bug fixes are buried in patches whose
subject describes something else, and none carry Fixes:/Cc: stable.
Please split these out.
Patch 3/13 (net/sxe2: add ACL engine event statistics support)
Error: stale count-manager pointer causes double free.
In sxe2_flow_rte_list_free(), mgr is declared once outside the
TAILQ_FOREACH_SAFE loop and never reset per iteration.
sxe2_flow_query_mgr() writes *mgr_ptr only on the full success
path; every error path leaves the caller's mgr untouched.
sxe2_flow_free_mgr() is then still called (it is gated on the COUNT
bit, not on ret), so on iteration N it operates on the mgr freed in
iteration N-1: TAILQ_REMOVE() on an already-removed node plus a
second rte_free().
This is reachable whenever an expanded flow has more than one
sxe2_flow entry with a COUNT action and the FW query command fails
on a later entry.
The new "user_id == 0 && mgr" guard fixes the first-iteration NULL
case but not this one. Reset the pointer per iteration:
TAILQ_FOREACH_SAFE(hw_flow, &flow->sxe2_flow_list, next, hw_flow_temp) {
mgr = NULL;
or declare mgr inside the loop body.
Error: sxe2_flow_free_mgr() frees without unlinking on unknown engine.
If flow->engine_type is neither ACL nor FNAV, neither branch runs,
cid_mgr_list stays NULL, no TAILQ_REMOVE happens -- and the function
still falls through to rte_free(mgr). That leaves a freed node on
whichever list it came from. Add an else branch that logs and skips
the free, or return early.
Warning: sxe2_flow_query_mgr() returns 0 for an unrecognized engine
type without setting *mgr_ptr. Callers treat 0 as "mgr is valid":
sxe2_flow_query_count() does count->hits = mgr->hits with mgr still
NULL. The COUNT action is currently rejected for non-FNAV/ACL
engines in sxe2_flow_parse_action(), so this is not reachable today,
but the contract is wrong. Return -ENOTSUP on that path.
Info: the trailing else in sxe2_flow_query_mgr()
} else {
PMD_LOG_ERR(DRV, "query flow engine neither FNAV nor ACL");
ret = -ENOTSUP;
}
is dead -- the if/else-if/else at the top of the function already
goto l_end for anything that is not ACL or FNAV.
Warning: unrelated fix in this patch.
-#define SXE2_PCI_DEVICE_ID_VF_1 0x10b
+#define SXE2_PCI_DEVICE_ID_VF_1 0x10b2
A VF PCI device ID correction has nothing to do with ACL statistics.
Separate patch, with Fixes: and Cc: stable@dpdk.org.
Warning: the rxq->fnav_enable assignment added to sxe2_queues_init()
is also unrelated to this patch's subject.
Warning: the acl-stat-type devarg is added here but documented in
patch 13/13. Code and documentation must land in the same commit.
Info: struct sxe2_flow_cid_mgr.stat_index is uint16_t, but
sxe2_drv_flow_acl_get_stat_id() returns uint32_t and
sxe2_drv_acl_query_stat_req.stat_id is __le32. The assignment
mgr->stat_index = stat_index truncates. Pre-existing on the fnav
side, but the new ACL path inherits it.
Patch 4/13 (net/sxe2: enhance device cap and res management)
Error: error-unwind regression in sxe2_dev_init().
Before this patch:
init_flow_err:
init_rss_err:
sxe2_security_uinit(dev);
init_security_err:
After:
init_flow_err:
sxe2_security_uinit(dev);
init_rss_err:
init_security_err:
sxe2_intr_uninit(dev);
sxe2_rss_disable() runs after sxe2_security_init() succeeded, so a
failure there now jumps past sxe2_security_uinit() and leaks the
security context. Move init_rss_err back above the security_uinit
call.
Error: buffer-split ptype count includes the sentinel.
sxe2_buffer_split_supported_hdr_ptypes_get() now sets
*no_of_elements = RTE_DIM(ptypes), but the array still ends with a
RTE_PTYPE_UNKNOWN terminator left over from the sentinel-based
convention. rte_eth_buffer_split_get_supported_hdr_ptypes() copies
all no_of_elements entries verbatim, so callers get a bogus
RTE_PTYPE_UNKNOWN entry and an inflated count. Compare ice, whose
array has no terminator. Drop the RTE_PTYPE_UNKNOWN element.
Warning: sxe2_dev_close() cleanup fixes are unlabelled.
This patch removes a duplicate sxe2_switchdev_uninit() and a
duplicate sxe2_dev_pci_map_uinit() from sxe2_dev_close(). Those are
double-free fixes and belong in their own patch with Fixes: and
Cc: stable@dpdk.org, not inside a "cap and res management" commit.
Info: dev_info->nb_rx_queues / nb_tx_queues are dead stores.
rte_eth_dev_info_get() overwrites both from dev->data after the PMD
op returns (lib/ethdev/rte_ethdev.c). Drop them.
Info: sxe2_dev_infos_get() returns -EINVAL directly on the new NULL
vsi check while the rest of the file uses goto l_end. Minor
inconsistency.
Info: after the new res_type bounds check in sxe2_dev_pci_res_seg_map(),
the following "if (!addr_info || ...)" test is redundant --
addr_info is &array[res_type] and can never be NULL.
Info: in sxe2_switchdev_repr_match(), port_idx is initialized to
UINT16_MAX and then unconditionally overwritten by the for loop.
Patch 1/13 (net/sxe2: add Rx queue buffer split fill support)
Warning: the subject describes buffer split, but the patch also drops
a debug log from __sxe2_drv_cmd_params_fill(), adds a
sxe2_link_update() call to sxe2_drv_mac_link_status_get(), fixes an
error path in sxe2_drv_udp_tunnel_get(), and rewords a dozen log
messages. The udp_tunnel_get change is a real fix (the function
previously copied response fields after a failed command); it wants
its own patch with a Fixes: tag.
Info: sxe2_rxq_buf_split_fill() re-tests
rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT, which the caller
has already tested, so the else branch clearing hdr_len /
split_type_mask is unreachable. Either drop the check in the helper
or drop it in the caller.
Patch 5/13 (net/sxe2: improve representor device initialization)
The added sxe2_stats_init() call and its l_init_irq_ctxt_err label
unwind correctly. No findings.
^ permalink raw reply [flat|nested] 17+ messages in thread
* [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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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; 17+ 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] 17+ 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-18 14:22 ` [PATCH v1 00/13] net/sxe2: fix bugs Stephen Hemminger
13 siblings, 0 replies; 17+ 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] 17+ 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; 17+ 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] 17+ messages in thread
end of thread, other threads:[~2026-08-18 14:22 UTC | newest]
Thread overview: 17+ 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-18 14:22 ` [PATCH v1 00/13] net/sxe2: fix bugs Stephen Hemminger
-- strict thread matches above, loose matches on Subject: below --
2026-08-14 12:21 liujie5
2026-08-14 18:44 ` Stephen Hemminger
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.