[dpdk-dev] [PATCH 6/9] net/hns3: support imissed stats for PF/VF

Min Hu (Connor) humin29 at huawei.com
Wed Mar 10 07:24:50 CET 2021


This patch added function level imissed stats for PF and VF. In kunpeng920,
imissed is supported, only including RPU drop stats in PF. In kunpeng930,
imissed is supported,including RPU drop stats and SSU drop stats in PF.

Signed-off-by: Min Hu (Connor) <humin29 at huawei.com>
---
 drivers/net/hns3/hns3_cmd.h       |  14 +++
 drivers/net/hns3/hns3_ethdev.c    |   2 +
 drivers/net/hns3/hns3_ethdev.h    |  21 ++++
 drivers/net/hns3/hns3_ethdev_vf.c |   9 ++
 drivers/net/hns3/hns3_regs.h      |   2 +
 drivers/net/hns3/hns3_stats.c     | 233 +++++++++++++++++++++++++++++---------
 drivers/net/hns3/hns3_stats.h     |   1 +
 7 files changed, 230 insertions(+), 52 deletions(-)

diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h
index 094bf7e..939bbc2 100644
--- a/drivers/net/hns3/hns3_cmd.h
+++ b/drivers/net/hns3/hns3_cmd.h
@@ -111,6 +111,8 @@ enum hns3_opcode_type {
 
 	HNS3_OPC_QUERY_DEV_SPECS        = 0x0050,
 
+	HNS3_OPC_SSU_DROP_REG           = 0x0065,
+
 	/* MAC command */
 	HNS3_OPC_CONFIG_MAC_MODE        = 0x0301,
 	HNS3_OPC_QUERY_LINK_STATUS      = 0x0307,
@@ -957,6 +959,18 @@ struct hns3_query_rpu_cmd {
 	uint32_t rsv2[2];
 };
 
+#define HNS3_OPC_SSU_DROP_REG_NUM 2
+
+struct hns3_query_ssu_cmd {
+	uint8_t rxtx;
+	uint8_t rsv[3];
+	uint32_t full_drop_cnt;
+	uint32_t part_drop_cnt;
+	uint32_t ncsi_full_drop_cnt;
+	uint32_t ncsi_part_drop_cnt;
+	uint32_t oq_glb_drop_cnt;
+};
+
 #define HNS3_MAX_TQP_NUM_HIP08_PF	64
 #define HNS3_DEFAULT_TX_BUF		0x4000    /* 16k  bytes */
 #define HNS3_TOTAL_PKT_BUF		0x108000  /* 1.03125M bytes */
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index db2c94a..cd92b8d 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -3122,6 +3122,7 @@ hns3_get_capability(struct hns3_hw *hw)
 		hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_2US;
 		hw->tso_mode = HNS3_TSO_SW_CAL_PSEUDO_H_CSUM;
 		hw->vlan_mode = HNS3_SW_SHIFT_AND_DISCARD_MODE;
+		hw->drop_stats_mode = HNS3_PKTS_DROP_STATS_MODE1;
 		hw->min_tx_pkt_len = HNS3_HIP08_MIN_TX_PKT_LEN;
 		pf->tqp_config_mode = HNS3_FIXED_MAX_TQP_NUM_MODE;
 		hw->rss_info.ipv6_sctp_offload_supported = false;
@@ -3140,6 +3141,7 @@ hns3_get_capability(struct hns3_hw *hw)
 	hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_1US;
 	hw->tso_mode = HNS3_TSO_HW_CAL_PSEUDO_H_CSUM;
 	hw->vlan_mode = HNS3_HW_SHIFT_AND_DISCARD_MODE;
+	hw->drop_stats_mode = HNS3_PKTS_DROP_STATS_MODE2;
 	hw->min_tx_pkt_len = HNS3_HIP09_MIN_TX_PKT_LEN;
 	pf->tqp_config_mode = HNS3_FLEX_MAX_TQP_NUM_MODE;
 	hw->rss_info.ipv6_sctp_offload_supported = true;
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index a29d6f8..915f183 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -426,6 +426,9 @@ struct hns3_queue_intr {
 #define HNS3_TSO_SW_CAL_PSEUDO_H_CSUM		0
 #define HNS3_TSO_HW_CAL_PSEUDO_H_CSUM		1
 
+#define HNS3_PKTS_DROP_STATS_MODE1		0
+#define HNS3_PKTS_DROP_STATS_MODE2		1
+
 struct hns3_hw {
 	struct rte_eth_dev_data *data;
 	void *io_base;
@@ -544,6 +547,24 @@ struct hns3_hw {
 	 *     port won't be copied to the function which has set promisc mode.
 	 */
 	uint8_t promisc_mode;
+
+	/*
+	 * drop_stats_mode mode.
+	 * value range:
+	 *      HNS3_PKTS_DROP_STATS_MODE1/HNS3_PKTS_DROP_STATS_MODE2
+	 *
+	 *  - HNS3_PKTS_DROP_STATS_MODE1
+	 *     This mode for kunpeng920. In this mode, port level imissed stats
+	 *     is supported. It only includes RPU drop stats.
+	 *
+	 *  - HNS3_PKTS_DROP_STATS_MODE2
+	 *     This mode for kunpeng930. In this mode, imissed stats and oerrors
+	 *     stats is supported. Function level imissed stats is supported. It
+	 *     includes RPU drop stats in VF, and includes both RPU drop stats
+	 *     and SSU drop stats in PF. Oerror stats is also supported in PF.
+	 */
+	uint8_t drop_stats_mode;
+
 	uint8_t max_non_tso_bd_num; /* max BD number of one non-TSO packet */
 
 	struct hns3_port_base_vlan_config port_base_vlan_cfg;
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index b7c27f6..25d74ba 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -1221,6 +1221,7 @@ hns3vf_get_capability(struct hns3_hw *hw)
 		hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_RSV_ONE;
 		hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_2US;
 		hw->tso_mode = HNS3_TSO_SW_CAL_PSEUDO_H_CSUM;
+		hw->drop_stats_mode = HNS3_PKTS_DROP_STATS_MODE1;
 		hw->min_tx_pkt_len = HNS3_HIP08_MIN_TX_PKT_LEN;
 		hw->rss_info.ipv6_sctp_offload_supported = false;
 		hw->promisc_mode = HNS3_UNLIMIT_PROMISC_MODE;
@@ -1238,6 +1239,7 @@ hns3vf_get_capability(struct hns3_hw *hw)
 	hw->intr.mapping_mode = HNS3_INTR_MAPPING_VEC_ALL;
 	hw->intr.gl_unit = HNS3_INTR_COALESCE_GL_UINT_1US;
 	hw->tso_mode = HNS3_TSO_HW_CAL_PSEUDO_H_CSUM;
+	hw->drop_stats_mode = HNS3_PKTS_DROP_STATS_MODE2;
 	hw->min_tx_pkt_len = HNS3_HIP09_MIN_TX_PKT_LEN;
 	hw->rss_info.ipv6_sctp_offload_supported = true;
 	hw->promisc_mode = HNS3_LIMIT_PROMISC_MODE;
@@ -1877,6 +1879,13 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev)
 	if (ret)
 		goto err_get_config;
 
+	/* Hardware statistics of imissed registers cleared. */
+	ret = hns3_update_imissed_stats(hw, true);
+	if (ret) {
+		hns3_err(hw, "clear imissed stats failed, ret = %d", ret);
+		goto err_set_tc_queue;
+	}
+
 	ret = hns3vf_set_tc_queue_mapping(hns, hw->tqps_num, hw->tqps_num);
 	if (ret) {
 		PMD_INIT_LOG(ERR, "failed to set tc info, ret = %d.", ret);
diff --git a/drivers/net/hns3/hns3_regs.h b/drivers/net/hns3/hns3_regs.h
index 0540554..e141fe1 100644
--- a/drivers/net/hns3/hns3_regs.h
+++ b/drivers/net/hns3/hns3_regs.h
@@ -36,6 +36,8 @@
 #define HNS3_GLOBAL_RESET_REG		0x20A00
 #define HNS3_FUN_RST_ING		0x20C00
 #define HNS3_GRO_EN_REG			0x28000
+
+#define HNS3_RPU_DROP_CNT_REG		0x28004
 #define HNS3_RXD_ADV_LAYOUT_EN_REG	0x28008
 
 /* Vector0 register bits for reset */
diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c
index 7cda36c..ccad477 100644
--- a/drivers/net/hns3/hns3_stats.c
+++ b/drivers/net/hns3/hns3_stats.c
@@ -269,6 +269,8 @@ static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = {
 static const struct hns3_xstats_name_offset hns3_imissed_stats_strings[] = {
 	{"RPU_DROP_CNT",
 		HNS3_IMISSED_STATS_FIELD_OFFSET(rpu_rx_drop_cnt)},
+	{"SSU_DROP_CNT",
+		HNS3_IMISSED_STATS_FIELD_OFFSET(ssu_rx_drop_cnt)},
 };
 
 #define HNS3_NUM_MAC_STATS (sizeof(hns3_mac_strings) / \
@@ -301,8 +303,7 @@ static const struct hns3_xstats_name_offset hns3_imissed_stats_strings[] = {
 #define HNS3_NUM_IMISSED_XSTATS (sizeof(hns3_imissed_stats_strings) / \
 	sizeof(hns3_imissed_stats_strings[0]))
 
-#define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + \
-			    HNS3_NUM_RESET_XSTATS + HNS3_NUM_IMISSED_XSTATS)
+#define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_RESET_XSTATS)
 
 static void hns3_tqp_stats_clear(struct hns3_hw *hw);
 
@@ -419,7 +420,7 @@ hns3_query_update_mac_stats(struct rte_eth_dev *dev)
 }
 
 static int
-hns3_update_rpu_drop_stats(struct hns3_hw *hw)
+hns3_update_port_rpu_drop_stats(struct hns3_hw *hw)
 {
 	struct hns3_rx_missed_stats *stats = &hw->imissed_stats;
 	struct hns3_query_rpu_cmd *req;
@@ -449,11 +450,89 @@ hns3_update_rpu_drop_stats(struct hns3_hw *hw)
 	return 0;
 }
 
+static void
+hns3_update_function_rpu_drop_stats(struct hns3_hw *hw)
+{
+	struct hns3_rx_missed_stats *stats = &hw->imissed_stats;
+
+	stats->rpu_rx_drop_cnt += hns3_read_dev(hw, HNS3_RPU_DROP_CNT_REG);
+}
+
+static int
+hns3_update_rpu_drop_stats(struct hns3_hw *hw)
+{
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	int ret = 0;
+
+	if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && !hns->is_vf)
+		ret = hns3_update_port_rpu_drop_stats(hw);
+	else if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2)
+		hns3_update_function_rpu_drop_stats(hw);
+
+	return ret;
+}
+
+static int
+hns3_get_ssu_drop_stats(struct hns3_hw *hw, struct hns3_cmd_desc *desc,
+			int bd_num, bool is_rx)
+{
+	struct hns3_query_ssu_cmd *req;
+	int ret;
+	int i;
+
+	for (i = 0; i < bd_num - 1; i++) {
+		hns3_cmd_setup_basic_desc(&desc[i],
+					  HNS3_OPC_SSU_DROP_REG, true);
+		desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
+	}
+	hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_SSU_DROP_REG, true);
+	req = (struct hns3_query_ssu_cmd *)desc[0].data;
+	req->rxtx = is_rx ? 0 : 1;
+	ret = hns3_cmd_send(hw, desc, bd_num);
+
+	return ret;
+}
+
+static int
+hns3_update_port_rx_ssu_drop_stats(struct hns3_hw *hw)
+{
+	struct hns3_rx_missed_stats *stats = &hw->imissed_stats;
+	struct hns3_cmd_desc desc[HNS3_OPC_SSU_DROP_REG_NUM];
+	struct hns3_query_ssu_cmd *req;
+	uint64_t cnt;
+	int ret;
+
+	ret = hns3_get_ssu_drop_stats(hw, desc, HNS3_OPC_SSU_DROP_REG_NUM,
+				      true);
+	if (ret) {
+		hns3_err(hw, "failed to get Rx SSU drop stats, ret = %d", ret);
+		return ret;
+	}
+
+	req = (struct hns3_query_ssu_cmd *)desc[0].data;
+	cnt = rte_le_to_cpu_32(req->full_drop_cnt) +
+		rte_le_to_cpu_32(req->part_drop_cnt);
+
+	stats->ssu_rx_drop_cnt += cnt;
+
+	return 0;
+}
+
 int
 hns3_update_imissed_stats(struct hns3_hw *hw, bool is_clear)
 {
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
 	int ret;
 
+	if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && hns->is_vf)
+		return 0;
+
+	if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2 && !hns->is_vf) {
+		ret = hns3_update_port_rx_ssu_drop_stats(hw);
+		if (ret)
+			return ret;
+	}
+
 	ret = hns3_update_rpu_drop_stats(hw);
 	if (ret)
 		return ret;
@@ -488,19 +567,17 @@ hns3_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *rte_stats)
 	uint16_t i;
 	int ret;
 
-	if (!hns->is_vf) {
-		/* Update imissed stats */
-		ret = hns3_update_imissed_stats(hw, false);
-		if (ret) {
-			hns3_err(hw, "update imissed stats failed, ret = %d",
-				 ret);
-			return ret;
-		}
-
-		rte_stats->imissed = imissed_stats->rpu_rx_drop_cnt;
+	/* Update imissed stats */
+	ret = hns3_update_imissed_stats(hw, false);
+	if (ret) {
+		hns3_err(hw, "update imissed stats failed, ret = %d",
+			 ret);
+		return ret;
 	}
+	rte_stats->imissed = imissed_stats->rpu_rx_drop_cnt +
+				imissed_stats->ssu_rx_drop_cnt;
 
-	/* Reads all the stats of a rxq in a loop to keep them synchronized */
+	/* Get the error stats and bytes of received packets */
 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
 		rxq = eth_dev->data->rx_queues[i];
 		if (rxq == NULL)
@@ -556,17 +633,14 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev)
 	uint16_t i;
 	int ret;
 
-	if (!hns->is_vf) {
-		/*
-		 * Note: Reading hardware statistics of imissed registers will
-		 * clear them.
-		 */
-		ret = hns3_update_imissed_stats(hw, true);
-		if (ret) {
-			hns3_err(hw, "clear imissed stats failed, ret = %d",
-				 ret);
-			return ret;
-		}
+	/*
+	 * Note: Reading hardware statistics of imissed registers will
+	 * clear them.
+	 */
+	ret = hns3_update_imissed_stats(hw, true);
+	if (ret) {
+		hns3_err(hw, "clear imissed stats failed, ret = %d", ret);
+		return ret;
 	}
 
 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
@@ -630,6 +704,22 @@ hns3_mac_stats_reset(__rte_unused struct rte_eth_dev *dev)
 	return 0;
 }
 
+static int
+hns3_get_imissed_stats_num(struct hns3_adapter *hns)
+{
+#define NO_IMISSED_STATS_NUM   0
+#define RPU_STATS_ITEM_NUM     1
+	struct hns3_hw *hw = &hns->hw;
+
+	if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE1 && hns->is_vf)
+		return NO_IMISSED_STATS_NUM;
+
+	if (hw->drop_stats_mode == HNS3_PKTS_DROP_STATS_MODE2 && !hns->is_vf)
+		return HNS3_NUM_IMISSED_XSTATS;
+
+	return RPU_STATS_ITEM_NUM;
+}
+
 /* This function calculates the number of xstats based on the current config */
 static int
 hns3_xstats_calc_num(struct rte_eth_dev *dev)
@@ -647,13 +737,17 @@ hns3_xstats_calc_num(struct rte_eth_dev *dev)
 	uint16_t nb_tx_q = dev->data->nb_tx_queues;
 	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;
+	int stats_num;
+
+	stats_num = rx_comm_stats_num + tx_comm_stats_num;
+	stats_num += hns3_get_imissed_stats_num(hns);
 
 	if (hns->is_vf)
-		return rx_comm_stats_num + tx_comm_stats_num +
-			HNS3_NUM_RESET_XSTATS;
+		stats_num += HNS3_NUM_RESET_XSTATS;
 	else
-		return rx_comm_stats_num + tx_comm_stats_num +
-			HNS3_FIX_NUM_STATS;
+		stats_num += HNS3_FIX_NUM_STATS;
+
+	return stats_num;
 }
 
 static void
@@ -835,6 +929,31 @@ hns3_tqp_basic_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 	hns3_txq_basic_stats_get(dev, xstats, count);
 }
 
+static void
+hns3_imissed_stats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
+			  int *count)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	struct hns3_hw *hw = &hns->hw;
+	struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats;
+	int imissed_stats_num;
+	int cnt = *count;
+	char *addr;
+	uint16_t i;
+
+	imissed_stats_num = hns3_get_imissed_stats_num(hns);
+
+	for (i = 0; i < imissed_stats_num; i++) {
+		addr = (char *)imissed_stats +
+			hns3_imissed_stats_strings[i].offset;
+		xstats[cnt].value = *(uint64_t *)addr;
+		xstats[cnt].id = cnt;
+		cnt++;
+	}
+
+	*count = cnt;
+}
+
 /*
  * Retrieve extended(tqp | Mac) statistics of an Ethernet device.
  * @param dev
@@ -854,7 +973,6 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 {
 	struct hns3_adapter *hns = dev->data->dev_private;
 	struct hns3_hw *hw = &hns->hw;
-	struct hns3_rx_missed_stats *imissed_stats = &hw->imissed_stats;
 	struct hns3_mac_stats *mac_stats = &hw->mac_stats;
 	struct hns3_reset_stats *reset_stats = &hw->reset.stats;
 	struct hns3_rx_bd_errors_stats *rx_err_stats;
@@ -890,24 +1008,17 @@ hns3_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
 			xstats[count].id = count;
 			count++;
 		}
+	}
 
-		ret = hns3_update_imissed_stats(hw, false);
-		if (ret) {
-			hns3_err(hw, "update imissed stats failed, ret = %d",
-				 ret);
-			return ret;
-		}
-
-		for (i = 0; i < HNS3_NUM_IMISSED_XSTATS; i++) {
-			addr = (char *)imissed_stats +
-				hns3_imissed_stats_strings[i].offset;
-			xstats[count].value = *(uint64_t *)addr;
-			xstats[count].id = count;
-			count++;
-		}
-
+	ret = hns3_update_imissed_stats(hw, false);
+	if (ret) {
+		hns3_err(hw, "update imissed stats failed, ret = %d",
+			 ret);
+		return ret;
 	}
 
+	hns3_imissed_stats_get(dev, xstats, &count);
+
 	/* Get the reset stat */
 	for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
 		addr = (char *)reset_stats + hns3_reset_stats_strings[i].offset;
@@ -992,6 +1103,28 @@ hns3_tqp_dfx_stats_name_get(struct rte_eth_dev *dev,
 	}
 }
 
+static void
+hns3_imissed_stats_name_get(struct rte_eth_dev *dev,
+			    struct rte_eth_xstat_name *xstats_names,
+			    uint32_t *count)
+{
+	struct hns3_adapter *hns = dev->data->dev_private;
+	uint32_t cnt = *count;
+	int imissed_stats_num;
+	uint16_t i;
+
+	imissed_stats_num = hns3_get_imissed_stats_num(hns);
+
+	for (i = 0; i < imissed_stats_num; i++) {
+		snprintf(xstats_names[cnt].name,
+			 sizeof(xstats_names[cnt].name),
+			 "%s", hns3_imissed_stats_strings[i].name);
+		cnt++;
+	}
+
+	*count = cnt;
+}
+
 /*
  * Retrieve names of extended statistics of an Ethernet device.
  *
@@ -1040,14 +1173,10 @@ hns3_dev_xstats_get_names(struct rte_eth_dev *dev,
 				 "%s", hns3_mac_strings[i].name);
 			count++;
 		}
-
-		for (i = 0; i < HNS3_NUM_IMISSED_XSTATS; i++) {
-			snprintf(xstats_names[count].name,
-				 sizeof(xstats_names[count].name),
-				 "%s", hns3_imissed_stats_strings[i].name);
-			count++;
-		}
 	}
+
+	hns3_imissed_stats_name_get(dev, xstats_names, &count);
+
 	for (i = 0; i < HNS3_NUM_RESET_XSTATS; i++) {
 		snprintf(xstats_names[count].name,
 			 sizeof(xstats_names[count].name),
diff --git a/drivers/net/hns3/hns3_stats.h b/drivers/net/hns3/hns3_stats.h
index 8ea69b4..273be42 100644
--- a/drivers/net/hns3/hns3_stats.h
+++ b/drivers/net/hns3/hns3_stats.h
@@ -112,6 +112,7 @@ struct hns3_mac_stats {
 
 struct hns3_rx_missed_stats {
 	uint64_t rpu_rx_drop_cnt;
+	uint64_t ssu_rx_drop_cnt;
 };
 
 /* store statistics names and its offset in stats structure */
-- 
2.7.4



More information about the dev mailing list