optimize basic stats ops.

Signed-off-by: Junlong Wang <wang.junlong1@zte.com.cn>
---
 drivers/net/zxdh/zxdh_ethdev.c     |   1 +
 drivers/net/zxdh/zxdh_ethdev.h     |   4 +-
 drivers/net/zxdh/zxdh_ethdev_ops.c | 241 +++++++++++++++++++++++---
 drivers/net/zxdh/zxdh_ethdev_ops.h |  43 +++--
 drivers/net/zxdh/zxdh_msg.c        | 143 ++++++++++++++++
 drivers/net/zxdh/zxdh_msg.h        |   6 +
 drivers/net/zxdh/zxdh_np.c         | 263 +++++++++++++++++++++++++++++
 drivers/net/zxdh/zxdh_np.h         |  40 +++++
 drivers/net/zxdh/zxdh_tables.h     |  16 +-
 9 files changed, 713 insertions(+), 44 deletions(-)

diff --git a/drivers/net/zxdh/zxdh_ethdev.c b/drivers/net/zxdh/zxdh_ethdev.c
index 9393712a31..0ae3ab0f81 100644
--- a/drivers/net/zxdh/zxdh_ethdev.c
+++ b/drivers/net/zxdh/zxdh_ethdev.c
@@ -1433,6 +1433,7 @@ static int zxdh_init_dev_share_data(struct rte_eth_dev *eth_dev)
         return -EINVAL;
 
     hw->slot_id = slot_id;
+    hw->dev_id = (hw->pcie_id << 16) | (hw->slot_id & 0xffff);
     g_dev_sd[slot_id].serial_id = serial_id;
     hw->dev_sd = &g_dev_sd[slot_id];
 
diff --git a/drivers/net/zxdh/zxdh_ethdev.h b/drivers/net/zxdh/zxdh_ethdev.h
index deebf075cc..87c3b5f022 100644
--- a/drivers/net/zxdh/zxdh_ethdev.h
+++ b/drivers/net/zxdh/zxdh_ethdev.h
@@ -126,13 +126,13 @@ struct zxdh_hw {
     uint8_t rss_enable;
     uint8_t rss_init;
     uint16_t slot_id;
-
     uint8_t que_set_flag;
+
+    uint32_t dev_id;
     uint16_t queue_pool_count;
     uint16_t queue_pool_start;
     struct zxdh_vlan_offload_cfg vlan_offload_cfg;
     uint8_t dl_net_hdr_len;
-    uint8_t rsv[2];
 };
 
 struct zxdh_dtb_shared_data {
diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.c b/drivers/net/zxdh/zxdh_ethdev_ops.c
index 83b77571d7..3b888bdaca 100644
--- a/drivers/net/zxdh/zxdh_ethdev_ops.c
+++ b/drivers/net/zxdh/zxdh_ethdev_ops.c
@@ -83,11 +83,6 @@ struct zxdh_hw_mac_bytes {
     uint64_t tx_good_bytes;
 };
 
-struct zxdh_np_stats_data {
-    uint64_t n_pkts_dropped;
-    uint64_t n_bytes_dropped;
-};
-
 struct zxdh_xstats_name_off {
     char name[RTE_ETH_XSTATS_NAME_SIZE];
     unsigned int offset;
@@ -1305,9 +1300,10 @@ zxdh_hw_vqm_stats_get(struct rte_eth_dev *dev, enum zxdh_agent_msg_type opcode,
     return 0;
 }
 
-static int zxdh_hw_mac_stats_get(struct rte_eth_dev *dev,
-                struct zxdh_hw_mac_stats *mac_stats,
-                struct zxdh_hw_mac_bytes *mac_bytes)
+static int
+zxdh_hw_mac_stats_get(struct rte_eth_dev *dev,
+        struct zxdh_hw_mac_stats *mac_stats,
+        struct zxdh_hw_mac_bytes *mac_bytes)
 {
     struct zxdh_hw *hw = dev->data->dev_private;
     uint64_t virt_addr = (uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX] + ZXDH_MAC_OFFSET);
@@ -1327,7 +1323,8 @@ static int zxdh_hw_mac_stats_get(struct rte_eth_dev *dev,
     return 0;
 }
 
-static void zxdh_data_hi_to_lo(uint64_t *data)
+void
+zxdh_data_hi_to_lo(uint64_t *data)
 {
     uint32_t n_data_hi;
     uint32_t n_data_lo;
@@ -1338,7 +1335,8 @@ static void zxdh_data_hi_to_lo(uint64_t *data)
                 rte_le_to_cpu_32(n_data_lo);
 }
 
-static int zxdh_np_stats_get(struct rte_eth_dev *dev, struct zxdh_hw_np_stats *np_stats)
+static int
+zxdh_np_stats_get(struct rte_eth_dev *dev, struct zxdh_hw_np_stats *np_stats)
 {
     struct zxdh_hw *hw = dev->data->dev_private;
     struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
@@ -1348,19 +1346,70 @@ static int zxdh_np_stats_get(struct rte_eth_dev *dev, struct zxdh_hw_np_stats *n
     int ret = 0;
 
     idx = stats_id + ZXDH_BROAD_STATS_EGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
     ret = zxdh_np_dtb_stats_get(hw->slot_id, dtb_data->queueid,
-                0, idx, (uint32_t *)&np_stats->np_tx_broadcast);
+                0, idx, (uint32_t *)&stats_data);
     if (ret)
         return ret;
-    zxdh_data_hi_to_lo(&np_stats->np_tx_broadcast);
+    np_stats->tx_broadcast_pkts = stats_data.n_pkts_dropped;
+    np_stats->tx_broadcast_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&np_stats->tx_broadcast_pkts);
+    zxdh_data_hi_to_lo(&np_stats->tx_broadcast_bytes);
 
     idx = stats_id + ZXDH_BROAD_STATS_INGRESS_BASE;
     memset(&stats_data, 0, sizeof(stats_data));
     ret = zxdh_np_dtb_stats_get(hw->slot_id, dtb_data->queueid,
-                0, idx, (uint32_t *)&np_stats->np_rx_broadcast);
+                0, idx, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+    np_stats->rx_broadcast_pkts = stats_data.n_pkts_dropped;
+    np_stats->rx_broadcast_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&np_stats->rx_broadcast_pkts);
+    zxdh_data_hi_to_lo(&np_stats->rx_broadcast_bytes);
+
+    idx = stats_id + ZXDH_MULTICAST_STATS_EGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(hw->slot_id, dtb_data->queueid,
+                0, idx, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+    np_stats->tx_multicast_pkts = stats_data.n_pkts_dropped;
+    np_stats->tx_multicast_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&np_stats->tx_multicast_pkts);
+    zxdh_data_hi_to_lo(&np_stats->tx_multicast_bytes);
+
+    idx = stats_id + ZXDH_MULTICAST_STATS_INGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(hw->slot_id, dtb_data->queueid,
+                0, idx, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+    np_stats->rx_multicast_pkts = stats_data.n_pkts_dropped;
+    np_stats->rx_multicast_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&np_stats->rx_multicast_pkts);
+    zxdh_data_hi_to_lo(&np_stats->rx_multicast_bytes);
+
+    idx = stats_id + ZXDH_UNICAST_STATS_EGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(hw->slot_id, dtb_data->queueid,
+                0, idx, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+    np_stats->tx_unicast_pkts = stats_data.n_pkts_dropped;
+    np_stats->tx_unicast_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&np_stats->tx_unicast_pkts);
+    zxdh_data_hi_to_lo(&np_stats->tx_unicast_bytes);
+
+    idx = stats_id + ZXDH_UNICAST_STATS_INGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(hw->slot_id, dtb_data->queueid,
+                0, idx, (uint32_t *)&stats_data);
     if (ret)
         return ret;
-    zxdh_data_hi_to_lo(&np_stats->np_rx_broadcast);
+    np_stats->rx_unicast_pkts = stats_data.n_pkts_dropped;
+    np_stats->rx_unicast_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&np_stats->rx_unicast_pkts);
+    zxdh_data_hi_to_lo(&np_stats->rx_unicast_bytes);
 
     idx = stats_id + ZXDH_MTU_STATS_EGRESS_BASE;
     memset(&stats_data, 0, sizeof(stats_data));
@@ -1368,11 +1417,10 @@ static int zxdh_np_stats_get(struct rte_eth_dev *dev, struct zxdh_hw_np_stats *n
                 1, idx, (uint32_t *)&stats_data);
     if (ret)
         return ret;
-
-    np_stats->np_tx_mtu_drop_pkts = stats_data.n_pkts_dropped;
-    np_stats->np_tx_mtu_drop_bytes = stats_data.n_bytes_dropped;
-    zxdh_data_hi_to_lo(&np_stats->np_tx_mtu_drop_pkts);
-    zxdh_data_hi_to_lo(&np_stats->np_tx_mtu_drop_bytes);
+    np_stats->tx_mtu_drop_pkts = stats_data.n_pkts_dropped;
+    np_stats->tx_mtu_drop_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&np_stats->tx_mtu_drop_pkts);
+    zxdh_data_hi_to_lo(&np_stats->tx_mtu_drop_bytes);
 
     idx = stats_id + ZXDH_MTU_STATS_INGRESS_BASE;
     memset(&stats_data, 0, sizeof(stats_data));
@@ -1380,10 +1428,32 @@ static int zxdh_np_stats_get(struct rte_eth_dev *dev, struct zxdh_hw_np_stats *n
                 1, idx, (uint32_t *)&stats_data);
     if (ret)
         return ret;
-    np_stats->np_rx_mtu_drop_pkts = stats_data.n_pkts_dropped;
-    np_stats->np_rx_mtu_drop_bytes = stats_data.n_bytes_dropped;
-    zxdh_data_hi_to_lo(&np_stats->np_rx_mtu_drop_pkts);
-    zxdh_data_hi_to_lo(&np_stats->np_rx_mtu_drop_bytes);
+    np_stats->rx_mtu_drop_pkts = stats_data.n_pkts_dropped;
+    np_stats->rx_mtu_drop_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&np_stats->rx_mtu_drop_pkts);
+    zxdh_data_hi_to_lo(&np_stats->rx_mtu_drop_bytes);
+
+    idx = stats_id + ZXDH_MTR_STATS_EGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(hw->slot_id, dtb_data->queueid,
+                1, idx, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+    np_stats->tx_mtr_drop_pkts = stats_data.n_pkts_dropped;
+    np_stats->tx_mtr_drop_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&np_stats->tx_mtr_drop_pkts);
+    zxdh_data_hi_to_lo(&np_stats->tx_mtr_drop_bytes);
+
+    idx = stats_id + ZXDH_MTR_STATS_INGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(hw->slot_id, dtb_data->queueid,
+                1, idx, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+    np_stats->rx_mtr_drop_pkts = stats_data.n_pkts_dropped;
+    np_stats->rx_mtr_drop_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&np_stats->rx_mtr_drop_pkts);
+    zxdh_data_hi_to_lo(&np_stats->rx_mtr_drop_bytes);
 
     return 0;
 }
@@ -1408,8 +1478,7 @@ zxdh_hw_np_stats_get(struct rte_eth_dev *dev, struct zxdh_hw_np_stats *np_stats)
                     &reply_info, sizeof(struct zxdh_msg_reply_info));
         if (ret) {
             PMD_DRV_LOG(ERR,
-                "%s Failed to send msg: port 0x%x msg type",
-                __func__, hw->vport.vport);
+                "Failed to send msg: port 0x%x msg type", hw->vport.vport);
             return -1;
         }
         memcpy(np_stats, &reply_info.reply_body.np_stats, sizeof(struct zxdh_hw_np_stats));
@@ -1438,8 +1507,8 @@ zxdh_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
     stats->ibytes = vqm_stats.rx_bytes;
     stats->obytes = vqm_stats.tx_bytes;
     stats->imissed = vqm_stats.rx_drop + mac_stats.rx_drop;
-    stats->ierrors = vqm_stats.rx_error + mac_stats.rx_error + np_stats.np_rx_mtu_drop_pkts;
-    stats->oerrors = vqm_stats.tx_error + mac_stats.tx_error + np_stats.np_tx_mtu_drop_pkts;
+    stats->ierrors = vqm_stats.rx_error + mac_stats.rx_error + np_stats.rx_mtu_drop_pkts;
+    stats->oerrors = vqm_stats.tx_error + mac_stats.tx_error + np_stats.tx_mtu_drop_pkts;
 
     stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
     for (i = 0; (i < dev->data->nb_rx_queues) && (i < RTE_ETHDEV_QUEUE_STAT_CNTRS); i++) {
@@ -1474,7 +1543,8 @@ zxdh_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
     return 0;
 }
 
-static int zxdh_hw_stats_reset(struct rte_eth_dev *dev, enum zxdh_agent_msg_type opcode)
+static int
+zxdh_hw_stats_reset(struct rte_eth_dev *dev, enum zxdh_agent_msg_type opcode)
 {
     struct zxdh_hw *hw = dev->data->dev_private;
     struct zxdh_msg_info msg_info = {0};
@@ -1505,13 +1575,128 @@ static int zxdh_hw_stats_reset(struct rte_eth_dev *dev, enum zxdh_agent_msg_type
     return 0;
 }
 
+int
+zxdh_hw_np_stats_pf_reset(struct rte_eth_dev *dev, uint32_t stats_id)
+{
+    struct zxdh_hw *hw = dev->data->dev_private;
+    struct zxdh_hw_stats_data stats_data;
+    uint32_t idx = 0;
+    int ret = 0;
+
+    idx = stats_id + ZXDH_UNICAST_STATS_EGRESS_BASE;
+    ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
+            1, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+
+    idx = stats_id + ZXDH_UNICAST_STATS_INGRESS_BASE;
+    ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
+            1, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+
+    idx = stats_id + ZXDH_MULTICAST_STATS_EGRESS_BASE;
+    ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
+            1, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+
+    idx = stats_id + ZXDH_MULTICAST_STATS_INGRESS_BASE;
+    ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
+            1, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+
+    idx = stats_id + ZXDH_BROAD_STATS_EGRESS_BASE;
+    ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
+            1, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+
+    idx = stats_id + ZXDH_BROAD_STATS_INGRESS_BASE;
+    ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
+            1, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+
+    idx = stats_id + ZXDH_MTU_STATS_EGRESS_BASE;
+    ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
+            1, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+
+    idx = stats_id + ZXDH_MTU_STATS_INGRESS_BASE;
+    ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
+            1, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+
+    idx = stats_id + ZXDH_MTR_STATS_EGRESS_BASE;
+    ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
+            1, (uint32_t *)&stats_data);
+    if (ret)
+        return ret;
+
+    idx = stats_id + ZXDH_MTR_STATS_INGRESS_BASE;
+    ret = zxdh_np_stat_ppu_cnt_get_ex(hw->dev_id, 1, idx,
+            1, (uint32_t *)&stats_data);
+
+    return ret;
+}
+
+static int
+zxdh_hw_np_stats_vf_reset(struct rte_eth_dev *dev)
+{
+    struct zxdh_hw *hw = dev->data->dev_private;
+    struct zxdh_msg_info msg_info = {0};
+    struct zxdh_msg_reply_info reply_info = {0};
+    int ret = 0;
+
+    msg_info.data.np_stats_query.clear_mode = 1;
+    zxdh_msg_head_build(hw, ZXDH_GET_NP_STATS, &msg_info);
+    ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(struct zxdh_msg_info),
+            &reply_info, sizeof(reply_info));
+    if (ret)
+        PMD_DRV_LOG(ERR, "Failed to send ZXDH_PORT_METER_STAT_GET msg. code:%d", ret);
+
+    return ret;
+}
+
+static int
+zxdh_np_stats_reset(struct rte_eth_dev *dev)
+{
+    struct zxdh_hw *hw = dev->data->dev_private;
+    uint32_t stats_id = zxdh_vport_to_vfid(hw->vport);
+    int ret;
+
+    if (hw->is_pf)
+        ret = zxdh_hw_np_stats_pf_reset(dev, stats_id);
+    else
+        ret = zxdh_hw_np_stats_vf_reset(dev);
+    return ret;
+}
+
 int zxdh_dev_stats_reset(struct rte_eth_dev *dev)
 {
     struct zxdh_hw *hw = dev->data->dev_private;
+    int i = 0;
 
     zxdh_hw_stats_reset(dev, ZXDH_VQM_DEV_STATS_RESET);
     if (hw->is_pf)
         zxdh_hw_stats_reset(dev, ZXDH_MAC_STATS_RESET);
+    zxdh_np_stats_reset(dev);
+    for (i = 0; ((i < dev->data->nb_rx_queues) && (i < RTE_ETHDEV_QUEUE_STAT_CNTRS)); i++) {
+        struct zxdh_virtnet_rx *rxvq = dev->data->rx_queues[i];
+        if (rxvq == NULL)
+            continue;
+        memset(&rxvq->stats, 0, sizeof(struct zxdh_virtnet_stats));
+    }
+    for (i = 0; ((i < dev->data->nb_tx_queues) && (i < RTE_ETHDEV_QUEUE_STAT_CNTRS)); i++) {
+        struct zxdh_virtnet_tx *txvq = dev->data->tx_queues[i];
+        if (txvq == NULL)
+            continue;
+        memset(&txvq->stats, 0, sizeof(struct zxdh_virtnet_stats));
+    }
 
     return 0;
 }
diff --git a/drivers/net/zxdh/zxdh_ethdev_ops.h b/drivers/net/zxdh/zxdh_ethdev_ops.h
index 8dbd73e2a5..9ab323fde1 100644
--- a/drivers/net/zxdh/zxdh_ethdev_ops.h
+++ b/drivers/net/zxdh/zxdh_ethdev_ops.h
@@ -28,17 +28,38 @@
 
 #define ZXDH_ETHER_MIN_MTU      68
 
+struct zxdh_np_stats_data {
+    uint64_t n_pkts_dropped;
+    uint64_t n_bytes_dropped;
+};
+
+struct zxdh_hw_stats_data {
+    uint64_t n_pkts_dropped;
+    uint64_t n_bytes_dropped;
+};
+
 struct zxdh_hw_np_stats {
-    uint64_t np_rx_broadcast;
-    uint64_t np_tx_broadcast;
-    uint64_t np_rx_mtu_drop_pkts;
-    uint64_t np_tx_mtu_drop_pkts;
-    uint64_t np_rx_mtu_drop_bytes;
-    uint64_t np_tx_mtu_drop_bytes;
-    uint64_t np_rx_mtr_drop_pkts;
-    uint64_t np_tx_mtr_drop_pkts;
-    uint64_t np_rx_mtr_drop_bytes;
-    uint64_t np_tx_mtr_drop_bytes;
+    uint64_t rx_unicast_pkts;
+    uint64_t tx_unicast_pkts;
+    uint64_t rx_unicast_bytes;
+    uint64_t tx_unicast_bytes;
+    uint64_t rx_multicast_pkts;
+    uint64_t tx_multicast_pkts;
+    uint64_t rx_multicast_bytes;
+    uint64_t tx_multicast_bytes;
+    uint64_t rx_broadcast_pkts;
+    uint64_t tx_broadcast_pkts;
+    uint64_t rx_broadcast_bytes;
+    uint64_t tx_broadcast_bytes;
+    uint64_t rx_mtu_drop_pkts;
+    uint64_t tx_mtu_drop_pkts;
+    uint64_t rx_mtu_drop_bytes;
+    uint64_t tx_mtu_drop_bytes;
+    uint64_t rx_mtr_drop_pkts;
+    uint64_t tx_mtr_drop_pkts;
+    uint64_t rx_mtr_drop_bytes;
+    uint64_t tx_mtr_drop_bytes;
+    uint64_t tx_ssvpc_pkts;
 };
 
 struct zxdh_hw_vqm_stats {
@@ -76,5 +97,7 @@ int zxdh_rss_configure(struct rte_eth_dev *dev);
 int zxdh_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
 int zxdh_dev_stats_reset(struct rte_eth_dev *dev);
 int zxdh_dev_mtu_set(struct rte_eth_dev *dev, uint16_t new_mtu);
+int zxdh_hw_np_stats_pf_reset(struct rte_eth_dev *dev, uint32_t stats_id);
+void zxdh_data_hi_to_lo(uint64_t *data);
 
 #endif /* ZXDH_ETHDEV_OPS_H */
diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c
index b99bd342ac..657527675b 100644
--- a/drivers/net/zxdh/zxdh_msg.c
+++ b/drivers/net/zxdh/zxdh_msg.c
@@ -16,6 +16,7 @@
 #include "zxdh_msg.h"
 #include "zxdh_pci.h"
 #include "zxdh_tables.h"
+#include "zxdh_np.h"
 
 #define ZXDH_REPS_INFO_FLAG_USABLE  0x00
 #define ZXDH_BAR_SEQID_NUM_MAX      256
@@ -1689,6 +1690,147 @@ zxdh_vf_port_attr_set(struct zxdh_hw *pf_hw, uint16_t vport, void *cfg_data,
     return ret;
 }
 
+static int
+zxdh_vf_np_stats_update(struct zxdh_hw *pf_hw, uint16_t vport,
+        void *cfg_data __rte_unused,
+        struct zxdh_msg_reply_body *res_info __rte_unused,
+        uint16_t *res_len __rte_unused)
+{
+    struct zxdh_np_stats_updata_msg *np_stats_query =
+             (struct zxdh_np_stats_updata_msg  *)cfg_data;
+    union zxdh_virport_num vport_num = {.vport = vport};
+    struct zxdh_hw_stats_data stats_data;
+    uint32_t is_clr = np_stats_query->clear_mode;
+    uint32_t idx = 0;
+    int ret = 0;
+
+    if (!res_len || !res_info) {
+        PMD_DRV_LOG(ERR, "get stat invalid inparams");
+        return -1;
+    }
+    if (is_clr == 1) {
+        ret = zxdh_hw_np_stats_pf_reset(pf_hw->eth_dev, zxdh_vport_to_vfid(vport_num));
+        return ret;
+    }
+    idx = zxdh_vport_to_vfid(vport_num) + ZXDH_UNICAST_STATS_EGRESS_BASE;
+    ret = zxdh_np_dtb_stats_get(pf_hw->dev_id, pf_hw->dev_sd->dtb_sd.queueid,
+            0, idx, (uint32_t *)&stats_data);
+    if (ret) {
+        PMD_DRV_LOG(ERR, "get stats failed. code:%d", ret);
+        return ret;
+    }
+    zxdh_data_hi_to_lo(&res_info->np_stats.tx_unicast_pkts);
+    zxdh_data_hi_to_lo(&res_info->np_stats.tx_unicast_bytes);
+
+    idx = zxdh_vport_to_vfid(vport_num) + ZXDH_UNICAST_STATS_INGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(pf_hw->dev_id, pf_hw->dev_sd->dtb_sd.queueid,
+            0, idx, (uint32_t *)&stats_data);
+    if (ret) {
+        PMD_DRV_LOG(ERR, "get stats failed. code:%d", ret);
+        return ret;
+    }
+    zxdh_data_hi_to_lo(&res_info->np_stats.rx_unicast_pkts);
+    zxdh_data_hi_to_lo(&res_info->np_stats.rx_unicast_bytes);
+
+    idx = zxdh_vport_to_vfid(vport_num) + ZXDH_MULTICAST_STATS_EGRESS_BASE;
+    ret = zxdh_np_dtb_stats_get(pf_hw->dev_id, pf_hw->dev_sd->dtb_sd.queueid,
+            0, idx, (uint32_t *)&stats_data);
+    if (ret) {
+        PMD_DRV_LOG(ERR, "get stats failed. code:%d", ret);
+        return ret;
+    }
+    zxdh_data_hi_to_lo(&res_info->np_stats.tx_multicast_pkts);
+    zxdh_data_hi_to_lo(&res_info->np_stats.tx_multicast_bytes);
+
+    idx = zxdh_vport_to_vfid(vport_num) + ZXDH_MULTICAST_STATS_INGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(pf_hw->dev_id, pf_hw->dev_sd->dtb_sd.queueid,
+            0, idx, (uint32_t *)&stats_data);
+    if (ret) {
+        PMD_DRV_LOG(ERR, "get stats failed. code:%d", ret);
+        return ret;
+    }
+    zxdh_data_hi_to_lo(&res_info->np_stats.rx_multicast_pkts);
+    zxdh_data_hi_to_lo(&res_info->np_stats.rx_multicast_bytes);
+
+    idx = zxdh_vport_to_vfid(vport_num) + ZXDH_BROAD_STATS_EGRESS_BASE;
+    ret = zxdh_np_dtb_stats_get(pf_hw->dev_id, pf_hw->dev_sd->dtb_sd.queueid,
+            0, idx, (uint32_t *)&stats_data);
+    if (ret) {
+        PMD_DRV_LOG(ERR, "get stats failed. code:%d", ret);
+        return ret;
+    }
+    zxdh_data_hi_to_lo(&res_info->np_stats.tx_broadcast_pkts);
+    zxdh_data_hi_to_lo(&res_info->np_stats.tx_broadcast_bytes);
+
+    idx = zxdh_vport_to_vfid(vport_num) + ZXDH_BROAD_STATS_INGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(pf_hw->dev_id, pf_hw->dev_sd->dtb_sd.queueid,
+            0, idx, (uint32_t *)&stats_data);
+    if (ret) {
+        PMD_DRV_LOG(ERR, "get stats failed. code:%d", ret);
+        return ret;
+    }
+    zxdh_data_hi_to_lo(&res_info->np_stats.rx_broadcast_pkts);
+    zxdh_data_hi_to_lo(&res_info->np_stats.rx_broadcast_bytes);
+
+    idx = zxdh_vport_to_vfid(vport_num) + ZXDH_MTU_STATS_EGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(pf_hw->dev_id, pf_hw->dev_sd->dtb_sd.queueid,
+            1, idx, (uint32_t *)&stats_data);
+    if (ret) {
+        PMD_DRV_LOG(ERR, "get stats failed. code:%d", ret);
+        return ret;
+    }
+    res_info->np_stats.tx_mtu_drop_pkts = stats_data.n_pkts_dropped;
+    res_info->np_stats.tx_mtu_drop_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&res_info->np_stats.tx_mtu_drop_pkts);
+    zxdh_data_hi_to_lo(&res_info->np_stats.tx_mtu_drop_bytes);
+
+    idx = zxdh_vport_to_vfid(vport_num) + ZXDH_MTU_STATS_INGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(pf_hw->dev_id, pf_hw->dev_sd->dtb_sd.queueid,
+            1, idx, (uint32_t *)&stats_data);
+    if (ret) {
+        PMD_DRV_LOG(ERR, "get stats failed. code:%d", ret);
+        return ret;
+    }
+    res_info->np_stats.rx_mtu_drop_pkts = stats_data.n_pkts_dropped;
+    res_info->np_stats.rx_mtu_drop_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&res_info->np_stats.rx_mtu_drop_pkts);
+    zxdh_data_hi_to_lo(&res_info->np_stats.rx_mtu_drop_bytes);
+
+    idx = zxdh_vport_to_vfid(vport_num) + ZXDH_MTR_STATS_EGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(pf_hw->dev_id, pf_hw->dev_sd->dtb_sd.queueid,
+            1, idx, (uint32_t *)&stats_data);
+    if (ret) {
+        PMD_DRV_LOG(ERR, "get stats failed. code:%d", ret);
+        return ret;
+    }
+    res_info->np_stats.tx_mtr_drop_pkts = stats_data.n_pkts_dropped;
+    res_info->np_stats.tx_mtr_drop_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&res_info->np_stats.tx_mtr_drop_pkts);
+    zxdh_data_hi_to_lo(&res_info->np_stats.tx_mtr_drop_bytes);
+
+    idx = zxdh_vport_to_vfid(vport_num) + ZXDH_MTR_STATS_INGRESS_BASE;
+    memset(&stats_data, 0, sizeof(stats_data));
+    ret = zxdh_np_dtb_stats_get(pf_hw->dev_id, pf_hw->dev_sd->dtb_sd.queueid,
+            1, idx, (uint32_t *)&stats_data);
+    if (ret) {
+        PMD_DRV_LOG(ERR, "get stats failed. code:%d", ret);
+        return ret;
+    }
+    res_info->np_stats.rx_mtr_drop_pkts = stats_data.n_pkts_dropped;
+    res_info->np_stats.rx_mtr_drop_bytes = stats_data.n_bytes_dropped;
+    zxdh_data_hi_to_lo(&res_info->np_stats.rx_mtr_drop_pkts);
+    zxdh_data_hi_to_lo(&res_info->np_stats.rx_mtr_drop_bytes);
+    *res_len = sizeof(struct zxdh_hw_np_stats);
+
+    return 0;
+}
+
 zxdh_msg_process_callback zxdh_proc_cb[] = {
     [ZXDH_NULL] = NULL,
     [ZXDH_VF_PORT_INIT] = zxdh_vf_port_init,
@@ -1705,6 +1847,7 @@ zxdh_msg_process_callback zxdh_proc_cb[] = {
     [ZXDH_RSS_HF_GET] = zxdh_vf_rss_hf_get,
     [ZXDH_VLAN_OFFLOAD] = zxdh_vf_set_vlan_offload,
     [ZXDH_PORT_ATTRS_SET] = zxdh_vf_port_attr_set,
+    [ZXDH_GET_NP_STATS] = zxdh_vf_np_stats_update,
 };
 
 static inline int
diff --git a/drivers/net/zxdh/zxdh_msg.h b/drivers/net/zxdh/zxdh_msg.h
index c4a940a438..cb830fa2da 100644
--- a/drivers/net/zxdh/zxdh_msg.h
+++ b/drivers/net/zxdh/zxdh_msg.h
@@ -320,6 +320,10 @@ enum zxdh_reps_flag {
     ZXDH_REPS_INVALID = 0xee,
 };
 
+struct zxdh_np_stats_updata_msg {
+    uint32_t clear_mode;
+};
+
 struct __rte_packed_begin zxdh_link_info_msg {
     uint8_t autoneg;
     uint8_t link_state;
@@ -347,6 +351,7 @@ struct __rte_packed_begin zxdh_msg_reply_body {
         struct zxdh_rss_reta rss_reta;
         struct zxdh_rss_hf rss_hf;
         struct zxdh_hw_vqm_stats vqm_stats;
+        struct zxdh_np_stats_updata_msg np_stats_query;
     } __rte_packed_end;
 } __rte_packed_end;
 
@@ -432,6 +437,7 @@ struct __rte_packed_begin zxdh_msg_info {
         struct zxdh_rss_reta rss_reta;
         struct zxdh_rss_enable rss_enable;
         struct zxdh_rss_hf rss_hf;
+        struct zxdh_np_stats_updata_msg np_stats_query;
     } __rte_packed_end data;
 } __rte_packed_end;
 
diff --git a/drivers/net/zxdh/zxdh_np.c b/drivers/net/zxdh/zxdh_np.c
index 1e6e8f0e75..015372bedc 100644
--- a/drivers/net/zxdh/zxdh_np.c
+++ b/drivers/net/zxdh/zxdh_np.c
@@ -2058,3 +2058,266 @@ zxdh_np_dtb_stats_get(uint32_t dev_id,
 
     return rc;
 }
+
+static uint32_t
+zxdh_np_se_done_status_check(uint32_t dev_id, uint32_t reg_no, uint32_t pos)
+{
+    uint32_t rc = 0;
+
+    uint32_t data = 0;
+    uint32_t rd_cnt = 0;
+    uint32_t done_flag = 0;
+
+    while (!done_flag) {
+        rc = zxdh_np_reg_read(dev_id, reg_no, 0, 0, &data);
+        if (rc != 0) {
+            PMD_DRV_LOG(ERR, " [ErrorCode:0x%x] !-- zxdh_np_reg_read Fail!", rc);
+            return rc;
+        }
+
+        done_flag = (data >> pos) & 0x1;
+
+        if (done_flag)
+            break;
+
+        if (rd_cnt > ZXDH_RD_CNT_MAX * ZXDH_RD_CNT_MAX)
+            return -1;
+
+        rd_cnt++;
+    }
+
+    return rc;
+}
+
+static uint32_t
+zxdh_np_se_smmu0_ind_read(uint32_t dev_id,
+                        uint32_t base_addr,
+                        uint32_t index,
+                        uint32_t rd_mode,
+                        uint32_t rd_clr_mode,
+                        uint32_t *p_data)
+{
+    uint32_t rc = 0;
+    uint32_t i = 0;
+    uint32_t row_index = 0;
+    uint32_t col_index = 0;
+    uint32_t temp_data[4] = {0};
+    uint32_t *p_temp_data = NULL;
+    ZXDH_SMMU0_SMMU0_CPU_IND_CMD_T cpu_ind_cmd = {0};
+
+    rc = zxdh_np_se_done_status_check(dev_id, ZXDH_SMMU0_SMMU0_WR_ARB_CPU_RDYR, 0);
+
+    if (rd_clr_mode == ZXDH_RD_MODE_HOLD) {
+        cpu_ind_cmd.cpu_ind_rw = ZXDH_SE_OPR_RD;
+        cpu_ind_cmd.cpu_ind_rd_mode = ZXDH_RD_MODE_HOLD;
+        cpu_ind_cmd.cpu_req_mode = ZXDH_ERAM128_OPR_128b;
+
+        switch (rd_mode) {
+        case ZXDH_ERAM128_OPR_128b:
+        {
+            if ((0xFFFFFFFF - (base_addr)) < (index))
+                return ZXDH_PAR_CHK_INVALID_INDEX;
+
+            if (base_addr + index > ZXDH_SE_SMMU0_ERAM_ADDR_NUM_TOTAL - 1) {
+                PMD_DRV_LOG(ERR, "%s : index out of range !", __func__);
+                return -1;
+            }
+
+            row_index = (index << 7) & ZXDH_ERAM128_BADDR_MASK;
+            break;
+        }
+
+        case ZXDH_ERAM128_OPR_64b:
+        {
+            if ((base_addr + (index >> 1)) > ZXDH_SE_SMMU0_ERAM_ADDR_NUM_TOTAL - 1) {
+                PMD_DRV_LOG(ERR, "%s : index out of range !", __func__);
+                return -1;
+            }
+
+            row_index = (index << 6) & ZXDH_ERAM128_BADDR_MASK;
+            col_index = index & 0x1;
+            break;
+        }
+
+        case ZXDH_ERAM128_OPR_32b:
+        {
+            if ((base_addr + (index >> 2)) > ZXDH_SE_SMMU0_ERAM_ADDR_NUM_TOTAL - 1) {
+                PMD_DRV_LOG(ERR, "%s : index out of range !", __func__);
+                return -1;
+            }
+
+            row_index = (index << 5) & ZXDH_ERAM128_BADDR_MASK;
+            col_index = index & 0x3;
+            break;
+        }
+
+        case ZXDH_ERAM128_OPR_1b:
+        {
+            if ((base_addr + (index >> 7)) > ZXDH_SE_SMMU0_ERAM_ADDR_NUM_TOTAL - 1) {
+                PMD_DRV_LOG(ERR, "%s : index out of range !", __func__);
+                return -1;
+            }
+            row_index = index & ZXDH_ERAM128_BADDR_MASK;
+            col_index = index & 0x7F;
+            break;
+        }
+        }
+
+        cpu_ind_cmd.cpu_ind_addr = ((base_addr << 7) & ZXDH_ERAM128_BADDR_MASK) + row_index;
+    } else {
+        cpu_ind_cmd.cpu_ind_rw = ZXDH_SE_OPR_RD;
+        cpu_ind_cmd.cpu_ind_rd_mode = ZXDH_RD_MODE_CLEAR;
+
+        switch (rd_mode) {
+        case ZXDH_ERAM128_OPR_128b:
+        {
+            if ((0xFFFFFFFF - (base_addr)) < (index)) {
+                PMD_DRV_LOG(ERR, "%s : index 0x%x is invalid!", __func__, index);
+                return ZXDH_PAR_CHK_INVALID_INDEX;
+            }
+            if (base_addr + index > ZXDH_SE_SMMU0_ERAM_ADDR_NUM_TOTAL - 1) {
+                PMD_DRV_LOG(ERR, "%s : index out of range !", __func__);
+                return -1;
+            }
+            row_index = (index << 7);
+            cpu_ind_cmd.cpu_req_mode = ZXDH_ERAM128_OPR_128b;
+            break;
+        }
+        case ZXDH_ERAM128_OPR_64b:
+        {
+            if ((base_addr + (index >> 1)) > ZXDH_SE_SMMU0_ERAM_ADDR_NUM_TOTAL - 1) {
+                PMD_DRV_LOG(ERR, "%s : index out of range !", __func__);
+                return -1;
+            }
+
+            row_index = (index << 6);
+            cpu_ind_cmd.cpu_req_mode = 2;
+            break;
+        }
+        case ZXDH_ERAM128_OPR_32b:
+        {
+            if ((base_addr + (index >> 2)) > ZXDH_SE_SMMU0_ERAM_ADDR_NUM_TOTAL - 1) {
+                PMD_DRV_LOG(ERR, "%s : index out of range !", __func__);
+                return -1;
+            }
+            row_index = (index << 5);
+            cpu_ind_cmd.cpu_req_mode = 1;
+            break;
+        }
+        case ZXDH_ERAM128_OPR_1b:
+        {
+            PMD_DRV_LOG(ERR, "rd_clr_mode[%d] or rd_mode[%d] error! ",
+                rd_clr_mode, rd_mode);
+            return -1;
+        }
+        }
+        cpu_ind_cmd.cpu_ind_addr = ((base_addr << 7) & ZXDH_ERAM128_BADDR_MASK) + row_index;
+    }
+
+    rc = zxdh_np_reg_write(dev_id,
+                        ZXDH_SMMU0_SMMU0_CPU_IND_CMDR,
+                        0,
+                        0,
+                        &cpu_ind_cmd);
+
+    rc = zxdh_np_se_done_status_check(dev_id, ZXDH_SMMU0_SMMU0_RD_CPU_IND_DONER, 0);
+
+    p_temp_data = temp_data;
+    for (i = 0; i < 4; i++) {
+        rc = zxdh_np_reg_read(dev_id,
+                            ZXDH_SMMU0_SMMU0_CPU_IND_RDAT0R + i,
+                            0,
+                            0,
+                            p_temp_data + 3 - i);
+    }
+
+    if (rd_clr_mode == ZXDH_RD_MODE_HOLD) {
+        switch (rd_mode) {
+        case ZXDH_ERAM128_OPR_128b:
+        {
+            rte_memcpy(p_data, p_temp_data, (128 / 8));
+            break;
+        }
+        case ZXDH_ERAM128_OPR_64b:
+        {
+            rte_memcpy(p_data, p_temp_data + ((1 - col_index) << 1), (64 / 8));
+            break;
+        }
+        case ZXDH_ERAM128_OPR_32b:
+        {
+            rte_memcpy(p_data, p_temp_data + ((3 - col_index)), (32 / 8));
+            break;
+        }
+        case ZXDH_ERAM128_OPR_1b:
+        {
+            ZXDH_COMM_UINT32_GET_BITS(p_data[0],
+                *(p_temp_data + (3 - col_index / 32)), (col_index % 32), 1);
+            break;
+        }
+        }
+    } else {
+        switch (rd_mode) {
+        case ZXDH_ERAM128_OPR_128b:
+        {
+            rte_memcpy(p_data, p_temp_data, (128 / 8));
+            break;
+        }
+        case ZXDH_ERAM128_OPR_64b:
+        {
+            rte_memcpy(p_data, p_temp_data, (64 / 8));
+            break;
+        }
+        case ZXDH_ERAM128_OPR_32b:
+        {
+            rte_memcpy(p_data, p_temp_data, (64 / 8));
+            break;
+        }
+        }
+    }
+
+    return rc;
+}
+
+uint32_t
+zxdh_np_stat_ppu_cnt_get_ex(uint32_t dev_id,
+                ZXDH_STAT_CNT_MODE_E rd_mode,
+                uint32_t index,
+                uint32_t clr_mode,
+                uint32_t *p_data)
+{
+    uint32_t rc = 0;
+    uint32_t ppu_eram_baddr = 0;
+    uint32_t ppu_eram_depth = 0;
+    uint32_t eram_rd_mode   = 0;
+    uint32_t eram_clr_mode  = 0;
+    ZXDH_PPU_STAT_CFG_T stat_cfg = {0};
+
+    zxdh_np_stat_cfg_soft_get(dev_id, &stat_cfg);
+
+    ppu_eram_depth = stat_cfg.eram_depth;
+    ppu_eram_baddr = stat_cfg.eram_baddr;
+
+    if ((index >> (ZXDH_STAT_128_MODE - rd_mode)) < ppu_eram_depth) {
+        if (rd_mode == ZXDH_STAT_128_MODE)
+            eram_rd_mode = ZXDH_ERAM128_OPR_128b;
+        else
+            eram_rd_mode = ZXDH_ERAM128_OPR_64b;
+
+        if (clr_mode == ZXDH_STAT_RD_CLR_MODE_UNCLR)
+            eram_clr_mode = ZXDH_RD_MODE_HOLD;
+        else
+            eram_clr_mode = ZXDH_RD_MODE_CLEAR;
+
+        rc = zxdh_np_se_smmu0_ind_read(dev_id,
+                                    ppu_eram_baddr,
+                                    index,
+                                    eram_rd_mode,
+                                    eram_clr_mode,
+                                    p_data);
+        ZXDH_COMM_CHECK_DEV_RC(dev_id, rc, "zxdh_np_se_smmu0_ind_read");
+    } else {
+        PMD_DRV_LOG(ERR, "DPDK DONT HAVE DDR STAT.");
+    }
+
+    return rc;
+}
diff --git a/drivers/net/zxdh/zxdh_np.h b/drivers/net/zxdh/zxdh_np.h
index 7da29cf7bd..d793189657 100644
--- a/drivers/net/zxdh/zxdh_np.h
+++ b/drivers/net/zxdh/zxdh_np.h
@@ -12,6 +12,9 @@
 #define ZXDH_PORT_NAME_MAX                    (32)
 #define ZXDH_DEV_CHANNEL_MAX                  (2)
 #define ZXDH_DEV_SDT_ID_MAX                   (256U)
+
+#define ZXDH_RD_CNT_MAX                       (128)
+
 /*DTB*/
 #define ZXDH_DTB_QUEUE_ITEM_NUM_MAX           (32)
 #define ZXDH_DTB_QUEUE_NUM_MAX                (128)
@@ -562,6 +565,38 @@ typedef enum zxdh_stat_cnt_mode_e {
     ZXDH_STAT_MAX_MODE,
 } ZXDH_STAT_CNT_MODE_E;
 
+typedef struct zxdh_smmu0_smmu0_cpu_ind_cmd_t {
+    uint32_t cpu_ind_rw;
+    uint32_t cpu_ind_rd_mode;
+    uint32_t cpu_req_mode;
+    uint32_t cpu_ind_addr;
+} ZXDH_SMMU0_SMMU0_CPU_IND_CMD_T;
+
+typedef enum zxdh_smmu0_smmu0_type_e {
+    ZXDH_DEV_MUTEX_T_SMMU0             = 0,
+    ZXDH_SMMU0_SMMU0_CPU_IND_CMDR      = 1,
+    ZXDH_SMMU0_SMMU0_CPU_IND_RDAT0R    = 2,
+    ZXDH_SMMU0_SMMU0_RD_CPU_IND_DONER  = 3,
+    ZXDH_SMMU0_SMMU0_WR_ARB_CPU_RDYR   = 4,
+    ZXDH_SMMU0_SMMU0_ED_ARB_CPU_RDYR   = 5,
+} ZXDH_SEMMU0_SEMMU0_TYPE_E;
+
+typedef enum zxdh_stat_rd_clr_mode_e {
+    ZXDH_STAT_RD_CLR_MODE_UNCLR = 0,
+    ZXDH_STAT_RD_CLR_MODE_CLR   = 1,
+    ZXDH_STAT_RD_CLR_MODE_MAX,
+} STAT_RD_CLR_MODE_E;
+
+typedef enum zxdh_eram128_rd_clr_mode_e {
+    ZXDH_RD_MODE_HOLD   = 0,
+    ZXDH_RD_MODE_CLEAR  = 1,
+} ZXDH_ERAM128_RD_CLR_MODE_E;
+
+typedef enum zxdh_se_opr_mode_e {
+    ZXDH_SE_OPR_RD      = 0,
+    ZXDH_SE_OPR_WR      = 1,
+} ZXDH_SE_OPR_MODE_E;
+
 int zxdh_np_host_init(uint32_t dev_id, ZXDH_DEV_INIT_CTRL_T *p_dev_init_ctrl);
 int zxdh_np_online_uninit(uint32_t dev_id, char *port_name, uint32_t queue_id);
 int zxdh_np_dtb_table_entry_write(uint32_t dev_id, uint32_t queue_id,
@@ -575,5 +610,10 @@ int zxdh_np_dtb_stats_get(uint32_t dev_id,
             ZXDH_STAT_CNT_MODE_E rd_mode,
             uint32_t index,
             uint32_t *p_data);
+uint32_t zxdh_np_stat_ppu_cnt_get_ex(uint32_t dev_id,
+            ZXDH_STAT_CNT_MODE_E rd_mode,
+            uint32_t index,
+            uint32_t clr_mode,
+            uint32_t *p_data);
 
 #endif /* ZXDH_NP_H */
diff --git a/drivers/net/zxdh/zxdh_tables.h b/drivers/net/zxdh/zxdh_tables.h
index 67294105e9..542cee5e49 100644
--- a/drivers/net/zxdh/zxdh_tables.h
+++ b/drivers/net/zxdh/zxdh_tables.h
@@ -51,10 +51,18 @@
 #define ZXDH_PORT_RSS_EN_OFF_FLAG                 42
 #define ZXDH_PORT_MTU_OFFLOAD_EN_OFF_FLAG         43
 
-#define ZXDH_MTU_STATS_EGRESS_BASE        0x8481
-#define ZXDH_MTU_STATS_INGRESS_BASE       0x8981
-#define ZXDH_BROAD_STATS_EGRESS_BASE      0xC902
-#define ZXDH_BROAD_STATS_INGRESS_BASE     0xD102
+#define ZXDH_MTU_STATS_EGRESS_BASE           0x8481
+#define ZXDH_MTU_STATS_INGRESS_BASE          0x8981
+#define ZXDH_MTR_STATS_EGRESS_BASE           0x7481
+#define ZXDH_MTR_STATS_INGRESS_BASE          0x7C81
+#define ZXDH_BROAD_STATS_EGRESS_BASE         0xA8C1
+#define ZXDH_BROAD_STATS_INGRESS_BASE        0xA3C1
+#define ZXDH_MULTICAST_STATS_EGRESS_BASE     0x9EC1
+#define ZXDH_MULTICAST_STATS_INGRESS_BASE    0x99C1
+#define ZXDH_UNICAST_STATS_EGRESS_BASE       0x94C1
+#define ZXDH_UNICAST_STATS_INGRESS_BASE      0x8FC1
+
+#define ZXDH_FLOW_STATS_INGRESS_BASE         0xADC1
 
 extern struct zxdh_dtb_shared_data g_dtb_data;
 
-- 
2.27.0