DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 08/27] net/failsafe: convert to stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Gaetan Rivet
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

The functions rte_atomic64 are deprecated, convert this
code to use stdatomic for reference count. Use the memory
order implied by naming P/V.

No need for initialization since refcnt is in space
allocated with rte_zmalloc().

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/failsafe/failsafe_ops.c     | 12 +++++-----
 drivers/net/failsafe/failsafe_private.h | 29 ++++++++++++++-----------
 drivers/net/failsafe/failsafe_rxtx.c    |  2 +-
 3 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index ddc8808ebe..fcb0051777 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -11,7 +11,7 @@
 #endif
 
 #include <rte_debug.h>
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 #include <ethdev_driver.h>
 #include <rte_malloc.h>
 #include <rte_flow.h>
@@ -440,14 +440,13 @@ fs_rx_queue_setup(struct rte_eth_dev *dev,
 	}
 	rxq = rte_zmalloc(NULL,
 			  sizeof(*rxq) +
-			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
+			  sizeof(uint64_t) * PRIV(dev)->subs_tail,
 			  RTE_CACHE_LINE_SIZE);
 	if (rxq == NULL) {
 		fs_unlock(dev, 0);
 		return -ENOMEM;
 	}
-	FOREACH_SUBDEV(sdev, i, dev)
-		rte_atomic64_init(&rxq->refcnt[i]);
+
 	rxq->qid = rx_queue_id;
 	rxq->socket_id = socket_id;
 	rxq->info.mp = mb_pool;
@@ -617,14 +616,13 @@ fs_tx_queue_setup(struct rte_eth_dev *dev,
 	}
 	txq = rte_zmalloc("ethdev TX queue",
 			  sizeof(*txq) +
-			  sizeof(rte_atomic64_t) * PRIV(dev)->subs_tail,
+			  sizeof(uint64_t) * PRIV(dev)->subs_tail,
 			  RTE_CACHE_LINE_SIZE);
 	if (txq == NULL) {
 		fs_unlock(dev, 0);
 		return -ENOMEM;
 	}
-	FOREACH_SUBDEV(sdev, i, dev)
-		rte_atomic64_init(&txq->refcnt[i]);
+
 	txq->qid = tx_queue_id;
 	txq->socket_id = socket_id;
 	txq->info.conf = *tx_conf;
diff --git a/drivers/net/failsafe/failsafe_private.h b/drivers/net/failsafe/failsafe_private.h
index babea6016e..89b06f9756 100644
--- a/drivers/net/failsafe/failsafe_private.h
+++ b/drivers/net/failsafe/failsafe_private.h
@@ -10,7 +10,7 @@
 #include <sys/queue.h>
 #include <pthread.h>
 
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 #include <dev_driver.h>
 #include <ethdev_driver.h>
 #include <rte_devargs.h>
@@ -75,7 +75,7 @@ struct rxq {
 	int event_fd;
 	unsigned int enable_events:1;
 	struct rte_eth_rxq_info info;
-	rte_atomic64_t refcnt[];
+	RTE_ATOMIC(uint64_t) refcnt[];
 };
 
 struct txq {
@@ -83,7 +83,7 @@ struct txq {
 	uint16_t qid;
 	unsigned int socket_id;
 	struct rte_eth_txq_info info;
-	rte_atomic64_t refcnt[];
+	RTE_ATOMIC(uint64_t) refcnt[];
 };
 
 struct rte_flow {
@@ -320,33 +320,36 @@ extern int failsafe_mac_from_arg;
  */
 
 /**
- * a: (rte_atomic64_t)
+ * a: _Atomic uint64_t
  */
 #define FS_ATOMIC_P(a) \
-	rte_atomic64_set(&(a), 1)
+	rte_atomic_exchange_explicit(&(a), 1, rte_memory_order_acquire)
 
 /**
- * a: (rte_atomic64_t)
+ * a: _Atomic uint64_t
  */
 #define FS_ATOMIC_V(a) \
-	rte_atomic64_set(&(a), 0)
+	rte_atomic_store_explicit(&(a), 0, rte_memory_order_release)
 
 /**
  * s: (struct sub_device *)
  * i: uint16_t qid
  */
 #define FS_ATOMIC_RX(s, i) \
-	rte_atomic64_read( \
-	 &((struct rxq *) \
-	 (fs_dev(s)->data->rx_queues[i]))->refcnt[(s)->sid])
+	rte_atomic_load_explicit( \
+		&((struct rxq *) \
+		  (fs_dev(s)->data->rx_queues[i]))->refcnt[(s)->sid], \
+		rte_memory_order_seq_cst)
+
 /**
  * s: (struct sub_device *)
  * i: uint16_t qid
  */
 #define FS_ATOMIC_TX(s, i) \
-	rte_atomic64_read( \
-	 &((struct txq *) \
-	 (fs_dev(s)->data->tx_queues[i]))->refcnt[(s)->sid])
+	rte_atomic_load_explicit( \
+		&((struct txq *) \
+		  (fs_dev(s)->data->tx_queues[i]))->refcnt[(s)->sid], \
+		rte_memory_order_seq_cst)
 
 #ifdef RTE_EXEC_ENV_FREEBSD
 #define FS_THREADID_TYPE void*
diff --git a/drivers/net/failsafe/failsafe_rxtx.c b/drivers/net/failsafe/failsafe_rxtx.c
index fe67293299..500483bda3 100644
--- a/drivers/net/failsafe/failsafe_rxtx.c
+++ b/drivers/net/failsafe/failsafe_rxtx.c
@@ -3,7 +3,7 @@
  * Copyright 2017 Mellanox Technologies, Ltd
  */
 
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 #include <rte_debug.h>
 #include <rte_mbuf.h>
 #include <ethdev_driver.h>
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 09/27] net/enic: do not use deprecated rte_atomic64
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, John Daley, Hyong Youb Kim, Bruce Richardson,
	Konstantin Ananyev
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

The rte_atomic64 datatype and functions are deprecated.
This driver was only using it for error statistics where atomic
is not necessary. The DPDK PMD model is that statistics do
not have to be exact in face of contention.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/enic/enic.h               |  6 +++---
 drivers/net/enic/enic_compat.h        |  1 -
 drivers/net/enic/enic_main.c          | 17 +++++++----------
 drivers/net/enic/enic_rxtx.c          | 14 ++++++--------
 drivers/net/enic/enic_rxtx_vec_avx2.c |  4 ++--
 5 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 87f6b35fcd..0a8d4a29ca 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -59,9 +59,9 @@
 #define ENICPMD_RXQ_INTR_OFFSET 1
 
 struct enic_soft_stats {
-	rte_atomic64_t rx_nombuf;
-	rte_atomic64_t rx_packet_errors;
-	rte_atomic64_t tx_oversized;
+	uint64_t rx_nombuf;
+	uint64_t rx_packet_errors;
+	uint64_t tx_oversized;
 };
 
 struct enic_memzone_entry {
diff --git a/drivers/net/enic/enic_compat.h b/drivers/net/enic/enic_compat.h
index 7cff6831b9..3ce4299e81 100644
--- a/drivers/net/enic/enic_compat.h
+++ b/drivers/net/enic/enic_compat.h
@@ -9,7 +9,6 @@
 #include <stdio.h>
 #include <unistd.h>
 
-#include <rte_atomic.h>
 #include <rte_malloc.h>
 #include <rte_log.h>
 #include <rte_io.h>
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 2696fa77d4..fb9a5754c9 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -83,17 +83,15 @@ static void enic_log_q_error(struct enic *enic)
 static void enic_clear_soft_stats(struct enic *enic)
 {
 	struct enic_soft_stats *soft_stats = &enic->soft_stats;
-	rte_atomic64_clear(&soft_stats->rx_nombuf);
-	rte_atomic64_clear(&soft_stats->rx_packet_errors);
-	rte_atomic64_clear(&soft_stats->tx_oversized);
+
+	memset(soft_stats, 0, sizeof(*soft_stats));
 }
 
 static void enic_init_soft_stats(struct enic *enic)
 {
 	struct enic_soft_stats *soft_stats = &enic->soft_stats;
-	rte_atomic64_init(&soft_stats->rx_nombuf);
-	rte_atomic64_init(&soft_stats->rx_packet_errors);
-	rte_atomic64_init(&soft_stats->tx_oversized);
+
+	memset(soft_stats, 0, sizeof(*soft_stats));
 	enic_clear_soft_stats(enic);
 }
 
@@ -132,7 +130,7 @@ int enic_dev_stats_get(struct enic *enic, struct rte_eth_stats *r_stats,
 	 * counted in ibytes even though truncated packets are dropped
 	 * which can make ibytes be slightly higher than it should be.
 	 */
-	rx_packet_errors = rte_atomic64_read(&soft_stats->rx_packet_errors);
+	rx_packet_errors = soft_stats->rx_packet_errors;
 	rx_truncated = rx_packet_errors - stats->rx.rx_errors;
 
 	r_stats->ipackets = stats->rx.rx_frames_ok - rx_truncated;
@@ -142,12 +140,11 @@ int enic_dev_stats_get(struct enic *enic, struct rte_eth_stats *r_stats,
 	r_stats->obytes = stats->tx.tx_bytes_ok;
 
 	r_stats->ierrors = stats->rx.rx_errors + stats->rx.rx_drop;
-	r_stats->oerrors = stats->tx.tx_errors
-			   + rte_atomic64_read(&soft_stats->tx_oversized);
+	r_stats->oerrors = stats->tx.tx_errors + soft_stats->tx_oversized;
 
 	r_stats->imissed = stats->rx.rx_no_bufs + rx_truncated;
 
-	r_stats->rx_nombuf = rte_atomic64_read(&soft_stats->rx_nombuf);
+	r_stats->rx_nombuf = soft_stats->rx_nombuf;
 	return 0;
 }
 
diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
index 549a153332..c87d947b93 100644
--- a/drivers/net/enic/enic_rxtx.c
+++ b/drivers/net/enic/enic_rxtx.c
@@ -112,7 +112,7 @@ enic_recv_pkts_common(void *rx_queue, struct rte_mbuf **rx_pkts,
 		/* allocate a new mbuf */
 		nmb = rte_mbuf_raw_alloc(rq->mp);
 		if (nmb == NULL) {
-			rte_atomic64_inc(&enic->soft_stats.rx_nombuf);
+			++enic->soft_stats.rx_nombuf;
 			break;
 		}
 
@@ -185,7 +185,7 @@ enic_recv_pkts_common(void *rx_queue, struct rte_mbuf **rx_pkts,
 		}
 		if (unlikely(packet_error)) {
 			rte_pktmbuf_free(first_seg);
-			rte_atomic64_inc(&enic->soft_stats.rx_packet_errors);
+			++enic->soft_stats.rx_packet_errors;
 			continue;
 		}
 
@@ -303,7 +303,7 @@ enic_noscatter_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		if (unlikely(cqd->bytes_written_flags &
 			     CQ_ENET_RQ_DESC_FLAGS_TRUNCATED)) {
 			rte_pktmbuf_free(*rxmb++);
-			rte_atomic64_inc(&enic->soft_stats.rx_packet_errors);
+			++enic->soft_stats.rx_packet_errors;
 			cqd++;
 			continue;
 		}
@@ -505,14 +505,12 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 	uint8_t offload_mode;
 	uint16_t header_len;
 	uint64_t tso;
-	rte_atomic64_t *tx_oversized;
 
 	enic_cleanup_wq(enic, wq);
 	wq_desc_avail = vnic_wq_desc_avail(wq);
 	head_idx = wq->head_idx;
 	desc_count = wq->ring.desc_count;
 	ol_flags_mask = RTE_MBUF_F_TX_VLAN | RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_L4_MASK;
-	tx_oversized = &enic->soft_stats.tx_oversized;
 
 	nb_pkts = RTE_MIN(nb_pkts, ENIC_TX_XMIT_MAX);
 
@@ -527,7 +525,7 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 		/* drop packet if it's too big to send */
 		if (unlikely(!tso && pkt_len > ENIC_TX_MAX_PKT_SIZE)) {
 			rte_pktmbuf_free(tx_pkt);
-			rte_atomic64_inc(tx_oversized);
+			++enic->soft_stats.tx_oversized;
 			continue;
 		}
 
@@ -558,7 +556,7 @@ uint16_t enic_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 			if (unlikely(header_len == 0 || ((tx_pkt->tso_segsz +
 			    header_len) > ENIC_TX_MAX_PKT_SIZE))) {
 				rte_pktmbuf_free(tx_pkt);
-				rte_atomic64_inc(tx_oversized);
+				++enic->soft_stats.tx_oversized;
 				continue;
 			}
 
@@ -681,7 +679,7 @@ static void enqueue_simple_pkts(struct rte_mbuf **pkts,
 		 */
 		if (unlikely(p->pkt_len > ENIC_TX_MAX_PKT_SIZE)) {
 			desc->length = ENIC_TX_MAX_PKT_SIZE;
-			rte_atomic64_inc(&enic->soft_stats.tx_oversized);
+			++enic->soft_stats.tx_oversized;
 		}
 		desc++;
 	}
diff --git a/drivers/net/enic/enic_rxtx_vec_avx2.c b/drivers/net/enic/enic_rxtx_vec_avx2.c
index 600efff270..53589ab788 100644
--- a/drivers/net/enic/enic_rxtx_vec_avx2.c
+++ b/drivers/net/enic/enic_rxtx_vec_avx2.c
@@ -81,7 +81,7 @@ enic_noscatter_vec_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		if (unlikely(cqd->bytes_written_flags &
 			     CQ_ENET_RQ_DESC_FLAGS_TRUNCATED)) {
 			rte_pktmbuf_free(*rxmb++);
-			rte_atomic64_inc(&enic->soft_stats.rx_packet_errors);
+			++enic->soft_stats.rx_packet_errors;
 		} else {
 			*rx++ = rx_one(cqd, *rxmb++, enic);
 		}
@@ -761,7 +761,7 @@ enic_noscatter_vec_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		if (unlikely(cqd->bytes_written_flags &
 			     CQ_ENET_RQ_DESC_FLAGS_TRUNCATED)) {
 			rte_pktmbuf_free(*rxmb++);
-			rte_atomic64_inc(&enic->soft_stats.rx_packet_errors);
+			++enic->soft_stats.rx_packet_errors;
 		} else {
 			*rx++ = rx_one(cqd, *rxmb++, enic);
 		}
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 10/27] net/pfe: use ethdev linkstatus helpers
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Gagandeep Singh
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

Rather than open coding with deprecated rte_atomic64,
use the existing ethdev helpers to get and set link status.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/pfe/pfe_ethdev.c | 32 ++------------------------------
 1 file changed, 2 insertions(+), 30 deletions(-)

diff --git a/drivers/net/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c
index 1efa17539e..1b183ab1f3 100644
--- a/drivers/net/pfe/pfe_ethdev.c
+++ b/drivers/net/pfe/pfe_ethdev.c
@@ -531,34 +531,6 @@ pfe_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
 	return NULL;
 }
 
-static inline int
-pfe_eth_atomic_read_link_status(struct rte_eth_dev *dev,
-				struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = link;
-	struct rte_eth_link *src = &dev->data->dev_link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-				*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
-static inline int
-pfe_eth_atomic_write_link_status(struct rte_eth_dev *dev,
-				 struct rte_eth_link *link)
-{
-	struct rte_eth_link *dst = &dev->data->dev_link;
-	struct rte_eth_link *src = link;
-
-	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
-				*(uint64_t *)src) == 0)
-		return -1;
-
-	return 0;
-}
-
 static int
 pfe_eth_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
 {
@@ -570,7 +542,7 @@ pfe_eth_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
 	memset(&old, 0, sizeof(old));
 	memset(&link, 0, sizeof(struct rte_eth_link));
 
-	pfe_eth_atomic_read_link_status(dev, &old);
+	rte_eth_linkstatus_get(dev, &old);
 
 	/* Read from PFE CDEV, status of link, if file was successfully
 	 * opened.
@@ -601,7 +573,7 @@ pfe_eth_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
 	link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
 	link.link_autoneg = RTE_ETH_LINK_AUTONEG;
 
-	pfe_eth_atomic_write_link_status(dev, &link);
+	rte_eth_linkstatus_set(dev, &link);
 
 	PFE_PMD_INFO("Port (%d) link is %s", dev->data->port_id,
 		     link.link_status ? "up" : "down");
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 11/27] net/sfc: replace rte_atomic with stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

The rte_atomicNN functions are deprecated and need to be replaced.
Use stdatomic for the restart required flag.
Use existing ethdev helper to set link status.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/sfc/sfc.c       | 9 +++++----
 drivers/net/sfc/sfc.h       | 4 ++--
 drivers/net/sfc/sfc_port.c  | 7 +------
 drivers/net/sfc/sfc_stats.h | 2 +-
 4 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 69747e49ae..3470f7eed6 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -670,8 +670,8 @@ sfc_restart_if_required(void *arg)
 	struct sfc_adapter *sa = arg;
 
 	/* If restart is scheduled, clear the flag and do it */
-	if (rte_atomic32_cmpset((volatile uint32_t *)&sa->restart_required,
-				1, 0)) {
+	if (rte_atomic_exchange_explicit(&sa->restart_required, false,
+					 rte_memory_order_seq_cst)) {
 		sfc_adapter_lock(sa);
 		if (sa->state == SFC_ETHDEV_STARTED)
 			(void)sfc_restart(sa);
@@ -685,7 +685,8 @@ sfc_schedule_restart(struct sfc_adapter *sa)
 	int rc;
 
 	/* Schedule restart alarm if it is not scheduled yet */
-	if (!rte_atomic32_test_and_set(&sa->restart_required))
+	if (rte_atomic_exchange_explicit(&sa->restart_required, true,
+					 rte_memory_order_seq_cst))
 		return;
 
 	rc = rte_eal_alarm_set(1, sfc_restart_if_required, sa);
@@ -1292,7 +1293,7 @@ sfc_probe(struct sfc_adapter *sa)
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
 	sa->socket_id = rte_socket_id();
-	rte_atomic32_init(&sa->restart_required);
+	sa->restart_required = false;
 
 	sfc_log_init(sa, "get family");
 	rc = sfc_efx_family(pci_dev, &mem_ebrp, &sa->family);
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 629578549f..515e1e708d 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -17,7 +17,7 @@
 #include <ethdev_driver.h>
 #include <rte_kvargs.h>
 #include <rte_spinlock.h>
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 
 #include "efx.h"
 
@@ -239,7 +239,7 @@ struct sfc_adapter {
 	efx_family_t			family;
 	efx_nic_t			*nic;
 	rte_spinlock_t			nic_lock;
-	rte_atomic32_t			restart_required;
+	RTE_ATOMIC(bool)		restart_required;
 
 	struct sfc_efx_mcdi		mcdi;
 	struct sfc_sriov		sriov;
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index 33b53f7ac8..d84648d454 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -121,7 +121,6 @@ sfc_port_reset_mac_stats(struct sfc_adapter *sa)
 static int
 sfc_port_init_dev_link(struct sfc_adapter *sa)
 {
-	struct rte_eth_link *dev_link = &sa->eth_dev->data->dev_link;
 	int rc;
 	efx_link_mode_t link_mode;
 	struct rte_eth_link current_link;
@@ -132,11 +131,7 @@ sfc_port_init_dev_link(struct sfc_adapter *sa)
 
 	sfc_port_link_mode_to_info(link_mode, sa->port.phy_adv_cap,
 				   &current_link);
-
-	EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
-	rte_atomic64_set((rte_atomic64_t *)dev_link,
-			 *(uint64_t *)&current_link);
-
+	rte_eth_linkstatus_set(sa->eth_dev, &current_link);
 	return 0;
 }
 
diff --git a/drivers/net/sfc/sfc_stats.h b/drivers/net/sfc/sfc_stats.h
index 597e14dab3..eaa2afd3fe 100644
--- a/drivers/net/sfc/sfc_stats.h
+++ b/drivers/net/sfc/sfc_stats.h
@@ -12,7 +12,7 @@
 
 #include <stdint.h>
 
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 
 #include "sfc_tweak.h"
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 12/27] crypto/ccp: replace use of rte_atomic64 with stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Sunil Uttarwar
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

The rte_atomicNN functions are deprecated. Replace the free
count with stdatomic.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/crypto/ccp/ccp_crypto.c | 11 +++++++----
 drivers/crypto/ccp/ccp_crypto.h |  2 +-
 drivers/crypto/ccp/ccp_dev.c    | 10 ++++++----
 drivers/crypto/ccp/ccp_dev.h    |  4 ++--
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/crypto/ccp/ccp_crypto.c b/drivers/crypto/ccp/ccp_crypto.c
index 5899d83bae..1800ad41c9 100644
--- a/drivers/crypto/ccp/ccp_crypto.c
+++ b/drivers/crypto/ccp/ccp_crypto.c
@@ -2683,7 +2683,8 @@ process_ops_to_enqueue(struct ccp_qp *qp,
 	b_info->cmd_q = cmd_q;
 	b_info->lsb_buf_phys = (phys_addr_t)rte_mem_virt2iova((void *)b_info->lsb_buf);
 
-	rte_atomic64_sub(&b_info->cmd_q->free_slots, slots_req);
+	rte_atomic_fetch_sub_explicit(&b_info->cmd_q->free_slots, slots_req,
+				      rte_memory_order_seq_cst);
 
 	b_info->head_offset = (uint32_t)(cmd_q->qbase_phys_addr + cmd_q->qidx *
 					 Q_DESC_SIZE);
@@ -2729,8 +2730,9 @@ process_ops_to_enqueue(struct ccp_qp *qp,
 			result = -1;
 		}
 		if (unlikely(result < 0)) {
-			rte_atomic64_add(&b_info->cmd_q->free_slots,
-					 (slots_req - b_info->desccnt));
+			rte_atomic_fetch_add_explicit(&b_info->cmd_q->free_slots,
+						      slots_req - b_info->desccnt,
+						      rte_memory_order_seq_cst);
 			break;
 		}
 		b_info->op[i] = op[i];
@@ -2914,7 +2916,8 @@ process_ops_to_dequeue(struct ccp_qp *qp,
 success:
 	*total_nb_ops = b_info->total_nb_ops;
 	nb_ops = ccp_prepare_ops(qp, op, b_info, nb_ops);
-	rte_atomic64_add(&b_info->cmd_q->free_slots, b_info->desccnt);
+	rte_atomic_fetch_add_explicit(&b_info->cmd_q->free_slots, b_info->desccnt,
+				      rte_memory_order_seq_cst);
 	b_info->desccnt = 0;
 	if (b_info->opcnt > 0) {
 		qp->b_info = b_info;
diff --git a/drivers/crypto/ccp/ccp_crypto.h b/drivers/crypto/ccp/ccp_crypto.h
index d0b417ca29..5c61b1582d 100644
--- a/drivers/crypto/ccp/ccp_crypto.h
+++ b/drivers/crypto/ccp/ccp_crypto.h
@@ -10,7 +10,7 @@
 #include <stdint.h>
 #include <string.h>
 
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 #include <rte_byteorder.h>
 #include <rte_io.h>
 #include <rte_pci.h>
diff --git a/drivers/crypto/ccp/ccp_dev.c b/drivers/crypto/ccp/ccp_dev.c
index 5088d8ded6..a75816cdfc 100644
--- a/drivers/crypto/ccp/ccp_dev.c
+++ b/drivers/crypto/ccp/ccp_dev.c
@@ -47,14 +47,15 @@ ccp_allot_queue(struct rte_cryptodev *cdev, int slot_req)
 	priv->last_dev = dev;
 	if (dev->qidx >= dev->cmd_q_count)
 		dev->qidx = 0;
-	ret = rte_atomic64_read(&dev->cmd_q[dev->qidx].free_slots);
+	ret = rte_atomic_load_explicit(&dev->cmd_q[dev->qidx].free_slots, rte_memory_order_relaxed);
 	if (ret >= slot_req)
 		return &dev->cmd_q[dev->qidx];
 	for (i = 0; i < dev->cmd_q_count; i++) {
 		dev->qidx++;
 		if (dev->qidx >= dev->cmd_q_count)
 			dev->qidx = 0;
-		ret = rte_atomic64_read(&dev->cmd_q[dev->qidx].free_slots);
+		ret = rte_atomic_load_explicit(&dev->cmd_q[dev->qidx].free_slots,
+					       rte_memory_order_relaxed);
 		if (ret >= slot_req)
 			return &dev->cmd_q[dev->qidx];
 	}
@@ -583,8 +584,9 @@ ccp_add_device(struct ccp_device *dev)
 			CCP_LOG_ERR("queue doesn't have lsb regions");
 		cmd_q->lsb = -1;
 
-		rte_atomic64_init(&cmd_q->free_slots);
-		rte_atomic64_set(&cmd_q->free_slots, (COMMANDS_PER_QUEUE - 1));
+		rte_atomic_store_explicit(&cmd_q->free_slots,
+					  COMMANDS_PER_QUEUE - 1,
+					  rte_memory_order_seq_cst);
 		/* unused slot barrier b/w H&T */
 	}
 
diff --git a/drivers/crypto/ccp/ccp_dev.h b/drivers/crypto/ccp/ccp_dev.h
index cd63830759..0d343c2426 100644
--- a/drivers/crypto/ccp/ccp_dev.h
+++ b/drivers/crypto/ccp/ccp_dev.h
@@ -11,7 +11,7 @@
 #include <string.h>
 
 #include <bus_pci_driver.h>
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 #include <rte_byteorder.h>
 #include <rte_io.h>
 #include <rte_pci.h>
@@ -182,7 +182,7 @@ struct __rte_cache_aligned ccp_queue {
 	struct ccp_device *dev;
 	char memz_name[RTE_MEMZONE_NAMESIZE];
 
-	rte_atomic64_t free_slots;
+	RTE_ATOMIC(uint64_t) free_slots;
 	/**< available free slots updated from enq/deq calls */
 
 	/* Queue identifier */
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 13/27] bus/dpaa: replace rte_atomic16 with stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Hemant Agrawal, Sachin Saxena
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

This is simple inuse flag which can be done with stdatomic
exchange logic.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/bus/dpaa/base/qbman/qman.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c
index 5534e1846c..82a976141a 100644
--- a/drivers/bus/dpaa/base/qbman/qman.c
+++ b/drivers/bus/dpaa/base/qbman/qman.c
@@ -11,6 +11,7 @@
 #include <rte_eventdev.h>
 #include <rte_byteorder.h>
 #include <rte_dpaa_logs.h>
+#include <rte_stdatomic.h>
 #include <eal_export.h>
 #include <dpaa_bits.h>
 
@@ -683,7 +684,7 @@ qman_init_portal(struct qman_portal *portal,
 
 #define MAX_GLOBAL_PORTALS 8
 static struct qman_portal global_portals[MAX_GLOBAL_PORTALS];
-static rte_atomic16_t global_portals_used[MAX_GLOBAL_PORTALS];
+static RTE_ATOMIC(bool) global_portals_used[MAX_GLOBAL_PORTALS];
 
 struct qman_portal *
 qman_alloc_global_portal(struct qm_portal_config *q_pcfg)
@@ -691,7 +692,8 @@ qman_alloc_global_portal(struct qm_portal_config *q_pcfg)
 	unsigned int i;
 
 	for (i = 0; i < MAX_GLOBAL_PORTALS; i++) {
-		if (rte_atomic16_test_and_set(&global_portals_used[i])) {
+		if (!rte_atomic_exchange_explicit(&global_portals_used[i], true,
+						  rte_memory_order_acquire)) {
 			global_portals[i].config = q_pcfg;
 			return &global_portals[i];
 		}
@@ -708,7 +710,8 @@ qman_free_global_portal(struct qman_portal *portal)
 
 	for (i = 0; i < MAX_GLOBAL_PORTALS; i++) {
 		if (&global_portals[i] == portal) {
-			rte_atomic16_clear(&global_portals_used[i]);
+			rte_atomic_store_explicit(&global_portals_used[i], false,
+						  rte_memory_order_release);
 			return 0;
 		}
 	}
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 14/27] drivers: replace rte_atomic16 with stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Hemant Agrawal, Sachin Saxena
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

The rte_atomicNN functions and types are deprecated.
The in_use and reference counts flag can be converted to stdatomic.

Also drop the unneeded NULL check in the loop body: TAILQ_FOREACH
terminates when the iterator becomes NULL, so var is guaranteed
non-NULL inside the loop.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c | 10 +++++++---
 drivers/bus/fslmc/portal/dpaa2_hw_dpci.c | 10 +++++++---
 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 12 ++++++++----
 drivers/bus/fslmc/portal/dpaa2_hw_pvt.h  |  8 ++++----
 drivers/event/dpaa2/dpaa2_hw_dpcon.c     | 11 +++++++----
 5 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
index 925e83e97d..d94f3965b6 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpbp.c
@@ -84,7 +84,7 @@ dpaa2_create_dpbp_device(int vdev_fd __rte_unused,
 	}
 
 	dpbp_node->dpbp_id = dpbp_id;
-	rte_atomic16_init(&dpbp_node->in_use);
+	dpbp_node->in_use = 0;
 
 	TAILQ_INSERT_TAIL(&dpbp_dev_list, dpbp_node, next);
 
@@ -103,7 +103,10 @@ struct dpaa2_dpbp_dev *dpaa2_alloc_dpbp_dev(void)
 
 	/* Get DPBP dev handle from list using index */
 	TAILQ_FOREACH(dpbp_dev, &dpbp_dev_list, next) {
-		if (dpbp_dev && rte_atomic16_test_and_set(&dpbp_dev->in_use))
+		uint32_t expected = 0;
+		if (rte_atomic_compare_exchange_strong_explicit(
+			    &dpbp_dev->in_use, &expected, 1,
+			    rte_memory_order_acquire, rte_memory_order_relaxed))
 			break;
 	}
 
@@ -118,7 +121,8 @@ void dpaa2_free_dpbp_dev(struct dpaa2_dpbp_dev *dpbp)
 	/* Match DPBP handle and mark it free */
 	TAILQ_FOREACH(dpbp_dev, &dpbp_dev_list, next) {
 		if (dpbp_dev == dpbp) {
-			rte_atomic16_dec(&dpbp_dev->in_use);
+			rte_atomic_store_explicit(&dpbp_dev->in_use, 0,
+						  rte_memory_order_release);
 			return;
 		}
 	}
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpci.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpci.c
index b546da82f6..789282085b 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpci.c
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpci.c
@@ -135,7 +135,7 @@ rte_dpaa2_create_dpci_device(int vdev_fd __rte_unused,
 	}
 
 	dpci_node->dpci_id = dpci_id;
-	rte_atomic16_init(&dpci_node->in_use);
+	dpci_node->in_use = 0;
 
 	TAILQ_INSERT_TAIL(&dpci_dev_list, dpci_node, next);
 
@@ -159,7 +159,10 @@ struct dpaa2_dpci_dev *rte_dpaa2_alloc_dpci_dev(void)
 
 	/* Get DPCI dev handle from list using index */
 	TAILQ_FOREACH(dpci_dev, &dpci_dev_list, next) {
-		if (dpci_dev && rte_atomic16_test_and_set(&dpci_dev->in_use))
+		uint32_t expected = 0;
+		if (rte_atomic_compare_exchange_strong_explicit(
+			    &dpci_dev->in_use, &expected, 1,
+			    rte_memory_order_acquire, rte_memory_order_relaxed))
 			break;
 	}
 
@@ -174,7 +177,8 @@ void rte_dpaa2_free_dpci_dev(struct dpaa2_dpci_dev *dpci)
 	/* Match DPCI handle and mark it free */
 	TAILQ_FOREACH(dpci_dev, &dpci_dev_list, next) {
 		if (dpci_dev == dpci) {
-			rte_atomic16_dec(&dpci_dev->in_use);
+			rte_atomic_store_explicit(&dpci_dev->in_use, 0,
+						  rte_memory_order_release);
 			return;
 		}
 	}
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index 2a9e519668..4d89915c29 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
@@ -293,7 +293,7 @@ static void dpaa2_put_qbman_swp(struct dpaa2_dpio_dev *dpio_dev)
 #ifdef RTE_EVENT_DPAA2
 		dpaa2_dpio_intr_deinit(dpio_dev);
 #endif
-		rte_atomic16_clear(&dpio_dev->ref_count);
+		rte_atomic_store_explicit(&dpio_dev->ref_count, 0, rte_memory_order_release);
 	}
 }
 
@@ -305,7 +305,10 @@ static struct dpaa2_dpio_dev *dpaa2_get_qbman_swp(void)
 
 	/* Get DPIO dev handle from list using index */
 	TAILQ_FOREACH(dpio_dev, &dpio_dev_list, next) {
-		if (dpio_dev && rte_atomic16_test_and_set(&dpio_dev->ref_count))
+		uint32_t expected = 0;
+		if (rte_atomic_compare_exchange_strong_explicit(
+			    &dpio_dev->ref_count, &expected, 1,
+			    rte_memory_order_acquire, rte_memory_order_relaxed))
 			break;
 	}
 	if (!dpio_dev) {
@@ -326,7 +329,8 @@ static struct dpaa2_dpio_dev *dpaa2_get_qbman_swp(void)
 		ret = dpaa2_configure_stashing(dpio_dev, cpu_id);
 		if (ret) {
 			DPAA2_BUS_ERR("dpaa2_configure_stashing failed");
-			rte_atomic16_clear(&dpio_dev->ref_count);
+			rte_atomic_store_explicit(&dpio_dev->ref_count, 0,
+						  rte_memory_order_release);
 			return NULL;
 		}
 	}
@@ -441,7 +445,7 @@ dpaa2_create_dpio_device(int vdev_fd,
 
 	dpio_dev->dpio = NULL;
 	dpio_dev->hw_id = object_id;
-	rte_atomic16_init(&dpio_dev->ref_count);
+
 	/* Using single portal  for all devices */
 	dpio_dev->mc_portal = dpaa2_get_mcp_ptr(MC_PORTAL_INDEX);
 
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
index e625a5c035..f2298b18e5 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_pvt.h
@@ -112,7 +112,7 @@ struct dpaa2_dpio_dev {
 	TAILQ_ENTRY(dpaa2_dpio_dev) next;
 		/**< Pointer to Next device instance */
 	uint16_t index; /**< Index of a instance in the list */
-	rte_atomic16_t ref_count;
+	RTE_ATOMIC(uint16_t) ref_count;
 		/**< How many thread contexts are sharing this.*/
 	uint16_t eqresp_ci;
 	uint16_t eqresp_pi;
@@ -141,7 +141,7 @@ struct dpaa2_dpbp_dev {
 		/**< Pointer to Next device instance */
 	struct fsl_mc_io dpbp;  /** handle to DPBP portal object */
 	uint16_t token;
-	rte_atomic16_t in_use;
+	RTE_ATOMIC(uint16_t) in_use;
 	uint32_t dpbp_id; /*HW ID for DPBP object */
 };
 
@@ -257,7 +257,7 @@ struct dpaa2_dpci_dev {
 		/**< Pointer to Next device instance */
 	struct fsl_mc_io dpci;  /** handle to DPCI portal object */
 	uint16_t token;
-	rte_atomic16_t in_use;
+	RTE_ATOMIC(uint16_t) in_use;
 	uint32_t dpci_id; /*HW ID for DPCI object */
 	struct dpaa2_queue rx_queue[DPAA2_DPCI_MAX_QUEUES];
 	struct dpaa2_queue tx_queue[DPAA2_DPCI_MAX_QUEUES];
@@ -267,7 +267,7 @@ struct dpaa2_dpcon_dev {
 	TAILQ_ENTRY(dpaa2_dpcon_dev) next;
 	struct fsl_mc_io dpcon;
 	uint16_t token;
-	rte_atomic16_t in_use;
+	RTE_ATOMIC(uint16_t) in_use;
 	uint32_t dpcon_id;
 	uint16_t qbman_ch_id;
 	uint8_t num_priorities;
diff --git a/drivers/event/dpaa2/dpaa2_hw_dpcon.c b/drivers/event/dpaa2/dpaa2_hw_dpcon.c
index ea5b0d4b85..9240534448 100644
--- a/drivers/event/dpaa2/dpaa2_hw_dpcon.c
+++ b/drivers/event/dpaa2/dpaa2_hw_dpcon.c
@@ -15,6 +15,7 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_string_fns.h>
+#include <rte_stdatomic.h>
 #include <rte_cycles.h>
 #include <rte_kvargs.h>
 #include <dev_driver.h>
@@ -53,7 +54,7 @@ rte_dpaa2_create_dpcon_device(int dev_fd __rte_unused,
 	int ret, dpcon_id = obj->object_id;
 
 	/* Allocate DPAA2 dpcon handle */
-	dpcon_node = rte_malloc(NULL, sizeof(struct dpaa2_dpcon_dev), 0);
+	dpcon_node = rte_zmalloc(NULL, sizeof(struct dpaa2_dpcon_dev), 0);
 	if (!dpcon_node) {
 		DPAA2_EVENTDEV_ERR(
 				"Memory allocation failed for dpcon device");
@@ -85,7 +86,6 @@ rte_dpaa2_create_dpcon_device(int dev_fd __rte_unused,
 	dpcon_node->qbman_ch_id = attr.qbman_ch_id;
 	dpcon_node->num_priorities = attr.num_priorities;
 	dpcon_node->dpcon_id = dpcon_id;
-	rte_atomic16_init(&dpcon_node->in_use);
 
 	TAILQ_INSERT_TAIL(&dpcon_dev_list, dpcon_node, next);
 
@@ -98,7 +98,10 @@ struct dpaa2_dpcon_dev *rte_dpaa2_alloc_dpcon_dev(void)
 
 	/* Get DPCON dev handle from list using index */
 	TAILQ_FOREACH(dpcon_dev, &dpcon_dev_list, next) {
-		if (dpcon_dev && rte_atomic16_test_and_set(&dpcon_dev->in_use))
+		uint32_t expected = 0;
+		if (rte_atomic_compare_exchange_strong_explicit(
+			    &dpcon_dev->in_use, &expected, 1,
+			    rte_memory_order_acquire, rte_memory_order_relaxed))
 			break;
 	}
 
@@ -112,7 +115,7 @@ void rte_dpaa2_free_dpcon_dev(struct dpaa2_dpcon_dev *dpcon)
 	/* Match DPCON handle and mark it free */
 	TAILQ_FOREACH(dpcon_dev, &dpcon_dev_list, next) {
 		if (dpcon_dev == dpcon) {
-			rte_atomic16_dec(&dpcon_dev->in_use);
+			rte_atomic_store_explicit(&dpcon_dev->in_use, 0, rte_memory_order_release);
 			return;
 		}
 	}
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 15/27] net/netvsc: replace rte_atomic32 with stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Long Li, Wei Hu
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

Change the rndis transaction id and buffer usage to use
stdatomic functions.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/netvsc/hn_rndis.c | 28 +++++++++++++++++++---------
 drivers/net/netvsc/hn_rxtx.c  | 12 +++++++-----
 drivers/net/netvsc/hn_var.h   |  6 +++---
 3 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/drivers/net/netvsc/hn_rndis.c b/drivers/net/netvsc/hn_rndis.c
index 7c54eebcef..4b1d3d5539 100644
--- a/drivers/net/netvsc/hn_rndis.c
+++ b/drivers/net/netvsc/hn_rndis.c
@@ -17,7 +17,7 @@
 #include <rte_string_fns.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 #include <rte_alarm.h>
 #include <rte_branch_prediction.h>
 #include <rte_ether.h>
@@ -59,7 +59,8 @@ hn_rndis_rid(struct hn_data *hv)
 	uint32_t rid;
 
 	do {
-		rid = rte_atomic32_add_return(&hv->rndis_req_id, 1);
+		rid = rte_atomic_fetch_add_explicit(&hv->rndis_req_id, 1,
+						    rte_memory_order_seq_cst);
 	} while (rid == 0);
 
 	return rid;
@@ -357,12 +358,14 @@ void hn_rndis_receive_response(struct hn_data *hv,
 	memcpy(hv->rndis_resp, data, len);
 
 	/* make sure response copied before update */
-	rte_smp_wmb();
-
-	if (rte_atomic32_cmpset(&hv->rndis_pending, hdr->rid, 0) == 0) {
+	uint32_t expected = hdr->rid;
+	if (!rte_atomic_compare_exchange_strong_explicit(&hv->rndis_pending,
+							 &expected, 0,
+							 rte_memory_order_release,
+							 rte_memory_order_relaxed)) {
 		PMD_DRV_LOG(NOTICE,
 			    "received id %#x pending id %#x",
-			    hdr->rid, (uint32_t)hv->rndis_pending);
+			    hdr->rid, expected);
 	}
 }
 
@@ -388,8 +391,11 @@ static int hn_rndis_exec1(struct hn_data *hv,
 		return -EINVAL;
 	}
 
+	uint32_t expected = 0;
 	if (comp != NULL &&
-	    rte_atomic32_cmpset(&hv->rndis_pending, 0, rid) == 0) {
+	    !rte_atomic_compare_exchange_strong_explicit(
+		    &hv->rndis_pending, &expected, rid,
+		    rte_memory_order_acquire, rte_memory_order_relaxed)) {
 		PMD_DRV_LOG(ERR,
 			    "Request already pending");
 		return -EBUSY;
@@ -405,7 +411,8 @@ static int hn_rndis_exec1(struct hn_data *hv,
 		time_t start = time(NULL);
 
 		/* Poll primary channel until response received */
-		while (hv->rndis_pending == rid) {
+		while (rte_atomic_load_explicit(&hv->rndis_pending,
+						rte_memory_order_acquire) == rid) {
 			if (hv->closed)
 				return -ENETDOWN;
 
@@ -413,7 +420,10 @@ static int hn_rndis_exec1(struct hn_data *hv,
 				PMD_DRV_LOG(ERR,
 					    "RNDIS response timed out");
 
-				rte_atomic32_cmpset(&hv->rndis_pending, rid, 0);
+				expected = rid;
+				rte_atomic_compare_exchange_strong_explicit(
+					&hv->rndis_pending, &expected, 0,
+					rte_memory_order_release, rte_memory_order_relaxed);
 				return -ETIMEDOUT;
 			}
 
diff --git a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c
index 0d770d1b25..6f536610f2 100644
--- a/drivers/net/netvsc/hn_rxtx.c
+++ b/drivers/net/netvsc/hn_rxtx.c
@@ -17,7 +17,7 @@
 #include <rte_string_fns.h>
 #include <rte_memzone.h>
 #include <rte_malloc.h>
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 #include <rte_bitmap.h>
 #include <rte_branch_prediction.h>
 #include <rte_ether.h>
@@ -558,7 +558,8 @@ static void hn_rx_buf_free_cb(void *buf __rte_unused, void *opaque)
 	struct hn_rx_queue *rxq = rxb->rxq;
 	struct hn_data *hv = rxq->hv;
 
-	rte_atomic32_dec(&rxq->rxbuf_outstanding);
+	rte_atomic_fetch_sub_explicit(&rxq->rxbuf_outstanding, 1,
+				      rte_memory_order_release);
 	hn_nvs_ack_rxbuf(hv, rxb->chan, rxb->xactid);
 }
 
@@ -602,8 +603,8 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
 	 * some space available in receive area for later packets.
 	 */
 	if (hv->rx_extmbuf_enable && dlen > hv->rx_copybreak &&
-	    (uint32_t)rte_atomic32_read(&rxq->rxbuf_outstanding) <
-			hv->rxbuf_section_cnt / 2) {
+	    rte_atomic_load_explicit(&rxq->rxbuf_outstanding,
+				     rte_memory_order_relaxed) < hv->rxbuf_section_cnt / 2) {
 		struct rte_mbuf_ext_shared_info *shinfo;
 		const void *rxbuf;
 		rte_iova_t iova;
@@ -619,7 +620,8 @@ static void hn_rxpkt(struct hn_rx_queue *rxq, struct hn_rx_bufinfo *rxb,
 
 		/* shinfo is already set to 1 by the caller */
 		if (rte_mbuf_ext_refcnt_update(shinfo, 1) == 2)
-			rte_atomic32_inc(&rxq->rxbuf_outstanding);
+			rte_atomic_fetch_add_explicit(&rxq->rxbuf_outstanding, 1,
+						      rte_memory_order_acquire);
 
 		rte_pktmbuf_attach_extbuf(m, data, iova,
 					  dlen + headroom, shinfo);
diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h
index ef55dee28e..b0929de790 100644
--- a/drivers/net/netvsc/hn_var.h
+++ b/drivers/net/netvsc/hn_var.h
@@ -85,7 +85,7 @@ struct hn_rx_queue {
 
 	void *event_buf;
 	struct hn_rx_bufinfo *rxbuf_info;
-	rte_atomic32_t  rxbuf_outstanding;
+	RTE_ATOMIC(uint32_t) rxbuf_outstanding;
 };
 
 
@@ -166,8 +166,8 @@ struct hn_data {
 	uint32_t	rndis_agg_pkts;
 	uint32_t	rndis_agg_align;
 
-	volatile uint32_t  rndis_pending;
-	rte_atomic32_t	rndis_req_id;
+	RTE_ATOMIC(uint32_t) rndis_pending;
+	RTE_ATOMIC(uint32_t) rndis_req_id;
 	uint8_t		rndis_resp[256];
 
 	uint32_t	rss_hash;
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 16/27] event/sw: convert from rte_atomic32 to stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

Use stdatomic to keep track of inflights.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/event/sw/sw_evdev.c        |  8 +++++---
 drivers/event/sw/sw_evdev.h        |  4 ++--
 drivers/event/sw/sw_evdev_worker.c | 16 +++++++++++-----
 3 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/event/sw/sw_evdev.c b/drivers/event/sw/sw_evdev.c
index 3ad82e94ac..a2f760a98d 100644
--- a/drivers/event/sw/sw_evdev.c
+++ b/drivers/event/sw/sw_evdev.c
@@ -153,7 +153,9 @@ sw_port_setup(struct rte_eventdev *dev, uint8_t port_id,
 		 * the sum to no leak credits
 		 */
 		int possible_inflights = p->inflight_credits + p->inflights;
-		rte_atomic32_sub(&sw->inflights, possible_inflights);
+		rte_atomic_fetch_sub_explicit(&sw->inflights,
+					      possible_inflights,
+					      rte_memory_order_release);
 	}
 
 	*p = (struct sw_port){0}; /* zero entire structure */
@@ -512,7 +514,7 @@ sw_dev_configure(const struct rte_eventdev *dev)
 	sw->qid_count = conf->nb_event_queues;
 	sw->port_count = conf->nb_event_ports;
 	sw->nb_events_limit = conf->nb_events_limit;
-	rte_atomic32_set(&sw->inflights, 0);
+	sw->inflights = 0;
 
 	/* Number of chunks sized for worst-case spread of events across IQs */
 	num_chunks = ((SW_INFLIGHT_EVENTS_TOTAL/SW_EVS_PER_Q_CHUNK)+1) +
@@ -633,7 +635,7 @@ sw_dump(struct rte_eventdev *dev, FILE *f)
 	fprintf(f, "\tsched cq/qid call: %"PRIu64"\n", sw->sched_cq_qid_called);
 	fprintf(f, "\tsched no IQ enq: %"PRIu64"\n", sw->sched_no_iq_enqueues);
 	fprintf(f, "\tsched no CQ enq: %"PRIu64"\n", sw->sched_no_cq_enqueues);
-	uint32_t inflights = rte_atomic32_read(&sw->inflights);
+	uint32_t inflights = rte_atomic_load_explicit(&sw->inflights, rte_memory_order_relaxed);
 	uint32_t credits = sw->nb_events_limit - inflights;
 	fprintf(f, "\tinflight %d, credits: %d\n", inflights, credits);
 
diff --git a/drivers/event/sw/sw_evdev.h b/drivers/event/sw/sw_evdev.h
index c159be21be..5e49b08030 100644
--- a/drivers/event/sw/sw_evdev.h
+++ b/drivers/event/sw/sw_evdev.h
@@ -8,7 +8,7 @@
 #include "sw_evdev_log.h"
 #include <rte_eventdev.h>
 #include <eventdev_pmd_vdev.h>
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 
 #define SW_DEFAULT_CREDIT_QUANTA 32
 #define SW_DEFAULT_SCHED_QUANTA 128
@@ -233,7 +233,7 @@ struct sw_evdev {
 	/* Contains all ports - load balanced and directed */
 	alignas(RTE_CACHE_LINE_SIZE) struct sw_port ports[SW_PORTS_MAX];
 
-	alignas(RTE_CACHE_LINE_SIZE) rte_atomic32_t inflights;
+	alignas(RTE_CACHE_LINE_SIZE) RTE_ATOMIC(uint32_t) inflights;
 
 	/*
 	 * max events in this instance. Cached here for performance.
diff --git a/drivers/event/sw/sw_evdev_worker.c b/drivers/event/sw/sw_evdev_worker.c
index 4215726513..0755def367 100644
--- a/drivers/event/sw/sw_evdev_worker.c
+++ b/drivers/event/sw/sw_evdev_worker.c
@@ -56,7 +56,7 @@ sw_event_enqueue_burst(void *port, const struct rte_event ev[], uint16_t num)
 	uint8_t new_ops[PORT_ENQUEUE_MAX_BURST_SIZE];
 	struct sw_port *p = port;
 	struct sw_evdev *sw = (void *)p->sw;
-	uint32_t sw_inflights = rte_atomic32_read(&sw->inflights);
+	uint32_t sw_inflights = rte_atomic_load_explicit(&sw->inflights, rte_memory_order_relaxed);
 	uint32_t credit_update_quanta = sw->credit_update_quanta;
 	int new = 0;
 
@@ -74,8 +74,10 @@ sw_event_enqueue_burst(void *port, const struct rte_event ev[], uint16_t num)
 		if (sw_inflights + credit_update_quanta > sw->nb_events_limit)
 			return 0;
 
-		rte_atomic32_add(&sw->inflights, credit_update_quanta);
-		p->inflight_credits += (credit_update_quanta);
+		rte_atomic_fetch_add_explicit(&sw->inflights,
+					      credit_update_quanta,
+					      rte_memory_order_acquire);
+		p->inflight_credits += credit_update_quanta;
 
 		/* If there are fewer inflight credits than new events, limit
 		 * the number of enqueued events.
@@ -124,7 +126,9 @@ sw_event_enqueue_burst(void *port, const struct rte_event ev[], uint16_t num)
 
 	/* Replenish credits if enough releases are performed */
 	if (p->inflight_credits >= credit_update_quanta * 2) {
-		rte_atomic32_sub(&sw->inflights, credit_update_quanta);
+		rte_atomic_fetch_sub_explicit(&sw->inflights,
+					      credit_update_quanta,
+					      rte_memory_order_release);
 		p->inflight_credits -= credit_update_quanta;
 	}
 
@@ -150,7 +154,9 @@ sw_event_dequeue_burst(void *port, struct rte_event *ev, uint16_t num,
 
 		/* Replenish credits if enough releases are performed */
 		if (p->inflight_credits >= credit_update_quanta * 2) {
-			rte_atomic32_sub(&sw->inflights, credit_update_quanta);
+			rte_atomic_fetch_sub_explicit(&sw->inflights,
+						      credit_update_quanta,
+						      rte_memory_order_release);
 			p->inflight_credits -= credit_update_quanta;
 		}
 	}
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 17/27] bus/vmbus: convert from rte_atomic to stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Long Li, Wei Hu
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

Replace deprecated rte_atomic32 operations in the vmbus ring buffer
producer with stdatomic equivalents, and replace the smp_wmb + CAS-spin
publish with rte_wait_until_equal_32 + release-store.

The two-cursor design is preserved: tbr->windex is the driver-private
reservation cursor that lets producers reserve slots concurrently
without a lock; vbr->windex is the host-visible commit cursor, updated
in reservation order so the host never observes windex pointing past
unwritten data. This is the lockless analogue of the spinlock-around-
single-cursor pattern used by the Linux (drivers/hv/ring_buffer.c
hv_ringbuffer_write) and FreeBSD (sys/dev/hyperv/vmbus/vmbus_br.c
vmbus_txbr_write) implementations of the same host contract.

The memory ordering mirrors __rte_ring_headtail_move_head and
__rte_ring_update_tail in lib/ring/rte_ring_c11_pvt.h: relaxed wait
for the previous producer's commit, release-store to publish. The
rte_smp_wmb before the publish is folded into the release ordering
on the store itself.

The host-shared vbr->windex remains volatile uint32_t in the packed
bufring struct; the atomic qualifier is added via cast at the access
site. The (uintptr_t) launder on the store-side cast suppresses a
spurious misaligned-atomic warning from the packed-struct attribute
(windex is 4-byte aligned in practice, at offset 0 of a page-aligned
struct).

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/bus/vmbus/private.h       |  2 +-
 drivers/bus/vmbus/vmbus_bufring.c | 39 +++++++++++++++++--------------
 2 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/bus/vmbus/private.h b/drivers/bus/vmbus/private.h
index 8ac6119ef2..42c4e81ac0 100644
--- a/drivers/bus/vmbus/private.h
+++ b/drivers/bus/vmbus/private.h
@@ -41,7 +41,7 @@ extern int vmbus_logtype_bus;
 struct vmbus_br {
 	struct vmbus_bufring *vbr;
 	uint32_t	dsize;
-	uint32_t	windex; /* next available location */
+	RTE_ATOMIC(uint32_t) windex; /* next available location */
 };
 
 #define UIO_NAME_MAX 64
diff --git a/drivers/bus/vmbus/vmbus_bufring.c b/drivers/bus/vmbus/vmbus_bufring.c
index fcb97287dc..624fe8b6c5 100644
--- a/drivers/bus/vmbus/vmbus_bufring.c
+++ b/drivers/bus/vmbus/vmbus_bufring.c
@@ -15,7 +15,7 @@
 #include <rte_tailq.h>
 #include <rte_log.h>
 #include <rte_malloc.h>
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 #include <rte_memory.h>
 #include <rte_pause.h>
 #include <rte_bus_vmbus.h>
@@ -114,6 +114,7 @@ vmbus_txbr_write(struct vmbus_br *tbr, const struct iovec iov[], int iovlen,
 	uint32_t ring_size = tbr->dsize;
 	uint32_t old_windex, next_windex, windex, total;
 	uint64_t save_windex;
+	bool success;
 	int i;
 
 	total = 0;
@@ -121,17 +122,13 @@ vmbus_txbr_write(struct vmbus_br *tbr, const struct iovec iov[], int iovlen,
 		total += iov[i].iov_len;
 	total += sizeof(save_windex);
 
+	/* Get current free location */
+	old_windex = rte_atomic_load_explicit(&tbr->windex,
+					      rte_memory_order_relaxed);
+
 	/* Reserve space in ring */
 	do {
-		uint32_t avail;
-
-		/* Get current free location */
-		old_windex = tbr->windex;
-
-		/* Prevent compiler reordering this with calculation */
-		rte_compiler_barrier();
-
-		avail = vmbus_br_availwrite(tbr, old_windex);
+		uint32_t avail = vmbus_br_availwrite(tbr, old_windex);
 
 		/* If not enough space in ring, then tell caller. */
 		if (avail <= total)
@@ -139,8 +136,13 @@ vmbus_txbr_write(struct vmbus_br *tbr, const struct iovec iov[], int iovlen,
 
 		next_windex = vmbus_br_idxinc(old_windex, total, ring_size);
 
-		/* Atomic update of next write_index for other threads */
-	} while (!rte_atomic32_cmpset(&tbr->windex, old_windex, next_windex));
+		/* Atomic update of next write_index for other threads
+		 * Can use weak since easy to recompute and retry.
+		 */
+		success = rte_atomic_compare_exchange_weak_explicit(
+				&tbr->windex, &old_windex, next_windex,
+				rte_memory_order_acquire, rte_memory_order_relaxed);
+	} while (unlikely(!success));
 
 	/* Space from old..new is now reserved */
 	windex = old_windex;
@@ -157,12 +159,15 @@ vmbus_txbr_write(struct vmbus_br *tbr, const struct iovec iov[], int iovlen,
 	/* The region reserved should match region used */
 	RTE_ASSERT(windex == next_windex);
 
-	/* Ensure that data is available before updating host index */
-	rte_smp_wmb();
+	/* Wait for previous producer to publish their windex update */
+	rte_wait_until_equal_32(&vbr->windex, old_windex, rte_memory_order_relaxed);
 
-	/* Checkin for our reservation. wait for our turn to update host */
-	while (!rte_atomic32_cmpset(&vbr->windex, old_windex, next_windex))
-		rte_pause();
+	/* Publish our windex update; prior data writes ordered via release.
+	 * windex is 4-byte aligned in practice (struct is page-aligned, windex
+	 * at offset 0); cast launders the packed-struct alignment-1 attribute.
+	 */
+	rte_atomic_store_explicit((volatile __rte_atomic uint32_t *)(uintptr_t)&vbr->windex,
+				  next_windex, rte_memory_order_release);
 
 	/* If host had read all data before this, then need to signal */
 	*need_sig |= vmbus_txbr_need_signal(vbr, old_windex);
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 18/27] common/dpaax: remove unused atomic macros
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Hemant Agrawal, Sachin Saxena
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

Driver copy/pasted some macros defining abstraction around
the now deprecated rte_atomic32. Dead code removed.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/common/dpaax/compat.h | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/drivers/common/dpaax/compat.h b/drivers/common/dpaax/compat.h
index d0635255da..580620caf0 100644
--- a/drivers/common/dpaax/compat.h
+++ b/drivers/common/dpaax/compat.h
@@ -365,20 +365,6 @@ static inline unsigned long get_zeroed_page(gfp_t __foo __rte_unused)
 #define spin_lock_irqsave(x, f) spin_lock_irq(x)
 #define spin_unlock_irqrestore(x, f) spin_unlock_irq(x)
 
-#define atomic_t                rte_atomic32_t
-#define atomic_read(v)          rte_atomic32_read(v)
-#define atomic_set(v, i)        rte_atomic32_set(v, i)
-
-#define atomic_inc(v)           rte_atomic32_add(v, 1)
-#define atomic_dec(v)           rte_atomic32_sub(v, 1)
-
-#define atomic_inc_and_test(v)  rte_atomic32_inc_and_test(v)
-#define atomic_dec_and_test(v)  rte_atomic32_dec_and_test(v)
-
-#define atomic_inc_return(v)    rte_atomic32_add_return(v, 1)
-#define atomic_dec_return(v)    rte_atomic32_sub_return(v, 1)
-#define atomic_sub_and_test(i, v) (rte_atomic32_sub_return(v, i) == 0)
-
 /* Interface name len*/
 #define IF_NAME_MAX_LEN 16
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 19/27] net/bnx2x: convert from rte_atomic32 to stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Julien Aube
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

Replace the legacy rte_atomic32_* API on sc->scan_fp with the
equivalent rte_atomic_*_explicit C11 helpers, ahead of the
deprecation of rte_atomicNN_t and its associated wrappers.

All accesses use rte_memory_order_seq_cst, matching the semantics
of the legacy API. No functional change.

The scan_fp field is a notification flag between the slow-path
command poster (bnx2x_sp_post) and the fastpath task that reaps
ramrod completions (bnx2x_handle_fp_tq), also cleared from
ecore_state_wait on success, panic, and timeout.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/bnx2x/bnx2x.c    | 6 +++---
 drivers/net/bnx2x/bnx2x.h    | 2 +-
 drivers/net/bnx2x/ecore_sp.c | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x.c b/drivers/net/bnx2x/bnx2x.c
index 8790c858d5..027a0a50d5 100644
--- a/drivers/net/bnx2x/bnx2x.c
+++ b/drivers/net/bnx2x/bnx2x.c
@@ -1098,7 +1098,7 @@ bnx2x_sp_post(struct bnx2x_softc *sc, int command, int cid, uint32_t data_hi,
 	 * Ask bnx2x_intr_intr() to process RAMROD
 	 * completion whenever it gets scheduled.
 	 */
-	rte_atomic32_set(&sc->scan_fp, 1);
+	rte_atomic_store_explicit(&sc->scan_fp, 1, rte_memory_order_seq_cst);
 	bnx2x_sp_prod_update(sc);
 
 	return 0;
@@ -4575,7 +4575,7 @@ static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp)
 	/* update the fastpath index */
 	bnx2x_update_fp_sb_idx(fp);
 
-	if (rte_atomic32_read(&sc->scan_fp) == 1) {
+	if (rte_atomic_load_explicit(&sc->scan_fp, rte_memory_order_seq_cst)) {
 		if (bnx2x_has_rx_work(fp)) {
 			more_rx = bnx2x_rxeof(sc, fp);
 		}
@@ -4586,7 +4586,7 @@ static void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp)
 			return;
 		}
 		/* We have completed slow path completion, clear the flag */
-		rte_atomic32_set(&sc->scan_fp, 0);
+		rte_atomic_store_explicit(&sc->scan_fp, 0, rte_memory_order_seq_cst);
 	}
 
 	bnx2x_ack_sb(sc, fp->igu_sb_id, USTORM_ID,
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 35206b4758..c5de4b71aa 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -1043,7 +1043,7 @@ struct bnx2x_softc {
 #define PERIODIC_STOP 0
 #define PERIODIC_GO   1
 	volatile unsigned long periodic_flags;
-	rte_atomic32_t	scan_fp;
+	RTE_ATOMIC(uint32_t) scan_fp;
 	struct bnx2x_fastpath fp[MAX_RSS_CHAINS];
 	struct bnx2x_sp_objs  sp_objs[MAX_RSS_CHAINS];
 
diff --git a/drivers/net/bnx2x/ecore_sp.c b/drivers/net/bnx2x/ecore_sp.c
index c6c3857778..33a40dea6e 100644
--- a/drivers/net/bnx2x/ecore_sp.c
+++ b/drivers/net/bnx2x/ecore_sp.c
@@ -299,21 +299,21 @@ static int ecore_state_wait(struct bnx2x_softc *sc, int state,
 #ifdef ECORE_STOP_ON_ERROR
 			ECORE_MSG(sc, "exit  (cnt %d)", 5000 - cnt);
 #endif
-			rte_atomic32_set(&sc->scan_fp, 0);
+			rte_atomic_store_explicit(&sc->scan_fp, 0, rte_memory_order_seq_cst);
 			return ECORE_SUCCESS;
 		}
 
 		ECORE_WAIT(sc, delay_us);
 
 		if (sc->panic) {
-			rte_atomic32_set(&sc->scan_fp, 0);
+			rte_atomic_store_explicit(&sc->scan_fp, 0, rte_memory_order_seq_cst);
 			return ECORE_IO;
 		}
 	}
 
 	/* timeout! */
 	PMD_DRV_LOG(ERR, sc, "timeout waiting for state %d", state);
-	rte_atomic32_set(&sc->scan_fp, 0);
+	rte_atomic_store_explicit(&sc->scan_fp, 0, rte_memory_order_seq_cst);
 #ifdef ECORE_STOP_ON_ERROR
 	ecore_panic();
 #endif
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 21/27] drivers/event: replace rte_atomic32 in selftests
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Hemant Agrawal, Sachin Saxena, Jerin Jacob
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

Last callers in these selftests of the rte_atomicNN_*() family,
which is being deprecated.

Convert total_events from rte_atomic32_t to RTE_ATOMIC(uint32_t)
for the stack-local instance and __rte_atomic uint32_t * for the
pointer in test_core_param. Switch reads and updates to
rte_atomic_*_explicit().

Reads in the busy-loop checks and progress logs use relaxed: the
counter is purely a "drained yet?" signal and no data is published
through it. The fetch_sub on the dequeue path uses release in
octeontx (preserving the publish-after-mbuf-free ordering already
implied by the seq_cst sub it replaces) and relaxed in dpaa2.

The stack-local atomic_total_events is initialized by direct
assignment instead of rte_atomic32_set(), since it is written
before any worker is launched.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/event/dpaa2/dpaa2_eventdev_selftest.c | 26 +++++----
 drivers/event/octeontx/ssovf_evdev_selftest.c | 58 ++++++++++---------
 2 files changed, 46 insertions(+), 38 deletions(-)

diff --git a/drivers/event/dpaa2/dpaa2_eventdev_selftest.c b/drivers/event/dpaa2/dpaa2_eventdev_selftest.c
index 9d4938efe6..2c688bd194 100644
--- a/drivers/event/dpaa2/dpaa2_eventdev_selftest.c
+++ b/drivers/event/dpaa2/dpaa2_eventdev_selftest.c
@@ -2,7 +2,7 @@
  * Copyright 2018-2019 NXP
  */
 
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
 #include <rte_debug.h>
@@ -49,7 +49,7 @@ struct event_attr {
 };
 
 struct test_core_param {
-	rte_atomic32_t *total_events;
+	__rte_atomic uint32_t *total_events;
 	uint64_t dequeue_tmo_ticks;
 	uint8_t port;
 	uint8_t sched_type;
@@ -444,10 +444,10 @@ worker_multi_port_fn(void *arg)
 	struct rte_event ev;
 	uint16_t valid_event;
 	uint8_t port = param->port;
-	rte_atomic32_t *total_events = param->total_events;
+	__rte_atomic uint32_t *total_events = param->total_events;
 	int ret;
 
-	while (rte_atomic32_read(total_events) > 0) {
+	while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
 		valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
 		if (!valid_event)
 			continue;
@@ -455,13 +455,15 @@ worker_multi_port_fn(void *arg)
 		ret = validate_event(&ev);
 		RTE_TEST_ASSERT_SUCCESS(ret, "Failed to validate event");
 		rte_pktmbuf_free(ev.mbuf);
-		rte_atomic32_sub(total_events, 1);
+
+		rte_atomic_fetch_sub_explicit(total_events, 1,
+					      rte_memory_order_relaxed);
 	}
 	return 0;
 }
 
 static int
-wait_workers_to_join(int lcore, const rte_atomic32_t *count)
+wait_workers_to_join(int lcore, const __rte_atomic uint32_t *count)
 {
 	uint64_t cycles, print_cycles;
 
@@ -472,15 +474,15 @@ wait_workers_to_join(int lcore, const rte_atomic32_t *count)
 		uint64_t new_cycles = rte_get_timer_cycles();
 
 		if (new_cycles - print_cycles > rte_get_timer_hz()) {
-			dpaa2_evdev_dbg("\r%s: events %d", __func__,
-				rte_atomic32_read(count));
+			dpaa2_evdev_dbg("\r%s: events %u", __func__,
+					rte_atomic_load_explicit(count, rte_memory_order_relaxed));
 			print_cycles = new_cycles;
 		}
 		if (new_cycles - cycles > rte_get_timer_hz() * 10) {
 			dpaa2_evdev_info(
-				"%s: No schedules for seconds, deadlock (%d)",
+				"%s: No schedules for seconds, deadlock (%u)",
 				__func__,
-				rte_atomic32_read(count));
+				rte_atomic_load_explicit(count, rte_memory_order_relaxed));
 			rte_event_dev_dump(evdev, stdout);
 			cycles = new_cycles;
 			return -1;
@@ -500,13 +502,13 @@ launch_workers_and_wait(int (*main_worker)(void *),
 	int w_lcore;
 	int ret;
 	struct test_core_param *param;
-	rte_atomic32_t atomic_total_events;
+	RTE_ATOMIC(uint32_t) atomic_total_events;
 	uint64_t dequeue_tmo_ticks;
 
 	if (!nb_workers)
 		return 0;
 
-	rte_atomic32_set(&atomic_total_events, total_events);
+	atomic_total_events = total_events;
 	RTE_BUILD_BUG_ON(NUM_PACKETS < MAX_EVENTS);
 
 	param = malloc(sizeof(struct test_core_param) * nb_workers);
diff --git a/drivers/event/octeontx/ssovf_evdev_selftest.c b/drivers/event/octeontx/ssovf_evdev_selftest.c
index b54ae126d2..500762af78 100644
--- a/drivers/event/octeontx/ssovf_evdev_selftest.c
+++ b/drivers/event/octeontx/ssovf_evdev_selftest.c
@@ -4,7 +4,7 @@
 
 #include <stdlib.h>
 
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
 #include <rte_debug.h>
@@ -84,7 +84,7 @@ seqn_list_check(int limit)
 }
 
 struct test_core_param {
-	rte_atomic32_t *total_events;
+	__rte_atomic uint32_t *total_events;
 	uint64_t dequeue_tmo_ticks;
 	uint8_t port;
 	uint8_t sched_type;
@@ -558,10 +558,10 @@ worker_multi_port_fn(void *arg)
 	struct rte_event ev;
 	uint16_t valid_event;
 	uint8_t port = param->port;
-	rte_atomic32_t *total_events = param->total_events;
+	__rte_atomic uint32_t *total_events = param->total_events;
 	int ret;
 
-	while (rte_atomic32_read(total_events) > 0) {
+	while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
 		valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
 		if (!valid_event)
 			continue;
@@ -569,13 +569,14 @@ worker_multi_port_fn(void *arg)
 		ret = validate_event(&ev);
 		RTE_TEST_ASSERT_SUCCESS(ret, "Failed to validate event");
 		rte_pktmbuf_free(ev.mbuf);
-		rte_atomic32_sub(total_events, 1);
+
+		rte_atomic_fetch_sub_explicit(total_events, 1, rte_memory_order_release);
 	}
 	return 0;
 }
 
 static inline int
-wait_workers_to_join(int lcore, const rte_atomic32_t *count)
+wait_workers_to_join(int lcore, const __rte_atomic uint32_t *count)
 {
 	uint64_t cycles, print_cycles;
 	RTE_SET_USED(count);
@@ -585,15 +586,15 @@ wait_workers_to_join(int lcore, const rte_atomic32_t *count)
 		uint64_t new_cycles = rte_get_timer_cycles();
 
 		if (new_cycles - print_cycles > rte_get_timer_hz()) {
-			ssovf_log_dbg("\r%s: events %d", __func__,
-				rte_atomic32_read(count));
+			ssovf_log_dbg("\r%s: events %u", __func__,
+				      rte_atomic_load_explicit(count, rte_memory_order_relaxed));
 			print_cycles = new_cycles;
 		}
 		if (new_cycles - cycles > rte_get_timer_hz() * 10) {
 			ssovf_log_dbg(
 				"%s: No schedules for seconds, deadlock (%d)",
 				__func__,
-				rte_atomic32_read(count));
+				rte_atomic_load_explicit(count, rte_memory_order_relaxed));
 			rte_event_dev_dump(evdev, stdout);
 			cycles = new_cycles;
 			return -1;
@@ -613,13 +614,13 @@ launch_workers_and_wait(int (*main_worker)(void *),
 	int w_lcore;
 	int ret;
 	struct test_core_param *param;
-	rte_atomic32_t atomic_total_events;
+	RTE_ATOMIC(uint32_t) atomic_total_events;
 	uint64_t dequeue_tmo_ticks;
 
 	if (!nb_workers)
 		return 0;
 
-	rte_atomic32_set(&atomic_total_events, total_events);
+	atomic_total_events = total_events;
 	seqn_list_init();
 
 	param = malloc(sizeof(struct test_core_param) * nb_workers);
@@ -889,10 +890,10 @@ worker_flow_based_pipeline(void *arg)
 	uint16_t valid_event;
 	uint8_t port = param->port;
 	uint8_t new_sched_type = param->sched_type;
-	rte_atomic32_t *total_events = param->total_events;
+	__rte_atomic uint32_t *total_events = param->total_events;
 	uint64_t dequeue_tmo_ticks = param->dequeue_tmo_ticks;
 
-	while (rte_atomic32_read(total_events) > 0) {
+	while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
 		valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1,
 					dequeue_tmo_ticks);
 		if (!valid_event)
@@ -910,7 +911,8 @@ worker_flow_based_pipeline(void *arg)
 		} else if (ev.sub_event_type == 1) { /* Events from stage 1*/
 			if (seqn_list_update(*rte_event_pmd_selftest_seqn(ev.mbuf)) == 0) {
 				rte_pktmbuf_free(ev.mbuf);
-				rte_atomic32_sub(total_events, 1);
+				rte_atomic_fetch_sub_explicit(total_events, 1,
+							      rte_memory_order_release);
 			} else {
 				ssovf_log_dbg("Failed to update seqn_list");
 				return -1;
@@ -1044,10 +1046,10 @@ worker_group_based_pipeline(void *arg)
 	uint16_t valid_event;
 	uint8_t port = param->port;
 	uint8_t new_sched_type = param->sched_type;
-	rte_atomic32_t *total_events = param->total_events;
+	__rte_atomic uint32_t *total_events = param->total_events;
 	uint64_t dequeue_tmo_ticks = param->dequeue_tmo_ticks;
 
-	while (rte_atomic32_read(total_events) > 0) {
+	while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
 		valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1,
 					dequeue_tmo_ticks);
 		if (!valid_event)
@@ -1065,7 +1067,8 @@ worker_group_based_pipeline(void *arg)
 		} else if (ev.queue_id == 1) { /* Events from stage 1(group 1)*/
 			if (seqn_list_update(*rte_event_pmd_selftest_seqn(ev.mbuf)) == 0) {
 				rte_pktmbuf_free(ev.mbuf);
-				rte_atomic32_sub(total_events, 1);
+				rte_atomic_fetch_sub_explicit(total_events, 1,
+							      rte_memory_order_release);
 			} else {
 				ssovf_log_dbg("Failed to update seqn_list");
 				return -1;
@@ -1203,16 +1206,17 @@ worker_flow_based_pipeline_max_stages_rand_sched_type(void *arg)
 	struct rte_event ev;
 	uint16_t valid_event;
 	uint8_t port = param->port;
-	rte_atomic32_t *total_events = param->total_events;
+	__rte_atomic uint32_t *total_events = param->total_events;
 
-	while (rte_atomic32_read(total_events) > 0) {
+	while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
 		valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
 		if (!valid_event)
 			continue;
 
 		if (ev.sub_event_type == 255) { /* last stage */
 			rte_pktmbuf_free(ev.mbuf);
-			rte_atomic32_sub(total_events, 1);
+			rte_atomic_fetch_sub_explicit(total_events, 1,
+							      rte_memory_order_release);
 		} else {
 			ev.event_type = RTE_EVENT_TYPE_CPU;
 			ev.sub_event_type++;
@@ -1278,16 +1282,17 @@ worker_queue_based_pipeline_max_stages_rand_sched_type(void *arg)
 			    RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
 			    &queue_count), "Queue count get failed");
 	uint8_t nr_queues = queue_count;
-	rte_atomic32_t *total_events = param->total_events;
+	__rte_atomic uint32_t *total_events = param->total_events;
 
-	while (rte_atomic32_read(total_events) > 0) {
+	while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
 		valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
 		if (!valid_event)
 			continue;
 
 		if (ev.queue_id == nr_queues - 1) { /* last stage */
 			rte_pktmbuf_free(ev.mbuf);
-			rte_atomic32_sub(total_events, 1);
+			rte_atomic_fetch_sub_explicit(total_events, 1,
+							      rte_memory_order_release);
 		} else {
 			ev.event_type = RTE_EVENT_TYPE_CPU;
 			ev.queue_id++;
@@ -1320,16 +1325,17 @@ worker_mixed_pipeline_max_stages_rand_sched_type(void *arg)
 			    RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
 			    &queue_count), "Queue count get failed");
 	uint8_t nr_queues = queue_count;
-	rte_atomic32_t *total_events = param->total_events;
+	__rte_atomic uint32_t *total_events = param->total_events;
 
-	while (rte_atomic32_read(total_events) > 0) {
+	while (rte_atomic_load_explicit(total_events, rte_memory_order_relaxed) > 0) {
 		valid_event = rte_event_dequeue_burst(evdev, port, &ev, 1, 0);
 		if (!valid_event)
 			continue;
 
 		if (ev.queue_id == nr_queues - 1) { /* Last stage */
 			rte_pktmbuf_free(ev.mbuf);
-			rte_atomic32_sub(total_events, 1);
+			rte_atomic_fetch_sub_explicit(total_events, 1,
+						      rte_memory_order_release);
 		} else {
 			ev.event_type = RTE_EVENT_TYPE_CPU;
 			ev.queue_id++;
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 24/27] net/vhost: use stdatomic instead of rte_atomic32
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Maxime Coquelin, Chenbo Xia
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

Convert allow_queuing, while_queuing, started, and dev_attached from
rte_atomic32_t to RTE_ATOMIC(uint32_t) and replace rte_atomic32_*()
with rte_atomic_*_explicit().

The data-path / control-thread handshake on allow_queuing and
while_queuing is a Dekker-style mutual-visibility pattern: each side
stores its own flag and then loads the peer's. Both legs must be
seq_cst to forbid store-load reordering; anything weaker permits both
sides to miss each other. The previous rte_atomic32_set/read compiled
to plain volatile stores/loads and provided no such ordering, so this
also closes a latent ordering hole on weakly-ordered ISAs.

The data-path exit store of while_queuing=0 is release, ordering
preceding slot accesses before the control thread observes the data
path as idle.

The flags started and dev_attached are consulted only inside
update_queuing_status, where the per-queue handshake provides the
real synchronization; their loads and stores are relaxed.

Factor the per-queue allow_queuing store and while_queuing wait into
a small update_queue() helper used by both rx and tx loops.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/vhost/rte_eth_vhost.c | 103 +++++++++++++++++++-----------
 1 file changed, 65 insertions(+), 38 deletions(-)

diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 05940f2461..3b1eedfe42 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -73,8 +73,8 @@ struct vhost_stats {
 
 struct vhost_queue {
 	int vid;
-	rte_atomic32_t allow_queuing;
-	rte_atomic32_t while_queuing;
+	RTE_ATOMIC(uint32_t) allow_queuing;
+	RTE_ATOMIC(uint32_t) while_queuing;
 	struct pmd_internal *internal;
 	struct rte_mempool *mb_pool;
 	uint16_t port;
@@ -86,14 +86,14 @@ struct vhost_queue {
 };
 
 struct pmd_internal {
-	rte_atomic32_t dev_attached;
+	RTE_ATOMIC(uint32_t) dev_attached;
 	char *iface_name;
 	uint64_t flags;
 	uint64_t disable_flags;
 	uint64_t features;
 	uint16_t max_queues;
 	int vid;
-	rte_atomic32_t started;
+	RTE_ATOMIC(uint32_t) started;
 	bool vlan_strip;
 	bool rx_sw_csum;
 	bool tx_sw_csum;
@@ -406,12 +406,19 @@ eth_vhost_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
 	uint16_t i, nb_rx = 0;
 	uint16_t nb_receive = nb_bufs;
 
-	if (unlikely(rte_atomic32_read(&r->allow_queuing) == 0))
+	/* Fast-path early exit; racy load is fine here -- if we miss a
+	 * transition we get caught by the seq_cst check below.
+	 */
+	if (unlikely(rte_atomic_load_explicit(&r->allow_queuing, rte_memory_order_relaxed) == 0))
 		return 0;
 
-	rte_atomic32_set(&r->while_queuing, 1);
-
-	if (unlikely(rte_atomic32_read(&r->allow_queuing) == 0))
+	/* Announce presence, then re-check. The store and the following
+	 * load MUST both be seq_cst so they are totally ordered with the
+	 * control thread's store-to-allow_queuing / load-of-while_queuing
+	 * pair. Anything weaker permits both sides to miss each other.
+	 */
+	rte_atomic_store_explicit(&r->while_queuing, 1, rte_memory_order_seq_cst);
+	if (unlikely(rte_atomic_load_explicit(&r->allow_queuing, rte_memory_order_seq_cst) == 0))
 		goto out;
 
 	/* Dequeue packets from guest TX queue */
@@ -446,7 +453,7 @@ eth_vhost_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
 	}
 
 out:
-	rte_atomic32_set(&r->while_queuing, 0);
+	rte_atomic_store_explicit(&r->while_queuing, 0, rte_memory_order_release);
 
 	return nb_rx;
 }
@@ -460,12 +467,19 @@ eth_vhost_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
 	uint64_t nb_bytes = 0;
 	uint64_t nb_missed = 0;
 
-	if (unlikely(rte_atomic32_read(&r->allow_queuing) == 0))
+	/* Fast-path early exit; racy load is fine here -- if we miss a
+	 * transition we get caught by the seq_cst check below.
+	 */
+	if (unlikely(rte_atomic_load_explicit(&r->allow_queuing, rte_memory_order_relaxed) == 0))
 		return 0;
 
-	rte_atomic32_set(&r->while_queuing, 1);
-
-	if (unlikely(rte_atomic32_read(&r->allow_queuing) == 0))
+	/* Announce presence, then re-check. The store and the following
+	 * load MUST both be seq_cst so they are totally ordered with the
+	 * control thread's store-to-allow_queuing / load-of-while_queuing
+	 * pair. Anything weaker permits both sides to miss each other.
+	 */
+	rte_atomic_store_explicit(&r->while_queuing, 1, rte_memory_order_seq_cst);
+	if (unlikely(rte_atomic_load_explicit(&r->allow_queuing, rte_memory_order_seq_cst) == 0))
 		goto out;
 
 	for (i = 0; i < nb_bufs; i++) {
@@ -515,7 +529,7 @@ eth_vhost_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
 	for (i = 0; likely(i < nb_tx); i++)
 		rte_pktmbuf_free(bufs[i]);
 out:
-	rte_atomic32_set(&r->while_queuing, 0);
+	rte_atomic_store_explicit(&r->while_queuing, 0, rte_memory_order_release);
 
 	return nb_tx;
 }
@@ -744,6 +758,19 @@ eth_vhost_unconfigure_intr(struct rte_eth_dev *eth_dev)
 	}
 }
 
+static inline void
+update_queue(struct vhost_queue *vq, uint32_t allow, bool wait_queuing)
+{
+	/* seq_cst: pairs with the data-path's seq_cst store of
+	 * while_queuing and seq_cst load of allow_queuing.  See
+	 * eth_vhost_rx().
+	 */
+	rte_atomic_store_explicit(&vq->allow_queuing, allow, rte_memory_order_seq_cst);
+	if (wait_queuing)
+		rte_wait_until_equal_32((volatile uint32_t *)(uintptr_t)&vq->while_queuing,
+					0, rte_memory_order_seq_cst);
+}
+
 static void
 update_queuing_status(struct rte_eth_dev *dev, bool wait_queuing)
 {
@@ -751,14 +778,18 @@ update_queuing_status(struct rte_eth_dev *dev, bool wait_queuing)
 	struct vhost_queue *vq;
 	struct rte_vhost_vring_state *state;
 	unsigned int i;
-	int allow_queuing = 1;
+	bool allow_queuing = true;
 
 	if (!dev->data->rx_queues || !dev->data->tx_queues)
 		return;
 
-	if (rte_atomic32_read(&internal->started) == 0 ||
-	    rte_atomic32_read(&internal->dev_attached) == 0)
-		allow_queuing = 0;
+	/* These are control-plane flags consulted only here;
+	 * the real data-path handshake is on vq->allow_queuing below.
+	 * Relaxed is sufficient.
+	 */
+	if (rte_atomic_load_explicit(&internal->started, rte_memory_order_relaxed) == 0 ||
+	    rte_atomic_load_explicit(&internal->dev_attached, rte_memory_order_relaxed) == 0)
+		allow_queuing = false;
 
 	state = vring_states[dev->data->port_id];
 
@@ -767,24 +798,18 @@ update_queuing_status(struct rte_eth_dev *dev, bool wait_queuing)
 		vq = dev->data->rx_queues[i];
 		if (vq == NULL)
 			continue;
-		if (allow_queuing && state->cur[vq->virtqueue_id])
-			rte_atomic32_set(&vq->allow_queuing, 1);
-		else
-			rte_atomic32_set(&vq->allow_queuing, 0);
-		while (wait_queuing && rte_atomic32_read(&vq->while_queuing))
-			rte_pause();
+
+		update_queue(vq, !!(allow_queuing && state->cur[vq->virtqueue_id]),
+			     wait_queuing);
 	}
 
 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
 		vq = dev->data->tx_queues[i];
 		if (vq == NULL)
 			continue;
-		if (allow_queuing && state->cur[vq->virtqueue_id])
-			rte_atomic32_set(&vq->allow_queuing, 1);
-		else
-			rte_atomic32_set(&vq->allow_queuing, 0);
-		while (wait_queuing && rte_atomic32_read(&vq->while_queuing))
-			rte_pause();
+
+		update_queue(vq, !!(allow_queuing && state->cur[vq->virtqueue_id]),
+			     wait_queuing);
 	}
 }
 
@@ -848,7 +873,7 @@ new_device(int vid)
 	}
 
 	internal->vid = vid;
-	if (rte_atomic32_read(&internal->started) == 1) {
+	if (rte_atomic_load_explicit(&internal->started, rte_memory_order_relaxed) == 1) {
 		queue_setup(eth_dev, internal);
 		if (dev_conf->intr_conf.rxq)
 			eth_vhost_configure_intr(eth_dev);
@@ -863,7 +888,7 @@ new_device(int vid)
 
 	vhost_dev_csum_configure(eth_dev);
 
-	rte_atomic32_set(&internal->dev_attached, 1);
+	rte_atomic_store_explicit(&internal->dev_attached, 1, rte_memory_order_relaxed);
 	update_queuing_status(eth_dev, false);
 
 	VHOST_LOG_LINE(INFO, "Vhost device %d created", vid);
@@ -893,7 +918,7 @@ destroy_device(int vid)
 	eth_dev = list->eth_dev;
 	internal = eth_dev->data->dev_private;
 
-	rte_atomic32_set(&internal->dev_attached, 0);
+	rte_atomic_store_explicit(&internal->dev_attached, 0, rte_memory_order_relaxed);
 	update_queuing_status(eth_dev, true);
 	eth_vhost_unconfigure_intr(eth_dev);
 
@@ -1148,11 +1173,11 @@ eth_dev_start(struct rte_eth_dev *eth_dev)
 	}
 
 	queue_setup(eth_dev, internal);
-	if (rte_atomic32_read(&internal->dev_attached) == 1 &&
+	if (rte_atomic_load_explicit(&internal->dev_attached, rte_memory_order_relaxed) == 1 &&
 			dev_conf->intr_conf.rxq)
 		eth_vhost_configure_intr(eth_dev);
 
-	rte_atomic32_set(&internal->started, 1);
+	rte_atomic_store_explicit(&internal->started, 1, rte_memory_order_relaxed);
 	update_queuing_status(eth_dev, false);
 
 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++)
@@ -1170,7 +1195,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
 	uint16_t i;
 
 	dev->data->dev_started = 0;
-	rte_atomic32_set(&internal->started, 0);
+	rte_atomic_store_explicit(&internal->started, 0, rte_memory_order_relaxed);
 	update_queuing_status(dev, true);
 
 	for (i = 0; i < dev->data->nb_rx_queues; i++)
@@ -1471,8 +1496,10 @@ vhost_dev_priv_dump(struct rte_eth_dev *dev, FILE *f)
 	fprintf(f, "features: 0x%" PRIx64 "\n", internal->features);
 	fprintf(f, "max_queues: %u\n", internal->max_queues);
 	fprintf(f, "vid: %d\n", internal->vid);
-	fprintf(f, "started: %d\n", rte_atomic32_read(&internal->started));
-	fprintf(f, "dev_attached: %d\n", rte_atomic32_read(&internal->dev_attached));
+	fprintf(f, "started: %u\n",
+		rte_atomic_load_explicit(&internal->started, rte_memory_order_relaxed));
+	fprintf(f, "dev_attached: %u\n",
+		rte_atomic_load_explicit(&internal->dev_attached, rte_memory_order_relaxed));
 	fprintf(f, "vlan_strip: %d\n", internal->vlan_strip);
 	fprintf(f, "rx_sw_csum: %d\n", internal->rx_sw_csum);
 	fprintf(f, "tx_sw_csum: %d\n", internal->tx_sw_csum);
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 25/27] vdpa/ifc: replace rte_atomic32 with stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

Last in-tree caller of rte_atomic32_*(), blocking deprecation of the
rte_atomicNN_*() family.

Replace rte_atomic32_read/set() with rte_atomic_load_explicit() and
rte_atomic_store_explicit() on the started, dev_attached, and running
flags. Narrow them to bool (only ever hold 0/1) and group with the
existing bools to reduce padding in struct ifcvf_internal.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/vdpa/ifc/ifcvf_vdpa.c | 37 ++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/vdpa/ifc/ifcvf_vdpa.c b/drivers/vdpa/ifc/ifcvf_vdpa.c
index f319d455ba..e5da11a2ba 100644
--- a/drivers/vdpa/ifc/ifcvf_vdpa.c
+++ b/drivers/vdpa/ifc/ifcvf_vdpa.c
@@ -25,6 +25,7 @@
 #include <rte_log.h>
 #include <rte_kvargs.h>
 #include <rte_devargs.h>
+#include <rte_stdatomic.h>
 
 #include "base/ifcvf.h"
 
@@ -68,10 +69,10 @@ struct ifcvf_internal {
 	struct rte_vdpa_device *vdev;
 	uint16_t max_queues;
 	uint64_t features;
-	rte_atomic32_t started;
-	rte_atomic32_t dev_attached;
-	rte_atomic32_t running;
 	rte_spinlock_t lock;
+	RTE_ATOMIC(bool) started;
+	RTE_ATOMIC(bool) dev_attached;
+	RTE_ATOMIC(bool) running;
 	bool sw_lm;
 	bool sw_fallback_running;
 	/* mediated vring for sw fallback */
@@ -712,9 +713,9 @@ update_datapath(struct ifcvf_internal *internal)
 
 	rte_spinlock_lock(&internal->lock);
 
-	if (!rte_atomic32_read(&internal->running) &&
-	    (rte_atomic32_read(&internal->started) &&
-	     rte_atomic32_read(&internal->dev_attached))) {
+	if (!rte_atomic_load_explicit(&internal->running, rte_memory_order_seq_cst) &&
+	    (rte_atomic_load_explicit(&internal->started, rte_memory_order_seq_cst) &&
+	     rte_atomic_load_explicit(&internal->dev_attached, rte_memory_order_seq_cst))) {
 		ret = ifcvf_dma_map(internal, true);
 		if (ret)
 			goto err;
@@ -735,10 +736,10 @@ update_datapath(struct ifcvf_internal *internal)
 		if (ret)
 			goto err;
 
-		rte_atomic32_set(&internal->running, 1);
-	} else if (rte_atomic32_read(&internal->running) &&
-		   (!rte_atomic32_read(&internal->started) ||
-		    !rte_atomic32_read(&internal->dev_attached))) {
+		rte_atomic_store_explicit(&internal->running, true, rte_memory_order_seq_cst);
+	} else if (rte_atomic_load_explicit(&internal->running, rte_memory_order_seq_cst) &&
+		   (!rte_atomic_load_explicit(&internal->started, rte_memory_order_seq_cst) ||
+		    !rte_atomic_load_explicit(&internal->dev_attached, rte_memory_order_seq_cst))) {
 		unset_intr_relay(internal);
 
 		ret = unset_notify_relay(internal);
@@ -755,7 +756,7 @@ update_datapath(struct ifcvf_internal *internal)
 		if (ret)
 			goto err;
 
-		rte_atomic32_set(&internal->running, 0);
+		rte_atomic_store_explicit(&internal->running, false, rte_memory_order_seq_cst);
 	}
 
 	rte_spinlock_unlock(&internal->lock);
@@ -1058,7 +1059,7 @@ ifcvf_sw_fallback_switchover(struct ifcvf_internal *internal)
 
 	vdpa_disable_vfio_intr(internal);
 
-	rte_atomic32_set(&internal->running, 0);
+	rte_atomic_store_explicit(&internal->running, false, rte_memory_order_seq_cst);
 
 	ret = rte_vhost_host_notifier_ctrl(vid, RTE_VHOST_QUEUE_ALL, false);
 	if (ret && ret != -ENOTSUP)
@@ -1113,11 +1114,11 @@ ifcvf_dev_config(int vid)
 
 	internal = list->internal;
 	internal->vid = vid;
-	rte_atomic32_set(&internal->dev_attached, 1);
+	rte_atomic_store_explicit(&internal->dev_attached, true, rte_memory_order_seq_cst);
 	if (update_datapath(internal) < 0) {
 		DRV_LOG(ERR, "failed to update datapath for vDPA device %s",
 			vdev->device->name);
-		rte_atomic32_set(&internal->dev_attached, 0);
+		rte_atomic_store_explicit(&internal->dev_attached, false, rte_memory_order_seq_cst);
 		return -1;
 	}
 
@@ -1166,7 +1167,7 @@ ifcvf_dev_close(int vid)
 
 		internal->sw_fallback_running = false;
 	} else {
-		rte_atomic32_set(&internal->dev_attached, 0);
+		rte_atomic_store_explicit(&internal->dev_attached, false, rte_memory_order_seq_cst);
 		if (update_datapath(internal) < 0) {
 			DRV_LOG(ERR, "failed to update datapath for vDPA device %s",
 				vdev->device->name);
@@ -1782,10 +1783,10 @@ ifcvf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 		goto error;
 	}
 
-	rte_atomic32_set(&internal->started, 1);
+	rte_atomic_store_explicit(&internal->started, true, rte_memory_order_seq_cst);
 	if (update_datapath(internal) < 0) {
 		DRV_LOG(ERR, "failed to update datapath %s", pci_dev->name);
-		rte_atomic32_set(&internal->started, 0);
+		rte_atomic_store_explicit(&internal->started, false, rte_memory_order_seq_cst);
 		rte_vdpa_unregister_device(internal->vdev);
 		pthread_mutex_lock(&internal_list_lock);
 		TAILQ_REMOVE(&internal_list, list, next);
@@ -1819,7 +1820,7 @@ ifcvf_pci_remove(struct rte_pci_device *pci_dev)
 	}
 
 	internal = list->internal;
-	rte_atomic32_set(&internal->started, 0);
+	rte_atomic_store_explicit(&internal->started, false, rte_memory_order_seq_cst);
 	if (update_datapath(internal) < 0)
 		DRV_LOG(ERR, "failed to update datapath %s", pci_dev->name);
 
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 27/27] eal: mark rte_atomicNN as deprecated
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Thomas Monjalon
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

The rte_atomicNN functions back in 2021 but code was still using these
functions. Now that all in tree code has been updated the functions
are marked with __rte_deprecated so that user code will get
see the deprecation.

Remove rte_atomicNN from checkpatches since usage is now
detected at compile time.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 devtools/checkpatches.sh               |  8 ---
 doc/guides/rel_notes/deprecation.rst   |  4 +-
 doc/guides/rel_notes/release_26_07.rst |  4 ++
 lib/eal/include/generic/rte_atomic.h   | 99 ++++++++++++++------------
 4 files changed, 59 insertions(+), 56 deletions(-)

diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index 81bb0fe4e8..a0cbbf09db 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -113,14 +113,6 @@ check_forbidden_additions() { # <patch>
 		-f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
 		"$1" || res=1
 
-	# refrain from new additions of 16/32/64 bits rte_atomicNN_xxx()
-	awk -v FOLDERS="lib drivers app examples" \
-		-v EXPRESSIONS="rte_atomic[0-9][0-9]_.*\\\(" \
-		-v RET_ON_FAIL=1 \
-		-v MESSAGE='Using rte_atomicNN_xxx' \
-		-f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
-		"$1" || res=1
-
 	# refrain from using compiler __sync_xxx builtins
 	awk -v FOLDERS="lib drivers app examples" \
 		-v EXPRESSIONS="__sync_.*\\\(" \
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 2190419f79..5d9226d551 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -43,9 +43,7 @@ Deprecation Notices
 * rte_atomicNN_xxx: These APIs do not take memory order parameter. This does
   not allow for writing optimized code for all the CPU architectures supported
   in DPDK. DPDK has adopted the atomic operations from
-  https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html. These
-  operations must be used for patches that need to be merged in 20.08 onwards.
-  This change will not introduce any performance degradation.
+  https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html.
 
 * lib: will fix extending some enum/define breaking the ABI. There are multiple
   samples in DPDK that enum/define terminated with a ``.*MAX.*`` value which is
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index f012d47a4b..2c8faffee9 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -92,6 +92,10 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* atomic: Marked the ``rte_atomicNN`` functions as deprecated.
+  As previously announced these functions were intended to be deprecated
+  but was not being enforced.
+
 
 ABI Changes
 -----------
diff --git a/lib/eal/include/generic/rte_atomic.h b/lib/eal/include/generic/rte_atomic.h
index 1b04b43cbb..b660f9fc1c 100644
--- a/lib/eal/include/generic/rte_atomic.h
+++ b/lib/eal/include/generic/rte_atomic.h
@@ -152,6 +152,13 @@ rte_smp_rmb(void)
 	rte_atomic_thread_fence(rte_memory_order_acquire);
 }
 
+/*
+ * The rte_atomicNN_* APIs defined below are deprecated in favour of C11 atomics.
+ * Suppress the deprecation warnings for the inlines to allow inter-related usage.
+ */
+__rte_diagnostic_push
+_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+
 /*------------------------- 16 bit atomic operations -------------------------*/
 
 #ifndef RTE_TOOLCHAIN_MSVC
@@ -172,7 +179,7 @@ rte_smp_rmb(void)
  * @return
  *   Non-zero on success; 0 on failure.
  */
-static inline int
+static __rte_deprecated inline int
 rte_atomic16_cmpset(volatile uint16_t *dst, uint16_t exp, uint16_t src)
 {
 	return __sync_bool_compare_and_swap(dst, exp, src);
@@ -193,7 +200,7 @@ rte_atomic16_cmpset(volatile uint16_t *dst, uint16_t exp, uint16_t src)
  * @return
  *   The original value at that location
  */
-static inline uint16_t
+static __rte_deprecated inline uint16_t
 rte_atomic16_exchange(volatile uint16_t *dst, uint16_t val)
 {
 	return rte_atomic_exchange_explicit((volatile __rte_atomic uint16_t *)dst,
@@ -218,7 +225,7 @@ typedef struct {
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic16_init(rte_atomic16_t *v)
 {
 	v->cnt = 0;
@@ -232,7 +239,7 @@ rte_atomic16_init(rte_atomic16_t *v)
  * @return
  *   The value of the counter.
  */
-static inline int16_t
+static __rte_deprecated inline int16_t
 rte_atomic16_read(const rte_atomic16_t *v)
 {
 	return v->cnt;
@@ -246,7 +253,7 @@ rte_atomic16_read(const rte_atomic16_t *v)
  * @param new_value
  *   The new value for the counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic16_set(rte_atomic16_t *v, int16_t new_value)
 {
 	v->cnt = new_value;
@@ -260,7 +267,7 @@ rte_atomic16_set(rte_atomic16_t *v, int16_t new_value)
  * @param inc
  *   The value to be added to the counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic16_add(rte_atomic16_t *v, int16_t inc)
 {
 	rte_atomic_fetch_add_explicit((volatile __rte_atomic int16_t *)&v->cnt, inc,
@@ -275,7 +282,7 @@ rte_atomic16_add(rte_atomic16_t *v, int16_t inc)
  * @param dec
  *   The value to be subtracted from the counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic16_sub(rte_atomic16_t *v, int16_t dec)
 {
 	rte_atomic_fetch_sub_explicit((volatile __rte_atomic int16_t *)&v->cnt, dec,
@@ -288,7 +295,7 @@ rte_atomic16_sub(rte_atomic16_t *v, int16_t dec)
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic16_inc(rte_atomic16_t *v)
 {
 	rte_atomic16_add(v, 1);
@@ -300,7 +307,7 @@ rte_atomic16_inc(rte_atomic16_t *v)
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic16_dec(rte_atomic16_t *v)
 {
 	rte_atomic16_sub(v, 1);
@@ -319,7 +326,7 @@ rte_atomic16_dec(rte_atomic16_t *v)
  * @return
  *   The value of v after the addition.
  */
-static inline int16_t
+static __rte_deprecated inline int16_t
 rte_atomic16_add_return(rte_atomic16_t *v, int16_t inc)
 {
 	return rte_atomic_fetch_add_explicit((volatile __rte_atomic int16_t *)&v->cnt, inc,
@@ -340,7 +347,7 @@ rte_atomic16_add_return(rte_atomic16_t *v, int16_t inc)
  * @return
  *   The value of v after the subtraction.
  */
-static inline int16_t
+static __rte_deprecated inline int16_t
 rte_atomic16_sub_return(rte_atomic16_t *v, int16_t dec)
 {
 	return rte_atomic_fetch_sub_explicit((volatile __rte_atomic int16_t *)&v->cnt, dec,
@@ -358,7 +365,7 @@ rte_atomic16_sub_return(rte_atomic16_t *v, int16_t dec)
  * @return
  *   True if the result after the increment operation is 0; false otherwise.
  */
-static inline int rte_atomic16_inc_and_test(rte_atomic16_t *v)
+static __rte_deprecated inline int rte_atomic16_inc_and_test(rte_atomic16_t *v)
 {
 	return rte_atomic_fetch_add_explicit((volatile __rte_atomic int16_t *)&v->cnt, 1,
 		rte_memory_order_seq_cst) + 1 == 0;
@@ -375,7 +382,7 @@ static inline int rte_atomic16_inc_and_test(rte_atomic16_t *v)
  * @return
  *   True if the result after the decrement operation is 0; false otherwise.
  */
-static inline int rte_atomic16_dec_and_test(rte_atomic16_t *v)
+static __rte_deprecated inline int rte_atomic16_dec_and_test(rte_atomic16_t *v)
 {
 	return rte_atomic_fetch_sub_explicit((volatile __rte_atomic int16_t *)&v->cnt, 1,
 		rte_memory_order_seq_cst) - 1 == 0;
@@ -392,7 +399,7 @@ static inline int rte_atomic16_dec_and_test(rte_atomic16_t *v)
  * @return
  *   0 if failed; else 1, success.
  */
-static inline int rte_atomic16_test_and_set(rte_atomic16_t *v)
+static __rte_deprecated inline int rte_atomic16_test_and_set(rte_atomic16_t *v)
 {
 	return rte_atomic16_cmpset((volatile uint16_t *)&v->cnt, 0, 1);
 }
@@ -403,7 +410,7 @@ static inline int rte_atomic16_test_and_set(rte_atomic16_t *v)
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void rte_atomic16_clear(rte_atomic16_t *v)
+static __rte_deprecated inline void rte_atomic16_clear(rte_atomic16_t *v)
 {
 	v->cnt = 0;
 }
@@ -426,7 +433,7 @@ static inline void rte_atomic16_clear(rte_atomic16_t *v)
  * @return
  *   Non-zero on success; 0 on failure.
  */
-static inline int
+static __rte_deprecated inline int
 rte_atomic32_cmpset(volatile uint32_t *dst, uint32_t exp, uint32_t src)
 {
 	return __sync_bool_compare_and_swap(dst, exp, src);
@@ -447,7 +454,7 @@ rte_atomic32_cmpset(volatile uint32_t *dst, uint32_t exp, uint32_t src)
  * @return
  *   The original value at that location
  */
-static inline uint32_t
+static __rte_deprecated inline uint32_t
 rte_atomic32_exchange(volatile uint32_t *dst, uint32_t val)
 {
 	return rte_atomic_exchange_explicit((volatile __rte_atomic uint32_t *)dst,
@@ -472,7 +479,7 @@ typedef struct {
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic32_init(rte_atomic32_t *v)
 {
 	v->cnt = 0;
@@ -486,7 +493,7 @@ rte_atomic32_init(rte_atomic32_t *v)
  * @return
  *   The value of the counter.
  */
-static inline int32_t
+static __rte_deprecated inline int32_t
 rte_atomic32_read(const rte_atomic32_t *v)
 {
 	return v->cnt;
@@ -500,7 +507,7 @@ rte_atomic32_read(const rte_atomic32_t *v)
  * @param new_value
  *   The new value for the counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic32_set(rte_atomic32_t *v, int32_t new_value)
 {
 	v->cnt = new_value;
@@ -514,7 +521,7 @@ rte_atomic32_set(rte_atomic32_t *v, int32_t new_value)
  * @param inc
  *   The value to be added to the counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic32_add(rte_atomic32_t *v, int32_t inc)
 {
 	rte_atomic_fetch_add_explicit((volatile __rte_atomic int32_t *)&v->cnt, inc,
@@ -529,7 +536,7 @@ rte_atomic32_add(rte_atomic32_t *v, int32_t inc)
  * @param dec
  *   The value to be subtracted from the counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic32_sub(rte_atomic32_t *v, int32_t dec)
 {
 	rte_atomic_fetch_sub_explicit((volatile __rte_atomic int32_t *)&v->cnt, dec,
@@ -542,7 +549,7 @@ rte_atomic32_sub(rte_atomic32_t *v, int32_t dec)
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic32_inc(rte_atomic32_t *v)
 {
 	rte_atomic32_add(v, 1);
@@ -554,7 +561,7 @@ rte_atomic32_inc(rte_atomic32_t *v)
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic32_dec(rte_atomic32_t *v)
 {
 	rte_atomic32_sub(v,1);
@@ -573,7 +580,7 @@ rte_atomic32_dec(rte_atomic32_t *v)
  * @return
  *   The value of v after the addition.
  */
-static inline int32_t
+static __rte_deprecated inline int32_t
 rte_atomic32_add_return(rte_atomic32_t *v, int32_t inc)
 {
 	return rte_atomic_fetch_add_explicit((volatile __rte_atomic int32_t *)&v->cnt, inc,
@@ -594,7 +601,7 @@ rte_atomic32_add_return(rte_atomic32_t *v, int32_t inc)
  * @return
  *   The value of v after the subtraction.
  */
-static inline int32_t
+static __rte_deprecated inline int32_t
 rte_atomic32_sub_return(rte_atomic32_t *v, int32_t dec)
 {
 	return rte_atomic_fetch_sub_explicit((volatile __rte_atomic int32_t *)&v->cnt, dec,
@@ -612,7 +619,7 @@ rte_atomic32_sub_return(rte_atomic32_t *v, int32_t dec)
  * @return
  *   True if the result after the increment operation is 0; false otherwise.
  */
-static inline int rte_atomic32_inc_and_test(rte_atomic32_t *v)
+static __rte_deprecated inline int rte_atomic32_inc_and_test(rte_atomic32_t *v)
 {
 	return rte_atomic_fetch_add_explicit((volatile __rte_atomic int32_t *)&v->cnt, 1,
 		rte_memory_order_seq_cst) + 1 == 0;
@@ -629,7 +636,7 @@ static inline int rte_atomic32_inc_and_test(rte_atomic32_t *v)
  * @return
  *   True if the result after the decrement operation is 0; false otherwise.
  */
-static inline int rte_atomic32_dec_and_test(rte_atomic32_t *v)
+static __rte_deprecated inline int rte_atomic32_dec_and_test(rte_atomic32_t *v)
 {
 	return rte_atomic_fetch_sub_explicit((volatile __rte_atomic int32_t *)&v->cnt, 1,
 		rte_memory_order_seq_cst) - 1 == 0;
@@ -646,7 +653,7 @@ static inline int rte_atomic32_dec_and_test(rte_atomic32_t *v)
  * @return
  *   0 if failed; else 1, success.
  */
-static inline int rte_atomic32_test_and_set(rte_atomic32_t *v)
+static __rte_deprecated inline int rte_atomic32_test_and_set(rte_atomic32_t *v)
 {
 	return rte_atomic32_cmpset((volatile uint32_t *)&v->cnt, 0, 1);
 }
@@ -657,7 +664,7 @@ static inline int rte_atomic32_test_and_set(rte_atomic32_t *v)
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void rte_atomic32_clear(rte_atomic32_t *v)
+static __rte_deprecated inline void rte_atomic32_clear(rte_atomic32_t *v)
 {
 	v->cnt = 0;
 }
@@ -679,7 +686,7 @@ static inline void rte_atomic32_clear(rte_atomic32_t *v)
  * @return
  *   Non-zero on success; 0 on failure.
  */
-static inline int
+static __rte_deprecated inline int
 rte_atomic64_cmpset(volatile uint64_t *dst, uint64_t exp, uint64_t src)
 {
 	return __sync_bool_compare_and_swap(dst, exp, src);
@@ -700,7 +707,7 @@ rte_atomic64_cmpset(volatile uint64_t *dst, uint64_t exp, uint64_t src)
  * @return
  *   The original value at that location
  */
-static inline uint64_t
+static __rte_deprecated inline uint64_t
 rte_atomic64_exchange(volatile uint64_t *dst, uint64_t val)
 {
 	return rte_atomic_exchange_explicit((volatile __rte_atomic uint64_t *)dst,
@@ -725,7 +732,7 @@ typedef struct {
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic64_init(rte_atomic64_t *v)
 {
 #ifdef __LP64__
@@ -750,7 +757,7 @@ rte_atomic64_init(rte_atomic64_t *v)
  * @return
  *   The value of the counter.
  */
-static inline int64_t
+static __rte_deprecated inline int64_t
 rte_atomic64_read(rte_atomic64_t *v)
 {
 #ifdef __LP64__
@@ -777,7 +784,7 @@ rte_atomic64_read(rte_atomic64_t *v)
  * @param new_value
  *   The new value of the counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic64_set(rte_atomic64_t *v, int64_t new_value)
 {
 #ifdef __LP64__
@@ -802,7 +809,7 @@ rte_atomic64_set(rte_atomic64_t *v, int64_t new_value)
  * @param inc
  *   The value to be added to the counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic64_add(rte_atomic64_t *v, int64_t inc)
 {
 	rte_atomic_fetch_add_explicit((volatile __rte_atomic int64_t *)&v->cnt, inc,
@@ -817,7 +824,7 @@ rte_atomic64_add(rte_atomic64_t *v, int64_t inc)
  * @param dec
  *   The value to be subtracted from the counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic64_sub(rte_atomic64_t *v, int64_t dec)
 {
 	rte_atomic_fetch_sub_explicit((volatile __rte_atomic int64_t *)&v->cnt, dec,
@@ -830,7 +837,7 @@ rte_atomic64_sub(rte_atomic64_t *v, int64_t dec)
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic64_inc(rte_atomic64_t *v)
 {
 	rte_atomic64_add(v, 1);
@@ -842,7 +849,7 @@ rte_atomic64_inc(rte_atomic64_t *v)
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void
+static __rte_deprecated inline void
 rte_atomic64_dec(rte_atomic64_t *v)
 {
 	rte_atomic64_sub(v, 1);
@@ -861,7 +868,7 @@ rte_atomic64_dec(rte_atomic64_t *v)
  * @return
  *   The value of v after the addition.
  */
-static inline int64_t
+static __rte_deprecated inline int64_t
 rte_atomic64_add_return(rte_atomic64_t *v, int64_t inc)
 {
 	return rte_atomic_fetch_add_explicit((volatile __rte_atomic int64_t *)&v->cnt, inc,
@@ -881,7 +888,7 @@ rte_atomic64_add_return(rte_atomic64_t *v, int64_t inc)
  * @return
  *   The value of v after the subtraction.
  */
-static inline int64_t
+static __rte_deprecated inline int64_t
 rte_atomic64_sub_return(rte_atomic64_t *v, int64_t dec)
 {
 	return rte_atomic_fetch_sub_explicit((volatile __rte_atomic int64_t *)&v->cnt, dec,
@@ -899,7 +906,7 @@ rte_atomic64_sub_return(rte_atomic64_t *v, int64_t dec)
  * @return
  *   True if the result after the addition is 0; false otherwise.
  */
-static inline int rte_atomic64_inc_and_test(rte_atomic64_t *v)
+static __rte_deprecated inline int rte_atomic64_inc_and_test(rte_atomic64_t *v)
 {
 	return rte_atomic64_add_return(v, 1) == 0;
 }
@@ -915,7 +922,7 @@ static inline int rte_atomic64_inc_and_test(rte_atomic64_t *v)
  * @return
  *   True if the result after subtraction is 0; false otherwise.
  */
-static inline int rte_atomic64_dec_and_test(rte_atomic64_t *v)
+static __rte_deprecated inline int rte_atomic64_dec_and_test(rte_atomic64_t *v)
 {
 	return rte_atomic64_sub_return(v, 1) == 0;
 }
@@ -931,7 +938,7 @@ static inline int rte_atomic64_dec_and_test(rte_atomic64_t *v)
  * @return
  *   0 if failed; else 1, success.
  */
-static inline int rte_atomic64_test_and_set(rte_atomic64_t *v)
+static __rte_deprecated inline int rte_atomic64_test_and_set(rte_atomic64_t *v)
 {
 	return rte_atomic64_cmpset((volatile uint64_t *)&v->cnt, 0, 1);
 }
@@ -942,13 +949,15 @@ static inline int rte_atomic64_test_and_set(rte_atomic64_t *v)
  * @param v
  *   A pointer to the atomic counter.
  */
-static inline void rte_atomic64_clear(rte_atomic64_t *v)
+static __rte_deprecated inline void rte_atomic64_clear(rte_atomic64_t *v)
 {
 	rte_atomic64_set(v, 0);
 }
 
 #endif
 
+__rte_diagnostic_pop
+
 /*------------------------ 128 bit atomic operations -------------------------*/
 
 /**
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 22/27] net/hinic: replace rte_atomic32 with stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Xiaoyun Wang
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

Convert dma_pool::inuse and hinic_os_dep::dma_alloc_cnt to
RTE_ATOMIC(uint32_t) and replace rte_atomic32_*() with the
rte_atomic_*_explicit() equivalents. The matching local variable
and log format change from int/%d to uint32_t/%u.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/hinic/base/hinic_compat.h    |  2 +-
 drivers/net/hinic/base/hinic_pmd_hwdev.c | 24 ++++++++++++++----------
 drivers/net/hinic/base/hinic_pmd_hwdev.h |  4 ++--
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/net/hinic/base/hinic_compat.h b/drivers/net/hinic/base/hinic_compat.h
index d3994c50e9..b0e42fa9bc 100644
--- a/drivers/net/hinic/base/hinic_compat.h
+++ b/drivers/net/hinic/base/hinic_compat.h
@@ -15,7 +15,7 @@
 #include <rte_memzone.h>
 #include <rte_memcpy.h>
 #include <rte_malloc.h>
-#include <rte_atomic.h>
+#include <rte_stdatomic.h>
 #include <rte_spinlock.h>
 #include <rte_cycles.h>
 #include <rte_log.h>
diff --git a/drivers/net/hinic/base/hinic_pmd_hwdev.c b/drivers/net/hinic/base/hinic_pmd_hwdev.c
index 818698dcb3..9a1b126632 100644
--- a/drivers/net/hinic/base/hinic_pmd_hwdev.c
+++ b/drivers/net/hinic/base/hinic_pmd_hwdev.c
@@ -116,7 +116,8 @@ static void *hinic_dma_mem_zalloc(struct hinic_hwdev *hwdev, size_t size,
 			   dma_addr_t *dma_handle, unsigned int align,
 			   unsigned int socket_id)
 {
-	int rc, alloc_cnt;
+	int rc;
+	uint32_t alloc_cnt;
 	const struct rte_memzone *mz;
 	char z_name[RTE_MEMZONE_NAMESIZE];
 	hash_sig_t sig;
@@ -125,8 +126,9 @@ static void *hinic_dma_mem_zalloc(struct hinic_hwdev *hwdev, size_t size,
 	if (dma_handle == NULL || 0 == size)
 		return NULL;
 
-	alloc_cnt = rte_atomic32_add_return(&hwdev->os_dep.dma_alloc_cnt, 1);
-	snprintf(z_name, sizeof(z_name), "%s_%d",
+	alloc_cnt = rte_atomic_fetch_add_explicit(&hwdev->os_dep.dma_alloc_cnt,
+						  1, rte_memory_order_relaxed);
+	snprintf(z_name, sizeof(z_name), "%s_%u",
 		 hwdev->pcidev_hdl->name, alloc_cnt);
 
 	mz = rte_memzone_reserve_aligned(z_name, size, socket_id,
@@ -282,7 +284,6 @@ struct dma_pool *dma_pool_create(const char *name, void *dev,
 	if (!pool)
 		return NULL;
 
-	rte_atomic32_set(&pool->inuse, 0);
 	pool->elem_size = size;
 	pool->align = align;
 	pool->boundary = boundary;
@@ -294,12 +295,15 @@ struct dma_pool *dma_pool_create(const char *name, void *dev,
 
 void dma_pool_destroy(struct dma_pool *pool)
 {
+	uint32_t inuse;
+
 	if (!pool)
 		return;
 
-	if (rte_atomic32_read(&pool->inuse) != 0) {
-		PMD_DRV_LOG(ERR, "Leak memory, dma_pool: %s, inuse_count: %d",
-			    pool->name, rte_atomic32_read(&pool->inuse));
+	inuse = rte_atomic_load_explicit(&pool->inuse, rte_memory_order_relaxed);
+	if (inuse != 0) {
+		PMD_DRV_LOG(ERR, "Leak memory, dma_pool: %s, inuse_count: %u",
+			    pool->name, inuse);
 	}
 
 	rte_free(pool);
@@ -312,14 +316,14 @@ void *dma_pool_alloc(struct pci_pool *pool, dma_addr_t *dma_addr)
 	buf = hinic_dma_mem_zalloc(pool->hwdev, pool->elem_size, dma_addr,
 				(u32)pool->align, SOCKET_ID_ANY);
 	if (buf)
-		rte_atomic32_inc(&pool->inuse);
+		rte_atomic_fetch_add_explicit(&pool->inuse, 1, rte_memory_order_relaxed);
 
 	return buf;
 }
 
 void dma_pool_free(struct pci_pool *pool, void *vaddr, dma_addr_t dma)
 {
-	rte_atomic32_dec(&pool->inuse);
+	rte_atomic_fetch_sub_explicit(&pool->inuse, 1, rte_memory_order_relaxed);
 	hinic_dma_mem_free(pool->hwdev, pool->elem_size, vaddr, dma);
 }
 
@@ -329,7 +333,7 @@ int hinic_osdep_init(struct hinic_hwdev *hwdev)
 	struct rte_hash_parameters dh_params = { 0 };
 	struct rte_hash *paddr_hash = NULL;
 
-	rte_atomic32_set(&hwdev->os_dep.dma_alloc_cnt, 0);
+	hwdev->os_dep.dma_alloc_cnt = 0;
 	rte_spinlock_init(&hwdev->os_dep.dma_hash_lock);
 
 	dh_params.name = hwdev->pcidev_hdl->name;
diff --git a/drivers/net/hinic/base/hinic_pmd_hwdev.h b/drivers/net/hinic/base/hinic_pmd_hwdev.h
index d6896b3f13..ad30ddd72e 100644
--- a/drivers/net/hinic/base/hinic_pmd_hwdev.h
+++ b/drivers/net/hinic/base/hinic_pmd_hwdev.h
@@ -18,7 +18,7 @@
 
 /* dma pool */
 struct dma_pool {
-	rte_atomic32_t inuse;
+	RTE_ATOMIC(uint32_t) inuse;
 	size_t elem_size;
 	size_t align;
 	size_t boundary;
@@ -402,7 +402,7 @@ struct hinic_hilink_link_info {
 /* dma os dependency implementation */
 struct hinic_os_dep {
 	/* kernel dma alloc api */
-	rte_atomic32_t dma_alloc_cnt;
+	RTE_ATOMIC(uint32_t) dma_alloc_cnt;
 	rte_spinlock_t  dma_hash_lock;
 	struct rte_hash *dma_addr_hash;
 };
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 23/27] net/txgbe: replace rte_atomic32 with stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Jiawen Wu, Zaiyu Wang
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

The swfw_busy flag guarding the AML SW-FW mailbox is a one-bit lock,
so convert it to RTE_ATOMIC(bool) and replace the legacy
test-and-set / clear pair with explicit acquire-release:

  rte_atomic32_test_and_set ->
      rte_atomic_exchange_explicit(.., true, acquire)
  rte_atomic32_clear        ->
      rte_atomic_store_explicit(.., false, release)

Acquire on the take pairs with release on the drop, so accesses
inside the critical section are synchronized between successive
holders. Default zero-initialization of struct txgbe_hw still
gives swfw_busy = false, so no init site needs updating.

Note: the code for the AML spinlock had a bug because
old rte_atomic32_test_set return value was not what the code
expected. This patch fixes that. A seperate patch for stable
has been sent upstream. (Drop this note from commit message
when rebasing after the fix is merged).

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/txgbe/base/txgbe_mng.c  | 4 ++--
 drivers/net/txgbe/base/txgbe_type.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/txgbe/base/txgbe_mng.c b/drivers/net/txgbe/base/txgbe_mng.c
index a1974820b6..c58e1d6589 100644
--- a/drivers/net/txgbe/base/txgbe_mng.c
+++ b/drivers/net/txgbe/base/txgbe_mng.c
@@ -185,7 +185,7 @@ txgbe_host_interface_command_aml(struct txgbe_hw *hw, u32 *buffer,
 	}
 
 	/* try to get lock */
-	while (rte_atomic32_test_and_set(&hw->swfw_busy)) {
+	while (rte_atomic_exchange_explicit(&hw->swfw_busy, true, rte_memory_order_acquire)) {
 		timeout--;
 		if (!timeout)
 			return TXGBE_ERR_TIMEOUT;
@@ -266,7 +266,7 @@ txgbe_host_interface_command_aml(struct txgbe_hw *hw, u32 *buffer,
 	/* index++, index replace txgbe_hic_hdr.checksum */
 	hw->swfw_index = resp->index == TXGBE_HIC_HDR_INDEX_MAX ?
 					0 : resp->index + 1;
-	rte_atomic32_clear(&hw->swfw_busy);
+	rte_atomic_store_explicit(&hw->swfw_busy, false, rte_memory_order_release);
 
 	return err;
 }
diff --git a/drivers/net/txgbe/base/txgbe_type.h b/drivers/net/txgbe/base/txgbe_type.h
index ede780321f..d3c82d51a4 100644
--- a/drivers/net/txgbe/base/txgbe_type.h
+++ b/drivers/net/txgbe/base/txgbe_type.h
@@ -880,7 +880,7 @@ struct txgbe_hw {
 	rte_spinlock_t phy_lock;
 	/*amlite: new SW-FW mbox */
 	u8 swfw_index;
-	rte_atomic32_t swfw_busy;
+	RTE_ATOMIC(bool) swfw_busy;
 	u32 fec_mode;
 	u32 cur_fec_link;
 };
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 20/27] bus/fslmc: replace rte_atomic32 with stdatomic
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Hemant Agrawal, Sachin Saxena
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

The atomic wrappers here are easily converted to stdatomic.
Drop any unused macros.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/bus/fslmc/qbman/include/compat.h | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/bus/fslmc/qbman/include/compat.h b/drivers/bus/fslmc/qbman/include/compat.h
index 5a57bd8ed1..9c87f0b639 100644
--- a/drivers/bus/fslmc/qbman/include/compat.h
+++ b/drivers/bus/fslmc/qbman/include/compat.h
@@ -81,18 +81,13 @@ do { \
 
 #define dma_wmb()		rte_io_wmb()
 
-#define atomic_t                rte_atomic32_t
-#define atomic_read(v)          rte_atomic32_read(v)
-#define atomic_set(v, i)        rte_atomic32_set(v, i)
-
-#define atomic_inc(v)           rte_atomic32_add(v, 1)
-#define atomic_dec(v)           rte_atomic32_sub(v, 1)
-
-#define atomic_inc_and_test(v)  rte_atomic32_inc_and_test(v)
-#define atomic_dec_and_test(v)  rte_atomic32_dec_and_test(v)
-
-#define atomic_inc_return(v)    rte_atomic32_add_return(v, 1)
-#define atomic_dec_return(v)    rte_atomic32_sub_return(v, 1)
-#define atomic_sub_and_test(i, v) (rte_atomic32_sub_return(v, i) == 0)
+typedef RTE_ATOMIC(uint32_t) atomic_t;
+
+#define atomic_read(v)          rte_atomic_load_explicit((v), rte_memory_order_relaxed)
+#define atomic_set(v, i)        rte_atomic_store_explicit((v), (i), rte_memory_order_relaxed)
+#define atomic_inc(v)           ((void)rte_atomic_fetch_add_explicit((v), 1, rte_memory_order_seq_cst))
+#define atomic_dec(v)           ((void)rte_atomic_fetch_sub_explicit((v), 1, rte_memory_order_seq_cst))
+#define atomic_inc_and_test(v)  (rte_atomic_fetch_add_explicit((v), 1, rte_memory_order_seq_cst) == -1)
+#define atomic_dec_and_test(v)  (rte_atomic_fetch_sub_explicit((v), 1, rte_memory_order_seq_cst) == 1)
 
 #endif /* HEADER_COMPAT_H */
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 26/27] test/atomic: suppress deprecation warnings for legacy APIs
From: Stephen Hemminger @ 2026-05-23 19:56 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger
In-Reply-To: <20260523195839.454952-1-stephen@networkplumber.org>

The rte_atomicNN_* APIs are now marked __rte_deprecated.
Wrap the whole file with __rte_diagnostic_push / pop and a
GCC pragma -Wdeprecated-declarations.

In future, when the APIs are removed this test collapses to just the
128-bit compare-and-swap case and the suppression goes with it.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test/test_atomic.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/app/test/test_atomic.c b/app/test/test_atomic.c
index 2a4531b833..f32a1aeff4 100644
--- a/app/test/test_atomic.c
+++ b/app/test/test_atomic.c
@@ -100,6 +100,15 @@
  *   - At the end of the test, the number of corrupted tokens must be 0.
  */
 
+/*
+ * The rte_atomicNN_* APIs exercised below are deprecated in favour of C11 atomics.
+ * Suppress the deprecation warnings for the whole file;
+ * when the APIs are removed this test collapses to the 128-bit
+ * compare-and-swap case and the suppression goes with it.
+ */
+__rte_diagnostic_push
+_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+
 #define NUM_ATOMIC_TYPES 3
 
 #define N_BASE 1000000u
@@ -645,4 +654,7 @@ test_atomic(void)
 	return 0;
 }
 REGISTER_FAST_TEST(atomic_autotest, NOHUGE_SKIP, ASAN_OK, test_atomic);
+
+__rte_diagnostic_pop
+
 #endif /* RTE_TOOLCHAIN_MSVC */
-- 
2.53.0


^ permalink raw reply related

* [PATCH v1 00/23] add net/sxe2 support for flow control
From: liujie5 @ 2026-05-24  9:32 UTC (permalink / raw)
  To: stephen; +Cc: dev, Jie Liu

From: Jie Liu <liujie5@linkdatatechnology.com>

v1:
-- add support for flow control
-- add support for flow control status interrupt notification
-- add support for ipsec inline protocol offload

Jie Liu (23):
  net/sxe2: support AVX512 vectorized path for Rx and Tx
  net/sxe2: add AVX2 vector data path for Rx and Tx
  drivers: add supported packet types get callback
  net/sxe2: support L2 filtering and MAC config
  drivers: support RSS feature
  net/sxe2: support TM hierarchy and shaping
  net/sxe2: support IPsec inline protocol offload
  net/sxe2: support statistics and multi-process
  drivers: interrupt handling
  net/sxe2: add NEON vec Rx/Tx burst functions
  net/sxe2: add support for VF representors
  net/sxe2: add support for custom UDP tunnel ports
  net/sxe2: support firmware version reading
  net/sxe2: implement get monitor address
  common/sxe2: add shared SFP module definitions
  net/sxe2: support SFP module info and EEPROM access
  net/sxe2: implement private dump info
  net/sxe2: add mbuf validation in Tx debug mode
  net/sxe2: add testpmd commands for private features
  net/sxe2: add private devargs parsing
  net/sxe2: support flow control status interrupt notification
  net/sxe2: update sxe2 feature matrix docs
  common/sxe2: add memseg walk callback

 doc/guides/nics/features/sxe2.ini          |   66 +
 drivers/common/sxe2/sxe2_common.c          |  156 ++
 drivers/common/sxe2/sxe2_common.h          |    4 +
 drivers/common/sxe2/sxe2_flow_public.h     |  633 +++++++
 drivers/common/sxe2/sxe2_ioctl_chnl.c      |  179 +-
 drivers/common/sxe2/sxe2_ioctl_chnl_func.h |   18 +
 drivers/common/sxe2/sxe2_msg.h             |  117 ++
 drivers/common/sxe2/sxe2_ptype.h           | 1793 ++++++++++++++++++
 drivers/net/sxe2/meson.build               |   56 +-
 drivers/net/sxe2/sxe2_cmd_chnl.c           | 1588 +++++++++++++++-
 drivers/net/sxe2/sxe2_cmd_chnl.h           |  139 ++
 drivers/net/sxe2/sxe2_drv_cmd.h            |  439 ++++-
 drivers/net/sxe2/sxe2_dump.c               |  304 +++
 drivers/net/sxe2/sxe2_dump.h               |   12 +
 drivers/net/sxe2/sxe2_ethdev.c             | 1526 ++++++++++++++-
 drivers/net/sxe2/sxe2_ethdev.h             |  113 +-
 drivers/net/sxe2/sxe2_ethdev_repr.c        |  610 ++++++
 drivers/net/sxe2/sxe2_ethdev_repr.h        |   32 +
 drivers/net/sxe2/sxe2_filter.c             |  897 +++++++++
 drivers/net/sxe2/sxe2_filter.h             |  100 +
 drivers/net/sxe2/sxe2_flow.c               | 1391 ++++++++++++++
 drivers/net/sxe2/sxe2_flow.h               |   30 +
 drivers/net/sxe2/sxe2_flow_define.h        |  144 ++
 drivers/net/sxe2/sxe2_flow_parse_action.c  | 1182 ++++++++++++
 drivers/net/sxe2/sxe2_flow_parse_action.h  |   23 +
 drivers/net/sxe2/sxe2_flow_parse_engine.c  |  106 ++
 drivers/net/sxe2/sxe2_flow_parse_engine.h  |   13 +
 drivers/net/sxe2/sxe2_flow_parse_pattern.c | 1935 ++++++++++++++++++++
 drivers/net/sxe2/sxe2_flow_parse_pattern.h |   46 +
 drivers/net/sxe2/sxe2_ipsec.c              | 1565 ++++++++++++++++
 drivers/net/sxe2/sxe2_ipsec.h              |  254 +++
 drivers/net/sxe2/sxe2_irq.c                | 1024 +++++++++++
 drivers/net/sxe2/sxe2_irq.h                |   25 +
 drivers/net/sxe2/sxe2_mac.c                |  535 ++++++
 drivers/net/sxe2/sxe2_mac.h                |   84 +
 drivers/net/sxe2/sxe2_mp.c                 |  413 +++++
 drivers/net/sxe2/sxe2_mp.h                 |   73 +
 drivers/net/sxe2/sxe2_queue.c              |   17 +-
 drivers/net/sxe2/sxe2_rss.c                |  584 ++++++
 drivers/net/sxe2/sxe2_rss.h                |   81 +
 drivers/net/sxe2/sxe2_rx.c                 |   38 +
 drivers/net/sxe2/sxe2_rx.h                 |    2 +
 drivers/net/sxe2/sxe2_security.c           |  335 ++++
 drivers/net/sxe2/sxe2_security.h           |   77 +
 drivers/net/sxe2/sxe2_stats.c              |  591 ++++++
 drivers/net/sxe2/sxe2_stats.h              |   39 +
 drivers/net/sxe2/sxe2_switchdev.c          |  332 ++++
 drivers/net/sxe2/sxe2_switchdev.h          |   33 +
 drivers/net/sxe2/sxe2_testpmd.c            |  733 ++++++++
 drivers/net/sxe2/sxe2_testpmd_lib.c        |  969 ++++++++++
 drivers/net/sxe2/sxe2_testpmd_lib.h        |  142 ++
 drivers/net/sxe2/sxe2_tm.c                 | 1169 ++++++++++++
 drivers/net/sxe2/sxe2_tm.h                 |   78 +
 drivers/net/sxe2/sxe2_tx.c                 |    7 +
 drivers/net/sxe2/sxe2_txrx.c               |  174 +-
 drivers/net/sxe2/sxe2_txrx.h               |    4 +
 drivers/net/sxe2/sxe2_txrx_check_mbuf.c    |  595 ++++++
 drivers/net/sxe2/sxe2_txrx_check_mbuf.h    |   38 +
 drivers/net/sxe2/sxe2_txrx_poll.c          |  243 ++-
 drivers/net/sxe2/sxe2_txrx_vec.c           |   46 +-
 drivers/net/sxe2/sxe2_txrx_vec.h           |   38 +-
 drivers/net/sxe2/sxe2_txrx_vec_avx2.c      |  777 ++++++++
 drivers/net/sxe2/sxe2_txrx_vec_avx512.c    |  897 +++++++++
 drivers/net/sxe2/sxe2_txrx_vec_common.h    |    1 -
 drivers/net/sxe2/sxe2_txrx_vec_neon.c      |  707 +++++++
 drivers/net/sxe2/sxe2_vsi.c                |  146 ++
 drivers/net/sxe2/sxe2_vsi.h                |   12 +-
 drivers/net/sxe2/sxe2vf_regs.h             |   82 +
 68 files changed, 26531 insertions(+), 81 deletions(-)
 create mode 100644 drivers/common/sxe2/sxe2_flow_public.h
 create mode 100644 drivers/common/sxe2/sxe2_msg.h
 create mode 100644 drivers/common/sxe2/sxe2_ptype.h
 create mode 100644 drivers/net/sxe2/sxe2_dump.c
 create mode 100644 drivers/net/sxe2/sxe2_dump.h
 create mode 100644 drivers/net/sxe2/sxe2_ethdev_repr.c
 create mode 100644 drivers/net/sxe2/sxe2_ethdev_repr.h
 create mode 100644 drivers/net/sxe2/sxe2_filter.c
 create mode 100644 drivers/net/sxe2/sxe2_filter.h
 create mode 100644 drivers/net/sxe2/sxe2_flow.c
 create mode 100644 drivers/net/sxe2/sxe2_flow.h
 create mode 100644 drivers/net/sxe2/sxe2_flow_define.h
 create mode 100644 drivers/net/sxe2/sxe2_flow_parse_action.c
 create mode 100644 drivers/net/sxe2/sxe2_flow_parse_action.h
 create mode 100644 drivers/net/sxe2/sxe2_flow_parse_engine.c
 create mode 100644 drivers/net/sxe2/sxe2_flow_parse_engine.h
 create mode 100644 drivers/net/sxe2/sxe2_flow_parse_pattern.c
 create mode 100644 drivers/net/sxe2/sxe2_flow_parse_pattern.h
 create mode 100644 drivers/net/sxe2/sxe2_ipsec.c
 create mode 100644 drivers/net/sxe2/sxe2_ipsec.h
 create mode 100644 drivers/net/sxe2/sxe2_irq.c
 create mode 100644 drivers/net/sxe2/sxe2_mac.c
 create mode 100644 drivers/net/sxe2/sxe2_mac.h
 create mode 100644 drivers/net/sxe2/sxe2_mp.c
 create mode 100644 drivers/net/sxe2/sxe2_mp.h
 create mode 100644 drivers/net/sxe2/sxe2_rss.c
 create mode 100644 drivers/net/sxe2/sxe2_rss.h
 create mode 100644 drivers/net/sxe2/sxe2_security.c
 create mode 100644 drivers/net/sxe2/sxe2_security.h
 create mode 100644 drivers/net/sxe2/sxe2_stats.c
 create mode 100644 drivers/net/sxe2/sxe2_stats.h
 create mode 100644 drivers/net/sxe2/sxe2_switchdev.c
 create mode 100644 drivers/net/sxe2/sxe2_switchdev.h
 create mode 100644 drivers/net/sxe2/sxe2_testpmd.c
 create mode 100644 drivers/net/sxe2/sxe2_testpmd_lib.c
 create mode 100644 drivers/net/sxe2/sxe2_testpmd_lib.h
 create mode 100644 drivers/net/sxe2/sxe2_tm.c
 create mode 100644 drivers/net/sxe2/sxe2_tm.h
 create mode 100644 drivers/net/sxe2/sxe2_txrx_check_mbuf.c
 create mode 100644 drivers/net/sxe2/sxe2_txrx_check_mbuf.h
 create mode 100644 drivers/net/sxe2/sxe2_txrx_vec_avx2.c
 create mode 100644 drivers/net/sxe2/sxe2_txrx_vec_avx512.c
 create mode 100644 drivers/net/sxe2/sxe2_txrx_vec_neon.c
 create mode 100644 drivers/net/sxe2/sxe2vf_regs.h

-- 
2.47.3


^ permalink raw reply

* [PATCH v1 02/23] net/sxe2: add AVX2 vector data path for Rx and Tx
From: liujie5 @ 2026-05-24  9:32 UTC (permalink / raw)
  To: stephen; +Cc: dev, Jie Liu
In-Reply-To: <20260524093259.397506-1-liujie5@linkdatatechnology.com>

From: Jie Liu <liujie5@linkdatatechnology.com>

Added AVX256 vectorized versions of Rx and Tx data path functions to
improve packet processing performance.

The vector path uses AVX2 SIMD instructions to process multiple
descriptors per loop, significantly reducing the per-packet overhead.

Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>

net/sxe2: support AVX512 vectorized path for Rx and Tx
---
 drivers/net/sxe2/meson.build          |   9 +
 drivers/net/sxe2/sxe2_txrx.c          |  38 +-
 drivers/net/sxe2/sxe2_txrx_vec.h      |  12 +-
 drivers/net/sxe2/sxe2_txrx_vec_avx2.c | 777 ++++++++++++++++++++++++++
 4 files changed, 831 insertions(+), 5 deletions(-)
 create mode 100644 drivers/net/sxe2/sxe2_txrx_vec_avx2.c

diff --git a/drivers/net/sxe2/meson.build b/drivers/net/sxe2/meson.build
index 30f2c7d816..98dd8bcec7 100644
--- a/drivers/net/sxe2/meson.build
+++ b/drivers/net/sxe2/meson.build
@@ -39,6 +39,15 @@ if arch_subdir == 'x86'
                         c_args: avx512_args)
                 objs += sxe2_avx512_lib.extract_objects('sxe2_txrx_vec_avx512.c')
         endif
+        sxe2_avx2_lib = static_library('sxe2_avx2_lib',
+                'sxe2_txrx_vec_avx2.c',
+                dependencies: [static_rte_ethdev,
+                        static_rte_kvargs, static_rte_hash,
+                        static_rte_security, static_rte_cryptodev,
+                        static_rte_bus_pci],
+                include_directories: includes,
+                c_args: [cflags, '-mavx2'])
+        objs += sxe2_avx2_lib.extract_objects('sxe2_txrx_vec_avx2.c')
 endif
 
 sources += files(
diff --git a/drivers/net/sxe2/sxe2_txrx.c b/drivers/net/sxe2/sxe2_txrx.c
index ee70a2a431..dcfaf7278d 100644
--- a/drivers/net/sxe2/sxe2_txrx.c
+++ b/drivers/net/sxe2/sxe2_txrx.c
@@ -168,8 +168,14 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
 				PMD_LOG_INFO(TX, "AVX512 is not supported in build env.");
 #endif
 			}
-			if ((tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK) == 0)
-				tx_mode_flags |= SXE2_TX_MODE_VEC_SSE;
+			if (((tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK) == 0) &&
+			    ((rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2) == 1) ||
+			    (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) == 1)) &&
+			    (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256))
+				tx_mode_flags |= SXE2_TX_MODE_VEC_AVX2;
+
+			if ((0 == (tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK)))
+				tx_mode_flags |=  SXE2_TX_MODE_VEC_SSE;
 #endif
 			if (tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK) {
 				ret = sxe2_tx_queues_vec_prepare(dev);
@@ -207,6 +213,13 @@ void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
 				dev->tx_pkt_burst = sxe2_tx_pkts_vec_avx512_simple;
 			}
 #endif
+		} else if (tx_mode_flags & SXE2_TX_MODE_VEC_AVX2) {
+			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_avx2;
+			} else {
+				dev->tx_pkt_burst = sxe2_tx_pkts_vec_avx2_simple;
+			}
 		} else {
 			if (tx_mode_flags & SXE2_TX_MODE_VEC_OFFLOAD) {
 				dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
@@ -241,6 +254,10 @@ static const struct {
 	{ sxe2_tx_pkts_vec_avx512_simple,
 	      "Vector AVX512 Simple" },
 #endif
+	{ sxe2_tx_pkts_vec_avx2,
+	      "Vector AVX2" },
+	{ sxe2_tx_pkts_vec_avx2_simple,
+	      "Vector AVX2 Simple" },
 	{ sxe2_tx_pkts_vec_sse,
 	      "Vector SSE" },
 	{ sxe2_tx_pkts_vec_sse_simple,
@@ -340,7 +357,13 @@ void sxe2_rx_mode_func_set(struct rte_eth_dev *dev)
 				PMD_LOG_INFO(RX, "AVX512 support detected but not enabled");
 #endif
 			}
-			if ((rx_mode_flags & SXE2_RX_MODE_VEC_SET_MASK) == 0 &&
+			if (((rx_mode_flags & SXE2_RX_MODE_VEC_SET_MASK) == 0) &&
+				((rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2) == 1) ||
+				(rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) == 1)) &&
+				(rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256))
+				rx_mode_flags |= SXE2_RX_MODE_VEC_AVX2;
+
+			if (((rx_mode_flags & SXE2_RX_MODE_VEC_SET_MASK) == 0) &&
 				rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128)
 				rx_mode_flags |= SXE2_RX_MODE_VEC_SSE;
 #endif
@@ -364,6 +387,11 @@ void sxe2_rx_mode_func_set(struct rte_eth_dev *dev)
 			else
 				dev->rx_pkt_burst = sxe2_rx_pkts_scattered_vec_avx512;
 #endif
+		} else if (rx_mode_flags & SXE2_RX_MODE_VEC_AVX2) {
+			if (rx_mode_flags & SXE2_RX_MODE_VEC_OFFLOAD)
+				dev->rx_pkt_burst = sxe2_rx_pkts_scattered_vec_avx2_offload;
+			else
+				dev->rx_pkt_burst = sxe2_rx_pkts_scattered_vec_avx2;
 		} else {
 			dev->rx_pkt_burst = sxe2_rx_pkts_scattered_vec_sse_offload;
 		}
@@ -391,6 +419,10 @@ static const struct {
 	{ sxe2_rx_pkts_scattered_vec_avx512_offload,
 	      "Offload Vector AVX512 Scattered" },
 #endif
+	{ sxe2_rx_pkts_scattered_vec_avx2,
+	      "Vector AVX2 Scattered" },
+	{ sxe2_rx_pkts_scattered_vec_avx2_offload,
+	      "Offload Vector AVX2 Scattered" },
 	{ sxe2_rx_pkts_scattered_vec_sse_offload,
 	      "Vector SSE Scattered" },
 #endif
diff --git a/drivers/net/sxe2/sxe2_txrx_vec.h b/drivers/net/sxe2/sxe2_txrx_vec.h
index 62a5b1f3f5..d7a0ce6ca5 100644
--- a/drivers/net/sxe2/sxe2_txrx_vec.h
+++ b/drivers/net/sxe2/sxe2_txrx_vec.h
@@ -10,19 +10,21 @@
 #define SXE2_RX_MODE_VEC_SIMPLE    RTE_BIT32(0)
 #define SXE2_RX_MODE_VEC_OFFLOAD   RTE_BIT32(1)
 #define SXE2_RX_MODE_VEC_SSE       RTE_BIT32(2)
+#define SXE2_RX_MODE_VEC_AVX2      RTE_BIT32(3)
 #define SXE2_RX_MODE_VEC_AVX512    RTE_BIT32(4)
 #define SXE2_RX_MODE_BATCH_ALLOC   RTE_BIT32(10)
 #define SXE2_RX_MODE_VEC_SET_MASK	(SXE2_RX_MODE_VEC_SIMPLE | \
 			SXE2_RX_MODE_VEC_OFFLOAD | SXE2_RX_MODE_VEC_SSE | \
-			SXE2_RX_MODE_VEC_AVX512)
+			SXE2_RX_MODE_VEC_AVX2 | SXE2_RX_MODE_VEC_AVX512)
 #define SXE2_TX_MODE_VEC_SIMPLE   RTE_BIT32(0)
 #define SXE2_TX_MODE_VEC_OFFLOAD  RTE_BIT32(1)
 #define SXE2_TX_MODE_VEC_SSE      RTE_BIT32(2)
+#define SXE2_TX_MODE_VEC_AVX2     RTE_BIT32(3)
 #define SXE2_TX_MODE_VEC_AVX512   RTE_BIT32(4)
 #define SXE2_TX_MODE_SIMPLE_BATCH RTE_BIT32(10)
 #define SXE2_TX_MODE_VEC_SET_MASK	(SXE2_TX_MODE_VEC_SIMPLE | \
 			SXE2_TX_MODE_VEC_OFFLOAD | SXE2_TX_MODE_VEC_SSE | \
-			SXE2_TX_MODE_VEC_AVX512)
+			SXE2_TX_MODE_VEC_AVX2 | SXE2_TX_MODE_VEC_AVX512)
 #define SXE2_TX_VEC_NO_SUPPORT_OFFLOAD (		  \
 			RTE_ETH_TX_OFFLOAD_MULTI_SEGS |		  \
 			RTE_ETH_TX_OFFLOAD_QINQ_INSERT |	  \
@@ -67,6 +69,12 @@ uint16_t sxe2_rx_pkts_scattered_vec_avx512(void *rx_queue,
 		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 uint16_t sxe2_rx_pkts_scattered_vec_avx512_offload(void *rx_queue,
 		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
+uint16_t sxe2_tx_pkts_vec_avx2_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
+uint16_t sxe2_tx_pkts_vec_avx2(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts);
+uint16_t sxe2_rx_pkts_scattered_vec_avx2(void *rx_queue,
+		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
+uint16_t sxe2_rx_pkts_scattered_vec_avx2_offload(void *rx_queue,
+		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 #endif
 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);
diff --git a/drivers/net/sxe2/sxe2_txrx_vec_avx2.c b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
new file mode 100644
index 0000000000..5d57ebf9e2
--- /dev/null
+++ b/drivers/net/sxe2/sxe2_txrx_vec_avx2.c
@@ -0,0 +1,777 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
+ */
+
+#include <rte_vect.h>
+
+#include "sxe2_ethdev.h"
+#include "sxe2_common_log.h"
+#include "sxe2_queue.h"
+#include "sxe2_txrx_vec.h"
+#include "sxe2_txrx_vec_common.h"
+#include "sxe2_vsi.h"
+
+static __rte_always_inline void
+sxe2_tx_desc_fill_one_avx2(volatile union sxe2_tx_data_desc *desc, struct rte_mbuf *pkt,
+			   uint64_t desc_cmd, bool with_offloads)
+{
+	__m128i data_desc;
+	uint64_t desc_qw1;
+	uint32_t desc_offset;
+
+	desc_qw1 = (SXE2_TX_DESC_DTYPE_DATA |
+		   ((uint64_t)desc_cmd) << SXE2_TX_DATA_DESC_CMD_SHIFT |
+		   ((uint64_t)pkt->data_len) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT);
+
+	desc_offset = SXE2_TX_DATA_DESC_MACLEN_VAL(pkt->l2_len);
+	desc_qw1 |= ((uint64_t)desc_offset) << SXE2_TX_DATA_DESC_OFFSET_SHIFT;
+	if (with_offloads)
+		sxe2_tx_desc_fill_offloads(pkt, &desc_qw1);
+
+	data_desc = _mm_set_epi64x(desc_qw1, rte_pktmbuf_iova(pkt));
+	_mm_store_si128(RTE_CAST_PTR(__m128i *, desc), data_desc);
+}
+
+static __rte_always_inline void
+sxe2_tx_desc_fill_avx2(volatile union sxe2_tx_data_desc *desc, struct rte_mbuf **pkts,
+		       uint16_t pkts_num, uint64_t desc_cmd, bool with_offloads)
+{
+	__m256i desc_group0;
+	__m256i desc_group1;
+	uint64_t desc0_qw1;
+	uint64_t desc1_qw1;
+	uint64_t desc2_qw1;
+	uint64_t desc3_qw1;
+
+	const uint64_t desc_qw1_com = (SXE2_TX_DESC_DTYPE_DATA |
+					((uint64_t)desc_cmd) << SXE2_TX_DATA_DESC_CMD_SHIFT);
+	uint32_t desc_offset[4] = {0};
+
+	if (((uint64_t)desc & 0x1F) != 0 && pkts_num != 0) {
+		sxe2_tx_desc_fill_one_avx2(desc, *pkts, desc_cmd, with_offloads);
+		pkts_num--;
+		desc++;
+		pkts++;
+	}
+
+	while (pkts_num > 3) {
+		desc3_qw1 = (desc_qw1_com |
+					((uint64_t)pkts[3]->data_len)
+					<< SXE2_TX_DATA_DESC_BUF_SZ_SHIFT);
+
+		desc_offset[3] = SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[3]->l2_len);
+		desc3_qw1 |= ((uint64_t)desc_offset[3]) << SXE2_TX_DATA_DESC_OFFSET_SHIFT;
+		if (with_offloads)
+			sxe2_tx_desc_fill_offloads(pkts[3], &desc3_qw1);
+
+		desc2_qw1 = (desc_qw1_com |
+					((uint64_t)pkts[2]->data_len)
+					<< SXE2_TX_DATA_DESC_BUF_SZ_SHIFT);
+		desc_offset[2] = SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[2]->l2_len);
+		desc2_qw1 |= ((uint64_t)desc_offset[2]) << SXE2_TX_DATA_DESC_OFFSET_SHIFT;
+		if (with_offloads)
+			sxe2_tx_desc_fill_offloads(pkts[2], &desc2_qw1);
+
+		desc1_qw1 = (desc_qw1_com |
+					((uint64_t)pkts[1]->data_len)
+					<< SXE2_TX_DATA_DESC_BUF_SZ_SHIFT);
+		desc_offset[1] = SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[1]->l2_len);
+		desc1_qw1 |= ((uint64_t)desc_offset[1]) << SXE2_TX_DATA_DESC_OFFSET_SHIFT;
+		if (with_offloads)
+			sxe2_tx_desc_fill_offloads(pkts[1], &desc1_qw1);
+
+		desc0_qw1 = (desc_qw1_com |
+					((uint64_t)pkts[0]->data_len)
+					<< SXE2_TX_DATA_DESC_BUF_SZ_SHIFT);
+		desc_offset[0] = SXE2_TX_DATA_DESC_MACLEN_VAL(pkts[0]->l2_len);
+		desc0_qw1 |= ((uint64_t)desc_offset[0]) << SXE2_TX_DATA_DESC_OFFSET_SHIFT;
+		if (with_offloads)
+			sxe2_tx_desc_fill_offloads(pkts[0], &desc0_qw1);
+
+		desc_group1 = _mm256_set_epi64x(desc3_qw1, rte_pktmbuf_iova(pkts[3]),
+					desc2_qw1, rte_pktmbuf_iova(pkts[2]));
+
+		desc_group0 = _mm256_set_epi64x(desc1_qw1, rte_pktmbuf_iova(pkts[1]),
+					desc0_qw1, rte_pktmbuf_iova(pkts[0]));
+
+		_mm256_store_si256(RTE_CAST_PTR(__m256i *, desc + 2), desc_group1);
+		_mm256_store_si256(RTE_CAST_PTR(__m256i *, desc), desc_group0);
+
+		pkts_num -= 4;
+		desc     += 4;
+		pkts     += 4;
+	}
+
+	while (pkts_num) {
+		sxe2_tx_desc_fill_one_avx2(desc, *pkts, desc_cmd, with_offloads);
+		pkts_num--;
+		desc++;
+		pkts++;
+	}
+}
+
+static __rte_always_inline uint16_t
+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;
+	uint16_t next_use;
+	uint16_t res_num;
+	uint16_t tx_num;
+
+	if (txq->desc_free_num < txq->free_thresh)
+		(void)sxe2_tx_bufs_free_vec(txq);
+
+	nb_pkts = RTE_MIN(txq->desc_free_num, nb_pkts);
+	if (unlikely(nb_pkts == 0)) {
+		PMD_LOG_DEBUG(TX, "Tx pkts avx2 batch: may not enough free desc, "
+				"free_desc=%u, need_tx_pkts=%u",
+				txq->desc_free_num, nb_pkts);
+		goto l_end;
+	}
+	tx_num = nb_pkts;
+
+	next_use = txq->next_use;
+	desc     = &txq->desc_ring[next_use];
+	buffer   = &txq->buffer_ring[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_desc_fill_avx2(desc, tx_pkts, res_num,
+				SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+		tx_pkts += (res_num - 1);
+		desc    += (res_num - 1);
+
+		sxe2_tx_desc_fill_one_avx2(desc, *tx_pkts++,
+				(SXE2_TX_DATA_DESC_CMD_EOP | SXE2_TX_DATA_DESC_CMD_RS),
+				with_offloads);
+
+		tx_num -= res_num;
+
+		next_use     = 0;
+		txq->next_rs = txq->rs_thresh - 1;
+		desc         = &txq->desc_ring[next_use];
+		buffer       = &txq->buffer_ring[next_use];
+	}
+
+	sxe2_tx_pkts_mbuf_fill(buffer, tx_pkts, tx_num);
+
+	sxe2_tx_desc_fill_avx2(desc, tx_pkts, tx_num,
+			SXE2_TX_DATA_DESC_CMD_EOP, with_offloads);
+
+	next_use += tx_num;
+	if (next_use > txq->next_rs) {
+		txq->desc_ring[txq->next_rs].read.type_cmd_off_bsz_l2t |=
+			rte_cpu_to_le_64(SXE2_TX_DATA_DESC_CMD_RS_MASK);
+
+		txq->next_rs += txq->rs_thresh;
+	}
+	txq->next_use = next_use;
+	SXE2_PCI_REG_WRITE_WC(txq->tdt_reg_addr, next_use);
+	PMD_LOG_DEBUG(TX, "port_id=%u queue_id=%u next_use=%u send_pkts=%u",
+			txq->port_id, txq->queue_id, next_use, nb_pkts);
+l_end:
+	return nb_pkts;
+}
+
+static __rte_always_inline uint16_t
+sxe2_tx_pkts_vec_avx2_common(struct sxe2_tx_queue *txq, struct rte_mbuf **tx_pkts,
+			     uint16_t nb_pkts, bool with_offloads)
+{
+	uint16_t tx_done_num = 0;
+	uint16_t tx_once_num;
+	uint16_t tx_need_num;
+
+	while (nb_pkts) {
+		tx_need_num = RTE_MIN(nb_pkts, txq->rs_thresh);
+		tx_once_num = sxe2_tx_pkts_vec_avx2_batch(txq,
+					tx_pkts + tx_done_num, tx_need_num, with_offloads);
+
+		nb_pkts     -= tx_once_num;
+		tx_done_num += tx_once_num;
+
+		if (tx_once_num < tx_need_num)
+			break;
+	}
+	return tx_done_num;
+}
+
+uint16_t sxe2_tx_pkts_vec_avx2_simple(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+	return sxe2_tx_pkts_vec_avx2_common(tx_queue, tx_pkts, nb_pkts, false);
+}
+
+uint16_t sxe2_tx_pkts_vec_avx2(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+	return sxe2_tx_pkts_vec_avx2_common(tx_queue, tx_pkts, nb_pkts, true);
+}
+
+static inline void sxe2_rx_queue_rearm_avx2(struct sxe2_rx_queue *rxq)
+{
+	volatile union sxe2_rx_desc *desc;
+	struct rte_mbuf **buffer;
+	struct rte_mbuf *mbuf0, *mbuf1;
+	__m128i dma_addr0, dma_addr1;
+	__m128i virt_addr0, virt_addr1;
+	__m128i hdr_room = _mm_set_epi64x(RTE_PKTMBUF_HEADROOM, RTE_PKTMBUF_HEADROOM);
+	int32_t ret;
+	uint16_t i;
+	uint16_t new_tail;
+
+	buffer = &rxq->buffer_ring[rxq->realloc_start];
+	desc   = &rxq->desc_ring[rxq->realloc_start];
+
+	ret = rte_mempool_get_bulk(rxq->mb_pool, (void *)buffer, SXE2_RX_REARM_THRESH_VEC);
+	if (ret != 0) {
+		if ((rxq->realloc_num + SXE2_RX_REARM_THRESH_VEC) >= rxq->ring_depth) {
+			dma_addr0 = _mm_setzero_si128();
+			for (i = 0; i < SXE2_RX_NUM_PER_LOOP_AVX; ++i) {
+				buffer[i] = &rxq->fake_mbuf;
+				_mm_store_si128(RTE_CAST_PTR(__m128i *, &desc[i].read), dma_addr0);
+			}
+		}
+
+		rxq->vsi->adapter->dev_info.dev_data->rx_mbuf_alloc_failed +=
+				SXE2_RX_REARM_THRESH_VEC;
+		goto l_end;
+	}
+
+	for (i = 0; i < SXE2_RX_REARM_THRESH_VEC; i += 2, buffer += 2) {
+		mbuf0 = buffer[0];
+		mbuf1 = buffer[1];
+#if RTE_IOVA_IN_MBUF
+
+		RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
+				 offsetof(struct rte_mbuf, buf_addr) + 8);
+#endif
+		virt_addr0 = _mm_loadu_si128((__m128i *)&mbuf0->buf_addr);
+		virt_addr1 = _mm_loadu_si128((__m128i *)&mbuf1->buf_addr);
+
+#if RTE_IOVA_IN_MBUF
+
+		dma_addr0 = _mm_unpackhi_epi64(virt_addr0, virt_addr0);
+		dma_addr1 = _mm_unpackhi_epi64(virt_addr1, virt_addr1);
+#else
+
+		dma_addr0 = _mm_unpacklo_epi64(virt_addr0, virt_addr0);
+		dma_addr1 = _mm_unpacklo_epi64(virt_addr1, virt_addr1);
+#endif
+
+		dma_addr0 = _mm_add_epi64(dma_addr0, hdr_room);
+		dma_addr1 = _mm_add_epi64(dma_addr1, hdr_room);
+
+		_mm_store_si128(RTE_CAST_PTR(__m128i *, &desc++->read), dma_addr0);
+		_mm_store_si128(RTE_CAST_PTR(__m128i *, &desc++->read), dma_addr1);
+	}
+
+	rxq->realloc_start += SXE2_RX_REARM_THRESH_VEC;
+	if (rxq->realloc_start >= rxq->ring_depth)
+		rxq->realloc_start = 0;
+	rxq->realloc_num -= SXE2_RX_REARM_THRESH_VEC;
+
+	new_tail = (rxq->realloc_start == 0) ?
+		(rxq->ring_depth - 1) : (rxq->realloc_start - 1);
+	SXE2_PCI_REG_WRITE_WC(rxq->rdt_reg_addr, new_tail);
+l_end:
+}
+
+static __rte_always_inline uint16_t
+sxe2_rx_pkts_common_vec_avx2(struct sxe2_rx_queue *rxq,
+			     struct rte_mbuf **rx_pkts, uint16_t nb_pkts, uint8_t *split_rxe_flags,
+			     uint8_t *umbcast_flags, bool do_offload)
+{
+	const uint32_t *ptype_tbl = rxq->vsi->adapter->ptype_tbl;
+	const __m256i mbuf_init   = _mm256_set_epi64x(0, 0, 0, rxq->mbuf_init_value);
+	struct rte_mbuf **buffer;
+	volatile union sxe2_rx_desc *desc;
+	__m256i mbufs6_7, mbufs4_5, mbufs2_3, mbufs0_1;
+	uint32_t bit_num;
+	uint16_t done_num;
+	uint16_t i = 0;
+	uint16_t j = 0;
+
+	buffer   = &rxq->buffer_ring[rxq->processing_idx];
+	desc     = &rxq->desc_ring[rxq->processing_idx];
+	done_num = 0;
+
+	rte_prefetch0(desc);
+
+	nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, SXE2_RX_NUM_PER_LOOP_AVX);
+
+	if (rxq->realloc_num > SXE2_RX_REARM_THRESH_VEC)
+		sxe2_rx_queue_rearm_avx2(rxq);
+
+	if (0 == (rte_le_to_cpu_64(desc->wb.status_err_ptype_len) &
+				SXE2_RX_DESC_STATUS_DD_MASK))
+		goto l_end;
+
+	const __m256i crc_adjust =
+		_mm256_set_epi16(0, 0, 0, -rxq->crc_len,
+				 0, -rxq->crc_len, 0,
+				 0, 0, 0, 0,
+				 -rxq->crc_len, 0, -rxq->crc_len, 0, 0);
+
+	const __m256i dd_mask = _mm256_set1_epi32(1);
+	const __m256i rvp_shuf_mask =
+		_mm256_set_epi8(7, 6, 5, 4,
+				3, 2, 13, 12,
+				0xFF, 0xFF, 13, 12,
+				0xFF, 0xFF, 0xFF, 0xFF,
+				7, 6, 5, 4,
+				3, 2, 13, 12,
+				0xFF, 0xFF, 13, 12,
+				0xFF, 0xFF, 0xFF, 0xFF);
+
+	const __m128i eop_shuf_mask =
+		_mm_set_epi8(0xFF, 0xFF, 0xFF, 0xFF,
+			     0xFF, 0xFF, 0xFF, 0xFF,
+			     8, 0, 10, 2,
+			     12, 4, 14, 6);
+
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
+			offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
+			offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, vlan_tci) !=
+			offsetof(struct rte_mbuf, rx_descriptor_fields1) + 10);
+	RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, hash) !=
+			offsetof(struct rte_mbuf, rx_descriptor_fields1) + 12);
+
+	for (i = 0; i < nb_pkts; i += SXE2_RX_NUM_PER_LOOP_AVX,
+				desc += SXE2_RX_NUM_PER_LOOP_AVX) {
+		_mm256_storeu_si256((void *)&rx_pkts[i],
+					_mm256_loadu_si256((void *)&buffer[i]));
+#ifdef RTE_ARCH_X86_64
+		_mm256_storeu_si256((void *)&rx_pkts[i + 4],
+					_mm256_loadu_si256((void *)&buffer[i + 4]));
+#endif
+
+		const __m128i desc7 = _mm_loadu_si128(RTE_CAST_PTR(const __m128i *, desc + 7));
+		rte_compiler_barrier();
+		const __m128i desc6 = _mm_loadu_si128(RTE_CAST_PTR(const __m128i *, desc + 6));
+		rte_compiler_barrier();
+		const __m128i desc5 = _mm_loadu_si128(RTE_CAST_PTR(const __m128i *, desc + 5));
+		rte_compiler_barrier();
+		const __m128i desc4 = _mm_loadu_si128(RTE_CAST_PTR(const __m128i *, desc + 4));
+		rte_compiler_barrier();
+		const __m128i desc3 = _mm_loadu_si128(RTE_CAST_PTR(const __m128i *, desc + 3));
+		rte_compiler_barrier();
+		const __m128i desc2 = _mm_loadu_si128(RTE_CAST_PTR(const __m128i *, desc + 2));
+		rte_compiler_barrier();
+		const __m128i desc1 = _mm_loadu_si128(RTE_CAST_PTR(const __m128i *, desc + 1));
+		rte_compiler_barrier();
+		const __m128i desc0 = _mm_loadu_si128(RTE_CAST_PTR(const __m128i *, desc + 0));
+
+		const __m256i descs6_7 =
+			_mm256_inserti128_si256(_mm256_castsi128_si256(desc6), desc7, 1);
+		const __m256i descs4_5 =
+			_mm256_inserti128_si256(_mm256_castsi128_si256(desc4), desc5, 1);
+		const __m256i descs2_3 =
+			_mm256_inserti128_si256(_mm256_castsi128_si256(desc2), desc3, 1);
+		const __m256i descs0_1 =
+			_mm256_inserti128_si256(_mm256_castsi128_si256(desc0), desc1, 1);
+
+		if (split_rxe_flags) {
+			for (j = 0; j < SXE2_RX_NUM_PER_LOOP_AVX; j++)
+				rte_mbuf_prefetch_part2(rx_pkts[i + j]);
+		}
+
+		mbufs6_7 = _mm256_shuffle_epi8(descs6_7, rvp_shuf_mask);
+		mbufs4_5 = _mm256_shuffle_epi8(descs4_5, rvp_shuf_mask);
+
+		mbufs6_7 = _mm256_add_epi16(mbufs6_7, crc_adjust);
+		mbufs4_5 = _mm256_add_epi16(mbufs4_5, crc_adjust);
+
+		const __m256i ptype_mask = _mm256_set1_epi32(SXE2_RX_DESC_PTYPE_MASK);
+
+		const __m256i staterrs4_7 = _mm256_unpackhi_epi32(descs6_7, descs4_5);
+
+		__m256i ptypes4_7 = _mm256_and_si256(staterrs4_7, ptype_mask);
+
+		const uint16_t ptype7 = _mm256_extract_epi16(ptypes4_7, 9);
+		const uint16_t ptype6 = _mm256_extract_epi16(ptypes4_7, 1);
+		const uint16_t ptype5 = _mm256_extract_epi16(ptypes4_7, 11);
+		const uint16_t ptype4 = _mm256_extract_epi16(ptypes4_7, 3);
+
+		mbufs6_7 = _mm256_insert_epi32(mbufs6_7, ptype_tbl[ptype7], 4);
+		mbufs6_7 = _mm256_insert_epi32(mbufs6_7, ptype_tbl[ptype6], 0);
+		mbufs4_5 = _mm256_insert_epi32(mbufs4_5, ptype_tbl[ptype5], 4);
+		mbufs4_5 = _mm256_insert_epi32(mbufs4_5, ptype_tbl[ptype4], 0);
+
+		mbufs2_3 = _mm256_shuffle_epi8(descs2_3, rvp_shuf_mask);
+		mbufs0_1 = _mm256_shuffle_epi8(descs0_1, rvp_shuf_mask);
+
+		mbufs2_3 = _mm256_add_epi16(mbufs2_3, crc_adjust);
+		mbufs0_1 = _mm256_add_epi16(mbufs0_1, crc_adjust);
+
+		const __m256i staterrs0_3 = _mm256_unpackhi_epi32(descs2_3, descs0_1);
+
+		__m256i ptypes0_3 = _mm256_and_si256(staterrs0_3, ptype_mask);
+
+		const uint16_t ptype3 = _mm256_extract_epi16(ptypes0_3, 9);
+		const uint16_t ptype2 = _mm256_extract_epi16(ptypes0_3, 1);
+		const uint16_t ptype1 = _mm256_extract_epi16(ptypes0_3, 11);
+		const uint16_t ptype0 = _mm256_extract_epi16(ptypes0_3, 3);
+
+		mbufs2_3 = _mm256_insert_epi32(mbufs2_3, ptype_tbl[ptype3], 4);
+		mbufs2_3 = _mm256_insert_epi32(mbufs2_3, ptype_tbl[ptype2], 0);
+		mbufs0_1 = _mm256_insert_epi32(mbufs0_1, ptype_tbl[ptype1], 4);
+		mbufs0_1 = _mm256_insert_epi32(mbufs0_1, ptype_tbl[ptype0], 0);
+
+		__m256i staterrs0_7 = _mm256_unpacklo_epi64(staterrs4_7, staterrs0_3);
+
+		__m256i stu_len0_7 = _mm256_unpackhi_epi64(staterrs4_7, staterrs0_3);
+		__m256i mbuf_flags = _mm256_setzero_si256();
+
+		if (do_offload) {
+			const __m256i desc_flags_mask = _mm256_set1_epi32(0x00001C04);
+			const __m256i desc_flags_rss_mask = _mm256_set1_epi32(0x20000000);
+			const __m256i vlan_flags =
+				_mm256_set_epi8
+				(0, 0, 0, 0, 0, 0, 0, 0,
+				 0, 0, 0,
+				 RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
+				 0, 0, 0, 0,
+				 0, 0, 0, 0, 0, 0, 0, 0,
+				 0, 0, 0,
+				 RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
+				 0, 0, 0, 0);
+
+			const __m256i rss_flags =
+				_mm256_set_epi8
+				(0, 0, 0, 0, 0, 0, 0, 0,
+				 0, 0, 0, RTE_MBUF_F_RX_RSS_HASH, 0, 0, 0, 0,
+				 0, 0, 0, 0, 0, 0, 0, 0,
+				 0, 0, 0, RTE_MBUF_F_RX_RSS_HASH, 0, 0, 0, 0);
+
+			const __m256i cksum_flags =
+				_mm256_set_epi8
+				(0, 0, 0, 0, 0, 0, 0, 0,
+				 ((RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
+					RTE_MBUF_F_RX_L4_CKSUM_BAD |
+					RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1),
+				 ((RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
+					RTE_MBUF_F_RX_L4_CKSUM_BAD |
+					RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1),
+				 ((RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
+					RTE_MBUF_F_RX_L4_CKSUM_GOOD |
+					RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1),
+				 ((RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
+					RTE_MBUF_F_RX_L4_CKSUM_GOOD |
+					RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1),
+				 ((RTE_MBUF_F_RX_L4_CKSUM_BAD |
+					RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1),
+				 ((RTE_MBUF_F_RX_L4_CKSUM_BAD |
+					RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1),
+				 ((RTE_MBUF_F_RX_L4_CKSUM_GOOD |
+					RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1),
+				 ((RTE_MBUF_F_RX_L4_CKSUM_GOOD |
+					RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1),
+
+				 0, 0, 0, 0, 0, 0, 0, 0,
+				 ((RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
+					RTE_MBUF_F_RX_L4_CKSUM_BAD |
+					RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1),
+				 ((RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
+					RTE_MBUF_F_RX_L4_CKSUM_BAD |
+					RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1),
+				 ((RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
+					RTE_MBUF_F_RX_L4_CKSUM_GOOD |
+					RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1),
+				 ((RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
+					RTE_MBUF_F_RX_L4_CKSUM_GOOD |
+					RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1),
+				 ((RTE_MBUF_F_RX_L4_CKSUM_BAD |
+					RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1),
+				 ((RTE_MBUF_F_RX_L4_CKSUM_BAD |
+					RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1),
+				 ((RTE_MBUF_F_RX_L4_CKSUM_GOOD |
+					RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1),
+				 ((RTE_MBUF_F_RX_L4_CKSUM_GOOD |
+					RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1));
+
+			const __m256i cksum_mask =
+				_mm256_set1_epi32
+				(RTE_MBUF_F_RX_IP_CKSUM_MASK |
+				RTE_MBUF_F_RX_L4_CKSUM_MASK |
+				RTE_MBUF_F_RX_OUTER_L4_CKSUM_MASK |
+				RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD);
+			const __m256i vlan_mask =
+				_mm256_set1_epi32
+				(RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED);
+
+			__m256i tmp_flags;
+			__m256i descs_flags = _mm256_and_si256(staterrs0_7, desc_flags_mask);
+			stu_len0_7 = _mm256_and_si256(stu_len0_7, desc_flags_rss_mask);
+
+			tmp_flags = _mm256_shuffle_epi8(vlan_flags, descs_flags);
+			mbuf_flags = _mm256_and_si256(tmp_flags, vlan_mask);
+
+			descs_flags = _mm256_srli_epi32(descs_flags, 10);
+			tmp_flags = _mm256_shuffle_epi8(cksum_flags, descs_flags);
+			tmp_flags = _mm256_slli_epi32(tmp_flags, 1);
+			tmp_flags = _mm256_and_si256(tmp_flags, cksum_mask);
+			mbuf_flags = _mm256_or_si256(mbuf_flags, tmp_flags);
+
+			descs_flags = _mm256_srli_epi32(stu_len0_7, 27);
+			tmp_flags = _mm256_shuffle_epi8(rss_flags, descs_flags);
+			mbuf_flags = _mm256_or_si256(mbuf_flags, tmp_flags);
+
+#ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
+
+			if (rxq->fnav_enable) {
+				__m256i fnav_vld0_3, fnav_vld4_7;
+				__m256i fnav_vld0_7;
+				__m256i v_zeros, v_ffff, v_u32_one;
+				const __m256i fdir_flags =
+					_mm256_set1_epi32
+					(RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID);
+				fnav_vld0_3 = _mm256_unpacklo_epi32(descs2_3, descs0_1);
+				fnav_vld4_7 = _mm256_unpacklo_epi32(descs6_7, descs4_5);
+
+				fnav_vld0_7 = _mm256_unpacklo_epi64(fnav_vld4_7, fnav_vld0_3);
+
+				fnav_vld0_7 = _mm256_slli_epi32(fnav_vld0_7, 26);
+				fnav_vld0_7 = _mm256_srli_epi32(fnav_vld0_7, 31);
+
+				v_zeros = _mm256_setzero_si256();
+				v_ffff = _mm256_cmpeq_epi32(v_zeros, v_zeros);
+				v_u32_one = _mm256_srli_epi32(v_ffff, 31);
+
+				tmp_flags = _mm256_cmpeq_epi32(fnav_vld0_7, v_u32_one);
+
+				tmp_flags = _mm256_and_si256(tmp_flags, fdir_flags);
+
+				mbuf_flags = _mm256_or_si256(mbuf_flags, tmp_flags);
+
+				rx_pkts[i + 0]->hash.fdir.hi = desc[0].wb.fd_filter_id;
+				rx_pkts[i + 1]->hash.fdir.hi = desc[1].wb.fd_filter_id;
+				rx_pkts[i + 2]->hash.fdir.hi = desc[2].wb.fd_filter_id;
+				rx_pkts[i + 3]->hash.fdir.hi = desc[3].wb.fd_filter_id;
+				rx_pkts[i + 4]->hash.fdir.hi = desc[4].wb.fd_filter_id;
+				rx_pkts[i + 5]->hash.fdir.hi = desc[5].wb.fd_filter_id;
+				rx_pkts[i + 6]->hash.fdir.hi = desc[6].wb.fd_filter_id;
+				rx_pkts[i + 7]->hash.fdir.hi = desc[7].wb.fd_filter_id;
+			}
+#endif
+		}
+
+		RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
+				 offsetof(struct rte_mbuf, rearm_data) + 8);
+		RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, rx_descriptor_fields1) !=
+				 offsetof(struct rte_mbuf, rearm_data) + 16);
+		RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, rearm_data) !=
+				 RTE_ALIGN(offsetof(struct rte_mbuf, rearm_data), 16));
+
+		__m256i rearm_arr[8];
+
+		rearm_arr[6] = _mm256_blend_epi32(mbuf_init, _mm256_slli_si256(mbuf_flags, 8), 4);
+		rearm_arr[4] = _mm256_blend_epi32(mbuf_init, _mm256_slli_si256(mbuf_flags, 4), 4);
+		rearm_arr[2] = _mm256_blend_epi32(mbuf_init, mbuf_flags, 4);
+		rearm_arr[0] = _mm256_blend_epi32(mbuf_init, _mm256_srli_si256(mbuf_flags, 4), 4);
+
+		rearm_arr[6] = _mm256_permute2f128_si256(rearm_arr[6], mbufs6_7, 0x20);
+		rearm_arr[4] = _mm256_permute2f128_si256(rearm_arr[4], mbufs4_5, 0x20);
+		rearm_arr[2] = _mm256_permute2f128_si256(rearm_arr[2], mbufs2_3, 0x20);
+		rearm_arr[0] = _mm256_permute2f128_si256(rearm_arr[0], mbufs0_1, 0x20);
+
+		_mm256_storeu_si256((__m256i *)&rx_pkts[i + 6]->rearm_data, rearm_arr[6]);
+		_mm256_storeu_si256((__m256i *)&rx_pkts[i + 4]->rearm_data, rearm_arr[4]);
+		_mm256_storeu_si256((__m256i *)&rx_pkts[i + 2]->rearm_data, rearm_arr[2]);
+		_mm256_storeu_si256((__m256i *)&rx_pkts[i + 0]->rearm_data, rearm_arr[0]);
+
+		const __m256i tmp_mbuf_flags =
+			_mm256_castsi128_si256(_mm256_extracti128_si256(mbuf_flags, 1));
+
+		rearm_arr[7] =
+			_mm256_blend_epi32(mbuf_init, _mm256_slli_si256(tmp_mbuf_flags, 8), 4);
+		rearm_arr[5] =
+			_mm256_blend_epi32(mbuf_init, _mm256_slli_si256(tmp_mbuf_flags, 4), 4);
+		rearm_arr[3] =
+			_mm256_blend_epi32(mbuf_init, tmp_mbuf_flags, 4);
+		rearm_arr[1] =
+			_mm256_blend_epi32(mbuf_init, _mm256_srli_si256(tmp_mbuf_flags, 4), 4);
+
+		rearm_arr[7] = _mm256_blend_epi32(rearm_arr[7], mbufs6_7, 0XF0);
+		rearm_arr[5] = _mm256_blend_epi32(rearm_arr[5], mbufs4_5, 0XF0);
+		rearm_arr[3] = _mm256_blend_epi32(rearm_arr[3], mbufs2_3, 0XF0);
+		rearm_arr[1] = _mm256_blend_epi32(rearm_arr[1], mbufs0_1, 0XF0);
+
+		_mm256_storeu_si256((__m256i *)&rx_pkts[i + 7]->rearm_data, rearm_arr[7]);
+		_mm256_storeu_si256((__m256i *)&rx_pkts[i + 5]->rearm_data, rearm_arr[5]);
+		_mm256_storeu_si256((__m256i *)&rx_pkts[i + 3]->rearm_data, rearm_arr[3]);
+		_mm256_storeu_si256((__m256i *)&rx_pkts[i + 1]->rearm_data, rearm_arr[1]);
+
+		if (umbcast_flags != NULL) {
+			const __m256i umbcast_mask =
+					_mm256_set1_epi32(SXE2_RX_DESC_STATUS_UMBCAST_MASK);
+			__m256i umbcast_bits_256 = _mm256_and_si256(staterrs0_7,
+								    umbcast_mask);
+
+			umbcast_bits_256 = _mm256_srli_epi32(umbcast_bits_256, 24);
+
+			__m128i umbcast_bits_128 = _mm_packs_epi32
+							(_mm256_castsi256_si128(umbcast_bits_256),
+							 _mm256_extractf128_si256
+								(umbcast_bits_256, 1));
+
+			umbcast_bits_128 = _mm_shuffle_epi8(umbcast_bits_128, eop_shuf_mask);
+
+			*(uint64_t *)umbcast_flags = _mm_cvtsi128_si64(umbcast_bits_128);
+			umbcast_flags += SXE2_RX_NUM_PER_LOOP_AVX;
+		}
+
+		if (split_rxe_flags != NULL) {
+			const __m256i eop_rxe_mask = _mm256_set1_epi32
+							(SXE2_RX_DESC_STATUS_EOP_MASK |
+							 SXE2_RX_DESC_ERROR_RXE_MASK |
+							 SXE2_RX_DESC_ERROR_OVERSIZE_MASK);
+
+			const __m128i eop_mask_128 = _mm_set1_epi16(SXE2_RX_DESC_STATUS_EOP_MASK);
+			const __m128i rxe_mask_128 = _mm_set1_epi16(SXE2_RX_DESC_ERROR_RXE_MASK |
+					SXE2_RX_DESC_ERROR_OVERSIZE_MASK);
+
+			const __m256i tmp_stats = _mm256_and_si256(staterrs0_7, eop_rxe_mask);
+
+			const __m128i eop_rxe_bits = _mm_packs_epi32
+							(_mm256_castsi256_si128(tmp_stats),
+							 _mm256_extractf128_si256(tmp_stats, 1));
+
+			__m128i not_eop_bits = _mm_andnot_si128(eop_rxe_bits, eop_mask_128);
+
+			not_eop_bits = _mm_or_si128
+					(not_eop_bits,
+					 _mm_srli_epi16
+					(_mm_and_si128(eop_rxe_bits, rxe_mask_128),
+					7));
+
+			not_eop_bits = _mm_shuffle_epi8(not_eop_bits, eop_shuf_mask);
+
+			*(uint64_t *)split_rxe_flags = _mm_cvtsi128_si64(not_eop_bits);
+			split_rxe_flags += SXE2_RX_NUM_PER_LOOP_AVX;
+		}
+
+		staterrs0_7 = _mm256_and_si256(staterrs0_7, dd_mask);
+
+		staterrs0_7 = _mm256_packs_epi32(staterrs0_7, _mm256_setzero_si256());
+		bit_num = rte_popcount64
+				(_mm_cvtsi128_si64(_mm256_extracti128_si256(staterrs0_7, 1)));
+		bit_num += rte_popcount64
+				(_mm_cvtsi128_si64(_mm256_castsi256_si128(staterrs0_7)));
+
+		done_num += bit_num;
+
+		if (bit_num != SXE2_RX_NUM_PER_LOOP_AVX)
+			break;
+	}
+
+	rxq->processing_idx += done_num;
+	rxq->processing_idx &= (rxq->ring_depth - 1);
+	if ((1 == (rxq->processing_idx & 1)) && done_num > 1) {
+		rxq->processing_idx--;
+		done_num--;
+	}
+	rxq->realloc_num     += done_num;
+
+l_end:
+	PMD_LOG_DEBUG(RX, "port_id=%u queue_id=%u last_id=%u recv_pkts=%d",
+		rxq->port_id, rxq->queue_id, rxq->processing_idx, done_num);
+	return done_num;
+}
+
+static __rte_always_inline uint16_t
+sxe2_rx_pkts_scattered_batch_vec_avx2(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts, bool do_offload)
+{
+	const uint64_t *split_rxe_flags64;
+	uint8_t split_rxe_flags[SXE2_RX_PKTS_BURST_BATCH_NUM_VEC] = {0};
+	uint8_t umbcast_flags[SXE2_RX_PKTS_BURST_BATCH_NUM_VEC] = {0};
+	uint16_t rx_done_num;
+	uint16_t rx_pkt_done_num;
+
+	rx_pkt_done_num = 0;
+
+	if (rxq->vsi->adapter->devargs.sw_stats_en) {
+		rx_done_num = sxe2_rx_pkts_common_vec_avx2(rxq, rx_pkts, nb_pkts,
+				split_rxe_flags, umbcast_flags, do_offload);
+	} else {
+		rx_done_num = sxe2_rx_pkts_common_vec_avx2(rxq, rx_pkts, nb_pkts,
+				split_rxe_flags, NULL, do_offload);
+	}
+	if (rx_done_num == 0)
+		goto l_end;
+
+	if (!rxq->vsi->adapter->devargs.sw_stats_en) {
+		split_rxe_flags64 = (uint64_t *)split_rxe_flags;
+
+		if (rxq->pkt_first_seg == NULL &&
+				split_rxe_flags64[0] == 0 && split_rxe_flags64[1] == 0 &&
+				split_rxe_flags64[2] == 0 && split_rxe_flags64[3] == 0) {
+			rx_pkt_done_num = rx_done_num;
+			goto l_end;
+		}
+
+		if (rxq->pkt_first_seg == NULL) {
+			while (rx_pkt_done_num < rx_done_num &&
+					split_rxe_flags[rx_pkt_done_num] == 0)
+				rx_pkt_done_num++;
+
+			if (rx_pkt_done_num == rx_done_num)
+				goto l_end;
+
+			rxq->pkt_first_seg = rx_pkts[rx_pkt_done_num];
+		}
+	}
+
+	rx_pkt_done_num += sxe2_rx_pkts_refactor(rxq, &rx_pkts[rx_pkt_done_num],
+			rx_done_num - rx_pkt_done_num, &split_rxe_flags[rx_pkt_done_num],
+			&umbcast_flags[rx_pkt_done_num]);
+
+l_end:
+	return rx_pkt_done_num;
+}
+
+static __rte_always_inline uint16_t
+sxe2_rx_pkts_scattered_common_vec_avx2(struct sxe2_rx_queue *rxq, struct rte_mbuf **rx_pkts,
+		uint16_t nb_pkts, bool do_offload)
+{
+	uint16_t done_num = 0;
+	uint16_t once_num;
+
+	while (nb_pkts > SXE2_RX_PKTS_BURST_BATCH_NUM) {
+		once_num =
+		sxe2_rx_pkts_scattered_batch_vec_avx2(rxq,
+						      rx_pkts + done_num,
+						      SXE2_RX_PKTS_BURST_BATCH_NUM,
+						      do_offload);
+		done_num += once_num;
+		nb_pkts -= once_num;
+		if (once_num < SXE2_RX_PKTS_BURST_BATCH_NUM)
+			goto l_end;
+	}
+
+	done_num += sxe2_rx_pkts_scattered_batch_vec_avx2(rxq,
+			rx_pkts + done_num, nb_pkts, do_offload);
+l_end:
+	return done_num;
+}
+
+uint16_t sxe2_rx_pkts_scattered_vec_avx2(void *rx_queue,
+		struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
+{
+	return sxe2_rx_pkts_scattered_common_vec_avx2(rx_queue,
+			rx_pkts, nb_pkts, false);
+}
+
+uint16_t sxe2_rx_pkts_scattered_vec_avx2_offload(void *rx_queue,
+		struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
+{
+	return sxe2_rx_pkts_scattered_common_vec_avx2(rx_queue,
+			rx_pkts, nb_pkts, true);
+}
-- 
2.47.3


^ permalink raw reply related

* [PATCH v1 08/23] net/sxe2: support statistics and multi-process
From: liujie5 @ 2026-05-24  9:32 UTC (permalink / raw)
  To: stephen; +Cc: dev, Jie Liu
In-Reply-To: <20260524093259.397506-1-liujie5@linkdatatechnology.com>

From: Jie Liu <liujie5@linkdatatechnology.com>

- The statistics support includes:
- Basic statistics (ipackets, opackets, ibytes, obytes, etc.)
- Extended statistics (xstats) for detailed hardware counters.
- Per-queue statistics for both RX and TX.

The multi-process support allows secondary processes to retrieve
statistics. Since secondary processes cannot access hardware registers
directly, an IPC mechanism is implemented using the DPDK MP API.

Atomic operations are used when reading 64-bit counters to ensure
data consistency between processes.

Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
 drivers/net/sxe2/meson.build     |   2 +
 drivers/net/sxe2/sxe2_cmd_chnl.c | 340 +++++++++++++++++-
 drivers/net/sxe2/sxe2_cmd_chnl.h |  23 ++
 drivers/net/sxe2/sxe2_drv_cmd.h  | 120 +++++++
 drivers/net/sxe2/sxe2_ethdev.c   |  38 +-
 drivers/net/sxe2/sxe2_mp.c       | 413 ++++++++++++++++++++++
 drivers/net/sxe2/sxe2_mp.h       |  73 ++++
 drivers/net/sxe2/sxe2_stats.c    | 586 +++++++++++++++++++++++++++++++
 drivers/net/sxe2/sxe2_stats.h    |  39 ++
 9 files changed, 1621 insertions(+), 13 deletions(-)
 create mode 100644 drivers/net/sxe2/sxe2_mp.c
 create mode 100644 drivers/net/sxe2/sxe2_mp.h
 create mode 100644 drivers/net/sxe2/sxe2_stats.c
 create mode 100644 drivers/net/sxe2/sxe2_stats.h

diff --git a/drivers/net/sxe2/meson.build b/drivers/net/sxe2/meson.build
index e3bcfc2876..d860629def 100644
--- a/drivers/net/sxe2/meson.build
+++ b/drivers/net/sxe2/meson.build
@@ -66,6 +66,8 @@ sources += files(
         'sxe2_tm.c',
         'sxe2_ipsec.c',
         'sxe2_security.c',
+        'sxe2_mp.c',
+        'sxe2_stats.c',
 )
 
 allow_internal_get_api = true
\ No newline at end of file
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 7711e8e57d..a1fc8a50e3 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -348,6 +348,184 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
 	return ret;
 }
 
+int32_t sxe2_drv_get_mac_stats(struct sxe2_adapter *adapter)
+{
+	int32_t ret = 0;
+	uint8_t i = 0;
+	struct sxe2_common_device *cdev = adapter->cdev;
+	struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
+	struct sxe2_stats *stats = &vsi->vsi_stats.vsi_hw_stats;
+	struct sxe2_drv_cmd_params param = {0};
+	struct sxe2_drv_mac_stats_resp resp = {0};
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_MAC_STATS_GET,
+				 NULL, 0,
+				 &resp, sizeof(resp));
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, DRV, "vsi stats get failed, ret=%d", ret);
+		goto l_end;
+	}
+
+	stats->rx_out_of_buffer        = rte_le_to_cpu_64(resp.rx_out_of_buffer);
+	stats->rx_qblock_drop          = rte_le_to_cpu_64(resp.rx_qblock_drop);
+	stats->tx_frame_good           = rte_le_to_cpu_64(resp.tx_frame_good);
+	stats->rx_frame_good           = rte_le_to_cpu_64(resp.rx_frame_good);
+	stats->rx_crc_errors           = rte_le_to_cpu_64(resp.rx_crc_errors);
+	stats->tx_bytes_good           = rte_le_to_cpu_64(resp.tx_bytes_good);
+	stats->rx_bytes_good           = rte_le_to_cpu_64(resp.rx_bytes_good);
+	stats->tx_multicast_good       = rte_le_to_cpu_64(resp.tx_multicast_good);
+	stats->tx_broadcast_good       = rte_le_to_cpu_64(resp.tx_broadcast_good);
+	stats->rx_multicast_good       = rte_le_to_cpu_64(resp.rx_multicast_good);
+	stats->rx_broadcast_good       = rte_le_to_cpu_64(resp.rx_broadcast_good);
+	stats->rx_len_errors           = rte_le_to_cpu_64(resp.rx_len_errors);
+	stats->rx_out_of_range_errors  = rte_le_to_cpu_64(resp.rx_out_of_range_errors);
+	stats->rx_oversize_pkts_phy    = rte_le_to_cpu_64(resp.rx_oversize_pkts_phy);
+	stats->rx_symbol_err	       = rte_le_to_cpu_64(resp.rx_symbol_err);
+	stats->rx_pause_frame	       = rte_le_to_cpu_64(resp.rx_pause_frame);
+	stats->tx_pause_frame	       = rte_le_to_cpu_64(resp.tx_pause_frame);
+	stats->rx_discards_phy	       = rte_le_to_cpu_64(resp.rx_discards_phy);
+	stats->rx_discards_ips_phy     = rte_le_to_cpu_64(resp.rx_discards_ips_phy);
+	stats->tx_dropped_link_down    = rte_le_to_cpu_64(resp.tx_dropped_link_down);
+	stats->rx_undersize_good       = rte_le_to_cpu_64(resp.rx_undersize_good);
+	stats->rx_runt_error	       = rte_le_to_cpu_64(resp.rx_runt_error);
+	stats->tx_bytes_good_bad       = rte_le_to_cpu_64(resp.tx_bytes_good_bad);
+	stats->tx_frame_good_bad       = rte_le_to_cpu_64(resp.tx_frame_good_bad);
+	stats->rx_jabbers              = rte_le_to_cpu_64(resp.rx_jabbers);
+	stats->rx_size_64              = rte_le_to_cpu_64(resp.rx_size_64);
+	stats->rx_size_65_127          = rte_le_to_cpu_64(resp.rx_size_65_127);
+	stats->rx_size_128_255         = rte_le_to_cpu_64(resp.rx_size_128_255);
+	stats->rx_size_256_511         = rte_le_to_cpu_64(resp.rx_size_256_511);
+	stats->rx_size_512_1023        = rte_le_to_cpu_64(resp.rx_size_512_1023);
+	stats->rx_size_1024_1522       = rte_le_to_cpu_64(resp.rx_size_1024_1522);
+	stats->rx_size_1523_max        = rte_le_to_cpu_64(resp.rx_size_1523_max);
+	stats->rx_pcs_symbol_err_phy   = rte_le_to_cpu_64(resp.rx_pcs_symbol_err_phy);
+	stats->rx_corrected_bits_phy   = rte_le_to_cpu_64(resp.rx_corrected_bits_phy);
+	stats->rx_err_lane_0_phy       = rte_le_to_cpu_64(resp.rx_err_lane_0_phy);
+	stats->rx_err_lane_1_phy       = rte_le_to_cpu_64(resp.rx_err_lane_1_phy);
+	stats->rx_err_lane_2_phy       = rte_le_to_cpu_64(resp.rx_err_lane_2_phy);
+	stats->rx_err_lane_3_phy       = rte_le_to_cpu_64(resp.rx_err_lane_3_phy);
+	stats->rx_illegal_bytes        = rte_le_to_cpu_64(resp.rx_illegal_bytes);
+	stats->rx_oversize_good        = rte_le_to_cpu_64(resp.rx_oversize_good);
+	stats->tx_unicast              = rte_le_to_cpu_64(resp.tx_unicast);
+	stats->tx_broadcast            = rte_le_to_cpu_64(resp.tx_broadcast);
+	stats->tx_multicast            = rte_le_to_cpu_64(resp.tx_multicast);
+	stats->tx_vlan_packet_good     = rte_le_to_cpu_64(resp.tx_vlan_packet_good);
+	stats->tx_size_64              = rte_le_to_cpu_64(resp.tx_size_64);
+	stats->tx_size_65_127          = rte_le_to_cpu_64(resp.tx_size_65_127);
+	stats->tx_size_128_255         = rte_le_to_cpu_64(resp.tx_size_128_255);
+	stats->tx_size_256_511         = rte_le_to_cpu_64(resp.tx_size_256_511);
+	stats->tx_size_512_1023        = rte_le_to_cpu_64(resp.tx_size_512_1023);
+	stats->tx_size_1024_1522       = rte_le_to_cpu_64(resp.tx_size_1024_1522);
+	stats->tx_size_1523_max        = rte_le_to_cpu_64(resp.tx_size_1523_max);
+	stats->tx_underflow_error      = rte_le_to_cpu_64(resp.tx_underflow_error);
+	stats->rx_byte_good_bad        = rte_le_to_cpu_64(resp.rx_byte_good_bad);
+	stats->rx_frame_good_bad       = rte_le_to_cpu_64(resp.rx_frame_good_bad);
+	stats->rx_unicast_good         = rte_le_to_cpu_64(resp.rx_unicast_good);
+	stats->rx_vlan_packets         = rte_le_to_cpu_64(resp.rx_vlan_packets);
+
+	for (i = 0; i < SXE2_MAX_USER_PRIORITY; i++) {
+		stats->rx_prio_buf_discard[i]  =
+			rte_le_to_cpu_64(resp.rx_prio_buf_discard[i]);
+		stats->prio_xoff_rx[i]  =
+			rte_le_to_cpu_64(resp.prio_xoff_rx[i]);
+		stats->prio_xoff_tx[i]  =
+			rte_le_to_cpu_64(resp.prio_xoff_tx[i]);
+		stats->prio_xon_rx[i]  =
+			rte_le_to_cpu_64(resp.prio_xon_rx[i]);
+		stats->prio_xon_tx[i]  =
+			rte_le_to_cpu_64(resp.prio_xon_tx[i]);
+		stats->prio_xon_2_xoff[i]  =
+			rte_le_to_cpu_64(resp.prio_xon_2_xoff[i]);
+	}
+
+l_end:
+	return ret;
+}
+
+int32_t sxe2_drv_mac_stats_reset(struct sxe2_adapter *adapter)
+{
+	int32_t ret = 0;
+	struct sxe2_common_device *cdev = adapter->cdev;
+	struct sxe2_drv_cmd_params param = {0};
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_MAC_STATS_CLEAR,
+				 NULL, 0,
+				 NULL, 0);
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, DRV, "mac stats reset failed, ret=%d", ret);
+		goto l_end;
+	}
+
+l_end:
+	return ret;
+}
+
+int32_t sxe2_drv_get_vsi_stats(struct sxe2_adapter *adapter)
+{
+	int32_t ret = 0;
+	struct sxe2_common_device *cdev = adapter->cdev;
+	struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
+	struct sxe2_stats *new_stats = &vsi->vsi_stats.vsi_hw_stats;
+	struct sxe2_drv_cmd_params param = {0};
+	struct sxe2_drv_vsi_stats_req req = {0};
+	struct sxe2_drv_vsi_stats_resp resp = {0};
+
+	req.vsi_id = rte_cpu_to_le_16(vsi->vsi_id);
+	req.sw_stats.rx_bytes = rte_cpu_to_le_64(vsi->vsi_stats.stats.ibytes);
+	req.sw_stats.rx_packets = rte_cpu_to_le_64(vsi->vsi_stats.stats.ipackets);
+	req.sw_stats.tx_bytes = rte_cpu_to_le_64(vsi->vsi_stats.stats.obytes);
+	req.sw_stats.tx_packets = rte_cpu_to_le_64(vsi->vsi_stats.stats.opackets);
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_VSI_STATS_GET,
+				 &req, sizeof(req),
+				 &resp, sizeof(resp));
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, DRV, "vsi stats get failed, ret=%d", ret);
+		goto l_end;
+	}
+
+	new_stats->rx_vsi_unicast_packets   = rte_le_to_cpu_64(resp.rx_vsi_unicast_packets);
+	new_stats->rx_vsi_bytes             = rte_le_to_cpu_64(resp.rx_vsi_bytes);
+	new_stats->tx_vsi_unicast_packets   = rte_le_to_cpu_64(resp.tx_vsi_unicast_packets);
+	new_stats->tx_vsi_bytes             = rte_le_to_cpu_64(resp.tx_vsi_bytes);
+	new_stats->rx_vsi_multicast_packets = rte_le_to_cpu_64(resp.rx_vsi_multicast_packets);
+	new_stats->tx_vsi_multicast_packets = rte_le_to_cpu_64(resp.tx_vsi_multicast_packets);
+	new_stats->rx_vsi_broadcast_packets = rte_le_to_cpu_64(resp.rx_vsi_broadcast_packets);
+	new_stats->tx_vsi_broadcast_packets = rte_le_to_cpu_64(resp.tx_vsi_broadcast_packets);
+	new_stats->opackets = new_stats->tx_vsi_unicast_packets +
+			      new_stats->tx_vsi_multicast_packets +
+			      new_stats->tx_vsi_broadcast_packets;
+	new_stats->obytes = new_stats->tx_vsi_bytes;
+	new_stats->ipackets = new_stats->rx_vsi_unicast_packets +
+			      new_stats->rx_vsi_multicast_packets +
+			      new_stats->rx_vsi_broadcast_packets;
+	new_stats->ibytes = new_stats->rx_vsi_bytes;
+
+l_end:
+	return ret;
+}
+
+int32_t sxe2_drv_vsi_stats_reset(struct sxe2_adapter *adapter)
+{
+	int32_t ret = 0;
+	struct sxe2_common_device *cdev = adapter->cdev;
+	struct sxe2_drv_cmd_params param = {0};
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_VSI_STATS_CLEAR,
+				 NULL, 0, NULL, 0);
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, DRV, "vsi stats reset failed, ret=%d", ret);
+		goto l_end;
+	}
+
+l_end:
+	return ret;
+}
+
 int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set)
 {
 	int32_t ret = 0;
@@ -409,8 +587,9 @@ int32_t sxe2_drv_uc_config(struct sxe2_adapter *adapter, struct rte_ether_addr *
 	mac_filter_cfg_req.type = SXE2_MAC_FILTER_TYPE_UC;
 
 	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_MAC_ADDR_UC,
-		 &mac_filter_cfg_req, sizeof(mac_filter_cfg_req),
-		 NULL, 0);
+				 &mac_filter_cfg_req,
+				 sizeof(mac_filter_cfg_req),
+				 NULL, 0);
 
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret)
@@ -435,8 +614,8 @@ int32_t sxe2_drv_mc_config(struct sxe2_adapter *adapter, struct rte_ether_addr *
 	mac_filter_cfg_req.type = SXE2_MAC_FILTER_TYPE_MC;
 
 	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_MAC_ADDR_MC,
-		 &mac_filter_cfg_req, sizeof(mac_filter_cfg_req),
-		 NULL, 0);
+				  &mac_filter_cfg_req, sizeof(mac_filter_cfg_req),
+				 NULL, 0);
 
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret)
@@ -455,7 +634,7 @@ int32_t sxe2_drv_vlan_config_query(struct sxe2_adapter *adapter)
 	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_VLAN_CFG_QUERY,
 				 NULL, 0,
 				 &vlan_cfg_query_resp,
-	 sizeof(vlan_cfg_query_resp));
+				 sizeof(vlan_cfg_query_resp));
 
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret)
@@ -566,7 +745,8 @@ int32_t sxe2_drv_rss_key_set(struct sxe2_adapter *adapter, uint8_t *key, uint16_
 	rte_memcpy(req->key, key, key_size);
 
 	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_RSS_KEY_SET,
-		req, buf_size, NULL, 0);
+				 req, buf_size,
+				 NULL, 0);
 
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret) {
@@ -602,7 +782,8 @@ int32_t sxe2_drv_rss_lut_set(struct sxe2_adapter *adapter, uint8_t *lut, uint16_
 	rte_memcpy(req->lut, lut, lut_size);
 
 	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_RSS_LUT_SET,
-		req, buf_size, NULL, 0);
+				 req, buf_size,
+				 NULL, 0);
 
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret) {
@@ -629,7 +810,8 @@ int32_t sxe2_drv_rss_hash_ctrl_func(struct sxe2_adapter *adapter, enum sxe2_rss_
 	req.func = func;
 
 	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_RSS_FUNC_SET,
-		&req, sizeof(req), NULL, 0);
+				 &req, sizeof(req),
+				 NULL, 0);
 
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret)
@@ -665,7 +847,8 @@ int32_t sxe2_drv_rss_hf_add(struct sxe2_adapter *adapter,
 	sxe2_drv_flow_bitmap_fill(req.hash_flds, rss_conf->flds);
 
 	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_RSS_HF_ADD,
-		&req, sizeof(req), NULL, 0);
+				 &req, sizeof(req),
+				 NULL, 0);
 
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret)
@@ -703,7 +886,8 @@ int32_t sxe2_drv_rss_hf_clear(struct sxe2_adapter *adapter)
 	int32_t ret = 0;
 
 	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_RSS_HF_CLEAR,
-		NULL, 0, NULL, 0);
+				 NULL, 0,
+				 NULL, 0);
 
 	ret = sxe2_drv_cmd_exec(cdev, &param);
 	if (ret)
@@ -878,7 +1062,6 @@ int32_t sxe2_drv_tm_commit(struct sxe2_adapter *adapter)
 	return ret;
 }
 
-
 int32_t sxe2_drv_ipsec_get_capa(struct sxe2_adapter *adapter)
 {
 	int32_t ret = -1;
@@ -1074,3 +1257,138 @@ int32_t sxe2_drv_ipsec_txsa_delete(struct sxe2_adapter *adapter,
 	return ret;
 }
 
+int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_queue_stats *qstats)
+{
+	struct sxe2_drv_cmd_params param = {0};
+	struct sxe2_queue_map_info resp = {0};
+	struct sxe2_common_device *cdev = adapter->cdev;
+	uint8_t pool_idx;
+	uint8_t index;
+	int32_t ret;
+
+	if (!(adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_Q_MAP)) {
+		ret = 0;
+		goto l_end;
+	}
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_TX_RX_MAP_GET,
+				 NULL, 0,
+				 &resp, sizeof(resp));
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret) {
+		PMD_LOG_ERR(DRV, "get queue info map failed, ret=%d", ret);
+		goto l_end;
+	}
+
+	for (pool_idx = 0; pool_idx < SXE2_RXQ_STATS_MAP_MAX_NUM; pool_idx++) {
+		qstats->q_ipackets[pool_idx] = resp.rxq_stats_map_info[pool_idx].rxq_lan_in_pkt_cnt;
+		qstats->q_ibytes[pool_idx] = resp.rxq_stats_map_info[pool_idx].rxq_lan_in_byte_cnt;
+	}
+
+	for (index = 0; index < SXE2_TXQ_STATS_MAP_MAX_NUM; index++) {
+		qstats->q_opackets[index] = resp.txq_stats_map_info[index].txq_lan_pkt_cnt;
+		qstats->q_obytes[index] = resp.txq_stats_map_info[index].txq_lan_byte_cnt;
+	}
+
+l_end:
+	return ret;
+}
+
+int32_t sxe2_drv_rxq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t pool_idx)
+{
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(eth_dev);
+	int32_t ret = 0;
+	struct sxe2_common_device *cdev = adapter->cdev;
+	struct sxe2_drv_cmd_params param = {0};
+	struct sxe2_drv_rx_map_req req = {0};
+	struct sxe2_rx_queue *rxq = NULL;
+
+	rxq = eth_dev->data->rx_queues[queue_id];
+	if (rxq == NULL) {
+		PMD_LOG_ERR(DRV, "Rx queue %u is not available or setup",
+				queue_id);
+		ret = -EINVAL;
+		goto l_end;
+	}
+
+	req.queue_id = rxq->queue_id;
+	req.pool_idx = pool_idx;
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_RX_MAP_SET,
+				 &req, sizeof(req),
+				 NULL, 0);
+
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret)
+		PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+
+l_end:
+	return ret;
+}
+
+int32_t sxe2_drv_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t pool_idx)
+{
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(eth_dev);
+	int32_t ret = 0;
+	struct sxe2_common_device *cdev = adapter->cdev;
+	struct sxe2_drv_cmd_params param = {0};
+	struct sxe2_drv_tx_map_req req = {0};
+	struct sxe2_tx_queue *txq = NULL;
+
+	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);
+		ret = -EINVAL;
+		goto l_end;
+	}
+
+	req.queue_id = txq->queue_id;
+	req.pool_idx = pool_idx;
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_TX_MAP_SET,
+				 &req, sizeof(req),
+				 NULL, 0);
+
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret)
+		PMD_LOG_ERR(DRV, "get dev caps failed, ret=%d", ret);
+
+l_end:
+	return ret;
+}
+
+int32_t sxe2_drv_mapping_reset(struct rte_eth_dev *eth_dev)
+{
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(eth_dev);
+	struct sxe2_drv_cmd_params param = {0};
+	struct sxe2_common_device *cdev = adapter->cdev;
+	int32_t ret;
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_TX_RX_MAP_RESET,
+				 NULL, 0,
+				 NULL, 0);
+
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret)
+		PMD_LOG_ERR(DRV, "Reset queue mapping failed, ret=%d", ret);
+
+	return ret;
+}
+
+int32_t sxe2_drv_mapping_stats_info_clear(struct rte_eth_dev *eth_dev)
+{
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(eth_dev);
+	struct sxe2_drv_cmd_params param = {0};
+	struct sxe2_common_device *cdev = adapter->cdev;
+	int32_t ret;
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_TX_RX_MAP_INFO_CLEAR,
+				 NULL, 0,
+				 NULL, 0);
+
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret)
+		PMD_LOG_ERR(DRV, "Clear map stats info failed, ret=%d", ret);
+
+	return ret;
+}
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index d8e09a4453..ff73d2f901 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -64,6 +64,29 @@ int32_t sxe2_drv_ipsec_txsa_delete(struct sxe2_adapter *adapter,
 
 int32_t sxe2_drv_promisc_config(struct sxe2_adapter *adapter, bool set);
 
+int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter);
+
+int32_t sxe2_drv_get_mac_stats(struct sxe2_adapter *adapter);
+
+int32_t sxe2_drv_mac_stats_reset(struct sxe2_adapter *adapter);
+
+int32_t sxe2_drv_get_vsi_stats(struct sxe2_adapter *adapter);
+
+int32_t sxe2_drv_vsi_stats_reset(struct sxe2_adapter *adapter);
+
+int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter,
+				       struct eth_queue_stats *qstats);
+
+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_txq_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t pool_idx);
+
+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_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index 4d9c2e05a8..a88e2b24bf 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -434,6 +434,126 @@ struct sxe2_drv_ipsec_rxsa_del_req {
 	uint8_t drv_id;
 };
 
+struct sxe2_drv_vsi_sw_stats {
+	__le64 rx_packets;
+	__le64 rx_bytes;
+	__le64 tx_packets;
+	__le64 tx_bytes;
+};
+
+struct sxe2_drv_vsi_stats_req {
+	__le16 vsi_id;
+	uint8_t  rsv[2];
+	struct sxe2_drv_vsi_sw_stats sw_stats;
+};
+
+struct sxe2_drv_vsi_stats_resp {
+	__le64 rx_vsi_unicast_packets;
+	__le64 rx_vsi_bytes;
+	__le64 tx_vsi_unicast_packets;
+	__le64 tx_vsi_bytes;
+	__le64 rx_vsi_multicast_packets;
+	__le64 tx_vsi_multicast_packets;
+	__le64 rx_vsi_broadcast_packets;
+	__le64 tx_vsi_broadcast_packets;
+};
+
+#define SXE2_MAX_USER_PRIORITY         (8)
+
+struct sxe2_drv_mac_stats_resp {
+	__le64 rx_out_of_buffer;
+	__le64 rx_qblock_drop;
+	__le64 tx_frame_good;
+	__le64 rx_frame_good;
+	__le64 rx_crc_errors;
+	__le64 tx_bytes_good;
+	__le64 rx_bytes_good;
+	__le64 tx_multicast_good;
+	__le64 tx_broadcast_good;
+	__le64 rx_multicast_good;
+	__le64 rx_broadcast_good;
+	__le64 rx_len_errors;
+	__le64 rx_out_of_range_errors;
+	__le64 rx_oversize_pkts_phy;
+	__le64 rx_symbol_err;
+	__le64 rx_pause_frame;
+	__le64 tx_pause_frame;
+	__le64 rx_discards_phy;
+	__le64 rx_discards_ips_phy;
+	__le64 tx_dropped_link_down;
+	__le64 rx_undersize_good;
+	__le64 rx_runt_error;
+	__le64 tx_bytes_good_bad;
+	__le64 tx_frame_good_bad;
+	__le64 rx_jabbers;
+	__le64 rx_size_64;
+	__le64 rx_size_65_127;
+	__le64 rx_size_128_255;
+	__le64 rx_size_256_511;
+	__le64 rx_size_512_1023;
+	__le64 rx_size_1024_1522;
+	__le64 rx_size_1523_max;
+	__le64 rx_pcs_symbol_err_phy;
+	__le64 rx_corrected_bits_phy;
+	__le64 rx_err_lane_0_phy;
+	__le64 rx_err_lane_1_phy;
+	__le64 rx_err_lane_2_phy;
+	__le64 rx_err_lane_3_phy;
+	__le64 rx_prio_buf_discard[SXE2_MAX_USER_PRIORITY];
+	__le64 rx_illegal_bytes;
+	__le64 rx_oversize_good;
+	__le64 tx_unicast;
+	__le64 tx_broadcast;
+	__le64 tx_multicast;
+	__le64 tx_vlan_packet_good;
+	__le64 tx_size_64;
+	__le64 tx_size_65_127;
+	__le64 tx_size_128_255;
+	__le64 tx_size_256_511;
+	__le64 tx_size_512_1023;
+	__le64 tx_size_1024_1522;
+	__le64 tx_size_1523_max;
+	__le64 tx_underflow_error;
+	__le64 rx_byte_good_bad;
+	__le64 rx_frame_good_bad;
+	__le64 rx_unicast_good;
+	__le64 rx_vlan_packets;
+	__le64 prio_xoff_rx[SXE2_MAX_USER_PRIORITY];
+	__le64 prio_xon_rx[SXE2_MAX_USER_PRIORITY];
+	__le64 prio_xon_tx[SXE2_MAX_USER_PRIORITY];
+	__le64 prio_xoff_tx[SXE2_MAX_USER_PRIORITY];
+	__le64 prio_xon_2_xoff[SXE2_MAX_USER_PRIORITY];
+};
+
+struct sxe2_txq_map_info {
+	__le32 txq_lan_pkt_cnt;
+	__le32 txq_lan_byte_cnt;
+};
+
+struct sxe2_rxq_map_info {
+	__le64 rxq_lan_in_pkt_cnt;
+	__le64 rxq_lan_in_byte_cnt;
+	__le64 rxq_fd_in_pkt_cnt;
+	__le64 rxq_mng_in_pkt_cnt;
+	__le64 rxq_mng_in_byte_cnt;
+	__le64 rxq_mng_out_pkt_cnt;
+};
+
+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];
+};
+
+struct sxe2_drv_rx_map_req {
+	__le16 queue_id;
+	uint8_t pool_idx;
+};
+
+struct sxe2_drv_tx_map_req {
+	__le16 queue_id;
+	uint8_t pool_idx;
+};
+
 enum sxe2_drv_cmd_module {
 	SXE2_DRV_CMD_MODULE_HANDSHAKE = 0,
 	SXE2_DRV_CMD_MODULE_DEV = 1,
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 00c0552d4a..dbe1a2bce1 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -31,6 +31,8 @@
 #include "sxe2_common.h"
 #include "sxe2_ptype.h"
 #include "sxe2_common_log.h"
+#include "sxe2_mp.h"
+#include "sxe2_stats.h"
 #include "sxe2_host_regs.h"
 #include "sxe2_ioctl_chnl_func.h"
 
@@ -132,6 +134,14 @@ static const struct eth_dev_ops sxe2_eth_dev_ops = {
 	.rss_hash_conf_get          = sxe2_dev_rss_hash_conf_get,
 
 	.tm_ops_get                 = sxe2_tm_ops_get,
+
+	.stats_get                  = sxe2_stats_info_get,
+	.stats_reset                = sxe2_stats_info_reset,
+	.xstats_get                 = sxe2_xstats_info_get,
+	.xstats_get_names           = sxe2_xstats_names_get,
+	.xstats_reset               = sxe2_stats_info_reset,
+
+	.queue_stats_mapping_set    = sxe2_queue_stats_mapping_set,
 };
 
 static int32_t sxe2_dev_configure(struct rte_eth_dev *dev)
@@ -1023,6 +1033,9 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
 		sxe2_rx_mode_func_set(dev);
 		sxe2_tx_mode_func_set(dev);
+		ret = sxe2_mp_init(dev);
+		if (ret != 0)
+			PMD_LOG_ERR(INIT, "Failed to mp init (secondary), ret=%d", ret);
 		goto l_end;
 	}
 
@@ -1076,12 +1089,27 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
 		goto init_sched_err;
 	}
 
+	ret = sxe2_stats_init(dev);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to stats init, ret=%d", ret);
+		goto init_xstats_err;
+	}
+
+	ret = sxe2_mp_init(dev);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to mp init, ret=%d", ret);
+		goto init_xstats_err;
+	}
+
 	goto l_end;
 
-init_security_err:
-	sxe2_eth_uinit(dev);
+init_xstats_err:
+	(void)sxe2_sched_uinit(dev);
 init_sched_err:
 init_rss_err:
+	sxe2_security_uinit(dev);
+init_security_err:
+	sxe2_eth_uinit(dev);
 init_eth_err:
 init_dev_info_err:
 	sxe2_vsi_uninit(dev);
@@ -1093,8 +1121,13 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
 
 static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
 {
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+		sxe2_mp_uninit(dev);
+		goto l_end;
+	}
 	(void)sxe2_dev_stop(dev);
 	(void)sxe2_queues_release(dev);
+	sxe2_mp_uninit(dev);
 	(void)sxe2_rss_disable(dev);
 	(void)sxe2_sched_uinit(dev);
 	sxe2_vsi_uninit(dev);
@@ -1102,6 +1135,7 @@ static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
 	sxe2_dev_pci_map_uinit(dev);
 	sxe2_eth_uinit(dev);
 
+l_end:
 	return 0;
 }
 
diff --git a/drivers/net/sxe2/sxe2_mp.c b/drivers/net/sxe2/sxe2_mp.c
new file mode 100644
index 0000000000..caf044dd24
--- /dev/null
+++ b/drivers/net/sxe2/sxe2_mp.c
@@ -0,0 +1,413 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
+ */
+
+#include <rte_eal.h>
+#include <rte_ethdev.h>
+#include <ethdev_driver.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_string_fns.h>
+
+#include "sxe2_mp.h"
+#include "sxe2_stats.h"
+#include "sxe2_common_log.h"
+
+static RTE_ATOMIC(uint16_t)primary_ethdev_cnt;
+static RTE_ATOMIC(uint16_t)secondary_ethdev_cnt;
+static const struct rte_memzone *sxe2_mp_mz;
+
+static int32_t sxe2_mp_acquire_token(void);
+static void sxe2_mp_release_token(void);
+
+static int32_t sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg,
+				   const void *peer);
+
+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)
+{
+	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 cnt = 0;
+
+	if (!rte_eth_dev_is_valid_port(param->port_id)) {
+		PMD_LOG_ERR(DRV, "primary process: invalid port_id %u",
+				param->port_id);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	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;
+	}
+
+	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,
+					  &mz_data->payload.stats_blk.qstats);
+		break;
+	case SXE2_MP_REQ_GET_XSTATS:
+		cnt = sxe2_xstats_info_get(dev,
+				mz_data->payload.xstats_blk.xstats,
+				SXE2_MP_MAX_XSTATS);
+
+		if (cnt >= 0) {
+			mz_data->payload.xstats_blk.xstats_num = (uint32_t)cnt;
+			ret = 0;
+		} else {
+			mz_data->payload.xstats_blk.xstats_num = 0;
+			ret = cnt;
+		}
+		break;
+	case SXE2_MP_REQ_RESET_STATS:
+		ret = sxe2_stats_hw_reset(dev);
+		break;
+	default:
+		PMD_LOG_ERR(DRV, "primary process: unrecognized msg type: %d",
+				param->type);
+		send_reply = false;
+		ret = -EINVAL;
+		goto out;
+	}
+out:
+	if (!send_reply)
+		return ret;
+
+	reply_param->result = ret;
+	reply_param->type = param->type;
+	reply_param->port_id = param->port_id;
+
+	return rte_mp_reply(&reply, peer);
+}
+
+static int32_t
+sxe2_mp_secondary_handle(const struct rte_mp_msg *mp_msg __rte_unused,
+			 const void *peer __rte_unused)
+{
+	PMD_LOG_WARN(DRV, "the secondary process handler should not be called");
+	return 0;
+}
+
+static int32_t
+sxe2_mp_init_primary(__rte_unused struct rte_eth_dev *dev)
+{
+	int32_t ret;
+
+	if (sxe2_mp_mz == NULL) {
+		sxe2_mp_mz = rte_memzone_reserve(SXE2_MP_MZ_NAME,
+				sizeof(struct sxe2_mp_shared_data),
+				rte_socket_id(), 0);
+		if (sxe2_mp_mz == NULL && rte_errno != EEXIST) {
+			PMD_LOG_ERR(DRV, "Failed to reserve memzone %s, error: %d",
+					SXE2_MP_MZ_NAME, -rte_errno);
+			ret = -rte_errno;
+			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;
+		}
+
+		struct sxe2_mp_shared_data *mz =
+			(struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
+		rte_atomic_store_explicit(&mz->in_use, 0, rte_memory_order_release);
+	}
+
+	ret = rte_mp_action_register(SXE2_MP_NAME, sxe2_mp_primary_handle);
+	if (ret && rte_errno == ENOTSUP) {
+		PMD_LOG_INFO(DRV, "Primary not support IPC.");
+		ret = 0;
+		goto out;
+	} else if (ret && rte_errno != EEXIST) {
+		PMD_LOG_ERR(DRV, "Failed to register MP primary handle, error: %d",
+			-rte_errno);
+		goto out;
+	}
+
+	rte_atomic_fetch_add_explicit(&primary_ethdev_cnt, 1, rte_memory_order_relaxed);
+
+	ret = 0;
+out:
+	return ret;
+}
+
+static int32_t
+sxe2_mp_init_secondary(__rte_unused struct rte_eth_dev *dev)
+{
+	int32_t ret;
+
+	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;
+	}
+
+	ret = rte_mp_action_register(SXE2_MP_NAME, sxe2_mp_secondary_handle);
+	if (ret && rte_errno != EEXIST) {
+		PMD_LOG_ERR(DRV, "Failed to register MP secondary handle, error: %d",
+				-rte_errno);
+		goto out;
+	}
+
+	rte_atomic_fetch_add_explicit(&secondary_ethdev_cnt, 1, rte_memory_order_relaxed);
+
+	ret = 0;
+out:
+	return ret;
+}
+
+int32_t
+sxe2_mp_init(struct rte_eth_dev *dev)
+{
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		return sxe2_mp_init_primary(dev);
+	else
+		return sxe2_mp_init_secondary(dev);
+}
+
+void
+sxe2_mp_uninit(__rte_unused struct rte_eth_dev *dev)
+{
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		if (rte_atomic_fetch_sub_explicit(&primary_ethdev_cnt, 1,
+			rte_memory_order_acq_rel) == 1) {
+			rte_mp_action_unregister(SXE2_MP_NAME);
+			if (sxe2_mp_mz != NULL) {
+				rte_memzone_free(sxe2_mp_mz);
+				sxe2_mp_mz = NULL;
+			}
+		}
+	} else {
+		if (rte_atomic_fetch_sub_explicit(&secondary_ethdev_cnt, 1,
+			rte_memory_order_acq_rel) == 1)
+			rte_mp_action_unregister(SXE2_MP_NAME);
+	}
+}
+
+static int32_t sxe2_mp_acquire_token(void)
+{
+	struct sxe2_mp_shared_data *mz;
+	uint16_t expected;
+
+	if (sxe2_mp_mz == NULL)
+		return -EINVAL;
+
+	mz = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
+
+	for (int32_t i = 0; i < SXE2_MP_MAX_SPIN; i++) {
+		expected = 0;
+		if (rte_atomic_compare_exchange_strong_explicit(&mz->in_use, &expected, 1,
+			rte_memory_order_acquire, rte_memory_order_relaxed))
+			return 0;
+
+		rte_pause();
+	}
+	return -EBUSY;
+}
+
+static void sxe2_mp_release_token(void)
+{
+	struct sxe2_mp_shared_data *mz;
+
+	if (sxe2_mp_mz == NULL)
+		return;
+
+	mz = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
+	rte_atomic_store_explicit(&mz->in_use, 0, rte_memory_order_release);
+}
+
+int32_t sxe2_mp_request_simple(struct rte_eth_dev *dev,
+			   enum sxe2_mp_req_type type,
+			   int32_t *result_out)
+{
+	struct rte_mp_msg msg;
+	struct rte_mp_reply reply = { 0 };
+	struct timespec ts = { .tv_sec = SXE2_MP_MSG_TIMEOUT, .tv_nsec = 0 };
+	struct sxe2_mp_param *param = (struct sxe2_mp_param *)msg.param;
+	struct sxe2_mp_shared_data *mz_data;
+	int32_t ret = 0;
+
+	mz_data = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
+
+	memset(&mz_data->payload, 0, sizeof(mz_data->payload));
+	memset(&msg, 0, sizeof(msg));
+	(void)strlcpy(msg.name, SXE2_MP_NAME, sizeof(msg.name));
+	msg.len_param = sizeof(*param);
+	param->type = type;
+	param->port_id = dev->data->port_id;
+
+	ret = rte_mp_request_sync(&msg, &reply, &ts);
+	if (ret != 0) {
+		PMD_LOG_ERR(DRV,
+				"IPC request(type=%d) failed for port %u: %s",
+				type, dev->data->port_id, rte_strerror(rte_errno));
+		ret = -rte_errno;
+		goto out;
+	}
+
+	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;
+		goto out;
+	}
+
+	*result_out = ((struct sxe2_mp_param *)reply.msgs[0].param)->result;
+
+out:
+	if (reply.msgs != NULL)
+		free(reply.msgs);
+
+	return ret;
+}
+
+int32_t sxe2_mp_req_get_stats(struct rte_eth_dev *dev,
+		      struct rte_eth_stats *stats,
+		      struct eth_queue_stats *qstats)
+{
+	struct sxe2_mp_shared_data *mz_data;
+	int32_t mp_ret;
+	int32_t ret;
+	int32_t token_acquired = 0;
+
+	if (sxe2_mp_mz == NULL)
+		return -EINVAL;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		PMD_LOG_WARN(DRV, "Primary process direct execution for port %u",
+			     dev->data->port_id);
+		return sxe2_stats_info_get(dev, stats, qstats);
+	}
+
+	int32_t token_ret = sxe2_mp_acquire_token();
+	if (token_ret != 0)
+		return token_ret;
+	token_acquired = 1;
+
+	mp_ret = sxe2_mp_request_simple(dev, SXE2_MP_REQ_GET_STATS, &ret);
+	if (mp_ret != 0) {
+		ret = mp_ret;
+		goto out;
+	}
+
+	if (ret != 0) {
+		PMD_LOG_ERR(DRV, "Primary failed to exec request (type=%d), result: %d for port %u",
+			    SXE2_MP_REQ_GET_STATS, ret, dev->data->port_id);
+		goto out;
+	}
+
+	mz_data = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
+	memcpy(stats, &mz_data->payload.stats_blk.stats, sizeof(*stats));
+	memcpy(qstats, &mz_data->payload.stats_blk.qstats, sizeof(*qstats));
+	PMD_LOG_DEBUG(DRV, "sxe2_mp: stats received via IPC for port %u",
+			  dev->data->port_id);
+	ret = 0;
+out:
+	if (token_acquired)
+		sxe2_mp_release_token();
+	return ret;
+}
+
+int32_t sxe2_mp_req_get_xstats(struct rte_eth_dev *dev,
+			   struct rte_eth_xstat *xstats, uint32_t usr_cnt)
+{
+	struct sxe2_mp_shared_data *mz_data;
+	int32_t ret;
+	int32_t mp_ret;
+	int32_t token_acquired = 0;
+
+	if (sxe2_mp_mz == NULL)
+		return -EINVAL;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		PMD_LOG_WARN(DRV, "Primary process direct execution for port %u",
+			     dev->data->port_id);
+		return sxe2_xstats_info_get(dev, xstats, usr_cnt);
+	}
+
+	int32_t token_ret = sxe2_mp_acquire_token();
+	if (token_ret != 0)
+		return token_ret;
+	token_acquired = 1;
+
+	mp_ret = sxe2_mp_request_simple(dev, SXE2_MP_REQ_GET_XSTATS, &ret);
+	if (mp_ret != 0) {
+		ret = mp_ret;
+		goto out;
+	}
+
+	if (ret != 0) {
+		PMD_LOG_ERR(DRV, "Primary failed to exec request (type=%d), result: %d for port %u",
+			    SXE2_MP_REQ_GET_XSTATS, ret, dev->data->port_id);
+		goto out;
+	}
+
+	mz_data = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
+	if (usr_cnt < mz_data->payload.xstats_blk.xstats_num) {
+		PMD_LOG_ERR(DRV, "user usr_cnt:%u less than xstats cnt:%u.",
+			    usr_cnt, mz_data->payload.xstats_blk.xstats_num);
+		ret = (int32_t)mz_data->payload.xstats_blk.xstats_num;
+		goto out;
+	}
+
+	memcpy(xstats, mz_data->payload.xstats_blk.xstats,
+		   mz_data->payload.xstats_blk.xstats_num *
+			   sizeof(struct rte_eth_xstat));
+	ret = (int32_t)mz_data->payload.xstats_blk.xstats_num;
+
+	PMD_LOG_DEBUG(DRV,
+			  "xstats received via IPC for port %u (cnt=%d)",
+			  dev->data->port_id, ret);
+out:
+	if (token_acquired)
+		sxe2_mp_release_token();
+	return ret;
+}
+
+int32_t
+sxe2_mp_req_reset_stats(struct rte_eth_dev *dev)
+{
+	int32_t mp_ret;
+	int32_t ret = 0;
+
+	if (sxe2_mp_mz == NULL)
+		return -EINVAL;
+
+	mp_ret = sxe2_mp_request_simple(dev, SXE2_MP_REQ_RESET_STATS, &ret);
+	if (mp_ret != 0)
+		return mp_ret;
+
+	if (ret != 0) {
+		PMD_LOG_ERR(DRV,
+				"Primary failed SXE2_MP_REQ_RESET_STATS, result: %d for port %u",
+				ret, dev->data->port_id);
+		return ret;
+	}
+	return 0;
+}
diff --git a/drivers/net/sxe2/sxe2_mp.h b/drivers/net/sxe2/sxe2_mp.h
new file mode 100644
index 0000000000..0e97655718
--- /dev/null
+++ b/drivers/net/sxe2/sxe2_mp.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
+ */
+
+#ifndef SXE2_MP_H
+#define SXE2_MP_H
+
+#include <rte_eal.h>
+#include <rte_ethdev.h>
+#include <rte_memzone.h>
+#include <rte_stdatomic.h>
+
+#define SXE2_MP_NAME		"sxe2_mp_msg"
+#define SXE2_MP_MZ_NAME		"sxe2_stats_mz"
+
+#define SXE2_MP_MSG_TIMEOUT 30
+
+#define SXE2_MP_MAX_XSTATS	128
+
+#define SXE2_MP_MAX_SPIN	100000
+
+enum sxe2_mp_req_type {
+	SXE2_MP_REQ_GET_STATS = 1,
+	SXE2_MP_REQ_GET_XSTATS,
+	SXE2_MP_REQ_RESET_STATS,
+};
+
+struct sxe2_mp_param {
+	enum sxe2_mp_req_type type;
+	uint32_t port_id;
+	int result;
+};
+
+union sxe2_mp_shared_payload {
+	struct {
+		struct rte_eth_stats stats;
+		struct eth_queue_stats qstats;
+	} stats_blk;
+	struct {
+		struct rte_eth_xstat xstats[SXE2_MP_MAX_XSTATS];
+		uint32_t xstats_num;
+	} xstats_blk;
+};
+
+struct sxe2_mp_shared_data {
+	RTE_ATOMIC(uint16_t)in_use;
+	union sxe2_mp_shared_payload payload;
+};
+
+static inline void sxe2_unlock_auto(rte_spinlock_t **lock)
+{
+	if (lock && *lock)
+		rte_spinlock_unlock(*lock);
+}
+
+int sxe2_mp_init(struct rte_eth_dev *dev);
+
+void sxe2_mp_uninit(struct rte_eth_dev *dev);
+
+int sxe2_mp_request_simple(struct rte_eth_dev *dev,
+			   enum sxe2_mp_req_type type,
+			   int *result_out);
+
+int sxe2_mp_req_get_stats(struct rte_eth_dev *dev,
+			  struct rte_eth_stats *stats,
+			  struct eth_queue_stats *qstats);
+
+int sxe2_mp_req_get_xstats(struct rte_eth_dev *dev,
+			   struct rte_eth_xstat *xstats, uint32_t usr_cnt);
+
+int sxe2_mp_req_reset_stats(struct rte_eth_dev *dev);
+
+#endif
diff --git a/drivers/net/sxe2/sxe2_stats.c b/drivers/net/sxe2/sxe2_stats.c
new file mode 100644
index 0000000000..7ea2815fa3
--- /dev/null
+++ b/drivers/net/sxe2/sxe2_stats.c
@@ -0,0 +1,586 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
+ */
+
+#include <rte_eal.h>
+
+#include "sxe2_ethdev.h"
+#include "sxe2_vsi.h"
+#include "sxe2_common_log.h"
+#include "sxe2_stats.h"
+#include "sxe2_queue.h"
+#include "sxe2_cmd_chnl.h"
+#include "sxe2_mp.h"
+
+#define SXE2_XSTAT_CNT_PF RTE_DIM(sxe2_xstats_field_pf)
+#define SXE2_XSTAT_CNT_VF RTE_DIM(sxe2_xstats_field_vf)
+
+static struct sxe2_stats_field sxe2_xstats_field_pf[] = {
+	{"rx_qblock_drop", offsetof(struct sxe2_stats, rx_qblock_drop)},
+	{"rx_out_of_buffer", offsetof(struct sxe2_stats, rx_out_of_buffer)},
+	{"tx_packets_phy", offsetof(struct sxe2_stats, tx_frame_good)},
+	{"rx_packets_phy", offsetof(struct sxe2_stats, rx_frame_good)},
+	{"rx_crc_errors_phy", offsetof(struct sxe2_stats, rx_crc_errors)},
+	{"tx_bytes_phy", offsetof(struct sxe2_stats, tx_bytes_good)},
+	{"rx_bytes_phy", offsetof(struct sxe2_stats, rx_bytes_good)},
+	{"tx_multicast_phy", offsetof(struct sxe2_stats, tx_multicast_good)},
+	{"tx_broadcast_phy", offsetof(struct sxe2_stats, tx_broadcast_good)},
+	{"rx_multicast_phy", offsetof(struct sxe2_stats, rx_multicast_good)},
+	{"rx_broadcast_phy", offsetof(struct sxe2_stats, rx_broadcast_good)},
+	{"rx_in_range_len_errs_phy", offsetof(struct sxe2_stats, rx_len_errors)},
+	{"rx_out_of_range_len_phy", offsetof(struct sxe2_stats, rx_out_of_range_errors)},
+	{"rx_oversize_pkts_phy", offsetof(struct sxe2_stats, rx_oversize_pkts_phy)},
+	{"rx_symbol_err_phy", offsetof(struct sxe2_stats, rx_symbol_err)},
+	{"rx_pause_ctrl_phy", offsetof(struct sxe2_stats, rx_pause_frame)},
+	{"tx_pause_ctrl_phy", offsetof(struct sxe2_stats, tx_pause_frame)},
+	{"rx_discards_phy", offsetof(struct sxe2_stats, rx_discards_phy)},
+	{"rx_discards_ips_phy", offsetof(struct sxe2_stats, rx_discards_ips_phy)},
+	{"tx_dropped_link_down_phy", offsetof(struct sxe2_stats, tx_dropped_link_down)},
+	{"rx_undersize_pkts_phy", offsetof(struct sxe2_stats, rx_undersize_good)},
+	{"rx_fragments_phy", offsetof(struct sxe2_stats, rx_runt_error)},
+	{"tx_bytes_all_phy", offsetof(struct sxe2_stats, tx_bytes_good_bad)},
+	{"tx_packets_all_phy", offsetof(struct sxe2_stats, tx_frame_good_bad)},
+	{"rx_jabbers_phy", offsetof(struct sxe2_stats, rx_jabbers)},
+	{"rx_64_bytes_phy", offsetof(struct sxe2_stats, rx_size_64)},
+	{"rx_65_to_127_bytes_phy", offsetof(struct sxe2_stats, rx_size_65_127)},
+	{"rx_128_to_255_bytes_phy", offsetof(struct sxe2_stats, rx_size_128_255)},
+	{"rx_256_to_511_bytes_phy", offsetof(struct sxe2_stats, rx_size_256_511)},
+	{"rx_512_to_1023_bytes_phy", offsetof(struct sxe2_stats, rx_size_512_1023)},
+	{"rx_1024_to_1522_bytes_phy", offsetof(struct sxe2_stats, rx_size_1024_1522)},
+	{"rx_1523_to_max_bytes_phy", offsetof(struct sxe2_stats, rx_size_1523_max)},
+	{"rx_pcs_symbol_err_phy", offsetof(struct sxe2_stats, rx_pcs_symbol_err_phy)},
+	{"rx_corrected_bits_phy", offsetof(struct sxe2_stats, rx_corrected_bits_phy)},
+	{"rx_err_lane_0_phy", offsetof(struct sxe2_stats, rx_err_lane_0_phy)},
+	{"rx_err_lane_1_phy", offsetof(struct sxe2_stats, rx_err_lane_1_phy)},
+	{"rx_err_lane_2_phy", offsetof(struct sxe2_stats, rx_err_lane_2_phy)},
+	{"rx_err_lane_3_phy", offsetof(struct sxe2_stats, rx_err_lane_3_phy)},
+	{"rx_illegal_bytes_phy", offsetof(struct sxe2_stats, rx_illegal_bytes)},
+	{"rx_oversize_good_phy", offsetof(struct sxe2_stats, rx_oversize_good)},
+	{"tx_unicast_all_phy", offsetof(struct sxe2_stats, tx_unicast)},
+	{"tx_broadcast_all_phy", offsetof(struct sxe2_stats, tx_broadcast)},
+	{"tx_multicast_all_phy", offsetof(struct sxe2_stats, tx_multicast)},
+	{"tx_vlan_packets_good_phy", offsetof(struct sxe2_stats, tx_vlan_packet_good)},
+	{"tx_64_bytes_phy", offsetof(struct sxe2_stats, tx_size_64)},
+	{"tx_65_to_127_bytes_phy", offsetof(struct sxe2_stats, tx_size_65_127)},
+	{"tx_128_to_255_bytes_phy", offsetof(struct sxe2_stats, tx_size_128_255)},
+	{"tx_256_to_511_bytes_phy", offsetof(struct sxe2_stats, tx_size_256_511)},
+	{"tx_512_to_1023_bytes_phy", offsetof(struct sxe2_stats, tx_size_512_1023)},
+	{"tx_1024_to_1522_bytes_phy", offsetof(struct sxe2_stats, tx_size_1024_1522)},
+	{"tx_1523_to_max_bytes_phy", offsetof(struct sxe2_stats, tx_size_1523_max)},
+	{"tx_underflow_error_phy", offsetof(struct sxe2_stats, tx_underflow_error)},
+	{"rx_bytes_all_phy", offsetof(struct sxe2_stats, rx_byte_good_bad)},
+	{"rx_packets_all_phy", offsetof(struct sxe2_stats, rx_frame_good_bad)},
+	{"rx_unicast_phy", offsetof(struct sxe2_stats, rx_unicast_good)},
+	{"rx_vlan_packets_phy", offsetof(struct sxe2_stats, rx_vlan_packets)},
+
+	{"rx_vport_bytes",             offsetof(struct sxe2_stats, rx_vsi_bytes)},
+	{"rx_vport_unicast_packets",   offsetof(struct sxe2_stats, rx_vsi_unicast_packets)},
+	{"rx_vport_broadcast_packets", offsetof(struct sxe2_stats, rx_vsi_broadcast_packets)},
+	{"rx_vport_multicast_packets", offsetof(struct sxe2_stats, rx_vsi_multicast_packets)},
+	{"rx_sw_unicast_packets",      offsetof(struct sxe2_stats, rx_sw_unicast_packets)},
+	{"rx_sw_broadcast_packets",    offsetof(struct sxe2_stats, rx_sw_broadcast_packets)},
+	{"rx_sw_multicast_packets",    offsetof(struct sxe2_stats, rx_sw_multicast_packets)},
+	{"rx_sw_drop_packets",         offsetof(struct sxe2_stats, rx_sw_drop_packets)},
+	{"rx_sw_drop_bytes",           offsetof(struct sxe2_stats, rx_sw_drop_bytes)},
+
+	{"tx_vport_bytes",             offsetof(struct sxe2_stats, tx_vsi_bytes)},
+	{"tx_vport_unicast_packets",   offsetof(struct sxe2_stats, tx_vsi_unicast_packets)},
+	{"tx_vport_broadcast_packets", offsetof(struct sxe2_stats, tx_vsi_broadcast_packets)},
+	{"tx_vport_multicast_packets", offsetof(struct sxe2_stats, tx_vsi_multicast_packets)},
+};
+
+static struct sxe2_stats_field sxe2_xstats_field_vf[] = {
+	{"rx_vport_bytes",             offsetof(struct sxe2_stats, rx_vsi_bytes)},
+	{"rx_vport_unicast_packets",   offsetof(struct sxe2_stats, rx_vsi_unicast_packets)},
+	{"rx_vport_broadcast_packets", offsetof(struct sxe2_stats, rx_vsi_broadcast_packets)},
+	{"rx_vport_multicast_packets", offsetof(struct sxe2_stats, rx_vsi_multicast_packets)},
+	{"rx_sw_unicast_packets",      offsetof(struct sxe2_stats, rx_sw_unicast_packets)},
+	{"rx_sw_broadcast_packets",    offsetof(struct sxe2_stats, rx_sw_broadcast_packets)},
+	{"rx_sw_multicast_packets",    offsetof(struct sxe2_stats, rx_sw_multicast_packets)},
+	{"rx_sw_drop_packets",         offsetof(struct sxe2_stats, rx_sw_drop_packets)},
+	{"rx_sw_drop_bytes",           offsetof(struct sxe2_stats, rx_sw_drop_bytes)},
+
+	{"tx_vport_bytes",             offsetof(struct sxe2_stats, tx_vsi_bytes)},
+	{"tx_vport_unicast_packets",   offsetof(struct sxe2_stats, tx_vsi_unicast_packets)},
+	{"tx_vport_broadcast_packets", offsetof(struct sxe2_stats, tx_vsi_broadcast_packets)},
+	{"tx_vport_multicast_packets", offsetof(struct sxe2_stats, tx_vsi_multicast_packets)},
+};
+
+static int32_t sxe2_xstat_pf_offset_get(uint32_t id, uint32_t *offset)
+{
+	int32_t ret  = 0;
+	uint32_t size = SXE2_XSTAT_CNT_PF;
+
+	if (id < size) {
+		*offset = sxe2_xstats_field_pf[id].offset;
+	} else {
+		ret = -EINVAL;
+		PMD_LOG_ERR(DRV, "invalid id:%u exceed stats size cnt:%u", id, size);
+	}
+	return ret;
+}
+
+static int32_t sxe2_xstat_vf_offset_get(uint32_t id, uint32_t *offset)
+{
+	int32_t ret  = 0;
+	uint32_t size = SXE2_XSTAT_CNT_VF;
+
+	if (id < size) {
+		*offset = sxe2_xstats_field_vf[id].offset;
+	} else {
+		ret = -EINVAL;
+		PMD_LOG_ERR(DRV, "invalid id:%u exceed stats size cnt:%u", id, size);
+	}
+	return ret;
+}
+
+static int32_t sxe2_mac_hw_stats_get_update(struct sxe2_adapter *adapter)
+{
+	int32_t ret = 0;
+
+	ret = sxe2_drv_get_mac_stats(adapter);
+	if (ret) {
+		PMD_LOG_ERR(DRV, "get mac stats failed, ret:%d.", ret);
+		goto l_end;
+	}
+
+l_end:
+	return ret;
+}
+
+static int32_t sxe2_vsi_hw_stats_get_update(struct sxe2_adapter *adapter)
+{
+	int32_t ret = 0;
+
+	ret = sxe2_drv_get_vsi_stats(adapter);
+	if (ret) {
+		PMD_LOG_ERR(DRV, "get vsi stats failed, ret:%d.", ret);
+		goto l_end;
+	}
+
+l_end:
+	return ret;
+}
+
+static int32_t sxe2_vsi_sw_stats_get_update(struct sxe2_adapter *adapter)
+{
+	int32_t ret  = 0;
+	struct sxe2_vsi          *vsi      = adapter->vsi_ctxt.main_vsi;
+	struct sxe2_stats        *sw_stats = &vsi->vsi_stats.vsi_sw_stats;
+	struct sxe2_rx_queue     *rxq;
+	uint32_t rx_queue_id;
+	memset(sw_stats, 0, sizeof(struct sxe2_stats));
+
+	for (rx_queue_id = 0; rx_queue_id < adapter->dev_info.dev_data->nb_rx_queues;
+		     rx_queue_id++) {
+		rxq = adapter->dev_info.dev_data->rx_queues[rx_queue_id];
+		if (rxq) {
+			sw_stats->ipackets += rxq->sw_stats.pkts;
+			sw_stats->ierrors += rxq->sw_stats.drop_pkts;
+			sw_stats->ibytes += rxq->sw_stats.bytes;
+
+			sw_stats->rx_sw_unicast_packets += rxq->sw_stats.unicast_pkts;
+			sw_stats->rx_sw_broadcast_packets += rxq->sw_stats.broadcast_pkts;
+			sw_stats->rx_sw_multicast_packets += rxq->sw_stats.multicast_pkts;
+			sw_stats->rx_sw_drop_packets += rxq->sw_stats.drop_pkts;
+			sw_stats->rx_sw_drop_bytes += rxq->sw_stats.drop_bytes;
+		}
+	}
+
+	return ret;
+}
+
+static void sxe2_stats_update(struct sxe2_adapter *adapter)
+{
+	struct sxe2_vsi          *vsi      = adapter->vsi_ctxt.main_vsi;
+	struct sxe2_stats        *stats = &vsi->vsi_stats.stats;
+	struct sxe2_stats        *hw_stats = &vsi->vsi_stats.vsi_hw_stats;
+	struct sxe2_stats        *sw_stats = &vsi->vsi_stats.vsi_sw_stats;
+	struct sxe2_stats        *sw_stats_prev = &vsi->vsi_stats.vsi_sw_stats_prev;
+	uint8_t i = 0;
+
+	memset(stats, 0, sizeof(struct sxe2_stats));
+
+	stats->opackets = hw_stats->opackets;
+	stats->obytes   = hw_stats->tx_vsi_bytes;
+	stats->tx_vsi_bytes             = hw_stats->tx_vsi_bytes;
+	stats->tx_vsi_unicast_packets   = hw_stats->tx_vsi_unicast_packets;
+	stats->tx_vsi_broadcast_packets = hw_stats->tx_vsi_broadcast_packets;
+	stats->tx_vsi_multicast_packets = hw_stats->tx_vsi_multicast_packets;
+
+	stats->ierrors = sw_stats->ierrors + sw_stats_prev->ierrors;
+	if (adapter->devargs.sw_stats_en) {
+		stats->ipackets = sw_stats->ipackets + sw_stats_prev->ipackets;
+		stats->ibytes = sw_stats->ibytes + sw_stats_prev->ibytes;
+	} else {
+		stats->ipackets = hw_stats->ipackets;
+		stats->ibytes   = hw_stats->rx_vsi_bytes;
+	}
+	stats->rx_vsi_bytes             = hw_stats->rx_vsi_bytes;
+	stats->rx_vsi_unicast_packets   = hw_stats->rx_vsi_unicast_packets;
+	stats->rx_vsi_broadcast_packets = hw_stats->rx_vsi_broadcast_packets;
+	stats->rx_vsi_multicast_packets = hw_stats->rx_vsi_multicast_packets;
+	stats->rx_sw_unicast_packets = sw_stats->rx_sw_unicast_packets +
+			sw_stats_prev->rx_sw_unicast_packets;
+	stats->rx_sw_broadcast_packets = sw_stats->rx_sw_broadcast_packets +
+			sw_stats_prev->rx_sw_broadcast_packets;
+	stats->rx_sw_multicast_packets = sw_stats->rx_sw_multicast_packets +
+			sw_stats_prev->rx_sw_multicast_packets;
+	stats->rx_sw_drop_packets = sw_stats->rx_sw_drop_packets +
+			sw_stats_prev->rx_sw_drop_packets;
+	stats->rx_sw_drop_bytes = sw_stats->rx_sw_drop_bytes +
+			sw_stats_prev->rx_sw_drop_bytes;
+
+	if (adapter->dev_type != SXE2_DEV_T_VF) {
+		stats->rx_out_of_buffer = hw_stats->rx_out_of_buffer;
+		stats->rx_qblock_drop = hw_stats->rx_qblock_drop;
+		stats->tx_frame_good = hw_stats->tx_frame_good;
+		stats->rx_frame_good = hw_stats->rx_frame_good;
+		stats->rx_crc_errors = hw_stats->rx_crc_errors;
+		stats->tx_bytes_good = hw_stats->tx_bytes_good;
+		stats->rx_bytes_good = hw_stats->rx_bytes_good;
+		stats->tx_multicast_good = hw_stats->tx_multicast_good;
+		stats->tx_broadcast_good = hw_stats->tx_broadcast_good;
+		stats->rx_multicast_good = hw_stats->rx_multicast_good;
+		stats->rx_broadcast_good = hw_stats->rx_broadcast_good;
+		stats->rx_len_errors = hw_stats->rx_len_errors;
+		stats->rx_out_of_range_errors = hw_stats->rx_out_of_range_errors;
+		stats->rx_oversize_pkts_phy = hw_stats->rx_oversize_pkts_phy;
+		stats->rx_symbol_err = hw_stats->rx_symbol_err;
+		stats->rx_pause_frame = hw_stats->rx_pause_frame;
+		stats->tx_pause_frame = hw_stats->tx_pause_frame;
+		stats->rx_discards_phy = hw_stats->rx_discards_phy;
+		stats->rx_discards_ips_phy = hw_stats->rx_discards_ips_phy;
+		stats->tx_dropped_link_down = hw_stats->tx_dropped_link_down;
+		stats->rx_undersize_good = hw_stats->rx_undersize_good;
+		stats->rx_runt_error = hw_stats->rx_runt_error;
+		stats->tx_bytes_good_bad = hw_stats->tx_bytes_good_bad;
+		stats->tx_frame_good_bad = hw_stats->tx_frame_good_bad;
+		stats->rx_jabbers = hw_stats->rx_jabbers;
+		stats->rx_size_64 = hw_stats->rx_size_64;
+		stats->rx_size_65_127 = hw_stats->rx_size_65_127;
+		stats->rx_size_128_255 = hw_stats->rx_size_128_255;
+		stats->rx_size_256_511 = hw_stats->rx_size_256_511;
+		stats->rx_size_512_1023 = hw_stats->rx_size_512_1023;
+		stats->rx_size_1024_1522 = hw_stats->rx_size_1024_1522;
+		stats->rx_size_1523_max = hw_stats->rx_size_1523_max;
+		stats->rx_pcs_symbol_err_phy = hw_stats->rx_pcs_symbol_err_phy;
+		stats->rx_corrected_bits_phy = hw_stats->rx_corrected_bits_phy;
+		stats->rx_err_lane_0_phy = hw_stats->rx_err_lane_0_phy;
+		stats->rx_err_lane_1_phy = hw_stats->rx_err_lane_1_phy;
+		stats->rx_err_lane_2_phy = hw_stats->rx_err_lane_2_phy;
+		stats->rx_err_lane_3_phy = hw_stats->rx_err_lane_3_phy;
+		stats->rx_illegal_bytes = hw_stats->rx_illegal_bytes;
+		stats->rx_oversize_good = hw_stats->rx_oversize_good;
+		stats->tx_unicast = hw_stats->tx_unicast;
+		stats->tx_broadcast = hw_stats->tx_broadcast;
+		stats->tx_multicast = hw_stats->tx_multicast;
+		stats->tx_vlan_packet_good = hw_stats->tx_vlan_packet_good;
+		stats->tx_size_64 = hw_stats->tx_size_64;
+		stats->tx_size_65_127 = hw_stats->tx_size_65_127;
+		stats->tx_size_128_255 = hw_stats->tx_size_128_255;
+		stats->tx_size_256_511 = hw_stats->tx_size_256_511;
+		stats->tx_size_512_1023 = hw_stats->tx_size_512_1023;
+		stats->tx_size_1024_1522 = hw_stats->tx_size_1024_1522;
+		stats->tx_size_1523_max = hw_stats->tx_size_1523_max;
+		stats->tx_underflow_error = hw_stats->tx_underflow_error;
+		stats->rx_byte_good_bad = hw_stats->rx_byte_good_bad;
+		stats->rx_frame_good_bad = hw_stats->rx_frame_good_bad;
+		stats->rx_unicast_good = hw_stats->rx_unicast_good;
+		stats->rx_vlan_packets = hw_stats->rx_vlan_packets;
+		rte_memcpy(stats->rx_prio_buf_discard, hw_stats->rx_prio_buf_discard,
+				sizeof(hw_stats->rx_prio_buf_discard));
+		rte_memcpy(stats->prio_xoff_rx, hw_stats->prio_xoff_rx,
+				sizeof(hw_stats->prio_xoff_rx));
+		rte_memcpy(stats->prio_xon_rx, hw_stats->prio_xon_rx,
+				sizeof(hw_stats->prio_xon_rx));
+		rte_memcpy(stats->prio_xon_tx, hw_stats->prio_xon_tx,
+				sizeof(hw_stats->prio_xon_tx));
+		rte_memcpy(stats->prio_xoff_tx, hw_stats->prio_xoff_tx,
+				sizeof(hw_stats->prio_xoff_tx));
+		rte_memcpy(stats->prio_xon_2_xoff, hw_stats->prio_xon_2_xoff,
+				sizeof(hw_stats->prio_xon_2_xoff));
+
+		stats->imissed = hw_stats->rx_out_of_buffer +
+				hw_stats->rx_qblock_drop;
+		for (i = 0; i < SXE2_MAX_USER_PRIORITY; i++)
+			stats->imissed += hw_stats->rx_prio_buf_discard[i];
+	}
+}
+
+int32_t sxe2_stats_info_get(struct rte_eth_dev *dev,
+			struct rte_eth_stats *stats,
+			struct eth_queue_stats *qstats)
+{
+	int32_t ret = 0;
+	struct sxe2_adapter *adapter  = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_vsi     *vsi      = adapter->vsi_ctxt.main_vsi;
+	struct sxe2_stats   *stats_out = &vsi->vsi_stats.stats;
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		return sxe2_mp_req_get_stats(dev, stats, qstats);
+
+	ret = sxe2_vsi_hw_stats_get_update(adapter);
+	if (ret)
+		goto end;
+
+	ret = sxe2_vsi_sw_stats_get_update(adapter);
+	if (ret)
+		goto end;
+
+	ret = sxe2_drv_queue_info_get_update(adapter, qstats);
+	if (ret)
+		goto end;
+
+	sxe2_stats_update(adapter);
+
+	stats->ipackets = stats_out->ipackets;
+	stats->ibytes   = stats_out->ibytes;
+	stats->ierrors  = stats_out->ierrors;
+	stats->imissed  = stats_out->imissed;
+	stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
+
+	stats->opackets = stats_out->opackets;
+	stats->obytes   = stats_out->obytes;
+
+	ret = 0;
+
+end:
+	return ret;
+}
+
+int32_t sxe2_xstats_info_get(struct rte_eth_dev *dev,
+		struct rte_eth_xstat *xstats, uint32_t usr_cnt)
+{
+	uint32_t i      = 0;
+	uint32_t cnt    = 0;
+	int32_t ret    = 0;
+	uint32_t offset = 0;
+	uint32_t xstats_cnt = 0;
+	struct sxe2_adapter    *adapter   = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_vsi        *vsi       = adapter->vsi_ctxt.main_vsi;
+	struct sxe2_vsi_stats  *xstats_out = &vsi->vsi_stats;
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		return sxe2_mp_req_get_xstats(dev, xstats, usr_cnt);
+
+	if (adapter->dev_type == SXE2_DEV_T_VF)
+		xstats_cnt = SXE2_XSTAT_CNT_VF;
+	else
+		xstats_cnt = SXE2_XSTAT_CNT_PF;
+
+	if (usr_cnt < xstats_cnt) {
+		ret = xstats_cnt;
+		PMD_LOG_ERR(DRV, "user usr_cnt:%u less than stats cnt:%u", usr_cnt, ret);
+		goto end;
+	}
+
+	ret = sxe2_vsi_hw_stats_get_update(adapter);
+	if (ret) {
+		ret = xstats_cnt;
+		goto end;
+	}
+
+	ret = sxe2_vsi_sw_stats_get_update(adapter);
+	if (ret) {
+		ret = xstats_cnt;
+		goto end;
+	}
+
+	if (adapter->dev_type == SXE2_DEV_T_VF) {
+		sxe2_stats_update(adapter);
+		for (i = 0; i < xstats_cnt; i++) {
+			(void)sxe2_xstat_vf_offset_get(i, &offset);
+			xstats[cnt].value = *(uint64_t *)(((int8_t *)(&xstats_out->stats)) +
+							  offset);
+			xstats[cnt].id    = cnt;
+			cnt++;
+		}
+	} else {
+		ret = sxe2_mac_hw_stats_get_update(adapter);
+		if (ret) {
+			ret = xstats_cnt;
+			goto end;
+		}
+
+		sxe2_stats_update(adapter);
+
+		for (i = 0; i < xstats_cnt; i++) {
+			(void)sxe2_xstat_pf_offset_get(i, &offset);
+			xstats[cnt].value = *(uint64_t *)(((int8_t *)(&xstats_out->stats)) +
+							  offset);
+			xstats[cnt].id = cnt;
+			cnt++;
+		}
+	}
+	ret = cnt;
+	PMD_LOG_DEBUG(DRV, "usr_cnt:%u stats cnt:%u stats done", usr_cnt, cnt);
+
+end:
+	return ret;
+}
+
+int32_t sxe2_xstats_names_get(__rte_unused struct rte_eth_dev *dev,
+	struct rte_eth_xstat_name *xstats_names,
+	__rte_unused unsigned int usr_cnt)
+{
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_stats_field *field = NULL;
+	uint32_t i   = 0;
+	uint32_t cnt = 0;
+	int32_t ret = -1;
+	uint32_t xstats_cnt = 0;
+
+	if (adapter->dev_type == SXE2_DEV_T_VF) {
+		field = sxe2_xstats_field_vf;
+		xstats_cnt = SXE2_XSTAT_CNT_VF;
+	} else {
+		field = sxe2_xstats_field_pf;
+		xstats_cnt = SXE2_XSTAT_CNT_PF;
+	}
+
+	if (!xstats_names) {
+		ret = xstats_cnt;
+		PMD_LOG_DEBUG(DRV, "xstats field size:%u", ret);
+		goto l_out;
+	}
+
+	if (usr_cnt < xstats_cnt) {
+		ret = -EINVAL;
+		PMD_LOG_ERR(DRV, "max:%d usr_cnt:%u invalid (err:%d)", xstats_cnt, usr_cnt, ret);
+		goto l_out;
+	}
+
+	for (i = 0; i < xstats_cnt; i++) {
+		(void)strlcpy(xstats_names[cnt].name, field[i].name,
+			      sizeof(xstats_names[cnt].name));
+		cnt++;
+	}
+
+	ret = cnt;
+
+l_out:
+	return ret;
+}
+
+int32_t sxe2_stats_hw_reset(struct rte_eth_dev *dev)
+{
+	int32_t ret = 0;
+	struct sxe2_adapter    *adapter   = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_vsi        *vsi       = adapter->vsi_ctxt.main_vsi;
+	struct sxe2_rx_queue   *rxq;
+	uint32_t rx_queue_id;
+
+	ret = sxe2_drv_vsi_stats_reset(adapter);
+	if (ret) {
+		PMD_LOG_ERR(DRV, "reset vsi stats failed, ret:%d.", ret);
+		goto l_end;
+	}
+	if (adapter->dev_type != SXE2_DEV_T_VF) {
+		ret = sxe2_drv_mac_stats_reset(adapter);
+		if (ret) {
+			PMD_LOG_ERR(DRV, "reset mac stats failed, ret:%d.", ret);
+			goto l_end;
+		}
+	}
+
+	memset(&vsi->vsi_stats, 0, sizeof(vsi->vsi_stats));
+	for (rx_queue_id = 0; rx_queue_id < dev->data->nb_rx_queues; rx_queue_id++) {
+		rxq = dev->data->rx_queues[rx_queue_id];
+		if (rxq)
+			memset(&rxq->sw_stats, 0, sizeof(rxq->sw_stats));
+	}
+
+l_end:
+	return ret;
+}
+
+int32_t sxe2_stats_info_reset(struct rte_eth_dev *dev)
+{
+	int32_t ret;
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		return sxe2_mp_req_reset_stats(dev);
+
+	if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_Q_MAP) {
+		ret = sxe2_drv_mapping_stats_info_clear(dev);
+		if (ret)
+			goto l_end;
+	}
+
+	ret = sxe2_stats_hw_reset(dev);
+	if (ret)
+		goto l_end;
+
+l_end:
+	return ret;
+}
+
+int32_t sxe2_stats_init(struct rte_eth_dev *dev)
+{
+	PMD_INIT_FUNC_TRACE();
+	int32_t ret;
+
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	ret = sxe2_queue_stats_map_init(dev);
+	if (ret)
+		goto l_end;
+
+	ret = sxe2_stats_hw_reset(dev);
+	if (ret)
+		goto l_end;
+
+l_end:
+	return ret;
+}
+
+int32_t sxe2_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
+				  uint16_t queue_id, uint8_t pool_idx, uint8_t is_rx)
+{
+	int32_t ret = -1;
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(eth_dev);
+
+	if (!(adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_Q_MAP)) {
+		PMD_LOG_ERR(DRV, "VF does not support queue mapping! ");
+		goto l_end;
+	}
+
+	if (is_rx)
+		ret = sxe2_drv_rxq_mapping_set(eth_dev, queue_id, pool_idx);
+	else
+		ret = sxe2_drv_txq_mapping_set(eth_dev, queue_id, pool_idx);
+
+	if (ret) {
+		PMD_LOG_ERR(DRV, "Queue stats mapping failed ! "
+			"queue_id:%u pool_idx:%u", queue_id, pool_idx);
+		goto l_end;
+	}
+
+	PMD_LOG_DEBUG(DRV, "port %u %s queue_id %d stat map to pool[%u] ",
+		     (uint16_t)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
+		     queue_id, pool_idx);
+l_end:
+	return ret;
+}
+
+int32_t sxe2_queue_stats_map_init(struct rte_eth_dev *dev)
+{
+	int32_t ret = 0;
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+
+	if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_Q_MAP) {
+		dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
+
+		ret = sxe2_drv_mapping_reset(dev);
+		if (ret) {
+			PMD_LOG_ERR(DRV, "Queue stats mapping init failed !");
+			goto l_end;
+		}
+	}
+
+l_end:
+	return ret;
+}
diff --git a/drivers/net/sxe2/sxe2_stats.h b/drivers/net/sxe2/sxe2_stats.h
new file mode 100644
index 0000000000..64ac2bb11d
--- /dev/null
+++ b/drivers/net/sxe2/sxe2_stats.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
+ */
+
+#ifndef __SXE2_STATS_H__
+#define __SXE2_STATS_H__
+
+#define SXE2_STATS_FIELD_NAME_SIZE  50
+
+struct sxe2_stats_field {
+	char name[SXE2_STATS_FIELD_NAME_SIZE];
+	uint32_t offset;
+};
+
+struct sxe2_adapter;
+
+int32_t sxe2_stats_info_get(struct rte_eth_dev *dev,
+			struct rte_eth_stats *stats,
+			struct eth_queue_stats *qstats);
+
+int32_t sxe2_xstats_info_get(struct rte_eth_dev *dev,
+	struct rte_eth_xstat *xstats, uint32_t usr_cnt);
+
+int32_t sxe2_xstats_names_get(__rte_unused struct rte_eth_dev *dev,
+			  struct rte_eth_xstat_name *xstats_names,
+			  __rte_unused unsigned int usr_cnt);
+
+int32_t sxe2_stats_hw_reset(struct rte_eth_dev *dev);
+
+int32_t sxe2_stats_info_reset(struct rte_eth_dev *dev);
+
+int32_t sxe2_stats_init(struct rte_eth_dev *dev);
+
+int32_t sxe2_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
+				  uint16_t queue_id, uint8_t pool_idx, uint8_t is_rx);
+
+int32_t sxe2_queue_stats_map_init(struct rte_eth_dev *dev);
+
+#endif
-- 
2.47.3


^ permalink raw reply related

* [PATCH v1 03/23] drivers: add supported packet types get callback
From: liujie5 @ 2026-05-24  9:32 UTC (permalink / raw)
  To: stephen; +Cc: dev, Jie Liu
In-Reply-To: <20260524093259.397506-1-liujie5@linkdatatechnology.com>

From: Jie Liu <liujie5@linkdatatechnology.com>

Implement dev_supported_ptypes_get ethdev callback for sxe2 PMD.
This allows applications to query the packet types the driver
is capable of identifying, such as L2, L3 (IPv4/IPv6), and
L4 (TCP/UDP/SCTP) layers.

Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
 drivers/common/sxe2/sxe2_ptype.h | 1793 ++++++++++++++++++++++++++++++
 drivers/net/sxe2/meson.build     |    1 +
 drivers/net/sxe2/sxe2_cmd_chnl.c |   22 +
 drivers/net/sxe2/sxe2_cmd_chnl.h |    2 +
 drivers/net/sxe2/sxe2_drv_cmd.h  |    6 +
 drivers/net/sxe2/sxe2_ethdev.c   |  169 ++-
 drivers/net/sxe2/sxe2_ethdev.h   |   19 +-
 drivers/net/sxe2/sxe2_mac.c      |  103 ++
 drivers/net/sxe2/sxe2_mac.h      |   50 +
 9 files changed, 2126 insertions(+), 39 deletions(-)
 create mode 100644 drivers/common/sxe2/sxe2_ptype.h
 create mode 100644 drivers/net/sxe2/sxe2_mac.c
 create mode 100644 drivers/net/sxe2/sxe2_mac.h

diff --git a/drivers/common/sxe2/sxe2_ptype.h b/drivers/common/sxe2/sxe2_ptype.h
new file mode 100644
index 0000000000..9c19570979
--- /dev/null
+++ b/drivers/common/sxe2/sxe2_ptype.h
@@ -0,0 +1,1793 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
+ */
+
+#ifndef _SXE2_PTYPE_H_
+#define _SXE2_PTYPE_H_
+#include <rte_ethdev.h>
+
+static inline const uint32_t *
+sxe2_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
+{
+	const uint32_t *ret = NULL;
+
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L2_ETHER_TIMESYNC,
+		RTE_PTYPE_L2_ETHER_LLDP,
+		RTE_PTYPE_L2_ETHER_ARP,
+		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_L4_FRAG,
+		RTE_PTYPE_L4_ICMP,
+		RTE_PTYPE_L4_NONFRAG,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_GRENAT,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L2_ETHER,
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L4_FRAG,
+		RTE_PTYPE_INNER_L4_ICMP,
+		RTE_PTYPE_INNER_L4_NONFRAG,
+		RTE_PTYPE_INNER_L4_SCTP,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst != NULL) {
+		*no_of_elements = RTE_DIM(ptypes);
+		ret = ptypes;
+	} else {
+		ret = NULL;
+	}
+
+	return ret;
+}
+
+static inline void sxe2_init_ptype_list(uint32_t *ptype)
+{
+	/* ptype[0] reserved */
+	ptype[1] = RTE_PTYPE_L2_ETHER;
+	ptype[2] = RTE_PTYPE_L2_ETHER_TIMESYNC;
+	/* ptype[3] - ptype[5] reserved */
+	ptype[6] = RTE_PTYPE_L2_ETHER_LLDP;
+	/* ECP */
+	ptype[7] = RTE_PTYPE_UNKNOWN;
+	/* ptype[8] - ptype[9] reserved */
+	/* EAPol */
+	ptype[10] = RTE_PTYPE_UNKNOWN;
+	ptype[11] = RTE_PTYPE_L2_ETHER_ARP;
+	/* ptype[12] - ptype[21] reserved */
+
+	/* Non tunneled IPv4 */
+	ptype[22] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_L4_FRAG;
+	ptype[23] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_L4_NONFRAG;
+	ptype[24] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_L4_UDP;
+	/* ptype[25] reserved */
+	ptype[26] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_L4_TCP;
+	ptype[27] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_L4_SCTP;
+	ptype[28] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_L4_ICMP;
+
+	/* IPv4 --> IPv4 */
+	ptype[29] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[30] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[31] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[32] reserved */
+	ptype[33] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[34] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[35] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv4 --> IPv6 */
+	ptype[36] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[37] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[38] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[39] reserved */
+	ptype[40] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[41] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[42] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv4 --> GRE/GENEVE/VXLAN */
+	ptype[43] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT;
+
+	/* IPv4 --> GRE/GENEVE/VXLAN --> IPv4 */
+	ptype[44] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[45] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[46] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[47] reserved */
+	ptype[48] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[49] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[50] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv4 --> GRE/GENEVE/VXLAN --> IPv6 */
+	ptype[51] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[52] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[53] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[54] reserved */
+	ptype[55] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[56] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[57] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv4 --> GRE/GENEVE/VXLAN --> MAC */
+	ptype[58] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER;
+
+	/* IPv4 --> GRE/GENEVE/VXLAN --> MAC --> IPv4 */
+	ptype[59] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[60] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[61] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[62] reserved */
+	ptype[63] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[64] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[65] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv4 --> GRE/GENEVE/VXLAN --> MAC --> IPv6 */
+	ptype[66] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[67] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[68] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[69] reserved */
+	ptype[70] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[71] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[72] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+	/* IPv4 --> GRE/GENEVE/VXLAN --> MAC/VLAN */
+	ptype[73] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN;
+	/* IPv4 --> GRE/GENEVE/VXLAN --> MAC/VLAN --> IPv4 */
+	ptype[74] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[75] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[76] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[77] reserved */
+	ptype[78] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_TCP;
+	ptype[79] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_SCTP;
+	ptype[80] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_ICMP;
+	/* IPv4 --> GRE/GENEVE/VXLAN --> MAC/VLAN --> IPv6 */
+	ptype[81] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_FRAG;
+	ptype[82] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[83] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[64] reserved */
+	ptype[85] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_TCP;
+	ptype[86] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_SCTP;
+	ptype[87] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_ICMP;
+	/* Non tunneled IPv6 */
+	ptype[88] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_L4_FRAG;
+	ptype[89] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_L4_NONFRAG;
+	ptype[90] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_L4_UDP;
+	/* ptype[91] reserved */
+	ptype[92] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_L4_TCP;
+	ptype[93] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_L4_SCTP;
+	ptype[94] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_L4_ICMP;
+
+	/* IPv6 --> IPv4 */
+	ptype[95] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[96] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[97] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[98] reserved */
+	ptype[99] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_IP |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[100] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_IP |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[101] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_IP |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 --> IPv6 */
+	ptype[102] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_IP |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[103] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_IP |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[104] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_IP |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[105] reserved */
+	ptype[106] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_IP |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_TCP;
+	ptype[107] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_IP |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[108] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_IP |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 --> GRE/GENEVE/VXLAN */
+	ptype[109] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT;
+
+	/* IPv6 --> GRE/GENEVE/VXLAN --> IPv4 */
+	ptype[110] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[111] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[112] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[113] reserved */
+	ptype[114] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_TCP;
+	ptype[115] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[116] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 --> GRE/GENEVE/VXLAN --> IPv6 */
+	ptype[117] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[118] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[119] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[120] reserved */
+	ptype[121] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_TCP;
+	ptype[122] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[123] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 --> GRE/GENEVE/VXLAN --> MAC */
+	ptype[124] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER;
+
+	/* IPv6 --> GRE/GENEVE/VXLAN --> MAC --> IPv4 */
+	ptype[125] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[126] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[127] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[128] reserved */
+	ptype[129] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_TCP;
+	ptype[130] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[131] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 --> GRE/GENEVE/VXLAN --> MAC --> IPv6 */
+	ptype[132] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[133] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[134] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[135] reserved */
+	ptype[136] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_TCP;
+	ptype[137] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[138] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 --> GRE/GENEVE/VXLAN --> MAC/VLAN */
+	ptype[139] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN;
+
+	/* IPv6 --> GRE/GENEVE/VXLAN --> MAC/VLAN --> IPv4 */
+	ptype[140] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[141] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[142] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[143] reserved */
+	ptype[144] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_TCP;
+	ptype[145] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_SCTP;
+	ptype[146] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 --> GRE/GENEVE/VXLAN --> MAC/VLAN --> IPv6 */
+	ptype[147] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[148] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[149] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[150] reserved */
+	ptype[151] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_TCP;
+	ptype[152] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_SCTP;
+	ptype[153] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_ICMP;
+	/* ptype[154] - ptype[159] reserved */
+	/* IPSec */
+	ptype[160] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_ESP;
+	ptype[161] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_ESP;
+	/* AH */
+	ptype[162] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[163] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* NAT-T-ESP */
+	ptype[164] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_ESP;
+	ptype[165] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_ESP;
+	/* SDN-ESP */
+	ptype[166] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_ESP;
+	ptype[167] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_ESP;
+	/* ptype[168] - ptype[271] reserved */
+	/* IPV4 --> VRRP */
+	ptype[272] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* IPV4 --> OSPF */
+	ptype[273] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* IPV6 --> VRRP */
+	ptype[274] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* IPV6 --> VRRP */
+	ptype[275] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* ATAoE */
+	ptype[276] = RTE_PTYPE_UNKNOWN;
+	/* Control */
+	ptype[278] = RTE_PTYPE_UNKNOWN;
+	/* ptype[279] - ptype[324] reserved */
+	/* GTP */
+	ptype[325] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPC;
+	ptype[326] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPC;
+	ptype[327] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPC;
+	ptype[328] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPC;
+	ptype[329] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU;
+	ptype[330] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU;
+	ptype[331] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_FRAG;
+	ptype[332] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[333] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[334] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_TCP;
+	ptype[335] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_ICMP;
+	ptype[336] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_FRAG;
+	ptype[337] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[338] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[339] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_TCP;
+	ptype[340] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_ICMP;
+	ptype[341] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_FRAG;
+	ptype[342] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[343] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[344] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_TCP;
+	ptype[345] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_ICMP;
+	ptype[346] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_FRAG;
+	ptype[347] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[348] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[349] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_TCP;
+	ptype[350] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_GTPU |
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_ICMP;
+	/* PFCP */
+	ptype[351] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP;
+	ptype[352] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP;
+	ptype[353] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP;
+	ptype[354] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP;
+	/* ptype[355] - ptype[359] reserved */
+	/* L2TPv3 */
+	ptype[360] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_L2TP;
+	ptype[361] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_L2TP;
+	/* ptype[362] - ptype[370] reserved */
+	/* eCPRI */
+	ptype[371] = RTE_PTYPE_UNKNOWN;
+	ptype[381] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[391] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[396] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv4, IGMP */
+	ptype[397] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv4, EIGRP */
+	ptype[398] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv4, EIGRP */
+	ptype[399] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv4, PIM */
+	ptype[400] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv4, PIM */
+	ptype[401] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv6, IGMP */
+	ptype[402] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv6, IGMP */
+	ptype[403] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv6, EIGRP */
+	ptype[404] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv6, EIGRP */
+	ptype[405] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv6, PIM */
+	ptype[406] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv6, PIM */
+	ptype[407] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv4, VRRP */
+	ptype[408] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv4, VRRP */
+	ptype[409] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv6, VRRP */
+	ptype[410] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv6, VRRP */
+	ptype[411] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv4, OSPF */
+	ptype[412] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv4, OSPF */
+	ptype[413] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv6, OSPF */
+	ptype[414] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv6, OSPF */
+	ptype[415] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv4, L2_TP_V3 */
+	ptype[416] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv4, L2_TP_V3 */
+	ptype[417] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv6, L2_TP_V3 */
+	ptype[418] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv6, L2_TP_V3 */
+	ptype[419] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv4, AH */
+	ptype[420] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv4, AH */
+	ptype[421] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv6, AH */
+	ptype[422] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv6, AH */
+	ptype[423] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv4, ESP */
+	ptype[424] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv4, ESP */
+	ptype[425] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv4, UDP, TUN, MAC, IPv6, ESP */
+	ptype[426] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* MAC, IPv6, UDP, TUN, MAC, IPv6, ESP */
+	ptype[427] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	/* TP-TUN GTPU */
+	ptype[450] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[451] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[452] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[453] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[454] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[455] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[456] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[457] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[458] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[459] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[460] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[461] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[462] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[463] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[464] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[465] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[466] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[467] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[468] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[469] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[470] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[471] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[472] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[473] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[474] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[475] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[476] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[477] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[478] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[479] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[480] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[481] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[482] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[483] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[484] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[485] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[486] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[487] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[488] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[489] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[490] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[491] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[492] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[493] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[494] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[495] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[496] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	ptype[497] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_TUNNEL_IP | RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_INNER_L4_UDP;
+	/* ptype[498] - ptype[767] reserved */
+	/* L2(NETWORK CPU) */
+	/* ISIS */
+	ptype[768] = RTE_PTYPE_UNKNOWN;
+	/* SDF */
+	ptype[769] = RTE_PTYPE_UNKNOWN;
+	/* PPoE_NEGO */
+	ptype[770] = RTE_PTYPE_L2_ETHER_PPPOE;
+	/* PPoE_PROTOCOL */
+	ptype[771] = RTE_PTYPE_L2_ETHER_PPPOE;
+	ptype[772] = RTE_PTYPE_L2_ETHER_PPPOE;
+	/* LACP */
+	ptype[773] = RTE_PTYPE_UNKNOWN;
+	/* ptype[774] - ptype[775] reserved */
+	/* IPv4 L3(NETWORK CPU) */
+	ptype[776] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_IGMP;
+	/* EIGRP */
+	ptype[777] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* PIM */
+	ptype[778] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[779] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_L2TP;
+	ptype[780] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_L2TP;
+	ptype[781] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_L2TP;
+	/* ptype[782] - ptype[783] reserved */
+	/* IPv6 L3(NETWORK CPU) */
+	ptype[784] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_IGMP;
+	/* EIGRP */
+	ptype[785] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* PIM */
+	ptype[786] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[787] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_L2TP;
+	ptype[788] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_L2TP;
+	ptype[789] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP | RTE_PTYPE_TUNNEL_L2TP;
+	/* ptype[790] - ptype[791] reserved */
+	/* IPv4 L4(NETWORK CPU) */
+	ptype[792] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_TCP;
+	ptype[793] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_TCP;
+	ptype[794] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[795] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[796] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[797] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP;
+	ptype[798] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[799] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[800] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[801] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	/* ptype[802] - ptype[807] reserved */
+	/* IPv6 L4(NETWORK CPU) */
+	ptype[808] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_TCP;
+	ptype[809] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_TCP;
+	ptype[810] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[811] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[812] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+		RTE_PTYPE_L4_UDP;
+	ptype[813] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[814] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[815] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[816] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	ptype[817] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_UDP;
+	/* ptype[818] - ptype[819] reserved */
+	/* IPv6 -> MAC */
+	ptype[820] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* IPv6 -> MAC -> IPv4*/
+	ptype[821] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[822] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[823] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[824] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[825] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[826] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* IPv6 -> MAC -> IPv4*/
+	ptype[827] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[828] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[829] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[830] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[831] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[832] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* ptype[833] - ptype[834] reserved */
+	/* IPv6 -> MAC/VLAN */
+	ptype[835] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* IPv6 -> MAC/VLAN -> IPv4 */
+	ptype[836] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[837] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[838] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[839] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[840] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[841] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	/* IPv6 -> MAC/VLAN -> IPv6 */
+	ptype[842] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[843] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[844] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[845] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[846] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+	ptype[847] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_L4_NONFRAG;
+
+	/* IPv6 -> UDP -> VXLAN/GENEVE -> PAY */
+	ptype[878] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT;
+
+	/* IPv6 -> UDP -> VXLAN/GENEVE -> IPv4 */
+	ptype[877] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[876] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[879] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_UDP;
+	ptype[880] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_TCP;
+	ptype[875] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[874] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 -> UDP -> VXLAN/GENEVE -> IPv6 */
+	ptype[871] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[870] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[872] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_UDP;
+	ptype[873] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_TCP;
+	ptype[869] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[868] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv4 -> UDP -> VXLAN/GENEVE -> PAY */
+	ptype[891] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT;
+	/* IPv4 -> UDP -> VXLAN/GENEVE -> IPv4 */
+	ptype[890] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[889] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[892] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[893] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[888] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[887] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+	/* IPv4 -> UDP -> VXLAN/GENEVE -> IPv6 */
+	ptype[884] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[883] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[885] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[886] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[882] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[881] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 -> UDP -> GRE -> PAY */
+	ptype[904] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT;
+	/* IPv6 -> UDP -> GRE -> IPv4 */
+	ptype[903] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[902] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[905] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[906] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[901] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[900] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+	/* IPv6 -> UDP -> GRE -> IPv6 */
+	ptype[897] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[896] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[898] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[899] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[895] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[894] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv4 -> UDP -> GRE -> PAY */
+	ptype[917] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT;
+	/* IPv4 -> UDP -> GRE -> IPv4 */
+	ptype[916] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[915] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[918] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[919] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[914] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[913] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+	/* IPv4 -> UDP -> GRE -> IPv6 */
+	ptype[910] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[909] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[911] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[912] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[908] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[907] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 -> UDP -> VXLAN/GENEVE -> MACVLAN -> PAY */
+	ptype[930] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN;
+
+	/* IPv6 -> UDP -> VXLAN/GENEVE -> MACVLAN -> IPv4 */
+	ptype[929] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[928] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[931] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_UDP;
+	ptype[932] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_TCP;
+	ptype[927] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[926] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 -> UDP -> VXLAN/GENEVE -> MACVLAN -> IPv6 */
+	ptype[923] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[922] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[924] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_UDP;
+	ptype[925] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_TCP;
+	ptype[921] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[920] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv4 -> UDP -> VXLAN/GENEVE -> MACVLAN -> PAY */
+	ptype[943] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN;
+	/* IPv4 -> UDP -> VXLAN/GENEVE -> MACVLAN -> IPv4 */
+	ptype[942] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[941] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[944] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[945] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[940] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[939] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+	/* IPv4 -> UDP -> VXLAN/GENEVE -> MACVLAN -> IPv6 */
+	ptype[936] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[935] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[937] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[938] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[934] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[933] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 > UDP -> GRE -> MACVLAN -> PAY */
+	ptype[956] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN;
+	/* IPv6 -> UDP -> GRE -> MACVLAN -> IPv4 */
+	ptype[955] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[954] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[957] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[958] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[953] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[952] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+	/* IPv6 -> UDP -> GRE -> MACVLAN -> IPv6 */
+	ptype[949] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[948] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[950] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[951] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[947] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[946] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv4 -> UDP -> GRE -> MACVLAN -> PAY */
+	ptype[969] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN;
+	/* IPv4 -> UDP -> GRE -> MACVLAN -> IPv4 */
+	ptype[968] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[967] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[970] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[971] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[966] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[965] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+	/* IPv4 -> UDP -> GRE -> MACVLAN -> IPv6 */
+	ptype[962] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[961] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[963] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[964] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[960] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[959] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER_VLAN |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 -> UDP -> VXLAN/GENEVE -> MAC -> PAY */
+	ptype[982] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER;
+
+	/* IPv6 -> UDP -> VXLAN/GENEVE -> MAC -> IPv4 */
+	ptype[981] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[980] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[983] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_UDP;
+	ptype[984] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_TCP;
+	ptype[979] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[978] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 -> UDP -> VXLAN/GENEVE -> MAC -> IPv6 */
+	ptype[975] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_FRAG;
+	ptype[974] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[976] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_UDP;
+	ptype[977] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_TCP;
+	ptype[973] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_SCTP;
+	ptype[972] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv4 -> UDP -> VXLAN/GENEVE -> MAC -> PAY */
+	ptype[995] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER;
+	/* IPv4 -> UDP -> VXLAN/GENEVE -> MAC -> IPv4 */
+	ptype[994] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[993] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[996] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[997] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[992] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[991] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+	/* IPv4 -> UDP -> VXLAN/GENEVE -> MAC -> IPv6 */
+	ptype[988] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[987] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[989] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[990] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[986] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[985] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv6 > UDP -> GRE -> MAC -> PAY */
+	ptype[1008] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER;
+	/* IPv6 -> UDP -> GRE -> MAC -> IPv4 */
+	ptype[1007] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[1006] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[1009] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[1010] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[1005] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[1004] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+	/* IPv6 -> UDP -> GRE -> MAC -> IPv6 */
+	ptype[1001] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[1000] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[1002] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[1003] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[999] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[998] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+
+	/* IPv4 -> UDP -> GRE -> MAC -> PAY */
+	ptype[1021] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				 RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER;
+	/* IPv4 -> UDP -> GRE -> MAC -> IPv4 */
+	ptype[1020] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[1019] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[1022] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[1023] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[1018] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[1017] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+	/* IPv4 -> UDP -> GRE -> MAC -> IPv6 */
+	ptype[1014] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_FRAG;
+	ptype[1013] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_NONFRAG;
+	ptype[1015] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_UDP;
+	ptype[1016] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_TCP;
+	ptype[1012] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_SCTP;
+	ptype[1011] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+				RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
+				RTE_PTYPE_INNER_L4_ICMP;
+}
+
+#endif /* _RTE_PTYPE_TUNNEL_GRENAT_H_ */
diff --git a/drivers/net/sxe2/meson.build b/drivers/net/sxe2/meson.build
index 98dd8bcec7..e22204e850 100644
--- a/drivers/net/sxe2/meson.build
+++ b/drivers/net/sxe2/meson.build
@@ -60,6 +60,7 @@ sources += files(
         'sxe2_txrx_poll.c',
         'sxe2_txrx.c',
         'sxe2_txrx_vec.c',
+        'sxe2_mac.c',
 )
 
 allow_internal_get_api = true
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index d16b6528d0..07eeb7f38c 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -321,3 +321,25 @@ int32_t sxe2_drv_txq_switch(struct sxe2_adapter *adapter, struct sxe2_tx_queue *
 
 	return ret;
 }
+
+int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
+{
+	int32_t ret = 0;
+	struct sxe2_common_device *cdev = adapter->cdev;
+	struct sxe2_drv_cmd_params param = {0};
+	struct sxe2_drv_link_info_resp resp = {0};
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_LINK_STATUS_GET,
+				 NULL, 0,
+				 &resp, sizeof(resp));
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, DRV, "link status get failed, ret=%d", ret);
+		goto l_end;
+	}
+	adapter->link_ctxt.speed = resp.speed;
+	adapter->link_ctxt.link_up = resp.status;
+
+l_end:
+	return ret;
+}
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index cd41cd9e8d..34004d37e2 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -34,4 +34,6 @@ int32_t sxe2_drv_txq_ctxt_cfg(struct sxe2_adapter *adapter,
 			      struct sxe2_tx_queue *txq,
 			      uint16_t txq_cnt);
 
+int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter);
+
 #endif /* __SXE2_CMD_CHNL_H__ */
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index a16087c6bf..e0ec70638e 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -227,6 +227,12 @@ struct sxe2_drv_vsi_info_get_resp {
 	struct sxe2_drv_msix_caps used_msix;
 };
 
+struct sxe2_drv_link_info_resp {
+	__le32 speed;
+	uint8_t status;
+	uint8_t rsv[3];
+};
+
 enum sxe2_drv_cmd_module {
 	SXE2_DRV_CMD_MODULE_HANDSHAKE = 0,
 	SXE2_DRV_CMD_MODULE_DEV = 1,
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index e0f7002138..01552a8202 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -27,7 +27,9 @@
 #include "sxe2_tx.h"
 #include "sxe2_rx.h"
 #include "sxe2_txrx.h"
+#include "sxe2_mac.h"
 #include "sxe2_common.h"
+#include "sxe2_ptype.h"
 #include "sxe2_common_log.h"
 #include "sxe2_host_regs.h"
 #include "sxe2_ioctl_chnl_func.h"
@@ -78,6 +80,41 @@ static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_pf[SXE2_PCI_MAP_RES_
 				      .reg_width = 10},
 };
 
+static int32_t sxe2_dev_configure(struct rte_eth_dev *dev);
+static int32_t sxe2_dev_start(struct rte_eth_dev *dev);
+static int32_t sxe2_dev_stop(struct rte_eth_dev *dev);
+static int32_t sxe2_dev_close(struct rte_eth_dev *dev);
+static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info);
+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);
+
+static const struct eth_dev_ops sxe2_eth_dev_ops = {
+	.dev_configure              = sxe2_dev_configure,
+	.dev_start                  = sxe2_dev_start,
+	.dev_stop                   = sxe2_dev_stop,
+	.dev_close                  = sxe2_dev_close,
+	.dev_infos_get              = sxe2_dev_infos_get,
+	.dev_supported_ptypes_get   = sxe2_dev_supported_ptypes_get,
+	.link_update                = sxe2_link_update,
+
+	.rx_queue_start             = sxe2_rx_queue_start,
+	.rx_queue_stop              = sxe2_rx_queue_stop,
+	.tx_queue_start             = sxe2_tx_queue_start,
+	.tx_queue_stop              = sxe2_tx_queue_stop,
+	.rx_queue_setup             = sxe2_rx_queue_setup,
+	.rx_queue_release           = sxe2_rx_queue_release,
+	.tx_queue_setup             = sxe2_tx_queue_setup,
+	.tx_queue_release           = sxe2_tx_queue_release,
+	.rxq_info_get               = sxe2_rx_queue_info_get,
+	.txq_info_get               = sxe2_tx_queue_info_get,
+	.rx_burst_mode_get          = sxe2_rx_burst_mode_get,
+	.tx_burst_mode_get          = sxe2_tx_burst_mode_get,
+	.tx_done_cleanup            = sxe2_tx_done_cleanup,
+
+	.mtu_set                    = sxe2_mtu_set,
+	.buffer_split_supported_hdr_ptypes_get = sxe2_buffer_split_supported_hdr_ptypes_get,
+};
+
 static int32_t sxe2_dev_configure(struct rte_eth_dev *dev)
 {
 	int32_t ret = 0;
@@ -122,6 +159,12 @@ static int32_t sxe2_dev_start(struct rte_eth_dev *dev)
 	sxe2_rx_mode_func_set(dev);
 	sxe2_tx_mode_func_set(dev);
 
+	ret = sxe2_link_update_init(dev);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to initialize link update, ret:%d", ret);
+		goto l_end;
+	}
+
 	ret = sxe2_queues_start(dev);
 	if (ret) {
 		PMD_LOG_ERR(INIT, "enable queues failed");
@@ -136,16 +179,6 @@ static int32_t sxe2_dev_start(struct rte_eth_dev *dev)
 	return ret;
 }
 
-static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
-{
-	(void)sxe2_dev_stop(dev);
-	(void)sxe2_queues_release(dev);
-	sxe2_vsi_uninit(dev);
-	sxe2_dev_pci_map_uinit(dev);
-
-	return 0;
-}
-
 static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
 			struct rte_eth_dev_info *dev_info)
 {
@@ -270,28 +303,59 @@ static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
-static const struct eth_dev_ops sxe2_eth_dev_ops = {
-	.dev_configure              = sxe2_dev_configure,
-	.dev_start                  = sxe2_dev_start,
-	.dev_stop                   = sxe2_dev_stop,
-	.dev_close                  = sxe2_dev_close,
-	.dev_infos_get              = sxe2_dev_infos_get,
+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)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_SCTP,
+
+		RTE_PTYPE_TUNNEL_GRENAT,
+
+		RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER,
+
+		RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+			RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+			RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+
+		RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+			RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+			RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+			RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_SCTP,
+
+		RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+			RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+			RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
+			RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_SCTP,
+
+		RTE_PTYPE_UNKNOWN
+	};
 
-	.rx_queue_start             = sxe2_rx_queue_start,
-	.rx_queue_stop              = sxe2_rx_queue_stop,
-	.tx_queue_start             = sxe2_tx_queue_start,
-	.tx_queue_stop              = sxe2_tx_queue_stop,
-	.rx_queue_setup             = sxe2_rx_queue_setup,
-	.rx_queue_release           = sxe2_rx_queue_release,
-	.tx_queue_setup             = sxe2_tx_queue_setup,
-	.tx_queue_release           = sxe2_tx_queue_release,
+	return ptypes;
+}
 
-	.rxq_info_get               = sxe2_rx_queue_info_get,
-	.txq_info_get               = sxe2_tx_queue_info_get,
-	.rx_burst_mode_get          = sxe2_rx_burst_mode_get,
-	.tx_burst_mode_get          = sxe2_tx_burst_mode_get,
-	.tx_done_cleanup            = sxe2_tx_done_cleanup,
-};
+static inline void sxe2_init_ptype_tbl(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	uint32_t *ptype = adapter->ptype_tbl;
+
+	PMD_INIT_FUNC_TRACE();
+
+	sxe2_init_ptype_list(ptype);
+}
 
 struct sxe2_pci_map_bar_info *sxe2_dev_get_bar_info(struct sxe2_adapter *adapter,
 						    enum sxe2_pci_map_resource res_type)
@@ -360,6 +424,29 @@ void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
 	return addr;
 }
 
+static int32_t sxe2_eth_init(struct rte_eth_dev *dev)
+{
+	int32_t ret = 0;
+
+	ret = sxe2_link_update_init(dev);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to initialize link update, ret:%d", ret);
+		goto l_end;
+	}
+
+	ret = sxe2_mtu_set(dev, dev->data->mtu);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to set mtu, ret=%d", ret);
+		goto l_end;
+	}
+l_end:
+	return ret;
+}
+
+static void sxe2_eth_uinit(struct rte_eth_dev *dev __rte_unused)
+{
+}
+
 static void sxe2_drv_dev_caps_set(struct sxe2_adapter *adapter,
 			struct sxe2_drv_dev_caps_resp *dev_caps)
 {
@@ -765,6 +852,8 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
 		goto l_end;
 	}
 
+	sxe2_init_ptype_tbl(dev);
+
 	ret = sxe2_hw_init(dev);
 	if (ret) {
 		PMD_LOG_ERR(INIT, "Failed to initialize hw, ret=[%d]", ret);
@@ -789,18 +878,38 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
 		goto init_dev_info_err;
 	}
 
+	ret = sxe2_eth_init(dev);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
+		goto init_eth_err;
+	}
+
 	goto l_end;
 
+init_eth_err:
 init_dev_info_err:
 	sxe2_vsi_uninit(dev);
 init_vsi_err:
+	sxe2_dev_pci_map_uinit(dev);
 l_end:
 	return ret;
 }
 
+static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
+{
+	(void)sxe2_dev_stop(dev);
+	(void)sxe2_queues_release(dev);
+	sxe2_vsi_uninit(dev);
+	sxe2_dev_pci_map_uinit(dev);
+	sxe2_eth_uinit(dev);
+
+	return 0;
+}
+
 static int32_t sxe2_dev_uninit(struct rte_eth_dev *dev)
 {
 	int32_t ret = 0;
+
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		goto l_end;
 
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 001413e75a..66f49ac0cc 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -118,12 +118,6 @@ enum {
 	SXE2_FLAGS_NBITS
 };
 
-struct sxe2_link_context {
-	rte_spinlock_t link_lock;
-	bool link_up;
-	uint32_t  speed;
-};
-
 struct sxe2_devargs {
 	uint8_t flow_dup_pattern_mode;
 	uint8_t func_flow_direct_en;
@@ -265,6 +259,12 @@ struct sxe2_sched_hw_cap {
 	uint8_t adj_lvl;
 };
 
+struct sxe2_link_context {
+	rte_spinlock_t link_lock;
+	bool link_up;
+	uint32_t  speed;
+};
+
 struct sxe2_adapter {
 	struct sxe2_common_device      *cdev;
 	struct sxe2_dev_info            dev_info;
@@ -274,9 +274,10 @@ struct sxe2_adapter {
 	struct sxe2_irq_context       irq_ctxt;
 	struct sxe2_queue_context     q_ctxt;
 	struct sxe2_vsi_context       vsi_ctxt;
-	struct sxe2_devargs			  devargs;
-	uint16_t                           dev_port_id;
-	uint64_t                           cap_flags;
+	struct sxe2_link_context      link_ctxt;
+	struct sxe2_devargs           devargs;
+	uint16_t                      dev_port_id;
+	uint64_t                      cap_flags;
 	enum sxe2_dev_type            dev_type;
 	uint32_t    ptype_tbl[SXE2_MAX_PTYPE_NUM];
 	struct rte_ether_addr           mac_addr;
diff --git a/drivers/net/sxe2/sxe2_mac.c b/drivers/net/sxe2/sxe2_mac.c
new file mode 100644
index 0000000000..3c2f909002
--- /dev/null
+++ b/drivers/net/sxe2/sxe2_mac.c
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
+ */
+
+#include <rte_os.h>
+#include "sxe2_osal.h"
+#include "sxe2_mac.h"
+#include "sxe2_common_log.h"
+#include "sxe2_ethdev.h"
+#include "sxe2_cmd_chnl.h"
+#include "sxe2_host_regs.h"
+
+int32_t sxe2_link_update_init(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(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) {
+		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;
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+
+	memset(&new_link, 0, sizeof(new_link));
+
+	switch (adapter->link_ctxt.speed) {
+	case 0:
+		new_link.link_speed = RTE_ETH_SPEED_NUM_NONE;
+		break;
+	case 10:
+		new_link.link_speed = RTE_ETH_SPEED_NUM_10M;
+		break;
+	case 100:
+		new_link.link_speed = RTE_ETH_SPEED_NUM_100M;
+		break;
+	case 1000:
+		new_link.link_speed = RTE_ETH_SPEED_NUM_1G;
+		break;
+	case 10000:
+		new_link.link_speed = RTE_ETH_SPEED_NUM_10G;
+		break;
+	case 20000:
+		new_link.link_speed = RTE_ETH_SPEED_NUM_20G;
+		break;
+	case 25000:
+		new_link.link_speed = RTE_ETH_SPEED_NUM_25G;
+		break;
+	case 40000:
+		new_link.link_speed = RTE_ETH_SPEED_NUM_40G;
+		break;
+	case 50000:
+		new_link.link_speed = RTE_ETH_SPEED_NUM_50G;
+		break;
+	case 100000:
+		new_link.link_speed = RTE_ETH_SPEED_NUM_100G;
+		break;
+	default:
+		new_link.link_speed = RTE_ETH_SPEED_NUM_NONE;
+		break;
+	}
+
+	new_link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
+	new_link.link_status = adapter->link_ctxt.link_up ? RTE_ETH_LINK_UP :
+					     RTE_ETH_LINK_DOWN;
+	new_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+				RTE_ETH_LINK_SPEED_FIXED);
+
+	return rte_eth_linkstatus_set(dev, &new_link);
+}
+
+int32_t sxe2_mtu_set(struct rte_eth_dev *dev, uint16_t mtu __rte_unused)
+{
+	int32_t ret                      = -1;
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (dev->data->dev_started != 0) {
+		PMD_DEV_LOG_ERR(adapter, DRV, "port %d must be stopped before configuration",
+				dev->data->port_id);
+		ret = -1;
+		goto l_end;
+	}
+
+	ret = 0;
+
+l_end:
+	return ret;
+}
diff --git a/drivers/net/sxe2/sxe2_mac.h b/drivers/net/sxe2/sxe2_mac.h
new file mode 100644
index 0000000000..28dc05e125
--- /dev/null
+++ b/drivers/net/sxe2/sxe2_mac.h
@@ -0,0 +1,50 @@
+
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
+ */
+
+#ifndef __SXE2_MAC_H__
+#define __SXE2_MAC_H__
+#include <ethdev_driver.h>
+#include "sxe2_host_regs.h"
+
+#define SXE2_NUM_MACADDR_MAX   64
+
+#define SXE2_DPDK_OFFLOAD_OUTER_INSERT_8021Q SXE2_VSI_L2TAGSTXVALID_ID_OUT_VLAN1
+#define SXE2_DPDK_OFFLOAD_OUTER_INSERT_8021AD SXE2_VSI_L2TAGSTXVALID_ID_STAG
+#define SXE2_DPDK_OFFLOAD_OUTER_INSERT_QINQ1 SXE2_VSI_L2TAGSTXVALID_ID_OUT_VLAN2
+#define SXE2_DPDK_OFFLOAD_OUTER_INSERT_VLAN  SXE2_VSI_L2TAGSTXVALID_ID_VLAN
+
+#define SXE2_DPDK_OFFLOAD_OUTER_INSERT_ENABLE SXE2_VSI_L2TAGSTXVALID_L2TAG1_VALID
+
+#define SXE2_DPDK_OFFLOAD_OUTER_STRIP_8021Q SXE2_VSI_TSR_ID_OUT_VLAN1
+#define SXE2_DPDK_OFFLOAD_OUTER_STRIP_8021AD SXE2_VSI_TSR_ID_STAG
+#define SXE2_DPDK_OFFLOAD_OUTER_STRIP_QINQ1 SXE2_VSI_TSR_ID_OUT_VLAN2
+
+#define SXE2_DPDK_OFFLOAD_INNER_INSERT_QINQ1  SXE2_VSI_L2TAGSTXVALID_ID_VLAN
+#define SXE2_DPDK_OFFLOAD_INNER_INSERT_ENABLE SXE2_VSI_L2TAGSTXVALID_L2TAG2_VALID
+
+#define SXE2_DPDK_OFFLOAD_INNER_STRIP_QINQ1 SXE2_VSI_TSR_ID_VLAN
+
+#define SXE2_DPDK_OFFLOAD_FIELD                (0X0F)
+#define SXE2_DPDK_OFFLOAD_TAGID_FIELD          (0X07)
+
+#define SXE2_DPDK_OFFLOAD_OUTER_STRIP_MASK (SXE2_DPDK_OFFLOAD_OUTER_STRIP_8021Q | \
+					SXE2_DPDK_OFFLOAD_OUTER_STRIP_8021AD | \
+					SXE2_DPDK_OFFLOAD_OUTER_STRIP_QINQ1)
+#define SXE2_DPDK_OFFLOAD_STRIP_OFFSET SXE2_VSI_TSR_SHOW_TAG_S
+
+#define SXE2_DPDK_OFFLOAD_INSERT_ENABLE (BIT(3))
+
+struct sxe2_mac_mc_list {
+	uint32_t count;
+	struct rte_ether_addr addr[SXE2_NUM_MACADDR_MAX];
+};
+
+int32_t sxe2_link_update_init(struct rte_eth_dev *dev);
+
+int32_t sxe2_link_update(struct rte_eth_dev *dev, __rte_unused int32_t wait_to_complete);
+
+int32_t sxe2_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
+
+#endif /* __SXE2_MAC_H__ */
-- 
2.47.3


^ permalink raw reply related

* [PATCH v1 09/23] drivers: interrupt handling
From: liujie5 @ 2026-05-24  9:32 UTC (permalink / raw)
  To: stephen; +Cc: dev, Jie Liu
In-Reply-To: <20260524093259.397506-1-liujie5@linkdatatechnology.com>

From: Jie Liu <liujie5@linkdatatechnology.com>

This patch includes:
- MSI-X vector allocation and mapping logic.
- Support for rx_queue_intr_enable and rx_queue_intr_disable ops.
- Interrupt handler to process admin and queue events.
- Integration with EAL interrupt framework.

RX queue interrupts allow applications to use rte_eth_dev_rx_intr_wait()
for power-efficient packet processing.

Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
 drivers/common/sxe2/sxe2_ioctl_chnl.c      | 177 +++-
 drivers/common/sxe2/sxe2_ioctl_chnl_func.h |  18 +
 drivers/net/sxe2/meson.build               |   1 +
 drivers/net/sxe2/sxe2_cmd_chnl.c           |  42 +
 drivers/net/sxe2/sxe2_cmd_chnl.h           |   4 +
 drivers/net/sxe2/sxe2_drv_cmd.h            |   8 +
 drivers/net/sxe2/sxe2_ethdev.c             |  93 +-
 drivers/net/sxe2/sxe2_ethdev.h             |   6 +
 drivers/net/sxe2/sxe2_irq.c                | 941 +++++++++++++++++++++
 drivers/net/sxe2/sxe2_irq.h                |  21 +
 drivers/net/sxe2/sxe2vf_regs.h             |  82 ++
 11 files changed, 1389 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/sxe2/sxe2_irq.c
 create mode 100644 drivers/net/sxe2/sxe2vf_regs.h

diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index 2ffbeb9217..173d8d57ae 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -67,6 +67,7 @@ sxe2_drv_cmd_exec(struct sxe2_common_device *cdev,
 	return ret;
 }
 
+
 RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_open)
 int32_t
 sxe2_drv_dev_open(struct sxe2_common_device *cdev, struct rte_pci_device *pci_dev)
@@ -87,7 +88,7 @@ sxe2_drv_dev_open(struct sxe2_common_device *cdev, struct rte_pci_device *pci_de
 	if (fd < 0) {
 		ret = -EBADF;
 		PMD_LOG_ERR(COM, "Fail to open device:%s, ret=%d, err:%s",
-				drv_name, ret, strerror(errno));
+			    drv_name, ret, strerror(errno));
 		goto l_end;
 	}
 
@@ -159,6 +160,177 @@ sxe2_drv_dev_handshake(struct sxe2_common_device *cdev)
 	return ret;
 }
 
+RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_rxq_irq_set)
+int32_t
+sxe2_drv_dev_rxq_irq_set(struct sxe2_common_device *cdev,
+		       uint16_t base_irq, int32_t *efd, uint16_t nb_irq)
+{
+	struct sxe2_ioctl_irq_set cmd_params;
+	int32_t ret = 0;
+	int32_t cmd_fd = 0;
+
+	if (cdev->config.kernel_reset) {
+		ret = -EPERM;
+		PMD_LOG_WARN(COM, "kernel reset, need restart app.");
+		goto l_end;
+	}
+
+	cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
+	if (cmd_fd < 0) {
+		ret = -EBADF;
+		PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
+		goto l_end;
+	}
+
+	PMD_LOG_DEBUG(COM, "Open fd=%d to set rxq irq, base_queue=%d, efds=%p, nb_irq=%d",
+		cmd_fd, base_irq, efd, nb_irq);
+
+	memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_irq_set));
+	cmd_params.base_irq_in_com = base_irq;
+	cmd_params.cnt = nb_irq;
+	cmd_params.event_fd = efd;
+
+	pthread_mutex_lock(&cdev->config.lock);
+	ret = ioctl(cmd_fd, SXE2_COM_CMD_IO_IRQS_REQ, &cmd_params);
+	if (ret < 0) {
+		PMD_LOG_ERR(COM, "Failed to set io irqs, fd=%d, ret=%d, err:%s",
+			    cmd_fd, ret, strerror(errno));
+		pthread_mutex_unlock(&cdev->config.lock);
+		goto l_end;
+	}
+	pthread_mutex_unlock(&cdev->config.lock);
+
+l_end:
+	return ret;
+}
+
+RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_other_irq_set)
+int32_t
+sxe2_drv_dev_other_irq_set(struct sxe2_common_device *cdev,
+			int32_t efd, uint64_t event)
+{
+	int32_t ret = 0;
+	int32_t cmd_fd = 0;
+	struct sxe2_ioctl_other_evt_set cmd_params;
+
+	if (cdev->config.kernel_reset) {
+		ret = -EPERM;
+		PMD_LOG_WARN(COM, "kernel reset, need restart app.");
+		goto l_end;
+	}
+
+	cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
+	if (cmd_fd < 0) {
+		ret = -EBADF;
+		PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
+		goto l_end;
+	}
+
+	PMD_LOG_DEBUG(COM, "Open fd=%d to set other irq, efd=%d, event=%"PRIu64"",
+		cmd_fd, efd, event);
+
+	memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_other_evt_set));
+	cmd_params.eventfd = efd;
+	cmd_params.filter_table = event;
+
+	pthread_mutex_lock(&cdev->config.lock);
+	ret = ioctl(cmd_fd, SXE2_COM_CMD_EVT_IRQ_REQ, &cmd_params);
+	if (ret < 0) {
+		PMD_LOG_ERR(COM, "Failed to set others evt, fd=%d, ret=%d, err:%s",
+			   cmd_fd, ret, strerror(errno));
+		ret = -EIO;
+		pthread_mutex_unlock(&cdev->config.lock);
+		goto l_end;
+	}
+	pthread_mutex_unlock(&cdev->config.lock);
+
+l_end:
+	return ret;
+}
+
+RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_other_irq_get)
+int32_t
+sxe2_drv_dev_other_irq_get(struct sxe2_common_device *cdev, uint64_t *event)
+{
+	int32_t ret = 0;
+	int32_t cmd_fd = 0;
+	struct sxe2_ioctl_other_evt_get cmd_params;
+
+	if (cdev->config.kernel_reset) {
+		ret = -EPERM;
+		PMD_LOG_WARN(COM, "kernel reset, need restart app.");
+		goto l_end;
+	}
+
+	cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
+	if (cmd_fd < 0) {
+		ret = -EBADF;
+		PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
+		goto l_end;
+	}
+
+	PMD_LOG_DEBUG(COM, "Open fd=%d to get other irq", cmd_fd);
+
+	memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_other_evt_get));
+
+	pthread_mutex_lock(&cdev->config.lock);
+	ret = ioctl(cmd_fd, SXE2_COM_CMD_EVT_CAUSE_GET, &cmd_params);
+	if (ret < 0) {
+		PMD_LOG_ERR(COM, "Failed to set others evt, fd=%d, ret=%d, err:%s",
+			   cmd_fd, ret, strerror(errno));
+		ret = -EIO;
+		pthread_mutex_unlock(&cdev->config.lock);
+		goto l_end;
+	}
+	pthread_mutex_unlock(&cdev->config.lock);
+	*event = cmd_params.evt_cause;
+
+l_end:
+	return ret;
+}
+
+RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_reset_irq_set)
+int32_t
+sxe2_drv_dev_reset_irq_set(struct sxe2_common_device *cdev, int32_t efd)
+{
+	int32_t ret = 0;
+	int32_t cmd_fd = 0;
+	struct sxe2_ioctl_reset_sub_set cmd_params;
+
+	if (cdev->config.kernel_reset) {
+		ret = -EPERM;
+		PMD_LOG_WARN(COM, "kernel reset, need restart app.");
+		goto l_end;
+	}
+
+	cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
+	if (cmd_fd < 0) {
+		ret = -EBADF;
+		PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
+		goto l_end;
+	}
+
+	PMD_LOG_DEBUG(COM, "Open fd=%d to set reset irq, efd=%d",
+		cmd_fd, efd);
+
+	memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_reset_sub_set));
+	cmd_params.eventfd = efd;
+
+	pthread_mutex_lock(&cdev->config.lock);
+	ret = ioctl(cmd_fd, SXE2_COM_CMD_RST_IRQ_REQ, &cmd_params);
+	if (ret < 0) {
+		PMD_LOG_ERR(COM, "Failed to set reset irqs, fd=%d, ret=%d, err:%s",
+			   cmd_fd, ret, strerror(errno));
+		ret = -EIO;
+		pthread_mutex_unlock(&cdev->config.lock);
+		goto l_end;
+	}
+	pthread_mutex_unlock(&cdev->config.lock);
+
+l_end:
+	return ret;
+}
+
 RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_mmap)
 void
 *sxe2_drv_dev_mmap(struct sxe2_common_device *cdev, uint8_t bar_idx, uint64_t len, uint64_t offset)
@@ -223,7 +395,7 @@ sxe2_drv_dev_munmap(struct sxe2_common_device *cdev, void *virt, uint64_t len)
 RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_dma_map)
 int32_t
 sxe2_drv_dev_dma_map(struct sxe2_common_device *cdev, uint64_t vaddr,
-			uint64_t iova, uint64_t size)
+		     uint64_t iova, uint64_t size)
 {
 	struct sxe2_ioctl_iommu_dma_map cmd_params;
 	enum rte_iova_mode iova_mode;
@@ -322,4 +494,3 @@ sxe2_drv_dev_dma_unmap(struct sxe2_common_device *cdev, uint64_t iova)
 l_end:
 	return ret;
 }
-
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl_func.h b/drivers/common/sxe2/sxe2_ioctl_chnl_func.h
index aed5a5b50d..f29194fc9e 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl_func.h
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl_func.h
@@ -29,6 +29,7 @@ int32_t
 sxe2_drv_dev_open(struct sxe2_common_device *cdev,
 		struct rte_pci_device *pci_dev);
 
+
 __rte_internal
 void
 sxe2_drv_dev_close(struct sxe2_common_device *cdev);
@@ -37,6 +38,23 @@ __rte_internal
 int32_t
 sxe2_drv_dev_handshake(struct sxe2_common_device *cdev);
 
+__rte_internal
+int32_t
+sxe2_drv_dev_rxq_irq_set(struct sxe2_common_device *cdev, uint16_t base_irq,
+			 int32_t *efd, uint16_t nb_irq);
+
+__rte_internal
+int32_t
+sxe2_drv_dev_other_irq_set(struct sxe2_common_device *cdev, int32_t efd, uint64_t event);
+
+__rte_internal
+int32_t
+sxe2_drv_dev_other_irq_get(struct sxe2_common_device *cdev, uint64_t *event);
+
+__rte_internal
+int32_t
+sxe2_drv_dev_reset_irq_set(struct sxe2_common_device *cdev, int32_t fd);
+
 __rte_internal
 void
 *sxe2_drv_dev_mmap(struct sxe2_common_device *cdev, uint8_t bar_idx,
diff --git a/drivers/net/sxe2/meson.build b/drivers/net/sxe2/meson.build
index d860629def..c73e13bbad 100644
--- a/drivers/net/sxe2/meson.build
+++ b/drivers/net/sxe2/meson.build
@@ -68,6 +68,7 @@ sources += files(
         'sxe2_security.c',
         'sxe2_mp.c',
         'sxe2_stats.c',
+        'sxe2_irq.c',
 )
 
 allow_internal_get_api = true
\ No newline at end of file
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index a1fc8a50e3..d1f15084ed 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -348,6 +348,48 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
 	return ret;
 }
 
+int32_t sxe2_drv_rxq_bind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx, uint16_t msix_idx)
+{
+	struct sxe2_common_device *cdev = adapter->cdev;
+	struct sxe2_drv_cmd_params param = {0};
+	struct sxe2_drv_queue_irq_bind_req req = {0};
+	int32_t ret = 0;
+
+	req.msix_idx = msix_idx;
+	req.q_idx = rxq_idx;
+	req.itr_idx = 0;
+	req.bind = true;
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_EVT_IRQ_BAND_RXQ,
+				 &req, sizeof(req),
+				 NULL, 0);
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret)
+		PMD_DEV_LOG_ERR(adapter, DRV, "rxq bind irq failed, ret=%d", ret);
+
+	return ret;
+}
+
+int32_t sxe2_drv_rxq_unbind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx)
+{
+	struct sxe2_common_device *cdev = adapter->cdev;
+	struct sxe2_drv_cmd_params param = {0};
+	struct sxe2_drv_queue_irq_bind_req req = {0};
+	int32_t ret = 0;
+
+	req.bind = false;
+	req.q_idx = rxq_idx;
+
+	sxe2_drv_cmd_params_fill(adapter, &param, SXE2_DRV_CMD_EVT_IRQ_BAND_RXQ,
+				 &req, sizeof(req),
+				 NULL, 0);
+	ret = sxe2_drv_cmd_exec(cdev, &param);
+	if (ret)
+		PMD_DEV_LOG_ERR(adapter, DRV, "rxq unbind irq failed, ret=%d", ret);
+
+	return ret;
+}
+
 int32_t sxe2_drv_get_mac_stats(struct sxe2_adapter *adapter)
 {
 	int32_t ret = 0;
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index ff73d2f901..c13653e8af 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -118,4 +118,8 @@ int32_t sxe2_drv_rss_hf_clear(struct sxe2_adapter *adapter);
 
 int32_t sxe2_drv_ptp_gettime(struct sxe2_adapter *adapter, struct sxe2_rx_queue *rxq);
 
+int32_t sxe2_drv_rxq_bind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx, uint16_t msix_idx);
+
+int32_t sxe2_drv_rxq_unbind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx);
+
 #endif /* __SXE2_CMD_CHNL_H__ */
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index a88e2b24bf..0b2a715000 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -215,6 +215,14 @@ struct sxe2_drv_q_switch_req {
 	uint8_t rsv[2];
 };
 
+struct sxe2_drv_queue_irq_bind_req {
+	__le16 q_idx;
+	__le16 msix_idx;
+	uint8_t itr_idx;
+	uint8_t bind;
+	uint8_t rsv[2];
+};
+
 struct sxe2_drv_vsi_create_req_resp {
 	uint16_t vsi_id;
 	uint16_t vsi_type;
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index dbe1a2bce1..f3fee74ddf 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -22,6 +22,7 @@
 #include <rte_eal_paging.h>
 
 #include "sxe2_ethdev.h"
+#include "sxe2_irq.h"
 #include "sxe2_drv_cmd.h"
 #include "sxe2_cmd_chnl.h"
 #include "sxe2_tx.h"
@@ -107,6 +108,9 @@ static const struct eth_dev_ops sxe2_eth_dev_ops = {
 	.rx_queue_release           = sxe2_rx_queue_release,
 	.tx_queue_setup             = sxe2_tx_queue_setup,
 	.tx_queue_release           = sxe2_tx_queue_release,
+	.rx_queue_intr_enable       = sxe2_rx_queue_intr_enable,
+	.rx_queue_intr_disable      = sxe2_rx_queue_intr_disable,
+
 	.rxq_info_get               = sxe2_rx_queue_info_get,
 	.txq_info_get               = sxe2_tx_queue_info_get,
 	.rx_burst_mode_get          = sxe2_rx_burst_mode_get,
@@ -177,6 +181,8 @@ static int32_t sxe2_dev_stop(struct rte_eth_dev *dev)
 	if (adapter->started == 0)
 		goto l_end;
 
+	sxe2_rxq_intr_disable(dev);
+
 	sxe2_txqs_all_stop(dev);
 	sxe2_rxqs_all_stop(dev);
 
@@ -215,6 +221,12 @@ static int32_t sxe2_dev_start(struct rte_eth_dev *dev)
 		goto l_end;
 	}
 
+	ret = sxe2_rxq_intr_enable(dev);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to enable rx queue intr");
+		goto l_rxq_intr_err;
+	}
+
 	ret = sxe2_queues_start(dev);
 	if (ret) {
 		PMD_LOG_ERR(INIT, "enable queues failed");
@@ -224,7 +236,10 @@ static int32_t sxe2_dev_start(struct rte_eth_dev *dev)
 	dev->data->dev_started = 1;
 	adapter->started = 1;
 	goto l_end;
+
 l_start_queues_err:
+	(void)sxe2_rxq_intr_disable(dev);
+l_rxq_intr_err:
 	(void)sxe2_filter_rule_stop(dev);
 l_end:
 	return ret;
@@ -615,6 +630,8 @@ static int32_t sxe2_func_caps_get(struct sxe2_adapter *adapter)
 
 	sxe2_sw_queue_ctx_hw_cap_set(adapter, &dev_caps.queue_caps);
 
+	sxe2_sw_irq_ctx_hw_cap_set(adapter, &dev_caps.msix_caps);
+
 	sxe2_sw_rss_ctx_hw_cap_set(adapter, &dev_caps.rss_hash_caps);
 
 	sxe2_sw_vsi_ctx_hw_cap_set(adapter, &dev_caps.vsi_caps);
@@ -636,6 +653,41 @@ static int32_t sxe2_dev_caps_get(struct sxe2_adapter *adapter)
 	return ret;
 }
 
+uint32_t sxe2_pci_map_read_reg(struct sxe2_adapter *adapter,
+		enum sxe2_pci_map_resource res_type, uint16_t idx_in_func)
+{
+	void *reg_addr;
+	uint32_t value;
+
+	reg_addr = sxe2_pci_map_addr_get(adapter, res_type, idx_in_func);
+	if (unlikely(reg_addr == NULL)) {
+		PMD_DEV_LOG_ERR(adapter, DRV, "reg addr:0x%p is error.", reg_addr);
+		value = SXE2_PCI_MAP_INVALID_VAL;
+		goto l_ret;
+	}
+
+	value = SXE2_PCI_REG_READ(reg_addr);
+
+l_ret:
+	return value;
+}
+
+void sxe2_pci_map_write_reg(struct sxe2_adapter *adapter,
+		enum sxe2_pci_map_resource res_type, uint16_t idx_in_func, uint32_t value)
+{
+	void *reg_addr;
+
+	reg_addr = sxe2_pci_map_addr_get(adapter, res_type, idx_in_func);
+	if (unlikely(reg_addr == NULL)) {
+		PMD_DEV_LOG_ERR(adapter, DRV, "reg addr:0x%p is error.", reg_addr);
+		goto l_ret;
+	}
+
+	SXE2_PCI_REG_WRITE_WC(reg_addr, value);
+l_ret:
+	return;
+}
+
 int32_t sxe2_dev_pci_seg_map(struct sxe2_adapter *adapter,
 			     enum sxe2_pci_map_resource res_type,
 			     uint64_t org_len,
@@ -715,6 +767,27 @@ static int32_t sxe2_hw_init(struct rte_eth_dev *dev)
 	return ret;
 }
 
+static int32_t sxe2_sw_init(struct rte_eth_dev *dev)
+{
+	int32_t ret = -1;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ret = sxe2_sw_irq_ctxt_init(dev);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to sw irq ctxt init, ret=[%d]", ret);
+		goto l_end;
+	}
+
+l_end:
+	return ret;
+}
+
+static void sxe2_sw_uninit(struct rte_eth_dev *dev)
+{
+	sxe2_sw_irq_ctxt_uninit(dev);
+}
+
 int32_t sxe2_dev_pci_res_seg_map(struct sxe2_adapter *adapter,
 				 uint32_t res_type,
 				 uint32_t item_cnt,
@@ -1065,6 +1138,18 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
 		goto init_dev_info_err;
 	}
 
+	ret = sxe2_sw_init(dev);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to initialize sw parameters, ret=[%d]", ret);
+		goto init_sw_err;
+	}
+
+	ret = sxe2_intr_init(dev);
+	if (ret != 0) {
+		PMD_LOG_ERR(INIT, "Failed to initialize interrupt, ret:%d", ret);
+		goto init_irq_err;
+	}
+
 	ret = sxe2_eth_init(dev);
 	if (ret) {
 		PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
@@ -1109,6 +1194,10 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
 init_rss_err:
 	sxe2_security_uinit(dev);
 init_security_err:
+	sxe2_intr_uninit(dev);
+init_irq_err:
+	sxe2_sw_uninit(dev);
+init_sw_err:
 	sxe2_eth_uinit(dev);
 init_eth_err:
 init_dev_info_err:
@@ -1132,8 +1221,10 @@ static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
 	(void)sxe2_sched_uinit(dev);
 	sxe2_vsi_uninit(dev);
 	sxe2_security_uinit(dev);
-	sxe2_dev_pci_map_uinit(dev);
+	sxe2_intr_uninit(dev);
+	sxe2_sw_uninit(dev);
 	sxe2_eth_uinit(dev);
+	sxe2_dev_pci_map_uinit(dev);
 
 l_end:
 	return 0;
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index 32a67ed344..65ada44c12 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -354,6 +354,12 @@ int32_t sxe2_dev_pci_res_seg_map(struct sxe2_adapter *adapter,
 				 uint32_t item_cnt,
 				 uint32_t item_base);
 
+void sxe2_pci_map_write_reg(struct sxe2_adapter *adapter,
+		enum sxe2_pci_map_resource res_type, uint16_t idx_in_func, uint32_t value);
+
+uint32_t sxe2_pci_map_read_reg(struct sxe2_adapter *adapter,
+		enum sxe2_pci_map_resource res_type, uint16_t idx_in_func);
+
 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);
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
new file mode 100644
index 0000000000..13619500ea
--- /dev/null
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -0,0 +1,941 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
+ */
+
+#include <stdint.h>
+#include <sys/eventfd.h>
+#include <unistd.h>
+#include <ethdev_pci.h>
+#include <ethdev_driver.h>
+#include <rte_alarm.h>
+#include <fcntl.h>
+#include <rte_stdatomic.h>
+
+#include "sxe2_ethdev.h"
+#include "sxe2_irq.h"
+#include "sxe2_common_log.h"
+#include "sxe2_queue.h"
+#include "sxe2_drv_cmd.h"
+#include "sxe2_ioctl_chnl_func.h"
+#include "sxe2vf_regs.h"
+#include "sxe2_host_regs.h"
+#include "sxe2_cmd_chnl.h"
+
+#define SXE2_INT_EVENT_OICR_ALL (SXE2_PF_INT_OICR_SWINT | \
+					SXE2_PF_INT_OICR_LAN_TX_ERR | \
+					SXE2_PF_INT_OICR_LAN_RX_ERR | \
+					SXE2_PF_INT_OICR_FW)
+
+#define MAX_EVENT_PENDING (16)
+
+struct sxe2_event_element {
+	TAILQ_ENTRY(sxe2_event_element) next;
+	struct rte_eth_dev *dev;
+};
+
+struct sxe2_event_handler {
+	RTE_ATOMIC(uint16_t)ndev;
+	rte_thread_t tid;
+	int32_t fd[2];
+	rte_spinlock_t  lock;
+	TAILQ_HEAD(event_list, sxe2_event_element) pending;
+};
+static struct sxe2_event_handler event_handler = {
+	.fd = {-1, -1},
+};
+static volatile int32_t event_thread_run;
+
+
+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];
+
+	if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
+		PMD_DEV_LOG_INFO(adapter, DRV, "OICR=%" PRIu64, oicr);
+		(void)sxe2_drv_mac_link_status_get(adapter);
+		if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+			rte_eth_dev_callback_process(dev,
+						     RTE_ETH_EVENT_INTR_LSC,
+						     NULL);
+	}
+}
+
+static uint32_t sxe2_event_intr_handle(void *param __rte_unused)
+{
+	struct sxe2_event_handler *handler = &event_handler;
+	struct sxe2_adapter *adapter;
+	struct sxe2_event_element *pos;
+	struct sxe2_event_element *tmp;
+	int32_t ret = 0;
+	uint64_t oicr = 0;
+	TAILQ_HEAD(event_list, sxe2_event_element) pending;
+	int8_t unused[MAX_EVENT_PENDING];
+	ssize_t nr;
+
+	while (event_thread_run) {
+		nr = read(handler->fd[0], &unused, sizeof(unused));
+		if (nr <= 0)
+			break;
+
+		rte_spinlock_lock(&handler->lock);
+		TAILQ_INIT(&pending);
+		TAILQ_CONCAT(&pending, &handler->pending, next);
+		rte_spinlock_unlock(&handler->lock);
+
+		TAILQ_FOREACH_SAFE(pos, &pending, next, tmp) {
+			TAILQ_REMOVE(&pending, pos, next);
+			adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(pos->dev);
+
+			ret = sxe2_drv_dev_other_irq_get(adapter->cdev, &oicr);
+			sxe2_event_irq_common_handler(adapter, oicr);
+
+			rte_free(pos);
+		}
+	}
+
+	return ret;
+}
+
+static int32_t sxe2_event_intr_handler_init(void)
+{
+	struct sxe2_event_handler *handler = &event_handler;
+	int32_t ret = 0;
+	int err = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	if (rte_atomic_fetch_add_explicit(&handler->ndev, 1, rte_memory_order_acq_rel) >= 1) {
+		ret = 0;
+		PMD_LOG_DEBUG(INIT, "%s: ndev > 1", __func__);
+		goto l_end;
+	}
+
+#if defined(RTE_EXEC_ENV_IS_WINDOWS) && RTE_EXEC_ENV_IS_WINDOWS != 0
+	err = _pipe(handler->fd, MAX_EVENT_PENDING, O_BINARY);
+#else
+	err = pipe(handler->fd);
+#endif
+	if (err != 0) {
+		ret = -ECHILD;
+		rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_release);
+		PMD_LOG_ERR(INIT, "%s: pipe failed", __func__);
+		goto l_end;
+	}
+
+	event_thread_run = 1;
+
+	TAILQ_INIT(&handler->pending);
+	rte_spinlock_init(&handler->lock);
+
+	if (rte_thread_create_internal_control(&handler->tid, "sxe2-event",
+				sxe2_event_intr_handle, NULL)) {
+		PMD_LOG_ERR(INIT, "%s: thread create failed", __func__);
+		rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_release);
+		ret = -ECHILD;
+		goto l_end;
+	}
+	ret = 0;
+l_end:
+	return ret;
+}
+
+static void sxe2_event_intr_handler_uinit(void)
+{
+	struct sxe2_event_handler *handler = &event_handler;
+	struct sxe2_event_element *pos;
+	struct sxe2_event_element *tmp;
+	ssize_t nw = 0;
+	int8_t notify_byte = 0;
+
+	PMD_INIT_FUNC_TRACE();
+	if (rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_acq_rel) > 1) {
+		PMD_LOG_DEBUG(INIT, "event handler uinit, ndev > 0");
+		return;
+	}
+
+	event_thread_run = 0;
+	nw = write(handler->fd[1], &notify_byte, 1);
+	RTE_SET_USED(nw);
+
+	(void)rte_thread_join(handler->tid, NULL);
+
+	if (handler->fd[0] != -1) {
+		close(handler->fd[0]);
+		handler->fd[0] = -1;
+	}
+	if (handler->fd[1] != -1) {
+		close(handler->fd[1]);
+		handler->fd[1] = -1;
+	}
+
+	rte_spinlock_lock(&handler->lock);
+	TAILQ_FOREACH_SAFE(pos, &handler->pending, next, tmp) {
+		TAILQ_REMOVE(&handler->pending, pos, next);
+		rte_free(pos);
+	}
+	rte_spinlock_unlock(&handler->lock);
+}
+
+static void sxe2_event_intr_post(struct rte_eth_dev *dev)
+{
+	struct sxe2_event_handler *handler = &event_handler;
+	struct sxe2_event_element *elem = rte_malloc(NULL, sizeof(struct sxe2_event_element), 0);
+	int8_t notify_byte = 0;
+	ssize_t nw = 0;
+
+	if (!elem)
+		goto l_end;
+
+	elem->dev = dev;
+
+	rte_spinlock_lock(&handler->lock);
+	TAILQ_INSERT_TAIL(&handler->pending, elem, next);
+	rte_spinlock_unlock(&handler->lock);
+
+	nw = write(handler->fd[1], &notify_byte, 1);
+	RTE_SET_USED(nw);
+
+l_end:
+	return;
+}
+
+static void sxe2_interrupt_handler_other(void *arg)
+{
+	struct rte_eth_dev *dev = (struct rte_eth_dev *)arg;
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	int32_t eventfd = adapter->irq_ctxt.other_event_fd;
+	int32_t ret = 0;
+	uint64_t buf = 0;
+
+	ret = read(eventfd, &buf, sizeof(buf));
+	if (ret != sizeof(buf)) {
+		PMD_DEV_LOG_ERR(adapter, DRV, "read eventfd[%d] failed, ret:%d, errno:%d.",
+				eventfd, ret, errno);
+	}
+
+	sxe2_event_intr_post(dev);
+}
+
+static void sxe2_interrupt_handler_reset(void *arg)
+{
+	struct rte_eth_dev *dev = (struct rte_eth_dev *)arg;
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	int32_t resetfd = adapter->irq_ctxt.reset_event_fd;
+	int32_t ret = 0;
+	uint64_t buf = 0;
+
+	ret = read(resetfd, &buf, sizeof(buf));
+	if (ret != sizeof(buf)) {
+		PMD_DEV_LOG_ERR(adapter, DRV, "read resetfd[%d] failed, ret:%d, errno:%d.",
+				resetfd, ret, errno);
+	}
+
+	sxe2_drv_cmd_close(adapter->cdev);
+
+	rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RMV, NULL);
+}
+
+int32_t sxe2_sw_irq_ctxt_init(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+	int32_t ret = 0;
+
+	irq_ctxt->rxq_avail_cnt = irq_ctxt->max_cnt_hw;
+	irq_ctxt->rxq_base_idx_in_pf = irq_ctxt->base_idx_in_func;
+	irq_ctxt->reset_event_fd = -1;
+	irq_ctxt->other_event_fd = -1;
+
+	return ret;
+}
+
+void sxe2_sw_irq_ctxt_uninit(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+
+	memset(&adapter->irq_ctxt, 0, sizeof(adapter->irq_ctxt));
+	adapter->irq_ctxt.reset_event_fd = -1;
+	adapter->irq_ctxt.other_event_fd = -1;
+}
+
+void sxe2_sw_irq_ctx_hw_cap_set(struct sxe2_adapter *adapter,
+				struct sxe2_drv_msix_caps *msix_caps)
+{
+	adapter->irq_ctxt.max_cnt_hw = msix_caps->msix_vectors_cnt;
+	adapter->irq_ctxt.base_idx_in_func = msix_caps->base_idx_in_func;
+}
+
+static int32_t sxe2_intr_handler_cfg(struct rte_intr_handle *handle,
+		int32_t fd, rte_intr_callback_fn cb, void *cb_arg)
+{
+	int32_t ret = 0;
+
+	ret = rte_intr_fd_set(handle, fd);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to set intr_handle->fd, error %i (%s)",
+			errno, strerror(errno));
+		goto err;
+	}
+
+	ret = rte_intr_type_set(handle, RTE_INTR_HANDLE_EXT);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to set intr_handle->type, error %i (%s)",
+			errno, strerror(errno));
+		goto err;
+	}
+
+	ret = rte_intr_callback_register(handle, cb, cb_arg);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to initialize register intr callback, ret=%d", ret);
+		goto err;
+	}
+err:
+	return ret;
+}
+
+static struct rte_intr_handle *
+sxe2_intr_handler_create(int32_t fd, rte_intr_callback_fn cb, void *cb_arg)
+{
+	struct rte_intr_handle *tmp_intr_handle = NULL;
+	int32_t ret = 0;
+
+	tmp_intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
+	if (!tmp_intr_handle) {
+		PMD_LOG_ERR(INIT, "Failed to alloc memory for intr_handler, error %i (%s)",
+			errno, strerror(errno));
+		goto err;
+	}
+
+	ret = rte_intr_fd_set(tmp_intr_handle, fd);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to set intr_handle->fd, error %i (%s)",
+				errno, strerror(errno));
+		goto err;
+	}
+
+	ret = rte_intr_type_set(tmp_intr_handle, RTE_INTR_HANDLE_EXT);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to set intr_handle->type, error %i (%s)",
+				errno, strerror(errno));
+		goto err;
+	}
+
+	ret = rte_intr_callback_register(tmp_intr_handle, cb, cb_arg);
+	if (ret) {
+		PMD_LOG_ERR(INIT, "Failed to initialize register intr callback, ret=%d", ret);
+		goto err;
+	}
+
+	return tmp_intr_handle;
+err:
+	rte_intr_instance_free(tmp_intr_handle);
+	return NULL;
+}
+
+static void sxe2_intr_handler_destroy(struct rte_intr_handle *intr_handle,
+				  rte_intr_callback_fn cb, void *cb_arg)
+{
+	if (!intr_handle)
+		return;
+
+	if (rte_intr_fd_get(intr_handle) >= 0)
+		(void)rte_intr_callback_unregister(intr_handle, cb, cb_arg);
+	rte_intr_instance_free(intr_handle);
+}
+
+static int32_t sxe2_event_intr_fd_create(void)
+{
+	int32_t fd = 0;
+
+	fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+	if (fd < 0) {
+		PMD_LOG_ERR(INIT, "Can't setup eventfd, error %i (%s)",
+			errno, strerror(errno));
+		goto err;
+	}
+
+	return fd;
+err:
+	return -EBADF;
+}
+
+static void sxe2_event_intr_fd_destroy(int32_t fd)
+{
+	if (fd >= 0)
+		close(fd);
+}
+
+static int32_t sxe2_other_intr_register(struct rte_eth_dev *dev, int32_t fd)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	int32_t ret = 0;
+	uint64_t event = RTE_BIT32(SXE2_COM_EC_LINK_CHG) |
+				RTE_BIT32(SXE2_COM_SW_MODE_LEGACY) |
+				RTE_BIT32(SXE2_COM_SW_MODE_SWITCHDEV) |
+				RTE_BIT32(SXE2_COM_FC_ST_CHANGE);
+
+	ret = sxe2_drv_dev_other_irq_set(adapter->cdev, fd, event);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set other irq, ret=%d", ret);
+		goto l_end;
+	}
+
+l_end:
+	return ret;
+}
+
+static void sxe2_other_intr_unregister(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	int32_t ret = 0;
+
+	ret = sxe2_drv_dev_other_irq_set(adapter->cdev, -1, 0);
+	if (ret)
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set other irq, ret=%d", ret);
+}
+
+static int32_t sxe2_reset_intr_register(struct rte_eth_dev *dev, int32_t fd)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	int32_t ret = 0;
+
+	ret = sxe2_drv_dev_reset_irq_set(adapter->cdev, fd);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set reset irq, ret=%d", ret);
+		goto l_end;
+	}
+
+l_end:
+	return ret;
+}
+
+static void sxe2_reset_intr_unregister(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	int32_t ret = 0;
+
+	ret = sxe2_drv_dev_reset_irq_set(adapter->cdev, -1);
+	if (ret)
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set reset irq, ret=%d", ret);
+}
+
+int32_t sxe2_intr_init(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct rte_pci_device *pci_dev = SXE2_DEV_TO_PCI(dev);
+	struct rte_intr_handle *reset_handle = NULL;
+	int32_t ofd = -1;
+	int32_t rfd = -1;
+	int32_t ret = 0;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ofd = sxe2_event_intr_fd_create();
+	if (ofd < 0) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create event intr fd");
+		ret = -EBADF;
+		goto l_end;
+	}
+
+	ret = sxe2_intr_handler_cfg(pci_dev->intr_handle,
+			ofd, sxe2_interrupt_handler_other, dev);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create intr handler");
+		goto l_err_create_other_handler;
+	}
+
+	ret = sxe2_event_intr_handler_init();
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Event handler init failed, ret=%d", ret);
+		goto l_err_event_intr_handler_init;
+	}
+
+	ret = sxe2_other_intr_register(dev, ofd);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to register other intr, ret=%d", ret);
+		goto l_err_register_other_intr;
+	}
+	adapter->irq_ctxt.other_event_fd = ofd;
+
+	rfd = sxe2_event_intr_fd_create();
+	if (rfd < 0) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create event intr fd");
+		ret = -EBADF;
+		goto l_err_create_reset_fd;
+	}
+
+	reset_handle = sxe2_intr_handler_create(rfd, sxe2_interrupt_handler_reset, dev);
+	if (!reset_handle) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create intr handler");
+		ret = -ENOMEM;
+		goto l_err_create_reset_handler;
+	}
+	adapter->irq_ctxt.reset_handle = reset_handle;
+
+	ret = sxe2_reset_intr_register(dev, rfd);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to register reset intr, ret=%d", ret);
+		goto l_err_register_reset_intr;
+	}
+	adapter->irq_ctxt.reset_event_fd = rfd;
+
+	goto l_end;
+l_err_register_reset_intr:
+	sxe2_intr_handler_destroy(reset_handle, sxe2_interrupt_handler_reset, dev);
+	adapter->irq_ctxt.reset_handle = NULL;
+l_err_create_reset_handler:
+	sxe2_event_intr_fd_destroy(rfd);
+l_err_create_reset_fd:
+	sxe2_other_intr_unregister(dev);
+	adapter->irq_ctxt.other_event_fd = -1;
+l_err_register_other_intr:
+	sxe2_event_intr_handler_uinit();
+l_err_event_intr_handler_init:
+	sxe2_intr_handler_destroy(pci_dev->intr_handle,
+			sxe2_interrupt_handler_other, dev);
+	pci_dev->intr_handle = NULL;
+l_err_create_other_handler:
+	sxe2_event_intr_fd_destroy(ofd);
+l_end:
+	return ret;
+}
+
+void sxe2_intr_uninit(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct rte_pci_device *pci_dev = SXE2_DEV_TO_PCI(dev);
+
+	sxe2_reset_intr_unregister(dev);
+	sxe2_intr_handler_destroy(adapter->irq_ctxt.reset_handle,
+				sxe2_interrupt_handler_reset, dev);
+	sxe2_event_intr_fd_destroy(adapter->irq_ctxt.reset_event_fd);
+	sxe2_other_intr_unregister(dev);
+	sxe2_event_intr_handler_uinit();
+	sxe2_intr_handler_destroy(pci_dev->intr_handle,
+				sxe2_interrupt_handler_other, dev);
+	sxe2_event_intr_fd_destroy(adapter->irq_ctxt.other_event_fd);
+
+	adapter->irq_ctxt.other_event_fd = -1;
+	adapter->irq_ctxt.reset_event_fd = -1;
+	pci_dev->intr_handle = NULL;
+	adapter->irq_ctxt.reset_handle = NULL;
+}
+
+static int32_t sxe2_rxq_intr_efd_alloc(struct rte_eth_dev *dev, int32_t *efd)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	int32_t ret = 0;
+	int32_t fd = 0;
+
+	fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+	if (fd < 0) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Can't setup eventfd, error %i (%s)",
+			errno, strerror(errno));
+		ret = -EBADF;
+		goto l_end;
+	}
+
+	*efd = fd;
+
+l_end:
+	return ret;
+}
+
+static void sxe2_rxq_intr_efd_free(int32_t efd)
+{
+	close(efd);
+}
+
+static void sxe2_pci_hw_int_itr_set(struct sxe2_adapter *adapter, uint16_t msix_idx, uint16_t itr)
+{
+	sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_ITR, msix_idx, itr);
+}
+
+static void sxe2_pci_hw_irq_disable(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+	uint32_t value = (SXE2_ITR_IDX_NONE << SXE2_VF_DYN_CTL_ITR_IDX_S);
+
+	sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx, value);
+}
+
+static void sxe2_pci_hw_irq_enable(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+	uint32_t value = SXE2_VF_DYN_CTL_INTENABLE |
+		SXE2_VF_DYN_CTL_CLEARPBA |
+			(SXE2_ITR_IDX_NONE << SXE2_VF_DYN_CTL_ITR_IDX_S);
+
+	sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx, value);
+}
+
+static uint32_t sxe2_pci_hw_irq_dyn_ctl_read(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+	return sxe2_pci_map_read_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx);
+}
+
+static void sxe2_pci_hw_msix_disable(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+	sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX,
+			irq_idx, SXE2VF_BAR4_MSIX_DISABLE);
+}
+
+static void sxe2_pci_hw_msix_enable(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+	sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX,
+			irq_idx, SXE2VF_BAR4_MSIX_ENABLE);
+}
+
+static void sxe2_pci_hw_irq_trigger(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+	sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx,
+			(SXE2VF_ITR_IDX_NONE << SXE2VF_DYN_CTL_ITR_IDX_SHIFT) |
+			SXE2VF_DYN_CTL_SWINT_TRIG | SXE2VF_DYN_CTL_INTENABLE_MSK);
+}
+
+static void sxe2_pci_hw_irq_clear_pba(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+	sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx,
+		(SXE2VF_ITR_IDX_NONE << SXE2VF_DYN_CTL_ITR_IDX_SHIFT) |
+		SXE2VF_DYN_CTL_CLEARPBA | SXE2VF_DYN_CTL_INTENABLE_MSK);
+}
+
+static void sxe2_rxq_msix_cfg_unmap(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+	uint16_t rxq_cnt = adapter->q_ctxt.qp_cnt_assign;
+	uint16_t i = 0;
+
+	for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++)
+		sxe2_pci_hw_irq_disable(adapter, irq_ctxt->rxq_msix_idx[i]);
+
+	for (i = 0; i < rxq_cnt; i++)
+		(void)sxe2_drv_rxq_unbind_irq(adapter, i);
+}
+
+static int32_t sxe2_rxq_msix_cfg_map(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+	int32_t ret = 0;
+	uint32_t val;
+	uint16_t rxq_cnt = dev->data->nb_rx_queues;
+	uint16_t i = 0;
+	uint8_t rx_low_latency = adapter->devargs.rx_low_latency;
+
+	for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++) {
+		sxe2_pci_hw_irq_disable(adapter, irq_ctxt->rxq_msix_idx[i]);
+		if (rx_low_latency) {
+			sxe2_pci_hw_int_itr_set(adapter, irq_ctxt->rxq_msix_idx[i],
+					SXE2_ITR_INTERVAL_LOW);
+		} else {
+			sxe2_pci_hw_int_itr_set(adapter, irq_ctxt->rxq_msix_idx[i],
+					SXE2_ITR_INTERVAL_NORMAL);
+		}
+	}
+
+	for (i = 0; i < rxq_cnt; i++) {
+		ret = sxe2_drv_rxq_bind_irq(adapter, i, irq_ctxt->rxq_msix_idx[i]);
+		if (ret != 0) {
+			PMD_DEV_LOG_ERR(adapter, INIT, "RXQ[%u] bind IRQ[%u] failed.",
+				i, irq_ctxt->rxq_msix_idx[i]);
+			goto l_end;
+		}
+	}
+
+	for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++)
+		sxe2_pci_hw_irq_enable(adapter, irq_ctxt->rxq_msix_idx[i]);
+
+	for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++) {
+		val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, i);
+		if ((val & SXE2VF_DYN_CTL_INTENABLE) == 0)
+			continue;
+
+		sxe2_pci_hw_msix_disable(adapter, i);
+		sxe2_pci_hw_irq_trigger(adapter, i);
+		val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, i);
+		sxe2_pci_hw_irq_clear_pba(adapter, i);
+		val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, i);
+		sxe2_pci_hw_msix_enable(adapter, i);
+	}
+
+l_end:
+	if (ret != 0)
+		sxe2_rxq_msix_cfg_unmap(dev);
+	return ret;
+}
+
+static int32_t sxe2_rxq_map_msix_intr(struct rte_eth_dev *dev,
+		uint16_t msix_base __rte_unused, uint16_t nb_msix,
+		uint16_t base_queue, uint16_t nb_queue)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+	uint32_t *msix_tbl = NULL;
+	int32_t ret = 0;
+	uint16_t i;
+
+	if (!nb_queue || !nb_msix || nb_queue < nb_msix) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Queue num[%u] or msix num[%u] is invalid.",
+				nb_queue, nb_msix);
+		ret = -EINVAL;
+		goto l_end;
+	}
+
+	msix_tbl = rte_zmalloc(NULL, sizeof(uint32_t) * nb_queue, 0);
+	if (!msix_tbl) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to alloc msix_tbl memory.");
+		ret = -ENOMEM;
+		goto l_end;
+	}
+	for (i = 0; i < nb_queue; i++) {
+		msix_tbl[i] = i % nb_msix;
+		PMD_DEV_LOG_INFO(adapter, INIT, "Queue %u is binding to vect %u",
+				base_queue + i, msix_tbl[i]);
+	}
+
+	irq_ctxt->rxq_irq_cnt = nb_msix;
+	irq_ctxt->rxq_msix_idx = msix_tbl;
+
+l_end:
+	return ret;
+}
+
+static void sxe2_rxq_unmap_msix_intr(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+
+	rte_free(irq_ctxt->rxq_msix_idx);
+	irq_ctxt->rxq_msix_idx = NULL;
+	irq_ctxt->rxq_irq_cnt = 0;
+}
+
+static int32_t sxe2_rxq_intr_register(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+	struct rte_intr_handle *intr_handle = dev->intr_handle;
+	int32_t *efd_tbl = NULL;
+	uint16_t rxq_cnt = dev->data->nb_rx_queues;
+	uint16_t nb_msix = irq_ctxt->rxq_irq_cnt;
+	uint16_t i;
+	int32_t ret = 0;
+
+	if (rte_intr_type_set(intr_handle, RTE_INTR_HANDLE_EXT)) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set intr_handle->type, error %i (%s)",
+				errno, strerror(errno));
+		ret = -EPERM;
+		goto l_end;
+	}
+
+	efd_tbl = rte_zmalloc(NULL, sizeof(int32_t) * nb_msix, 0);
+	if (!efd_tbl) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to alloc efd_tbl memory.");
+		ret = -ENOMEM;
+		goto l_end;
+	}
+
+	for (i = 0; i < nb_msix; i++) {
+		ret = sxe2_rxq_intr_efd_alloc(dev, &efd_tbl[i]);
+		if (ret) {
+			PMD_DEV_LOG_ERR(adapter, INIT, "Failed to alloc efd_tbl, ret=%d", ret);
+			goto l_free_efd_tbl;
+		}
+	}
+
+	if (rte_intr_vec_list_alloc(intr_handle, "sxe2 rxq int", rxq_cnt)) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to allocate %d rx_queues intr_vec",
+				rxq_cnt);
+		ret = -ENOMEM;
+		goto l_free_efd_tbl;
+	}
+
+	for	(i = 0; i < rxq_cnt; i++) {
+		ret = rte_intr_vec_list_index_set(intr_handle, i,
+				irq_ctxt->rxq_msix_idx[i] + RTE_INTR_VEC_RXTX_OFFSET);
+		if (ret) {
+			PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set msix_tbl, ret=%d", ret);
+			goto l_free_efd_tbl;
+		}
+	}
+
+	for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++) {
+		ret = rte_intr_efds_index_set(intr_handle, i, efd_tbl[i]);
+		if (ret) {
+			PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set efd_tbl, ret=%d", ret);
+			goto l_free_efd_tbl;
+		}
+	}
+
+	if (rte_intr_nb_efd_set(intr_handle, rxq_cnt)) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Set intr nb efd failed, error %i (%s)",
+			errno, strerror(errno));
+		ret = -EPERM;
+		goto l_free_efd_tbl;
+	}
+
+	ret = sxe2_drv_dev_rxq_irq_set(adapter->cdev, 0, efd_tbl, nb_msix);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set rxq irq, ret=%d", ret);
+		goto l_free_efd_tbl;
+	}
+	irq_ctxt->rxq_event_fd = efd_tbl;
+
+	goto l_end;
+
+l_free_efd_tbl:
+	if (efd_tbl) {
+		for (i = 0; i < nb_msix; i++)
+			if (efd_tbl[i] >= 0)
+				sxe2_rxq_intr_efd_free(efd_tbl[i]);
+		rte_free(efd_tbl);
+	}
+	irq_ctxt->rxq_event_fd = NULL;
+
+	rte_intr_vec_list_free(intr_handle);
+l_end:
+	return ret;
+}
+
+static void sxe2_rxq_intr_unregister(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+	struct rte_intr_handle *intr_handle = dev->intr_handle;
+	int32_t efd = -1;
+	uint16_t msix_cnt = irq_ctxt->rxq_irq_cnt;
+	uint16_t i;
+
+	if (irq_ctxt->rxq_event_fd) {
+		for (i = 0; i < msix_cnt; i++) {
+			(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_intr_vec_list_free(intr_handle);
+
+	rte_intr_nb_efd_set(intr_handle, 0);
+	rte_intr_max_intr_set(intr_handle, 0);
+}
+
+int32_t sxe2_rxq_intr_enable(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	uint16_t msix_vect = adapter->irq_ctxt.rxq_base_idx_in_pf;
+	uint16_t msix_cnt = adapter->irq_ctxt.rxq_avail_cnt;
+	uint16_t rxq_cnt = dev->data->nb_rx_queues;
+	uint16_t rxq_base = adapter->q_ctxt.base_idx_in_pf;
+	int32_t ret = 0;
+
+	if (!rxq_cnt)
+		goto l_end;
+
+	msix_cnt = RTE_MIN(msix_cnt, rxq_cnt);
+
+	ret = sxe2_rxq_map_msix_intr(dev, msix_vect, msix_cnt, rxq_base, rxq_cnt);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to rxq[%d] map msix[%d] intr, cnt=%d, ret=%d",
+					rxq_base, msix_vect, rxq_cnt, ret);
+		goto l_end;
+	}
+
+	if (dev->data->dev_conf.intr_conf.rxq) {
+		ret = sxe2_rxq_intr_register(dev);
+		if (ret) {
+			PMD_DEV_LOG_ERR(adapter, INIT, "Failed to register rxq[%d] intr, ret=%d",
+					rxq_base, ret);
+			goto l_err_unmap;
+		}
+	}
+
+	ret = sxe2_rxq_msix_cfg_map(dev);
+	if (ret) {
+		PMD_DEV_LOG_ERR(adapter, INIT, "Failed to rxq[%d] map msix[%d] intr, ret=%d",
+					rxq_base, msix_vect, ret);
+		goto l_err_unregister;
+	}
+
+	goto l_end;
+l_err_unregister:
+	if (dev->data->dev_conf.intr_conf.rxq)
+		sxe2_rxq_intr_unregister(dev);
+l_err_unmap:
+	sxe2_rxq_unmap_msix_intr(dev);
+l_end:
+	return ret;
+}
+
+void sxe2_rxq_intr_disable(struct rte_eth_dev *dev)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+
+	if (!irq_ctxt->rxq_irq_cnt)
+		goto l_end;
+
+	sxe2_rxq_msix_cfg_unmap(dev);
+
+	if (dev->data->dev_conf.intr_conf.rxq)
+		sxe2_rxq_intr_unregister(dev);
+
+	sxe2_rxq_unmap_msix_intr(dev);
+
+l_end:
+	return;
+}
+
+int32_t sxe2_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+	uint64_t buf;
+	uint16_t irq_idx = irq_ctxt->rxq_msix_idx[queue_id];
+	size_t read_ret;
+
+	read_ret = read(irq_ctxt->rxq_event_fd[irq_idx], &buf, sizeof(buf));
+	(void)read_ret;
+	sxe2_pci_hw_irq_enable(adapter, irq_idx);
+	return 0;
+}
+
+int32_t sxe2_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+	struct sxe2_adapter *adapter =
+		SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+	uint32_t val;
+	int32_t ret = 0;
+	uint16_t irq_idx = adapter->irq_ctxt.rxq_msix_idx[queue_id];
+
+	val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, irq_idx);
+	if ((val & SXE2VF_DYN_CTL_INTENABLE) == 0) {
+		PMD_DEV_LOG_DEBUG(adapter, INIT, "rxq [%d] interrupt is disabled.", queue_id);
+		goto l_end;
+	}
+
+	sxe2_pci_hw_msix_disable(adapter, irq_idx);
+	sxe2_pci_hw_irq_trigger(adapter, irq_idx);
+	val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, irq_idx);
+	sxe2_pci_hw_irq_clear_pba(adapter, irq_idx);
+	val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, irq_idx);
+	sxe2_pci_hw_msix_enable(adapter, irq_idx);
+l_end:
+	return ret;
+}
diff --git a/drivers/net/sxe2/sxe2_irq.h b/drivers/net/sxe2/sxe2_irq.h
index bb96c6d842..c898c16f84 100644
--- a/drivers/net/sxe2/sxe2_irq.h
+++ b/drivers/net/sxe2/sxe2_irq.h
@@ -45,4 +45,25 @@ struct sxe2_irq_context {
 	int32_t *rxq_event_fd;
 };
 
+uint32_t sxe2_drv_dev_other_cause_get(struct sxe2_adapter *adapter);
+
+int32_t sxe2_intr_init(struct rte_eth_dev *dev);
+
+void sxe2_intr_uninit(struct rte_eth_dev *dev);
+
+int32_t sxe2_sw_irq_ctxt_init(struct rte_eth_dev *dev);
+
+void sxe2_sw_irq_ctxt_uninit(struct rte_eth_dev *dev);
+
+void sxe2_sw_irq_ctx_hw_cap_set(struct sxe2_adapter *adapter,
+		struct sxe2_drv_msix_caps *msix_caps);
+
+int32_t sxe2_rxq_intr_enable(struct rte_eth_dev *dev);
+
+void sxe2_rxq_intr_disable(struct rte_eth_dev *dev);
+
+int32_t sxe2_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
+
+int32_t sxe2_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);
+
 #endif /* __SXE2_IRQ_H__ */
diff --git a/drivers/net/sxe2/sxe2vf_regs.h b/drivers/net/sxe2/sxe2vf_regs.h
new file mode 100644
index 0000000000..503c7ce04f
--- /dev/null
+++ b/drivers/net/sxe2/sxe2vf_regs.h
@@ -0,0 +1,82 @@
+
+#ifndef __SXE2VF_REGS_H__
+#define __SXE2VF_REGS_H__
+
+#define SXE2VF_MBX_Q_LEN_M      0x3FF
+#define SXE2VF_MBX_Q_LEN_VFE_M  RTE_BIT32(28)
+
+#define SXE2VF_MBX_Q_LEN_OVFL_M RTE_BIT32(29)
+#define SXE2VF_MBX_Q_LEN_CRIT_M RTE_BIT32(30)
+#define SXE2VF_MBX_Q_LEN_ENA_M  RTE_BIT32(31)
+
+#define SXE2VF_MBX_RQ_HEAD      (0x00008000)
+#define SXE2VF_MBX_RQ_TAIL      (0x00008400)
+#define SXE2VF_MBX_RQ_LEN       (0x00007C00)
+#define SXE2VF_MBX_RQ_BAH       (0x00007800)
+#define SXE2VF_MBX_RQ_BAL       (0x00007400)
+
+#define SXE2VF_MBX_TQ_HEAD      (0x00006C00)
+#define SXE2VF_MBX_TQ_TAIL      (0x00007000)
+#define SXE2VF_MBX_TQ_LEN       (0x00006800)
+#define SXE2VF_MBX_TQ_BAH       (0x00006400)
+#define SXE2VF_MBX_TQ_BAL       (0x00006000)
+
+#define SXE2VF_RXQ_TAIL(_QRX)                 (0x2000 + ((_QRX) * 4))
+#define SXE2VF_TXQ_TAIL(_QRX)                 (0x1000 + ((_QRX) * 4))
+
+#define SXE2VF_INT_BASE 0x00002800
+
+#define SXE2VF_DYN_CTL0 (SXE2VF_INT_BASE + 0x0)
+
+#define SXE2VF_DYN_CTL(_idx) (SXE2VF_INT_BASE + 0x4 + ((_idx) * 4))
+#define SXE2VF_VF_DYN_CTL(_idx) (SXE2VF_INT_BASE + ((_idx) * 4))
+
+#define SXE2VF_BAR4_MSIX_BASE 0
+#define SXE2VF_BAR4_MSIX_CTL(_idx) (SXE2VF_BAR4_MSIX_BASE + 0xC + ((_idx) * 0x10))
+#define SXE2VF_BAR4_MSIX_ENABLE 0
+#define SXE2VF_BAR4_MSIX_DISABLE 1
+
+#define SXE2VF_DYN_CTL_INTENABLE RTE_BIT32(0)
+#define SXE2VF_DYN_CTL_CLEARPBA   RTE_BIT32(1)
+#define SXE2VF_DYN_CTL_SWINT_TRIG RTE_BIT32(2)
+#define SXE2VF_DYN_CTL_SW_ITR_IDX_ENABLE RTE_BIT32(24)
+
+#define SXE2VF_DYN_CTL_INTENABLE_MSK \
+	RTE_BIT32(31)
+
+#define SXE2VF_DYN_CTL_ITR_IDX_SHIFT 3
+
+enum sxe2vf_itr_idx {
+	SXE2VF_ITR_IDX_0 = 0,
+	SXE2VF_ITR_IDX_1,
+	SXE2VF_ITR_IDX_2,
+	SXE2VF_ITR_IDX_NONE,
+};
+
+#define SXE2VF_INT_ITR0   (0x00002800 + 65 * 0x4)
+#define SXE2VF_INT_ITR(_i, _irq_idx) (SXE2VF_INT_ITR0 + \
+			0x4 + (_i) * 0x104 + ((_irq_idx) * 4))
+#define SXE2VF_VF_INT_ITR(_itr_idx, _irq_idx) (0x00002800 + \
+			(0x104 * (_itr_idx)) + ((_irq_idx) * 4))
+#define SXE2VF_PFG_INT_CTL_ITR_GRAN_0    (2)
+
+#define SXE2VF_PCIE_SYS_READY              0x38c
+#define SXE2VF_PCIE_SYS_READY_CORER_ASSERT RTE_BIT32(0)
+#define SXE2VF_PCIE_SYS_READY_STOP_DROP_DONE RTE_BIT32(2)
+#define SXE2VF_PCIE_SYS_READY_R5        RTE_BIT32(3)
+#define SXE2VF_PCIE_SYS_READY_STOP_DROP RTE_BIT32(16)
+
+#define SXE2VF_PCIE_DEV_CTRL_DEV_STATUS               0x78
+#define SXE2VF_PCIE_DEV_CTRL_DEV_STATUS_TRANS_PENDING RTE_BIT32(21)
+
+#define SXE2VF_VF_VRC_VFGEN_RSTAT             (0x5800)
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT           GENMASK(1, 0)
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT_VFR       (0)
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT_COMPLETE  (RTE_BIT32(0))
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT_VF_ACTIVE (RTE_BIT32(1))
+
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT_FORVF_VFR (1)
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT_FORVF_MASK \
+	(RTE_BIT32(10))
+
+#endif /* SXE2VF_VF_INT_ITR */
-- 
2.47.3


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox