Add support to get stats and extended stats by reading hardware registers. Signed-off-by: Zaiyu Wang <zaiyuw...@trustnetic.com> --- doc/guides/nics/features/ngbe_vf.ini | 2 + drivers/net/ngbe/base/ngbe_vf.h | 32 +++++++ drivers/net/ngbe/ngbe_ethdev_vf.c | 138 +++++++++++++++++++++++++++ 3 files changed, 172 insertions(+)
diff --git a/doc/guides/nics/features/ngbe_vf.ini b/doc/guides/nics/features/ngbe_vf.ini index 8e66565e6a..11a9105abc 100644 --- a/doc/guides/nics/features/ngbe_vf.ini +++ b/doc/guides/nics/features/ngbe_vf.ini @@ -23,6 +23,8 @@ Inner L3 checksum = P Inner L4 checksum = P Rx descriptor status = Y Tx descriptor status = Y +Basic stats = Y +Extended stats = Y Multiprocess aware = Y Linux = Y ARMv8 = Y diff --git a/drivers/net/ngbe/base/ngbe_vf.h b/drivers/net/ngbe/base/ngbe_vf.h index 5cf225dd35..abe1655f8e 100644 --- a/drivers/net/ngbe/base/ngbe_vf.h +++ b/drivers/net/ngbe/base/ngbe_vf.h @@ -11,6 +11,38 @@ #define NGBE_VF_MAX_TX_QUEUES 1 #define NGBE_VF_MAX_RX_QUEUES 1 +struct ngbevf_hw_stats { + u64 base_vfgprc; + u64 base_vfgptc; + u64 base_vfgorc; + u64 base_vfgotc; + u64 base_vfmprc; + + u64 last_vfgprc; + u64 last_vfgptc; + u64 last_vfgorc; + u64 last_vfgotc; + u64 last_vfmprc; + u64 last_vfbprc; + u64 last_vfmptc; + u64 last_vfbptc; + + u64 vfgprc; + u64 vfgptc; + u64 vfgorc; + u64 vfgotc; + u64 vfmprc; + u64 vfbprc; + u64 vfmptc; + u64 vfbptc; + + u64 saved_reset_vfgprc; + u64 saved_reset_vfgptc; + u64 saved_reset_vfgorc; + u64 saved_reset_vfgotc; + u64 saved_reset_vfmprc; +}; + s32 ngbe_init_ops_vf(struct ngbe_hw *hw); s32 ngbe_init_hw_vf(struct ngbe_hw *hw); s32 ngbe_start_hw_vf(struct ngbe_hw *hw); diff --git a/drivers/net/ngbe/ngbe_ethdev_vf.c b/drivers/net/ngbe/ngbe_ethdev_vf.c index 01e9d5d8ee..93d801a1f3 100644 --- a/drivers/net/ngbe/ngbe_ethdev_vf.c +++ b/drivers/net/ngbe/ngbe_ethdev_vf.c @@ -22,6 +22,7 @@ static int ngbevf_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete); static void ngbevf_intr_disable(struct rte_eth_dev *dev); static void ngbevf_intr_enable(struct rte_eth_dev *dev); +static int ngbevf_dev_stats_reset(struct rte_eth_dev *dev); static int ngbevf_vlan_offload_config(struct rte_eth_dev *dev, int mask); static void ngbevf_set_vfta_all(struct rte_eth_dev *dev, bool on); static void ngbevf_configure_msix(struct rte_eth_dev *dev); @@ -65,6 +66,13 @@ static const struct rte_eth_desc_lim tx_desc_lim = { static const struct eth_dev_ops ngbevf_eth_dev_ops; +static const struct rte_ngbe_xstats_name_off rte_ngbevf_stats_strings[] = { + {"rx_multicast_packets", offsetof(struct ngbevf_hw_stats, vfmprc)}, +}; + +#define NGBEVF_NB_XSTATS (sizeof(rte_ngbevf_stats_strings) / \ + sizeof(rte_ngbevf_stats_strings[0])) + /* * Negotiate mailbox API version with the PF. * After reset API version is always set to the basic one (ngbe_mbox_api_10). @@ -180,6 +188,9 @@ eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev) /* init_mailbox_params */ hw->mbx.init_params(hw); + /* Reset the hw statistics */ + ngbevf_dev_stats_reset(eth_dev); + /* Disable the interrupts for VF */ ngbevf_intr_disable(eth_dev); @@ -298,6 +309,128 @@ static struct rte_pci_driver rte_ngbevf_pmd = { .remove = eth_ngbevf_pci_remove, }; +static int ngbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, unsigned int limit) +{ + unsigned int i; + + if (limit < NGBEVF_NB_XSTATS && xstats_names != NULL) + return -ENOMEM; + + if (xstats_names != NULL) + for (i = 0; i < NGBEVF_NB_XSTATS; i++) + snprintf(xstats_names[i].name, + sizeof(xstats_names[i].name), + "%s", rte_ngbevf_stats_strings[i].name); + return NGBEVF_NB_XSTATS; +} + +static void +ngbevf_update_stats(struct rte_eth_dev *dev) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct ngbevf_hw_stats *hw_stats = (struct ngbevf_hw_stats *) + NGBE_DEV_STATS(dev); + + /* Good Rx packet, include VF loopback */ + NGBE_UPDCNT32(NGBE_QPRXPKT(0), + hw_stats->last_vfgprc, hw_stats->vfgprc); + + /* Good Rx octets, include VF loopback */ + NGBE_UPDCNT36(NGBE_QPRXOCTL(0), + hw_stats->last_vfgorc, hw_stats->vfgorc); + + /* Rx Multicst Packet */ + NGBE_UPDCNT32(NGBE_QPRXMPKT(0), + hw_stats->last_vfmprc, hw_stats->vfmprc); + + /* Rx Broadcast Packet */ + NGBE_UPDCNT32(NGBE_QPRXBPKT(0), + hw_stats->last_vfbprc, hw_stats->vfbprc); + + hw->rx_loaded = 0; + + /* Good Tx packet, include VF loopback */ + NGBE_UPDCNT32(NGBE_QPTXPKT(0), + hw_stats->last_vfgptc, hw_stats->vfgptc); + + /* Good Tx octets, include VF loopback */ + NGBE_UPDCNT36(NGBE_QPTXOCTL(0), + hw_stats->last_vfgotc, hw_stats->vfgotc); + + /* Tx Multicst Packet */ + NGBE_UPDCNT32(NGBE_QPTXMPKT(0), + hw_stats->last_vfmprc, hw_stats->vfmprc); + + /* Tx Broadcast Packet */ + NGBE_UPDCNT32(NGBE_QPTXBPKT(0), + hw_stats->last_vfbptc, hw_stats->vfbptc); + + hw->offset_loaded = 0; +} + +static int +ngbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, + unsigned int n) +{ + struct ngbevf_hw_stats *hw_stats = (struct ngbevf_hw_stats *) + NGBE_DEV_STATS(dev); + unsigned int i; + + if (n < NGBEVF_NB_XSTATS) + return NGBEVF_NB_XSTATS; + + ngbevf_update_stats(dev); + + if (!xstats) + return 0; + + /* Extended stats */ + for (i = 0; i < NGBEVF_NB_XSTATS; i++) { + xstats[i].id = i; + xstats[i].value = *(uint64_t *)(((char *)hw_stats) + + rte_ngbevf_stats_strings[i].offset); + } + + return NGBEVF_NB_XSTATS; +} + +static int +ngbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +{ + struct ngbevf_hw_stats *hw_stats = (struct ngbevf_hw_stats *) + NGBE_DEV_STATS(dev); + + ngbevf_update_stats(dev); + + if (stats == NULL) + return -EINVAL; + + stats->ipackets = hw_stats->vfgprc; + stats->ibytes = hw_stats->vfgorc; + stats->opackets = hw_stats->vfgptc; + stats->obytes = hw_stats->vfgotc; + return 0; +} + +static int +ngbevf_dev_stats_reset(struct rte_eth_dev *dev) +{ + struct ngbevf_hw_stats *hw_stats = (struct ngbevf_hw_stats *) + NGBE_DEV_STATS(dev); + + /* Sync HW register to the last stats */ + ngbevf_dev_stats_get(dev, NULL); + + /* reset HW current stats*/ + hw_stats->vfgprc = 0; + hw_stats->vfgorc = 0; + hw_stats->vfgptc = 0; + hw_stats->vfgotc = 0; + + return 0; +} + static int ngbevf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) @@ -948,6 +1081,11 @@ ngbevf_dev_interrupt_handler(void *param) static const struct eth_dev_ops ngbevf_eth_dev_ops = { .dev_configure = ngbevf_dev_configure, .link_update = ngbevf_dev_link_update, + .stats_get = ngbevf_dev_stats_get, + .xstats_get = ngbevf_dev_xstats_get, + .stats_reset = ngbevf_dev_stats_reset, + .xstats_reset = ngbevf_dev_stats_reset, + .xstats_get_names = ngbevf_dev_xstats_get_names, .promiscuous_enable = ngbevf_dev_promiscuous_enable, .promiscuous_disable = ngbevf_dev_promiscuous_disable, .allmulticast_enable = ngbevf_dev_allmulticast_enable, -- 2.21.0.windows.1