provide extended stats ops implementations.<br /> <br />Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn> <br />---<br /> doc/guides/nics/features/zxdh.ini  |   1 +<br /> doc/guides/nics/zxdh.rst           |   1 +<br /> drivers/net/zxdh/zxdh_ethdev.c     |   3 +<br /> drivers/net/zxdh/zxdh_ethdev_ops.c | 265 ++++++++++++++++++++++++++++-<br /> drivers/net/zxdh/zxdh_ethdev_ops.h |   4 +<br /> 5 files changed, 271 insertions(+), 3 deletions(-)<br /> <br />diff --git a/doc/guides/nics/features/zxdh.ini b/doc/guides/nics/features/zxdh.ini<br />index c80b6dffbb..cad756ac6e 100644<br />--- a/doc/guides/nics/features/zxdh.ini<br />+++ b/doc/guides/nics/features/zxdh.ini<br />@@ -30,3 +30,4 @@ Inner L3 checksum    = Y<br /> Inner L4 checksum    = Y<br /> LRO                  = Y<br /> TSO                  = Y<br />+Extended stats       = Y<br />diff --git a/doc/guides/nics/zxdh.rst b/doc/guides/nics/zxdh.rst<br />index bb3ec2c293..3cf0615a7d 100644<br />--- a/doc/guides/nics/zxdh.rst<br />+++ b/doc/guides/nics/zxdh.rst<br />@@ -39,6 +39,7 @@ Features of the ZXDH PMD are:<br /> - Inner and Outer Checksum offload<br /> - Hardware LRO<br /> - Hardware TSO for generic IP or UDP tunnel, including VXLAN<br />+- Extended Statistics query<br />  <br />  <br /> Driver compilation and testing<br />diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c<br />index 19c247239c..7cab8f0192 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev.c<br />+++ b/drivers/net/zxdh/zxdh_ethdev.c<br />@@ -1369,6 +1369,9 @@ static const struct eth_dev_ops zxdh_eth_dev_ops = {<br />     .rss_hash_conf_get         = zxdh_rss_hash_conf_get,<br />     .stats_get                 = zxdh_dev_stats_get,<br />     .stats_reset             = zxdh_dev_stats_reset,<br />+    .xstats_get                 = zxdh_dev_xstats_get,<br />+    .xstats_get_names         = zxdh_dev_xstats_get_names,<br />+    .xstats_reset             = zxdh_dev_stats_reset,<br />     .mtu_set                 = zxdh_dev_mtu_set,<br /> };<br />  <br />diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.c b/drivers/net/zxdh/zxdh_ethdev_ops.c<br />index 65bd176762..7a1efa292f 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev_ops.c<br />+++ b/drivers/net/zxdh/zxdh_ethdev_ops.c<br />@@ -83,18 +83,24 @@ struct zxdh_hw_mac_bytes {<br />     uint64_t tx_good_bytes;<br /> };<br />  <br />-struct zxdh_xstats_name_off {<br />+struct rte_zxdh_xstats_name_off {<br />     char name[RTE_ETH_XSTATS_NAME_SIZE];<br />     unsigned int offset;<br /> };<br />  <br />-static const struct zxdh_xstats_name_off zxdh_rxq_stat_strings[] = {<br />+static const struct rte_zxdh_xstats_name_off zxdh_rxq_stat_strings[] = {<br />     {"good_packets",           offsetof(struct zxdh_virtnet_rx, stats.packets)},<br />     {"good_bytes",             offsetof(struct zxdh_virtnet_rx, stats.bytes)},<br />     {"errors",                 offsetof(struct zxdh_virtnet_rx, stats.errors)},<br />+    {"idle",                   offsetof(struct zxdh_virtnet_rx, stats.idle)},<br />+    {"full",                   offsetof(struct zxdh_virtnet_rx, stats.full)},<br />+    {"norefill",               offsetof(struct zxdh_virtnet_rx, stats.norefill)},<br />     {"multicast_packets",      offsetof(struct zxdh_virtnet_rx, stats.multicast)},<br />     {"broadcast_packets",      offsetof(struct zxdh_virtnet_rx, stats.broadcast)},<br />     {"truncated_err",          offsetof(struct zxdh_virtnet_rx, stats.truncated_err)},<br />+    {"offload_cfg_err",        offsetof(struct zxdh_virtnet_rx, stats.offload_cfg_err)},<br />+    {"invalid_hdr_len_err",    offsetof(struct zxdh_virtnet_rx, stats.invalid_hdr_len_err)},<br />+    {"no_segs_err",            offsetof(struct zxdh_virtnet_rx, stats.no_segs_err)},<br />     {"undersize_packets",      offsetof(struct zxdh_virtnet_rx, stats.size_bins[0])},<br />     {"size_64_packets",        offsetof(struct zxdh_virtnet_rx, stats.size_bins[1])},<br />     {"size_65_127_packets",    offsetof(struct zxdh_virtnet_rx, stats.size_bins[2])},<br />@@ -105,13 +111,18 @@ static const struct zxdh_xstats_name_off zxdh_rxq_stat_strings[] = {<br />     {"size_1519_max_packets",  offsetof(struct zxdh_virtnet_rx, stats.size_bins[7])},<br /> };<br />  <br />-static const struct zxdh_xstats_name_off zxdh_txq_stat_strings[] = {<br />+static const struct rte_zxdh_xstats_name_off zxdh_txq_stat_strings[] = {<br />     {"good_packets",           offsetof(struct zxdh_virtnet_tx, stats.packets)},<br />     {"good_bytes",             offsetof(struct zxdh_virtnet_tx, stats.bytes)},<br />     {"errors",                 offsetof(struct zxdh_virtnet_tx, stats.errors)},<br />+    {"idle",                   offsetof(struct zxdh_virtnet_tx, stats.idle)},<br />+    {"norefill",               offsetof(struct zxdh_virtnet_tx, stats.norefill)},<br />     {"multicast_packets",      offsetof(struct zxdh_virtnet_tx, stats.multicast)},<br />     {"broadcast_packets",      offsetof(struct zxdh_virtnet_tx, stats.broadcast)},<br />     {"truncated_err",          offsetof(struct zxdh_virtnet_tx, stats.truncated_err)},<br />+    {"offload_cfg_err",        offsetof(struct zxdh_virtnet_tx, stats.offload_cfg_err)},<br />+    {"invalid_hdr_len_err",    offsetof(struct zxdh_virtnet_tx, stats.invalid_hdr_len_err)},<br />+    {"no_segs_err",            offsetof(struct zxdh_virtnet_tx, stats.no_segs_err)},<br />     {"undersize_packets",      offsetof(struct zxdh_virtnet_tx, stats.size_bins[0])},<br />     {"size_64_packets",        offsetof(struct zxdh_virtnet_tx, stats.size_bins[1])},<br />     {"size_65_127_packets",    offsetof(struct zxdh_virtnet_tx, stats.size_bins[2])},<br />@@ -122,6 +133,109 @@ static const struct zxdh_xstats_name_off zxdh_txq_stat_strings[] = {<br />     {"size_1519_max_packets",  offsetof(struct zxdh_virtnet_tx, stats.size_bins[7])},<br /> };<br />  <br />+static const struct rte_zxdh_xstats_name_off zxdh_np_stat_strings[] = {<br />+    {"np_rx_unicast_pkts",     offsetof(struct zxdh_hw_np_stats, rx_unicast_pkts)},<br />+    {"np_tx_unicast_pkts",     offsetof(struct zxdh_hw_np_stats, tx_unicast_pkts)},<br />+    {"np_rx_unicast_bytes",    offsetof(struct zxdh_hw_np_stats, rx_unicast_bytes)},<br />+    {"np_tx_unicast_bytes",    offsetof(struct zxdh_hw_np_stats, tx_unicast_bytes)},<br />+    {"np_rx_multicast_pkts",   offsetof(struct zxdh_hw_np_stats, rx_multicast_pkts)},<br />+    {"np_tx_multicast_pkts",   offsetof(struct zxdh_hw_np_stats, tx_multicast_pkts)},<br />+    {"np_rx_multicast_bytes",  offsetof(struct zxdh_hw_np_stats, rx_multicast_bytes)},<br />+    {"np_tx_multicast_bytes",  offsetof(struct zxdh_hw_np_stats, tx_multicast_bytes)},<br />+    {"np_rx_broadcast_pkts",   offsetof(struct zxdh_hw_np_stats, rx_broadcast_pkts)},<br />+    {"np_tx_broadcast_pkts",   offsetof(struct zxdh_hw_np_stats, tx_broadcast_pkts)},<br />+    {"np_rx_broadcast_bytes",  offsetof(struct zxdh_hw_np_stats, rx_broadcast_bytes)},<br />+    {"np_tx_broadcast_bytes",  offsetof(struct zxdh_hw_np_stats, tx_broadcast_bytes)},<br />+    {"np_rx_mtu_drop_pkts",    offsetof(struct zxdh_hw_np_stats, rx_mtu_drop_pkts)},<br />+    {"np_tx_mtu_drop_pkts",    offsetof(struct zxdh_hw_np_stats, tx_mtu_drop_pkts)},<br />+    {"np_tx_mtu_drop_bytes",   offsetof(struct zxdh_hw_np_stats, tx_mtu_drop_bytes)},<br />+    {"np_rx_mtu_drop_bytes",   offsetof(struct zxdh_hw_np_stats, rx_mtu_drop_bytes)},<br />+    {"np_rx_plcr_drop_pkts",   offsetof(struct zxdh_hw_np_stats, rx_mtr_drop_pkts)},<br />+    {"np_rx_plcr_drop_bytes",  offsetof(struct zxdh_hw_np_stats, rx_mtr_drop_bytes)},<br />+    {"np_tx_plcr_drop_pkts",   offsetof(struct zxdh_hw_np_stats, tx_mtr_drop_pkts)},<br />+    {"np_tx_plcr_drop_bytes",  offsetof(struct zxdh_hw_np_stats, tx_mtr_drop_bytes)},<br />+};<br />+<br />+static const struct rte_zxdh_xstats_name_off zxdh_mac_stat_strings[] = {<br />+    {"mac_rx_total",           offsetof(struct zxdh_hw_mac_stats, rx_total)},<br />+    {"mac_rx_pause",           offsetof(struct zxdh_hw_mac_stats, rx_pause)},<br />+    {"mac_rx_unicast",         offsetof(struct zxdh_hw_mac_stats, rx_unicast)},<br />+    {"mac_rx_multicast",       offsetof(struct zxdh_hw_mac_stats, rx_multicast)},<br />+    {"mac_rx_broadcast",       offsetof(struct zxdh_hw_mac_stats, rx_broadcast)},<br />+    {"mac_rx_vlan",            offsetof(struct zxdh_hw_mac_stats, rx_vlan)},<br />+    {"mac_rx_size_64",         offsetof(struct zxdh_hw_mac_stats, rx_size_64)},<br />+    {"mac_rx_size_65_127",     offsetof(struct zxdh_hw_mac_stats, rx_size_65_127)},<br />+    {"mac_rx_size_128_255",    offsetof(struct zxdh_hw_mac_stats, rx_size_128_255)},<br />+    {"mac_rx_size_256_511",    offsetof(struct zxdh_hw_mac_stats, rx_size_256_511)},<br />+    {"mac_rx_size_512_1023",   offsetof(struct zxdh_hw_mac_stats, rx_size_512_1023)},<br />+    {"mac_rx_size_1024_1518",  offsetof(struct zxdh_hw_mac_stats, rx_size_1024_1518)},<br />+    {"mac_rx_size_1519_mru",   offsetof(struct zxdh_hw_mac_stats, rx_size_1519_mru)},<br />+    {"mac_rx_undersize",       offsetof(struct zxdh_hw_mac_stats, rx_undersize)},<br />+    {"mac_rx_oversize",        offsetof(struct zxdh_hw_mac_stats, rx_oversize)},<br />+    {"mac_rx_fragment",        offsetof(struct zxdh_hw_mac_stats, rx_fragment)},<br />+    {"mac_rx_jabber",          offsetof(struct zxdh_hw_mac_stats, rx_jabber)},<br />+    {"mac_rx_control",         offsetof(struct zxdh_hw_mac_stats, rx_control)},<br />+    {"mac_rx_eee",             offsetof(struct zxdh_hw_mac_stats, rx_eee)},<br />+    {"mac_rx_error",           offsetof(struct zxdh_hw_mac_stats, rx_error)},<br />+    {"mac_rx_fcs_error",       offsetof(struct zxdh_hw_mac_stats, rx_fcs_error)},<br />+    {"mac_rx_drop",            offsetof(struct zxdh_hw_mac_stats, rx_drop)},<br />+<br />+    {"mac_tx_total",           offsetof(struct zxdh_hw_mac_stats, tx_total)},<br />+    {"mac_tx_pause",           offsetof(struct zxdh_hw_mac_stats, tx_pause)},<br />+    {"mac_tx_unicast",         offsetof(struct zxdh_hw_mac_stats, tx_unicast)},<br />+    {"mac_tx_multicast",       offsetof(struct zxdh_hw_mac_stats, tx_multicast)},<br />+    {"mac_tx_broadcast",       offsetof(struct zxdh_hw_mac_stats, tx_broadcast)},<br />+    {"mac_tx_vlan",            offsetof(struct zxdh_hw_mac_stats, tx_vlan)},<br />+    {"mac_tx_size_64",         offsetof(struct zxdh_hw_mac_stats, tx_size_64)},<br />+    {"mac_tx_size_65_127",     offsetof(struct zxdh_hw_mac_stats, tx_size_65_127)},<br />+    {"mac_tx_size_128_255",    offsetof(struct zxdh_hw_mac_stats, tx_size_128_255)},<br />+    {"mac_tx_size_256_511",    offsetof(struct zxdh_hw_mac_stats, tx_size_256_511)},<br />+    {"mac_tx_size_512_1023",   offsetof(struct zxdh_hw_mac_stats, tx_size_512_1023)},<br />+    {"mac_tx_size_1024_1518",  offsetof(struct zxdh_hw_mac_stats, tx_size_1024_1518)},<br />+    {"mac_tx_size_1519_mtu",   offsetof(struct zxdh_hw_mac_stats, tx_size_1519_mtu)},<br />+    {"mac_tx_undersize",       offsetof(struct zxdh_hw_mac_stats, tx_undersize)},<br />+    {"mac_tx_oversize",        offsetof(struct zxdh_hw_mac_stats, tx_oversize)},<br />+    {"mac_tx_fragment",        offsetof(struct zxdh_hw_mac_stats, tx_fragment)},<br />+    {"mac_tx_jabber",          offsetof(struct zxdh_hw_mac_stats, tx_jabber)},<br />+    {"mac_tx_control",         offsetof(struct zxdh_hw_mac_stats, tx_control)},<br />+    {"mac_tx_eee",             offsetof(struct zxdh_hw_mac_stats, tx_eee)},<br />+    {"mac_tx_error",           offsetof(struct zxdh_hw_mac_stats, tx_error)},<br />+    {"mac_tx_fcs_error",       offsetof(struct zxdh_hw_mac_stats, tx_fcs_error)},<br />+    {"mac_tx_drop",            offsetof(struct zxdh_hw_mac_stats, tx_drop)},<br />+};<br />+<br />+static const struct rte_zxdh_xstats_name_off zxdh_mac_bytes_strings[] = {<br />+    {"mac_rx_total_bytes",      offsetof(struct zxdh_hw_mac_bytes, rx_total_bytes)},<br />+    {"mac_rx_good_bytes",       offsetof(struct zxdh_hw_mac_bytes, rx_good_bytes)},<br />+    {"mac_tx_total_bytes",      offsetof(struct zxdh_hw_mac_bytes, tx_total_bytes)},<br />+    {"mac_tx_good_bytes",       offsetof(struct zxdh_hw_mac_bytes, tx_good_bytes)},<br />+};<br />+<br />+static const struct rte_zxdh_xstats_name_off zxdh_vqm_stat_strings[] = {<br />+    {"vqm_rx_vport_packets",    offsetof(struct zxdh_hw_vqm_stats, rx_total)},<br />+    {"vqm_tx_vport_packets",    offsetof(struct zxdh_hw_vqm_stats, tx_total)},<br />+    {"vqm_rx_vport_bytes",      offsetof(struct zxdh_hw_vqm_stats, rx_bytes)},<br />+    {"vqm_tx_vport_bytes",      offsetof(struct zxdh_hw_vqm_stats, tx_bytes)},<br />+    {"vqm_rx_vport_dropped",    offsetof(struct zxdh_hw_vqm_stats, rx_drop)},<br />+};<br />+<br />+#define ZXDH_NB_RXQ_XSTATS (sizeof(zxdh_rxq_stat_strings) / \<br />+            sizeof(zxdh_rxq_stat_strings[0]))<br />+#define ZXDH_NB_TXQ_XSTATS (sizeof(zxdh_txq_stat_strings) / \<br />+            sizeof(zxdh_txq_stat_strings[0]))<br />+<br />+#define ZXDH_NP_XSTATS (sizeof(zxdh_np_stat_strings) / \<br />+            sizeof(zxdh_np_stat_strings[0]))<br />+<br />+#define ZXDH_MAC_XSTATS (sizeof(zxdh_mac_stat_strings) / \<br />+            sizeof(zxdh_mac_stat_strings[0]))<br />+<br />+#define ZXDH_MAC_BYTES (sizeof(zxdh_mac_bytes_strings) / \<br />+            sizeof(zxdh_mac_bytes_strings[0]))<br />+<br />+#define ZXDH_VQM_XSTATS (sizeof(zxdh_vqm_stat_strings) / \<br />+            sizeof(zxdh_vqm_stat_strings[0]))<br />+<br /> static int32_t zxdh_config_port_status(struct rte_eth_dev *dev, uint16_t link_status)<br /> {<br />     struct zxdh_hw *hw = dev->data->dev_private;<br />@@ -1764,3 +1878,148 @@ int zxdh_dev_mtu_set(struct rte_eth_dev *dev, uint16_t new_mtu)<br />     dev->data->mtu = new_mtu;<br />     return 0;<br /> }<br />+<br />+int32_t<br />+zxdh_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, uint32_t n)<br />+{<br />+    struct zxdh_hw *hw = dev->data->dev_private;<br />+    struct zxdh_hw_np_stats np_stats = {0};<br />+    struct zxdh_hw_mac_stats mac_stats = {0};<br />+    struct zxdh_hw_mac_bytes mac_bytes = {0};<br />+    struct zxdh_hw_vqm_stats  vqm_stats = {0};<br />+    uint32_t nstats = dev->data->nb_tx_queues * ZXDH_NB_TXQ_XSTATS +<br />+            dev->data->nb_rx_queues * ZXDH_NB_RXQ_XSTATS +<br />+            ZXDH_NP_XSTATS + ZXDH_VQM_XSTATS;<br />+    uint32_t i = 0;<br />+    uint32_t count = 0;<br />+    uint32_t t = 0;<br />+<br />+    if (hw->is_pf) {<br />+        nstats += ZXDH_MAC_XSTATS + ZXDH_MAC_BYTES;<br />+        zxdh_hw_mac_stats_get(dev, &mac_stats, &mac_bytes);<br />+    }<br />+    if (n < nstats)<br />+        return nstats;<br />+    zxdh_hw_vqm_stats_get(dev, ZXDH_VQM_DEV_STATS_GET,  &vqm_stats);<br />+    zxdh_hw_np_stats_get(dev, &np_stats);<br />+    for (i = 0; i < ZXDH_NP_XSTATS; i++) {<br />+        xstats[count].value = *(uint64_t *)(((char *)&np_stats)<br />+                         + zxdh_np_stat_strings[i].offset);<br />+        xstats[count].id = count;<br />+        count++;<br />+    }<br />+    if (hw->is_pf) {<br />+        for (i = 0; i < ZXDH_MAC_XSTATS; i++) {<br />+            xstats[count].value = *(uint64_t *)(((char *)&mac_stats)<br />+                         + zxdh_mac_stat_strings[i].offset);<br />+            xstats[count].id = count;<br />+            count++;<br />+        }<br />+        for (i = 0; i < ZXDH_MAC_BYTES; i++) {<br />+            xstats[count].value = *(uint64_t *)(((char *)&mac_bytes)<br />+                         + zxdh_mac_bytes_strings[i].offset);<br />+            xstats[count].id = count;<br />+            count++;<br />+        }<br />+    }<br />+    for (i = 0; i < ZXDH_VQM_XSTATS; i++) {<br />+        xstats[count].value = *(uint64_t *)(((char *)&vqm_stats)<br />+                         + zxdh_vqm_stat_strings[i].offset);<br />+        xstats[count].id = count;<br />+        count++;<br />+    }<br />+    for (i = 0; i < dev->data->nb_rx_queues; i++) {<br />+        struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[i];<br />+<br />+        if (rxvq == NULL)<br />+            continue;<br />+        for (t = 0; t < ZXDH_NB_RXQ_XSTATS; t++) {<br />+            xstats[count].value = *(uint64_t *)(((char *)rxvq)<br />+                         + zxdh_rxq_stat_strings[t].offset);<br />+            xstats[count].id = count;<br />+            count++;<br />+        }<br />+    }<br />+    for (i = 0; i < dev->data->nb_tx_queues; i++) {<br />+        struct zxdh_virtnet_tx *txvq = dev->data->tx_queues[i];<br />+<br />+        if (txvq == NULL)<br />+            continue;<br />+<br />+        for (t = 0; t < ZXDH_NB_TXQ_XSTATS; t++) {<br />+            xstats[count].value = *(uint64_t *)(((char *)txvq)<br />+                         + zxdh_txq_stat_strings[t].offset);<br />+            xstats[count].id = count;<br />+            count++;<br />+        }<br />+    }<br />+    return count;<br />+}<br />+<br />+<br />+int32_t<br />+zxdh_dev_xstats_get_names(struct rte_eth_dev *dev,<br />+                struct rte_eth_xstat_name *xstats_names,<br />+                __rte_unused unsigned int limit)<br />+{<br />+    uint32_t i       = 0;<br />+    uint32_t count = 0;<br />+    uint32_t t       = 0;<br />+    struct zxdh_hw *hw = dev->data->dev_private;<br />+    unsigned int nstats = dev->data->nb_tx_queues * ZXDH_NB_TXQ_XSTATS +<br />+                    dev->data->nb_rx_queues * ZXDH_NB_RXQ_XSTATS +<br />+                    ZXDH_NP_XSTATS + ZXDH_VQM_XSTATS;<br />+<br />+    if (hw->is_pf)<br />+        nstats += ZXDH_MAC_XSTATS + ZXDH_MAC_BYTES;<br />+<br />+    if (xstats_names != NULL) {<br />+        for (i = 0; i < ZXDH_NP_XSTATS; i++) {<br />+            snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),<br />+            "%s", zxdh_np_stat_strings[i].name);<br />+            count++;<br />+        }<br />+        if (hw->is_pf) {<br />+            for (i = 0; i < ZXDH_MAC_XSTATS; i++) {<br />+                snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),<br />+                "%s", zxdh_mac_stat_strings[i].name);<br />+                count++;<br />+            }<br />+            for (i = 0; i < ZXDH_MAC_BYTES; i++) {<br />+                snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),<br />+                "%s", zxdh_mac_bytes_strings[i].name);<br />+                count++;<br />+            }<br />+        }<br />+        for (i = 0; i < ZXDH_VQM_XSTATS; i++) {<br />+            snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),<br />+            "%s", zxdh_vqm_stat_strings[i].name);<br />+            count++;<br />+        }<br />+        for (i = 0; i < dev->data->nb_rx_queues; i++) {<br />+            struct virtnet_rx *rxvq = dev->data->rx_queues[i];<br />+<br />+            if (rxvq == NULL)<br />+                continue;<br />+            for (t = 0; t < ZXDH_NB_RXQ_XSTATS; t++) {<br />+                snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),<br />+                "rx_q%u_%s", i, zxdh_rxq_stat_strings[t].name);<br />+                count++;<br />+            }<br />+        }<br />+<br />+        for (i = 0; i < dev->data->nb_tx_queues; i++) {<br />+            struct virtnet_tx *txvq = dev->data->tx_queues[i];<br />+<br />+            if (txvq == NULL)<br />+                continue;<br />+            for (t = 0; t < ZXDH_NB_TXQ_XSTATS; t++) {<br />+                snprintf(xstats_names[count].name, sizeof(xstats_names[count].name),<br />+                "tx_q%u_%s", i, zxdh_txq_stat_strings[t].name);<br />+                count++;<br />+            }<br />+        }<br />+        return count;<br />+    }<br />+    return nstats;<br />+}<br />diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.h b/drivers/net/zxdh/zxdh_ethdev_ops.h<br />index 9ab323fde1..37d0299f23 100644<br />--- a/drivers/net/zxdh/zxdh_ethdev_ops.h<br />+++ b/drivers/net/zxdh/zxdh_ethdev_ops.h<br />@@ -99,5 +99,9 @@ int zxdh_dev_stats_reset(struct rte_eth_dev *dev);<br /> int zxdh_dev_mtu_set(struct rte_eth_dev *dev, uint16_t new_mtu);<br /> int zxdh_hw_np_stats_pf_reset(struct rte_eth_dev *dev, uint32_t stats_id);<br /> void zxdh_data_hi_to_lo(uint64_t *data);<br />+int32_t zxdh_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, uint32_t n);<br />+int32_t zxdh_dev_xstats_get_names(struct rte_eth_dev *dev,<br />+            struct rte_eth_xstat_name *xstats_names,<br />+            __rte_unused unsigned int limit);<br />  <br /> #endif /* ZXDH_ETHDEV_OPS_H */<br />--  <br />2.27.0<br />