From: Ajit Khaparde <[email protected]>

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: [email protected]

Signed-off-by: Ajit Khaparde <[email protected]>
Signed-off-by: Mohammad Shuab Siddique <[email protected]>
---
 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

Reply via email to