* [PATCH] net/bnxt: allow get stats when port is stopped
@ 2026-03-02 19:51 Mohammad Shuab Siddique
2026-03-11 18:37 ` Thomas Monjalon
0 siblings, 1 reply; 2+ messages in thread
From: Mohammad Shuab Siddique @ 2026-03-02 19:51 UTC (permalink / raw)
To: dev; +Cc: kishore.padmanabha, Ajit Khaparde, stable,
Mohammad Shuab Siddique
From: Ajit Khaparde <ajit.khaparde@broadcom.com>
Currently the driver returns an error if stats are requested
when the port is stopped.
But some applications may need to get the port stats even if
the port is stopped.
Allow the get stats command to show the existing stats
if the port is stopped.
When the port is started the driver will get the stats from
the firmware.
Cc: stable@dpdk.org
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: Mohammad Shuab Siddique <mohammad-shuab.siddique@broadcom.com>
---
drivers/net/bnxt/bnxt_ethdev.c | 47 ++++++++++-------
drivers/net/bnxt/bnxt_hwrm.c | 94 +++++++++++++++++++++++++++++++---
drivers/net/bnxt/bnxt_stats.c | 3 --
3 files changed, 114 insertions(+), 30 deletions(-)
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 3c618c6e82..6601ddf575 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -786,7 +786,7 @@ static int bnxt_update_phy_setting(struct bnxt *bp)
return rc;
}
-static void bnxt_free_prev_ring_stats(struct bnxt *bp)
+static void bnxt_free_prev_ring_stats_ext(struct bnxt *bp)
{
/* tpa v2 devices use ext variant local struct */
if (BNXT_TPA_V2_P7(bp)) {
@@ -796,6 +796,10 @@ static void bnxt_free_prev_ring_stats(struct bnxt *bp)
bp->prev_tx_ring_stats_ext = NULL;
return;
}
+}
+
+static void bnxt_free_prev_ring_stats(struct bnxt *bp)
+{
rte_free(bp->prev_rx_ring_stats);
rte_free(bp->prev_tx_ring_stats);
bp->prev_rx_ring_stats = NULL;
@@ -804,17 +808,19 @@ static void bnxt_free_prev_ring_stats(struct bnxt *bp)
static int bnxt_alloc_prev_ring_ext_stats(struct bnxt *bp)
{
- bp->prev_rx_ring_stats_ext = rte_zmalloc("bnxt_prev_rx_ring_stats_ext",
- sizeof(struct bnxt_ring_stats_ext) *
- bp->rx_cp_nr_rings,
- 0);
+ if (bp->prev_rx_ring_stats_ext == NULL)
+ bp->prev_rx_ring_stats_ext = rte_zmalloc("bnxt_prev_rx_ring_stats_ext",
+ sizeof(struct bnxt_ring_stats_ext) *
+ bp->rx_cp_nr_rings,
+ 0);
if (bp->prev_rx_ring_stats_ext == NULL)
return -ENOMEM;
- bp->prev_tx_ring_stats_ext = rte_zmalloc("bnxt_prev_tx_ring_stats_ext",
- sizeof(struct bnxt_ring_stats_ext) *
- bp->tx_cp_nr_rings,
- 0);
+ if (bp->prev_tx_ring_stats_ext == NULL)
+ bp->prev_tx_ring_stats_ext = rte_zmalloc("bnxt_prev_tx_ring_stats_ext",
+ sizeof(struct bnxt_ring_stats_ext) *
+ bp->tx_cp_nr_rings,
+ 0);
if (bp->tx_cp_nr_rings > 0 && bp->prev_tx_ring_stats_ext == NULL)
goto error;
@@ -831,24 +837,26 @@ static int bnxt_alloc_prev_ring_stats(struct bnxt *bp)
if (BNXT_TPA_V2_P7(bp))
return bnxt_alloc_prev_ring_ext_stats(bp);
- bp->prev_rx_ring_stats = rte_zmalloc("bnxt_prev_rx_ring_stats",
- sizeof(struct bnxt_ring_stats) *
- bp->rx_cp_nr_rings,
- 0);
+ if (bp->prev_rx_ring_stats == NULL)
+ bp->prev_rx_ring_stats = rte_zmalloc("bnxt_prev_rx_ring_stats",
+ sizeof(struct bnxt_ring_stats) *
+ bp->rx_cp_nr_rings,
+ 0);
if (bp->prev_rx_ring_stats == NULL)
return -ENOMEM;
- bp->prev_tx_ring_stats = rte_zmalloc("bnxt_prev_tx_ring_stats",
- sizeof(struct bnxt_ring_stats) *
- bp->tx_cp_nr_rings,
- 0);
+ if (bp->prev_tx_ring_stats == NULL)
+ bp->prev_tx_ring_stats = rte_zmalloc("bnxt_prev_tx_ring_stats",
+ sizeof(struct bnxt_ring_stats) *
+ bp->tx_cp_nr_rings,
+ 0);
if (bp->tx_cp_nr_rings > 0 && bp->prev_tx_ring_stats == NULL)
goto error;
return 0;
error:
- bnxt_free_prev_ring_stats(bp);
+ bnxt_free_prev_ring_stats_ext(bp);
return -ENOMEM;
}
@@ -1758,7 +1766,6 @@ static int bnxt_dev_stop(struct rte_eth_dev *eth_dev)
bnxt_shutdown_nic(bp);
bnxt_hwrm_if_change(bp, false);
- bnxt_free_prev_ring_stats(bp);
rte_free(bp->mark_table);
bp->mark_table = NULL;
@@ -1966,6 +1973,8 @@ static int bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
if (eth_dev->data->dev_started)
ret = bnxt_dev_stop(eth_dev);
+ bnxt_free_prev_ring_stats_ext(bp);
+ bnxt_free_prev_ring_stats(bp);
bnxt_uninit_resources(bp, false);
bnxt_drv_uninit(bp);
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 0cef22b5ec..ac5cbbae0c 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -5356,13 +5356,54 @@ static void bnxt_update_prev_stat(uint64_t *cntr, uint64_t *prev_cntr)
*prev_cntr = *cntr;
}
+static void bnxt_get_prev_tx_stats(struct bnxt_ring_stats *ring_stats,
+ struct bnxt_ring_stats *prev_stats)
+{
+ ring_stats->tx_ucast_pkts = prev_stats->tx_ucast_pkts;
+ ring_stats->tx_mcast_pkts = prev_stats->tx_mcast_pkts;
+ ring_stats->tx_bcast_pkts = prev_stats->tx_bcast_pkts;
+ ring_stats->tx_ucast_bytes = prev_stats->tx_ucast_bytes;
+ ring_stats->tx_mcast_bytes = prev_stats->tx_mcast_bytes;
+ ring_stats->tx_bcast_bytes = prev_stats->tx_bcast_bytes;
+ ring_stats->tx_discard_pkts = prev_stats->tx_discard_pkts;
+}
+
+static void bnxt_get_prev_rx_stats(struct bnxt_ring_stats *ring_stats,
+ struct bnxt_ring_stats *prev_stats)
+{
+ ring_stats->rx_ucast_pkts = prev_stats->rx_ucast_pkts;
+ ring_stats->rx_mcast_pkts = prev_stats->rx_mcast_pkts;
+ ring_stats->rx_bcast_pkts = prev_stats->rx_bcast_pkts;
+ ring_stats->rx_ucast_bytes = prev_stats->rx_ucast_bytes;
+ ring_stats->rx_mcast_bytes = prev_stats->rx_mcast_bytes;
+ ring_stats->rx_bcast_bytes = prev_stats->rx_bcast_bytes;
+ ring_stats->rx_discard_pkts = prev_stats->rx_discard_pkts;
+ ring_stats->rx_error_pkts = prev_stats->rx_error_pkts;
+ ring_stats->rx_agg_pkts = prev_stats->rx_agg_pkts;
+ ring_stats->rx_agg_bytes = prev_stats->rx_agg_bytes;
+ ring_stats->rx_agg_events = prev_stats->rx_agg_events;
+ ring_stats->rx_agg_aborts = prev_stats->rx_agg_aborts;
+}
+
int bnxt_hwrm_ring_stats(struct bnxt *bp, uint32_t cid, int idx,
struct bnxt_ring_stats *ring_stats, bool rx)
{
int rc = 0;
struct hwrm_stat_ctx_query_input req = {.req_type = 0};
struct hwrm_stat_ctx_query_output *resp = bp->hwrm_cmd_resp_addr;
+ struct bnxt_ring_stats *prev_stats = &bp->prev_rx_ring_stats[idx];
+ if (!rx)
+ prev_stats = &bp->prev_tx_ring_stats[idx];
+
+ if (!bp->eth_dev->data->dev_started) {
+ if (rx)
+ bnxt_get_prev_rx_stats(ring_stats, prev_stats);
+ else
+ bnxt_get_prev_tx_stats(ring_stats, prev_stats);
+
+ return 0;
+ }
HWRM_PREP(&req, HWRM_STAT_CTX_QUERY, BNXT_USE_CHIMP_MB);
req.stat_ctx_id = rte_cpu_to_le_32(cid);
@@ -5372,8 +5413,6 @@ int bnxt_hwrm_ring_stats(struct bnxt *bp, uint32_t cid, int idx,
HWRM_CHECK_RESULT();
if (rx) {
- struct bnxt_ring_stats *prev_stats = &bp->prev_rx_ring_stats[idx];
-
ring_stats->rx_ucast_pkts = rte_le_to_cpu_64(resp->rx_ucast_pkts);
bnxt_update_prev_stat(&ring_stats->rx_ucast_pkts,
&prev_stats->rx_ucast_pkts);
@@ -5422,8 +5461,6 @@ int bnxt_hwrm_ring_stats(struct bnxt *bp, uint32_t cid, int idx,
bnxt_update_prev_stat(&ring_stats->rx_agg_aborts,
&prev_stats->rx_agg_aborts);
} else {
- struct bnxt_ring_stats *prev_stats = &bp->prev_tx_ring_stats[idx];
-
ring_stats->tx_ucast_pkts = rte_le_to_cpu_64(resp->tx_ucast_pkts);
bnxt_update_prev_stat(&ring_stats->tx_ucast_pkts,
&prev_stats->tx_ucast_pkts);
@@ -5458,6 +5495,38 @@ int bnxt_hwrm_ring_stats(struct bnxt *bp, uint32_t cid, int idx,
return rc;
}
+static void bnxt_get_prev_rx_stats_ext(struct bnxt_ring_stats_ext *ring_stats,
+ struct bnxt_ring_stats_ext *prev_stats)
+{
+ ring_stats->rx_ucast_pkts = prev_stats->rx_ucast_pkts;
+ ring_stats->rx_mcast_pkts = prev_stats->rx_mcast_pkts;
+ ring_stats->rx_bcast_pkts = prev_stats->rx_bcast_pkts;
+ ring_stats->rx_ucast_bytes = prev_stats->rx_ucast_bytes;
+ ring_stats->rx_mcast_bytes = prev_stats->rx_mcast_bytes;
+ ring_stats->rx_bcast_bytes = prev_stats->rx_bcast_bytes;
+ ring_stats->rx_discard_pkts = prev_stats->rx_discard_pkts;
+ ring_stats->rx_error_pkts = prev_stats->rx_error_pkts;
+ ring_stats->rx_tpa_eligible_pkt = prev_stats->rx_tpa_eligible_pkt;
+ ring_stats->rx_tpa_eligible_bytes = prev_stats->rx_tpa_eligible_bytes;
+ ring_stats->rx_tpa_pkt = prev_stats->rx_tpa_pkt;
+ ring_stats->rx_tpa_bytes = prev_stats->rx_tpa_bytes;
+ ring_stats->rx_tpa_errors = prev_stats->rx_tpa_errors;
+ ring_stats->rx_tpa_events = prev_stats->rx_tpa_events;
+}
+
+static void bnxt_get_prev_tx_stats_ext(struct bnxt_ring_stats_ext *ring_stats,
+ struct bnxt_ring_stats_ext *prev_stats)
+{
+ ring_stats->tx_ucast_pkts = prev_stats->tx_ucast_pkts;
+ ring_stats->tx_mcast_pkts = prev_stats->tx_mcast_pkts;
+ ring_stats->tx_bcast_pkts = prev_stats->tx_bcast_pkts;
+ ring_stats->tx_ucast_bytes = prev_stats->tx_ucast_bytes;
+ ring_stats->tx_mcast_bytes = prev_stats->tx_mcast_bytes;
+ ring_stats->tx_bcast_bytes = prev_stats->tx_bcast_bytes;
+ ring_stats->tx_discard_pkts = prev_stats->tx_discard_pkts;
+ ring_stats->tx_error_pkts = prev_stats->tx_error_pkts;
+}
+
int bnxt_hwrm_ring_stats_ext(struct bnxt *bp, uint32_t cid, int idx,
struct bnxt_ring_stats_ext *ring_stats, bool rx)
{
@@ -5465,6 +5534,19 @@ int bnxt_hwrm_ring_stats_ext(struct bnxt *bp, uint32_t cid, int idx,
struct hwrm_stat_ext_ctx_query_input req = {.req_type = 0};
struct hwrm_stat_ext_ctx_query_output *resp = bp->hwrm_cmd_resp_addr;
+ struct bnxt_ring_stats_ext *prev_stats = &bp->prev_rx_ring_stats_ext[idx];
+
+ if (!rx)
+ prev_stats = &bp->prev_tx_ring_stats_ext[idx];
+
+ if (!bp->eth_dev->data->dev_started) {
+ if (rx)
+ bnxt_get_prev_rx_stats_ext(ring_stats, prev_stats);
+ else
+ bnxt_get_prev_tx_stats_ext(ring_stats, prev_stats);
+
+ return 0;
+ }
HWRM_PREP(&req, HWRM_STAT_EXT_CTX_QUERY, BNXT_USE_CHIMP_MB);
req.stat_ctx_id = rte_cpu_to_le_32(cid);
@@ -5473,8 +5555,6 @@ int bnxt_hwrm_ring_stats_ext(struct bnxt *bp, uint32_t cid, int idx,
HWRM_CHECK_RESULT();
if (rx) {
- struct bnxt_ring_stats_ext *prev_stats = &bp->prev_rx_ring_stats_ext[idx];
-
ring_stats->rx_ucast_pkts = rte_le_to_cpu_64(resp->rx_ucast_pkts);
bnxt_update_prev_stat(&ring_stats->rx_ucast_pkts,
&prev_stats->rx_ucast_pkts);
@@ -5531,8 +5611,6 @@ int bnxt_hwrm_ring_stats_ext(struct bnxt *bp, uint32_t cid, int idx,
bnxt_update_prev_stat(&ring_stats->rx_tpa_events,
&prev_stats->rx_tpa_events);
} else {
- struct bnxt_ring_stats_ext *prev_stats = &bp->prev_tx_ring_stats_ext[idx];
-
ring_stats->tx_ucast_pkts = rte_le_to_cpu_64(resp->tx_ucast_pkts);
bnxt_update_prev_stat(&ring_stats->tx_ucast_pkts,
&prev_stats->tx_ucast_pkts);
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index 88cfbaf9ff..7b96cf0df9 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -717,9 +717,6 @@ int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
if (rc)
return rc;
- if (!eth_dev->data->dev_started)
- return -EIO;
-
if (BNXT_TPA_V2_P7(bp))
return bnxt_stats_get_ext(eth_dev, bnxt_stats, qstats);
--
2.47.3
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] net/bnxt: allow get stats when port is stopped
2026-03-02 19:51 [PATCH] net/bnxt: allow get stats when port is stopped Mohammad Shuab Siddique
@ 2026-03-11 18:37 ` Thomas Monjalon
0 siblings, 0 replies; 2+ messages in thread
From: Thomas Monjalon @ 2026-03-11 18:37 UTC (permalink / raw)
To: Mohammad Shuab Siddique; +Cc: dev, kishore.padmanabha, Ajit Khaparde
02/03/2026 20:51, Mohammad Shuab Siddique:
> From: Ajit Khaparde <ajit.khaparde@broadcom.com>
>
> Currently the driver returns an error if stats are requested
> when the port is stopped.
> But some applications may need to get the port stats even if
> the port is stopped.
> Allow the get stats command to show the existing stats
> if the port is stopped.
> When the port is started the driver will get the stats from
> the firmware.
>
> Cc: stable@dpdk.org
>
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
> Signed-off-by: Mohammad Shuab Siddique <mohammad-shuab.siddique@broadcom.com>
Applied, thanks.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-03-11 18:37 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-02 19:51 [PATCH] net/bnxt: allow get stats when port is stopped Mohammad Shuab Siddique
2026-03-11 18:37 ` Thomas Monjalon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox