Add support the extend stats for flower firmware, include the stats for
each queue.

Signed-off-by: Chaoyong He <chaoyong...@corigine.com>
Reviewed-by: Long Wu <long...@corigine.com>
Reviewed-by: Peng Zhang <peng.zh...@corigine.com>
---
 .../net/nfp/flower/nfp_flower_representor.c   | 47 ++++++++++++++-
 .../net/nfp/flower/nfp_flower_representor.h   |  4 ++
 drivers/net/nfp/nfp_net_common.c              | 58 +++++++++++++++----
 3 files changed, 96 insertions(+), 13 deletions(-)

diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c 
b/drivers/net/nfp/flower/nfp_flower_representor.c
index f9001ab1f0..f1451fcca2 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.c
+++ b/drivers/net/nfp/flower/nfp_flower_representor.c
@@ -199,7 +199,7 @@ nfp_flower_repr_stats_get(struct rte_eth_dev *ethdev,
        return 0;
 }
 
-static int
+int
 nfp_flower_repr_stats_reset(struct rte_eth_dev *ethdev)
 {
        struct nfp_flower_representor *repr;
@@ -228,6 +228,8 @@ nfp_flower_repr_rx_burst(void *rx_queue,
                struct rte_mbuf **rx_pkts,
                uint16_t nb_pkts)
 {
+       uint32_t i;
+       uint32_t data_len;
        unsigned int available = 0;
        unsigned int total_dequeue;
        struct nfp_net_rxq *rxq;
@@ -255,7 +257,13 @@ nfp_flower_repr_rx_burst(void *rx_queue,
                                "received: %u, available: %u", repr->name,
                                repr->port_id, total_dequeue, available);
 
+               data_len = 0;
+               for (i = 0; i < total_dequeue; i++)
+                       data_len += rx_pkts[i]->data_len;
+
                repr->repr_stats.ipackets += total_dequeue;
+               repr->repr_stats.q_ipackets[rxq->qidx] += total_dequeue;
+               repr->repr_stats.q_ibytes[rxq->qidx] += data_len;
        }
 
        return total_dequeue;
@@ -268,6 +276,7 @@ nfp_flower_repr_tx_burst(void *tx_queue,
 {
        uint16_t i;
        uint16_t sent;
+       uint32_t data_len;
        void *pf_tx_queue;
        struct nfp_net_txq *txq;
        struct rte_eth_dev *dev;
@@ -297,7 +306,14 @@ nfp_flower_repr_tx_burst(void *tx_queue,
        if (sent != 0) {
                PMD_TX_LOG(DEBUG, "Representor Tx burst for %s, port_id: %#x 
transmitted: %hu",
                                repr->name, repr->port_id, sent);
+
+               data_len = 0;
+               for (i = 0; i < sent; i++)
+                       data_len += tx_pkts[i]->data_len;
+
                repr->repr_stats.opackets += sent;
+               repr->repr_stats.q_opackets[txq->qidx] += sent;
+               repr->repr_stats.q_obytes[txq->qidx] += data_len;
        }
 
        return sent;
@@ -356,6 +372,7 @@ nfp_flower_repr_uninit(struct rte_eth_dev *eth_dev)
        struct nfp_flower_representor *repr;
 
        repr = eth_dev->data->dev_private;
+       rte_free(repr->repr_xstats_base);
        rte_ring_free(repr->ring);
 
        if (repr->repr_type == NFP_REPR_TYPE_PHYS_PORT) {
@@ -497,6 +514,12 @@ static const struct eth_dev_ops nfp_flower_repr_dev_ops = {
 
        .flow_ops_get         = nfp_flow_ops_get,
        .mtr_ops_get          = nfp_net_mtr_ops_get,
+
+       .xstats_get             = nfp_net_xstats_get,
+       .xstats_reset           = nfp_net_xstats_reset,
+       .xstats_get_names       = nfp_net_xstats_get_names,
+       .xstats_get_by_id       = nfp_net_xstats_get_by_id,
+       .xstats_get_names_by_id = nfp_net_xstats_get_names_by_id,
 };
 
 static uint32_t
@@ -548,7 +571,8 @@ nfp_flower_pf_repr_init(struct rte_eth_dev *eth_dev,
        eth_dev->dev_ops = &nfp_flower_pf_repr_dev_ops;
        eth_dev->rx_pkt_burst = nfp_net_recv_pkts;
        eth_dev->tx_pkt_burst = nfp_flower_pf_xmit_pkts;
-       eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
+       eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR |
+                       RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
 
        eth_dev->data->representor_id = 0;
 
@@ -582,6 +606,7 @@ nfp_flower_repr_init(struct rte_eth_dev *eth_dev,
        int ret;
        uint16_t index;
        unsigned int numa_node;
+       struct nfp_net_hw_priv *hw_priv;
        char ring_name[RTE_ETH_NAME_MAX_LEN];
        struct nfp_app_fw_flower *app_fw_flower;
        struct nfp_flower_representor *repr;
@@ -593,6 +618,7 @@ nfp_flower_repr_init(struct rte_eth_dev *eth_dev,
 
        /* Memory has been allocated in the eth_dev_create() function */
        repr = eth_dev->data->dev_private;
+       hw_priv = eth_dev->process_private;
 
        /*
         * We need multiproduce rings as we can have multiple PF ports.
@@ -620,7 +646,8 @@ nfp_flower_repr_init(struct rte_eth_dev *eth_dev,
        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;
-       eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
+       eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR |
+                       RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
 
        if (repr->repr_type == NFP_REPR_TYPE_PHYS_PORT)
                eth_dev->data->representor_id = repr->vf_id;
@@ -662,6 +689,20 @@ nfp_flower_repr_init(struct rte_eth_dev *eth_dev,
                app_fw_flower->vf_reprs[index] = repr;
        }
 
+       if (repr->repr_type == NFP_REPR_TYPE_PHYS_PORT) {
+               repr->mac_stats = hw_priv->pf_dev->mac_stats_bar +
+                               (repr->nfp_idx * NFP_MAC_STATS_SIZE);
+       }
+
+       /* Allocate memory for extended statistics counters */
+       repr->repr_xstats_base = rte_zmalloc("rte_eth_xstat",
+                       sizeof(struct rte_eth_xstat) * 
nfp_net_xstats_size(eth_dev), 0);
+       if (repr->repr_xstats_base == NULL) {
+               PMD_INIT_LOG(ERR, "No memory for xstats base on device %s!", 
repr->name);
+               ret = -ENOMEM;
+               goto mac_cleanup;
+       }
+
        return 0;
 
 mac_cleanup:
diff --git a/drivers/net/nfp/flower/nfp_flower_representor.h 
b/drivers/net/nfp/flower/nfp_flower_representor.h
index d539e53b23..c068c4462c 100644
--- a/drivers/net/nfp/flower/nfp_flower_representor.h
+++ b/drivers/net/nfp/flower/nfp_flower_representor.h
@@ -20,10 +20,14 @@ struct nfp_flower_representor {
        struct rte_ring *ring;
        struct rte_eth_link link;
        struct rte_eth_stats repr_stats;
+
+       struct rte_eth_xstat *repr_xstats_base;
+       uint8_t *mac_stats;
 };
 
 int nfp_flower_repr_create(struct nfp_app_fw_flower *app_fw_flower,
                struct nfp_net_hw_priv *hw_priv);
 bool nfp_flower_repr_is_vf(struct nfp_flower_representor *repr);
+int nfp_flower_repr_stats_reset(struct rte_eth_dev *ethdev);
 
 #endif /* __NFP_FLOWER_REPRESENTOR_H__ */
diff --git a/drivers/net/nfp/nfp_net_common.c b/drivers/net/nfp/nfp_net_common.c
index 7541afa235..260920ecff 100644
--- a/drivers/net/nfp/nfp_net_common.c
+++ b/drivers/net/nfp/nfp_net_common.c
@@ -954,12 +954,23 @@ uint32_t
 nfp_net_xstats_size(const struct rte_eth_dev *dev)
 {
        uint32_t count;
+       bool vf_flag = false;
        struct nfp_net_hw *hw;
+       struct nfp_flower_representor *repr;
        const uint32_t size = RTE_DIM(nfp_net_xstats);
 
-       /* If the device is a VF, then there will be no MAC stats */
-       hw = nfp_net_get_hw(dev);
-       if (hw->mac_stats == NULL) {
+       if (rte_eth_dev_is_repr(dev)) {
+               repr = dev->data->dev_private;
+               if (repr->mac_stats == NULL)
+                       vf_flag = true;
+       } else {
+               hw = dev->data->dev_private;
+               if (hw->mac_stats == NULL)
+                       vf_flag = true;
+       }
+
+       /* If the device is a VF or VF-repr, then there will be no MAC stats */
+       if (vf_flag) {
                for (count = 0; count < size; count++) {
                        if (nfp_net_xstats[count].group == NFP_XSTAT_GROUP_MAC)
                                break;
@@ -989,14 +1000,29 @@ nfp_net_xstats_value(const struct rte_eth_dev *dev,
                bool raw)
 {
        uint64_t value;
+       uint8_t *mac_stats;
        struct nfp_net_hw *hw;
        struct nfp_xstat xstat;
+       struct rte_eth_xstat *xstats_base;
+       struct nfp_flower_representor *repr;
+
+       if (rte_eth_dev_is_repr(dev)) {
+               repr = dev->data->dev_private;
+               hw = repr->app_fw_flower->pf_hw;
+
+               mac_stats = repr->mac_stats;
+               xstats_base = repr->repr_xstats_base;
+       } else {
+               hw = dev->data->dev_private;
+
+               mac_stats = hw->mac_stats;
+               xstats_base = hw->eth_xstats_base;
+       }
 
-       hw = nfp_net_get_hw(dev);
        xstat = nfp_net_xstats[index];
 
        if (xstat.group == NFP_XSTAT_GROUP_MAC)
-               value = nn_readq(hw->mac_stats + xstat.offset);
+               value = nn_readq(mac_stats + xstat.offset);
        else
                value = nn_cfg_readq(&hw->super, xstat.offset);
 
@@ -1009,7 +1035,7 @@ nfp_net_xstats_value(const struct rte_eth_dev *dev,
         * baseline value. The result is the count of this statistic since the 
last time
         * it was "reset".
         */
-       return value - hw->eth_xstats_base[index].value;
+       return value - xstats_base[index].value;
 }
 
 /* NOTE: All callers ensure dev is always set. */
@@ -1130,17 +1156,29 @@ nfp_net_xstats_reset(struct rte_eth_dev *dev)
        uint32_t id;
        uint32_t read_size;
        struct nfp_net_hw *hw;
+       struct rte_eth_xstat *xstats_base;
+       struct nfp_flower_representor *repr;
 
-       hw = nfp_net_get_hw(dev);
        read_size = nfp_net_xstats_size(dev);
 
+       if (rte_eth_dev_is_repr(dev)) {
+               repr = dev->data->dev_private;
+               xstats_base = repr->repr_xstats_base;
+       } else {
+               hw = dev->data->dev_private;
+               xstats_base = hw->eth_xstats_base;
+       }
+
        for (id = 0; id < read_size; id++) {
-               hw->eth_xstats_base[id].id = id;
-               hw->eth_xstats_base[id].value = nfp_net_xstats_value(dev, id, 
true);
+               xstats_base[id].id = id;
+               xstats_base[id].value = nfp_net_xstats_value(dev, id, true);
        }
 
        /* Successfully reset xstats, now call function to reset basic stats. */
-       return nfp_net_stats_reset(dev);
+       if (rte_eth_dev_is_repr(dev))
+               return nfp_flower_repr_stats_reset(dev);
+       else
+               return nfp_net_stats_reset(dev);
 }
 
 void
-- 
2.39.1

Reply via email to