diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 449d967..7c51e83 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -6148,8 +6148,6 @@ hns3_dev_init(struct rte_eth_dev *eth_dev)
 		return 0;
 	}
 
-	eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
-
 	ret = hns3_mp_init_primary();
 	if (ret) {
 		PMD_INIT_LOG(ERR,
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index bb4ec6b..37135d7 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -2746,8 +2746,6 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev)
 		return 0;
 	}
 
-	eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
-
 	ret = hns3_mp_init_primary();
 	if (ret) {
 		PMD_INIT_LOG(ERR,
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 3d5f74f..30f1e06 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -1792,6 +1792,7 @@ hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc,
 	rxq->io_head_reg = (volatile void *)((char *)rxq->io_base +
 			   HNS3_RING_RX_HEAD_REG);
 	rxq->rx_buf_len = rx_buf_size;
+	memset(&rxq->basic_stats, 0, sizeof(struct hns3_rx_basic_stats));
 	memset(&rxq->err_stats, 0, sizeof(struct hns3_rx_bd_errors_stats));
 	memset(&rxq->dfx_stats, 0, sizeof(struct hns3_rx_dfx_stats));
 
@@ -2618,6 +2619,7 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc,
 					     HNS3_RING_TX_TAIL_REG);
 	txq->min_tx_pkt_len = hw->min_tx_pkt_len;
 	txq->tso_mode = hw->tso_mode;
+	memset(&txq->basic_stats, 0, sizeof(struct hns3_tx_basic_stats));
 	memset(&txq->dfx_stats, 0, sizeof(struct hns3_tx_dfx_stats));
 
 	rte_spinlock_lock(&hw->lock);
diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h
index 8a0c981..331b507 100644
--- a/drivers/net/hns3/hns3_rxtx.h
+++ b/drivers/net/hns3/hns3_rxtx.h
@@ -266,6 +266,12 @@ struct hns3_entry {
 	struct rte_mbuf *mbuf;
 };
 
+struct hns3_rx_basic_stats {
+	uint64_t packets;
+	uint64_t bytes;
+	uint64_t errors;
+};
+
 struct hns3_rx_dfx_stats {
 	uint64_t l3_csum_errors;
 	uint64_t l4_csum_errors;
@@ -324,6 +330,7 @@ struct hns3_rx_queue {
 	bool pvid_sw_discard_en;
 	bool enabled;           /* indicate if Rx queue has been enabled */
 
+	struct hns3_rx_basic_stats basic_stats;
 	/* DFX statistics that driver does not need to discard packets */
 	struct hns3_rx_dfx_stats dfx_stats;
 	/* Error statistics that driver needs to discard packets */
@@ -338,6 +345,11 @@ struct hns3_rx_queue {
 	struct rte_mbuf fake_mbuf; /* fake mbuf used with vector rx */
 };
 
+struct hns3_tx_basic_stats {
+	uint64_t packets;
+	uint64_t bytes;
+};
+
 /*
  * The following items are used for the abnormal errors statistics in
  * the Tx datapath. When upper level application calls the
@@ -472,6 +484,7 @@ struct hns3_tx_queue {
 	bool pvid_sw_shift_en;
 	bool enabled;           /* indicate if Tx queue has been enabled */
 
+	struct hns3_tx_basic_stats basic_stats;
 	struct hns3_tx_dfx_stats dfx_stats;
 };
 
diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c
index 419d7e2..3ba09e2 100644
--- a/drivers/net/hns3/hns3_stats.c
+++ b/drivers/net/hns3/hns3_stats.c
@@ -11,6 +11,24 @@
 #include "hns3_logs.h"
 #include "hns3_regs.h"
 
+/* The statistics of the per-rxq basic stats */
+static const struct hns3_xstats_name_offset hns3_rxq_basic_stats_strings[] = {
+	{"packets",
+		HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(packets)},
+	{"bytes",
+		HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(bytes)},
+	{"errors",
+		HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(errors)}
+};
+
+/* The statistics of the per-txq basic stats */
+static const struct hns3_xstats_name_offset hns3_txq_basic_stats_strings[] = {
+	{"packets",
+		HNS3_TXQ_BASIC_STATS_FIELD_OFFSET(packets)},
+	{"bytes",
+		HNS3_TXQ_BASIC_STATS_FIELD_OFFSET(bytes)}
+};
+
 /* MAC statistics */
 static const struct hns3_xstats_name_offset hns3_mac_strings[] = {
 	{"mac_tx_mac_pause_num",
@@ -330,6 +348,12 @@ static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = {
 #define HNS3_NUM_TX_QUEUE_STATS (sizeof(hns3_tx_queue_strings) / \
 	sizeof(hns3_tx_queue_strings[0]))
 
+#define HNS3_NUM_RXQ_BASIC_STATS (sizeof(hns3_rxq_basic_stats_strings) / \
+	sizeof(hns3_rxq_basic_stats_strings[0]))
+
+#define HNS3_NUM_TXQ_BASIC_STATS (sizeof(hns3_txq_basic_stats_strings) / \
+	sizeof(hns3_txq_basic_stats_strings[0]))
+
 #define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_ERROR_INT_XSTATS + \
 			    HNS3_NUM_RESET_XSTATS)
 
@@ -508,9 +532,7 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats)
 	struct hns3_hw *hw = &hns->hw;
 	struct hns3_tqp_stats *stats = &hw->tqp_stats;
 	struct hns3_rx_queue *rxq;
-	struct hns3_tx_queue *txq;
 	uint64_t cnt;
-	uint64_t num;
 	uint16_t i;
 	int ret;
 
@@ -522,25 +544,14 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats)
 	}
 
 	/* Get the error stats of received packets */
-	num = RTE_MIN(RTE_ETHDEV_QUEUE_STAT_CNTRS, eth_dev->data->nb_rx_queues);
-	for (i = 0; i != num; ++i) {
+	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
 		rxq = eth_dev->data->rx_queues[i];
 		if (rxq) {
 			cnt = rxq->err_stats.l2_errors +
 				rxq->err_stats.pkt_len_errors;
-			rte_stats->q_errors[i] = cnt;
-			rte_stats->q_ipackets[i] =
-				stats->rcb_rx_ring_pktnum[i] - cnt;
 			rte_stats->ierrors += cnt;
 		}
 	}
-	/* Get the error stats of transmitted packets */
-	num = RTE_MIN(RTE_ETHDEV_QUEUE_STAT_CNTRS, eth_dev->data->nb_tx_queues);
-	for (i = 0; i < num; i++) {
-		txq = eth_dev->data->tx_queues[i];
-		if (txq)
-			rte_stats->q_opackets[i] = stats->rcb_tx_ring_pktnum[i];
-	}
 
 	rte_stats->oerrors = 0;
 	rte_stats->ipackets  = stats->rcb_rx_ring_pktnum_rcd -
@@ -600,6 +611,11 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev)
 		}
 	}
 
+	/*
+	 * 'packets' in hns3_tx_basic_stats and hns3_rx_basic_stats come
+	 * from hw->tqp_stats. And clearing tqp stats is like clearing
+	 * their source.
+	 */
 	hns3_tqp_stats_clear(hw);
 
 	return 0;
@@ -628,21 +644,26 @@ hns3_mac_stats_reset(__rte_unused struct rte_eth_dev *dev)
 static int
 hns3_xstats_calc_num(struct rte_eth_dev *dev)
 {
+#define HNS3_PF_VF_RX_COMM_STATS_NUM	(HNS3_NUM_RX_BD_ERROR_XSTATS + \
+					 HNS3_NUM_RXQ_DFX_XSTATS + \
+					 HNS3_NUM_RX_QUEUE_STATS + \
+					 HNS3_NUM_RXQ_BASIC_STATS)
+#define HNS3_PF_VF_TX_COMM_STATS_NUM	(HNS3_NUM_TXQ_DFX_XSTATS + \
+					 HNS3_NUM_TX_QUEUE_STATS + \
+					 HNS3_NUM_TXQ_BASIC_STATS)
+
 	struct hns3_adapter *hns = dev->data->dev_private;
 	uint16_t nb_rx_q = dev->data->nb_rx_queues;
 	uint16_t nb_tx_q = dev->data->nb_tx_queues;
-	int bderr_stats = nb_rx_q * HNS3_NUM_RX_BD_ERROR_XSTATS;
-	int rx_dfx_stats = nb_rx_q * HNS3_NUM_RXQ_DFX_XSTATS;
-	int tx_dfx_stats = nb_tx_q * HNS3_NUM_TXQ_DFX_XSTATS;
-	int rx_queue_stats = nb_rx_q * HNS3_NUM_RX_QUEUE_STATS;
-	int tx_queue_stats = nb_tx_q * HNS3_NUM_TX_QUEUE_STATS;
+	int rx_comm_stats_num = nb_rx_q * HNS3_PF_VF_RX_COMM_STATS_NUM;
+	int tx_comm_stats_num = nb_tx_q * HNS3_PF_VF_TX_COMM_STATS_NUM;
 
 	if (hns->is_vf)
-		return bderr_stats + rx_dfx_stats + tx_dfx_stats +
-			rx_queue_stats + tx_queue_stats + HNS3_NUM_RESET_XSTATS;
+		return rx_comm_stats_num + tx_comm_stats_num +
+			HNS3_NUM_RESET_XSTATS;
 	else
-		return bderr_stats + rx_dfx_stats + tx_dfx_stats +
-			rx_queue_stats + tx_queue_stats + HNS3_FIX_NUM_STATS;
+		return rx_comm_stats_num + tx_comm_stats_num +
+			HNS3_FIX_NUM_STATS;
 }
 
 static void
@@ -751,6 +772,118 @@ hns3_tqp_dfx_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 	hns3_rxq_dfx_stats_get(dev, xstats, count);
 	hns3_txq_dfx_stats_get(dev, xstats, count);
 }
+
+static void
+hns3_rxq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
+			 int *count)
+{
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct hns3_tqp_stats *stats = &hw->tqp_stats;
+	struct hns3_rx_basic_stats *rxq_stats;
+	struct hns3_rx_queue *rxq;
+	uint16_t i, j;
+	char *val;
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		if (rxq == NULL)
+			continue;
+
+		rxq_stats = &rxq->basic_stats;
+		rxq_stats->errors = rxq->err_stats.l2_errors +
+					rxq->err_stats.pkt_len_errors;
+		rxq_stats->packets = stats->rcb_rx_ring_pktnum[i] -
+			rxq_stats->errors;
+		rxq_stats->bytes = 0;
+		for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) {
+			val = (char *)rxq_stats +
+				hns3_rxq_basic_stats_strings[j].offset;
+			xstats[*count].value = *(uint64_t *)val;
+			xstats[*count].id = *count;
+			(*count)++;
+		}
+	}
+}
+
+static void
+hns3_txq_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
+			 int *count)
+{
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct hns3_tqp_stats *stats = &hw->tqp_stats;
+	struct hns3_tx_basic_stats *txq_stats;
+	struct hns3_tx_queue *txq;
+	uint16_t i, j;
+	char *val;
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		txq = dev->data->tx_queues[i];
+		if (txq == NULL)
+			continue;
+
+		txq_stats = &txq->basic_stats;
+		txq_stats->packets = stats->rcb_tx_ring_pktnum[i];
+		txq_stats->bytes = 0;
+		for (j = 0; j < HNS3_NUM_TXQ_BASIC_STATS; j++) {
+			val = (char *)txq_stats +
+				hns3_txq_basic_stats_strings[j].offset;
+			xstats[*count].value = *(uint64_t *)val;
+			xstats[*count].id = *count;
+			(*count)++;
+		}
+	}
+}
+
+static int
+hns3_tqp_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
+			 int *count)
+{
+	struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
+
+	/* Update tqp stats by read register */
+	ret = hns3_update_tqp_stats(hw);
+	if (ret) {
+		hns3_err(hw, "Update tqp stats fail, ret = %d.", ret);
+		return ret;
+	}
+
+	hns3_rxq_basic_stats_get(dev, xstats, count);
+	hns3_txq_basic_stats_get(dev, xstats, count);
+
+	return 0;
+}
+
+/*
+ * The function is only called by hns3_dev_xstats_reset to clear
+ * basic stats of per-queue. TQP stats are all cleared in hns3_stats_reset
+ * which is called before this function.
+ *
+ * @param dev
+ *   Pointer to Ethernet device.
+ */
+static void
+hns3_tqp_basic_stats_clear(struct rte_eth_dev *dev)
+{
+	struct hns3_tx_queue *txq;
+	struct hns3_rx_queue *rxq;
+	uint16_t i;
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		if (rxq)
+			memset(&rxq->basic_stats, 0,
+			       sizeof(struct hns3_rx_basic_stats));
+	}
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		txq = dev->data->tx_queues[i];
+		if (txq)
+			memset(&txq->basic_stats, 0,
+			       sizeof(struct hns3_tx_basic_stats));
+	}
+}
+
 /*
  * Retrieve extended(tqp | Mac) statistics of an Ethernet device.
  * @param dev
@@ -789,6 +922,10 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 
 	count = 0;
 
+	ret = hns3_tqp_basic_stats_get(dev, xstats, &count);
+	if (ret < 0)
+		return ret;
+
 	if (!hns->is_vf) {
 		/* Update Mac stats */
 		ret = hns3_query_update_mac_stats(dev);
@@ -844,28 +981,55 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 }
 
 static void
+hns3_tqp_basic_stats_name_get(struct rte_eth_dev *dev,
+			      struct rte_eth_xstat_name *xstats_names,
+			      uint32_t *count)
+{
+	uint16_t i, j;
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		for (j = 0; j < HNS3_NUM_RXQ_BASIC_STATS; j++) {
+			snprintf(xstats_names[*count].name,
+				 sizeof(xstats_names[*count].name),
+				 "rx_q%u_%s", i,
+				 hns3_rxq_basic_stats_strings[j].name);
+			(*count)++;
+		}
+	}
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		for (j = 0; j < HNS3_NUM_TXQ_BASIC_STATS; j++) {
+			snprintf(xstats_names[*count].name,
+				 sizeof(xstats_names[*count].name),
+				 "tx_q%u_%s", i,
+				 hns3_txq_basic_stats_strings[j].name);
+			(*count)++;
+		}
+	}
+}
+
+static void
 hns3_tqp_dfx_stats_name_get(struct rte_eth_dev *dev,
 			    struct rte_eth_xstat_name *xstats_names,
 			    uint32_t *count)
 {
 	uint16_t i, j;
 
-	for (j = 0; j < dev->data->nb_rx_queues; j++) {
-		for (i = 0; i < HNS3_NUM_RXQ_DFX_XSTATS; i++) {
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		for (j = 0; j < HNS3_NUM_RXQ_DFX_XSTATS; j++) {
 			snprintf(xstats_names[*count].name,
 				 sizeof(xstats_names[*count].name),
-				 "rx_q%u_%s", j,
-				 hns3_rxq_dfx_stats_strings[i].name);
+				 "rx_q%u_%s", i,
+				 hns3_rxq_dfx_stats_strings[j].name);
 			(*count)++;
 		}
 	}
 
-	for (j = 0; j < dev->data->nb_tx_queues; j++) {
-		for (i = 0; i < HNS3_NUM_TXQ_DFX_XSTATS; i++) {
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		for (j = 0; j < HNS3_NUM_TXQ_DFX_XSTATS; j++) {
 			snprintf(xstats_names[*count].name,
 				 sizeof(xstats_names[*count].name),
-				 "tx_q%u_%s", j,
-				 hns3_txq_dfx_stats_strings[i].name);
+				 "tx_q%u_%s", i,
+				 hns3_txq_dfx_stats_strings[j].name);
 			(*count)++;
 		}
 	}
@@ -908,6 +1072,8 @@ hns3_dev_xstats_get_names(struct rte_eth_dev *dev,
 	if (xstats_names == NULL)
 		return cnt_stats;
 
+	hns3_tqp_basic_stats_name_get(dev, xstats_names, &count);
+
 	/* Note: size limited checked in rte_eth_xstats_get_names() */
 	if (!hns->is_vf) {
 		/* Get MAC name from hw->hw_xstats.mac_stats struct */
@@ -999,7 +1165,6 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 	uint32_t count_value;
 	uint64_t len;
 	uint32_t i;
-	int ret;
 
 	if (ids == NULL && values == NULL)
 		return cnt_stats;
@@ -1008,13 +1173,6 @@ hns3_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
 		if (size < cnt_stats)
 			return cnt_stats;
 
-	/* Update tqp stats by read register */
-	ret = hns3_update_tqp_stats(hw);
-	if (ret) {
-		hns3_err(hw, "Update tqp stats fail : %d", ret);
-		return ret;
-	}
-
 	len = cnt_stats * sizeof(struct rte_eth_xstat);
 	values_copy = rte_zmalloc("hns3_xstats_values", len, 0);
 	if (values_copy == NULL) {
@@ -1157,11 +1315,12 @@ hns3_dev_xstats_reset(struct rte_eth_dev *dev)
 	if (ret)
 		return ret;
 
+	hns3_tqp_basic_stats_clear(dev);
+	hns3_tqp_dfx_stats_clear(dev);
+
 	/* Clear reset stats */
 	memset(&hns->hw.reset.stats, 0, sizeof(struct hns3_reset_stats));
 
-	hns3_tqp_dfx_stats_clear(dev);
-
 	if (hns->is_vf)
 		return 0;
 
diff --git a/drivers/net/hns3/hns3_stats.h b/drivers/net/hns3/hns3_stats.h
index 12842cd..d213be5 100644
--- a/drivers/net/hns3/hns3_stats.h
+++ b/drivers/net/hns3/hns3_stats.h
@@ -135,6 +135,12 @@ struct hns3_reset_stats;
 #define HNS3_TXQ_DFX_STATS_FIELD_OFFSET(f) \
 	(offsetof(struct hns3_tx_dfx_stats, f))
 
+#define HNS3_RXQ_BASIC_STATS_FIELD_OFFSET(f) \
+	(offsetof(struct hns3_rx_basic_stats, f))
+
+#define HNS3_TXQ_BASIC_STATS_FIELD_OFFSET(f) \
+	(offsetof(struct hns3_tx_basic_stats, f))
+
 int hns3_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats);
 int hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 			unsigned int n);
