DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/7] Complete removal of queue stats mapping
@ 2026-05-30 16:09 Stephen Hemminger
  2026-05-30 16:09 ` [RFC 1/7] net/virtio: remove unused " Stephen Hemminger
                   ` (8 more replies)
  0 siblings, 9 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-05-30 16:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The per-queue stats mapping mechanism (rte_eth_dev_set_{rx,tx}_queue_stats_mapping
and the queue_stats_mapping_set ethdev op) was a workaround for hardware that
could only expose a limited number of queue stat registers. It let an application
fold many queues onto a small set of counters. Since 25.11 queue statistics are
filled in directly by the ethdev layer indexed by queue id, so the mapping is no
longer needed; the functions were deprecated then by commit 2863cbd9ee6d.

This series finishes the job. The drivers that still implemented the op are
converted to report queue stats directly by queue id (bounded by
RTE_ETHDEV_QUEUE_STAT_CNTRS), and the op, the two public functions, their trace
points, and the documentation are removed from ethdev. The leftover per-driver
mapping tables, accessor macros, and init code go away with them.

This is an RFC against 26.11, where the ABI break from removing the two stable
symbols is expected. The Removed Items / ABI Changes release notes entry will be
added once the 26.11 notes file is opened.


Stephen Hemminger (7):
  net/virtio: remove unused queue stats mapping
  net/enic: remove queue_stats_mapping ethdev_op
  net/cnxk: remove queue stats mapping
  net/e1000: remove queue stats mapping
  net/ixgbe: remove queue stats mapping
  net/txgbe: remove queue stats mapping
  ethdev: remove support for queue stats mapping

 doc/guides/nics/features.rst           |  7 --
 doc/guides/rel_notes/deprecation.rst   |  6 --
 drivers/net/cnxk/cnxk_ethdev.c         |  1 -
 drivers/net/cnxk/cnxk_ethdev.h         |  6 --
 drivers/net/cnxk/cnxk_stats.c          | 76 ++++++++------------
 drivers/net/enic/enic_ethdev.c         | 11 ---
 drivers/net/intel/e1000/igc_ethdev.c   | 54 ++------------
 drivers/net/intel/e1000/igc_ethdev.h   |  2 -
 drivers/net/intel/ixgbe/ixgbe_ethdev.c | 97 --------------------------
 drivers/net/intel/ixgbe/ixgbe_ethdev.h |  9 ---
 drivers/net/txgbe/txgbe_ethdev.c       | 87 ++---------------------
 drivers/net/txgbe/txgbe_ethdev.h       | 13 ----
 drivers/net/virtio/virtio_ethdev.c     | 21 ------
 lib/ethdev/ethdev_driver.h             | 11 ---
 lib/ethdev/ethdev_trace.h              | 20 ------
 lib/ethdev/ethdev_trace_points.c       |  6 --
 lib/ethdev/rte_ethdev.c                | 62 ----------------
 lib/ethdev/rte_ethdev.h                | 45 ------------
 18 files changed, 45 insertions(+), 489 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 45+ messages in thread

* [RFC 1/7] net/virtio: remove unused queue stats mapping
  2026-05-30 16:09 [RFC 0/7] Complete removal of queue stats mapping Stephen Hemminger
@ 2026-05-30 16:09 ` Stephen Hemminger
  2026-05-30 16:09 ` [RFC 2/7] net/enic: remove queue_stats_mapping ethdev_op Stephen Hemminger
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-05-30 16:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Maxime Coquelin, Chenbo Xia

The queue_stats_mapping op in virtio looks like a vestiage
from when it was needed to get per queue stats. That hasn't
been true since 25.11 release.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/virtio/virtio_ethdev.c | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 9fd746b80f..0b2574bd02 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -90,12 +90,6 @@ static int virtio_intr_disable(struct rte_eth_dev *dev);
 static int virtio_get_monitor_addr(void *rx_queue,
 				struct rte_power_monitor_cond *pmc);
 
-static int virtio_dev_queue_stats_mapping_set(
-	struct rte_eth_dev *eth_dev,
-	uint16_t queue_id,
-	uint8_t stat_idx,
-	uint8_t is_rx);
-
 static void virtio_notify_peers(struct rte_eth_dev *dev);
 static void virtio_ack_link_announce(struct rte_eth_dev *dev);
 
@@ -672,8 +666,6 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.rss_hash_conf_get       = virtio_dev_rss_hash_conf_get,
 	.reta_update             = virtio_dev_rss_reta_update,
 	.reta_query              = virtio_dev_rss_reta_query,
-	/* collect stats per queue */
-	.queue_stats_mapping_set = virtio_dev_queue_stats_mapping_set,
 	.vlan_filter_set         = virtio_vlan_filter_set,
 	.mac_addr_add            = virtio_mac_addr_add,
 	.mac_addr_remove         = virtio_mac_addr_remove,
@@ -693,8 +685,6 @@ const struct eth_dev_ops virtio_user_secondary_eth_dev_ops = {
 	.xstats_get_names        = virtio_dev_xstats_get_names,
 	.stats_reset             = virtio_dev_stats_reset,
 	.xstats_reset            = virtio_dev_stats_reset,
-	/* collect stats per queue */
-	.queue_stats_mapping_set = virtio_dev_queue_stats_mapping_set,
 };
 
 static void
@@ -2823,16 +2813,5 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	return 0;
 }
 
-/*
- * It enables testpmd to collect per queue stats.
- */
-static int
-virtio_dev_queue_stats_mapping_set(__rte_unused struct rte_eth_dev *eth_dev,
-__rte_unused uint16_t queue_id, __rte_unused uint8_t stat_idx,
-__rte_unused uint8_t is_rx)
-{
-	return 0;
-}
-
 RTE_LOG_REGISTER_SUFFIX(virtio_logtype_init, init, NOTICE);
 RTE_LOG_REGISTER_SUFFIX(virtio_logtype_driver, driver, NOTICE);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [RFC 2/7] net/enic: remove queue_stats_mapping ethdev_op
  2026-05-30 16:09 [RFC 0/7] Complete removal of queue stats mapping Stephen Hemminger
  2026-05-30 16:09 ` [RFC 1/7] net/virtio: remove unused " Stephen Hemminger
@ 2026-05-30 16:09 ` Stephen Hemminger
  2026-05-30 16:09 ` [RFC 3/7] net/cnxk: remove queue stats mapping Stephen Hemminger
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-05-30 16:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, John Daley, Hyong Youb Kim

Better to just let compiler initialize fields to NULL since then
if fields change that driver doesn't use, the driver source
will not need to be changed.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/enic/enic_ethdev.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index a853a5047a..545edf12bd 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -1119,8 +1119,6 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.dev_configure        = enicpmd_dev_configure,
 	.dev_start            = enicpmd_dev_start,
 	.dev_stop             = enicpmd_dev_stop,
-	.dev_set_link_up      = NULL,
-	.dev_set_link_down    = NULL,
 	.dev_close            = enicpmd_dev_close,
 	.promiscuous_enable   = enicpmd_dev_promiscuous_enable,
 	.promiscuous_disable  = enicpmd_dev_promiscuous_disable,
@@ -1129,14 +1127,10 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.link_update          = enicpmd_dev_link_update,
 	.stats_get            = enicpmd_dev_stats_get,
 	.stats_reset          = enicpmd_dev_stats_reset,
-	.queue_stats_mapping_set = NULL,
 	.dev_infos_get        = enicpmd_dev_info_get,
 	.dev_supported_ptypes_get = enicpmd_dev_supported_ptypes_get,
 	.mtu_set              = enicpmd_mtu_set,
-	.vlan_filter_set      = NULL,
-	.vlan_tpid_set        = NULL,
 	.vlan_offload_set     = enicpmd_vlan_offload_set,
-	.vlan_strip_queue_set = NULL,
 	.rx_queue_start       = enicpmd_dev_rx_queue_start,
 	.rx_queue_stop        = enicpmd_dev_rx_queue_stop,
 	.tx_queue_start       = enicpmd_dev_tx_queue_start,
@@ -1151,11 +1145,6 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.txq_info_get         = enicpmd_dev_txq_info_get,
 	.rx_burst_mode_get    = enicpmd_dev_rx_burst_mode_get,
 	.tx_burst_mode_get    = enicpmd_dev_tx_burst_mode_get,
-	.dev_led_on           = NULL,
-	.dev_led_off          = NULL,
-	.flow_ctrl_get        = NULL,
-	.flow_ctrl_set        = NULL,
-	.priority_flow_ctrl_set = NULL,
 	.mac_addr_add         = enicpmd_add_mac_addr,
 	.mac_addr_remove      = enicpmd_remove_mac_addr,
 	.mac_addr_set         = enicpmd_set_mac_addr,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [RFC 3/7] net/cnxk: remove queue stats mapping
  2026-05-30 16:09 [RFC 0/7] Complete removal of queue stats mapping Stephen Hemminger
  2026-05-30 16:09 ` [RFC 1/7] net/virtio: remove unused " Stephen Hemminger
  2026-05-30 16:09 ` [RFC 2/7] net/enic: remove queue_stats_mapping ethdev_op Stephen Hemminger
@ 2026-05-30 16:09 ` Stephen Hemminger
  2026-05-30 16:09 ` [RFC 4/7] net/e1000: " Stephen Hemminger
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-05-30 16:09 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, Nithin Dabilpuram, Kiran Kumar K,
	Sunil Kumar Kori, Satha Rao, Harman Kalra

The queue stats mapping feature has been deprecated since 25.11.
Remove support in this driver for stats map.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/cnxk/cnxk_ethdev.c |  1 -
 drivers/net/cnxk/cnxk_ethdev.h |  6 ---
 drivers/net/cnxk/cnxk_stats.c  | 76 ++++++++++++++--------------------
 3 files changed, 31 insertions(+), 52 deletions(-)

diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 06d1c9b362..c8e7d70c2a 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -2104,7 +2104,6 @@ struct eth_dev_ops cnxk_eth_dev_ops = {
 	.rx_queue_intr_enable = cnxk_nix_rx_queue_intr_enable,
 	.rx_queue_intr_disable = cnxk_nix_rx_queue_intr_disable,
 	.pool_ops_supported = cnxk_nix_pool_ops_supported,
-	.queue_stats_mapping_set = cnxk_nix_queue_stats_mapping,
 	.stats_get = cnxk_nix_stats_get,
 	.stats_reset = cnxk_nix_stats_reset,
 	.xstats_get = cnxk_nix_xstats_get,
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index 8691acc642..d73a4ff3d3 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -416,10 +416,6 @@ struct cnxk_eth_dev {
 	/* LSO Tunnel format indices */
 	uint64_t lso_tun_fmt;
 
-	/* Per queue statistics counters */
-	uint32_t txq_stat_map[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-	uint32_t rxq_stat_map[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-
 	/* Security data */
 	struct cnxk_eth_dev_sec_inb inb;
 	struct cnxk_eth_dev_sec_outb outb;
@@ -687,8 +683,6 @@ void cnxk_eth_dev_link_status_get_cb(struct roc_nix *nix,
 void cnxk_eth_dev_q_err_cb(struct roc_nix *nix, void *data);
 int cnxk_nix_link_info_configure(struct rte_eth_dev *eth_dev);
 int cnxk_nix_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete);
-int cnxk_nix_queue_stats_mapping(struct rte_eth_dev *dev, uint16_t queue_id,
-				 uint8_t stat_idx, uint8_t is_rx);
 int cnxk_nix_stats_reset(struct rte_eth_dev *dev);
 int cnxk_nix_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		       struct eth_queue_stats *qstats);
diff --git a/drivers/net/cnxk/cnxk_stats.c b/drivers/net/cnxk/cnxk_stats.c
index d57659ef51..e5d29a78b3 100644
--- a/drivers/net/cnxk/cnxk_stats.c
+++ b/drivers/net/cnxk/cnxk_stats.c
@@ -14,7 +14,8 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
 	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
 	struct roc_nix *nix = &dev->nix;
 	struct roc_nix_stats nix_stats;
-	int rc = 0, i;
+	unsigned int i;
+	int rc = 0;
 
 	rc = roc_nix_stats_get(nix, &nix_stats);
 	if (rc)
@@ -33,31 +34,35 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
 	stats->ibytes = nix_stats.rx_octs;
 	stats->ierrors = nix_stats.rx_err;
 
-	if (qstats != NULL) {
-		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
-			struct roc_nix_stats_queue qstats_data;
-			uint16_t qidx;
-
-			if (dev->txq_stat_map[i] & (1U << 31)) {
-				qidx = dev->txq_stat_map[i] & 0xFFFF;
-				rc = roc_nix_stats_queue_get(nix, qidx, 0, &qstats_data);
-				if (rc)
-					goto exit;
-				qstats->q_opackets[i] = qstats_data.tx_pkts;
-				qstats->q_obytes[i] = qstats_data.tx_octs;
-				qstats->q_errors[i] = qstats_data.tx_drop_pkts;
-			}
-
-			if (dev->rxq_stat_map[i] & (1U << 31)) {
-				qidx = dev->rxq_stat_map[i] & 0xFFFF;
-				rc = roc_nix_stats_queue_get(nix, qidx, 1, &qstats_data);
-				if (rc)
-					goto exit;
-				qstats->q_ipackets[i] = qstats_data.rx_pkts;
-				qstats->q_ibytes[i] = qstats_data.rx_octs;
-				qstats->q_errors[i] += qstats_data.rx_drop_pkts;
-			}
-		}
+	if (qstats == NULL)
+		goto exit;
+
+	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+		struct roc_nix_stats_queue qstats_data;
+
+		if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+			break;
+
+		rc = roc_nix_stats_queue_get(nix, i, 0, &qstats_data);
+		if (rc)
+			goto exit;
+		qstats->q_opackets[i] = qstats_data.tx_pkts;
+		qstats->q_obytes[i] = qstats_data.tx_octs;
+		qstats->q_errors[i] = qstats_data.tx_drop_pkts;
+	}
+
+	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
+		struct roc_nix_stats_queue qstats_data;
+
+		if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+			break;
+
+		rc = roc_nix_stats_queue_get(nix, i, 1, &qstats_data);
+		if (rc)
+			goto exit;
+		qstats->q_ipackets[i] = qstats_data.rx_pkts;
+		qstats->q_ibytes[i] = qstats_data.rx_octs;
+		qstats->q_errors[i] += qstats_data.rx_drop_pkts;
 	}
 exit:
 	return rc;
@@ -71,25 +76,6 @@ cnxk_nix_stats_reset(struct rte_eth_dev *eth_dev)
 	return roc_nix_stats_reset(&dev->nix);
 }
 
-int
-cnxk_nix_queue_stats_mapping(struct rte_eth_dev *eth_dev, uint16_t queue_id,
-			     uint8_t stat_idx, uint8_t is_rx)
-{
-	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
-
-	if (is_rx) {
-		if (queue_id >= dev->nb_rxq)
-			return -EINVAL;
-		dev->rxq_stat_map[stat_idx] = ((1U << 31) | queue_id);
-	} else {
-		if (queue_id >= dev->nb_txq)
-			return -EINVAL;
-		dev->txq_stat_map[stat_idx] = ((1U << 31) | queue_id);
-	}
-
-	return 0;
-}
-
 int
 cnxk_nix_xstats_get(struct rte_eth_dev *eth_dev, struct rte_eth_xstat *xstats,
 		    unsigned int n)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [RFC 4/7] net/e1000: remove queue stats mapping
  2026-05-30 16:09 [RFC 0/7] Complete removal of queue stats mapping Stephen Hemminger
                   ` (2 preceding siblings ...)
  2026-05-30 16:09 ` [RFC 3/7] net/cnxk: remove queue stats mapping Stephen Hemminger
@ 2026-05-30 16:09 ` Stephen Hemminger
  2026-05-30 16:10 ` [RFC 5/7] net/ixgbe: " Stephen Hemminger
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-05-30 16:09 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Support for queue stats mapping has been deprecated since 25.11.
Remove support for this operation in the e1000 driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/intel/e1000/igc_ethdev.c | 54 ++++------------------------
 drivers/net/intel/e1000/igc_ethdev.h |  2 --
 2 files changed, 7 insertions(+), 49 deletions(-)

diff --git a/drivers/net/intel/e1000/igc_ethdev.c b/drivers/net/intel/e1000/igc_ethdev.c
index 727ea36c2b..891c810132 100644
--- a/drivers/net/intel/e1000/igc_ethdev.c
+++ b/drivers/net/intel/e1000/igc_ethdev.c
@@ -239,9 +239,7 @@ static int eth_igc_xstats_get_names_by_id(struct rte_eth_dev *dev,
 		const uint64_t *ids, struct rte_eth_xstat_name *xstats_names,
 		unsigned int limit);
 static int eth_igc_xstats_reset(struct rte_eth_dev *dev);
-static int
-eth_igc_queue_stats_mapping_set(struct rte_eth_dev *dev,
-	uint16_t queue_id, uint8_t stat_idx, uint8_t is_rx);
+
 static int
 eth_igc_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);
 static int
@@ -317,7 +315,6 @@ static const struct eth_dev_ops eth_igc_ops = {
 	.xstats_get_names	= eth_igc_xstats_get_names,
 	.stats_reset		= eth_igc_xstats_reset,
 	.xstats_reset		= eth_igc_xstats_reset,
-	.queue_stats_mapping_set = eth_igc_queue_stats_mapping_set,
 	.rx_queue_intr_enable	= eth_igc_rx_queue_intr_enable,
 	.rx_queue_intr_disable	= eth_igc_rx_queue_intr_disable,
 	.flow_ctrl_get		= eth_igc_flow_ctrl_get,
@@ -1362,7 +1359,7 @@ eth_igc_dev_init(struct rte_eth_dev *dev)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
 	struct e1000_hw *hw = IGC_DEV_PRIVATE_HW(dev);
-	int i, error = 0;
+	int error = 0;
 
 	PMD_INIT_FUNC_TRACE();
 	dev->dev_ops = &eth_igc_ops;
@@ -1493,12 +1490,6 @@ eth_igc_dev_init(struct rte_eth_dev *dev)
 	/* enable support intr */
 	igc_intr_other_enable(dev);
 
-	/* initiate queue status */
-	for (i = 0; i < IGC_QUEUE_PAIRS_NUM; i++) {
-		igc->txq_stats_map[i] = -1;
-		igc->rxq_stats_map[i] = -1;
-	}
-
 	igc_flow_init(dev);
 	igc_clear_all_filter(dev);
 	return 0;
@@ -2031,7 +2022,6 @@ static int
 eth_igc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats,
 		struct eth_queue_stats *qstats)
 {
-	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
 	struct e1000_hw *hw = IGC_DEV_PRIVATE_HW(dev);
 	struct e1000_hw_stats *stats = IGC_DEV_PRIVATE_STATS(dev);
 	struct igc_hw_queue_stats *queue_stats =
@@ -2070,19 +2060,11 @@ eth_igc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats,
 	/* Get per-queue statuses */
 	if (qstats) {
 		for (i = 0; i < IGC_QUEUE_PAIRS_NUM; i++) {
-			/* GET TX queue statuses */
-			int map_id = igc->txq_stats_map[i];
-			if (map_id >= 0) {
-				qstats->q_opackets[map_id] += queue_stats->pqgptc[i];
-				qstats->q_obytes[map_id] += queue_stats->pqgotc[i];
-			}
-			/* Get RX queue statuses */
-			map_id = igc->rxq_stats_map[i];
-			if (map_id >= 0) {
-				qstats->q_ipackets[map_id] += queue_stats->pqgprc[i];
-				qstats->q_ibytes[map_id] += queue_stats->pqgorc[i];
-				qstats->q_errors[map_id] += queue_stats->rqdpc[i];
-			}
+			qstats->q_opackets[i] += queue_stats->pqgptc[i];
+			qstats->q_obytes[i] += queue_stats->pqgotc[i];
+			qstats->q_ipackets[i] += queue_stats->pqgprc[i];
+			qstats->q_ibytes[i] += queue_stats->pqgorc[i];
+			qstats->q_errors[i] += queue_stats->rqdpc[i];
 		}
 	}
 
@@ -2231,28 +2213,6 @@ eth_igc_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 	}
 }
 
-static int
-eth_igc_queue_stats_mapping_set(struct rte_eth_dev *dev,
-		uint16_t queue_id, uint8_t stat_idx, uint8_t is_rx)
-{
-	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
-
-	/* check queue id is valid */
-	if (queue_id >= IGC_QUEUE_PAIRS_NUM) {
-		PMD_DRV_LOG(ERR, "queue id(%u) error, max is %u",
-			queue_id, IGC_QUEUE_PAIRS_NUM - 1);
-		return -EINVAL;
-	}
-
-	/* store the mapping status id */
-	if (is_rx)
-		igc->rxq_stats_map[queue_id] = stat_idx;
-	else
-		igc->txq_stats_map[queue_id] = stat_idx;
-
-	return 0;
-}
-
 static int
 eth_igc_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
diff --git a/drivers/net/intel/e1000/igc_ethdev.h b/drivers/net/intel/e1000/igc_ethdev.h
index 7fa7877adf..96ff520da7 100644
--- a/drivers/net/intel/e1000/igc_ethdev.h
+++ b/drivers/net/intel/e1000/igc_ethdev.h
@@ -227,8 +227,6 @@ struct igc_adapter {
 	struct e1000_hw		hw;
 	struct e1000_hw_stats	stats;
 	struct igc_hw_queue_stats queue_stats;
-	int16_t txq_stats_map[IGC_QUEUE_PAIRS_NUM];
-	int16_t rxq_stats_map[IGC_QUEUE_PAIRS_NUM];
 
 	struct igc_interrupt	intr;
 	struct igc_vfta	shadow_vfta;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [RFC 5/7] net/ixgbe: remove queue stats mapping
  2026-05-30 16:09 [RFC 0/7] Complete removal of queue stats mapping Stephen Hemminger
                   ` (3 preceding siblings ...)
  2026-05-30 16:09 ` [RFC 4/7] net/e1000: " Stephen Hemminger
@ 2026-05-30 16:10 ` Stephen Hemminger
  2026-05-30 16:10 ` [RFC 6/7] net/txgbe: " Stephen Hemminger
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-05-30 16:10 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Anatoly Burakov, Vladimir Medvedkin

The support for queue_stats_map has been deprecated since 25.11.
Remove support for queue mapping in ixgbe driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/intel/ixgbe/ixgbe_ethdev.c | 97 --------------------------
 drivers/net/intel/ixgbe/ixgbe_ethdev.h |  9 ---
 2 files changed, 106 deletions(-)

diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.c b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
index 9dc015dfff..a7d995a768 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
@@ -182,10 +182,6 @@ static int ixgbe_dev_xstats_get_names_by_id(
 	const uint64_t *ids,
 	struct rte_eth_xstat_name *xstats_names,
 	unsigned int limit);
-static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
-					     uint16_t queue_id,
-					     uint8_t stat_idx,
-					     uint8_t is_rx);
 static int ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
 				 size_t fw_size);
 static int ixgbe_dev_info_get(struct rte_eth_dev *dev,
@@ -511,7 +507,6 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.xstats_reset         = ixgbe_dev_xstats_reset,
 	.xstats_get_names     = ixgbe_dev_xstats_get_names,
 	.xstats_get_names_by_id = ixgbe_dev_xstats_get_names_by_id,
-	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
 	.fw_version_get       = ixgbe_fw_version_get,
 	.dev_infos_get        = ixgbe_dev_info_get,
 	.dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
@@ -886,96 +881,6 @@ ixgbe_reset_qstat_mappings(struct ixgbe_hw *hw)
 	}
 }
 
-
-static int
-ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
-				  uint16_t queue_id,
-				  uint8_t stat_idx,
-				  uint8_t is_rx)
-{
-#define QSM_REG_NB_BITS_PER_QMAP_FIELD 8
-#define NB_QMAP_FIELDS_PER_QSM_REG 4
-#define QMAP_FIELD_RESERVED_BITS_MASK 0x0f
-
-	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
-	struct ixgbe_stat_mapping_registers *stat_mappings =
-		IXGBE_DEV_PRIVATE_TO_STAT_MAPPINGS(eth_dev->data->dev_private);
-	uint32_t qsmr_mask = 0;
-	uint32_t clearing_mask = QMAP_FIELD_RESERVED_BITS_MASK;
-	uint32_t q_map;
-	uint8_t n, offset;
-
-	if ((hw->mac.type != ixgbe_mac_82599EB) &&
-		(hw->mac.type != ixgbe_mac_X540) &&
-		(hw->mac.type != ixgbe_mac_X550) &&
-		(hw->mac.type != ixgbe_mac_X550EM_x) &&
-		(hw->mac.type != ixgbe_mac_X550EM_a) &&
-		(hw->mac.type != ixgbe_mac_E610))
-		return -ENOSYS;
-
-	PMD_INIT_LOG(DEBUG, "Setting port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-
-	n = (uint8_t)(queue_id / NB_QMAP_FIELDS_PER_QSM_REG);
-	if (n >= IXGBE_NB_STAT_MAPPING_REGS) {
-		PMD_INIT_LOG(ERR, "Nb of stat mapping registers exceeded");
-		return -EIO;
-	}
-	offset = (uint8_t)(queue_id % NB_QMAP_FIELDS_PER_QSM_REG);
-
-	/* Now clear any previous stat_idx set */
-	clearing_mask <<= (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] &= ~clearing_mask;
-	else
-		stat_mappings->rqsmr[n] &= ~clearing_mask;
-
-	q_map = (uint32_t)stat_idx;
-	q_map &= QMAP_FIELD_RESERVED_BITS_MASK;
-	qsmr_mask = q_map << (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] |= qsmr_mask;
-	else
-		stat_mappings->rqsmr[n] |= qsmr_mask;
-
-	PMD_INIT_LOG(DEBUG, "Set port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-	PMD_INIT_LOG(DEBUG, "%s[%d] = 0x%08x", is_rx ? "RQSMR" : "TQSM", n,
-		     is_rx ? stat_mappings->rqsmr[n] : stat_mappings->tqsm[n]);
-
-	/* Now write the mapping in the appropriate register */
-	if (is_rx) {
-		PMD_INIT_LOG(DEBUG, "Write 0x%x to RX IXGBE stat mapping reg:%d",
-			     stat_mappings->rqsmr[n], n);
-		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(n), stat_mappings->rqsmr[n]);
-	} else {
-		PMD_INIT_LOG(DEBUG, "Write 0x%x to TX IXGBE stat mapping reg:%d",
-			     stat_mappings->tqsm[n], n);
-		IXGBE_WRITE_REG(hw, IXGBE_TQSM(n), stat_mappings->tqsm[n]);
-	}
-	return 0;
-}
-
-static void
-ixgbe_restore_statistics_mapping(struct rte_eth_dev *dev)
-{
-	struct ixgbe_stat_mapping_registers *stat_mappings =
-		IXGBE_DEV_PRIVATE_TO_STAT_MAPPINGS(dev->data->dev_private);
-	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	int i;
-
-	/* write whatever was in stat mapping table to the NIC */
-	for (i = 0; i < IXGBE_NB_STAT_MAPPING_REGS; i++) {
-		/* rx */
-		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), stat_mappings->rqsmr[i]);
-
-		/* tx */
-		IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), stat_mappings->tqsm[i]);
-	}
-}
-
 static void
 ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config)
 {
@@ -2742,8 +2647,6 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 						RTE_BIT64(idx));
 	}
 
-	ixgbe_restore_statistics_mapping(dev);
-
 	err = ixgbe_flow_ctrl_enable(dev, hw);
 	if (err < 0) {
 		PMD_INIT_LOG(ERR, "enable flow ctrl err");
diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.h b/drivers/net/intel/ixgbe/ixgbe_ethdev.h
index 5d3243cb4d..ba826b6d8d 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.h
@@ -216,11 +216,6 @@ struct ixgbe_interrupt {
 	uint32_t mask_original;
 };
 
-struct ixgbe_stat_mapping_registers {
-	uint32_t tqsm[IXGBE_NB_STAT_MAPPING_REGS];
-	uint32_t rqsmr[IXGBE_NB_STAT_MAPPING_REGS];
-};
-
 struct ixgbe_vfta {
 	uint32_t vfta[IXGBE_VFTA_SIZE];
 };
@@ -471,7 +466,6 @@ struct ixgbe_adapter {
 	struct rte_eth_fdir_conf    fdir_conf;
 	struct ixgbe_hw_fdir_info   fdir;
 	struct ixgbe_interrupt      intr;
-	struct ixgbe_stat_mapping_registers stat_mappings;
 	struct ixgbe_vfta           shadow_vfta;
 	struct ixgbe_hwstrip		hwstrip;
 	struct ixgbe_dcb_config     dcb_config;
@@ -546,9 +540,6 @@ uint16_t ixgbe_vf_representor_tx_burst(void *tx_queue, struct rte_mbuf **tx_pkts
 #define IXGBE_DEV_PRIVATE_TO_FDIR_INFO(adapter) \
 	(&((struct ixgbe_adapter *)adapter)->fdir)
 
-#define IXGBE_DEV_PRIVATE_TO_STAT_MAPPINGS(adapter) \
-	(&((struct ixgbe_adapter *)adapter)->stat_mappings)
-
 #define IXGBE_DEV_PRIVATE_TO_VFTA(adapter) \
 	(&((struct ixgbe_adapter *)adapter)->shadow_vfta)
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [RFC 6/7] net/txgbe: remove queue stats mapping
  2026-05-30 16:09 [RFC 0/7] Complete removal of queue stats mapping Stephen Hemminger
                   ` (4 preceding siblings ...)
  2026-05-30 16:10 ` [RFC 5/7] net/ixgbe: " Stephen Hemminger
@ 2026-05-30 16:10 ` Stephen Hemminger
  2026-05-30 16:10 ` [RFC 7/7] ethdev: remove support for " Stephen Hemminger
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-05-30 16:10 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Jiawen Wu, Zaiyu Wang

Support for queue stats mapping has been deprecated since 25.11.
Remove support for this ethdev op in txgbe driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/txgbe/txgbe_ethdev.c | 87 +++-----------------------------
 drivers/net/txgbe/txgbe_ethdev.h | 13 -----
 2 files changed, 7 insertions(+), 93 deletions(-)

diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 5d360f8305..3886a2cbf4 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -391,60 +391,6 @@ txgbe_disable_intr(struct txgbe_hw *hw)
 	txgbe_flush(hw);
 }
 
-static int
-txgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
-				  uint16_t queue_id,
-				  uint8_t stat_idx,
-				  uint8_t is_rx)
-{
-	struct txgbe_hw *hw = TXGBE_DEV_HW(eth_dev);
-	struct txgbe_stat_mappings *stat_mappings =
-		TXGBE_DEV_STAT_MAPPINGS(eth_dev);
-	uint32_t qsmr_mask = 0;
-	uint32_t clearing_mask = QMAP_FIELD_RESERVED_BITS_MASK;
-	uint32_t q_map;
-	uint8_t n, offset;
-
-	if (!txgbe_is_pf(hw))
-		return -ENOSYS;
-
-	if (stat_idx & ~QMAP_FIELD_RESERVED_BITS_MASK)
-		return -EIO;
-
-	PMD_INIT_LOG(DEBUG, "Setting port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-
-	n = (uint8_t)(queue_id / NB_QMAP_FIELDS_PER_QSM_REG);
-	if (n >= TXGBE_NB_STAT_MAPPING) {
-		PMD_INIT_LOG(ERR, "Nb of stat mapping registers exceeded");
-		return -EIO;
-	}
-	offset = (uint8_t)(queue_id % NB_QMAP_FIELDS_PER_QSM_REG);
-
-	/* Now clear any previous stat_idx set */
-	clearing_mask <<= (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] &= ~clearing_mask;
-	else
-		stat_mappings->rqsm[n] &= ~clearing_mask;
-
-	q_map = (uint32_t)stat_idx;
-	q_map &= QMAP_FIELD_RESERVED_BITS_MASK;
-	qsmr_mask = q_map << (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] |= qsmr_mask;
-	else
-		stat_mappings->rqsm[n] |= qsmr_mask;
-
-	PMD_INIT_LOG(DEBUG, "Set port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-	PMD_INIT_LOG(DEBUG, "%s[%d] = 0x%08x", is_rx ? "RQSMR" : "TQSM", n,
-		     is_rx ? stat_mappings->rqsm[n] : stat_mappings->tqsm[n]);
-	return 0;
-}
-
 static void
 txgbe_dcb_init(struct txgbe_hw *hw, struct txgbe_dcb_config *dcb_config)
 {
@@ -2457,10 +2403,8 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 {
 	struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
 	struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
-	struct txgbe_stat_mappings *stat_mappings =
-			TXGBE_DEV_STAT_MAPPINGS(dev);
 	struct txgbe_tx_queue *txq;
-	uint32_t i, j;
+	unsigned int i;
 
 	txgbe_read_stats_registers(hw, hw_stats);
 
@@ -2474,29 +2418,13 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	stats->obytes = hw_stats->tx_bytes;
 
 	if (qstats != NULL) {
-		memset(&qstats->q_ipackets, 0, sizeof(qstats->q_ipackets));
-		memset(&qstats->q_opackets, 0, sizeof(qstats->q_opackets));
-		memset(&qstats->q_ibytes, 0, sizeof(qstats->q_ibytes));
-		memset(&qstats->q_obytes, 0, sizeof(qstats->q_obytes));
-		memset(&qstats->q_errors, 0, sizeof(qstats->q_errors));
 		for (i = 0; i < TXGBE_MAX_QP; i++) {
-			uint32_t n = i / NB_QMAP_FIELDS_PER_QSM_REG;
-			uint32_t offset = (i % NB_QMAP_FIELDS_PER_QSM_REG) * 8;
-			uint32_t q_map;
-
-			q_map = (stat_mappings->rqsm[n] >> offset)
-					& QMAP_FIELD_RESERVED_BITS_MASK;
-			j = (q_map < RTE_ETHDEV_QUEUE_STAT_CNTRS
-			     ? q_map : q_map % RTE_ETHDEV_QUEUE_STAT_CNTRS);
-			qstats->q_ipackets[j] += hw_stats->qp[i].rx_qp_packets;
-			qstats->q_ibytes[j] += hw_stats->qp[i].rx_qp_bytes;
-
-			q_map = (stat_mappings->tqsm[n] >> offset)
-					& QMAP_FIELD_RESERVED_BITS_MASK;
-			j = (q_map < RTE_ETHDEV_QUEUE_STAT_CNTRS
-			     ? q_map : q_map % RTE_ETHDEV_QUEUE_STAT_CNTRS);
-			qstats->q_opackets[j] += hw_stats->qp[i].tx_qp_packets;
-			qstats->q_obytes[j] += hw_stats->qp[i].tx_qp_bytes;
+			if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+				break;
+			qstats->q_ipackets[i] += hw_stats->qp[i].rx_qp_packets;
+			qstats->q_ibytes[i] += hw_stats->qp[i].rx_qp_bytes;
+			qstats->q_opackets[i] += hw_stats->qp[i].tx_qp_packets;
+			qstats->q_obytes[i] += hw_stats->qp[i].tx_qp_bytes;
 		}
 	}
 
@@ -5987,7 +5915,6 @@ static const struct eth_dev_ops txgbe_eth_dev_ops = {
 	.xstats_reset               = txgbe_dev_xstats_reset,
 	.xstats_get_names           = txgbe_dev_xstats_get_names,
 	.xstats_get_names_by_id     = txgbe_dev_xstats_get_names_by_id,
-	.queue_stats_mapping_set    = txgbe_dev_queue_stats_mapping_set,
 	.fw_version_get             = txgbe_fw_version_get,
 	.dev_supported_ptypes_get   = txgbe_dev_supported_ptypes_get,
 	.mtu_set                    = txgbe_dev_mtu_set,
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index 189fbac541..ac977dfc02 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -153,15 +153,6 @@ struct txgbe_interrupt {
 	uint64_t mask_orig; /* save mask during delayed handler */
 };
 
-#define TXGBE_NB_STAT_MAPPING  32
-#define QSM_REG_NB_BITS_PER_QMAP_FIELD 8
-#define NB_QMAP_FIELDS_PER_QSM_REG 4
-#define QMAP_FIELD_RESERVED_BITS_MASK 0x0f
-struct txgbe_stat_mappings {
-	uint32_t tqsm[TXGBE_NB_STAT_MAPPING];
-	uint32_t rqsm[TXGBE_NB_STAT_MAPPING];
-};
-
 struct txgbe_vfta {
 	uint32_t vfta[TXGBE_VFTA_SIZE];
 };
@@ -355,7 +346,6 @@ struct txgbe_adapter {
 	struct rte_eth_fdir_conf    fdir_conf;
 	struct txgbe_hw_fdir_info   fdir;
 	struct txgbe_interrupt      intr;
-	struct txgbe_stat_mappings  stat_mappings;
 	struct txgbe_vfta           shadow_vfta;
 	struct txgbe_hwstrip        hwstrip;
 	struct txgbe_dcb_config     dcb_config;
@@ -398,9 +388,6 @@ struct txgbe_adapter {
 #define TXGBE_DEV_FDIR(dev) \
 	(&((struct txgbe_adapter *)(dev)->data->dev_private)->fdir)
 
-#define TXGBE_DEV_STAT_MAPPINGS(dev) \
-	(&((struct txgbe_adapter *)(dev)->data->dev_private)->stat_mappings)
-
 #define TXGBE_DEV_VFTA(dev) \
 	(&((struct txgbe_adapter *)(dev)->data->dev_private)->shadow_vfta)
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [RFC 7/7] ethdev: remove support for queue stats mapping
  2026-05-30 16:09 [RFC 0/7] Complete removal of queue stats mapping Stephen Hemminger
                   ` (5 preceding siblings ...)
  2026-05-30 16:10 ` [RFC 6/7] net/txgbe: " Stephen Hemminger
@ 2026-05-30 16:10 ` Stephen Hemminger
  2026-06-01  1:56   ` fengchengwen
  2026-06-01  8:45   ` Andrew Rybchenko
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
  8 siblings, 2 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-05-30 16:10 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Thomas Monjalon, Andrew Rybchenko

The support for queue stats mapping has since 25.11 release
by commit 2863cbd9ee6d ("ethdev: deprecate queue stats mapping functions")

This patch completes final removal from ethdev and documentation.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 doc/guides/nics/features.rst         |  7 ----
 doc/guides/rel_notes/deprecation.rst |  6 ---
 lib/ethdev/ethdev_driver.h           | 11 -----
 lib/ethdev/ethdev_trace.h            | 20 ---------
 lib/ethdev/ethdev_trace_points.c     |  6 ---
 lib/ethdev/rte_ethdev.c              | 62 ----------------------------
 lib/ethdev/rte_ethdev.h              | 45 --------------------
 7 files changed, 157 deletions(-)

diff --git a/doc/guides/nics/features.rst b/doc/guides/nics/features.rst
index a075c057ec..0d3476e850 100644
--- a/doc/guides/nics/features.rst
+++ b/doc/guides/nics/features.rst
@@ -748,13 +748,6 @@ If driver does not support this feature the per queue stats will be zero.
 * **[implements] eth_dev_ops**: ``stats_get``, ``stats_reset``.
 * **[related]    API**: ``rte_eth_stats_get``, ``rte_eth_stats_reset()``.
 
-May also support configuring per-queue stat counter mapping.
-Used by some drivers to workaround HW limitations.
-
-* **[implements] eth_dev_ops**: ``queue_stats_mapping_set``.
-* **[related]    API**: ``rte_eth_dev_set_rx_queue_stats_mapping()``,
-  ``rte_eth_dev_set_tx_queue_stats_mapping()``.
-
 
 .. _nic_features_extended_stats:
 
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 17f90a6352..38702b838e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -78,12 +78,6 @@ Deprecation Notices
   and the header struct ``rte_vxlan_gpe_hdr`` with the macro ``RTE_ETHER_VXLAN_GPE_HLEN``
   will be removed in DPDK 25.11.
 
-* ethdev: The queue stats mapping functions
-  ``rte_eth_dev_set_tx_queue_stats_mapping`` and ``rte_eth_dev_set_rx_queue_stats_mapping``
-  are deprecated and will be removed in a future release.
-  Following the removal of queue statistics from the main ethdev statistics structure,
-  these functions are no longer needed.
-
 * ethdev: The flow API matching pattern structures, ``struct rte_flow_item_*``,
   should start with relevant protocol header structure from lib/net/.
   The individual protocol header fields and the protocol header struct
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index 0f336f9567..0477579cc3 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -567,15 +567,6 @@ typedef int (*eth_xstats_disable_counter_t)(struct rte_eth_dev *dev, uint64_t id
 /** @internal Query the state of an xstat the can be enabled and disabled in runtime. */
 typedef int (*eth_xstats_query_state_t)(struct rte_eth_dev *dev, uint64_t id);
 
-/**
- * @internal
- * Set a queue statistics mapping for a Tx/Rx queue of an Ethernet device.
- */
-typedef int (*eth_queue_stats_mapping_set_t)(struct rte_eth_dev *dev,
-					     uint16_t queue_id,
-					     uint8_t stat_idx,
-					     uint8_t is_rx);
-
 /** @internal Get specific information of an Ethernet device. */
 typedef int (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				   struct rte_eth_dev_info *dev_info);
@@ -1454,8 +1445,6 @@ struct eth_dev_ops {
 	eth_xstats_reset_t         xstats_reset;
 	/** Get names of extended statistics */
 	eth_xstats_get_names_t     xstats_get_names;
-	/** Configure per queue stat counter mapping */
-	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info */
 	/** Retrieve Rx queue information */
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index 6554cc1a21..6f1804a765 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -310,26 +310,6 @@ RTE_TRACE_POINT(
 	rte_trace_point_emit_int(ret);
 )
 
-RTE_TRACE_POINT(
-	rte_ethdev_trace_set_rx_queue_stats_mapping,
-	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t rx_queue_id,
-		uint8_t stat_idx, int ret),
-	rte_trace_point_emit_u16(port_id);
-	rte_trace_point_emit_u16(rx_queue_id);
-	rte_trace_point_emit_u8(stat_idx);
-	rte_trace_point_emit_int(ret);
-)
-
-RTE_TRACE_POINT(
-	rte_ethdev_trace_set_tx_queue_stats_mapping,
-	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t tx_queue_id,
-		uint8_t stat_idx, int ret),
-	rte_trace_point_emit_u16(port_id);
-	rte_trace_point_emit_u16(tx_queue_id);
-	rte_trace_point_emit_u8(stat_idx);
-	rte_trace_point_emit_int(ret);
-)
-
 RTE_TRACE_POINT(
 	rte_ethdev_trace_fw_version_get,
 	RTE_TRACE_POINT_ARGS(uint16_t port_id, const char *fw_version,
diff --git a/lib/ethdev/ethdev_trace_points.c b/lib/ethdev/ethdev_trace_points.c
index 0a28378a56..b0644ea489 100644
--- a/lib/ethdev/ethdev_trace_points.c
+++ b/lib/ethdev/ethdev_trace_points.c
@@ -230,12 +230,6 @@ RTE_TRACE_POINT_REGISTER(rte_eth_trace_xstats_get,
 RTE_TRACE_POINT_REGISTER(rte_eth_trace_xstats_reset,
 	lib.ethdev.xstats_reset)
 
-RTE_TRACE_POINT_REGISTER(rte_ethdev_trace_set_tx_queue_stats_mapping,
-	lib.ethdev.set_tx_queue_stats_mapping)
-
-RTE_TRACE_POINT_REGISTER(rte_ethdev_trace_set_rx_queue_stats_mapping,
-	lib.ethdev.set_rx_queue_stats_mapping)
-
 RTE_TRACE_POINT_REGISTER(rte_ethdev_trace_fw_version_get,
 	lib.ethdev.fw_version_get)
 
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index d0273e3f7b..e9bd5ba473 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -160,11 +160,6 @@ static const struct {
 	{RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"},
 };
 
-enum {
-	STAT_QMAP_TX = 0,
-	STAT_QMAP_RX
-};
-
 static const struct {
 	enum rte_eth_hash_function algo;
 	const char *name;
@@ -3997,63 +3992,6 @@ rte_eth_xstats_query_state(uint16_t port_id, uint64_t id)
 	return -ENOTSUP;
 }
 
-static int
-eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id,
-		uint8_t stat_idx, uint8_t is_rx)
-{
-	struct rte_eth_dev *dev;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	dev = &rte_eth_devices[port_id];
-
-	if (is_rx && (queue_id >= dev->data->nb_rx_queues))
-		return -EINVAL;
-
-	if (!is_rx && (queue_id >= dev->data->nb_tx_queues))
-		return -EINVAL;
-
-	if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
-		return -EINVAL;
-
-	if (dev->dev_ops->queue_stats_mapping_set == NULL)
-		return -ENOTSUP;
-	return dev->dev_ops->queue_stats_mapping_set(dev, queue_id, stat_idx, is_rx);
-}
-
-RTE_EXPORT_SYMBOL(rte_eth_dev_set_tx_queue_stats_mapping)
-int
-rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id,
-		uint8_t stat_idx)
-{
-	int ret;
-
-	ret = eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
-						tx_queue_id,
-						stat_idx, STAT_QMAP_TX));
-
-	rte_ethdev_trace_set_tx_queue_stats_mapping(port_id, tx_queue_id,
-						    stat_idx, ret);
-
-	return ret;
-}
-
-RTE_EXPORT_SYMBOL(rte_eth_dev_set_rx_queue_stats_mapping)
-int
-rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id,
-		uint8_t stat_idx)
-{
-	int ret;
-
-	ret = eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
-						rx_queue_id,
-						stat_idx, STAT_QMAP_RX));
-
-	rte_ethdev_trace_set_rx_queue_stats_mapping(port_id, rx_queue_id,
-						    stat_idx, ret);
-
-	return ret;
-}
-
 RTE_EXPORT_SYMBOL(rte_eth_dev_fw_version_get)
 int
 rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 3f4d2438e4..e91eada38c 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -3478,51 +3478,6 @@ int rte_eth_xstats_query_state(uint16_t port_id, uint64_t id);
  */
 int rte_eth_xstats_reset(uint16_t port_id);
 
-/**
- *  Set a mapping for the specified transmit queue to the specified per-queue
- *  statistics counter.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param tx_queue_id
- *   The index of the transmit queue for which a queue stats mapping is required.
- *   The value must be in the range [0, nb_tx_queue - 1] previously supplied
- *   to rte_eth_dev_configure().
- * @param stat_idx
- *   The per-queue packet statistics functionality number that the transmit
- *   queue is to be assigned.
- *   The value must be in the range [0, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1].
- *   Max RTE_ETHDEV_QUEUE_STAT_CNTRS being 256.
- * @return
- *   Zero if successful. Non-zero otherwise.
- */
-__rte_deprecated
-int rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id,
-		uint16_t tx_queue_id, uint8_t stat_idx);
-
-/**
- *  Set a mapping for the specified receive queue to the specified per-queue
- *  statistics counter.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param rx_queue_id
- *   The index of the receive queue for which a queue stats mapping is required.
- *   The value must be in the range [0, nb_rx_queue - 1] previously supplied
- *   to rte_eth_dev_configure().
- * @param stat_idx
- *   The per-queue packet statistics functionality number that the receive
- *   queue is to be assigned.
- *   The value must be in the range [0, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1].
- *   Max RTE_ETHDEV_QUEUE_STAT_CNTRS being 256.
- * @return
- *   Zero if successful. Non-zero otherwise.
- */
-__rte_deprecated
-int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
-					   uint16_t rx_queue_id,
-					   uint8_t stat_idx);
-
 /**
  * Retrieve the Ethernet address of an Ethernet device.
  *
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [RFC 7/7] ethdev: remove support for queue stats mapping
  2026-05-30 16:10 ` [RFC 7/7] ethdev: remove support for " Stephen Hemminger
@ 2026-06-01  1:56   ` fengchengwen
  2026-06-01  8:45   ` Andrew Rybchenko
  1 sibling, 0 replies; 45+ messages in thread
From: fengchengwen @ 2026-06-01  1:56 UTC (permalink / raw)
  To: Stephen Hemminger, dev; +Cc: Thomas Monjalon, Andrew Rybchenko

Acked-by: Chengwen Feng <fengchengwen@huawei.com>

On 5/31/2026 12:10 AM, Stephen Hemminger wrote:
> The support for queue stats mapping has since 25.11 release
> by commit 2863cbd9ee6d ("ethdev: deprecate queue stats mapping functions")
> 
> This patch completes final removal from ethdev and documentation.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [RFC 7/7] ethdev: remove support for queue stats mapping
  2026-05-30 16:10 ` [RFC 7/7] ethdev: remove support for " Stephen Hemminger
  2026-06-01  1:56   ` fengchengwen
@ 2026-06-01  8:45   ` Andrew Rybchenko
  1 sibling, 0 replies; 45+ messages in thread
From: Andrew Rybchenko @ 2026-06-01  8:45 UTC (permalink / raw)
  To: Stephen Hemminger, dev; +Cc: Thomas Monjalon

On 5/30/26 7:10 PM, Stephen Hemminger wrote:
> The support for queue stats mapping has since 25.11 release
> by commit 2863cbd9ee6d ("ethdev: deprecate queue stats mapping functions")
> 
> This patch completes final removal from ethdev and documentation.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>


^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH v2 0/9] Complete removal of queue stats mapping
  2026-05-30 16:09 [RFC 0/7] Complete removal of queue stats mapping Stephen Hemminger
                   ` (6 preceding siblings ...)
  2026-05-30 16:10 ` [RFC 7/7] ethdev: remove support for " Stephen Hemminger
@ 2026-07-23 20:28 ` Stephen Hemminger
  2026-07-23 20:28   ` [PATCH v2 1/9] net/virtio: remove unused " Stephen Hemminger
                     ` (10 more replies)
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
  8 siblings, 11 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-23 20:28 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

The per-queue stats mapping mechanism (rte_eth_dev_set_{rx,tx}_queue_stats_mapping
and the queue_stats_mapping_set ethdev op) was a workaround for hardware that
could only expose a limited number of queue stat registers. It let an application
fold many queues onto a small set of counters. Since 25.11 queue statistics are
filled in directly by the ethdev layer indexed by queue id, so the mapping is no
longer needed; the functions were deprecated then by commit 2863cbd9ee6d.

This series finishes the job. The drivers that still implemented the op are
converted to report queue stats directly by queue id (bounded by
RTE_ETHDEV_QUEUE_STAT_CNTRS), and the op, the two public functions, their trace
points, and the documentation are removed from ethdev. The leftover per-driver
mapping tables, accessor macros, and init code go away with them.

Also, found some leftover bits from the earlier removal.

Stephen Hemminger (9):
  net/virtio: remove unused queue stats mapping
  app/testpmd: remove unused function prototype
  net/enic: remove unneeded ops initialization
  net/cnxk: remove queue stats mapping
  net/e1000: remove queue stats mapping
  net/ixgbe: remove queue stats mapping
  net/txgbe: remove queue stats mapping
  net/sxe2: remove queue stats mapping
  ethdev: remove support for queue stats mapping

 app/test-pmd/cmdline.c                 |  6 --
 app/test-pmd/testpmd.h                 |  2 -
 doc/guides/nics/features.rst           |  7 --
 doc/guides/rel_notes/deprecation.rst   |  6 --
 doc/guides/rel_notes/release_26_11.rst |  5 ++
 drivers/net/cnxk/cnxk_ethdev.c         |  1 -
 drivers/net/cnxk/cnxk_ethdev.h         |  6 --
 drivers/net/cnxk/cnxk_stats.c          | 76 ++++++++------------
 drivers/net/enic/enic_ethdev.c         | 11 ---
 drivers/net/intel/e1000/igc_ethdev.c   | 54 ++------------
 drivers/net/intel/e1000/igc_ethdev.h   |  2 -
 drivers/net/intel/ixgbe/ixgbe_ethdev.c | 97 -------------------------
 drivers/net/intel/ixgbe/ixgbe_ethdev.h |  9 ---
 drivers/net/sxe2/sxe2_cmd_chnl.c       | 99 --------------------------
 drivers/net/sxe2/sxe2_cmd_chnl.h       | 10 ---
 drivers/net/sxe2/sxe2_ethdev.c         |  5 --
 drivers/net/sxe2/sxe2_stats.c          | 76 +-------------------
 drivers/net/sxe2/sxe2_stats.h          |  5 --
 drivers/net/txgbe/txgbe_ethdev.c       | 87 ++--------------------
 drivers/net/txgbe/txgbe_ethdev.h       | 13 ----
 drivers/net/virtio/virtio_ethdev.c     | 21 ------
 lib/ethdev/ethdev_driver.h             | 11 ---
 lib/ethdev/ethdev_trace.h              | 20 ------
 lib/ethdev/ethdev_trace_points.c       |  6 --
 lib/ethdev/rte_ethdev.c                | 62 ----------------
 lib/ethdev/rte_ethdev.h                | 45 ------------
 26 files changed, 53 insertions(+), 689 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH v2 1/9] net/virtio: remove unused queue stats mapping
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
@ 2026-07-23 20:28   ` Stephen Hemminger
  2026-07-23 20:28   ` [PATCH v2 2/9] app/testpmd: remove unused function prototype Stephen Hemminger
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-23 20:28 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Maxime Coquelin, Chenbo Xia

The queue_stats_mapping op in virtio looks like a vestige
from when it was needed to get per queue stats. That hasn't
been true since 25.11 release.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/virtio/virtio_ethdev.c | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 9fd746b80f..0b2574bd02 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -90,12 +90,6 @@ static int virtio_intr_disable(struct rte_eth_dev *dev);
 static int virtio_get_monitor_addr(void *rx_queue,
 				struct rte_power_monitor_cond *pmc);
 
-static int virtio_dev_queue_stats_mapping_set(
-	struct rte_eth_dev *eth_dev,
-	uint16_t queue_id,
-	uint8_t stat_idx,
-	uint8_t is_rx);
-
 static void virtio_notify_peers(struct rte_eth_dev *dev);
 static void virtio_ack_link_announce(struct rte_eth_dev *dev);
 
@@ -672,8 +666,6 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.rss_hash_conf_get       = virtio_dev_rss_hash_conf_get,
 	.reta_update             = virtio_dev_rss_reta_update,
 	.reta_query              = virtio_dev_rss_reta_query,
-	/* collect stats per queue */
-	.queue_stats_mapping_set = virtio_dev_queue_stats_mapping_set,
 	.vlan_filter_set         = virtio_vlan_filter_set,
 	.mac_addr_add            = virtio_mac_addr_add,
 	.mac_addr_remove         = virtio_mac_addr_remove,
@@ -693,8 +685,6 @@ const struct eth_dev_ops virtio_user_secondary_eth_dev_ops = {
 	.xstats_get_names        = virtio_dev_xstats_get_names,
 	.stats_reset             = virtio_dev_stats_reset,
 	.xstats_reset            = virtio_dev_stats_reset,
-	/* collect stats per queue */
-	.queue_stats_mapping_set = virtio_dev_queue_stats_mapping_set,
 };
 
 static void
@@ -2823,16 +2813,5 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	return 0;
 }
 
-/*
- * It enables testpmd to collect per queue stats.
- */
-static int
-virtio_dev_queue_stats_mapping_set(__rte_unused struct rte_eth_dev *eth_dev,
-__rte_unused uint16_t queue_id, __rte_unused uint8_t stat_idx,
-__rte_unused uint8_t is_rx)
-{
-	return 0;
-}
-
 RTE_LOG_REGISTER_SUFFIX(virtio_logtype_init, init, NOTICE);
 RTE_LOG_REGISTER_SUFFIX(virtio_logtype_driver, driver, NOTICE);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v2 2/9] app/testpmd: remove unused function prototype
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
  2026-07-23 20:28   ` [PATCH v2 1/9] net/virtio: remove unused " Stephen Hemminger
@ 2026-07-23 20:28   ` Stephen Hemminger
  2026-07-23 20:28   ` [PATCH v2 3/9] net/enic: remove unneeded ops initialization Stephen Hemminger
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-23 20:28 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, stable, Aman Singh, Bruce Richardson

The function set_qmap was removed in 25.11 release but
the prototype was still there.

Also, remove leftover help text.

Fixes: 2863cbd9ee6d ("ethdev: deprecate queue stats mapping functions")
Cc: stable@dpdk.org

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/cmdline.c | 6 ------
 app/test-pmd/testpmd.h | 2 --
 2 files changed, 8 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 10ee7c5179..d299edb88e 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -581,12 +581,6 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set port (port_id) rxq (queue_id) avail_thresh (0..99)>\n "
 			"    set available descriptors threshold for Rx queue\n\n"
 
-			"set stat_qmap (tx|rx) (port_id) (queue_id) (qmapping)\n"
-			"    Set statistics mapping (qmapping 0..15) for RX/TX"
-			" queue on port.\n"
-			"    e.g., 'set stat_qmap rx 0 2 5' sets rx queue 2"
-			" on port 0 to mapping 5.\n\n"
-
 			"set xstats-hide-zero on|off\n"
 			"    Set the option to hide the zero values"
 			" for xstats display.\n"
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 083171853c..b5643e74f5 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -1158,8 +1158,6 @@ void tx_qinq_set(portid_t port_id, uint16_t vlan_tci, uint16_t vlan_tci_outer);
 void tx_vlan_reset(portid_t port_id);
 void tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on);
 
-void set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value);
-
 void set_xstats_hide_zero(uint8_t on_off);
 void set_xstats_show_state(uint8_t on_off);
 void set_xstats_hide_disabled(uint8_t on_off);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v2 3/9] net/enic: remove unneeded ops initialization
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
  2026-07-23 20:28   ` [PATCH v2 1/9] net/virtio: remove unused " Stephen Hemminger
  2026-07-23 20:28   ` [PATCH v2 2/9] app/testpmd: remove unused function prototype Stephen Hemminger
@ 2026-07-23 20:28   ` Stephen Hemminger
  2026-07-24  1:52     ` Hyong Youb Kim (hyonkim)
  2026-07-23 20:28   ` [PATCH v2 4/9] net/cnxk: remove queue stats mapping Stephen Hemminger
                     ` (7 subsequent siblings)
  10 siblings, 1 reply; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-23 20:28 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, John Daley, Hyong Youb Kim

Better to just let compiler initialize fields to NULL since then
if fields change that driver doesn't use, the driver source
will not need to be changed.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/enic/enic_ethdev.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2e5cd186f9..648aa67a85 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -1119,8 +1119,6 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.dev_configure        = enicpmd_dev_configure,
 	.dev_start            = enicpmd_dev_start,
 	.dev_stop             = enicpmd_dev_stop,
-	.dev_set_link_up      = NULL,
-	.dev_set_link_down    = NULL,
 	.dev_close            = enicpmd_dev_close,
 	.promiscuous_enable   = enicpmd_dev_promiscuous_enable,
 	.promiscuous_disable  = enicpmd_dev_promiscuous_disable,
@@ -1129,14 +1127,10 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.link_update          = enicpmd_dev_link_update,
 	.stats_get            = enicpmd_dev_stats_get,
 	.stats_reset          = enicpmd_dev_stats_reset,
-	.queue_stats_mapping_set = NULL,
 	.dev_infos_get        = enicpmd_dev_info_get,
 	.dev_supported_ptypes_get = enicpmd_dev_supported_ptypes_get,
 	.mtu_set              = enicpmd_mtu_set,
-	.vlan_filter_set      = NULL,
-	.vlan_tpid_set        = NULL,
 	.vlan_offload_set     = enicpmd_vlan_offload_set,
-	.vlan_strip_queue_set = NULL,
 	.rx_queue_start       = enicpmd_dev_rx_queue_start,
 	.rx_queue_stop        = enicpmd_dev_rx_queue_stop,
 	.tx_queue_start       = enicpmd_dev_tx_queue_start,
@@ -1151,11 +1145,6 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.txq_info_get         = enicpmd_dev_txq_info_get,
 	.rx_burst_mode_get    = enicpmd_dev_rx_burst_mode_get,
 	.tx_burst_mode_get    = enicpmd_dev_tx_burst_mode_get,
-	.dev_led_on           = NULL,
-	.dev_led_off          = NULL,
-	.flow_ctrl_get        = NULL,
-	.flow_ctrl_set        = NULL,
-	.priority_flow_ctrl_set = NULL,
 	.mac_addr_add         = enicpmd_add_mac_addr,
 	.mac_addr_remove      = enicpmd_remove_mac_addr,
 	.mac_addr_set         = enicpmd_set_mac_addr,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v2 4/9] net/cnxk: remove queue stats mapping
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
                     ` (2 preceding siblings ...)
  2026-07-23 20:28   ` [PATCH v2 3/9] net/enic: remove unneeded ops initialization Stephen Hemminger
@ 2026-07-23 20:28   ` Stephen Hemminger
  2026-07-24  7:26     ` David Marchand
  2026-07-23 20:28   ` [PATCH v2 5/9] net/e1000: " Stephen Hemminger
                     ` (6 subsequent siblings)
  10 siblings, 1 reply; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-23 20:28 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, Nithin Dabilpuram, Kiran Kumar K,
	Sunil Kumar Kori, Satha Rao, Harman Kalra

The queue stats mapping feature has been deprecated since 25.11.
Remove support in this driver for stats map.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/cnxk/cnxk_ethdev.c |  1 -
 drivers/net/cnxk/cnxk_ethdev.h |  6 ---
 drivers/net/cnxk/cnxk_stats.c  | 76 ++++++++++++++--------------------
 3 files changed, 31 insertions(+), 52 deletions(-)

diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index c41959173b..9a4da870cd 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -2103,7 +2103,6 @@ struct eth_dev_ops cnxk_eth_dev_ops = {
 	.rx_queue_intr_enable = cnxk_nix_rx_queue_intr_enable,
 	.rx_queue_intr_disable = cnxk_nix_rx_queue_intr_disable,
 	.pool_ops_supported = cnxk_nix_pool_ops_supported,
-	.queue_stats_mapping_set = cnxk_nix_queue_stats_mapping,
 	.stats_get = cnxk_nix_stats_get,
 	.stats_reset = cnxk_nix_stats_reset,
 	.xstats_get = cnxk_nix_xstats_get,
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index fc66135c66..5dd74de577 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -423,10 +423,6 @@ struct cnxk_eth_dev {
 	/* LSO Tunnel format indices */
 	uint64_t lso_tun_fmt;
 
-	/* Per queue statistics counters */
-	uint32_t txq_stat_map[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-	uint32_t rxq_stat_map[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-
 	/* Security data */
 	struct cnxk_eth_dev_sec_inb inb;
 	struct cnxk_eth_dev_sec_outb outb;
@@ -700,8 +696,6 @@ void cnxk_eth_dev_link_status_get_cb(struct roc_nix *nix,
 void cnxk_eth_dev_q_err_cb(struct roc_nix *nix, void *data);
 int cnxk_nix_link_info_configure(struct rte_eth_dev *eth_dev);
 int cnxk_nix_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete);
-int cnxk_nix_queue_stats_mapping(struct rte_eth_dev *dev, uint16_t queue_id,
-				 uint8_t stat_idx, uint8_t is_rx);
 int cnxk_nix_stats_reset(struct rte_eth_dev *dev);
 int cnxk_nix_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		       struct eth_queue_stats *qstats);
diff --git a/drivers/net/cnxk/cnxk_stats.c b/drivers/net/cnxk/cnxk_stats.c
index d57659ef51..e5d29a78b3 100644
--- a/drivers/net/cnxk/cnxk_stats.c
+++ b/drivers/net/cnxk/cnxk_stats.c
@@ -14,7 +14,8 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
 	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
 	struct roc_nix *nix = &dev->nix;
 	struct roc_nix_stats nix_stats;
-	int rc = 0, i;
+	unsigned int i;
+	int rc = 0;
 
 	rc = roc_nix_stats_get(nix, &nix_stats);
 	if (rc)
@@ -33,31 +34,35 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
 	stats->ibytes = nix_stats.rx_octs;
 	stats->ierrors = nix_stats.rx_err;
 
-	if (qstats != NULL) {
-		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
-			struct roc_nix_stats_queue qstats_data;
-			uint16_t qidx;
-
-			if (dev->txq_stat_map[i] & (1U << 31)) {
-				qidx = dev->txq_stat_map[i] & 0xFFFF;
-				rc = roc_nix_stats_queue_get(nix, qidx, 0, &qstats_data);
-				if (rc)
-					goto exit;
-				qstats->q_opackets[i] = qstats_data.tx_pkts;
-				qstats->q_obytes[i] = qstats_data.tx_octs;
-				qstats->q_errors[i] = qstats_data.tx_drop_pkts;
-			}
-
-			if (dev->rxq_stat_map[i] & (1U << 31)) {
-				qidx = dev->rxq_stat_map[i] & 0xFFFF;
-				rc = roc_nix_stats_queue_get(nix, qidx, 1, &qstats_data);
-				if (rc)
-					goto exit;
-				qstats->q_ipackets[i] = qstats_data.rx_pkts;
-				qstats->q_ibytes[i] = qstats_data.rx_octs;
-				qstats->q_errors[i] += qstats_data.rx_drop_pkts;
-			}
-		}
+	if (qstats == NULL)
+		goto exit;
+
+	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+		struct roc_nix_stats_queue qstats_data;
+
+		if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+			break;
+
+		rc = roc_nix_stats_queue_get(nix, i, 0, &qstats_data);
+		if (rc)
+			goto exit;
+		qstats->q_opackets[i] = qstats_data.tx_pkts;
+		qstats->q_obytes[i] = qstats_data.tx_octs;
+		qstats->q_errors[i] = qstats_data.tx_drop_pkts;
+	}
+
+	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
+		struct roc_nix_stats_queue qstats_data;
+
+		if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+			break;
+
+		rc = roc_nix_stats_queue_get(nix, i, 1, &qstats_data);
+		if (rc)
+			goto exit;
+		qstats->q_ipackets[i] = qstats_data.rx_pkts;
+		qstats->q_ibytes[i] = qstats_data.rx_octs;
+		qstats->q_errors[i] += qstats_data.rx_drop_pkts;
 	}
 exit:
 	return rc;
@@ -71,25 +76,6 @@ cnxk_nix_stats_reset(struct rte_eth_dev *eth_dev)
 	return roc_nix_stats_reset(&dev->nix);
 }
 
-int
-cnxk_nix_queue_stats_mapping(struct rte_eth_dev *eth_dev, uint16_t queue_id,
-			     uint8_t stat_idx, uint8_t is_rx)
-{
-	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
-
-	if (is_rx) {
-		if (queue_id >= dev->nb_rxq)
-			return -EINVAL;
-		dev->rxq_stat_map[stat_idx] = ((1U << 31) | queue_id);
-	} else {
-		if (queue_id >= dev->nb_txq)
-			return -EINVAL;
-		dev->txq_stat_map[stat_idx] = ((1U << 31) | queue_id);
-	}
-
-	return 0;
-}
-
 int
 cnxk_nix_xstats_get(struct rte_eth_dev *eth_dev, struct rte_eth_xstat *xstats,
 		    unsigned int n)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v2 5/9] net/e1000: remove queue stats mapping
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
                     ` (3 preceding siblings ...)
  2026-07-23 20:28   ` [PATCH v2 4/9] net/cnxk: remove queue stats mapping Stephen Hemminger
@ 2026-07-23 20:28   ` Stephen Hemminger
  2026-07-24  7:31     ` David Marchand
  2026-07-23 20:28   ` [PATCH v2 6/9] net/ixgbe: " Stephen Hemminger
                     ` (5 subsequent siblings)
  10 siblings, 1 reply; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-23 20:28 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Support for queue stats mapping has been deprecated since 25.11.
Remove support for this operation in the e1000 driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/intel/e1000/igc_ethdev.c | 54 ++++------------------------
 drivers/net/intel/e1000/igc_ethdev.h |  2 --
 2 files changed, 7 insertions(+), 49 deletions(-)

diff --git a/drivers/net/intel/e1000/igc_ethdev.c b/drivers/net/intel/e1000/igc_ethdev.c
index de35da2c36..e5feea10d4 100644
--- a/drivers/net/intel/e1000/igc_ethdev.c
+++ b/drivers/net/intel/e1000/igc_ethdev.c
@@ -239,9 +239,7 @@ static int eth_igc_xstats_get_names_by_id(struct rte_eth_dev *dev,
 		const uint64_t *ids, struct rte_eth_xstat_name *xstats_names,
 		unsigned int limit);
 static int eth_igc_xstats_reset(struct rte_eth_dev *dev);
-static int
-eth_igc_queue_stats_mapping_set(struct rte_eth_dev *dev,
-	uint16_t queue_id, uint8_t stat_idx, uint8_t is_rx);
+
 static int
 eth_igc_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);
 static int
@@ -317,7 +315,6 @@ static const struct eth_dev_ops eth_igc_ops = {
 	.xstats_get_names	= eth_igc_xstats_get_names,
 	.stats_reset		= eth_igc_xstats_reset,
 	.xstats_reset		= eth_igc_xstats_reset,
-	.queue_stats_mapping_set = eth_igc_queue_stats_mapping_set,
 	.rx_queue_intr_enable	= eth_igc_rx_queue_intr_enable,
 	.rx_queue_intr_disable	= eth_igc_rx_queue_intr_disable,
 	.flow_ctrl_get		= eth_igc_flow_ctrl_get,
@@ -1362,7 +1359,7 @@ eth_igc_dev_init(struct rte_eth_dev *dev)
 	struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(dev, *pci_dev);
 	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
 	struct e1000_hw *hw = IGC_DEV_PRIVATE_HW(dev);
-	int i, error = 0;
+	int error = 0;
 
 	PMD_INIT_FUNC_TRACE();
 	dev->dev_ops = &eth_igc_ops;
@@ -1493,12 +1490,6 @@ eth_igc_dev_init(struct rte_eth_dev *dev)
 	/* enable support intr */
 	igc_intr_other_enable(dev);
 
-	/* initiate queue status */
-	for (i = 0; i < IGC_QUEUE_PAIRS_NUM; i++) {
-		igc->txq_stats_map[i] = -1;
-		igc->rxq_stats_map[i] = -1;
-	}
-
 	igc_flow_init(dev);
 	igc_clear_all_filter(dev);
 	return 0;
@@ -2031,7 +2022,6 @@ static int
 eth_igc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats,
 		struct eth_queue_stats *qstats)
 {
-	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
 	struct e1000_hw *hw = IGC_DEV_PRIVATE_HW(dev);
 	struct e1000_hw_stats *stats = IGC_DEV_PRIVATE_STATS(dev);
 	struct igc_hw_queue_stats *queue_stats =
@@ -2070,19 +2060,11 @@ eth_igc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats,
 	/* Get per-queue statuses */
 	if (qstats) {
 		for (i = 0; i < IGC_QUEUE_PAIRS_NUM; i++) {
-			/* GET TX queue statuses */
-			int map_id = igc->txq_stats_map[i];
-			if (map_id >= 0) {
-				qstats->q_opackets[map_id] += queue_stats->pqgptc[i];
-				qstats->q_obytes[map_id] += queue_stats->pqgotc[i];
-			}
-			/* Get RX queue statuses */
-			map_id = igc->rxq_stats_map[i];
-			if (map_id >= 0) {
-				qstats->q_ipackets[map_id] += queue_stats->pqgprc[i];
-				qstats->q_ibytes[map_id] += queue_stats->pqgorc[i];
-				qstats->q_errors[map_id] += queue_stats->rqdpc[i];
-			}
+			qstats->q_opackets[i] += queue_stats->pqgptc[i];
+			qstats->q_obytes[i] += queue_stats->pqgotc[i];
+			qstats->q_ipackets[i] += queue_stats->pqgprc[i];
+			qstats->q_ibytes[i] += queue_stats->pqgorc[i];
+			qstats->q_errors[i] += queue_stats->rqdpc[i];
 		}
 	}
 
@@ -2231,28 +2213,6 @@ eth_igc_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 	}
 }
 
-static int
-eth_igc_queue_stats_mapping_set(struct rte_eth_dev *dev,
-		uint16_t queue_id, uint8_t stat_idx, uint8_t is_rx)
-{
-	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
-
-	/* check queue id is valid */
-	if (queue_id >= IGC_QUEUE_PAIRS_NUM) {
-		PMD_DRV_LOG(ERR, "queue id(%u) error, max is %u",
-			queue_id, IGC_QUEUE_PAIRS_NUM - 1);
-		return -EINVAL;
-	}
-
-	/* store the mapping status id */
-	if (is_rx)
-		igc->rxq_stats_map[queue_id] = stat_idx;
-	else
-		igc->txq_stats_map[queue_id] = stat_idx;
-
-	return 0;
-}
-
 static int
 eth_igc_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
diff --git a/drivers/net/intel/e1000/igc_ethdev.h b/drivers/net/intel/e1000/igc_ethdev.h
index 7fa7877adf..96ff520da7 100644
--- a/drivers/net/intel/e1000/igc_ethdev.h
+++ b/drivers/net/intel/e1000/igc_ethdev.h
@@ -227,8 +227,6 @@ struct igc_adapter {
 	struct e1000_hw		hw;
 	struct e1000_hw_stats	stats;
 	struct igc_hw_queue_stats queue_stats;
-	int16_t txq_stats_map[IGC_QUEUE_PAIRS_NUM];
-	int16_t rxq_stats_map[IGC_QUEUE_PAIRS_NUM];
 
 	struct igc_interrupt	intr;
 	struct igc_vfta	shadow_vfta;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v2 6/9] net/ixgbe: remove queue stats mapping
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
                     ` (4 preceding siblings ...)
  2026-07-23 20:28   ` [PATCH v2 5/9] net/e1000: " Stephen Hemminger
@ 2026-07-23 20:28   ` Stephen Hemminger
  2026-07-23 20:28   ` [PATCH v2 7/9] net/txgbe: " Stephen Hemminger
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-23 20:28 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Anatoly Burakov, Vladimir Medvedkin

The support for queue_stats_map has been deprecated since 25.11.
Remove support for queue mapping in ixgbe driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/intel/ixgbe/ixgbe_ethdev.c | 97 --------------------------
 drivers/net/intel/ixgbe/ixgbe_ethdev.h |  9 ---
 2 files changed, 106 deletions(-)

diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.c b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
index c5010f623c..3a4ca0c79b 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
@@ -182,10 +182,6 @@ static int ixgbe_dev_xstats_get_names_by_id(
 	const uint64_t *ids,
 	struct rte_eth_xstat_name *xstats_names,
 	unsigned int limit);
-static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
-					     uint16_t queue_id,
-					     uint8_t stat_idx,
-					     uint8_t is_rx);
 static int ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
 				 size_t fw_size);
 static int ixgbe_dev_info_get(struct rte_eth_dev *dev,
@@ -511,7 +507,6 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.xstats_reset         = ixgbe_dev_xstats_reset,
 	.xstats_get_names     = ixgbe_dev_xstats_get_names,
 	.xstats_get_names_by_id = ixgbe_dev_xstats_get_names_by_id,
-	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
 	.fw_version_get       = ixgbe_fw_version_get,
 	.dev_infos_get        = ixgbe_dev_info_get,
 	.dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
@@ -886,96 +881,6 @@ ixgbe_reset_qstat_mappings(struct ixgbe_hw *hw)
 	}
 }
 
-
-static int
-ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
-				  uint16_t queue_id,
-				  uint8_t stat_idx,
-				  uint8_t is_rx)
-{
-#define QSM_REG_NB_BITS_PER_QMAP_FIELD 8
-#define NB_QMAP_FIELDS_PER_QSM_REG 4
-#define QMAP_FIELD_RESERVED_BITS_MASK 0x0f
-
-	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
-	struct ixgbe_stat_mapping_registers *stat_mappings =
-		IXGBE_DEV_PRIVATE_TO_STAT_MAPPINGS(eth_dev->data->dev_private);
-	uint32_t qsmr_mask = 0;
-	uint32_t clearing_mask = QMAP_FIELD_RESERVED_BITS_MASK;
-	uint32_t q_map;
-	uint8_t n, offset;
-
-	if ((hw->mac.type != ixgbe_mac_82599EB) &&
-		(hw->mac.type != ixgbe_mac_X540) &&
-		(hw->mac.type != ixgbe_mac_X550) &&
-		(hw->mac.type != ixgbe_mac_X550EM_x) &&
-		(hw->mac.type != ixgbe_mac_X550EM_a) &&
-		(hw->mac.type != ixgbe_mac_E610))
-		return -ENOSYS;
-
-	PMD_INIT_LOG(DEBUG, "Setting port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-
-	n = (uint8_t)(queue_id / NB_QMAP_FIELDS_PER_QSM_REG);
-	if (n >= IXGBE_NB_STAT_MAPPING_REGS) {
-		PMD_INIT_LOG(ERR, "Nb of stat mapping registers exceeded");
-		return -EIO;
-	}
-	offset = (uint8_t)(queue_id % NB_QMAP_FIELDS_PER_QSM_REG);
-
-	/* Now clear any previous stat_idx set */
-	clearing_mask <<= (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] &= ~clearing_mask;
-	else
-		stat_mappings->rqsmr[n] &= ~clearing_mask;
-
-	q_map = (uint32_t)stat_idx;
-	q_map &= QMAP_FIELD_RESERVED_BITS_MASK;
-	qsmr_mask = q_map << (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] |= qsmr_mask;
-	else
-		stat_mappings->rqsmr[n] |= qsmr_mask;
-
-	PMD_INIT_LOG(DEBUG, "Set port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-	PMD_INIT_LOG(DEBUG, "%s[%d] = 0x%08x", is_rx ? "RQSMR" : "TQSM", n,
-		     is_rx ? stat_mappings->rqsmr[n] : stat_mappings->tqsm[n]);
-
-	/* Now write the mapping in the appropriate register */
-	if (is_rx) {
-		PMD_INIT_LOG(DEBUG, "Write 0x%x to RX IXGBE stat mapping reg:%d",
-			     stat_mappings->rqsmr[n], n);
-		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(n), stat_mappings->rqsmr[n]);
-	} else {
-		PMD_INIT_LOG(DEBUG, "Write 0x%x to TX IXGBE stat mapping reg:%d",
-			     stat_mappings->tqsm[n], n);
-		IXGBE_WRITE_REG(hw, IXGBE_TQSM(n), stat_mappings->tqsm[n]);
-	}
-	return 0;
-}
-
-static void
-ixgbe_restore_statistics_mapping(struct rte_eth_dev *dev)
-{
-	struct ixgbe_stat_mapping_registers *stat_mappings =
-		IXGBE_DEV_PRIVATE_TO_STAT_MAPPINGS(dev->data->dev_private);
-	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	int i;
-
-	/* write whatever was in stat mapping table to the NIC */
-	for (i = 0; i < IXGBE_NB_STAT_MAPPING_REGS; i++) {
-		/* rx */
-		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), stat_mappings->rqsmr[i]);
-
-		/* tx */
-		IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), stat_mappings->tqsm[i]);
-	}
-}
-
 static void
 ixgbe_dcb_init(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config)
 {
@@ -2742,8 +2647,6 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 						RTE_BIT64(idx));
 	}
 
-	ixgbe_restore_statistics_mapping(dev);
-
 	err = ixgbe_flow_ctrl_enable(dev, hw);
 	if (err < 0) {
 		PMD_INIT_LOG(ERR, "enable flow ctrl err");
diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.h b/drivers/net/intel/ixgbe/ixgbe_ethdev.h
index 5d3243cb4d..ba826b6d8d 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.h
@@ -216,11 +216,6 @@ struct ixgbe_interrupt {
 	uint32_t mask_original;
 };
 
-struct ixgbe_stat_mapping_registers {
-	uint32_t tqsm[IXGBE_NB_STAT_MAPPING_REGS];
-	uint32_t rqsmr[IXGBE_NB_STAT_MAPPING_REGS];
-};
-
 struct ixgbe_vfta {
 	uint32_t vfta[IXGBE_VFTA_SIZE];
 };
@@ -471,7 +466,6 @@ struct ixgbe_adapter {
 	struct rte_eth_fdir_conf    fdir_conf;
 	struct ixgbe_hw_fdir_info   fdir;
 	struct ixgbe_interrupt      intr;
-	struct ixgbe_stat_mapping_registers stat_mappings;
 	struct ixgbe_vfta           shadow_vfta;
 	struct ixgbe_hwstrip		hwstrip;
 	struct ixgbe_dcb_config     dcb_config;
@@ -546,9 +540,6 @@ uint16_t ixgbe_vf_representor_tx_burst(void *tx_queue, struct rte_mbuf **tx_pkts
 #define IXGBE_DEV_PRIVATE_TO_FDIR_INFO(adapter) \
 	(&((struct ixgbe_adapter *)adapter)->fdir)
 
-#define IXGBE_DEV_PRIVATE_TO_STAT_MAPPINGS(adapter) \
-	(&((struct ixgbe_adapter *)adapter)->stat_mappings)
-
 #define IXGBE_DEV_PRIVATE_TO_VFTA(adapter) \
 	(&((struct ixgbe_adapter *)adapter)->shadow_vfta)
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v2 7/9] net/txgbe: remove queue stats mapping
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
                     ` (5 preceding siblings ...)
  2026-07-23 20:28   ` [PATCH v2 6/9] net/ixgbe: " Stephen Hemminger
@ 2026-07-23 20:28   ` Stephen Hemminger
  2026-07-23 20:28   ` [PATCH v2 8/9] net/sxe2: " Stephen Hemminger
                     ` (3 subsequent siblings)
  10 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-23 20:28 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Jiawen Wu, Zaiyu Wang

Support for queue stats mapping has been deprecated since 25.11.
Remove support for this ethdev op in txgbe driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/txgbe/txgbe_ethdev.c | 87 +++-----------------------------
 drivers/net/txgbe/txgbe_ethdev.h | 13 -----
 2 files changed, 7 insertions(+), 93 deletions(-)

diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 4d2746371b..6349aca90f 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -386,60 +386,6 @@ txgbe_disable_intr(struct txgbe_hw *hw)
 	txgbe_flush(hw);
 }
 
-static int
-txgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
-				  uint16_t queue_id,
-				  uint8_t stat_idx,
-				  uint8_t is_rx)
-{
-	struct txgbe_hw *hw = TXGBE_DEV_HW(eth_dev);
-	struct txgbe_stat_mappings *stat_mappings =
-		TXGBE_DEV_STAT_MAPPINGS(eth_dev);
-	uint32_t qsmr_mask = 0;
-	uint32_t clearing_mask = QMAP_FIELD_RESERVED_BITS_MASK;
-	uint32_t q_map;
-	uint8_t n, offset;
-
-	if (!txgbe_is_pf(hw))
-		return -ENOSYS;
-
-	if (stat_idx & ~QMAP_FIELD_RESERVED_BITS_MASK)
-		return -EIO;
-
-	PMD_INIT_LOG(DEBUG, "Setting port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-
-	n = (uint8_t)(queue_id / NB_QMAP_FIELDS_PER_QSM_REG);
-	if (n >= TXGBE_NB_STAT_MAPPING) {
-		PMD_INIT_LOG(ERR, "Nb of stat mapping registers exceeded");
-		return -EIO;
-	}
-	offset = (uint8_t)(queue_id % NB_QMAP_FIELDS_PER_QSM_REG);
-
-	/* Now clear any previous stat_idx set */
-	clearing_mask <<= (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] &= ~clearing_mask;
-	else
-		stat_mappings->rqsm[n] &= ~clearing_mask;
-
-	q_map = (uint32_t)stat_idx;
-	q_map &= QMAP_FIELD_RESERVED_BITS_MASK;
-	qsmr_mask = q_map << (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] |= qsmr_mask;
-	else
-		stat_mappings->rqsm[n] |= qsmr_mask;
-
-	PMD_INIT_LOG(DEBUG, "Set port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-	PMD_INIT_LOG(DEBUG, "%s[%d] = 0x%08x", is_rx ? "RQSMR" : "TQSM", n,
-		     is_rx ? stat_mappings->rqsm[n] : stat_mappings->tqsm[n]);
-	return 0;
-}
-
 static void
 txgbe_dcb_init(struct txgbe_hw *hw, struct txgbe_dcb_config *dcb_config)
 {
@@ -2491,10 +2437,8 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 {
 	struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
 	struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
-	struct txgbe_stat_mappings *stat_mappings =
-			TXGBE_DEV_STAT_MAPPINGS(dev);
 	struct txgbe_tx_queue *txq;
-	uint32_t i, j;
+	unsigned int i;
 
 	txgbe_read_stats_registers(hw, hw_stats);
 
@@ -2508,29 +2452,13 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	stats->obytes = hw_stats->tx_bytes;
 
 	if (qstats != NULL) {
-		memset(&qstats->q_ipackets, 0, sizeof(qstats->q_ipackets));
-		memset(&qstats->q_opackets, 0, sizeof(qstats->q_opackets));
-		memset(&qstats->q_ibytes, 0, sizeof(qstats->q_ibytes));
-		memset(&qstats->q_obytes, 0, sizeof(qstats->q_obytes));
-		memset(&qstats->q_errors, 0, sizeof(qstats->q_errors));
 		for (i = 0; i < TXGBE_MAX_QP; i++) {
-			uint32_t n = i / NB_QMAP_FIELDS_PER_QSM_REG;
-			uint32_t offset = (i % NB_QMAP_FIELDS_PER_QSM_REG) * 8;
-			uint32_t q_map;
-
-			q_map = (stat_mappings->rqsm[n] >> offset)
-					& QMAP_FIELD_RESERVED_BITS_MASK;
-			j = (q_map < RTE_ETHDEV_QUEUE_STAT_CNTRS
-			     ? q_map : q_map % RTE_ETHDEV_QUEUE_STAT_CNTRS);
-			qstats->q_ipackets[j] += hw_stats->qp[i].rx_qp_packets;
-			qstats->q_ibytes[j] += hw_stats->qp[i].rx_qp_bytes;
-
-			q_map = (stat_mappings->tqsm[n] >> offset)
-					& QMAP_FIELD_RESERVED_BITS_MASK;
-			j = (q_map < RTE_ETHDEV_QUEUE_STAT_CNTRS
-			     ? q_map : q_map % RTE_ETHDEV_QUEUE_STAT_CNTRS);
-			qstats->q_opackets[j] += hw_stats->qp[i].tx_qp_packets;
-			qstats->q_obytes[j] += hw_stats->qp[i].tx_qp_bytes;
+			if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+				break;
+			qstats->q_ipackets[i] += hw_stats->qp[i].rx_qp_packets;
+			qstats->q_ibytes[i] += hw_stats->qp[i].rx_qp_bytes;
+			qstats->q_opackets[i] += hw_stats->qp[i].tx_qp_packets;
+			qstats->q_obytes[i] += hw_stats->qp[i].tx_qp_bytes;
 		}
 	}
 
@@ -6365,7 +6293,6 @@ static const struct eth_dev_ops txgbe_eth_dev_ops = {
 	.xstats_reset               = txgbe_dev_xstats_reset,
 	.xstats_get_names           = txgbe_dev_xstats_get_names,
 	.xstats_get_names_by_id     = txgbe_dev_xstats_get_names_by_id,
-	.queue_stats_mapping_set    = txgbe_dev_queue_stats_mapping_set,
 	.fw_version_get             = txgbe_fw_version_get,
 	.dev_supported_ptypes_get   = txgbe_dev_supported_ptypes_get,
 	.mtu_set                    = txgbe_dev_mtu_set,
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index c32c61d8bf..a617b70e3c 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -153,15 +153,6 @@ struct txgbe_interrupt {
 	uint64_t mask_orig; /* save mask during delayed handler */
 };
 
-#define TXGBE_NB_STAT_MAPPING  32
-#define QSM_REG_NB_BITS_PER_QMAP_FIELD 8
-#define NB_QMAP_FIELDS_PER_QSM_REG 4
-#define QMAP_FIELD_RESERVED_BITS_MASK 0x0f
-struct txgbe_stat_mappings {
-	uint32_t tqsm[TXGBE_NB_STAT_MAPPING];
-	uint32_t rqsm[TXGBE_NB_STAT_MAPPING];
-};
-
 struct txgbe_vfta {
 	uint32_t vfta[TXGBE_VFTA_SIZE];
 };
@@ -355,7 +346,6 @@ struct txgbe_adapter {
 	struct rte_eth_fdir_conf    fdir_conf;
 	struct txgbe_hw_fdir_info   fdir;
 	struct txgbe_interrupt      intr;
-	struct txgbe_stat_mappings  stat_mappings;
 	struct txgbe_vfta           shadow_vfta;
 	struct txgbe_hwstrip        hwstrip;
 	struct txgbe_dcb_config     dcb_config;
@@ -398,9 +388,6 @@ struct txgbe_adapter {
 #define TXGBE_DEV_FDIR(dev) \
 	(&((struct txgbe_adapter *)(dev)->data->dev_private)->fdir)
 
-#define TXGBE_DEV_STAT_MAPPINGS(dev) \
-	(&((struct txgbe_adapter *)(dev)->data->dev_private)->stat_mappings)
-
 #define TXGBE_DEV_VFTA(dev) \
 	(&((struct txgbe_adapter *)(dev)->data->dev_private)->shadow_vfta)
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v2 8/9] net/sxe2: remove queue stats mapping
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
                     ` (6 preceding siblings ...)
  2026-07-23 20:28   ` [PATCH v2 7/9] net/txgbe: " Stephen Hemminger
@ 2026-07-23 20:28   ` Stephen Hemminger
  2026-07-23 20:28   ` [PATCH v2 9/9] ethdev: remove support for " Stephen Hemminger
                     ` (2 subsequent siblings)
  10 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-23 20:28 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Jie Liu

The queue stats mapping API is removed in 26.11. Drop the
.queue_stats_mapping_set op and the SXE2_DEV_CAPS_OFFLOAD_Q_MAP
handling, along with the now-unused mapping init/reset helpers.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/sxe2/sxe2_cmd_chnl.c | 99 --------------------------------
 drivers/net/sxe2/sxe2_cmd_chnl.h | 10 ----
 drivers/net/sxe2/sxe2_ethdev.c   |  5 --
 drivers/net/sxe2/sxe2_stats.c    | 76 +-----------------------
 drivers/net/sxe2/sxe2_stats.h    |  5 --
 5 files changed, 3 insertions(+), 192 deletions(-)

diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b09989fe50..050488301c 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1609,105 +1609,6 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_
 	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;
-}
-
 int32_t sxe2_drv_flow_filter_add(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
 {
 	struct sxe2_drv_flow_filter_req req = { 0 };
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index d63caad526..f43dcc8e7a 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -102,16 +102,6 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter,
 int32_t sxe2_drv_fc_state_get(struct sxe2_adapter *adapter,
 			      struct sxe2_drv_vsi_fc_get_resp *dev_fc_state_resp);
 
-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_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 8bbfdc3a15..440411a65a 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -194,8 +194,6 @@ static const struct eth_dev_ops sxe2_eth_dev_ops = {
 	.xstats_get_names           = sxe2_xstats_names_get,
 	.xstats_reset               = sxe2_stats_info_reset,
 
-	.queue_stats_mapping_set    = sxe2_queue_stats_mapping_set,
-
 	.fw_version_get             = sxe2_fw_version_string_get,
 
 	.get_monitor_addr           = sxe2_get_monitor_addr,
@@ -1309,9 +1307,6 @@ static void sxe2_drv_dev_caps_set(struct sxe2_adapter *adapter,
 	if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
 		adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_PTP;
 
-	if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_Q_MAP)
-		adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_Q_MAP;
-
 	if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_FC_STATE)
 		adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_FC_STATE;
 }
diff --git a/drivers/net/sxe2/sxe2_stats.c b/drivers/net/sxe2/sxe2_stats.c
index 3ad8fe2fe9..27cd019c1a 100644
--- a/drivers/net/sxe2/sxe2_stats.c
+++ b/drivers/net/sxe2/sxe2_stats.c
@@ -497,90 +497,20 @@ int32_t sxe2_stats_hw_reset(struct rte_eth_dev *dev)
 
 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;
+	return sxe2_stats_hw_reset(dev);
 }
 
 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);
+	dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
 
-	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;
+	return sxe2_stats_hw_reset(dev);
 }
diff --git a/drivers/net/sxe2/sxe2_stats.h b/drivers/net/sxe2/sxe2_stats.h
index 64ac2bb11d..f9cb5a8225 100644
--- a/drivers/net/sxe2/sxe2_stats.h
+++ b/drivers/net/sxe2/sxe2_stats.h
@@ -31,9 +31,4 @@ 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.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v2 9/9] ethdev: remove support for queue stats mapping
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
                     ` (7 preceding siblings ...)
  2026-07-23 20:28   ` [PATCH v2 8/9] net/sxe2: " Stephen Hemminger
@ 2026-07-23 20:28   ` Stephen Hemminger
  2026-07-24  7:39   ` [PATCH v2 0/9] Complete removal of " David Marchand
  2026-07-24  7:42   ` David Marchand
  10 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-23 20:28 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Chengwen Feng, Andrew Rybchenko,
	Thomas Monjalon

The support for queue stats mapping has been deprecated since 25.11
release by commit 2863cbd9ee6d ("ethdev: deprecate queue stats mapping
functions")

This patch completes final removal from ethdev and documentation.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/nics/features.rst           |  7 ---
 doc/guides/rel_notes/deprecation.rst   |  6 ---
 doc/guides/rel_notes/release_26_11.rst |  5 +++
 lib/ethdev/ethdev_driver.h             | 11 -----
 lib/ethdev/ethdev_trace.h              | 20 ---------
 lib/ethdev/ethdev_trace_points.c       |  6 ---
 lib/ethdev/rte_ethdev.c                | 62 --------------------------
 lib/ethdev/rte_ethdev.h                | 45 -------------------
 8 files changed, 5 insertions(+), 157 deletions(-)

diff --git a/doc/guides/nics/features.rst b/doc/guides/nics/features.rst
index 0b0c69e7cd..d6852b063c 100644
--- a/doc/guides/nics/features.rst
+++ b/doc/guides/nics/features.rst
@@ -764,13 +764,6 @@ If driver does not support this feature the per queue stats will be zero.
 * **[implements] eth_dev_ops**: ``stats_get``, ``stats_reset``.
 * **[related]    API**: ``rte_eth_stats_get``, ``rte_eth_stats_reset()``.
 
-May also support configuring per-queue stat counter mapping.
-Used by some drivers to workaround HW limitations.
-
-* **[implements] eth_dev_ops**: ``queue_stats_mapping_set``.
-* **[related]    API**: ``rte_eth_dev_set_rx_queue_stats_mapping()``,
-  ``rte_eth_dev_set_tx_queue_stats_mapping()``.
-
 
 .. _nic_features_extended_stats:
 
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 6ad7698c6b..aaa2918865 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -83,12 +83,6 @@ Deprecation Notices
   and the header struct ``rte_vxlan_gpe_hdr`` with the macro ``RTE_ETHER_VXLAN_GPE_HLEN``
   will be removed in DPDK 25.11.
 
-* ethdev: The queue stats mapping functions
-  ``rte_eth_dev_set_tx_queue_stats_mapping`` and ``rte_eth_dev_set_rx_queue_stats_mapping``
-  are deprecated and will be removed in a future release.
-  Following the removal of queue statistics from the main ethdev statistics structure,
-  these functions are no longer needed.
-
 * ethdev: The flow API matching pattern structures, ``struct rte_flow_item_*``,
   should start with relevant protocol header structure from lib/net/.
   The individual protocol header fields and the protocol header struct
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 938617ca75..ed6937c8b5 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -68,6 +68,11 @@ Removed Items
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* ethdev: Removed support for ethdev queue stats mapping.
+
+  ``rte_eth_dev_set_tx_queue_stats_mapping`` and ``rte_eth_dev_set_rx_queue_stats_mapping``
+  were deprecated and are now removed.
+
 
 API Changes
 -----------
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index 0f336f9567..0477579cc3 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -567,15 +567,6 @@ typedef int (*eth_xstats_disable_counter_t)(struct rte_eth_dev *dev, uint64_t id
 /** @internal Query the state of an xstat the can be enabled and disabled in runtime. */
 typedef int (*eth_xstats_query_state_t)(struct rte_eth_dev *dev, uint64_t id);
 
-/**
- * @internal
- * Set a queue statistics mapping for a Tx/Rx queue of an Ethernet device.
- */
-typedef int (*eth_queue_stats_mapping_set_t)(struct rte_eth_dev *dev,
-					     uint16_t queue_id,
-					     uint8_t stat_idx,
-					     uint8_t is_rx);
-
 /** @internal Get specific information of an Ethernet device. */
 typedef int (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				   struct rte_eth_dev_info *dev_info);
@@ -1454,8 +1445,6 @@ struct eth_dev_ops {
 	eth_xstats_reset_t         xstats_reset;
 	/** Get names of extended statistics */
 	eth_xstats_get_names_t     xstats_get_names;
-	/** Configure per queue stat counter mapping */
-	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info */
 	/** Retrieve Rx queue information */
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index 6554cc1a21..6f1804a765 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -310,26 +310,6 @@ RTE_TRACE_POINT(
 	rte_trace_point_emit_int(ret);
 )
 
-RTE_TRACE_POINT(
-	rte_ethdev_trace_set_rx_queue_stats_mapping,
-	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t rx_queue_id,
-		uint8_t stat_idx, int ret),
-	rte_trace_point_emit_u16(port_id);
-	rte_trace_point_emit_u16(rx_queue_id);
-	rte_trace_point_emit_u8(stat_idx);
-	rte_trace_point_emit_int(ret);
-)
-
-RTE_TRACE_POINT(
-	rte_ethdev_trace_set_tx_queue_stats_mapping,
-	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t tx_queue_id,
-		uint8_t stat_idx, int ret),
-	rte_trace_point_emit_u16(port_id);
-	rte_trace_point_emit_u16(tx_queue_id);
-	rte_trace_point_emit_u8(stat_idx);
-	rte_trace_point_emit_int(ret);
-)
-
 RTE_TRACE_POINT(
 	rte_ethdev_trace_fw_version_get,
 	RTE_TRACE_POINT_ARGS(uint16_t port_id, const char *fw_version,
diff --git a/lib/ethdev/ethdev_trace_points.c b/lib/ethdev/ethdev_trace_points.c
index 0a28378a56..b0644ea489 100644
--- a/lib/ethdev/ethdev_trace_points.c
+++ b/lib/ethdev/ethdev_trace_points.c
@@ -230,12 +230,6 @@ RTE_TRACE_POINT_REGISTER(rte_eth_trace_xstats_get,
 RTE_TRACE_POINT_REGISTER(rte_eth_trace_xstats_reset,
 	lib.ethdev.xstats_reset)
 
-RTE_TRACE_POINT_REGISTER(rte_ethdev_trace_set_tx_queue_stats_mapping,
-	lib.ethdev.set_tx_queue_stats_mapping)
-
-RTE_TRACE_POINT_REGISTER(rte_ethdev_trace_set_rx_queue_stats_mapping,
-	lib.ethdev.set_rx_queue_stats_mapping)
-
 RTE_TRACE_POINT_REGISTER(rte_ethdev_trace_fw_version_get,
 	lib.ethdev.fw_version_get)
 
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index 9efeaf77cb..d6915a6b08 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -160,11 +160,6 @@ static const struct {
 	{RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"},
 };
 
-enum {
-	STAT_QMAP_TX = 0,
-	STAT_QMAP_RX
-};
-
 static const struct {
 	enum rte_eth_hash_function algo;
 	const char *name;
@@ -4005,63 +4000,6 @@ rte_eth_xstats_query_state(uint16_t port_id, uint64_t id)
 	return -ENOTSUP;
 }
 
-static int
-eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id,
-		uint8_t stat_idx, uint8_t is_rx)
-{
-	struct rte_eth_dev *dev;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	dev = &rte_eth_devices[port_id];
-
-	if (is_rx && (queue_id >= dev->data->nb_rx_queues))
-		return -EINVAL;
-
-	if (!is_rx && (queue_id >= dev->data->nb_tx_queues))
-		return -EINVAL;
-
-	if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
-		return -EINVAL;
-
-	if (dev->dev_ops->queue_stats_mapping_set == NULL)
-		return -ENOTSUP;
-	return dev->dev_ops->queue_stats_mapping_set(dev, queue_id, stat_idx, is_rx);
-}
-
-RTE_EXPORT_SYMBOL(rte_eth_dev_set_tx_queue_stats_mapping)
-int
-rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id,
-		uint8_t stat_idx)
-{
-	int ret;
-
-	ret = eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
-						tx_queue_id,
-						stat_idx, STAT_QMAP_TX));
-
-	rte_ethdev_trace_set_tx_queue_stats_mapping(port_id, tx_queue_id,
-						    stat_idx, ret);
-
-	return ret;
-}
-
-RTE_EXPORT_SYMBOL(rte_eth_dev_set_rx_queue_stats_mapping)
-int
-rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id,
-		uint8_t stat_idx)
-{
-	int ret;
-
-	ret = eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
-						rx_queue_id,
-						stat_idx, STAT_QMAP_RX));
-
-	rte_ethdev_trace_set_rx_queue_stats_mapping(port_id, rx_queue_id,
-						    stat_idx, ret);
-
-	return ret;
-}
-
 RTE_EXPORT_SYMBOL(rte_eth_dev_fw_version_get)
 int
 rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index ee400b386f..3aa7a22fbc 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -3491,51 +3491,6 @@ int rte_eth_xstats_query_state(uint16_t port_id, uint64_t id);
  */
 int rte_eth_xstats_reset(uint16_t port_id);
 
-/**
- *  Set a mapping for the specified transmit queue to the specified per-queue
- *  statistics counter.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param tx_queue_id
- *   The index of the transmit queue for which a queue stats mapping is required.
- *   The value must be in the range [0, nb_tx_queue - 1] previously supplied
- *   to rte_eth_dev_configure().
- * @param stat_idx
- *   The per-queue packet statistics functionality number that the transmit
- *   queue is to be assigned.
- *   The value must be in the range [0, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1].
- *   Max RTE_ETHDEV_QUEUE_STAT_CNTRS being 256.
- * @return
- *   Zero if successful. Non-zero otherwise.
- */
-__rte_deprecated
-int rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id,
-		uint16_t tx_queue_id, uint8_t stat_idx);
-
-/**
- *  Set a mapping for the specified receive queue to the specified per-queue
- *  statistics counter.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param rx_queue_id
- *   The index of the receive queue for which a queue stats mapping is required.
- *   The value must be in the range [0, nb_rx_queue - 1] previously supplied
- *   to rte_eth_dev_configure().
- * @param stat_idx
- *   The per-queue packet statistics functionality number that the receive
- *   queue is to be assigned.
- *   The value must be in the range [0, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1].
- *   Max RTE_ETHDEV_QUEUE_STAT_CNTRS being 256.
- * @return
- *   Zero if successful. Non-zero otherwise.
- */
-__rte_deprecated
-int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
-					   uint16_t rx_queue_id,
-					   uint8_t stat_idx);
-
 /**
  * Retrieve the Ethernet address of an Ethernet device.
  *
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* RE: [PATCH v2 3/9] net/enic: remove unneeded ops initialization
  2026-07-23 20:28   ` [PATCH v2 3/9] net/enic: remove unneeded ops initialization Stephen Hemminger
@ 2026-07-24  1:52     ` Hyong Youb Kim (hyonkim)
  0 siblings, 0 replies; 45+ messages in thread
From: Hyong Youb Kim (hyonkim) @ 2026-07-24  1:52 UTC (permalink / raw)
  To: Stephen Hemminger, dev@dpdk.org; +Cc: John Daley (johndale)



> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Friday, July 24, 2026 5:28 AM
> To: dev@dpdk.org
> Cc: Stephen Hemminger <stephen@networkplumber.org>; John Daley
> (johndale) <johndale@cisco.com>; Hyong Youb Kim (hyonkim)
> <hyonkim@cisco.com>
> Subject: [PATCH v2 3/9] net/enic: remove unneeded ops initialization
> 
> Better to just let compiler initialize fields to NULL since then
> if fields change that driver doesn't use, the driver source
> will not need to be changed.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  drivers/net/enic/enic_ethdev.c | 11 -----------
>  1 file changed, 11 deletions(-)
> 
> diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
> index 2e5cd186f9..648aa67a85 100644
> --- a/drivers/net/enic/enic_ethdev.c
> +++ b/drivers/net/enic/enic_ethdev.c
> @@ -1119,8 +1119,6 @@ static const struct eth_dev_ops
> enicpmd_eth_dev_ops = {
>  	.dev_configure        = enicpmd_dev_configure,
>  	.dev_start            = enicpmd_dev_start,
>  	.dev_stop             = enicpmd_dev_stop,
> -	.dev_set_link_up      = NULL,
> -	.dev_set_link_down    = NULL,
>  	.dev_close            = enicpmd_dev_close,
>  	.promiscuous_enable   = enicpmd_dev_promiscuous_enable,
>  	.promiscuous_disable  = enicpmd_dev_promiscuous_disable,
> @@ -1129,14 +1127,10 @@ static const struct eth_dev_ops
> enicpmd_eth_dev_ops = {
>  	.link_update          = enicpmd_dev_link_update,
>  	.stats_get            = enicpmd_dev_stats_get,
>  	.stats_reset          = enicpmd_dev_stats_reset,
> -	.queue_stats_mapping_set = NULL,
>  	.dev_infos_get        = enicpmd_dev_info_get,
>  	.dev_supported_ptypes_get = enicpmd_dev_supported_ptypes_get,
>  	.mtu_set              = enicpmd_mtu_set,
> -	.vlan_filter_set      = NULL,
> -	.vlan_tpid_set        = NULL,
>  	.vlan_offload_set     = enicpmd_vlan_offload_set,
> -	.vlan_strip_queue_set = NULL,
>  	.rx_queue_start       = enicpmd_dev_rx_queue_start,
>  	.rx_queue_stop        = enicpmd_dev_rx_queue_stop,
>  	.tx_queue_start       = enicpmd_dev_tx_queue_start,
> @@ -1151,11 +1145,6 @@ static const struct eth_dev_ops
> enicpmd_eth_dev_ops = {
>  	.txq_info_get         = enicpmd_dev_txq_info_get,
>  	.rx_burst_mode_get    = enicpmd_dev_rx_burst_mode_get,
>  	.tx_burst_mode_get    = enicpmd_dev_tx_burst_mode_get,
> -	.dev_led_on           = NULL,
> -	.dev_led_off          = NULL,
> -	.flow_ctrl_get        = NULL,
> -	.flow_ctrl_set        = NULL,
> -	.priority_flow_ctrl_set = NULL,
>  	.mac_addr_add         = enicpmd_add_mac_addr,
>  	.mac_addr_remove      = enicpmd_remove_mac_addr,
>  	.mac_addr_set         = enicpmd_set_mac_addr,
> --
> 2.53.0

Acked-by: Hyong Youb Kim <hyonkim@cisco.com>

Thanks.
-Hyong


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v2 4/9] net/cnxk: remove queue stats mapping
  2026-07-23 20:28   ` [PATCH v2 4/9] net/cnxk: remove queue stats mapping Stephen Hemminger
@ 2026-07-24  7:26     ` David Marchand
  2026-07-24 15:20       ` Stephen Hemminger
  0 siblings, 1 reply; 45+ messages in thread
From: David Marchand @ 2026-07-24  7:26 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
	Satha Rao, Harman Kalra

On Thu, 23 Jul 2026 at 22:30, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> diff --git a/drivers/net/cnxk/cnxk_stats.c b/drivers/net/cnxk/cnxk_stats.c
> index d57659ef51..e5d29a78b3 100644
> --- a/drivers/net/cnxk/cnxk_stats.c
> +++ b/drivers/net/cnxk/cnxk_stats.c
> @@ -14,7 +14,8 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
>         struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
>         struct roc_nix *nix = &dev->nix;
>         struct roc_nix_stats nix_stats;
> -       int rc = 0, i;
> +       unsigned int i;
> +       int rc = 0;

Nit: rc is set the line after.

>
>         rc = roc_nix_stats_get(nix, &nix_stats);
>         if (rc)
> @@ -33,31 +34,35 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
>         stats->ibytes = nix_stats.rx_octs;
>         stats->ierrors = nix_stats.rx_err;
>
> -       if (qstats != NULL) {
> -               for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
> -                       struct roc_nix_stats_queue qstats_data;
> -                       uint16_t qidx;
> -
> -                       if (dev->txq_stat_map[i] & (1U << 31)) {
> -                               qidx = dev->txq_stat_map[i] & 0xFFFF;
> -                               rc = roc_nix_stats_queue_get(nix, qidx, 0, &qstats_data);
> -                               if (rc)
> -                                       goto exit;
> -                               qstats->q_opackets[i] = qstats_data.tx_pkts;
> -                               qstats->q_obytes[i] = qstats_data.tx_octs;
> -                               qstats->q_errors[i] = qstats_data.tx_drop_pkts;
> -                       }
> -
> -                       if (dev->rxq_stat_map[i] & (1U << 31)) {
> -                               qidx = dev->rxq_stat_map[i] & 0xFFFF;
> -                               rc = roc_nix_stats_queue_get(nix, qidx, 1, &qstats_data);
> -                               if (rc)
> -                                       goto exit;
> -                               qstats->q_ipackets[i] = qstats_data.rx_pkts;
> -                               qstats->q_ibytes[i] = qstats_data.rx_octs;
> -                               qstats->q_errors[i] += qstats_data.rx_drop_pkts;
> -                       }
> -               }
> +       if (qstats == NULL)
> +               goto exit;
> +
> +       for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
> +               struct roc_nix_stats_queue qstats_data;
> +
> +               if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
> +                       break;
> +
> +               rc = roc_nix_stats_queue_get(nix, i, 0, &qstats_data);
> +               if (rc)
> +                       goto exit;
> +               qstats->q_opackets[i] = qstats_data.tx_pkts;
> +               qstats->q_obytes[i] = qstats_data.tx_octs;
> +               qstats->q_errors[i] = qstats_data.tx_drop_pkts;
> +       }
> +
> +       for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
> +               struct roc_nix_stats_queue qstats_data;
> +
> +               if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
> +                       break;
> +
> +               rc = roc_nix_stats_queue_get(nix, i, 1, &qstats_data);
> +               if (rc)
> +                       goto exit;
> +               qstats->q_ipackets[i] = qstats_data.rx_pkts;
> +               qstats->q_ibytes[i] = qstats_data.rx_octs;
> +               qstats->q_errors[i] += qstats_data.rx_drop_pkts;

It was already there, but I find it suspicious that only Rx errors are
handled like those are reset on read.


-- 
David Marchand


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v2 5/9] net/e1000: remove queue stats mapping
  2026-07-23 20:28   ` [PATCH v2 5/9] net/e1000: " Stephen Hemminger
@ 2026-07-24  7:31     ` David Marchand
  2026-08-13 12:26       ` Bruce Richardson
  0 siblings, 1 reply; 45+ messages in thread
From: David Marchand @ 2026-07-24  7:31 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Thu, 23 Jul 2026 at 22:30, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> @@ -2070,19 +2060,11 @@ eth_igc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats,
>         /* Get per-queue statuses */
>         if (qstats) {
>                 for (i = 0; i < IGC_QUEUE_PAIRS_NUM; i++) {
> -                       /* GET TX queue statuses */
> -                       int map_id = igc->txq_stats_map[i];
> -                       if (map_id >= 0) {
> -                               qstats->q_opackets[map_id] += queue_stats->pqgptc[i];
> -                               qstats->q_obytes[map_id] += queue_stats->pqgotc[i];
> -                       }
> -                       /* Get RX queue statuses */
> -                       map_id = igc->rxq_stats_map[i];
> -                       if (map_id >= 0) {
> -                               qstats->q_ipackets[map_id] += queue_stats->pqgprc[i];
> -                               qstats->q_ibytes[map_id] += queue_stats->pqgorc[i];
> -                               qstats->q_errors[map_id] += queue_stats->rqdpc[i];
> -                       }
> +                       qstats->q_opackets[i] += queue_stats->pqgptc[i];
> +                       qstats->q_obytes[i] += queue_stats->pqgotc[i];
> +                       qstats->q_ipackets[i] += queue_stats->pqgprc[i];
> +                       qstats->q_ibytes[i] += queue_stats->pqgorc[i];
> +                       qstats->q_errors[i] += queue_stats->rqdpc[i];
>                 }
>         }
>

I suppose this is harmless.. but strange to read all queues regardless
of what has been configured.


-- 
David Marchand


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v2 0/9] Complete removal of queue stats mapping
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
                     ` (8 preceding siblings ...)
  2026-07-23 20:28   ` [PATCH v2 9/9] ethdev: remove support for " Stephen Hemminger
@ 2026-07-24  7:39   ` David Marchand
  2026-07-24  7:42   ` David Marchand
  10 siblings, 0 replies; 45+ messages in thread
From: David Marchand @ 2026-07-24  7:39 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Thu, 23 Jul 2026 at 22:29, Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> The per-queue stats mapping mechanism (rte_eth_dev_set_{rx,tx}_queue_stats_mapping
> and the queue_stats_mapping_set ethdev op) was a workaround for hardware that
> could only expose a limited number of queue stat registers. It let an application
> fold many queues onto a small set of counters. Since 25.11 queue statistics are
> filled in directly by the ethdev layer indexed by queue id, so the mapping is no
> longer needed; the functions were deprecated then by commit 2863cbd9ee6d.
>
> This series finishes the job. The drivers that still implemented the op are
> converted to report queue stats directly by queue id (bounded by
> RTE_ETHDEV_QUEUE_STAT_CNTRS), and the op, the two public functions, their trace
> points, and the documentation are removed from ethdev. The leftover per-driver
> mapping tables, accessor macros, and init code go away with them.
>
> Also, found some leftover bits from the earlier removal.
>
> Stephen Hemminger (9):
>   net/virtio: remove unused queue stats mapping
>   app/testpmd: remove unused function prototype
>   net/enic: remove unneeded ops initialization
>   net/cnxk: remove queue stats mapping
>   net/e1000: remove queue stats mapping
>   net/ixgbe: remove queue stats mapping
>   net/txgbe: remove queue stats mapping
>   net/sxe2: remove queue stats mapping
>   ethdev: remove support for queue stats mapping
>
>  app/test-pmd/cmdline.c                 |  6 --
>  app/test-pmd/testpmd.h                 |  2 -
>  doc/guides/nics/features.rst           |  7 --
>  doc/guides/rel_notes/deprecation.rst   |  6 --
>  doc/guides/rel_notes/release_26_11.rst |  5 ++
>  drivers/net/cnxk/cnxk_ethdev.c         |  1 -
>  drivers/net/cnxk/cnxk_ethdev.h         |  6 --
>  drivers/net/cnxk/cnxk_stats.c          | 76 ++++++++------------
>  drivers/net/enic/enic_ethdev.c         | 11 ---
>  drivers/net/intel/e1000/igc_ethdev.c   | 54 ++------------
>  drivers/net/intel/e1000/igc_ethdev.h   |  2 -
>  drivers/net/intel/ixgbe/ixgbe_ethdev.c | 97 -------------------------
>  drivers/net/intel/ixgbe/ixgbe_ethdev.h |  9 ---
>  drivers/net/sxe2/sxe2_cmd_chnl.c       | 99 --------------------------
>  drivers/net/sxe2/sxe2_cmd_chnl.h       | 10 ---
>  drivers/net/sxe2/sxe2_ethdev.c         |  5 --
>  drivers/net/sxe2/sxe2_stats.c          | 76 +-------------------
>  drivers/net/sxe2/sxe2_stats.h          |  5 --
>  drivers/net/txgbe/txgbe_ethdev.c       | 87 ++--------------------
>  drivers/net/txgbe/txgbe_ethdev.h       | 13 ----
>  drivers/net/virtio/virtio_ethdev.c     | 21 ------
>  lib/ethdev/ethdev_driver.h             | 11 ---
>  lib/ethdev/ethdev_trace.h              | 20 ------
>  lib/ethdev/ethdev_trace_points.c       |  6 --
>  lib/ethdev/rte_ethdev.c                | 62 ----------------
>  lib/ethdev/rte_ethdev.h                | 45 ------------
>  26 files changed, 53 insertions(+), 689 deletions(-)

I sent two comments but the series itself lgtm.

For the series:
Acked-by: David Marchand <david.marchand@redhat.com>


-- 
David Marchand


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v2 0/9] Complete removal of queue stats mapping
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
                     ` (9 preceding siblings ...)
  2026-07-24  7:39   ` [PATCH v2 0/9] Complete removal of " David Marchand
@ 2026-07-24  7:42   ` David Marchand
  2026-07-24 15:28     ` Stephen Hemminger
  10 siblings, 1 reply; 45+ messages in thread
From: David Marchand @ 2026-07-24  7:42 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Thu, 23 Jul 2026 at 22:29, Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> The per-queue stats mapping mechanism (rte_eth_dev_set_{rx,tx}_queue_stats_mapping
> and the queue_stats_mapping_set ethdev op) was a workaround for hardware that
> could only expose a limited number of queue stat registers. It let an application
> fold many queues onto a small set of counters. Since 25.11 queue statistics are
> filled in directly by the ethdev layer indexed by queue id, so the mapping is no
> longer needed; the functions were deprecated then by commit 2863cbd9ee6d.
>
> This series finishes the job. The drivers that still implemented the op are
> converted to report queue stats directly by queue id (bounded by
> RTE_ETHDEV_QUEUE_STAT_CNTRS), and the op, the two public functions, their trace
> points, and the documentation are removed from ethdev. The leftover per-driver
> mapping tables, accessor macros, and init code go away with them.

Do you have plans to remove this RTE_ETHDEV_QUEUE_STAT_CNTRS limit in
the future?


-- 
David Marchand


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v2 4/9] net/cnxk: remove queue stats mapping
  2026-07-24  7:26     ` David Marchand
@ 2026-07-24 15:20       ` Stephen Hemminger
  0 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-24 15:20 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
	Satha Rao, Harman Kalra

On Fri, 24 Jul 2026 09:26:10 +0200
David Marchand <david.marchand@redhat.com> wrote:

> > +       for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
> > +               struct roc_nix_stats_queue qstats_data;
> > +
> > +               if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
> > +                       break;
> > +
> > +               rc = roc_nix_stats_queue_get(nix, i, 1, &qstats_data);
> > +               if (rc)
> > +                       goto exit;
> > +               qstats->q_ipackets[i] = qstats_data.rx_pkts;
> > +               qstats->q_ibytes[i] = qstats_data.rx_octs;
> > +               qstats->q_errors[i] += qstats_data.rx_drop_pkts;  
> 
> It was already there, but I find it suspicious that only Rx errors are
> handled like those are reset on read.

This was a somewhat automated conversion.
It looks like the rx error counter across all queues is populated
from hardware and rx_drop is counted in software per queue.

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v2 0/9] Complete removal of queue stats mapping
  2026-07-24  7:42   ` David Marchand
@ 2026-07-24 15:28     ` Stephen Hemminger
  0 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-07-24 15:28 UTC (permalink / raw)
  To: David Marchand; +Cc: dev

On Fri, 24 Jul 2026 09:42:09 +0200
David Marchand <david.marchand@redhat.com> wrote:

> Do you have plans to remove this RTE_ETHDEV_QUEUE_STAT_CNTRS limit in
> the future?


No, that is much harder and has bigger impact.

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v2 5/9] net/e1000: remove queue stats mapping
  2026-07-24  7:31     ` David Marchand
@ 2026-08-13 12:26       ` Bruce Richardson
  0 siblings, 0 replies; 45+ messages in thread
From: Bruce Richardson @ 2026-08-13 12:26 UTC (permalink / raw)
  To: David Marchand; +Cc: Stephen Hemminger, dev

On Fri, Jul 24, 2026 at 09:31:21AM +0200, David Marchand wrote:
> On Thu, 23 Jul 2026 at 22:30, Stephen Hemminger
> <stephen@networkplumber.org> wrote:
> > @@ -2070,19 +2060,11 @@ eth_igc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats,
> >         /* Get per-queue statuses */
> >         if (qstats) {
> >                 for (i = 0; i < IGC_QUEUE_PAIRS_NUM; i++) {
> > -                       /* GET TX queue statuses */
> > -                       int map_id = igc->txq_stats_map[i];
> > -                       if (map_id >= 0) {
> > -                               qstats->q_opackets[map_id] += queue_stats->pqgptc[i];
> > -                               qstats->q_obytes[map_id] += queue_stats->pqgotc[i];
> > -                       }
> > -                       /* Get RX queue statuses */
> > -                       map_id = igc->rxq_stats_map[i];
> > -                       if (map_id >= 0) {
> > -                               qstats->q_ipackets[map_id] += queue_stats->pqgprc[i];
> > -                               qstats->q_ibytes[map_id] += queue_stats->pqgorc[i];
> > -                               qstats->q_errors[map_id] += queue_stats->rqdpc[i];
> > -                       }
> > +                       qstats->q_opackets[i] += queue_stats->pqgptc[i];
> > +                       qstats->q_obytes[i] += queue_stats->pqgotc[i];
> > +                       qstats->q_ipackets[i] += queue_stats->pqgprc[i];
> > +                       qstats->q_ibytes[i] += queue_stats->pqgorc[i];
> > +                       qstats->q_errors[i] += queue_stats->rqdpc[i];
> >                 }
> >         }
> >
> 
> I suppose this is harmless.. but strange to read all queues regardless
> of what has been configured.
> 
I'd tend to agree. Even though IGC_QUEUE_PAIRS_NUM is set to just 4, I'd
still check for each of the stats if it's less than configured rxq's or
txq's.

Otherwise:
Acked-by: Bruce Richardson <bruce.richardson@intel.com>


^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS
  2026-05-30 16:09 [RFC 0/7] Complete removal of queue stats mapping Stephen Hemminger
                   ` (7 preceding siblings ...)
  2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
@ 2026-08-13 17:54 ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 01/16] net/virtio: remove unused queue stats mapping Stephen Hemminger
                     ` (15 more replies)
  8 siblings, 16 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:54 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This patch series completes the removal (with help of AI) of the queue
stats counters an mapping. There are also a couple of uncovered bugs
in the process.

The per-queue stats mapping mechanism (rte_eth_dev_set_{rx,tx}_queue_stats_mapping
and the queue_stats_mapping_set ethdev op) was a workaround for hardware that
could only expose a limited number of queue stat registers. It let an application
fold many queues onto a small set of counters. Since 25.11 queue statistics are
filled in directly by the ethdev layer indexed by queue id, so the mapping is no
longer needed; the functions were deprecated then by commit 2863cbd9ee6d.

Tried to split out the bug fixes where possible.

The big patch is a tree wide removal of RTE_ETHDEV_QUEUE_STAT_CNTRS.
Instead the rte_ethdev allocates the temporary qstats array based
on what the driver reports as number of queues; before querying the
driver for its stats. The error counters are no longer per-queue
because that wasn't that helpful, instead error counters are global.

The same logic to map per-queue stats into xstats still exists and
the user visible xstats remain the same. The impact is only to the
driver API.

Also added test for statistics in pmd_ring test to make sure
there is test coverage.

Stephen Hemminger (16):
  net/virtio: remove unused queue stats mapping
  app/testpmd: remove leftover set qmap
  net/enic: remove unneeded ops initialization
  net/cnxk: fix Tx drops added to Rx queue errors
  net/cnxk: remove queue stats mapping
  net/e1000: remove queue stats mapping
  net/ixgbe: remove queue stats mapping
  net/txgbe: remove queue stats mapping
  net/sxe2: fix null dereference in stats get
  net/sxe2: remove queue stats mapping
  ethdev: remove support for queue stats mapping
  net/mvpp2: fix out of range Tx queue stats write
  net/ntnic: fix Tx errors reported as Rx queue errors
  net/xsc: fix Tx errors added to Rx queue errors
  ethdev: remove queue stats counter limit
  test/pmd_ring: test per-queue xstats

 app/test-pmd/cmdline.c                        |   6 -
 app/test-pmd/testpmd.h                        |   2 -
 app/test/test_pmd_ring.c                      | 145 ++++++++++++++++++
 doc/guides/howto/debug_troubleshoot.rst       |   5 +-
 doc/guides/nics/bnxt.rst                      |   4 +-
 doc/guides/nics/features.rst                  |  12 +-
 doc/guides/rel_notes/deprecation.rst          |   6 -
 doc/guides/rel_notes/release_26_11.rst        |   9 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst   |  11 --
 drivers/net/af_packet/rte_eth_af_packet.c     |  15 +-
 drivers/net/af_xdp/rte_eth_af_xdp.c           |  13 +-
 drivers/net/ark/ark_ethdev_rx.c               |   7 +-
 drivers/net/ark/ark_ethdev_tx.c               |   6 +-
 drivers/net/atlantic/atl_ethdev.c             |  13 +-
 drivers/net/atlantic/atl_rxtx.c               |   8 +-
 drivers/net/atlantic/atl_types.h              |  15 +-
 drivers/net/avp/avp_ethdev.c                  |  13 +-
 drivers/net/axgbe/axgbe_ethdev.c              |  13 +-
 drivers/net/bnxt/bnxt_ethdev.c                |   5 -
 drivers/net/bnxt/bnxt_reps.c                  |   9 +-
 drivers/net/bnxt/bnxt_stats.c                 |  40 ++---
 drivers/net/cnxk/cnxk_ethdev.c                |   1 -
 drivers/net/cnxk/cnxk_ethdev.h                |   6 -
 drivers/net/cnxk/cnxk_rep_ops.c               |   8 +-
 drivers/net/cnxk/cnxk_stats.c                 |  67 +++-----
 drivers/net/dpaa2/dpaa2_ethdev.c              |  17 +-
 drivers/net/ena/ena_ethdev.c                  |  21 +--
 drivers/net/enic/enic_ethdev.c                |  11 --
 drivers/net/hinic/hinic_pmd_ethdev.c          |  17 +-
 drivers/net/hinic3/hinic3_ethdev.c            |  13 +-
 drivers/net/intel/e1000/igc_ethdev.c          |  57 ++-----
 drivers/net/intel/e1000/igc_ethdev.h          |   2 -
 drivers/net/intel/fm10k/fm10k_ethdev.c        |  16 +-
 drivers/net/intel/ixgbe/ixgbe_ethdev.c        | 137 ++++-------------
 drivers/net/intel/ixgbe/ixgbe_ethdev.h        |   9 --
 drivers/net/ionic/ionic_lif.c                 |  24 +--
 drivers/net/mana/mana.c                       |  12 +-
 drivers/net/memif/rte_eth_memif.c             |  16 +-
 drivers/net/mlx4/mlx4_ethdev.c                |  14 +-
 drivers/net/mlx5/mlx5_rx.h                    |   3 +-
 drivers/net/mlx5/mlx5_stats.c                 |  22 ++-
 drivers/net/mvpp2/mrvl_ethdev.c               |  21 ++-
 drivers/net/nbl/nbl_dev/nbl_dev.c             |   2 -
 drivers/net/nbl/nbl_hw/nbl_txrx.c             |  12 +-
 drivers/net/netvsc/hn_ethdev.c                |  12 +-
 drivers/net/netvsc/hn_vf.c                    |   3 +-
 drivers/net/nfb/nfb_stats.c                   |  12 +-
 drivers/net/nfp/flower/nfp_flower.c           |   8 +-
 .../net/nfp/flower/nfp_flower_representor.c   |  32 ++--
 .../net/nfp/flower/nfp_flower_representor.h   |   4 +-
 drivers/net/nfp/nfp_ethdev.c                  |  13 ++
 drivers/net/nfp/nfp_ethdev_vf.c               |  13 ++
 drivers/net/nfp/nfp_net_common.c              |  36 ++---
 drivers/net/nfp/nfp_net_common.h              |   3 +-
 drivers/net/ngbe/ngbe_ethdev.c                |  34 +---
 drivers/net/ngbe/ngbe_ethdev.h                |  12 --
 drivers/net/ntnic/ntnic_ethdev.c              |  13 +-
 drivers/net/null/rte_eth_null.c               |  12 +-
 drivers/net/octeon_ep/otx_ep_ethdev.c         |  13 +-
 drivers/net/pcap/pcap_ethdev.c                |  14 +-
 drivers/net/qede/qede_ethdev.c                |  36 +----
 drivers/net/ring/rte_eth_ring.c               |  10 +-
 drivers/net/rnp/rnp_ethdev.c                  |  12 +-
 drivers/net/sxe2/sxe2_cmd_chnl.c              | 119 ++------------
 drivers/net/sxe2/sxe2_cmd_chnl.h              |  10 --
 drivers/net/sxe2/sxe2_ethdev.c                |   5 -
 drivers/net/sxe2/sxe2_mp.c                    |  17 +-
 drivers/net/sxe2/sxe2_mp.h                    |   7 +-
 drivers/net/sxe2/sxe2_stats.c                 |  84 +---------
 drivers/net/sxe2/sxe2_stats.h                 |   5 -
 drivers/net/tap/rte_eth_tap.c                 |  12 +-
 drivers/net/thunderx/nicvf_ethdev.c           |  24 +--
 drivers/net/txgbe/txgbe_ethdev.c              |  89 +----------
 drivers/net/txgbe/txgbe_ethdev.h              |  13 --
 drivers/net/vhost/rte_eth_vhost.c             |  14 +-
 drivers/net/virtio/virtio_ethdev.c            |  33 +---
 drivers/net/vmxnet3/vmxnet3_ethdev.c          |  13 +-
 drivers/net/xsc/xsc_ethdev.c                  |  15 +-
 drivers/net/zxdh/zxdh_ethdev_ops.c            |  24 +--
 lib/ethdev/ethdev_driver.h                    |  38 ++---
 lib/ethdev/ethdev_private.c                   |   2 -
 lib/ethdev/ethdev_trace.h                     |  20 ---
 lib/ethdev/ethdev_trace_points.c              |   6 -
 lib/ethdev/rte_ethdev.c                       | 128 +++++-----------
 lib/ethdev/rte_ethdev.h                       |  45 ------
 85 files changed, 665 insertions(+), 1215 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH v3 01/16] net/virtio: remove unused queue stats mapping
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 02/16] app/testpmd: remove leftover set qmap Stephen Hemminger
                     ` (14 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Maxime Coquelin, Chenbo Xia

The queue_stats_mapping op in virtio looks like a vestige
from when it was needed to get per queue stats. That hasn't
been true since 25.11 release.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/virtio/virtio_ethdev.c | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 9fd746b80f..0b2574bd02 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -90,12 +90,6 @@ static int virtio_intr_disable(struct rte_eth_dev *dev);
 static int virtio_get_monitor_addr(void *rx_queue,
 				struct rte_power_monitor_cond *pmc);
 
-static int virtio_dev_queue_stats_mapping_set(
-	struct rte_eth_dev *eth_dev,
-	uint16_t queue_id,
-	uint8_t stat_idx,
-	uint8_t is_rx);
-
 static void virtio_notify_peers(struct rte_eth_dev *dev);
 static void virtio_ack_link_announce(struct rte_eth_dev *dev);
 
@@ -672,8 +666,6 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 	.rss_hash_conf_get       = virtio_dev_rss_hash_conf_get,
 	.reta_update             = virtio_dev_rss_reta_update,
 	.reta_query              = virtio_dev_rss_reta_query,
-	/* collect stats per queue */
-	.queue_stats_mapping_set = virtio_dev_queue_stats_mapping_set,
 	.vlan_filter_set         = virtio_vlan_filter_set,
 	.mac_addr_add            = virtio_mac_addr_add,
 	.mac_addr_remove         = virtio_mac_addr_remove,
@@ -693,8 +685,6 @@ const struct eth_dev_ops virtio_user_secondary_eth_dev_ops = {
 	.xstats_get_names        = virtio_dev_xstats_get_names,
 	.stats_reset             = virtio_dev_stats_reset,
 	.xstats_reset            = virtio_dev_stats_reset,
-	/* collect stats per queue */
-	.queue_stats_mapping_set = virtio_dev_queue_stats_mapping_set,
 };
 
 static void
@@ -2823,16 +2813,5 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	return 0;
 }
 
-/*
- * It enables testpmd to collect per queue stats.
- */
-static int
-virtio_dev_queue_stats_mapping_set(__rte_unused struct rte_eth_dev *eth_dev,
-__rte_unused uint16_t queue_id, __rte_unused uint8_t stat_idx,
-__rte_unused uint8_t is_rx)
-{
-	return 0;
-}
-
 RTE_LOG_REGISTER_SUFFIX(virtio_logtype_init, init, NOTICE);
 RTE_LOG_REGISTER_SUFFIX(virtio_logtype_driver, driver, NOTICE);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 02/16] app/testpmd: remove leftover set qmap
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 01/16] net/virtio: remove unused queue stats mapping Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 03/16] net/enic: remove unneeded ops initialization Stephen Hemminger
                     ` (13 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, stable, Aman Singh, Bruce Richardson

The function set_qmap was removed in 25.11 release but
the prototype was still there.

Also, remove leftover help text.

Fixes: 2863cbd9ee6d ("ethdev: deprecate queue stats mapping functions")
Cc: stable@dpdk.org

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/cmdline.c                      |  6 ------
 app/test-pmd/testpmd.h                      |  2 --
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 11 -----------
 3 files changed, 19 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 10ee7c5179..d299edb88e 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -581,12 +581,6 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set port (port_id) rxq (queue_id) avail_thresh (0..99)>\n "
 			"    set available descriptors threshold for Rx queue\n\n"
 
-			"set stat_qmap (tx|rx) (port_id) (queue_id) (qmapping)\n"
-			"    Set statistics mapping (qmapping 0..15) for RX/TX"
-			" queue on port.\n"
-			"    e.g., 'set stat_qmap rx 0 2 5' sets rx queue 2"
-			" on port 0 to mapping 5.\n\n"
-
 			"set xstats-hide-zero on|off\n"
 			"    Set the option to hide the zero values"
 			" for xstats display.\n"
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 083171853c..b5643e74f5 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -1158,8 +1158,6 @@ void tx_qinq_set(portid_t port_id, uint16_t vlan_tci, uint16_t vlan_tci_outer);
 void tx_vlan_reset(portid_t port_id);
 void tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on);
 
-void set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value);
-
 void set_xstats_hide_zero(uint8_t on_off);
 void set_xstats_show_state(uint8_t on_off);
 void set_xstats_hide_disabled(uint8_t on_off);
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index e65376df54..30cac0ad8c 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1554,17 +1554,6 @@ Set available descriptors threshold for a specific Rx queue of port::
 
 Use 0 value to disable the threshold and corresponding event.
 
-set stat_qmap
-~~~~~~~~~~~~~
-
-Set statistics mapping (qmapping 0..15) for RX/TX queue on port::
-
-   testpmd> set stat_qmap (tx|rx) (port_id) (queue_id) (qmapping)
-
-For example, to set rx queue 2 on port 0 to mapping 5::
-
-   testpmd>set stat_qmap rx 0 2 5
-
 set xstats-hide-zero
 ~~~~~~~~~~~~~~~~~~~~
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 03/16] net/enic: remove unneeded ops initialization
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 01/16] net/virtio: remove unused queue stats mapping Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 02/16] app/testpmd: remove leftover set qmap Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 04/16] net/cnxk: fix Tx drops added to Rx queue errors Stephen Hemminger
                     ` (12 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Hyong Youb Kim, John Daley

Better to just let compiler initialize fields to NULL since then
if fields change that driver doesn't use, the driver source
will not need to be changed.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Hyong Youb Kim <hyonkim@cisco.com>
---
 drivers/net/enic/enic_ethdev.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2e5cd186f9..648aa67a85 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -1119,8 +1119,6 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.dev_configure        = enicpmd_dev_configure,
 	.dev_start            = enicpmd_dev_start,
 	.dev_stop             = enicpmd_dev_stop,
-	.dev_set_link_up      = NULL,
-	.dev_set_link_down    = NULL,
 	.dev_close            = enicpmd_dev_close,
 	.promiscuous_enable   = enicpmd_dev_promiscuous_enable,
 	.promiscuous_disable  = enicpmd_dev_promiscuous_disable,
@@ -1129,14 +1127,10 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.link_update          = enicpmd_dev_link_update,
 	.stats_get            = enicpmd_dev_stats_get,
 	.stats_reset          = enicpmd_dev_stats_reset,
-	.queue_stats_mapping_set = NULL,
 	.dev_infos_get        = enicpmd_dev_info_get,
 	.dev_supported_ptypes_get = enicpmd_dev_supported_ptypes_get,
 	.mtu_set              = enicpmd_mtu_set,
-	.vlan_filter_set      = NULL,
-	.vlan_tpid_set        = NULL,
 	.vlan_offload_set     = enicpmd_vlan_offload_set,
-	.vlan_strip_queue_set = NULL,
 	.rx_queue_start       = enicpmd_dev_rx_queue_start,
 	.rx_queue_stop        = enicpmd_dev_rx_queue_stop,
 	.tx_queue_start       = enicpmd_dev_tx_queue_start,
@@ -1151,11 +1145,6 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.txq_info_get         = enicpmd_dev_txq_info_get,
 	.rx_burst_mode_get    = enicpmd_dev_rx_burst_mode_get,
 	.tx_burst_mode_get    = enicpmd_dev_tx_burst_mode_get,
-	.dev_led_on           = NULL,
-	.dev_led_off          = NULL,
-	.flow_ctrl_get        = NULL,
-	.flow_ctrl_set        = NULL,
-	.priority_flow_ctrl_set = NULL,
 	.mac_addr_add         = enicpmd_add_mac_addr,
 	.mac_addr_remove      = enicpmd_remove_mac_addr,
 	.mac_addr_set         = enicpmd_set_mac_addr,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 04/16] net/cnxk: fix Tx drops added to Rx queue errors
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (2 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 03/16] net/enic: remove unneeded ops initialization Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 05/16] net/cnxk: remove queue stats mapping Stephen Hemminger
                     ` (11 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, stable, Nithin Dabilpuram, Kiran Kumar K,
	Sunil Kumar Kori, Satha Rao, Harman Kalra, Hemant Agrawal,
	Bruce Richardson

q_errors counts received packets dropped, and is reported as the
rx_qN_errors xstat. The Tx branch assigns the Tx drop count and the Rx
branch adds to it, so rx_qN_errors reports both. Stat indexes with only
a Tx mapping hold Tx drops alone.

Tx drops are already counted in oerrors, so drop the assignment and
store the Rx drop count directly.

Fixes: 58ae74244c90 ("ethdev: remove queue stats from basic stats structure")
Cc: stable@dpdk.org

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/cnxk/cnxk_stats.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/cnxk/cnxk_stats.c b/drivers/net/cnxk/cnxk_stats.c
index d57659ef51..6c812bd732 100644
--- a/drivers/net/cnxk/cnxk_stats.c
+++ b/drivers/net/cnxk/cnxk_stats.c
@@ -45,7 +45,6 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
 					goto exit;
 				qstats->q_opackets[i] = qstats_data.tx_pkts;
 				qstats->q_obytes[i] = qstats_data.tx_octs;
-				qstats->q_errors[i] = qstats_data.tx_drop_pkts;
 			}
 
 			if (dev->rxq_stat_map[i] & (1U << 31)) {
@@ -55,7 +54,7 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
 					goto exit;
 				qstats->q_ipackets[i] = qstats_data.rx_pkts;
 				qstats->q_ibytes[i] = qstats_data.rx_octs;
-				qstats->q_errors[i] += qstats_data.rx_drop_pkts;
+				qstats->q_errors[i] = qstats_data.rx_drop_pkts;
 			}
 		}
 	}
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 05/16] net/cnxk: remove queue stats mapping
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (3 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 04/16] net/cnxk: fix Tx drops added to Rx queue errors Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 06/16] net/e1000: " Stephen Hemminger
                     ` (10 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, Nithin Dabilpuram, Kiran Kumar K,
	Sunil Kumar Kori, Satha Rao, Harman Kalra

The queue stats mapping feature has been deprecated since 25.11.
Remove support in this driver for stats map.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/cnxk/cnxk_ethdev.c |  1 -
 drivers/net/cnxk/cnxk_ethdev.h |  6 ---
 drivers/net/cnxk/cnxk_stats.c  | 73 ++++++++++++++--------------------
 3 files changed, 29 insertions(+), 51 deletions(-)

diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index c41959173b..9a4da870cd 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -2103,7 +2103,6 @@ struct eth_dev_ops cnxk_eth_dev_ops = {
 	.rx_queue_intr_enable = cnxk_nix_rx_queue_intr_enable,
 	.rx_queue_intr_disable = cnxk_nix_rx_queue_intr_disable,
 	.pool_ops_supported = cnxk_nix_pool_ops_supported,
-	.queue_stats_mapping_set = cnxk_nix_queue_stats_mapping,
 	.stats_get = cnxk_nix_stats_get,
 	.stats_reset = cnxk_nix_stats_reset,
 	.xstats_get = cnxk_nix_xstats_get,
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index fc66135c66..5dd74de577 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -423,10 +423,6 @@ struct cnxk_eth_dev {
 	/* LSO Tunnel format indices */
 	uint64_t lso_tun_fmt;
 
-	/* Per queue statistics counters */
-	uint32_t txq_stat_map[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-	uint32_t rxq_stat_map[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-
 	/* Security data */
 	struct cnxk_eth_dev_sec_inb inb;
 	struct cnxk_eth_dev_sec_outb outb;
@@ -700,8 +696,6 @@ void cnxk_eth_dev_link_status_get_cb(struct roc_nix *nix,
 void cnxk_eth_dev_q_err_cb(struct roc_nix *nix, void *data);
 int cnxk_nix_link_info_configure(struct rte_eth_dev *eth_dev);
 int cnxk_nix_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete);
-int cnxk_nix_queue_stats_mapping(struct rte_eth_dev *dev, uint16_t queue_id,
-				 uint8_t stat_idx, uint8_t is_rx);
 int cnxk_nix_stats_reset(struct rte_eth_dev *dev);
 int cnxk_nix_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		       struct eth_queue_stats *qstats);
diff --git a/drivers/net/cnxk/cnxk_stats.c b/drivers/net/cnxk/cnxk_stats.c
index 6c812bd732..469a18f93e 100644
--- a/drivers/net/cnxk/cnxk_stats.c
+++ b/drivers/net/cnxk/cnxk_stats.c
@@ -14,7 +14,7 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
 	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
 	struct roc_nix *nix = &dev->nix;
 	struct roc_nix_stats nix_stats;
-	int rc = 0, i;
+	int rc, i;
 
 	rc = roc_nix_stats_get(nix, &nix_stats);
 	if (rc)
@@ -33,30 +33,34 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
 	stats->ibytes = nix_stats.rx_octs;
 	stats->ierrors = nix_stats.rx_err;
 
-	if (qstats != NULL) {
-		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
-			struct roc_nix_stats_queue qstats_data;
-			uint16_t qidx;
-
-			if (dev->txq_stat_map[i] & (1U << 31)) {
-				qidx = dev->txq_stat_map[i] & 0xFFFF;
-				rc = roc_nix_stats_queue_get(nix, qidx, 0, &qstats_data);
-				if (rc)
-					goto exit;
-				qstats->q_opackets[i] = qstats_data.tx_pkts;
-				qstats->q_obytes[i] = qstats_data.tx_octs;
-			}
-
-			if (dev->rxq_stat_map[i] & (1U << 31)) {
-				qidx = dev->rxq_stat_map[i] & 0xFFFF;
-				rc = roc_nix_stats_queue_get(nix, qidx, 1, &qstats_data);
-				if (rc)
-					goto exit;
-				qstats->q_ipackets[i] = qstats_data.rx_pkts;
-				qstats->q_ibytes[i] = qstats_data.rx_octs;
-				qstats->q_errors[i] = qstats_data.rx_drop_pkts;
-			}
-		}
+	if (qstats == NULL)
+		goto exit;
+
+	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+		struct roc_nix_stats_queue qstats_data;
+
+		if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+			break;
+
+		rc = roc_nix_stats_queue_get(nix, i, 0, &qstats_data);
+		if (rc)
+			goto exit;
+		qstats->q_opackets[i] = qstats_data.tx_pkts;
+		qstats->q_obytes[i] = qstats_data.tx_octs;
+	}
+
+	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
+		struct roc_nix_stats_queue qstats_data;
+
+		if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+			break;
+
+		rc = roc_nix_stats_queue_get(nix, i, 1, &qstats_data);
+		if (rc)
+			goto exit;
+		qstats->q_ipackets[i] = qstats_data.rx_pkts;
+		qstats->q_ibytes[i] = qstats_data.rx_octs;
+		qstats->q_errors[i] = qstats_data.rx_drop_pkts;
 	}
 exit:
 	return rc;
@@ -70,25 +74,6 @@ cnxk_nix_stats_reset(struct rte_eth_dev *eth_dev)
 	return roc_nix_stats_reset(&dev->nix);
 }
 
-int
-cnxk_nix_queue_stats_mapping(struct rte_eth_dev *eth_dev, uint16_t queue_id,
-			     uint8_t stat_idx, uint8_t is_rx)
-{
-	struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
-
-	if (is_rx) {
-		if (queue_id >= dev->nb_rxq)
-			return -EINVAL;
-		dev->rxq_stat_map[stat_idx] = ((1U << 31) | queue_id);
-	} else {
-		if (queue_id >= dev->nb_txq)
-			return -EINVAL;
-		dev->txq_stat_map[stat_idx] = ((1U << 31) | queue_id);
-	}
-
-	return 0;
-}
-
 int
 cnxk_nix_xstats_get(struct rte_eth_dev *eth_dev, struct rte_eth_xstat *xstats,
 		    unsigned int n)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 06/16] net/e1000: remove queue stats mapping
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (4 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 05/16] net/cnxk: remove queue stats mapping Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 07/16] net/ixgbe: " Stephen Hemminger
                     ` (9 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

Support for queue stats mapping has been deprecated since 25.11.
Remove support for this operation in the e1000 driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/intel/e1000/igc_ethdev.c | 56 ++++------------------------
 drivers/net/intel/e1000/igc_ethdev.h |  2 -
 2 files changed, 8 insertions(+), 50 deletions(-)

diff --git a/drivers/net/intel/e1000/igc_ethdev.c b/drivers/net/intel/e1000/igc_ethdev.c
index de35da2c36..943a479f9a 100644
--- a/drivers/net/intel/e1000/igc_ethdev.c
+++ b/drivers/net/intel/e1000/igc_ethdev.c
@@ -239,9 +239,7 @@ static int eth_igc_xstats_get_names_by_id(struct rte_eth_dev *dev,
 		const uint64_t *ids, struct rte_eth_xstat_name *xstats_names,
 		unsigned int limit);
 static int eth_igc_xstats_reset(struct rte_eth_dev *dev);
-static int
-eth_igc_queue_stats_mapping_set(struct rte_eth_dev *dev,
-	uint16_t queue_id, uint8_t stat_idx, uint8_t is_rx);
+
 static int
 eth_igc_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);
 static int
@@ -317,7 +315,6 @@ static const struct eth_dev_ops eth_igc_ops = {
 	.xstats_get_names	= eth_igc_xstats_get_names,
 	.stats_reset		= eth_igc_xstats_reset,
 	.xstats_reset		= eth_igc_xstats_reset,
-	.queue_stats_mapping_set = eth_igc_queue_stats_mapping_set,
 	.rx_queue_intr_enable	= eth_igc_rx_queue_intr_enable,
 	.rx_queue_intr_disable	= eth_igc_rx_queue_intr_disable,
 	.flow_ctrl_get		= eth_igc_flow_ctrl_get,
@@ -1362,7 +1359,7 @@ eth_igc_dev_init(struct rte_eth_dev *dev)
 	struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(dev, *pci_dev);
 	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
 	struct e1000_hw *hw = IGC_DEV_PRIVATE_HW(dev);
-	int i, error = 0;
+	int error = 0;
 
 	PMD_INIT_FUNC_TRACE();
 	dev->dev_ops = &eth_igc_ops;
@@ -1493,12 +1490,6 @@ eth_igc_dev_init(struct rte_eth_dev *dev)
 	/* enable support intr */
 	igc_intr_other_enable(dev);
 
-	/* initiate queue status */
-	for (i = 0; i < IGC_QUEUE_PAIRS_NUM; i++) {
-		igc->txq_stats_map[i] = -1;
-		igc->rxq_stats_map[i] = -1;
-	}
-
 	igc_flow_init(dev);
 	igc_clear_all_filter(dev);
 	return 0;
@@ -2031,7 +2022,6 @@ static int
 eth_igc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats,
 		struct eth_queue_stats *qstats)
 {
-	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
 	struct e1000_hw *hw = IGC_DEV_PRIVATE_HW(dev);
 	struct e1000_hw_stats *stats = IGC_DEV_PRIVATE_STATS(dev);
 	struct igc_hw_queue_stats *queue_stats =
@@ -2069,20 +2059,12 @@ eth_igc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats,
 
 	/* Get per-queue statuses */
 	if (qstats) {
-		for (i = 0; i < IGC_QUEUE_PAIRS_NUM; i++) {
-			/* GET TX queue statuses */
-			int map_id = igc->txq_stats_map[i];
-			if (map_id >= 0) {
-				qstats->q_opackets[map_id] += queue_stats->pqgptc[i];
-				qstats->q_obytes[map_id] += queue_stats->pqgotc[i];
-			}
-			/* Get RX queue statuses */
-			map_id = igc->rxq_stats_map[i];
-			if (map_id >= 0) {
-				qstats->q_ipackets[map_id] += queue_stats->pqgprc[i];
-				qstats->q_ibytes[map_id] += queue_stats->pqgorc[i];
-				qstats->q_errors[map_id] += queue_stats->rqdpc[i];
-			}
+		for (i = 0; i < RTE_MIN(IGC_QUEUE_PAIRS_NUM, RTE_ETHDEV_QUEUE_STAT_CNTRS); i++) {
+			qstats->q_opackets[i] += queue_stats->pqgptc[i];
+			qstats->q_obytes[i] += queue_stats->pqgotc[i];
+			qstats->q_ipackets[i] += queue_stats->pqgprc[i];
+			qstats->q_ibytes[i] += queue_stats->pqgorc[i];
+			qstats->q_errors[i] += queue_stats->rqdpc[i];
 		}
 	}
 
@@ -2231,28 +2213,6 @@ eth_igc_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 	}
 }
 
-static int
-eth_igc_queue_stats_mapping_set(struct rte_eth_dev *dev,
-		uint16_t queue_id, uint8_t stat_idx, uint8_t is_rx)
-{
-	struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
-
-	/* check queue id is valid */
-	if (queue_id >= IGC_QUEUE_PAIRS_NUM) {
-		PMD_DRV_LOG(ERR, "queue id(%u) error, max is %u",
-			queue_id, IGC_QUEUE_PAIRS_NUM - 1);
-		return -EINVAL;
-	}
-
-	/* store the mapping status id */
-	if (is_rx)
-		igc->rxq_stats_map[queue_id] = stat_idx;
-	else
-		igc->txq_stats_map[queue_id] = stat_idx;
-
-	return 0;
-}
-
 static int
 eth_igc_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
diff --git a/drivers/net/intel/e1000/igc_ethdev.h b/drivers/net/intel/e1000/igc_ethdev.h
index 7fa7877adf..96ff520da7 100644
--- a/drivers/net/intel/e1000/igc_ethdev.h
+++ b/drivers/net/intel/e1000/igc_ethdev.h
@@ -227,8 +227,6 @@ struct igc_adapter {
 	struct e1000_hw		hw;
 	struct e1000_hw_stats	stats;
 	struct igc_hw_queue_stats queue_stats;
-	int16_t txq_stats_map[IGC_QUEUE_PAIRS_NUM];
-	int16_t rxq_stats_map[IGC_QUEUE_PAIRS_NUM];
 
 	struct igc_interrupt	intr;
 	struct igc_vfta	shadow_vfta;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 07/16] net/ixgbe: remove queue stats mapping
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (5 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 06/16] net/e1000: " Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 08/16] net/txgbe: " Stephen Hemminger
                     ` (8 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Anatoly Burakov, Vladimir Medvedkin

The support for queue_stats_map has been deprecated since 25.11.
Remove support for queue mapping in ixgbe driver.

Unlike other drivers where the mapping was a software renumbering,
the ixgbe per-queue counters (QPRC/QPTC/QBRC/QBTC/QPRDC) are routed
by the RQSMR and TQSM registers which must be programmed after reset.
These were previously zeroed at probe, which routes every queue to
counter 0, and relied on the application to program a mapping.

Program the identity mapping instead, so queue N is counted by
counter N without application involvement. DCB still overrides this
with its own per traffic class mapping when configured.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/intel/ixgbe/ixgbe_ethdev.c | 123 ++++---------------------
 drivers/net/intel/ixgbe/ixgbe_ethdev.h |   9 --
 2 files changed, 19 insertions(+), 113 deletions(-)

diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.c b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
index c5010f623c..d35da73d69 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
@@ -182,10 +182,6 @@ static int ixgbe_dev_xstats_get_names_by_id(
 	const uint64_t *ids,
 	struct rte_eth_xstat_name *xstats_names,
 	unsigned int limit);
-static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
-					     uint16_t queue_id,
-					     uint8_t stat_idx,
-					     uint8_t is_rx);
 static int ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
 				 size_t fw_size);
 static int ixgbe_dev_info_get(struct rte_eth_dev *dev,
@@ -511,7 +507,6 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.xstats_reset         = ixgbe_dev_xstats_reset,
 	.xstats_get_names     = ixgbe_dev_xstats_get_names,
 	.xstats_get_names_by_id = ixgbe_dev_xstats_get_names_by_id,
-	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
 	.fw_version_get       = ixgbe_fw_version_get,
 	.dev_infos_get        = ixgbe_dev_info_get,
 	.dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
@@ -870,109 +865,31 @@ ixgbe_disable_intr(struct ixgbe_hw *hw)
 }
 
 /*
- * This function resets queue statistics mapping registers.
+ * This function programs the queue statistics mapping registers.
  * From Niantic datasheet, Initialization of Statistics section:
  * "...if software requires the queue counters, the RQSMR and TQSM registers
  * must be re-programmed following a device reset.
+ *
+ * Each register maps four queues, one 8 bit field per queue, of which only
+ * the low four bits select one of the IXGBE_QUEUE_STAT_COUNTERS counters.
+ * Program the identity mapping so that queue N is counted by counter N,
+ * wrapping for queues beyond the number of available counters.
+ *
+ * Note: DCB overrides this with a per traffic class mapping when it is
+ * configured later in ixgbe_dev_rx_init().
  */
 static void
-ixgbe_reset_qstat_mappings(struct ixgbe_hw *hw)
-{
-	uint32_t i;
-
-	for (i = 0; i != IXGBE_NB_STAT_MAPPING_REGS; i++) {
-		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), 0);
-		IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), 0);
-	}
-}
-
-
-static int
-ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
-				  uint16_t queue_id,
-				  uint8_t stat_idx,
-				  uint8_t is_rx)
-{
-#define QSM_REG_NB_BITS_PER_QMAP_FIELD 8
-#define NB_QMAP_FIELDS_PER_QSM_REG 4
-#define QMAP_FIELD_RESERVED_BITS_MASK 0x0f
-
-	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
-	struct ixgbe_stat_mapping_registers *stat_mappings =
-		IXGBE_DEV_PRIVATE_TO_STAT_MAPPINGS(eth_dev->data->dev_private);
-	uint32_t qsmr_mask = 0;
-	uint32_t clearing_mask = QMAP_FIELD_RESERVED_BITS_MASK;
-	uint32_t q_map;
-	uint8_t n, offset;
-
-	if ((hw->mac.type != ixgbe_mac_82599EB) &&
-		(hw->mac.type != ixgbe_mac_X540) &&
-		(hw->mac.type != ixgbe_mac_X550) &&
-		(hw->mac.type != ixgbe_mac_X550EM_x) &&
-		(hw->mac.type != ixgbe_mac_X550EM_a) &&
-		(hw->mac.type != ixgbe_mac_E610))
-		return -ENOSYS;
-
-	PMD_INIT_LOG(DEBUG, "Setting port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-
-	n = (uint8_t)(queue_id / NB_QMAP_FIELDS_PER_QSM_REG);
-	if (n >= IXGBE_NB_STAT_MAPPING_REGS) {
-		PMD_INIT_LOG(ERR, "Nb of stat mapping registers exceeded");
-		return -EIO;
-	}
-	offset = (uint8_t)(queue_id % NB_QMAP_FIELDS_PER_QSM_REG);
-
-	/* Now clear any previous stat_idx set */
-	clearing_mask <<= (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] &= ~clearing_mask;
-	else
-		stat_mappings->rqsmr[n] &= ~clearing_mask;
-
-	q_map = (uint32_t)stat_idx;
-	q_map &= QMAP_FIELD_RESERVED_BITS_MASK;
-	qsmr_mask = q_map << (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] |= qsmr_mask;
-	else
-		stat_mappings->rqsmr[n] |= qsmr_mask;
-
-	PMD_INIT_LOG(DEBUG, "Set port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-	PMD_INIT_LOG(DEBUG, "%s[%d] = 0x%08x", is_rx ? "RQSMR" : "TQSM", n,
-		     is_rx ? stat_mappings->rqsmr[n] : stat_mappings->tqsm[n]);
-
-	/* Now write the mapping in the appropriate register */
-	if (is_rx) {
-		PMD_INIT_LOG(DEBUG, "Write 0x%x to RX IXGBE stat mapping reg:%d",
-			     stat_mappings->rqsmr[n], n);
-		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(n), stat_mappings->rqsmr[n]);
-	} else {
-		PMD_INIT_LOG(DEBUG, "Write 0x%x to TX IXGBE stat mapping reg:%d",
-			     stat_mappings->tqsm[n], n);
-		IXGBE_WRITE_REG(hw, IXGBE_TQSM(n), stat_mappings->tqsm[n]);
-	}
-	return 0;
-}
-
-static void
-ixgbe_restore_statistics_mapping(struct rte_eth_dev *dev)
+ixgbe_init_qstat_mappings(struct ixgbe_hw *hw)
 {
-	struct ixgbe_stat_mapping_registers *stat_mappings =
-		IXGBE_DEV_PRIVATE_TO_STAT_MAPPINGS(dev->data->dev_private);
-	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	int i;
+	uint32_t i, reg;
 
-	/* write whatever was in stat mapping table to the NIC */
-	for (i = 0; i < IXGBE_NB_STAT_MAPPING_REGS; i++) {
-		/* rx */
-		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), stat_mappings->rqsmr[i]);
+	RTE_BUILD_BUG_ON(RTE_DIM(((struct ixgbe_hw_stats *)0)->qprc) != 16);
 
-		/* tx */
-		IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), stat_mappings->tqsm[i]);
+	for (i = 0; i != IXGBE_NB_STAT_MAPPING_REGS; i++) {
+		/* four queues per register, 8 bits each */
+		reg = 0x03020100 + 0x04040404 * (i % 4);
+		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
+		IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg);
 	}
 }
 
@@ -1246,8 +1163,8 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
 	/* disable interrupt */
 	ixgbe_disable_intr(hw);
 
-	/* reset mappings for queue statistics hw counters*/
-	ixgbe_reset_qstat_mappings(hw);
+	/* program identity mapping for queue statistics hw counters */
+	ixgbe_init_qstat_mappings(hw);
 
 	/* Allocate memory for storing MAC addresses */
 	eth_dev->data->mac_addrs = rte_zmalloc("ixgbe", RTE_ETHER_ADDR_LEN *
@@ -2742,8 +2659,6 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 						RTE_BIT64(idx));
 	}
 
-	ixgbe_restore_statistics_mapping(dev);
-
 	err = ixgbe_flow_ctrl_enable(dev, hw);
 	if (err < 0) {
 		PMD_INIT_LOG(ERR, "enable flow ctrl err");
diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.h b/drivers/net/intel/ixgbe/ixgbe_ethdev.h
index 5d3243cb4d..ba826b6d8d 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.h
@@ -216,11 +216,6 @@ struct ixgbe_interrupt {
 	uint32_t mask_original;
 };
 
-struct ixgbe_stat_mapping_registers {
-	uint32_t tqsm[IXGBE_NB_STAT_MAPPING_REGS];
-	uint32_t rqsmr[IXGBE_NB_STAT_MAPPING_REGS];
-};
-
 struct ixgbe_vfta {
 	uint32_t vfta[IXGBE_VFTA_SIZE];
 };
@@ -471,7 +466,6 @@ struct ixgbe_adapter {
 	struct rte_eth_fdir_conf    fdir_conf;
 	struct ixgbe_hw_fdir_info   fdir;
 	struct ixgbe_interrupt      intr;
-	struct ixgbe_stat_mapping_registers stat_mappings;
 	struct ixgbe_vfta           shadow_vfta;
 	struct ixgbe_hwstrip		hwstrip;
 	struct ixgbe_dcb_config     dcb_config;
@@ -546,9 +540,6 @@ uint16_t ixgbe_vf_representor_tx_burst(void *tx_queue, struct rte_mbuf **tx_pkts
 #define IXGBE_DEV_PRIVATE_TO_FDIR_INFO(adapter) \
 	(&((struct ixgbe_adapter *)adapter)->fdir)
 
-#define IXGBE_DEV_PRIVATE_TO_STAT_MAPPINGS(adapter) \
-	(&((struct ixgbe_adapter *)adapter)->stat_mappings)
-
 #define IXGBE_DEV_PRIVATE_TO_VFTA(adapter) \
 	(&((struct ixgbe_adapter *)adapter)->shadow_vfta)
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 08/16] net/txgbe: remove queue stats mapping
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (6 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 07/16] net/ixgbe: " Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 09/16] net/sxe2: fix null dereference in stats get Stephen Hemminger
                     ` (7 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Jiawen Wu, Zaiyu Wang

Support for queue stats mapping has been deprecated since 25.11.
Remove support for this ethdev op in txgbe driver.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/txgbe/txgbe_ethdev.c | 87 +++-----------------------------
 drivers/net/txgbe/txgbe_ethdev.h | 13 -----
 2 files changed, 7 insertions(+), 93 deletions(-)

diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 4d2746371b..6349aca90f 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -386,60 +386,6 @@ txgbe_disable_intr(struct txgbe_hw *hw)
 	txgbe_flush(hw);
 }
 
-static int
-txgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
-				  uint16_t queue_id,
-				  uint8_t stat_idx,
-				  uint8_t is_rx)
-{
-	struct txgbe_hw *hw = TXGBE_DEV_HW(eth_dev);
-	struct txgbe_stat_mappings *stat_mappings =
-		TXGBE_DEV_STAT_MAPPINGS(eth_dev);
-	uint32_t qsmr_mask = 0;
-	uint32_t clearing_mask = QMAP_FIELD_RESERVED_BITS_MASK;
-	uint32_t q_map;
-	uint8_t n, offset;
-
-	if (!txgbe_is_pf(hw))
-		return -ENOSYS;
-
-	if (stat_idx & ~QMAP_FIELD_RESERVED_BITS_MASK)
-		return -EIO;
-
-	PMD_INIT_LOG(DEBUG, "Setting port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-
-	n = (uint8_t)(queue_id / NB_QMAP_FIELDS_PER_QSM_REG);
-	if (n >= TXGBE_NB_STAT_MAPPING) {
-		PMD_INIT_LOG(ERR, "Nb of stat mapping registers exceeded");
-		return -EIO;
-	}
-	offset = (uint8_t)(queue_id % NB_QMAP_FIELDS_PER_QSM_REG);
-
-	/* Now clear any previous stat_idx set */
-	clearing_mask <<= (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] &= ~clearing_mask;
-	else
-		stat_mappings->rqsm[n] &= ~clearing_mask;
-
-	q_map = (uint32_t)stat_idx;
-	q_map &= QMAP_FIELD_RESERVED_BITS_MASK;
-	qsmr_mask = q_map << (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
-	if (!is_rx)
-		stat_mappings->tqsm[n] |= qsmr_mask;
-	else
-		stat_mappings->rqsm[n] |= qsmr_mask;
-
-	PMD_INIT_LOG(DEBUG, "Set port %d, %s queue_id %d to stat index %d",
-		     (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
-		     queue_id, stat_idx);
-	PMD_INIT_LOG(DEBUG, "%s[%d] = 0x%08x", is_rx ? "RQSMR" : "TQSM", n,
-		     is_rx ? stat_mappings->rqsm[n] : stat_mappings->tqsm[n]);
-	return 0;
-}
-
 static void
 txgbe_dcb_init(struct txgbe_hw *hw, struct txgbe_dcb_config *dcb_config)
 {
@@ -2491,10 +2437,8 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 {
 	struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
 	struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
-	struct txgbe_stat_mappings *stat_mappings =
-			TXGBE_DEV_STAT_MAPPINGS(dev);
 	struct txgbe_tx_queue *txq;
-	uint32_t i, j;
+	unsigned int i;
 
 	txgbe_read_stats_registers(hw, hw_stats);
 
@@ -2508,29 +2452,13 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	stats->obytes = hw_stats->tx_bytes;
 
 	if (qstats != NULL) {
-		memset(&qstats->q_ipackets, 0, sizeof(qstats->q_ipackets));
-		memset(&qstats->q_opackets, 0, sizeof(qstats->q_opackets));
-		memset(&qstats->q_ibytes, 0, sizeof(qstats->q_ibytes));
-		memset(&qstats->q_obytes, 0, sizeof(qstats->q_obytes));
-		memset(&qstats->q_errors, 0, sizeof(qstats->q_errors));
 		for (i = 0; i < TXGBE_MAX_QP; i++) {
-			uint32_t n = i / NB_QMAP_FIELDS_PER_QSM_REG;
-			uint32_t offset = (i % NB_QMAP_FIELDS_PER_QSM_REG) * 8;
-			uint32_t q_map;
-
-			q_map = (stat_mappings->rqsm[n] >> offset)
-					& QMAP_FIELD_RESERVED_BITS_MASK;
-			j = (q_map < RTE_ETHDEV_QUEUE_STAT_CNTRS
-			     ? q_map : q_map % RTE_ETHDEV_QUEUE_STAT_CNTRS);
-			qstats->q_ipackets[j] += hw_stats->qp[i].rx_qp_packets;
-			qstats->q_ibytes[j] += hw_stats->qp[i].rx_qp_bytes;
-
-			q_map = (stat_mappings->tqsm[n] >> offset)
-					& QMAP_FIELD_RESERVED_BITS_MASK;
-			j = (q_map < RTE_ETHDEV_QUEUE_STAT_CNTRS
-			     ? q_map : q_map % RTE_ETHDEV_QUEUE_STAT_CNTRS);
-			qstats->q_opackets[j] += hw_stats->qp[i].tx_qp_packets;
-			qstats->q_obytes[j] += hw_stats->qp[i].tx_qp_bytes;
+			if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+				break;
+			qstats->q_ipackets[i] += hw_stats->qp[i].rx_qp_packets;
+			qstats->q_ibytes[i] += hw_stats->qp[i].rx_qp_bytes;
+			qstats->q_opackets[i] += hw_stats->qp[i].tx_qp_packets;
+			qstats->q_obytes[i] += hw_stats->qp[i].tx_qp_bytes;
 		}
 	}
 
@@ -6365,7 +6293,6 @@ static const struct eth_dev_ops txgbe_eth_dev_ops = {
 	.xstats_reset               = txgbe_dev_xstats_reset,
 	.xstats_get_names           = txgbe_dev_xstats_get_names,
 	.xstats_get_names_by_id     = txgbe_dev_xstats_get_names_by_id,
-	.queue_stats_mapping_set    = txgbe_dev_queue_stats_mapping_set,
 	.fw_version_get             = txgbe_fw_version_get,
 	.dev_supported_ptypes_get   = txgbe_dev_supported_ptypes_get,
 	.mtu_set                    = txgbe_dev_mtu_set,
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index c32c61d8bf..a617b70e3c 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -153,15 +153,6 @@ struct txgbe_interrupt {
 	uint64_t mask_orig; /* save mask during delayed handler */
 };
 
-#define TXGBE_NB_STAT_MAPPING  32
-#define QSM_REG_NB_BITS_PER_QMAP_FIELD 8
-#define NB_QMAP_FIELDS_PER_QSM_REG 4
-#define QMAP_FIELD_RESERVED_BITS_MASK 0x0f
-struct txgbe_stat_mappings {
-	uint32_t tqsm[TXGBE_NB_STAT_MAPPING];
-	uint32_t rqsm[TXGBE_NB_STAT_MAPPING];
-};
-
 struct txgbe_vfta {
 	uint32_t vfta[TXGBE_VFTA_SIZE];
 };
@@ -355,7 +346,6 @@ struct txgbe_adapter {
 	struct rte_eth_fdir_conf    fdir_conf;
 	struct txgbe_hw_fdir_info   fdir;
 	struct txgbe_interrupt      intr;
-	struct txgbe_stat_mappings  stat_mappings;
 	struct txgbe_vfta           shadow_vfta;
 	struct txgbe_hwstrip        hwstrip;
 	struct txgbe_dcb_config     dcb_config;
@@ -398,9 +388,6 @@ struct txgbe_adapter {
 #define TXGBE_DEV_FDIR(dev) \
 	(&((struct txgbe_adapter *)(dev)->data->dev_private)->fdir)
 
-#define TXGBE_DEV_STAT_MAPPINGS(dev) \
-	(&((struct txgbe_adapter *)(dev)->data->dev_private)->stat_mappings)
-
 #define TXGBE_DEV_VFTA(dev) \
 	(&((struct txgbe_adapter *)(dev)->data->dev_private)->shadow_vfta)
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 09/16] net/sxe2: fix null dereference in stats get
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (7 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 08/16] net/txgbe: " Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 10/16] net/sxe2: remove queue stats mapping Stephen Hemminger
                     ` (6 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, stable, Jie Liu

The qstats argument is NULL when the application calls
rte_eth_stats_get(), which only asks for the port level statistics.
Both the primary and the secondary path dereference it unconditionally,
so plain statistics retrieval crashes.

Only fetch and copy the per queue statistics when qstats is given.

Fixes: 5db446ba97b0 ("net/sxe2: support statistics and multi-process")
Cc: stable@dpdk.org

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/sxe2/sxe2_mp.c    | 3 ++-
 drivers/net/sxe2/sxe2_stats.c | 8 +++++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sxe2/sxe2_mp.c b/drivers/net/sxe2/sxe2_mp.c
index a4a5c76495..a9598b6dd6 100644
--- a/drivers/net/sxe2/sxe2_mp.c
+++ b/drivers/net/sxe2/sxe2_mp.c
@@ -325,7 +325,8 @@ int32_t sxe2_mp_req_get_stats(struct rte_eth_dev *dev,
 
 	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));
+	if (qstats != NULL)
+		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;
diff --git a/drivers/net/sxe2/sxe2_stats.c b/drivers/net/sxe2/sxe2_stats.c
index 3ad8fe2fe9..0e4857a906 100644
--- a/drivers/net/sxe2/sxe2_stats.c
+++ b/drivers/net/sxe2/sxe2_stats.c
@@ -328,9 +328,11 @@ int32_t sxe2_stats_info_get(struct rte_eth_dev *dev,
 	if (ret)
 		goto end;
 
-	ret = sxe2_drv_queue_info_get_update(adapter, qstats);
-	if (ret)
-		goto end;
+	if (qstats != NULL) {
+		ret = sxe2_drv_queue_info_get_update(adapter, qstats);
+		if (ret)
+			goto end;
+	}
 
 	sxe2_stats_update(adapter);
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 10/16] net/sxe2: remove queue stats mapping
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (8 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 09/16] net/sxe2: fix null dereference in stats get Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 11/16] ethdev: remove support for " Stephen Hemminger
                     ` (5 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Jie Liu

The queue stats mapping API is removed in 26.11. Drop the
.queue_stats_mapping_set op and the SXE2_DEV_CAPS_OFFLOAD_Q_MAP
handling, along with the now-unused mapping init/reset helpers.

Per-queue stats are now reported one entry per configured queue
rather than one entry per stat mapping pool, so convert the
multi-process path as well. The qstats member of the shared payload
becomes an array large enough for every queue the primary can
report, and the secondary copies back the queue count in use
instead of a single entry.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/sxe2/sxe2_cmd_chnl.c | 99 --------------------------------
 drivers/net/sxe2/sxe2_cmd_chnl.h | 10 ----
 drivers/net/sxe2/sxe2_ethdev.c   |  5 --
 drivers/net/sxe2/sxe2_mp.c       | 18 +++++-
 drivers/net/sxe2/sxe2_mp.h       |  7 ++-
 drivers/net/sxe2/sxe2_stats.c    | 76 +-----------------------
 drivers/net/sxe2/sxe2_stats.h    |  5 --
 7 files changed, 24 insertions(+), 196 deletions(-)

diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index b09989fe50..050488301c 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1609,105 +1609,6 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_
 	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;
-}
-
 int32_t sxe2_drv_flow_filter_add(struct sxe2_adapter *adapter, struct sxe2_flow *flow)
 {
 	struct sxe2_drv_flow_filter_req req = { 0 };
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index d63caad526..f43dcc8e7a 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -102,16 +102,6 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter,
 int32_t sxe2_drv_fc_state_get(struct sxe2_adapter *adapter,
 			      struct sxe2_drv_vsi_fc_get_resp *dev_fc_state_resp);
 
-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_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 8bbfdc3a15..440411a65a 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -194,8 +194,6 @@ static const struct eth_dev_ops sxe2_eth_dev_ops = {
 	.xstats_get_names           = sxe2_xstats_names_get,
 	.xstats_reset               = sxe2_stats_info_reset,
 
-	.queue_stats_mapping_set    = sxe2_queue_stats_mapping_set,
-
 	.fw_version_get             = sxe2_fw_version_string_get,
 
 	.get_monitor_addr           = sxe2_get_monitor_addr,
@@ -1309,9 +1307,6 @@ static void sxe2_drv_dev_caps_set(struct sxe2_adapter *adapter,
 	if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
 		adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_PTP;
 
-	if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_Q_MAP)
-		adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_Q_MAP;
-
 	if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_FC_STATE)
 		adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_FC_STATE;
 }
diff --git a/drivers/net/sxe2/sxe2_mp.c b/drivers/net/sxe2/sxe2_mp.c
index a9598b6dd6..298a95ac7a 100644
--- a/drivers/net/sxe2/sxe2_mp.c
+++ b/drivers/net/sxe2/sxe2_mp.c
@@ -15,6 +15,11 @@
 #include "sxe2_stats.h"
 #include "sxe2_common_log.h"
 
+/* The shared qstats array must hold every queue the primary may write. */
+static_assert(SXE2_RXQ_STATS_MAP_MAX_NUM <= SXE2_MP_MAX_QSTATS &&
+	      SXE2_TXQ_STATS_MAP_MAX_NUM <= SXE2_MP_MAX_QSTATS,
+	      "shared qstats array too small for per-queue stats");
+
 static RTE_ATOMIC(uint16_t)primary_ethdev_cnt;
 static RTE_ATOMIC(uint16_t)secondary_ethdev_cnt;
 static const struct rte_memzone *sxe2_mp_mz;
@@ -65,9 +70,11 @@ sxe2_mp_primary_handle(const struct rte_mp_msg *mp_msg, const void *peer)
 
 	switch (param->type) {
 	case SXE2_MP_REQ_GET_STATS:
+		memset(mz_data->payload.stats_blk.qstats, 0,
+		       sizeof(mz_data->payload.stats_blk.qstats));
 		ret = sxe2_stats_info_get(dev,
 					  &mz_data->payload.stats_blk.stats,
-					  &mz_data->payload.stats_blk.qstats);
+					  mz_data->payload.stats_blk.qstats);
 		break;
 	case SXE2_MP_REQ_GET_XSTATS:
 		cnt = sxe2_xstats_info_get(dev,
@@ -325,8 +332,13 @@ int32_t sxe2_mp_req_get_stats(struct rte_eth_dev *dev,
 
 	mz_data = (struct sxe2_mp_shared_data *)sxe2_mp_mz->addr;
 	memcpy(stats, &mz_data->payload.stats_blk.stats, sizeof(*stats));
-	if (qstats != NULL)
-		memcpy(qstats, &mz_data->payload.stats_blk.qstats, sizeof(*qstats));
+	if (qstats != NULL) {
+		uint16_t nb_queues = RTE_MAX(dev->data->nb_rx_queues,
+					     dev->data->nb_tx_queues);
+
+		memcpy(qstats, mz_data->payload.stats_blk.qstats,
+		       RTE_MIN(nb_queues, SXE2_MP_MAX_QSTATS) * sizeof(*qstats));
+	}
 	PMD_LOG_DEBUG(DRV, "sxe2_mp: stats received via IPC for port %u",
 			  dev->data->port_id);
 	ret = 0;
diff --git a/drivers/net/sxe2/sxe2_mp.h b/drivers/net/sxe2/sxe2_mp.h
index da9cc91d8d..aafe3cb1ba 100644
--- a/drivers/net/sxe2/sxe2_mp.h
+++ b/drivers/net/sxe2/sxe2_mp.h
@@ -10,6 +10,8 @@
 #include <rte_memzone.h>
 #include <rte_stdatomic.h>
 
+#include "sxe2_drv_cmd.h"
+
 #define SXE2_MP_NAME		"sxe2_mp_msg"
 #define SXE2_MP_MZ_NAME		"sxe2_stats_mz"
 
@@ -17,6 +19,9 @@
 
 #define SXE2_MP_MAX_XSTATS	128
 
+/* Must cover every queue the primary can report per-queue stats for. */
+#define SXE2_MP_MAX_QSTATS	SXE2_TXQ_STATS_MAP_MAX_NUM
+
 #define SXE2_MP_MAX_SPIN	100000
 
 enum sxe2_mp_req_type {
@@ -34,7 +39,7 @@ struct sxe2_mp_param {
 union sxe2_mp_shared_payload {
 	struct {
 		struct rte_eth_stats stats;
-		struct eth_queue_stats qstats;
+		struct eth_queue_stats qstats[SXE2_MP_MAX_QSTATS];
 	} stats_blk;
 	struct {
 		struct rte_eth_xstat xstats[SXE2_MP_MAX_XSTATS];
diff --git a/drivers/net/sxe2/sxe2_stats.c b/drivers/net/sxe2/sxe2_stats.c
index 0e4857a906..74a2594099 100644
--- a/drivers/net/sxe2/sxe2_stats.c
+++ b/drivers/net/sxe2/sxe2_stats.c
@@ -499,90 +499,20 @@ int32_t sxe2_stats_hw_reset(struct rte_eth_dev *dev)
 
 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;
+	return sxe2_stats_hw_reset(dev);
 }
 
 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;
-}
+	dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
 
-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;
+	return sxe2_stats_hw_reset(dev);
 }
diff --git a/drivers/net/sxe2/sxe2_stats.h b/drivers/net/sxe2/sxe2_stats.h
index 64ac2bb11d..f9cb5a8225 100644
--- a/drivers/net/sxe2/sxe2_stats.h
+++ b/drivers/net/sxe2/sxe2_stats.h
@@ -31,9 +31,4 @@ 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.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 11/16] ethdev: remove support for queue stats mapping
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (9 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 10/16] net/sxe2: remove queue stats mapping Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 12/16] net/mvpp2: fix out of range Tx queue stats write Stephen Hemminger
                     ` (4 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Chengwen Feng, Andrew Rybchenko,
	Thomas Monjalon

The support for queue stats mapping has been deprecated since 25.11
release by commit 2863cbd9ee6d ("ethdev: deprecate queue stats mapping
functions")

This patch completes final removal from ethdev and documentation.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/guides/nics/features.rst           |  7 ---
 doc/guides/rel_notes/deprecation.rst   |  6 ---
 doc/guides/rel_notes/release_26_11.rst |  5 +++
 lib/ethdev/ethdev_driver.h             | 11 -----
 lib/ethdev/ethdev_trace.h              | 20 ---------
 lib/ethdev/ethdev_trace_points.c       |  6 ---
 lib/ethdev/rte_ethdev.c                | 62 --------------------------
 lib/ethdev/rte_ethdev.h                | 45 -------------------
 8 files changed, 5 insertions(+), 157 deletions(-)

diff --git a/doc/guides/nics/features.rst b/doc/guides/nics/features.rst
index 0b0c69e7cd..d6852b063c 100644
--- a/doc/guides/nics/features.rst
+++ b/doc/guides/nics/features.rst
@@ -764,13 +764,6 @@ If driver does not support this feature the per queue stats will be zero.
 * **[implements] eth_dev_ops**: ``stats_get``, ``stats_reset``.
 * **[related]    API**: ``rte_eth_stats_get``, ``rte_eth_stats_reset()``.
 
-May also support configuring per-queue stat counter mapping.
-Used by some drivers to workaround HW limitations.
-
-* **[implements] eth_dev_ops**: ``queue_stats_mapping_set``.
-* **[related]    API**: ``rte_eth_dev_set_rx_queue_stats_mapping()``,
-  ``rte_eth_dev_set_tx_queue_stats_mapping()``.
-
 
 .. _nic_features_extended_stats:
 
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 6ad7698c6b..aaa2918865 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -83,12 +83,6 @@ Deprecation Notices
   and the header struct ``rte_vxlan_gpe_hdr`` with the macro ``RTE_ETHER_VXLAN_GPE_HLEN``
   will be removed in DPDK 25.11.
 
-* ethdev: The queue stats mapping functions
-  ``rte_eth_dev_set_tx_queue_stats_mapping`` and ``rte_eth_dev_set_rx_queue_stats_mapping``
-  are deprecated and will be removed in a future release.
-  Following the removal of queue statistics from the main ethdev statistics structure,
-  these functions are no longer needed.
-
 * ethdev: The flow API matching pattern structures, ``struct rte_flow_item_*``,
   should start with relevant protocol header structure from lib/net/.
   The individual protocol header fields and the protocol header struct
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index c8cc86295d..d29d7591e9 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -77,6 +77,11 @@ Removed Items
     ``rte_rib6_is_equal``
   * table: ``RTE_LPM_IPV6_ADDR_SIZE``
 
+* ethdev: Removed support for ethdev queue stats mapping.
+
+  ``rte_eth_dev_set_tx_queue_stats_mapping`` and ``rte_eth_dev_set_rx_queue_stats_mapping``
+  were deprecated and are now removed.
+
 
 API Changes
 -----------
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index 0f336f9567..0477579cc3 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -567,15 +567,6 @@ typedef int (*eth_xstats_disable_counter_t)(struct rte_eth_dev *dev, uint64_t id
 /** @internal Query the state of an xstat the can be enabled and disabled in runtime. */
 typedef int (*eth_xstats_query_state_t)(struct rte_eth_dev *dev, uint64_t id);
 
-/**
- * @internal
- * Set a queue statistics mapping for a Tx/Rx queue of an Ethernet device.
- */
-typedef int (*eth_queue_stats_mapping_set_t)(struct rte_eth_dev *dev,
-					     uint16_t queue_id,
-					     uint8_t stat_idx,
-					     uint8_t is_rx);
-
 /** @internal Get specific information of an Ethernet device. */
 typedef int (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				   struct rte_eth_dev_info *dev_info);
@@ -1454,8 +1445,6 @@ struct eth_dev_ops {
 	eth_xstats_reset_t         xstats_reset;
 	/** Get names of extended statistics */
 	eth_xstats_get_names_t     xstats_get_names;
-	/** Configure per queue stat counter mapping */
-	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info */
 	/** Retrieve Rx queue information */
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index 6554cc1a21..6f1804a765 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -310,26 +310,6 @@ RTE_TRACE_POINT(
 	rte_trace_point_emit_int(ret);
 )
 
-RTE_TRACE_POINT(
-	rte_ethdev_trace_set_rx_queue_stats_mapping,
-	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t rx_queue_id,
-		uint8_t stat_idx, int ret),
-	rte_trace_point_emit_u16(port_id);
-	rte_trace_point_emit_u16(rx_queue_id);
-	rte_trace_point_emit_u8(stat_idx);
-	rte_trace_point_emit_int(ret);
-)
-
-RTE_TRACE_POINT(
-	rte_ethdev_trace_set_tx_queue_stats_mapping,
-	RTE_TRACE_POINT_ARGS(uint16_t port_id, uint16_t tx_queue_id,
-		uint8_t stat_idx, int ret),
-	rte_trace_point_emit_u16(port_id);
-	rte_trace_point_emit_u16(tx_queue_id);
-	rte_trace_point_emit_u8(stat_idx);
-	rte_trace_point_emit_int(ret);
-)
-
 RTE_TRACE_POINT(
 	rte_ethdev_trace_fw_version_get,
 	RTE_TRACE_POINT_ARGS(uint16_t port_id, const char *fw_version,
diff --git a/lib/ethdev/ethdev_trace_points.c b/lib/ethdev/ethdev_trace_points.c
index 0a28378a56..b0644ea489 100644
--- a/lib/ethdev/ethdev_trace_points.c
+++ b/lib/ethdev/ethdev_trace_points.c
@@ -230,12 +230,6 @@ RTE_TRACE_POINT_REGISTER(rte_eth_trace_xstats_get,
 RTE_TRACE_POINT_REGISTER(rte_eth_trace_xstats_reset,
 	lib.ethdev.xstats_reset)
 
-RTE_TRACE_POINT_REGISTER(rte_ethdev_trace_set_tx_queue_stats_mapping,
-	lib.ethdev.set_tx_queue_stats_mapping)
-
-RTE_TRACE_POINT_REGISTER(rte_ethdev_trace_set_rx_queue_stats_mapping,
-	lib.ethdev.set_rx_queue_stats_mapping)
-
 RTE_TRACE_POINT_REGISTER(rte_ethdev_trace_fw_version_get,
 	lib.ethdev.fw_version_get)
 
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index 9efeaf77cb..d6915a6b08 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -160,11 +160,6 @@ static const struct {
 	{RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"},
 };
 
-enum {
-	STAT_QMAP_TX = 0,
-	STAT_QMAP_RX
-};
-
 static const struct {
 	enum rte_eth_hash_function algo;
 	const char *name;
@@ -4005,63 +4000,6 @@ rte_eth_xstats_query_state(uint16_t port_id, uint64_t id)
 	return -ENOTSUP;
 }
 
-static int
-eth_dev_set_queue_stats_mapping(uint16_t port_id, uint16_t queue_id,
-		uint8_t stat_idx, uint8_t is_rx)
-{
-	struct rte_eth_dev *dev;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-	dev = &rte_eth_devices[port_id];
-
-	if (is_rx && (queue_id >= dev->data->nb_rx_queues))
-		return -EINVAL;
-
-	if (!is_rx && (queue_id >= dev->data->nb_tx_queues))
-		return -EINVAL;
-
-	if (stat_idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
-		return -EINVAL;
-
-	if (dev->dev_ops->queue_stats_mapping_set == NULL)
-		return -ENOTSUP;
-	return dev->dev_ops->queue_stats_mapping_set(dev, queue_id, stat_idx, is_rx);
-}
-
-RTE_EXPORT_SYMBOL(rte_eth_dev_set_tx_queue_stats_mapping)
-int
-rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id, uint16_t tx_queue_id,
-		uint8_t stat_idx)
-{
-	int ret;
-
-	ret = eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
-						tx_queue_id,
-						stat_idx, STAT_QMAP_TX));
-
-	rte_ethdev_trace_set_tx_queue_stats_mapping(port_id, tx_queue_id,
-						    stat_idx, ret);
-
-	return ret;
-}
-
-RTE_EXPORT_SYMBOL(rte_eth_dev_set_rx_queue_stats_mapping)
-int
-rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id, uint16_t rx_queue_id,
-		uint8_t stat_idx)
-{
-	int ret;
-
-	ret = eth_err(port_id, eth_dev_set_queue_stats_mapping(port_id,
-						rx_queue_id,
-						stat_idx, STAT_QMAP_RX));
-
-	rte_ethdev_trace_set_rx_queue_stats_mapping(port_id, rx_queue_id,
-						    stat_idx, ret);
-
-	return ret;
-}
-
 RTE_EXPORT_SYMBOL(rte_eth_dev_fw_version_get)
 int
 rte_eth_dev_fw_version_get(uint16_t port_id, char *fw_version, size_t fw_size)
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index ee400b386f..3aa7a22fbc 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -3491,51 +3491,6 @@ int rte_eth_xstats_query_state(uint16_t port_id, uint64_t id);
  */
 int rte_eth_xstats_reset(uint16_t port_id);
 
-/**
- *  Set a mapping for the specified transmit queue to the specified per-queue
- *  statistics counter.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param tx_queue_id
- *   The index of the transmit queue for which a queue stats mapping is required.
- *   The value must be in the range [0, nb_tx_queue - 1] previously supplied
- *   to rte_eth_dev_configure().
- * @param stat_idx
- *   The per-queue packet statistics functionality number that the transmit
- *   queue is to be assigned.
- *   The value must be in the range [0, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1].
- *   Max RTE_ETHDEV_QUEUE_STAT_CNTRS being 256.
- * @return
- *   Zero if successful. Non-zero otherwise.
- */
-__rte_deprecated
-int rte_eth_dev_set_tx_queue_stats_mapping(uint16_t port_id,
-		uint16_t tx_queue_id, uint8_t stat_idx);
-
-/**
- *  Set a mapping for the specified receive queue to the specified per-queue
- *  statistics counter.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param rx_queue_id
- *   The index of the receive queue for which a queue stats mapping is required.
- *   The value must be in the range [0, nb_rx_queue - 1] previously supplied
- *   to rte_eth_dev_configure().
- * @param stat_idx
- *   The per-queue packet statistics functionality number that the receive
- *   queue is to be assigned.
- *   The value must be in the range [0, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1].
- *   Max RTE_ETHDEV_QUEUE_STAT_CNTRS being 256.
- * @return
- *   Zero if successful. Non-zero otherwise.
- */
-__rte_deprecated
-int rte_eth_dev_set_rx_queue_stats_mapping(uint16_t port_id,
-					   uint16_t rx_queue_id,
-					   uint8_t stat_idx);
-
 /**
  * Retrieve the Ethernet address of an Ethernet device.
  *
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 12/16] net/mvpp2: fix out of range Tx queue stats write
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (10 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 11/16] ethdev: remove support for " Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 13/16] net/ntnic: fix Tx errors reported as Rx queue errors Stephen Hemminger
                     ` (3 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, stable, Liron Himi, Jacek Siuda,
	Tomasz Duszynski

The Tx queue stats loop logs an error when the queue index is out of
range, then writes q_opackets[idx] and q_obytes[idx] anyway. The Rx loop
skips the queue in this case.

Add the missing continue. Latent today since MRVL_PP2_TXQ_MAX (8) is
below RTE_ETHDEV_QUEUE_STAT_CNTRS (16), but the check is wrong.

Fixes: bdffe0c70a0b ("net/mrvl: support basic stats")
Cc: stable@dpdk.org

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/mvpp2/mrvl_ethdev.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index 1074092d43..bc947ff52e 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -1546,6 +1546,7 @@ mrvl_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 			MRVL_LOG(ERR,
 				"tx queue %d stats out of range (0 - %d)",
 				idx, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
+			continue;
 		}
 
 		ret = pp2_ppio_outq_get_statistics(priv->ppio, idx,
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 13/16] net/ntnic: fix Tx errors reported as Rx queue errors
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (11 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 12/16] net/mvpp2: fix out of range Tx queue stats write Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 14/16] net/xsc: fix Tx errors added to " Stephen Hemminger
                     ` (2 subsequent siblings)
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, stable, Christian Koue Muf, Serhii Iliushyk,
	Danylo Vodopianov

q_errors counts received packets dropped, and is reported as the
rx_qN_errors xstat. The Tx loop fills it with the Tx error count and the
Rx loop never sets it, so rx_qN_errors is purely a Tx counter.

Tx errors are already counted in oerrors, so drop the assignment.

Fixes: effa04693274 ("net/ntnic: add statistics")
Cc: stable@dpdk.org

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/ntnic/ntnic_ethdev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index 7cc90a7a5b..bee34d20d7 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -209,7 +209,6 @@ static int dpdk_stats_collect(struct pmd_internals *internals, struct rte_eth_st
 		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
 			qstats->q_opackets[i] = internals->txq_scg[i].tx_pkts;
 			qstats->q_obytes[i] = internals->txq_scg[i].tx_bytes;
-			qstats->q_errors[i] = internals->txq_scg[i].err_pkts;
 		}
 		tx_total += internals->txq_scg[i].tx_pkts;
 		tx_total_b += internals->txq_scg[i].tx_bytes;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 14/16] net/xsc: fix Tx errors added to Rx queue errors
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (12 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 13/16] net/ntnic: fix Tx errors reported as Rx queue errors Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 15/16] ethdev: remove queue stats counter limit Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 16/16] test/pmd_ring: test per-queue xstats Stephen Hemminger
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, stable, Renyong Wan, Na Na, Rong Qian,
	Xiaoxiong Zhang, Dongwei Xu

q_errors counts received packets dropped, and is reported as the
rx_qN_errors xstat. The Rx loop fills it correctly, then the Tx loop
adds the Tx error count, so rx_qN_errors reports both.

Tx errors are already counted in oerrors, so drop the assignment.

Fixes: c80ab1a551cc ("net/xsc: support basic statistics")
Cc: stable@dpdk.org

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/xsc/xsc_ethdev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/xsc/xsc_ethdev.c b/drivers/net/xsc/xsc_ethdev.c
index 39a67ff8cd..505f973d66 100644
--- a/drivers/net/xsc/xsc_ethdev.c
+++ b/drivers/net/xsc/xsc_ethdev.c
@@ -614,7 +614,6 @@ xsc_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		if (qstats != NULL && idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
 			qstats->q_opackets[idx] += txq->stats.tx_pkts;
 			qstats->q_obytes[idx] += txq->stats.tx_bytes;
-			qstats->q_errors[idx] += txq->stats.tx_errors;
 		}
 		stats->opackets += txq->stats.tx_pkts;
 		stats->obytes += txq->stats.tx_bytes;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 15/16] ethdev: remove queue stats counter limit
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (13 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 14/16] net/xsc: fix Tx errors added to " Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  2026-08-13 17:55   ` [PATCH v3 16/16] test/pmd_ring: test per-queue xstats Stephen Hemminger
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, Kishore Padmanabha, Ajit Khaparde,
	Ciara Loftus, Maryam Tahhan, Shepard Siegel, Ed Czeck,
	John Miller, Igor Russkikh, Steven Webster, Matt Peters,
	Selwin Sebastian, Nithin Dabilpuram, Kiran Kumar K,
	Sunil Kumar Kori, Satha Rao, Harman Kalra, Hemant Agrawal,
	Sachin Saxena, Shai Brandes, Evgeny Schemeilin, Amit Bernstein,
	Wajeeh Atrash, Xiaoyun Wang, Feifei Wang, Anatoly Burakov,
	Vladimir Medvedkin, Andrew Boyer, Long Li, Wei Hu, Jakub Grajciar,
	Matan Azrad, Viacheslav Ovsiienko, Dariusz Sosnowski, Bing Zhao,
	Ori Kam, Suanming Mou, Liron Himi, Dimon Zhao, Leon Yu, Sam Chen,
	Martin Spinler, Chaoyong He, Jiawen Wu, Zaiyu Wang,
	Christian Koue Muf, Serhii Iliushyk, Tetsuya Mukawa,
	Vamsi Attunuru, Devendra Singh Rawat, Alok Prasad,
	Bruce Richardson, Wenbo Cao, Jie Liu, Jerin Jacob, Maciej Czekaj,
	Maxime Coquelin, Chenbo Xia, Jochen Behrens, Renyong Wan, Na Na,
	Rong Qian, Xiaoxiong Zhang, Dongwei Xu, Junlong Wang, Ming Ran,
	Thomas Monjalon, Andrew Rybchenko

Queue stats were passed back from drivers in arrays of
RTE_ETHDEV_QUEUE_STAT_CNTRS entries, limiting reporting to the first 16
queues unless DPDK was rebuilt with a larger value.

Replace the arrays with one counter structure per queue, allocated by
ethdev and sized to the number of queues configured on the port.
Queue counts are already validated by rte_eth_dev_configure(), so no
additional limit is needed.

Drop the per-queue error counter. Only a few drivers filled it, and
errors are still counted by the port level ierrors and oerrors.

RTE_ETHDEV_QUEUE_STAT_CNTRS is unused now and removed. It was defined in
ethdev_driver.h, only installed with the driver SDK, so the ABI is
unaffected.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 doc/guides/howto/debug_troubleshoot.rst       |  5 +-
 doc/guides/nics/bnxt.rst                      |  4 +-
 doc/guides/nics/features.rst                  |  5 +-
 doc/guides/rel_notes/release_26_11.rst        |  4 ++
 drivers/net/af_packet/rte_eth_af_packet.c     | 15 +++--
 drivers/net/af_xdp/rte_eth_af_xdp.c           | 13 ++--
 drivers/net/ark/ark_ethdev_rx.c               |  7 +-
 drivers/net/ark/ark_ethdev_tx.c               |  6 +-
 drivers/net/atlantic/atl_ethdev.c             | 13 ++--
 drivers/net/atlantic/atl_rxtx.c               |  8 +--
 drivers/net/atlantic/atl_types.h              | 15 +++--
 drivers/net/avp/avp_ethdev.c                  | 13 ++--
 drivers/net/axgbe/axgbe_ethdev.c              | 13 ++--
 drivers/net/bnxt/bnxt_ethdev.c                |  5 --
 drivers/net/bnxt/bnxt_reps.c                  |  9 ++-
 drivers/net/bnxt/bnxt_stats.c                 | 40 ++++-------
 drivers/net/cnxk/cnxk_rep_ops.c               |  8 +--
 drivers/net/cnxk/cnxk_stats.c                 | 15 ++---
 drivers/net/dpaa2/dpaa2_ethdev.c              | 17 ++---
 drivers/net/ena/ena_ethdev.c                  | 21 ++----
 drivers/net/hinic/hinic_pmd_ethdev.c          | 17 +++--
 drivers/net/hinic3/hinic3_ethdev.c            | 13 ++--
 drivers/net/intel/e1000/igc_ethdev.c          | 13 ++--
 drivers/net/intel/fm10k/fm10k_ethdev.c        | 16 +++--
 drivers/net/intel/ixgbe/ixgbe_ethdev.c        | 14 ++--
 drivers/net/ionic/ionic_lif.c                 | 24 +++----
 drivers/net/mana/mana.c                       | 12 ++--
 drivers/net/memif/rte_eth_memif.c             | 16 ++---
 drivers/net/mlx4/mlx4_ethdev.c                | 14 ++--
 drivers/net/mlx5/mlx5_rx.h                    |  3 +-
 drivers/net/mlx5/mlx5_stats.c                 | 22 +++----
 drivers/net/mvpp2/mrvl_ethdev.c               | 20 +++---
 drivers/net/nbl/nbl_dev/nbl_dev.c             |  2 -
 drivers/net/nbl/nbl_hw/nbl_txrx.c             | 12 ++--
 drivers/net/netvsc/hn_ethdev.c                | 12 ++--
 drivers/net/netvsc/hn_vf.c                    |  3 +-
 drivers/net/nfb/nfb_stats.c                   | 12 ++--
 drivers/net/nfp/flower/nfp_flower.c           |  8 +--
 .../net/nfp/flower/nfp_flower_representor.c   | 32 ++++++---
 .../net/nfp/flower/nfp_flower_representor.h   |  4 +-
 drivers/net/nfp/nfp_ethdev.c                  | 13 ++++
 drivers/net/nfp/nfp_ethdev_vf.c               | 13 ++++
 drivers/net/nfp/nfp_net_common.c              | 36 ++++------
 drivers/net/nfp/nfp_net_common.h              |  3 +-
 drivers/net/ngbe/ngbe_ethdev.c                | 34 +++-------
 drivers/net/ngbe/ngbe_ethdev.h                | 12 ----
 drivers/net/ntnic/ntnic_ethdev.c              | 12 ++--
 drivers/net/null/rte_eth_null.c               | 12 ++--
 drivers/net/octeon_ep/otx_ep_ethdev.c         | 13 ++--
 drivers/net/pcap/pcap_ethdev.c                | 14 ++--
 drivers/net/qede/qede_ethdev.c                | 36 ++--------
 drivers/net/ring/rte_eth_ring.c               | 10 ++-
 drivers/net/rnp/rnp_ethdev.c                  | 12 ++--
 drivers/net/sxe2/sxe2_cmd_chnl.c              | 20 +++---
 drivers/net/tap/rte_eth_tap.c                 | 12 ++--
 drivers/net/thunderx/nicvf_ethdev.c           | 24 +++----
 drivers/net/txgbe/txgbe_ethdev.c              | 14 ++--
 drivers/net/vhost/rte_eth_vhost.c             | 14 ++--
 drivers/net/virtio/virtio_ethdev.c            | 12 ++--
 drivers/net/vmxnet3/vmxnet3_ethdev.c          | 13 ++--
 drivers/net/xsc/xsc_ethdev.c                  | 14 ++--
 drivers/net/zxdh/zxdh_ethdev_ops.c            | 24 +++----
 lib/ethdev/ethdev_driver.h                    | 27 ++++----
 lib/ethdev/ethdev_private.c                   |  2 -
 lib/ethdev/rte_ethdev.c                       | 66 ++++++++++---------
 65 files changed, 445 insertions(+), 522 deletions(-)

diff --git a/doc/guides/howto/debug_troubleshoot.rst b/doc/guides/howto/debug_troubleshoot.rst
index c19aada6f8..969118fcfc 100644
--- a/doc/guides/howto/debug_troubleshoot.rst
+++ b/doc/guides/howto/debug_troubleshoot.rst
@@ -120,8 +120,9 @@ RX-TX port and associated cores :numref:`dtg_rx_tx_drop`.
    * Identify if there are multiple RX queue configured for port by
      ``nb_rx_queues`` using ``rte_eth_dev_info_get``.
 
-   * Using ``rte_eth_dev_stats`` fetch drops in q_errors, check if RX thread
-     is configured to fetch packets from the port queue pair.
+   * Using ``rte_eth_dev_stats`` fetch drops in ``ierrors`` and ``imissed``,
+     check if RX thread is configured to fetch packets from the port queue
+     pair.
 
    * Using ``rte_eth_dev_stats`` shows drops in ``rx_nombuf``, check if RX
      thread has enough cycles to consume the packets from the queue.
diff --git a/doc/guides/nics/bnxt.rst b/doc/guides/nics/bnxt.rst
index 45529a89ee..48b950876c 100644
--- a/doc/guides/nics/bnxt.rst
+++ b/doc/guides/nics/bnxt.rst
@@ -588,9 +588,7 @@ Basic stats include:
 * ierrors
 * oerrors
 
-By default, per-queue stats for 16 queues are supported. For more than 16
-queues, BNXT PMD should be compiled with ``RTE_ETHDEV_QUEUE_STAT_CNTRS``
-set to the desired number of queues.
+Per-queue stats are supported for all configured queues.
 
 Extended Stats
 ^^^^^^^^^^^^^^
diff --git a/doc/guides/nics/features.rst b/doc/guides/nics/features.rst
index d6852b063c..43eda7867d 100644
--- a/doc/guides/nics/features.rst
+++ b/doc/guides/nics/features.rst
@@ -757,8 +757,9 @@ These apply to all drivers.
 Stats per queue
 ---------------
 
-Supports per queue stats: q_ipackets, q_opackets, q_ibytes, q_obytes, q_errors.
-Statistics only supplied for first ``RTE_ETHDEV_QUEUE_STAT_CNTRS`` (16) queues.
+Supports per queue stats: q_ipackets, q_opackets, q_ibytes, q_obytes.
+Statistics are supplied for all configured queues,
+subject to any hardware counter limit of the device.
 If driver does not support this feature the per queue stats will be zero.
 
 * **[implements] eth_dev_ops**: ``stats_get``, ``stats_reset``.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index d29d7591e9..ed271a81f6 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -82,6 +82,10 @@ Removed Items
   ``rte_eth_dev_set_tx_queue_stats_mapping`` and ``rte_eth_dev_set_rx_queue_stats_mapping``
   were deprecated and are now removed.
 
+* ethdev: Removed the ``RTE_ETHDEV_QUEUE_STAT_CNTRS`` build time limit.
+  Per-queue xstats are now reported for all queues, not just the first 16.
+  The ``rx_qN_errors`` xstat is removed, drops are still counted in ``ierrors``.
+
 
 API Changes
 -----------
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
index b0ff22ea55..a97b826305 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -515,12 +515,15 @@ eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats, struct eth_q
 		tx_err_total += internal->tx_queue[i].err_pkts;
 		tx_bytes_total += internal->tx_queue[i].tx_bytes;
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = internal->rx_queue[i].rx_pkts;
-			qstats->q_ibytes[i] = internal->rx_queue[i].rx_bytes;
-			qstats->q_opackets[i] = internal->tx_queue[i].tx_pkts;
-			qstats->q_obytes[i] = internal->tx_queue[i].tx_bytes;
-			qstats->q_errors[i] = internal->rx_queue[i].rx_nombuf;
+		if (qstats != NULL) {
+			if (i < dev->data->nb_rx_queues) {
+				qstats[i].q_ipackets = internal->rx_queue[i].rx_pkts;
+				qstats[i].q_ibytes = internal->rx_queue[i].rx_bytes;
+			}
+			if (i < dev->data->nb_tx_queues) {
+				qstats[i].q_opackets = internal->tx_queue[i].tx_pkts;
+				qstats[i].q_obytes = internal->tx_queue[i].tx_bytes;
+			}
 		}
 	}
 
diff --git a/drivers/net/af_xdp/rte_eth_af_xdp.c b/drivers/net/af_xdp/rte_eth_af_xdp.c
index 2cdb533276..be2f5760ae 100644
--- a/drivers/net/af_xdp/rte_eth_af_xdp.c
+++ b/drivers/net/af_xdp/rte_eth_af_xdp.c
@@ -910,12 +910,13 @@ eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		rxq = &internals->rx_queues[i];
 		txq = rxq->pair;
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = rxq->stats.rx_pkts;
-			qstats->q_ibytes[i] = rxq->stats.rx_bytes;
-			qstats->q_opackets[i] = txq->stats.tx_pkts;
-			qstats->q_obytes[i] = txq->stats.tx_bytes;
-			qstats->q_errors[i] = 0; /* Not used */
+		if (qstats != NULL) {
+			qstats[i].q_ipackets = rxq->stats.rx_pkts;
+			qstats[i].q_ibytes = rxq->stats.rx_bytes;
+			if (i < dev->data->nb_tx_queues) {
+				qstats[i].q_opackets = txq->stats.tx_pkts;
+				qstats[i].q_obytes = txq->stats.tx_bytes;
+			}
 		}
 
 		ipackets += rxq->stats.rx_pkts;
diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index 42f2db6610..adba943fa2 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -592,10 +592,9 @@ ark_rx_queue_stats_get(void *vqueue, struct rte_eth_stats *stats,
 	stats->ibytes += ibytes;
 	stats->imissed += idropped;
 
-	if (qstats && queue->queue_index < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-		qstats->q_ipackets[queue->queue_index] = ipackets;
-		qstats->q_ibytes[queue->queue_index] = ibytes;
-		qstats->q_errors[queue->queue_index] = idropped;
+	if (qstats != NULL) {
+		qstats[queue->queue_index].q_ipackets = ipackets;
+		qstats[queue->queue_index].q_ibytes = ibytes;
 	}
 }
 
diff --git a/drivers/net/ark/ark_ethdev_tx.c b/drivers/net/ark/ark_ethdev_tx.c
index c9b5b005ca..0d6a94b919 100644
--- a/drivers/net/ark/ark_ethdev_tx.c
+++ b/drivers/net/ark/ark_ethdev_tx.c
@@ -433,9 +433,9 @@ ark_tx_queue_stats_get(void *vqueue, struct rte_eth_stats *stats, struct eth_que
 	stats->obytes += bytes;
 	stats->oerrors += queue->tx_errors;
 
-	if (qstats && queue->queue_index < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-		qstats->q_opackets[queue->queue_index] = pkts;
-		qstats->q_obytes[queue->queue_index] = bytes;
+	if (qstats != NULL) {
+		qstats[queue->queue_index].q_opackets = pkts;
+		qstats[queue->queue_index].q_obytes = bytes;
 	}
 }
 
diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c
index 0b2033c084..24184bdb18 100644
--- a/drivers/net/atlantic/atl_ethdev.c
+++ b/drivers/net/atlantic/atl_ethdev.c
@@ -954,12 +954,13 @@ atl_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	stats->rx_nombuf = swstats->rx_nombuf;
 
 	if (qstats != NULL) {
-		for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
-			qstats->q_ipackets[i] = swstats->q_ipackets[i];
-			qstats->q_opackets[i] = swstats->q_opackets[i];
-			qstats->q_ibytes[i] = swstats->q_ibytes[i];
-			qstats->q_obytes[i] = swstats->q_obytes[i];
-			qstats->q_errors[i] = swstats->q_errors[i];
+		for (i = 0; i < dev->data->nb_rx_queues && i < AQ_HW_MAX_RX_QUEUES; i++) {
+			qstats[i].q_ipackets = swstats->rxq[i].packets;
+			qstats[i].q_ibytes = swstats->rxq[i].bytes;
+		}
+		for (i = 0; i < dev->data->nb_tx_queues && i < AQ_HW_MAX_TX_QUEUES; i++) {
+			qstats[i].q_opackets = swstats->txq[i].packets;
+			qstats[i].q_obytes = swstats->txq[i].bytes;
 		}
 	}
 	return 0;
diff --git a/drivers/net/atlantic/atl_rxtx.c b/drivers/net/atlantic/atl_rxtx.c
index 7b7bf5abbc..8d02b92304 100644
--- a/drivers/net/atlantic/atl_rxtx.c
+++ b/drivers/net/atlantic/atl_rxtx.c
@@ -1075,8 +1075,8 @@ atl_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		 * of returned packets.
 		 */
 		rx_pkts[nb_rx++] = rx_mbuf_first;
-		adapter->sw_stats.q_ipackets[rxq->queue_id]++;
-		adapter->sw_stats.q_ibytes[rxq->queue_id] +=
+		adapter->sw_stats.rxq[rxq->queue_id].packets++;
+		adapter->sw_stats.rxq[rxq->queue_id].bytes +=
 			rx_mbuf_first->pkt_len;
 
 		PMD_RX_LOG(DEBUG, "add mbuf segs=%d pkt_len=%d",
@@ -1297,8 +1297,8 @@ atl_xmit_pkt(struct aq_hw_s *hw, struct atl_tx_queue *txq,
 
 	txq->tx_free -= desc_count;
 
-	adapter->sw_stats.q_opackets[txq->queue_id]++;
-	adapter->sw_stats.q_obytes[txq->queue_id] += pay_len;
+	adapter->sw_stats.txq[txq->queue_id].packets++;
+	adapter->sw_stats.txq[txq->queue_id].bytes += pay_len;
 }
 
 uint16_t
diff --git a/drivers/net/atlantic/atl_types.h b/drivers/net/atlantic/atl_types.h
index dfd7016600..be9f3aacc1 100644
--- a/drivers/net/atlantic/atl_types.h
+++ b/drivers/net/atlantic/atl_types.h
@@ -15,6 +15,8 @@
 #include <rte_common.h>
 #include <ethdev_driver.h>
 
+#include "atl_common.h"
+
 typedef uint8_t		u8;
 typedef int8_t		s8;
 typedef uint16_t	u16;
@@ -225,11 +227,14 @@ struct atl_sw_stats {
 	u64 pcrc8ec;
 
 	u64 rx_nombuf;
-	u64 q_ipackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-	u64 q_opackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-	u64 q_ibytes[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-	u64 q_obytes[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-	u64 q_errors[RTE_ETHDEV_QUEUE_STAT_CNTRS];
+	struct {
+		u64 packets;
+		u64 bytes;
+	} rxq[AQ_HW_MAX_RX_QUEUES];
+	struct {
+		u64 packets;
+		u64 bytes;
+	} txq[AQ_HW_MAX_TX_QUEUES];
 };
 
 #endif
diff --git a/drivers/net/avp/avp_ethdev.c b/drivers/net/avp/avp_ethdev.c
index 8af6c45381..d536f764cf 100644
--- a/drivers/net/avp/avp_ethdev.c
+++ b/drivers/net/avp/avp_ethdev.c
@@ -2256,10 +2256,9 @@ avp_dev_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
 			stats->ibytes += rxq->bytes;
 			stats->ierrors += rxq->errors;
 
-			if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-				qstats->q_ipackets[i] += rxq->packets;
-				qstats->q_ibytes[i] += rxq->bytes;
-				qstats->q_errors[i] += rxq->errors;
+			if (qstats != NULL && i < eth_dev->data->nb_rx_queues) {
+				qstats[i].q_ipackets += rxq->packets;
+				qstats[i].q_ibytes += rxq->bytes;
 			}
 		}
 	}
@@ -2272,9 +2271,9 @@ avp_dev_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
 			stats->obytes += txq->bytes;
 			stats->oerrors += txq->errors;
 
-			if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-				qstats->q_opackets[i] += txq->packets;
-				qstats->q_obytes[i] += txq->bytes;
+			if (qstats != NULL && i < eth_dev->data->nb_tx_queues) {
+				qstats[i].q_opackets += txq->packets;
+				qstats[i].q_obytes += txq->bytes;
 			}
 		}
 	}
diff --git a/drivers/net/axgbe/axgbe_ethdev.c b/drivers/net/axgbe/axgbe_ethdev.c
index 61725d55ca..93e198ba95 100644
--- a/drivers/net/axgbe/axgbe_ethdev.c
+++ b/drivers/net/axgbe/axgbe_ethdev.c
@@ -1156,10 +1156,9 @@ axgbe_dev_stats_get(struct rte_eth_dev *dev,
 			stats->rx_nombuf += rxq->rx_mbuf_alloc_failed;
 			stats->ierrors += rxq->errors;
 
-			if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-				qstats->q_ipackets[i] = rxq->pkts;
-				qstats->q_ibytes[i] = rxq->bytes;
-				qstats->q_errors[i] = rxq->errors + rxq->rx_mbuf_alloc_failed;
+			if (qstats != NULL && i < dev->data->nb_rx_queues) {
+				qstats[i].q_ipackets = rxq->pkts;
+				qstats[i].q_ibytes = rxq->bytes;
 			}
 		} else {
 			PMD_DRV_LOG_LINE(DEBUG, "Rx queue not setup for port %d",
@@ -1174,9 +1173,9 @@ axgbe_dev_stats_get(struct rte_eth_dev *dev,
 			stats->obytes += txq->bytes;
 			stats->oerrors += txq->errors;
 
-			if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-				qstats->q_opackets[i] = txq->pkts;
-				qstats->q_obytes[i] = txq->bytes;
+			if (qstats != NULL && i < dev->data->nb_tx_queues) {
+				qstats[i].q_opackets = txq->pkts;
+				qstats[i].q_obytes = txq->bytes;
 			}
 		} else {
 			PMD_DRV_LOG_LINE(DEBUG, "Tx queue not setup for port %d",
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 8e8ead8f61..c6f566c214 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1843,11 +1843,6 @@ int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 	struct bnxt_tx_queue *txq;
 	uint16_t queue_idx;
 
-	if (bp->rx_cp_nr_rings > RTE_ETHDEV_QUEUE_STAT_CNTRS)
-		PMD_DRV_LOG_LINE(ERR,
-			    "RxQ cnt %d > RTE_ETHDEV_QUEUE_STAT_CNTRS %d",
-			    bp->rx_cp_nr_rings, RTE_ETHDEV_QUEUE_STAT_CNTRS);
-
 	do {
 		rc = bnxt_hwrm_if_change(bp, true);
 		if (rc == 0 || rc != -EAGAIN)
diff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c
index e26a086f41..dd0f14d5c6 100644
--- a/drivers/net/bnxt/bnxt_reps.c
+++ b/drivers/net/bnxt/bnxt_reps.c
@@ -909,11 +909,10 @@ int bnxt_rep_stats_get_op(struct rte_eth_dev *eth_dev,
 		stats->imissed += rep_bp->rx_drop_pkts[i];
 
 		if (qstats) {
-			qstats->q_ipackets[i] = rep_bp->rx_pkts[i];
-			qstats->q_ibytes[i] = rep_bp->rx_bytes[i];
-			qstats->q_opackets[i] = rep_bp->tx_pkts[i];
-			qstats->q_obytes[i] = rep_bp->tx_bytes[i];
-			qstats->q_errors[i] = rep_bp->rx_drop_pkts[i];
+			qstats[i].q_ipackets = rep_bp->rx_pkts[i];
+			qstats[i].q_ibytes = rep_bp->rx_bytes[i];
+			qstats[i].q_opackets = rep_bp->tx_pkts[i];
+			qstats[i].q_obytes = rep_bp->tx_bytes[i];
 		}
 	}
 
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index ba858710a5..37b33f0505 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -576,18 +576,14 @@ static void bnxt_fill_rte_eth_stats_ext(struct rte_eth_stats *stats,
 		uint64_t ibytes = ring_stats->rx_ucast_bytes +
 				ring_stats->rx_mcast_bytes +
 				ring_stats->rx_bcast_bytes;
-		uint64_t ierrors = ring_stats->rx_discard_pkts +
-				ring_stats->rx_error_pkts;
-
 		stats->ipackets += ipackets;
 		stats->ibytes += ibytes;
 		stats->imissed += ring_stats->rx_discard_pkts;
 		stats->ierrors += ring_stats->rx_error_pkts;
 
 		if (qstats) {
-			qstats->q_ipackets[i] = ipackets;
-			qstats->q_ibytes[i] = ibytes;
-			qstats->q_errors[i] = ierrors;
+			qstats[i].q_ipackets = ipackets;
+			qstats[i].q_ibytes = ibytes;
 		}
 	} else {
 		uint64_t opackets = ring_stats->tx_ucast_pkts +
@@ -602,8 +598,8 @@ static void bnxt_fill_rte_eth_stats_ext(struct rte_eth_stats *stats,
 		stats->oerrors += ring_stats->tx_discard_pkts;
 
 		if (qstats) {
-			qstats->q_opackets[i] = opackets;
-			qstats->q_obytes[i] = obytes;
+			qstats[i].q_opackets = opackets;
+			qstats[i].q_obytes = obytes;
 		}
 	}
 }
@@ -620,18 +616,14 @@ static void bnxt_fill_rte_eth_stats(struct rte_eth_stats *stats,
 		uint64_t ibytes = ring_stats->rx_ucast_bytes +
 				ring_stats->rx_mcast_bytes +
 				ring_stats->rx_bcast_bytes;
-		uint64_t ierrors = ring_stats->rx_discard_pkts +
-				ring_stats->rx_error_pkts;
-
 		stats->ipackets += ipackets;
 		stats->ibytes += ibytes;
 		stats->imissed += ring_stats->rx_discard_pkts;
 		stats->ierrors += ring_stats->rx_error_pkts;
 
 		if (qstats) {
-			qstats->q_ipackets[i] = ipackets;
-			qstats->q_ibytes[i] = ibytes;
-			qstats->q_errors[i] = ierrors;
+			qstats[i].q_ipackets = ipackets;
+			qstats[i].q_ibytes = ibytes;
 		}
 	} else {
 		uint64_t opackets = ring_stats->tx_ucast_pkts +
@@ -646,8 +638,8 @@ static void bnxt_fill_rte_eth_stats(struct rte_eth_stats *stats,
 		stats->oerrors += ring_stats->tx_discard_pkts;
 
 		if (qstats) {
-			qstats->q_opackets[i] = opackets;
-			qstats->q_obytes[i] = obytes;
+			qstats[i].q_opackets = opackets;
+			qstats[i].q_obytes = obytes;
 		}
 	}
 }
@@ -661,9 +653,7 @@ static int bnxt_stats_get_ext(struct rte_eth_dev *eth_dev,
 	struct bnxt *bp = eth_dev->data->dev_private;
 	unsigned int num_q_stats;
 
-	num_q_stats = RTE_MIN(bp->rx_cp_nr_rings,
-			      (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
-
+	num_q_stats = RTE_MIN(bp->rx_cp_nr_rings, eth_dev->data->nb_rx_queues);
 	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
 		struct bnxt_rx_queue *rxq = bp->rx_queues[i];
 		struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
@@ -687,9 +677,7 @@ static int bnxt_stats_get_ext(struct rte_eth_dev *eth_dev,
 							 rte_memory_order_relaxed);
 	}
 
-	num_q_stats = RTE_MIN(bp->tx_cp_nr_rings,
-			      (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
-
+	num_q_stats = RTE_MIN(bp->tx_cp_nr_rings, eth_dev->data->nb_tx_queues);
 	for (i = 0; i < bp->tx_cp_nr_rings; i++) {
 		struct bnxt_tx_queue *txq = bp->tx_queues[i];
 		struct bnxt_cp_ring_info *cpr = txq->cp_ring;
@@ -728,9 +716,7 @@ int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
 	if (BNXT_TPA_V2_P7(bp))
 		return bnxt_stats_get_ext(eth_dev, bnxt_stats, qstats);
 
-	num_q_stats = RTE_MIN(bp->rx_cp_nr_rings,
-			      (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
-
+	num_q_stats = RTE_MIN(bp->rx_cp_nr_rings, eth_dev->data->nb_rx_queues);
 	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
 		struct bnxt_rx_queue *rxq = bp->rx_queues[i];
 		struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
@@ -753,9 +739,7 @@ int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
 							 rte_memory_order_relaxed);
 	}
 
-	num_q_stats = RTE_MIN(bp->tx_cp_nr_rings,
-			      (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
-
+	num_q_stats = RTE_MIN(bp->tx_cp_nr_rings, eth_dev->data->nb_tx_queues);
 	for (i = 0; i < bp->tx_cp_nr_rings; i++) {
 		struct bnxt_tx_queue *txq = bp->tx_queues[i];
 		struct bnxt_cp_ring_info *cpr = txq->cp_ring;
diff --git a/drivers/net/cnxk/cnxk_rep_ops.c b/drivers/net/cnxk/cnxk_rep_ops.c
index c481015592..4a9c027bf5 100644
--- a/drivers/net/cnxk/cnxk_rep_ops.c
+++ b/drivers/net/cnxk/cnxk_rep_ops.c
@@ -614,10 +614,10 @@ cnxk_rep_stats_get(struct rte_eth_dev *ethdev, struct rte_eth_stats *stats,
 	}
 
 	if (qstats != NULL) {
-		qstats->q_ipackets[0] = vf_stats.ipackets;
-		qstats->q_ibytes[0] = vf_stats.ibytes;
-		qstats->q_opackets[0] = vf_stats.opackets;
-		qstats->q_obytes[0] = vf_stats.obytes;
+		qstats[0].q_ipackets = vf_stats.ipackets;
+		qstats[0].q_ibytes = vf_stats.ibytes;
+		qstats[0].q_opackets = vf_stats.opackets;
+		qstats[0].q_obytes = vf_stats.obytes;
 	}
 
 	stats->ipackets = vf_stats.ipackets;
diff --git a/drivers/net/cnxk/cnxk_stats.c b/drivers/net/cnxk/cnxk_stats.c
index 469a18f93e..c15c8761c1 100644
--- a/drivers/net/cnxk/cnxk_stats.c
+++ b/drivers/net/cnxk/cnxk_stats.c
@@ -39,28 +39,21 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
 	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
 		struct roc_nix_stats_queue qstats_data;
 
-		if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
-			break;
-
 		rc = roc_nix_stats_queue_get(nix, i, 0, &qstats_data);
 		if (rc)
 			goto exit;
-		qstats->q_opackets[i] = qstats_data.tx_pkts;
-		qstats->q_obytes[i] = qstats_data.tx_octs;
+		qstats[i].q_opackets = qstats_data.tx_pkts;
+		qstats[i].q_obytes = qstats_data.tx_octs;
 	}
 
 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
 		struct roc_nix_stats_queue qstats_data;
 
-		if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
-			break;
-
 		rc = roc_nix_stats_queue_get(nix, i, 1, &qstats_data);
 		if (rc)
 			goto exit;
-		qstats->q_ipackets[i] = qstats_data.rx_pkts;
-		qstats->q_ibytes[i] = qstats_data.rx_octs;
-		qstats->q_errors[i] = qstats_data.rx_drop_pkts;
+		qstats[i].q_ipackets = qstats_data.rx_pkts;
+		qstats[i].q_ibytes = qstats_data.rx_octs;
 	}
 exit:
 	return rc;
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index f211357919..8ae4fd89c5 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -2002,20 +2002,17 @@ dpaa2_dev_stats_get(struct rte_eth_dev *dev,
 	stats->oerrors = value.page_2.egress_discarded_frames;
 	stats->imissed = value.page_2.ingress_nobuffer_discards;
 
-	/* Fill in per queue stats */
+	/* Fill in per queue stats. Byte counting is not implemented. */
 	if (qstats != NULL) {
-		for (i = 0; (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) &&
-			(i < priv->nb_rx_queues || i < priv->nb_tx_queues); ++i) {
+		for (i = 0; i < dev->data->nb_rx_queues; ++i) {
 			dpaa2_rxq = priv->rx_vq[i];
-			dpaa2_txq = priv->tx_vq[i];
 			if (dpaa2_rxq)
-				qstats->q_ipackets[i] = dpaa2_rxq->rx_pkts;
+				qstats[i].q_ipackets = dpaa2_rxq->rx_pkts;
+		}
+		for (i = 0; i < dev->data->nb_tx_queues; ++i) {
+			dpaa2_txq = priv->tx_vq[i];
 			if (dpaa2_txq)
-				qstats->q_opackets[i] = dpaa2_txq->tx_pkts;
-
-			/* Byte counting is not implemented */
-			qstats->q_ibytes[i]   = 0;
-			qstats->q_obytes[i]   = 0;
+				qstats[i].q_opackets = dpaa2_txq->tx_pkts;
 		}
 	}
 
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index ad2ac6dbbf..ae48afcfdc 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1264,7 +1264,6 @@ static int ena_stats_get(struct rte_eth_dev *dev,
 	struct ena_com_dev *ena_dev = &adapter->ena_dev;
 	int rc;
 	int i;
-	int max_rings_stats;
 
 	memset(&ena_stats, 0, sizeof(ena_stats));
 
@@ -1295,26 +1294,18 @@ static int ena_stats_get(struct rte_eth_dev *dev,
 
 	/* Queue statistics */
 	if (qstats) {
-		max_rings_stats = RTE_MIN(dev->data->nb_rx_queues,
-			RTE_ETHDEV_QUEUE_STAT_CNTRS);
-		for (i = 0; i < max_rings_stats; ++i) {
+		for (i = 0; i < dev->data->nb_rx_queues; ++i) {
 			struct ena_stats_rx *rx_stats = &adapter->rx_ring[i].rx_stats;
 
-			qstats->q_ibytes[i] = rx_stats->bytes;
-			qstats->q_ipackets[i] = rx_stats->cnt;
-			qstats->q_errors[i] = rx_stats->bad_desc_num +
-				rx_stats->bad_req_id +
-				rx_stats->bad_desc +
-				rx_stats->unknown_error;
+			qstats[i].q_ibytes = rx_stats->bytes;
+			qstats[i].q_ipackets = rx_stats->cnt;
 		}
 
-		max_rings_stats = RTE_MIN(dev->data->nb_tx_queues,
-			RTE_ETHDEV_QUEUE_STAT_CNTRS);
-		for (i = 0; i < max_rings_stats; ++i) {
+		for (i = 0; i < dev->data->nb_tx_queues; ++i) {
 			struct ena_stats_tx *tx_stats = &adapter->tx_ring[i].tx_stats;
 
-			qstats->q_obytes[i] = tx_stats->bytes;
-			qstats->q_opackets[i] = tx_stats->cnt;
+			qstats[i].q_obytes = tx_stats->bytes;
+			qstats[i].q_opackets = tx_stats->cnt;
 		}
 	}
 
diff --git a/drivers/net/hinic/hinic_pmd_ethdev.c b/drivers/net/hinic/hinic_pmd_ethdev.c
index 91a4348fb6..016d632e64 100644
--- a/drivers/net/hinic/hinic_pmd_ethdev.c
+++ b/drivers/net/hinic/hinic_pmd_ethdev.c
@@ -1329,14 +1329,13 @@ hinic_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 
 	/* rx queue stats */
 	if (qstats) {
-		q_num = (nic_dev->num_rq < RTE_ETHDEV_QUEUE_STAT_CNTRS) ?
-				nic_dev->num_rq : RTE_ETHDEV_QUEUE_STAT_CNTRS;
+		q_num = (nic_dev->num_rq < dev->data->nb_rx_queues) ?
+				nic_dev->num_rq : dev->data->nb_rx_queues;
 		for (i = 0; i < q_num; i++) {
 			rxq = nic_dev->rxqs[i];
 			hinic_rxq_get_stats(rxq, &rxq_stats);
-			qstats->q_ipackets[i] = rxq_stats.packets;
-			qstats->q_ibytes[i] = rxq_stats.bytes;
-			qstats->q_errors[i] = rxq_stats.rx_discards;
+			qstats[i].q_ipackets = rxq_stats.packets;
+			qstats[i].q_ibytes = rxq_stats.bytes;
 
 			stats->ierrors += rxq_stats.errors;
 			rx_discards_pmd += rxq_stats.rx_discards;
@@ -1344,13 +1343,13 @@ hinic_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		}
 
 		/* tx queue stats */
-		q_num = (nic_dev->num_sq < RTE_ETHDEV_QUEUE_STAT_CNTRS) ?
-			nic_dev->num_sq : RTE_ETHDEV_QUEUE_STAT_CNTRS;
+		q_num = (nic_dev->num_sq < dev->data->nb_tx_queues) ?
+			nic_dev->num_sq : dev->data->nb_tx_queues;
 		for (i = 0; i < q_num; i++) {
 			txq = nic_dev->txqs[i];
 			hinic_txq_get_stats(txq, &txq_stats);
-			qstats->q_opackets[i] = txq_stats.packets;
-			qstats->q_obytes[i] = txq_stats.bytes;
+			qstats[i].q_opackets = txq_stats.packets;
+			qstats[i].q_obytes = txq_stats.bytes;
 			stats->oerrors += (txq_stats.tx_busy + txq_stats.off_errs);
 		}
 	} else {
diff --git a/drivers/net/hinic3/hinic3_ethdev.c b/drivers/net/hinic3/hinic3_ethdev.c
index 361e52f7b9..eb5ddd9de6 100644
--- a/drivers/net/hinic3/hinic3_ethdev.c
+++ b/drivers/net/hinic3/hinic3_ethdev.c
@@ -2763,10 +2763,9 @@ hinic3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		rxq->rxq_stats.errors = rxq->rxq_stats.csum_errors +
 					rxq->rxq_stats.other_errors;
 
-		if (qstats && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = rxq->rxq_stats.packets;
-			qstats->q_ibytes[i] = rxq->rxq_stats.bytes;
-			qstats->q_errors[i] = rxq->rxq_stats.errors;
+		if (qstats && i < dev->data->nb_rx_queues) {
+			qstats[i].q_ipackets = rxq->rxq_stats.packets;
+			qstats[i].q_ibytes = rxq->rxq_stats.bytes;
 		}
 		stats->ierrors += rxq->rxq_stats.errors;
 		rx_discards_pmd += rxq->rxq_stats.dropped;
@@ -2777,9 +2776,9 @@ hinic3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	for (uint32_t i = 0; i < nic_dev->num_sqs; i++) {
 		struct hinic3_txq *txq = nic_dev->txqs[i];
 		stats->oerrors += (txq->txq_stats.tx_busy + txq->txq_stats.offload_errors);
-		if (qstats && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[i] = txq->txq_stats.packets;
-			qstats->q_obytes[i] = txq->txq_stats.bytes;
+		if (qstats && i < dev->data->nb_tx_queues) {
+			qstats[i].q_opackets = txq->txq_stats.packets;
+			qstats[i].q_obytes = txq->txq_stats.bytes;
 		}
 	}
 
diff --git a/drivers/net/intel/e1000/igc_ethdev.c b/drivers/net/intel/e1000/igc_ethdev.c
index 943a479f9a..73dd5dd1a3 100644
--- a/drivers/net/intel/e1000/igc_ethdev.c
+++ b/drivers/net/intel/e1000/igc_ethdev.c
@@ -2059,12 +2059,13 @@ eth_igc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats,
 
 	/* Get per-queue statuses */
 	if (qstats) {
-		for (i = 0; i < RTE_MIN(IGC_QUEUE_PAIRS_NUM, RTE_ETHDEV_QUEUE_STAT_CNTRS); i++) {
-			qstats->q_opackets[i] += queue_stats->pqgptc[i];
-			qstats->q_obytes[i] += queue_stats->pqgotc[i];
-			qstats->q_ipackets[i] += queue_stats->pqgprc[i];
-			qstats->q_ibytes[i] += queue_stats->pqgorc[i];
-			qstats->q_errors[i] += queue_stats->rqdpc[i];
+		for (i = 0; i < RTE_MIN(IGC_QUEUE_PAIRS_NUM, dev->data->nb_rx_queues); i++) {
+			qstats[i].q_ipackets += queue_stats->pqgprc[i];
+			qstats[i].q_ibytes += queue_stats->pqgorc[i];
+		}
+		for (i = 0; i < RTE_MIN(IGC_QUEUE_PAIRS_NUM, dev->data->nb_tx_queues); i++) {
+			qstats[i].q_opackets += queue_stats->pqgptc[i];
+			qstats[i].q_obytes += queue_stats->pqgotc[i];
 		}
 	}
 
diff --git a/drivers/net/intel/fm10k/fm10k_ethdev.c b/drivers/net/intel/fm10k/fm10k_ethdev.c
index ca438d2d02..3b2daba79e 100644
--- a/drivers/net/intel/fm10k/fm10k_ethdev.c
+++ b/drivers/net/intel/fm10k/fm10k_ethdev.c
@@ -1328,14 +1328,16 @@ fm10k_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	fm10k_update_hw_stats(hw, hw_stats);
 
 	ipackets = opackets = ibytes = obytes = imissed = 0;
-	for (i = 0; (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) &&
-			(i < hw->mac.max_queues); ++i) {
+	for (i = 0; i < hw->mac.max_queues; ++i) {
 		if (qstats != NULL) {
-			qstats->q_ipackets[i] = hw_stats->q[i].rx_packets.count;
-			qstats->q_opackets[i] = hw_stats->q[i].tx_packets.count;
-			qstats->q_ibytes[i]   = hw_stats->q[i].rx_bytes.count;
-			qstats->q_obytes[i]   = hw_stats->q[i].tx_bytes.count;
-			qstats->q_errors[i]   = hw_stats->q[i].rx_drops.count;
+			if (i < dev->data->nb_rx_queues) {
+				qstats[i].q_ipackets = hw_stats->q[i].rx_packets.count;
+				qstats[i].q_ibytes   = hw_stats->q[i].rx_bytes.count;
+			}
+			if (i < dev->data->nb_tx_queues) {
+				qstats[i].q_opackets = hw_stats->q[i].tx_packets.count;
+				qstats[i].q_obytes   = hw_stats->q[i].tx_bytes.count;
+			}
 		}
 		ipackets += hw_stats->q[i].rx_packets.count;
 		opackets += hw_stats->q[i].tx_packets.count;
diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.c b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
index d35da73d69..3620331d6c 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
@@ -3355,12 +3355,14 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev,
 
 	if (qstats != NULL) {
 		for (i = 0; i < RTE_MIN_T(IXGBE_QUEUE_STAT_COUNTERS,
-				RTE_ETHDEV_QUEUE_STAT_CNTRS, typeof(i)); i++) {
-			qstats->q_ipackets[i] = hw_stats->qprc[i];
-			qstats->q_opackets[i] = hw_stats->qptc[i];
-			qstats->q_ibytes[i] = hw_stats->qbrc[i];
-			qstats->q_obytes[i] = hw_stats->qbtc[i];
-			qstats->q_errors[i] = hw_stats->qprdc[i];
+				dev->data->nb_rx_queues, typeof(i)); i++) {
+			qstats[i].q_ipackets = hw_stats->qprc[i];
+			qstats[i].q_ibytes = hw_stats->qbrc[i];
+		}
+		for (i = 0; i < RTE_MIN_T(IXGBE_QUEUE_STAT_COUNTERS,
+				dev->data->nb_tx_queues, typeof(i)); i++) {
+			qstats[i].q_opackets = hw_stats->qptc[i];
+			qstats[i].q_obytes = hw_stats->qbtc[i];
 		}
 	}
 
diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index b52c8cad88..2443c98881 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -105,10 +105,15 @@ ionic_lif_get_abs_stats(const struct ionic_lif *lif, struct rte_eth_stats *stats
 {
 	struct ionic_lif_stats *ls = &lif->info->stats;
 	uint32_t i;
-	uint32_t num_rx_q_counters = RTE_MIN(lif->nrxqcqs, (uint32_t)
-			RTE_ETHDEV_QUEUE_STAT_CNTRS);
-	uint32_t num_tx_q_counters = RTE_MIN(lif->ntxqcqs, (uint32_t)
-			RTE_ETHDEV_QUEUE_STAT_CNTRS);
+	/*
+	 * The queue stats array is indexed by queue id and sized by the
+	 * queue counts passed to configure, which is not necessarily the
+	 * number of queues the LIF has allocated.
+	 */
+	uint32_t num_rx_q_counters = RTE_MIN(lif->nrxqcqs,
+			(uint32_t)lif->eth_dev->data->nb_rx_queues);
+	uint32_t num_tx_q_counters = RTE_MIN(lif->ntxqcqs,
+			(uint32_t)lif->eth_dev->data->nb_tx_queues);
 
 	memset(stats, 0, sizeof(*stats));
 
@@ -148,11 +153,8 @@ ionic_lif_get_abs_stats(const struct ionic_lif *lif, struct rte_eth_stats *stats
 	if (qstats != NULL) {
 		for (i = 0; i < num_rx_q_counters; i++) {
 			struct ionic_rx_stats *rx_stats = &lif->rxqcqs[i]->stats;
-			qstats->q_ipackets[i] = rx_stats->packets;
-			qstats->q_ibytes[i] = rx_stats->bytes;
-			qstats->q_errors[i] =
-				rx_stats->bad_cq_status +
-				rx_stats->bad_len;
+			qstats[i].q_ipackets = rx_stats->packets;
+			qstats[i].q_ibytes = rx_stats->bytes;
 		}
 	}
 
@@ -185,8 +187,8 @@ ionic_lif_get_abs_stats(const struct ionic_lif *lif, struct rte_eth_stats *stats
 	if (qstats != NULL) {
 		for (i = 0; i < num_tx_q_counters; i++) {
 			struct ionic_tx_stats *tx_stats = &lif->txqcqs[i]->stats;
-			qstats->q_opackets[i] = tx_stats->packets;
-			qstats->q_obytes[i] = tx_stats->bytes;
+			qstats[i].q_opackets = tx_stats->packets;
+			qstats[i].q_obytes = tx_stats->bytes;
 		}
 	}
 }
diff --git a/drivers/net/mana/mana.c b/drivers/net/mana/mana.c
index 0b72f711a1..72c8501d3c 100644
--- a/drivers/net/mana/mana.c
+++ b/drivers/net/mana/mana.c
@@ -779,9 +779,9 @@ mana_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		stats->obytes += txq->stats.bytes;
 		stats->oerrors += txq->stats.errors;
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[i] = txq->stats.packets;
-			qstats->q_obytes[i] = txq->stats.bytes;
+		if (qstats != NULL && i < dev->data->nb_tx_queues) {
+			qstats[i].q_opackets = txq->stats.packets;
+			qstats[i].q_obytes = txq->stats.bytes;
 		}
 	}
 
@@ -798,9 +798,9 @@ mana_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 
 		/* There is no good way to get stats->imissed, not setting it */
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = rxq->stats.packets;
-			qstats->q_ibytes[i] = rxq->stats.bytes;
+		if (qstats != NULL && i < dev->data->nb_rx_queues) {
+			qstats[i].q_ipackets = rxq->stats.packets;
+			qstats[i].q_ibytes = rxq->stats.bytes;
 		}
 
 		stats->rx_nombuf += rxq->stats.nombuf;
diff --git a/drivers/net/memif/rte_eth_memif.c b/drivers/net/memif/rte_eth_memif.c
index 5d153c3a5a..1c8dc1d5ec 100644
--- a/drivers/net/memif/rte_eth_memif.c
+++ b/drivers/net/memif/rte_eth_memif.c
@@ -1607,15 +1607,15 @@ memif_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 
 	tmp = (pmd->role == MEMIF_ROLE_CLIENT) ? pmd->run.num_s2c_rings :
 	    pmd->run.num_c2s_rings;
-	nq = (tmp < RTE_ETHDEV_QUEUE_STAT_CNTRS) ? tmp :
-	    RTE_ETHDEV_QUEUE_STAT_CNTRS;
+	nq = (tmp < dev->data->nb_rx_queues) ? tmp :
+	    dev->data->nb_rx_queues;
 
 	/* RX stats */
 	for (i = 0; i < nq; i++) {
 		mq = dev->data->rx_queues[i];
 		if (qstats != NULL) {
-			qstats->q_ipackets[i] = mq->n_pkts;
-			qstats->q_ibytes[i] = mq->n_bytes;
+			qstats[i].q_ipackets = mq->n_pkts;
+			qstats[i].q_ibytes = mq->n_bytes;
 		}
 		stats->ipackets += mq->n_pkts;
 		stats->ibytes += mq->n_bytes;
@@ -1624,15 +1624,15 @@ memif_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 
 	tmp = (pmd->role == MEMIF_ROLE_CLIENT) ? pmd->run.num_c2s_rings :
 	    pmd->run.num_s2c_rings;
-	nq = (tmp < RTE_ETHDEV_QUEUE_STAT_CNTRS) ? tmp :
-	    RTE_ETHDEV_QUEUE_STAT_CNTRS;
+	nq = (tmp < dev->data->nb_tx_queues) ? tmp :
+	    dev->data->nb_tx_queues;
 
 	/* TX stats */
 	for (i = 0; i < nq; i++) {
 		mq = dev->data->tx_queues[i];
 		if (qstats != NULL) {
-			qstats->q_opackets[i] = mq->n_pkts;
-			qstats->q_obytes[i] = mq->n_bytes;
+			qstats[i].q_opackets = mq->n_pkts;
+			qstats[i].q_obytes = mq->n_bytes;
 		}
 		stats->opackets += mq->n_pkts;
 		stats->obytes += mq->n_bytes;
diff --git a/drivers/net/mlx4/mlx4_ethdev.c b/drivers/net/mlx4/mlx4_ethdev.c
index efc6ee4577..4ea79bf1eb 100644
--- a/drivers/net/mlx4/mlx4_ethdev.c
+++ b/drivers/net/mlx4/mlx4_ethdev.c
@@ -717,11 +717,9 @@ mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		if (rxq == NULL)
 			continue;
 		idx = rxq->stats.idx;
-		if (qstats != NULL && idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[idx] += rxq->stats.ipackets;
-			qstats->q_ibytes[idx] += rxq->stats.ibytes;
-			qstats->q_errors[idx] += (rxq->stats.idropped +
-					      rxq->stats.rx_nombuf);
+		if (qstats != NULL && idx < dev->data->nb_rx_queues) {
+			qstats[idx].q_ipackets += rxq->stats.ipackets;
+			qstats[idx].q_ibytes += rxq->stats.ibytes;
 		}
 		tmp.ipackets += rxq->stats.ipackets;
 		tmp.ibytes += rxq->stats.ibytes;
@@ -734,9 +732,9 @@ mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		if (txq == NULL)
 			continue;
 		idx = txq->stats.idx;
-		if (qstats != NULL && idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[idx] += txq->stats.opackets;
-			qstats->q_obytes[idx] += txq->stats.obytes;
+		if (qstats != NULL && idx < dev->data->nb_tx_queues) {
+			qstats[idx].q_opackets += txq->stats.opackets;
+			qstats[idx].q_obytes += txq->stats.obytes;
 		}
 		tmp.opackets += txq->stats.opackets;
 		tmp.obytes += txq->stats.obytes;
diff --git a/drivers/net/mlx5/mlx5_rx.h b/drivers/net/mlx5/mlx5_rx.h
index cd48ee37ef..0d1eee61b2 100644
--- a/drivers/net/mlx5/mlx5_rx.h
+++ b/drivers/net/mlx5/mlx5_rx.h
@@ -53,9 +53,10 @@ struct mlx5_xstats_name_off {
 	unsigned int offset;
 };
 
+/* Only used with offsetof() for the xstats names table. */
 struct mlx5_rq_stats {
 	/** Total number of hairpin queue packets received that are dropped. */
-	uint64_t q_oobs[RTE_ETHDEV_QUEUE_STAT_CNTRS];
+	uint64_t q_oobs;
 };
 
 /* Compressed CQE context. */
diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c
index 5cd3e303cc..1fbd298c77 100644
--- a/drivers/net/mlx5/mlx5_stats.c
+++ b/drivers/net/mlx5/mlx5_stats.c
@@ -44,7 +44,7 @@ static int
 mlx5_rq_xstats_get(struct rte_eth_dev *dev,
 					struct rte_eth_xstat *stats)
 {
-	uint16_t n_stats_rq = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+	uint16_t n_stats_rq = dev->data->nb_rx_queues;
 	int cnt_used_entries = 0;
 
 	for (unsigned int idx = 0; idx < n_stats_rq; idx++) {
@@ -101,7 +101,7 @@ mlx5_rq_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
 	unsigned int i;
 	int cnt_used_entries = 0;
 
-	uint16_t n_stats_rq = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+	uint16_t n_stats_rq = dev->data->nb_rx_queues;
 
 	for (i = 0; (i != n_stats_rq); ++i) {
 		rxq = mlx5_rxq_get(dev, i);
@@ -227,17 +227,13 @@ mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		if (rxq == NULL)
 			continue;
 		idx = rxq->idx;
-		if (qstats != NULL && idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
+		if (qstats != NULL && idx < dev->data->nb_rx_queues) {
 #ifdef MLX5_PMD_SOFT_COUNTERS
-			qstats->q_ipackets[idx] += rxq->stats.ipackets -
+			qstats[idx].q_ipackets += rxq->stats.ipackets -
 				rxq->stats_reset.ipackets;
-			qstats->q_ibytes[idx] += rxq->stats.ibytes -
+			qstats[idx].q_ibytes += rxq->stats.ibytes -
 				rxq->stats_reset.ibytes;
 #endif
-			qstats->q_errors[idx] += (rxq->stats.idropped +
-					      rxq->stats.rx_nombuf) -
-					      (rxq->stats_reset.idropped +
-					      rxq->stats_reset.rx_nombuf);
 		}
 #ifdef MLX5_PMD_SOFT_COUNTERS
 		tmp.ipackets += rxq->stats.ipackets - rxq->stats_reset.ipackets;
@@ -253,11 +249,11 @@ mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		if (txq == NULL)
 			continue;
 		idx = txq->idx;
-		if (qstats != NULL && idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
+		if (qstats != NULL && idx < dev->data->nb_tx_queues) {
 #ifdef MLX5_PMD_SOFT_COUNTERS
-			qstats->q_opackets[idx] += txq->stats.opackets -
+			qstats[idx].q_opackets += txq->stats.opackets -
 						txq->stats_reset.opackets;
-			qstats->q_obytes[idx] += txq->stats.obytes -
+			qstats[idx].q_obytes += txq->stats.obytes -
 						txq->stats_reset.obytes;
 #endif
 		}
@@ -467,7 +463,7 @@ mlx5_xstats_get_names(struct rte_eth_dev *dev,
 static struct mlx5_stat_counter_ctrl*
 mlx5_rxq_get_counter_by_id(struct rte_eth_dev *dev, uint64_t id, uint64_t *rq_id)
 {
-	uint16_t n_stats_rq = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+	uint16_t n_stats_rq = dev->data->nb_rx_queues;
 
 	for (int i = 0; (i != n_stats_rq); i++) {
 		struct mlx5_rxq_data *rxq_data = mlx5_rxq_data_get(dev, i);
diff --git a/drivers/net/mvpp2/mrvl_ethdev.c b/drivers/net/mvpp2/mrvl_ethdev.c
index bc947ff52e..d7ed504bee 100644
--- a/drivers/net/mvpp2/mrvl_ethdev.c
+++ b/drivers/net/mvpp2/mrvl_ethdev.c
@@ -1505,10 +1505,10 @@ mrvl_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 			continue;
 
 		idx = rxq->queue_id;
-		if (unlikely(idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)) {
+		if (unlikely(idx >= dev->data->nb_rx_queues)) {
 			MRVL_LOG(ERR,
 				"rx queue %d stats out of range (0 - %d)",
-				idx, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
+				idx, dev->data->nb_rx_queues - 1);
 			continue;
 		}
 
@@ -1523,12 +1523,8 @@ mrvl_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		}
 
 		if (qstats != NULL) {
-			qstats->q_ibytes[idx] = rxq->bytes_recv;
-			qstats->q_ipackets[idx] = rx_stats.enq_desc - rxq->drop_mac;
-			qstats->q_errors[idx] = rx_stats.drop_early +
-					       rx_stats.drop_fullq +
-					       rx_stats.drop_bm +
-					       rxq->drop_mac;
+			qstats[idx].q_ibytes = rxq->bytes_recv;
+			qstats[idx].q_ipackets = rx_stats.enq_desc - rxq->drop_mac;
 		}
 		stats->ibytes += rxq->bytes_recv;
 		drop_mac += rxq->drop_mac;
@@ -1542,10 +1538,10 @@ mrvl_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 			continue;
 
 		idx = txq->queue_id;
-		if (unlikely(idx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)) {
+		if (unlikely(idx >= dev->data->nb_tx_queues)) {
 			MRVL_LOG(ERR,
 				"tx queue %d stats out of range (0 - %d)",
-				idx, RTE_ETHDEV_QUEUE_STAT_CNTRS - 1);
+				idx, dev->data->nb_tx_queues - 1);
 			continue;
 		}
 
@@ -1558,8 +1554,8 @@ mrvl_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		}
 
 		if (qstats != NULL) {
-			qstats->q_opackets[idx] = tx_stats.deq_desc;
-			qstats->q_obytes[idx] = txq->bytes_sent;
+			qstats[idx].q_opackets = tx_stats.deq_desc;
+			qstats[idx].q_obytes = txq->bytes_sent;
 		}
 		stats->obytes += txq->bytes_sent;
 	}
diff --git a/drivers/net/nbl/nbl_dev/nbl_dev.c b/drivers/net/nbl/nbl_dev/nbl_dev.c
index 3c0e98d687..320f26619f 100644
--- a/drivers/net/nbl/nbl_dev/nbl_dev.c
+++ b/drivers/net/nbl/nbl_dev/nbl_dev.c
@@ -534,8 +534,6 @@ int nbl_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats,
 		goto update_hw_stats_fail;
 
 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
-		if (qstats && i < RTE_ETHDEV_QUEUE_STAT_CNTRS)
-			qstats->q_errors[i] = net_dev->hw_stats.total_uvn_stat_pkt_drop[i];
 		rte_stats->imissed += net_dev->hw_stats.total_uvn_stat_pkt_drop[i];
 	}
 
diff --git a/drivers/net/nbl/nbl_hw/nbl_txrx.c b/drivers/net/nbl/nbl_hw/nbl_txrx.c
index f29f0a6d5b..7beae85177 100644
--- a/drivers/net/nbl/nbl_hw/nbl_txrx.c
+++ b/drivers/net/nbl/nbl_hw/nbl_txrx.c
@@ -795,10 +795,10 @@ static int nbl_res_txrx_get_stats(void *priv, struct rte_eth_stats *rte_stats,
 		rxq_stats_reset = &rxq->rxq_stats_reset;
 		idx = rxq->queue_id;
 
-		if (qstats && idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[idx] += rxq_stats->rx_packets -
+		if (qstats && idx < eth_dev->data->nb_rx_queues) {
+			qstats[idx].q_ipackets += rxq_stats->rx_packets -
 							rxq_stats_reset->rx_packets;
-			qstats->q_ibytes[idx] += rxq_stats->rx_bytes - rxq_stats_reset->rx_bytes;
+			qstats[idx].q_ibytes += rxq_stats->rx_bytes - rxq_stats_reset->rx_bytes;
 		}
 		rte_stats->ipackets += rxq_stats->rx_packets - rxq_stats_reset->rx_packets;
 		rte_stats->ibytes += rxq_stats->rx_bytes - rxq_stats_reset->rx_bytes;
@@ -814,10 +814,10 @@ static int nbl_res_txrx_get_stats(void *priv, struct rte_eth_stats *rte_stats,
 		txq_stats_reset = &txq->txq_stats_reset;
 		idx = txq->queue_id;
 
-		if (qstats && idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[idx] += txq_stats->tx_packets -
+		if (qstats && idx < eth_dev->data->nb_tx_queues) {
+			qstats[idx].q_opackets += txq_stats->tx_packets -
 							txq_stats_reset->tx_packets;
-			qstats->q_obytes[idx] += txq_stats->tx_bytes - txq_stats_reset->tx_bytes;
+			qstats[idx].q_obytes += txq_stats->tx_bytes - txq_stats_reset->tx_bytes;
 		}
 		rte_stats->opackets += txq_stats->tx_packets - txq_stats_reset->tx_packets;
 		rte_stats->obytes += txq_stats->tx_bytes - txq_stats_reset->tx_bytes;
diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c
index 9a193e4a7a..e4fdf89873 100644
--- a/drivers/net/netvsc/hn_ethdev.c
+++ b/drivers/net/netvsc/hn_ethdev.c
@@ -1122,9 +1122,9 @@ static int hn_dev_stats_get(struct rte_eth_dev *dev,
 		stats->obytes += txq->stats.bytes;
 		stats->oerrors += txq->stats.errors;
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[i] += txq->stats.packets;
-			qstats->q_obytes[i] += txq->stats.bytes;
+		if (qstats != NULL) {
+			qstats[i].q_opackets += txq->stats.packets;
+			qstats[i].q_obytes += txq->stats.bytes;
 		}
 	}
 
@@ -1139,9 +1139,9 @@ static int hn_dev_stats_get(struct rte_eth_dev *dev,
 		stats->ierrors += rxq->stats.errors;
 		stats->imissed += rxq->stats.ring_full;
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] += rxq->stats.packets;
-			qstats->q_ibytes[i] += rxq->stats.bytes;
+		if (qstats != NULL) {
+			qstats[i].q_ipackets += rxq->stats.packets;
+			qstats[i].q_ibytes += rxq->stats.bytes;
 		}
 	}
 
diff --git a/drivers/net/netvsc/hn_vf.c b/drivers/net/netvsc/hn_vf.c
index 27c46ce404..96e811278a 100644
--- a/drivers/net/netvsc/hn_vf.c
+++ b/drivers/net/netvsc/hn_vf.c
@@ -927,7 +927,8 @@ int hn_vf_stats_get(struct rte_eth_dev *dev,
 		 * rte_eth_stats_get API because we need to forward the
 		 * per-queue stats (qstats) which the public API does not
 		 * support.  The caller (eth_stats_qstats_get) has already
-		 * zeroed stats and qstats before invoking this callback.
+		 * zeroed stats, and qstats is zeroed by its allocation,
+		 * before invoking this callback.
 		 */
 		if (vf_dev->dev_ops->stats_get != NULL)
 			ret = vf_dev->dev_ops->stats_get(vf_dev, stats,
diff --git a/drivers/net/nfb/nfb_stats.c b/drivers/net/nfb/nfb_stats.c
index f7a0189ffe..0b4bdc7d18 100644
--- a/drivers/net/nfb/nfb_stats.c
+++ b/drivers/net/nfb/nfb_stats.c
@@ -25,9 +25,9 @@ nfb_eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		if (rx_queue == NULL)
 			continue;
 
-		if (qstats && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = rx_queue->rx_pkts;
-			qstats->q_ibytes[i] = rx_queue->rx_bytes;
+		if (qstats && i < dev->data->nb_rx_queues) {
+			qstats[i].q_ipackets = rx_queue->rx_pkts;
+			qstats[i].q_ibytes = rx_queue->rx_bytes;
 		}
 	}
 
@@ -36,9 +36,9 @@ nfb_eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		if (tx_queue == NULL)
 			continue;
 
-		if (qstats && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[i] = tx_queue->tx_pkts;
-			qstats->q_obytes[i] = tx_queue->tx_bytes;
+		if (qstats && i < dev->data->nb_tx_queues) {
+			qstats[i].q_opackets = tx_queue->tx_pkts;
+			qstats[i].q_obytes = tx_queue->tx_bytes;
 		}
 	}
 
diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c
index 4eeb9aee3b..14a8992376 100644
--- a/drivers/net/nfp/flower/nfp_flower.c
+++ b/drivers/net/nfp/flower/nfp_flower.c
@@ -238,8 +238,8 @@ nfp_flower_multiple_pf_recv_pkts(void *rx_queue,
 		for (i = 0; i < recv; i++)
 			data_len += rx_pkts[i]->data_len;
 
-		repr->repr_qstats.q_ipackets[rxq->qidx] += recv;
-		repr->repr_qstats.q_ibytes[rxq->qidx] += data_len;
+		repr->repr_qstats[rxq->qidx].q_ipackets += recv;
+		repr->repr_qstats[rxq->qidx].q_ibytes += data_len;
 	}
 
 	return recv;
@@ -276,8 +276,8 @@ nfp_flower_multiple_pf_xmit_pkts(void *tx_queue,
 		for (i = 0; i < sent; i++)
 			data_len += tx_pkts[i]->data_len;
 
-		repr->repr_qstats.q_opackets[txq->qidx] += sent;
-		repr->repr_qstats.q_obytes[txq->qidx] += data_len;
+		repr->repr_qstats[txq->qidx].q_opackets += sent;
+		repr->repr_qstats[txq->qidx].q_obytes += data_len;
 	}
 
 	return sent;
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c
index 9b984dbc8d..231a76980d 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.c
+++ b/drivers/net/nfp/flower/nfp_flower_representor.c
@@ -324,15 +324,15 @@ nfp_flower_repr_stats_get(struct rte_eth_dev *ethdev,
 	repr->repr_stats.ipackets = 0;
 	repr->repr_stats.ibytes = 0;
 	for (i = 0; i < ethdev->data->nb_rx_queues; i++) {
-		repr->repr_stats.ipackets += repr->repr_qstats.q_ipackets[i];
-		repr->repr_stats.ibytes += repr->repr_qstats.q_ibytes[i];
+		repr->repr_stats.ipackets += repr->repr_qstats[i].q_ipackets;
+		repr->repr_stats.ibytes += repr->repr_qstats[i].q_ibytes;
 	}
 
 	repr->repr_stats.opackets = 0;
 	repr->repr_stats.obytes = 0;
 	for (i = 0; i < ethdev->data->nb_tx_queues; i++) {
-		repr->repr_stats.opackets += repr->repr_qstats.q_opackets[i];
-		repr->repr_stats.obytes += repr->repr_qstats.q_obytes[i];
+		repr->repr_stats.opackets += repr->repr_qstats[i].q_opackets;
+		repr->repr_stats.obytes += repr->repr_qstats[i].q_obytes;
 	}
 
 	*stats = repr->repr_stats;
@@ -347,7 +347,8 @@ nfp_flower_repr_stats_reset(struct rte_eth_dev *ethdev)
 
 	repr = ethdev->data->dev_private;
 	memset(&repr->repr_stats, 0, sizeof(struct rte_eth_stats));
-	memset(&repr->repr_qstats, 0, sizeof(struct eth_queue_stats));
+	memset(repr->repr_qstats, 0,
+			sizeof(struct eth_queue_stats) * repr->repr_nb_qstats);
 
 	return 0;
 }
@@ -403,8 +404,8 @@ nfp_flower_repr_rx_burst(void *rx_queue,
 		for (i = 0; i < total_dequeue; i++)
 			data_len += rx_pkts[i]->data_len;
 
-		repr->repr_qstats.q_ipackets[rxq->qidx] += total_dequeue;
-		repr->repr_qstats.q_ibytes[rxq->qidx] += data_len;
+		repr->repr_qstats[rxq->qidx].q_ipackets += total_dequeue;
+		repr->repr_qstats[rxq->qidx].q_ibytes += data_len;
 	}
 
 	return total_dequeue;
@@ -451,8 +452,8 @@ nfp_flower_repr_tx_burst(void *tx_queue,
 		for (i = 0; i < sent; i++)
 			data_len += tx_pkts[i]->data_len;
 
-		repr->repr_qstats.q_opackets[txq->qidx] += sent;
-		repr->repr_qstats.q_obytes[txq->qidx] += data_len;
+		repr->repr_qstats[txq->qidx].q_opackets += sent;
+		repr->repr_qstats[txq->qidx].q_obytes += data_len;
 	}
 
 	return sent;
@@ -528,6 +529,7 @@ nfp_flower_repr_uninit(struct rte_eth_dev *eth_dev)
 
 	repr = eth_dev->data->dev_private;
 	nfp_flower_repr_base_uninit(repr);
+	rte_free(repr->repr_qstats);
 	rte_free(repr->ring);
 
 	if (nfp_flower_repr_is_phy(repr)) {
@@ -893,6 +895,17 @@ nfp_flower_repr_init(struct rte_eth_dev *eth_dev,
 		return -ENOMEM;
 	}
 
+	repr->repr_nb_qstats = RTE_MAX(app_fw_flower->pf_hw->max_rx_queues,
+			app_fw_flower->pf_hw->max_tx_queues);
+	repr->repr_qstats = rte_zmalloc_socket("nfp_repr_qstats",
+			sizeof(struct eth_queue_stats) * repr->repr_nb_qstats,
+			RTE_CACHE_LINE_SIZE, numa_node);
+	if (repr->repr_qstats == NULL) {
+		PMD_DRV_LOG(ERR, "Queue stats alloc failed for %s.", ring_name);
+		rte_free(repr->ring);
+		return -ENOMEM;
+	}
+
 	eth_dev->dev_ops = &nfp_flower_repr_dev_ops;
 	eth_dev->rx_pkt_burst = nfp_flower_repr_rx_burst;
 	eth_dev->tx_pkt_burst = nfp_flower_repr_tx_burst;
@@ -928,6 +941,7 @@ nfp_flower_repr_init(struct rte_eth_dev *eth_dev,
 	return 0;
 
 ring_cleanup:
+	rte_free(repr->repr_qstats);
 	rte_free(repr->ring);
 
 	return ret;
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.h b/drivers/net/nfp/flower/nfp_flower_representor.h
index 66714d9a51..74e09749f6 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.h
+++ b/drivers/net/nfp/flower/nfp_flower_representor.h
@@ -22,7 +22,9 @@ struct nfp_flower_representor {
 	struct rte_ring **ring;
 	struct rte_eth_link link;
 	struct rte_eth_stats repr_stats;
-	struct eth_queue_stats repr_qstats;
+	/** Per-queue counters, one entry per queue */
+	struct eth_queue_stats *repr_qstats;
+	uint16_t repr_nb_qstats;
 
 	struct rte_eth_xstat *repr_xstats_base;
 	uint8_t *mac_stats;
diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index d2da18013c..2f7ce812e4 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -663,6 +663,7 @@ nfp_net_uninit(struct rte_eth_dev *eth_dev)
 	if ((net_hw->super.cap_ext & NFP_NET_CFG_CTRL_FLOW_STEER) != 0)
 		nfp_net_flow_priv_uninit(hw_priv->pf_dev, net_hw->idx);
 
+	rte_free(net_hw->eth_qstats_base);
 	rte_free(net_hw->eth_xstats_base);
 	if ((net_hw->super.cap & NFP_NET_CFG_CTRL_TXRWB) != 0)
 		nfp_net_txrwb_free(eth_dev);
@@ -1091,6 +1092,17 @@ nfp_net_init(struct rte_eth_dev *eth_dev,
 		goto ipsec_exit;
 	}
 
+	net_hw->eth_qstats_base = rte_calloc("eth_queue_stats",
+			RTE_MAX(net_hw->max_rx_queues, net_hw->max_tx_queues),
+			sizeof(struct eth_queue_stats), 0);
+	if (net_hw->eth_qstats_base == NULL) {
+		PMD_INIT_LOG(ERR, "No memory for queue stats base values on device %s!",
+				pci_dev->device.name);
+		rte_free(net_hw->eth_xstats_base);
+		err = -ENOMEM;
+		goto ipsec_exit;
+	}
+
 	/* Work out where in the BAR the queues start. */
 	tx_base = nn_cfg_readl(hw, NFP_NET_CFG_START_TXQ);
 	rx_base = nn_cfg_readl(hw, NFP_NET_CFG_START_RXQ);
@@ -1183,6 +1195,7 @@ nfp_net_init(struct rte_eth_dev *eth_dev,
 	if ((hw->cap & NFP_NET_CFG_CTRL_TXRWB) != 0)
 		nfp_net_txrwb_free(eth_dev);
 xstats_free:
+	rte_free(net_hw->eth_qstats_base);
 	rte_free(net_hw->eth_xstats_base);
 ipsec_exit:
 	nfp_ipsec_uninit(eth_dev);
diff --git a/drivers/net/nfp/nfp_ethdev_vf.c b/drivers/net/nfp/nfp_ethdev_vf.c
index a86cc36592..d81a5052b9 100644
--- a/drivers/net/nfp/nfp_ethdev_vf.c
+++ b/drivers/net/nfp/nfp_ethdev_vf.c
@@ -172,6 +172,7 @@ nfp_netvf_close(struct rte_eth_dev *dev)
 	pci_dev = RTE_CLASS_TO_BUS_DEVICE(dev, *pci_dev);
 	hw_priv = dev->process_private;
 
+	rte_free(net_hw->eth_qstats_base);
 	rte_free(net_hw->eth_xstats_base);
 	rte_free(hw_priv);
 
@@ -339,6 +340,17 @@ nfp_netvf_init(struct rte_eth_dev *eth_dev)
 		goto hw_priv_free;
 	}
 
+	net_hw->eth_qstats_base = rte_calloc("eth_queue_stats",
+			RTE_MAX(net_hw->max_rx_queues, net_hw->max_tx_queues),
+			sizeof(struct eth_queue_stats), 0);
+	if (net_hw->eth_qstats_base == NULL) {
+		PMD_INIT_LOG(ERR, "No memory for queue stats base values on device %s!",
+				pci_dev->device.name);
+		rte_free(net_hw->eth_xstats_base);
+		err = -ENOMEM;
+		goto hw_priv_free;
+	}
+
 	/* Work out where in the BAR the queues start. */
 	start_q = nn_cfg_readl(hw, NFP_NET_CFG_START_TXQ);
 	tx_bar_off = nfp_qcp_queue_offset(dev_info, start_q);
@@ -406,6 +418,7 @@ nfp_netvf_init(struct rte_eth_dev *eth_dev)
 	return 0;
 
 free_xstats:
+	rte_free(net_hw->eth_qstats_base);
 	rte_free(net_hw->eth_xstats_base);
 hw_priv_free:
 	rte_free(hw_priv);
diff --git a/drivers/net/nfp/nfp_net_common.c b/drivers/net/nfp/nfp_net_common.c
index 2d36311cfe..afa0bc0faf 100644
--- a/drivers/net/nfp/nfp_net_common.c
+++ b/drivers/net/nfp/nfp_net_common.c
@@ -919,35 +919,29 @@ nfp_net_stats_get(struct rte_eth_dev *dev,
 
 	/* Reading per RX ring stats */
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
-			break;
-
 		uint64_t q_ipackets = nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i));
-		q_ipackets -= hw->eth_qstats_base.q_ipackets[i];
+		q_ipackets -= hw->eth_qstats_base[i].q_ipackets;
 
 		uint64_t q_ibytes = nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i) + 0x8);
-		q_ibytes -= hw->eth_qstats_base.q_ibytes[i];
+		q_ibytes -= hw->eth_qstats_base[i].q_ibytes;
 
 		if (qstats != NULL) {
-			qstats->q_ipackets[i] = q_ipackets;
-			qstats->q_ibytes[i] = q_ibytes;
+			qstats[i].q_ipackets = q_ipackets;
+			qstats[i].q_ibytes = q_ibytes;
 		}
 	}
 
 	/* Reading per TX ring stats */
 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
-		if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
-			break;
-
 		uint64_t q_opackets = nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i));
-		q_opackets -= hw->eth_qstats_base.q_opackets[i];
+		q_opackets -= hw->eth_qstats_base[i].q_opackets;
 
 		uint64_t q_obytes = nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i) + 0x8);
-		q_obytes -= hw->eth_qstats_base.q_obytes[i];
+		q_obytes -= hw->eth_qstats_base[i].q_obytes;
 
 		if (qstats != NULL) {
-			qstats->q_opackets[i] = q_opackets;
-			qstats->q_obytes[i] = q_obytes;
+			qstats[i].q_opackets = q_opackets;
+			qstats[i].q_obytes = q_obytes;
 		}
 	}
 
@@ -999,25 +993,19 @@ nfp_net_stats_reset(struct rte_eth_dev *dev)
 
 	/* Reading per RX ring stats */
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
-			break;
-
-		hw->eth_qstats_base.q_ipackets[i] =
+		hw->eth_qstats_base[i].q_ipackets =
 				nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i));
 
-		hw->eth_qstats_base.q_ibytes[i] =
+		hw->eth_qstats_base[i].q_ibytes =
 				nn_cfg_readq(&hw->super, NFP_NET_CFG_RXR_STATS(i) + 0x8);
 	}
 
 	/* Reading per TX ring stats */
 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
-		if (i == RTE_ETHDEV_QUEUE_STAT_CNTRS)
-			break;
-
-		hw->eth_qstats_base.q_opackets[i] =
+		hw->eth_qstats_base[i].q_opackets =
 				nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i));
 
-		hw->eth_qstats_base.q_obytes[i] =
+		hw->eth_qstats_base[i].q_obytes =
 				nn_cfg_readq(&hw->super, NFP_NET_CFG_TXR_STATS(i) + 0x8);
 	}
 
diff --git a/drivers/net/nfp/nfp_net_common.h b/drivers/net/nfp/nfp_net_common.h
index 2bd2d54028..51082c6d29 100644
--- a/drivers/net/nfp/nfp_net_common.h
+++ b/drivers/net/nfp/nfp_net_common.h
@@ -250,7 +250,8 @@ struct nfp_net_hw {
 
 	/** Records starting point for counters */
 	struct rte_eth_stats eth_stats_base;
-	struct eth_queue_stats eth_qstats_base;
+	/** Per-queue counters, one entry per queue */
+	struct eth_queue_stats *eth_qstats_base;
 	struct rte_eth_xstat *eth_xstats_base;
 
 	struct nfp_cpp_area *ctrl_area;
diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c
index 09bcd791ed..dc8e65ecc2 100644
--- a/drivers/net/ngbe/ngbe_ethdev.c
+++ b/drivers/net/ngbe/ngbe_ethdev.c
@@ -1498,10 +1498,8 @@ ngbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 {
 	struct ngbe_hw *hw = ngbe_dev_hw(dev);
 	struct ngbe_hw_stats *hw_stats = NGBE_DEV_STATS(dev);
-	struct ngbe_stat_mappings *stat_mappings =
-			NGBE_DEV_STAT_MAPPINGS(dev);
 	struct ngbe_tx_queue *txq;
-	uint32_t i, j;
+	uint32_t i;
 
 	ngbe_read_stats_registers(hw, hw_stats);
 
@@ -1515,29 +1513,13 @@ ngbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	stats->obytes = hw_stats->tx_bytes;
 
 	if (qstats != NULL) {
-		memset(&qstats->q_ipackets, 0, sizeof(qstats->q_ipackets));
-		memset(&qstats->q_opackets, 0, sizeof(qstats->q_opackets));
-		memset(&qstats->q_ibytes, 0, sizeof(qstats->q_ibytes));
-		memset(&qstats->q_obytes, 0, sizeof(qstats->q_obytes));
-		memset(&qstats->q_errors, 0, sizeof(qstats->q_errors));
-		for (i = 0; i < NGBE_MAX_QP; i++) {
-			uint32_t n = i / NB_QMAP_FIELDS_PER_QSM_REG;
-			uint32_t offset = (i % NB_QMAP_FIELDS_PER_QSM_REG) * 8;
-			uint32_t q_map;
-
-			q_map = (stat_mappings->rqsm[n] >> offset)
-					& QMAP_FIELD_RESERVED_BITS_MASK;
-			j = (q_map < RTE_ETHDEV_QUEUE_STAT_CNTRS
-			     ? q_map : q_map % RTE_ETHDEV_QUEUE_STAT_CNTRS);
-			qstats->q_ipackets[j] += hw_stats->qp[i].rx_qp_packets;
-			qstats->q_ibytes[j] += hw_stats->qp[i].rx_qp_bytes;
-
-			q_map = (stat_mappings->tqsm[n] >> offset)
-					& QMAP_FIELD_RESERVED_BITS_MASK;
-			j = (q_map < RTE_ETHDEV_QUEUE_STAT_CNTRS
-			     ? q_map : q_map % RTE_ETHDEV_QUEUE_STAT_CNTRS);
-			qstats->q_opackets[j] += hw_stats->qp[i].tx_qp_packets;
-			qstats->q_obytes[j] += hw_stats->qp[i].tx_qp_bytes;
+		for (i = 0; i < NGBE_MAX_QP && i < dev->data->nb_rx_queues; i++) {
+			qstats[i].q_ipackets += hw_stats->qp[i].rx_qp_packets;
+			qstats[i].q_ibytes += hw_stats->qp[i].rx_qp_bytes;
+		}
+		for (i = 0; i < NGBE_MAX_QP && i < dev->data->nb_tx_queues; i++) {
+			qstats[i].q_opackets += hw_stats->qp[i].tx_qp_packets;
+			qstats[i].q_obytes += hw_stats->qp[i].tx_qp_bytes;
 		}
 	}
 
diff --git a/drivers/net/ngbe/ngbe_ethdev.h b/drivers/net/ngbe/ngbe_ethdev.h
index 4f8dcff00e..12ee884ce1 100644
--- a/drivers/net/ngbe/ngbe_ethdev.h
+++ b/drivers/net/ngbe/ngbe_ethdev.h
@@ -61,14 +61,6 @@ struct ngbe_interrupt {
 	uint64_t mask_orig; /* save mask during delayed handler */
 };
 
-#define NGBE_NB_STAT_MAPPING  32
-#define NB_QMAP_FIELDS_PER_QSM_REG 4
-#define QMAP_FIELD_RESERVED_BITS_MASK 0x0f
-struct ngbe_stat_mappings {
-	uint32_t tqsm[NGBE_NB_STAT_MAPPING];
-	uint32_t rqsm[NGBE_NB_STAT_MAPPING];
-};
-
 struct ngbe_vfta {
 	uint32_t vfta[NGBE_VFTA_SIZE];
 };
@@ -127,7 +119,6 @@ struct ngbe_adapter {
 	struct ngbe_hw             hw;
 	struct ngbe_hw_stats       stats;
 	struct ngbe_interrupt      intr;
-	struct ngbe_stat_mappings  stat_mappings;
 	struct ngbe_vfta           shadow_vfta;
 	struct ngbe_hwstrip        hwstrip;
 	struct ngbe_vf_info        *vfdata;
@@ -171,9 +162,6 @@ ngbe_dev_intr(struct rte_eth_dev *dev)
 	return intr;
 }
 
-#define NGBE_DEV_STAT_MAPPINGS(dev) \
-	(&((struct ngbe_adapter *)(dev)->data->dev_private)->stat_mappings)
-
 #define NGBE_DEV_VFTA(dev) \
 	(&((struct ngbe_adapter *)(dev)->data->dev_private)->shadow_vfta)
 
diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c
index bee34d20d7..effaf7cade 100644
--- a/drivers/net/ntnic/ntnic_ethdev.c
+++ b/drivers/net/ntnic/ntnic_ethdev.c
@@ -197,18 +197,18 @@ static int dpdk_stats_collect(struct pmd_internals *internals, struct rte_eth_st
 	ntnic_filter_ops->poll_statistics(internals);
 
 	for (i = 0; i < internals->nb_rx_queues; i++) {
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = internals->rxq_scg[i].rx_pkts;
-			qstats->q_ibytes[i] = internals->rxq_scg[i].rx_bytes;
+		if (qstats != NULL) {
+			qstats[i].q_ipackets = internals->rxq_scg[i].rx_pkts;
+			qstats[i].q_ibytes = internals->rxq_scg[i].rx_bytes;
 		}
 		rx_total += internals->rxq_scg[i].rx_pkts;
 		rx_total_b += internals->rxq_scg[i].rx_bytes;
 	}
 
 	for (i = 0; i < internals->nb_tx_queues; i++) {
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[i] = internals->txq_scg[i].tx_pkts;
-			qstats->q_obytes[i] = internals->txq_scg[i].tx_bytes;
+		if (qstats != NULL) {
+			qstats[i].q_opackets = internals->txq_scg[i].tx_pkts;
+			qstats[i].q_obytes = internals->txq_scg[i].tx_bytes;
 		}
 		tx_total += internals->txq_scg[i].tx_pkts;
 		tx_total_b += internals->txq_scg[i].tx_bytes;
diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
index 7fba3a661b..a469825cb6 100644
--- a/drivers/net/null/rte_eth_null.c
+++ b/drivers/net/null/rte_eth_null.c
@@ -332,9 +332,9 @@ eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		stats->ipackets += pkts;
 		stats->ibytes += bytes;
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = pkts;
-			qstats->q_ibytes[i] = bytes;
+		if (qstats != NULL && i < dev->data->nb_rx_queues) {
+			qstats[i].q_ipackets = pkts;
+			qstats[i].q_ibytes = bytes;
 		}
 	}
 
@@ -348,9 +348,9 @@ eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		stats->opackets += pkts;
 		stats->obytes += bytes;
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[i] = pkts;
-			qstats->q_obytes[i] = bytes;
+		if (qstats != NULL && i < dev->data->nb_tx_queues) {
+			qstats[i].q_opackets = pkts;
+			qstats[i].q_obytes = bytes;
 		}
 	}
 
diff --git a/drivers/net/octeon_ep/otx_ep_ethdev.c b/drivers/net/octeon_ep/otx_ep_ethdev.c
index 876d2f9d7d..85b3c09155 100644
--- a/drivers/net/octeon_ep/otx_ep_ethdev.c
+++ b/drivers/net/octeon_ep/otx_ep_ethdev.c
@@ -626,9 +626,9 @@ otx_ep_dev_stats_get(struct rte_eth_dev *eth_dev,
 
 	for (i = 0; i < otx_epvf->nb_tx_queues; i++) {
 		ostats = &otx_epvf->instr_queue[i]->stats;
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[i] = ostats->tx_pkts;
-			qstats->q_obytes[i] = ostats->tx_bytes;
+		if (qstats != NULL && i < eth_dev->data->nb_tx_queues) {
+			qstats[i].q_opackets = ostats->tx_pkts;
+			qstats[i].q_obytes = ostats->tx_bytes;
 		}
 		stats->opackets += ostats->tx_pkts;
 		stats->obytes += ostats->tx_bytes;
@@ -636,10 +636,9 @@ otx_ep_dev_stats_get(struct rte_eth_dev *eth_dev,
 	}
 	for (i = 0; i < otx_epvf->nb_rx_queues; i++) {
 		istats = &otx_epvf->droq[i]->stats;
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = istats->pkts_received;
-			qstats->q_ibytes[i] = istats->bytes_received;
-			qstats->q_errors[i] = istats->rx_err;
+		if (qstats != NULL && i < eth_dev->data->nb_rx_queues) {
+			qstats[i].q_ipackets = istats->pkts_received;
+			qstats[i].q_ibytes = istats->bytes_received;
 		}
 		stats->ipackets += istats->pkts_received;
 		stats->ibytes += istats->bytes_received;
diff --git a/drivers/net/pcap/pcap_ethdev.c b/drivers/net/pcap/pcap_ethdev.c
index 08d3ab9e91..b1f3718c8a 100644
--- a/drivers/net/pcap/pcap_ethdev.c
+++ b/drivers/net/pcap/pcap_ethdev.c
@@ -1075,11 +1075,10 @@ eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	unsigned long tx_packets_err_total = 0;
 	const struct pmd_internals *internal = dev->data->dev_private;
 
-	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&
-			i < dev->data->nb_rx_queues; i++) {
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
 		if (qstats != NULL) {
-			qstats->q_ipackets[i] = internal->rx_queue[i].rx_stat.pkts;
-			qstats->q_ibytes[i] = internal->rx_queue[i].rx_stat.bytes;
+			qstats[i].q_ipackets = internal->rx_queue[i].rx_stat.pkts;
+			qstats[i].q_ibytes = internal->rx_queue[i].rx_stat.bytes;
 		}
 		rx_nombuf_total += internal->rx_queue[i].rx_stat.rx_nombuf;
 		rx_err_total += internal->rx_queue[i].rx_stat.err_pkts;
@@ -1088,11 +1087,10 @@ eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		rx_missed_total += queue_missed_stat_get(dev, i);
 	}
 
-	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&
-			i < dev->data->nb_tx_queues; i++) {
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
 		if (qstats != NULL) {
-			qstats->q_opackets[i] = internal->tx_queue[i].tx_stat.pkts;
-			qstats->q_obytes[i] = internal->tx_queue[i].tx_stat.bytes;
+			qstats[i].q_opackets = internal->tx_queue[i].tx_stat.pkts;
+			qstats[i].q_obytes = internal->tx_queue[i].tx_stat.bytes;
 		}
 		tx_packets_total += internal->tx_queue[i].tx_stat.pkts;
 		tx_bytes_total += internal->tx_queue[i].tx_stat.bytes;
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 4efc2dd349..b5bbcd6625 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -397,10 +397,8 @@ static void qede_reset_queue_stats(struct qede_dev *qdev, bool xstats)
 
 	DP_VERBOSE(edev, ECORE_MSG_DEBUG, "Clearing queue stats\n");
 
-	rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(dev),
-			       RTE_ETHDEV_QUEUE_STAT_CNTRS);
-	txq_stat_cntrs = RTE_MIN(QEDE_TSS_COUNT(dev),
-			       RTE_ETHDEV_QUEUE_STAT_CNTRS);
+	rxq_stat_cntrs = QEDE_RSS_COUNT(dev);
+	txq_stat_cntrs = QEDE_TSS_COUNT(dev);
 
 	for (qid = 0; qid < qdev->num_rx_queues; qid++) {
 		OSAL_MEMSET(((char *)(qdev->fp_array[qid].rxq)) +
@@ -1634,20 +1632,11 @@ qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats,
 	eth_stats->oerrors = stats.common.tx_err_drop_pkts;
 
 	/* Queue stats */
-	rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(eth_dev),
-			       RTE_ETHDEV_QUEUE_STAT_CNTRS);
-	txq_stat_cntrs = RTE_MIN(QEDE_TSS_COUNT(eth_dev),
-			       RTE_ETHDEV_QUEUE_STAT_CNTRS);
-	if (rxq_stat_cntrs != (unsigned int)QEDE_RSS_COUNT(eth_dev) ||
-	    txq_stat_cntrs != (unsigned int)QEDE_TSS_COUNT(eth_dev))
-		DP_VERBOSE(edev, ECORE_MSG_DEBUG,
-		       "Not all the queue stats will be displayed. Set"
-		       " RTE_ETHDEV_QUEUE_STAT_CNTRS config param"
-		       " appropriately and retry.\n");
+	rxq_stat_cntrs = QEDE_RSS_COUNT(eth_dev);
+	txq_stat_cntrs = QEDE_TSS_COUNT(eth_dev);
 
 	for (qid = 0; qid < eth_dev->data->nb_rx_queues; qid++) {
 		uint64_t q_ipackets = 0;
-		uint64_t q_errors = 0;
 
 		for_each_hwfn(edev, hw_fn) {
 			idx = qid * edev->num_hwfns + hw_fn;
@@ -1657,21 +1646,10 @@ qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats,
 					(((char *)(qdev->fp_array[idx].rxq)) +
 					 offsetof(struct qede_rx_queue,
 					 rcv_pkts));
-			q_errors +=
-				*(uint64_t *)
-					(((char *)(qdev->fp_array[idx].rxq)) +
-					 offsetof(struct qede_rx_queue,
-					 rx_hw_errors)) +
-				*(uint64_t *)
-					(((char *)(qdev->fp_array[idx].rxq)) +
-					 offsetof(struct qede_rx_queue,
-					 rx_alloc_errors));
 		}
 
-		if (qstats != NULL) {
-			qstats->q_ipackets[i] = q_ipackets;
-			qstats->q_errors[i] = q_errors;
-		}
+		if (qstats != NULL)
+			qstats[i].q_ipackets = q_ipackets;
 
 		i++;
 		if (i == rxq_stat_cntrs)
@@ -1693,7 +1671,7 @@ qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats,
 		}
 
 		if (qstats != NULL)
-			qstats->q_opackets[j] = q_opackets;
+			qstats[j].q_opackets = q_opackets;
 
 		j++;
 		if (j == txq_stat_cntrs)
diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
index b639544eab..2ba9b66b41 100644
--- a/drivers/net/ring/rte_eth_ring.c
+++ b/drivers/net/ring/rte_eth_ring.c
@@ -203,17 +203,15 @@ eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	unsigned long rx_total = 0, tx_total = 0;
 	const struct pmd_internals *internal = dev->data->dev_private;
 
-	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&
-			i < dev->data->nb_rx_queues; i++) {
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
 		if (qstats != NULL)
-			qstats->q_ipackets[i] = internal->rx_ring_queues[i].rx_pkts;
+			qstats[i].q_ipackets = internal->rx_ring_queues[i].rx_pkts;
 		rx_total += internal->rx_ring_queues[i].rx_pkts;
 	}
 
-	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&
-			i < dev->data->nb_tx_queues; i++) {
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
 		if (qstats != NULL)
-			qstats->q_opackets[i] = internal->tx_ring_queues[i].tx_pkts;
+			qstats[i].q_opackets = internal->tx_ring_queues[i].tx_pkts;
 		tx_total += internal->tx_ring_queues[i].tx_pkts;
 	}
 
diff --git a/drivers/net/rnp/rnp_ethdev.c b/drivers/net/rnp/rnp_ethdev.c
index e48ad0e317..125134f8d4 100644
--- a/drivers/net/rnp/rnp_ethdev.c
+++ b/drivers/net/rnp/rnp_ethdev.c
@@ -1252,9 +1252,9 @@ rnp_dev_stats_get(struct rte_eth_dev *dev,
 			continue;
 		stats->ipackets += rxq->stats.ipackets;
 		stats->ibytes += rxq->stats.ibytes;
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = rxq->stats.ipackets;
-			qstats->q_ibytes[i] = rxq->stats.ibytes;
+		if (qstats != NULL && i < dev->data->nb_rx_queues) {
+			qstats[i].q_ipackets = rxq->stats.ipackets;
+			qstats[i].q_ibytes = rxq->stats.ibytes;
 		}
 	}
 
@@ -1266,9 +1266,9 @@ rnp_dev_stats_get(struct rte_eth_dev *dev,
 		stats->opackets += txq->stats.opackets;
 		stats->obytes += txq->stats.obytes;
 		stats->oerrors += txq->stats.errors;
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[i] = txq->stats.opackets;
-			qstats->q_obytes[i] = txq->stats.obytes;
+		if (qstats != NULL && i < dev->data->nb_tx_queues) {
+			qstats[i].q_opackets = txq->stats.opackets;
+			qstats[i].q_obytes = txq->stats.obytes;
 		}
 	}
 	stats->imissed = eth_stats->rx_trans_drop + eth_stats->rx_trunc_drop;
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index 050488301c..130e0fa11b 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -1577,15 +1577,11 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_
 	struct sxe2_drv_cmd_params param = {0};
 	struct sxe2_queue_map_info resp = {0};
 	struct sxe2_common_device *cdev = adapter->cdev;
+	struct rte_eth_dev_data *dev_data = adapter->dev_info.dev_data;
 	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));
@@ -1595,14 +1591,16 @@ int32_t sxe2_drv_queue_info_get_update(struct sxe2_adapter *adapter, struct eth_
 		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 (pool_idx = 0; pool_idx < SXE2_RXQ_STATS_MAP_MAX_NUM &&
+			pool_idx < dev_data->nb_rx_queues; pool_idx++) {
+		qstats[pool_idx].q_ipackets = resp.rxq_stats_map_info[pool_idx].rxq_lan_in_pkt_cnt;
+		qstats[pool_idx].q_ibytes = 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;
+	for (index = 0; index < SXE2_TXQ_STATS_MAP_MAX_NUM &&
+			index < dev_data->nb_tx_queues; index++) {
+		qstats[index].q_opackets = resp.txq_stats_map_info[index].txq_lan_pkt_cnt;
+		qstats[index].q_obytes = resp.txq_stats_map_info[index].txq_lan_byte_cnt;
 	}
 
 l_end:
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index b93452f168..3d381a47a9 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -1004,9 +1004,9 @@ tap_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *tap_stats,
 
 		if (rxq == NULL)
 			continue;
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = rxq->stats.packets;
-			qstats->q_ibytes[i] = rxq->stats.bytes;
+		if (qstats != NULL && i < dev->data->nb_rx_queues) {
+			qstats[i].q_ipackets = rxq->stats.packets;
+			qstats[i].q_ibytes = rxq->stats.bytes;
 		}
 		rx_total += rxq->stats.packets;
 		rx_bytes_total += rxq->stats.bytes;
@@ -1019,9 +1019,9 @@ tap_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *tap_stats,
 
 		if (txq == NULL)
 			continue;
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[i] = txq->stats.packets;
-			qstats->q_obytes[i] = txq->stats.bytes;
+		if (qstats != NULL && i < dev->data->nb_tx_queues) {
+			qstats[i].q_opackets = txq->stats.packets;
+			qstats[i].q_obytes = txq->stats.bytes;
 		}
 		tx_total += txq->stats.packets;
 		tx_bytes_total += txq->stats.bytes;
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index 6e34da7c3c..30d03f4db9 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -306,13 +306,13 @@ nicvf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 
 	/* Reading per RX ring stats */
 	for (qidx = rx_start; qidx <= rx_end; qidx++) {
-		if (qidx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+		if (qidx >= dev->data->nb_rx_queues)
 			break;
 
 		nicvf_hw_get_rx_qstats(nic, &rx_qstats, qidx);
 		if (qstats != NULL) {
-			qstats->q_ibytes[qidx] = rx_qstats.q_rx_bytes;
-			qstats->q_ipackets[qidx] = rx_qstats.q_rx_packets;
+			qstats[qidx].q_ibytes = rx_qstats.q_rx_bytes;
+			qstats[qidx].q_ipackets = rx_qstats.q_rx_packets;
 		}
 	}
 
@@ -321,13 +321,13 @@ nicvf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 
 	/* Reading per TX ring stats */
 	for (qidx = tx_start; qidx <= tx_end; qidx++) {
-		if (qidx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+		if (qidx >= dev->data->nb_tx_queues)
 			break;
 
 		nicvf_hw_get_tx_qstats(nic, &tx_qstats, qidx);
 		if (qstats != NULL) {
-			qstats->q_obytes[qidx] = tx_qstats.q_tx_bytes;
-			qstats->q_opackets[qidx] = tx_qstats.q_tx_packets;
+			qstats[qidx].q_obytes = tx_qstats.q_tx_bytes;
+			qstats[qidx].q_opackets = tx_qstats.q_tx_packets;
 		}
 	}
 
@@ -342,14 +342,14 @@ nicvf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 
 		/* Reading per RX ring stats */
 		for (qidx = rx_start; qidx <= rx_end; qidx++) {
-			if (qidx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+			if (qidx >= dev->data->nb_rx_queues)
 				break;
 
 			nicvf_hw_get_rx_qstats(snic, &rx_qstats,
 					       qidx % MAX_RCV_QUEUES_PER_QS);
 			if (qstats != NULL) {
-				qstats->q_ibytes[qidx] = rx_qstats.q_rx_bytes;
-				qstats->q_ipackets[qidx] = rx_qstats.q_rx_packets;
+				qstats[qidx].q_ibytes = rx_qstats.q_rx_bytes;
+				qstats[qidx].q_ipackets = rx_qstats.q_rx_packets;
 			}
 		}
 
@@ -357,14 +357,14 @@ nicvf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		nicvf_tx_range(dev, snic, &tx_start, &tx_end);
 		/* Reading per TX ring stats */
 		for (qidx = tx_start; qidx <= tx_end; qidx++) {
-			if (qidx >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
+			if (qidx >= dev->data->nb_tx_queues)
 				break;
 
 			nicvf_hw_get_tx_qstats(snic, &tx_qstats,
 					       qidx % MAX_SND_QUEUES_PER_QS);
 			if (qstats != NULL) {
-				qstats->q_obytes[qidx] = tx_qstats.q_tx_bytes;
-				qstats->q_opackets[qidx] = tx_qstats.q_tx_packets;
+				qstats[qidx].q_obytes = tx_qstats.q_tx_bytes;
+				qstats[qidx].q_opackets = tx_qstats.q_tx_packets;
 			}
 		}
 	}
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 6349aca90f..5eae613d32 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -2452,13 +2452,13 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	stats->obytes = hw_stats->tx_bytes;
 
 	if (qstats != NULL) {
-		for (i = 0; i < TXGBE_MAX_QP; i++) {
-			if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
-				break;
-			qstats->q_ipackets[i] += hw_stats->qp[i].rx_qp_packets;
-			qstats->q_ibytes[i] += hw_stats->qp[i].rx_qp_bytes;
-			qstats->q_opackets[i] += hw_stats->qp[i].tx_qp_packets;
-			qstats->q_obytes[i] += hw_stats->qp[i].tx_qp_bytes;
+		for (i = 0; i < TXGBE_MAX_QP && i < dev->data->nb_rx_queues; i++) {
+			qstats[i].q_ipackets += hw_stats->qp[i].rx_qp_packets;
+			qstats[i].q_ibytes += hw_stats->qp[i].rx_qp_bytes;
+		}
+		for (i = 0; i < TXGBE_MAX_QP && i < dev->data->nb_tx_queues; i++) {
+			qstats[i].q_opackets += hw_stats->qp[i].tx_qp_packets;
+			qstats[i].q_obytes += hw_stats->qp[i].tx_qp_bytes;
 		}
 	}
 
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 05940f2461..f2dfae7175 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -1319,27 +1319,25 @@ eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	unsigned long tx_total_errors = 0;
 	struct vhost_queue *vq;
 
-	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&
-			i < dev->data->nb_rx_queues; i++) {
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
 		if (dev->data->rx_queues[i] == NULL)
 			continue;
 		vq = dev->data->rx_queues[i];
 		if (qstats != NULL) {
-			qstats->q_ipackets[i] = vq->stats.pkts;
-			qstats->q_ibytes[i] = vq->stats.bytes;
+			qstats[i].q_ipackets = vq->stats.pkts;
+			qstats[i].q_ibytes = vq->stats.bytes;
 		}
 		rx_total += vq->stats.pkts;
 		rx_total_bytes += vq->stats.bytes;
 	}
 
-	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&
-			i < dev->data->nb_tx_queues; i++) {
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
 		if (dev->data->tx_queues[i] == NULL)
 			continue;
 		vq = dev->data->tx_queues[i];
 		if (qstats != NULL) {
-			qstats->q_opackets[i] = vq->stats.pkts;
-			qstats->q_obytes[i] = vq->stats.bytes;
+			qstats[i].q_opackets = vq->stats.pkts;
+			qstats[i].q_obytes = vq->stats.bytes;
 		}
 		tx_total += vq->stats.pkts;
 		tx_total_bytes += vq->stats.bytes;
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 0b2574bd02..a6fe4f3023 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -701,9 +701,9 @@ virtio_update_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		stats->opackets += txvq->stats.packets;
 		stats->obytes += txvq->stats.bytes;
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[i] = txvq->stats.packets;
-			qstats->q_obytes[i] = txvq->stats.bytes;
+		if (qstats != NULL && i < dev->data->nb_tx_queues) {
+			qstats[i].q_opackets = txvq->stats.packets;
+			qstats[i].q_obytes = txvq->stats.bytes;
 		}
 	}
 
@@ -716,9 +716,9 @@ virtio_update_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		stats->ibytes += rxvq->stats.bytes;
 		stats->ierrors += rxvq->stats.errors;
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = rxvq->stats.packets;
-			qstats->q_ibytes[i] = rxvq->stats.bytes;
+		if (qstats != NULL && i < dev->data->nb_rx_queues) {
+			qstats[i].q_ipackets = rxvq->stats.packets;
+			qstats[i].q_ibytes = rxvq->stats.bytes;
 		}
 	}
 
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index b7cf217724..4a7c76cfef 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -1504,9 +1504,9 @@ vmxnet3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		stats->obytes += bytes;
 		stats->oerrors += txStats.pktsTxError + txStats.pktsTxDiscard;
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[i] = packets;
-			qstats->q_obytes[i] = bytes;
+		if (qstats != NULL && i < dev->data->nb_tx_queues) {
+			qstats[i].q_opackets = packets;
+			qstats[i].q_obytes = bytes;
 		}
 	}
 
@@ -1526,10 +1526,9 @@ vmxnet3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 		stats->ierrors += rxStats.pktsRxError;
 		stats->imissed += rxStats.pktsRxOutOfBuf;
 
-		if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[i] = packets;
-			qstats->q_ibytes[i] = bytes;
-			qstats->q_errors[i] = rxStats.pktsRxError;
+		if (qstats != NULL && i < dev->data->nb_rx_queues) {
+			qstats[i].q_ipackets = packets;
+			qstats[i].q_ibytes = bytes;
 		}
 	}
 
diff --git a/drivers/net/xsc/xsc_ethdev.c b/drivers/net/xsc/xsc_ethdev.c
index 505f973d66..5fbe68782e 100644
--- a/drivers/net/xsc/xsc_ethdev.c
+++ b/drivers/net/xsc/xsc_ethdev.c
@@ -593,11 +593,9 @@ xsc_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 			continue;
 
 		idx = rxq->idx;
-		if (qstats != NULL && idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_ipackets[idx] += rxq->stats.rx_pkts;
-			qstats->q_ibytes[idx] += rxq->stats.rx_bytes;
-			qstats->q_errors[idx] += rxq->stats.rx_errors +
-						rxq->stats.rx_nombuf;
+		if (qstats != NULL && idx < dev->data->nb_rx_queues) {
+			qstats[idx].q_ipackets += rxq->stats.rx_pkts;
+			qstats[idx].q_ibytes += rxq->stats.rx_bytes;
 		}
 		stats->ipackets += rxq->stats.rx_pkts;
 		stats->ibytes += rxq->stats.rx_bytes;
@@ -611,9 +609,9 @@ xsc_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 			continue;
 
 		idx = txq->idx;
-		if (qstats != NULL && idx < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
-			qstats->q_opackets[idx] += txq->stats.tx_pkts;
-			qstats->q_obytes[idx] += txq->stats.tx_bytes;
+		if (qstats != NULL && idx < dev->data->nb_tx_queues) {
+			qstats[idx].q_opackets += txq->stats.tx_pkts;
+			qstats[idx].q_obytes += txq->stats.tx_bytes;
 		}
 		stats->opackets += txq->stats.tx_pkts;
 		stats->obytes += txq->stats.tx_bytes;
diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.c b/drivers/net/zxdh/zxdh_ethdev_ops.c
index 50247116d9..489ef76269 100644
--- a/drivers/net/zxdh/zxdh_ethdev_ops.c
+++ b/drivers/net/zxdh/zxdh_ethdev_ops.c
@@ -1824,37 +1824,29 @@ zxdh_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
 	}
 
 	stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
-	for (i = 0; (i < dev->data->nb_rx_queues) && (i < RTE_ETHDEV_QUEUE_STAT_CNTRS); i++) {
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
 		struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[i];
 
 		if (rxvq == NULL)
 			continue;
 		if (qstats != NULL) {
-			qstats->q_ipackets[i] = *(uint64_t *)(((char *)rxvq) +
+			qstats[i].q_ipackets = *(uint64_t *)(((char *)rxvq) +
 					zxdh_rxq_stat_strings[0].offset);
-			qstats->q_ibytes[i] = *(uint64_t *)(((char *)rxvq) +
+			qstats[i].q_ibytes = *(uint64_t *)(((char *)rxvq) +
 					zxdh_rxq_stat_strings[1].offset);
-			qstats->q_errors[i] = *(uint64_t *)(((char *)rxvq) +
-					zxdh_rxq_stat_strings[2].offset);
-			qstats->q_errors[i] += *(uint64_t *)(((char *)rxvq) +
-					zxdh_rxq_stat_strings[5].offset);
 		}
 	}
 
-	for (i = 0; (i < dev->data->nb_tx_queues) && (i < RTE_ETHDEV_QUEUE_STAT_CNTRS); i++) {
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
 		struct zxdh_virtnet_tx *txvq = dev->data->tx_queues[i];
 
 		if (txvq == NULL)
 			continue;
 		if (qstats != NULL) {
-			qstats->q_opackets[i] = *(uint64_t *)(((char *)txvq) +
+			qstats[i].q_opackets = *(uint64_t *)(((char *)txvq) +
 					zxdh_txq_stat_strings[0].offset);
-			qstats->q_obytes[i] = *(uint64_t *)(((char *)txvq) +
+			qstats[i].q_obytes = *(uint64_t *)(((char *)txvq) +
 					zxdh_txq_stat_strings[1].offset);
-			qstats->q_errors[i] += *(uint64_t *)(((char *)txvq) +
-					zxdh_txq_stat_strings[2].offset);
-			qstats->q_errors[i] += *(uint64_t *)(((char *)txvq) +
-					zxdh_txq_stat_strings[5].offset);
 		}
 	}
 	return 0;
@@ -2002,13 +1994,13 @@ int zxdh_dev_stats_reset(struct rte_eth_dev *dev)
 	if (hw->is_pf)
 		zxdh_hw_stats_reset(dev, ZXDH_MAC_STATS_RESET);
 	zxdh_np_stats_reset(dev);
-	for (i = 0; ((i < dev->data->nb_rx_queues) && (i < RTE_ETHDEV_QUEUE_STAT_CNTRS)); i++) {
+	for (i = 0; (i < dev->data->nb_rx_queues); i++) {
 		struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[i];
 		if (rxvq == NULL)
 			continue;
 		memset(&rxvq->stats, 0, sizeof(struct zxdh_virtnet_stats));
 	}
-	for (i = 0; ((i < dev->data->nb_tx_queues) && (i < RTE_ETHDEV_QUEUE_STAT_CNTRS)); i++) {
+	for (i = 0; (i < dev->data->nb_tx_queues); i++) {
 		struct zxdh_virtnet_tx *txvq = dev->data->tx_queues[i];
 		if (txvq == NULL)
 			continue;
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index 0477579cc3..041ba6851e 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -24,25 +24,16 @@
 extern "C" {
 #endif
 
-#define RTE_ETHDEV_QUEUE_STAT_CNTRS 16 /* max 256 */
-
 /**
  * @internal
- * Structure used to pass queue stats back to ethdev
- * for drivers which rely on ethdev to add the queue stats automatically to xstats.
+ * Per-queue counters added to xstats by ethdev.
+ * The array is allocated and zeroed by ethdev, with one entry per queue.
  */
 struct eth_queue_stats {
-	/* Queue stats are limited to max 256 queues. */
-	/** Total number of queue Rx packets. */
-	uint64_t q_ipackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-	/** Total number of queue Tx packets. */
-	uint64_t q_opackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-	/** Total number of successfully received queue bytes. */
-	uint64_t q_ibytes[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-	/** Total number of successfully transmitted queue bytes. */
-	uint64_t q_obytes[RTE_ETHDEV_QUEUE_STAT_CNTRS];
-	/** Total number of queue packets received that are dropped. */
-	uint64_t q_errors[RTE_ETHDEV_QUEUE_STAT_CNTRS];
+	uint64_t q_ipackets;	/**< Number of received packets. */
+	uint64_t q_opackets;	/**< Number of transmitted packets. */
+	uint64_t q_ibytes;	/**< Number of received bytes. */
+	uint64_t q_obytes;	/**< Number of transmitted bytes. */
 };
 
 /**
@@ -456,7 +447,11 @@ typedef int (*eth_speed_lanes_get_capability_t)(struct rte_eth_dev *dev,
  * @param stats
  *   The stats structure to be completed by the driver and returned to the user.
  * @param qstats
- *   Any queue statistics to be returned.
+ *   Any queue statistics to be returned, indexed by queue id.
+ *   The array has RTE_MAX(nb_rx_queues, nb_tx_queues) entries and is
+ *   zeroed by ethdev before the driver is called. The driver must not
+ *   write past nb_rx_queues for the Rx fields, or past nb_tx_queues
+ *   for the Tx fields.
  *   @note: This parameter can be NULL
  */
 typedef int (*eth_stats_get_t)(struct rte_eth_dev *dev,
diff --git a/lib/ethdev/ethdev_private.c b/lib/ethdev/ethdev_private.c
index 75ea3eedff..70cc6ae63c 100644
--- a/lib/ethdev/ethdev_private.c
+++ b/lib/ethdev/ethdev_private.c
@@ -510,8 +510,6 @@ eth_stats_qstats_get(uint16_t port_id, struct rte_eth_stats *stats, struct eth_q
 	}
 
 	memset(stats, 0, sizeof(*stats));
-	if (qstats != NULL)
-		memset(qstats, 0, sizeof(*qstats));
 
 	if (dev->dev_ops->stats_get == NULL)
 		return -ENOTSUP;
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index d6915a6b08..253f6c0efa 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -75,7 +75,6 @@ static const struct rte_eth_xstats_name_off eth_dev_stats_strings[] = {
 static const struct rte_eth_xstats_name_off eth_dev_rxq_stats_strings[] = {
 	{"packets", offsetof(struct eth_queue_stats, q_ipackets)},
 	{"bytes", offsetof(struct eth_queue_stats, q_ibytes)},
-	{"errors", offsetof(struct eth_queue_stats, q_errors)},
 };
 
 #define RTE_NB_RXQ_STATS RTE_DIM(eth_dev_rxq_stats_strings)
@@ -3387,8 +3386,8 @@ eth_dev_get_xstats_basic_count(struct rte_eth_dev *dev)
 	uint16_t nb_rxqs, nb_txqs;
 	int count;
 
-	nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
-	nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+	nb_rxqs = dev->data->nb_rx_queues;
+	nb_txqs = dev->data->nb_tx_queues;
 
 	count = RTE_NB_STATS;
 	if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) {
@@ -3501,7 +3500,7 @@ eth_basic_stats_get_names(struct rte_eth_dev *dev,
 	if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0)
 		return cnt_used_entries;
 
-	num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+	num_q = dev->data->nb_rx_queues;
 	for (id_queue = 0; id_queue < num_q; id_queue++) {
 		for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) {
 			unsigned int cc;
@@ -3518,7 +3517,7 @@ eth_basic_stats_get_names(struct rte_eth_dev *dev,
 		}
 
 	}
-	num_q = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+	num_q = dev->data->nb_tx_queues;
 	for (id_queue = 0; id_queue < num_q; id_queue++) {
 		for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) {
 			unsigned int cc;
@@ -3708,54 +3707,61 @@ eth_basic_stats_get(uint16_t port_id, struct rte_eth_xstat *xstats)
 {
 	struct rte_eth_dev *dev;
 	struct rte_eth_stats eth_stats;
-	struct eth_queue_stats queue_stats;
+	struct eth_queue_stats *queue_stats = NULL;
 	unsigned int count = 0, i, q;
-	uint64_t val, *stats_ptr;
-	uint16_t nb_rxqs, nb_txqs;
+	uint16_t nb_rxqs, nb_txqs, nb_q;
+	uint64_t *stats_ptr;
 	int ret;
 
-	ret = eth_stats_qstats_get(port_id, &eth_stats, &queue_stats);
-	if (ret < 0)
-		return ret;
-
 	dev = &rte_eth_devices[port_id];
 
-	nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
-	nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+	if (dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) {
+		nb_rxqs = dev->data->nb_rx_queues;
+		nb_txqs = dev->data->nb_tx_queues;
+	} else {
+		nb_rxqs = 0;
+		nb_txqs = 0;
+	}
+
+	nb_q = RTE_MAX(nb_rxqs, nb_txqs);
+	if (nb_q > 0) {
+		queue_stats = calloc(nb_q, sizeof(*queue_stats));
+		if (queue_stats == NULL)
+			return -ENOMEM;
+	}
+
+	ret = eth_stats_qstats_get(port_id, &eth_stats, queue_stats);
+	if (ret < 0)
+		goto out;
 
 	/* global stats */
 	for (i = 0; i < RTE_NB_STATS; i++) {
 		stats_ptr = RTE_PTR_ADD(&eth_stats,
 					eth_dev_stats_strings[i].offset);
-		val = *stats_ptr;
-		xstats[count++].value = val;
+		xstats[count++].value = *stats_ptr;
 	}
 
-	if ((dev->data->dev_flags & RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS) == 0)
-		return count;
-
 	/* per-rxq stats */
 	for (q = 0; q < nb_rxqs; q++) {
 		for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
-			stats_ptr = RTE_PTR_ADD(&queue_stats,
-					eth_dev_rxq_stats_strings[i].offset +
-					q * sizeof(uint64_t));
-			val = *stats_ptr;
-			xstats[count++].value = val;
+			stats_ptr = RTE_PTR_ADD(&queue_stats[q],
+					eth_dev_rxq_stats_strings[i].offset);
+			xstats[count++].value = *stats_ptr;
 		}
 	}
 
 	/* per-txq stats */
 	for (q = 0; q < nb_txqs; q++) {
 		for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
-			stats_ptr = RTE_PTR_ADD(&queue_stats,
-					eth_dev_txq_stats_strings[i].offset +
-					q * sizeof(uint64_t));
-			val = *stats_ptr;
-			xstats[count++].value = val;
+			stats_ptr = RTE_PTR_ADD(&queue_stats[q],
+					eth_dev_txq_stats_strings[i].offset);
+			xstats[count++].value = *stats_ptr;
 		}
 	}
-	return count;
+	ret = count;
+out:
+	free(queue_stats);
+	return ret;
 }
 
 static int
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 16/16] test/pmd_ring: test per-queue xstats
  2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
                     ` (14 preceding siblings ...)
  2026-08-13 17:55   ` [PATCH v3 15/16] ethdev: remove queue stats counter limit Stephen Hemminger
@ 2026-08-13 17:55   ` Stephen Hemminger
  15 siblings, 0 replies; 45+ messages in thread
From: Stephen Hemminger @ 2026-08-13 17:55 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Bruce Richardson

Add a test that per-queue xstats are reported for every configured
queue, and only for those. Uses different Rx and Tx queue counts so
that each direction is checked independently.

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

diff --git a/app/test/test_pmd_ring.c b/app/test/test_pmd_ring.c
index cb08dcf1d9..e7682906df 100644
--- a/app/test/test_pmd_ring.c
+++ b/app/test/test_pmd_ring.c
@@ -4,7 +4,10 @@
 #include "test.h"
 #include <string.h>
 
+#include <inttypes.h>
+#include <stdbool.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #include <rte_eth_ring.h>
 #include <rte_ethdev.h>
@@ -557,6 +560,147 @@ test_ethdev_configure_ports(void)
 	return TEST_SUCCESS;
 }
 
+/*
+ * Per-queue xstats are added by ethdev for all configured queues.
+ * Use a port with different Rx and Tx queue counts to check that each
+ * direction is reported independently.
+ */
+#define QSTATS_NB_RXQ 3
+#define QSTATS_NB_TXQ 5
+#define QSTATS_NB_RINGS RTE_MAX(QSTATS_NB_RXQ, QSTATS_NB_TXQ)
+
+static int
+test_queue_xstats(void)
+{
+	struct rte_ring *qrings[QSTATS_NB_RINGS] = { };
+	struct rte_eth_xstat_name *names = NULL;
+	struct rte_eth_xstat *xstats = NULL;
+	struct rte_eth_conf null_conf;
+	unsigned int i, nb_names, found;
+	char expected[RTE_ETH_XSTATS_NAME_SIZE];
+	int port = -1, nb_xstats, ret = -1;
+	uint16_t q;
+
+	for (q = 0; q < QSTATS_NB_RINGS; q++) {
+		char name[RTE_RING_NAMESIZE];
+
+		snprintf(name, sizeof(name), "RQ%u", q);
+		qrings[q] = rte_ring_create(name, RING_SIZE, SOCKET0,
+				RING_F_SP_ENQ | RING_F_SC_DEQ);
+		if (qrings[q] == NULL) {
+			printf("rte_ring_create %s failed\n", name);
+			goto out;
+		}
+	}
+
+	port = rte_eth_from_rings("net_ringq", qrings, QSTATS_NB_RXQ,
+			qrings, QSTATS_NB_TXQ, SOCKET0);
+	if (port < 0) {
+		printf("failed to create port\n");
+		goto out;
+	}
+
+	memset(&null_conf, 0, sizeof(null_conf));
+	if (rte_eth_dev_configure(port, QSTATS_NB_RXQ, QSTATS_NB_TXQ,
+			&null_conf) < 0) {
+		printf("configure failed\n");
+		goto out;
+	}
+
+	for (q = 0; q < QSTATS_NB_RXQ; q++) {
+		if (rte_eth_rx_queue_setup(port, q, RING_SIZE, SOCKET0,
+				NULL, mp) < 0) {
+			printf("Rx queue %u setup failed\n", q);
+			goto out;
+		}
+	}
+	for (q = 0; q < QSTATS_NB_TXQ; q++) {
+		if (rte_eth_tx_queue_setup(port, q, RING_SIZE, SOCKET0,
+				NULL) < 0) {
+			printf("Tx queue %u setup failed\n", q);
+			goto out;
+		}
+	}
+
+	nb_xstats = rte_eth_xstats_get_names(port, NULL, 0);
+	if (nb_xstats <= 0) {
+		printf("no xstats reported\n");
+		goto out;
+	}
+
+	names = calloc(nb_xstats, sizeof(*names));
+	xstats = calloc(nb_xstats, sizeof(*xstats));
+	if (names == NULL || xstats == NULL) {
+		printf("out of memory\n");
+		goto out;
+	}
+
+	nb_names = rte_eth_xstats_get_names(port, names, nb_xstats);
+	if (nb_names != (unsigned int)nb_xstats) {
+		printf("got %u names, expected %d\n", nb_names, nb_xstats);
+		goto out;
+	}
+
+	if (rte_eth_xstats_get(port, xstats, nb_xstats) != nb_xstats) {
+		printf("xstats count does not match names count\n");
+		goto out;
+	}
+
+	/* No traffic has passed, so every counter must still be zero. */
+	for (i = 0; i < (unsigned int)nb_xstats; i++) {
+		if (xstats[i].value != 0) {
+			printf("xstat '%s' is %"PRIu64", expected 0\n",
+					names[xstats[i].id].name, xstats[i].value);
+			goto out;
+		}
+	}
+
+	/* Every configured queue must have its counters, in both directions. */
+	for (q = 0; q < QSTATS_NB_RXQ + QSTATS_NB_TXQ; q++) {
+		bool rx = q < QSTATS_NB_RXQ;
+
+		snprintf(expected, sizeof(expected), "%s_q%u_packets",
+				rx ? "rx" : "tx", rx ? q : q - QSTATS_NB_RXQ);
+
+		for (i = 0, found = 0; i < nb_names; i++)
+			if (strcmp(names[i].name, expected) == 0)
+				found++;
+
+		if (found != 1) {
+			printf("expected one '%s', got %u\n", expected, found);
+			goto out;
+		}
+	}
+
+	/* Queues beyond the configured count must not be reported. */
+	snprintf(expected, sizeof(expected), "rx_q%u_packets", QSTATS_NB_RXQ);
+	for (i = 0; i < nb_names; i++) {
+		if (strcmp(names[i].name, expected) == 0) {
+			printf("unexpected stat '%s'\n", expected);
+			goto out;
+		}
+	}
+
+	snprintf(expected, sizeof(expected), "tx_q%u_packets", QSTATS_NB_TXQ);
+	for (i = 0; i < nb_names; i++) {
+		if (strcmp(names[i].name, expected) == 0) {
+			printf("unexpected stat '%s'\n", expected);
+			goto out;
+		}
+	}
+
+	ret = TEST_SUCCESS;
+out:
+	free(names);
+	free(xstats);
+	if (port >= 0)
+		rte_eth_dev_close(port);
+	for (q = 0; q < QSTATS_NB_RINGS; q++)
+		rte_ring_free(qrings[q]);
+
+	return ret;
+}
+
 static int
 test_get_stats_for_port(void)
 {
@@ -581,6 +725,7 @@ unit_test_suite test_pmd_ring_suite  = {
 		TEST_CASE(test_send_basic_packets),
 		TEST_CASE(test_get_stats_for_port),
 		TEST_CASE(test_stats_reset_for_port),
+		TEST_CASE(test_queue_xstats),
 		TEST_CASE(test_pmd_ring_pair_create_attach),
 		TEST_CASE(test_command_line_ring_port),
 		TEST_CASES_END()
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2026-08-13 18:05 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-30 16:09 [RFC 0/7] Complete removal of queue stats mapping Stephen Hemminger
2026-05-30 16:09 ` [RFC 1/7] net/virtio: remove unused " Stephen Hemminger
2026-05-30 16:09 ` [RFC 2/7] net/enic: remove queue_stats_mapping ethdev_op Stephen Hemminger
2026-05-30 16:09 ` [RFC 3/7] net/cnxk: remove queue stats mapping Stephen Hemminger
2026-05-30 16:09 ` [RFC 4/7] net/e1000: " Stephen Hemminger
2026-05-30 16:10 ` [RFC 5/7] net/ixgbe: " Stephen Hemminger
2026-05-30 16:10 ` [RFC 6/7] net/txgbe: " Stephen Hemminger
2026-05-30 16:10 ` [RFC 7/7] ethdev: remove support for " Stephen Hemminger
2026-06-01  1:56   ` fengchengwen
2026-06-01  8:45   ` Andrew Rybchenko
2026-07-23 20:28 ` [PATCH v2 0/9] Complete removal of " Stephen Hemminger
2026-07-23 20:28   ` [PATCH v2 1/9] net/virtio: remove unused " Stephen Hemminger
2026-07-23 20:28   ` [PATCH v2 2/9] app/testpmd: remove unused function prototype Stephen Hemminger
2026-07-23 20:28   ` [PATCH v2 3/9] net/enic: remove unneeded ops initialization Stephen Hemminger
2026-07-24  1:52     ` Hyong Youb Kim (hyonkim)
2026-07-23 20:28   ` [PATCH v2 4/9] net/cnxk: remove queue stats mapping Stephen Hemminger
2026-07-24  7:26     ` David Marchand
2026-07-24 15:20       ` Stephen Hemminger
2026-07-23 20:28   ` [PATCH v2 5/9] net/e1000: " Stephen Hemminger
2026-07-24  7:31     ` David Marchand
2026-08-13 12:26       ` Bruce Richardson
2026-07-23 20:28   ` [PATCH v2 6/9] net/ixgbe: " Stephen Hemminger
2026-07-23 20:28   ` [PATCH v2 7/9] net/txgbe: " Stephen Hemminger
2026-07-23 20:28   ` [PATCH v2 8/9] net/sxe2: " Stephen Hemminger
2026-07-23 20:28   ` [PATCH v2 9/9] ethdev: remove support for " Stephen Hemminger
2026-07-24  7:39   ` [PATCH v2 0/9] Complete removal of " David Marchand
2026-07-24  7:42   ` David Marchand
2026-07-24 15:28     ` Stephen Hemminger
2026-08-13 17:54 ` [PATCH v3 00/16] remove stats mapping an RTE_ETHDEV_QUEUE_STAT_CNTRS Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 01/16] net/virtio: remove unused queue stats mapping Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 02/16] app/testpmd: remove leftover set qmap Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 03/16] net/enic: remove unneeded ops initialization Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 04/16] net/cnxk: fix Tx drops added to Rx queue errors Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 05/16] net/cnxk: remove queue stats mapping Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 06/16] net/e1000: " Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 07/16] net/ixgbe: " Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 08/16] net/txgbe: " Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 09/16] net/sxe2: fix null dereference in stats get Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 10/16] net/sxe2: remove queue stats mapping Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 11/16] ethdev: remove support for " Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 12/16] net/mvpp2: fix out of range Tx queue stats write Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 13/16] net/ntnic: fix Tx errors reported as Rx queue errors Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 14/16] net/xsc: fix Tx errors added to " Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 15/16] ethdev: remove queue stats counter limit Stephen Hemminger
2026-08-13 17:55   ` [PATCH v3 16/16] test/pmd_ring: test per-queue xstats Stephen Hemminger

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