[dpdk-dev,v4,21/26] net/bnxt: add support to get and clear VF specific stats

Message ID 20170601170723.48709-22-ajit.khaparde@broadcom.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail apply patch file failure

Commit Message

Ajit Khaparde June 1, 2017, 5:07 p.m. UTC
  This patch adds code to get and clear VF stats.
It also adds the necessary HWRM structures to send the command
to the firmware.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
  - Move the PF related MAC/VLAN anti spoof counter to xstats.
---
 app/test-pmd/cmdline.c                    | 23 +++++++--
 drivers/net/bnxt/bnxt_hwrm.c              | 38 ++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  3 ++
 drivers/net/bnxt/bnxt_stats.c             | 60 +++++++++++++++++++++-
 drivers/net/bnxt/rte_pmd_bnxt.c           | 83 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 52 +++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  3 ++
 7 files changed, 255 insertions(+), 7 deletions(-)
  

Patch

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 90e4a27..f49d83b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -13079,9 +13079,16 @@  cmd_show_vf_stats_parsed(
 	memset(&stats, 0, sizeof(stats));
 
 #ifdef RTE_LIBRTE_I40E_PMD
-	ret = rte_pmd_i40e_get_vf_stats(res->port_id,
-					res->vf_id,
-					&stats);
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_get_vf_stats(res->port_id,
+						res->vf_id,
+						&stats);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_get_vf_stats(res->port_id,
+						res->vf_id,
+						&stats);
 #endif
 
 	switch (ret) {
@@ -13177,8 +13184,14 @@  cmd_clear_vf_stats_parsed(
 		return;
 
 #ifdef RTE_LIBRTE_I40E_PMD
-	ret = rte_pmd_i40e_reset_vf_stats(res->port_id,
-					  res->vf_id);
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_reset_vf_stats(res->port_id,
+						  res->vf_id);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_reset_vf_stats(res->port_id,
+						  res->vf_id);
 #endif
 
 	switch (ret) {
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index f143541..6ea31ca 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1237,6 +1237,27 @@  int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 	return rc;
 }
 
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+				  uint64_t *dropped)
+{
+	int rc = 0;
+	struct hwrm_func_qstats_input req = {.req_type = 0};
+	struct hwrm_func_qstats_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, FUNC_QSTATS, -1, resp);
+
+	req.fid = rte_cpu_to_le_16(fid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	if (dropped)
+		*dropped = rte_le_to_cpu_64(resp->tx_drop_pkts);
+
+	return rc;
+}
+
 int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 			  struct rte_eth_stats *stats)
 {
@@ -1274,6 +1295,23 @@  int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 	return rc;
 }
 
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid)
+{
+	int rc = 0;
+	struct hwrm_func_clr_stats_input req = {.req_type = 0};
+	struct hwrm_func_clr_stats_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, FUNC_CLR_STATS, -1, resp);
+
+	req.fid = rte_cpu_to_le_16(fid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 /*
  * HWRM utility functions
  */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index f51ebcf..5aaf947 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -66,6 +66,9 @@  int bnxt_hwrm_func_reset(struct bnxt *bp);
 int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 			  struct rte_eth_stats *stats);
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+				  uint64_t *dropped);
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid);
 int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp);
 int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index ade8195..d7d0e35 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -165,6 +165,49 @@  static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
 				tx_bytes)},
 };
 
+static const struct bnxt_xstats_name_off bnxt_func_stats_strings[] = {
+	{"tx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_ucast_pkts)},
+	{"tx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_mcast_pkts)},
+	{"tx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_bcast_pkts)},
+	{"tx_err_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_err_pkts)},
+	{"tx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_drop_pkts)},
+	{"tx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
+				tx_ucast_bytes)},
+	{"tx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				tx_mcast_bytes)},
+	{"tx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				tx_bcast_bytes)},
+	{"rx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_ucast_pkts)},
+	{"rx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_mcast_pkts)},
+	{"rx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_bcast_pkts)},
+	{"rx_err_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_err_pkts)},
+	{"rx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_drop_pkts)},
+	{"rx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_ucast_bytes)},
+	{"rx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_mcast_bytes)},
+	{"rx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_bcast_bytes)},
+	{"rx_agg_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_pkts)},
+	{"rx_agg_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_bytes)},
+	{"rx_agg_events", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_events)},
+	{"rx_agg_aborts", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_aborts)},
+};
+
 /*
  * Statistics functions
  */
@@ -224,6 +267,7 @@  int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
 
 	unsigned int count, i;
+	uint64_t tx_drop_pkts;
 
 	if (!(bp->flags & BNXT_FLAG_PORT_STATS)) {
 		RTE_LOG(ERR, PMD, "xstats not supported for VF\n");
@@ -231,9 +275,10 @@  int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 	}
 
 	bnxt_hwrm_port_qstats(bp);
+	bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, &tx_drop_pkts);
 
 	count = RTE_DIM(bnxt_rx_stats_strings) +
-		RTE_DIM(bnxt_tx_stats_strings);
+		RTE_DIM(bnxt_tx_stats_strings) + 1; /* For tx_drop_pkts */
 
 	if (n < count)
 		return count;
@@ -255,6 +300,10 @@  int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 		count++;
 	}
 
+	/* The Tx drop pkts aka the Anti spoof coounter */
+	xstats[count].value = rte_le_to_cpu_64(tx_drop_pkts);
+	count++;
+
 	return count;
 }
 
@@ -262,8 +311,9 @@  int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
 	struct rte_eth_xstat_name *xstats_names,
 	__rte_unused unsigned int limit)
 {
+	/* Account for the Tx drop pkts aka the Anti spoof counter */
 	const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
-				RTE_DIM(bnxt_tx_stats_strings);
+				RTE_DIM(bnxt_tx_stats_strings) + 1;
 	unsigned int i, count;
 
 	if (xstats_names != NULL) {
@@ -284,6 +334,12 @@  int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
 				bnxt_tx_stats_strings[i].name);
 			count++;
 		}
+
+		snprintf(xstats_names[count].name,
+				sizeof(xstats_names[count].name),
+				"%s",
+				bnxt_func_stats_strings[4].name);
+		count++;
 	}
 	return stat_cnt;
 }
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 644a890..ebe95b6 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -459,3 +459,86 @@  int rte_pmd_bnxt_set_vf_vlan_filter(uint8_t port, uint16_t vlan,
 
 	return rc;
 }
+
+int rte_pmd_bnxt_get_vf_stats(uint8_t port,
+			      uint16_t vf_id,
+			      struct rte_eth_stats *stats)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to get VF %d stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_qstats(bp, bp->pf.first_vf_id + vf_id, stats);
+}
+
+int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
+				uint16_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to reset VF %d stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id);
+}
+
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
+				      uint64_t *count)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to query VF %d TX drops on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
+					     count);
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 024620f..7bfd376 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -165,6 +165,41 @@  int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
 				uint16_t tx_rate, uint64_t q_msk);
 
 /**
+ * Get VF's statistics
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @param stats
+ *    A pointer to a structure of type *rte_eth_stats* to be filled with
+ *    the values of device counters supported statistics:
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+
+int rte_pmd_bnxt_get_vf_stats(uint8_t port,
+			      uint16_t vf_id,
+			      struct rte_eth_stats *stats);
+
+/**
+ * Clear VF's statistics
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
+				uint16_t vf_id);
+
+/**
  * Enable/Disable VF VLAN anti spoof
  *
  * @param port
@@ -181,4 +216,21 @@  int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
  *   - (-EINVAL) if bad parameter.
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Queries the TX drop counter for the function
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @param count
+ *    Pointer to a uint64_t that will be populated with the counter value.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ *   - (-EINVAL) invalid vf_id specified.
+ *   - (-ENOTSUP) Ethernet device is not a PF
+ */
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
+				      uint64_t *count);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 770b076..f0eda7b 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -9,6 +9,9 @@  DPDK_17.08 {
 	rte_pmd_bnxt_set_vf_vlan_stripq;
 	rte_pmd_bnxt_set_vf_vlan_filter;
 	rte_pmd_bnxt_set_vf_vlan_anti_spoof;
+	rte_pmd_bnxt_get_vf_stats;
+	rte_pmd_bnxt_reset_vf_stats;
+	rte_pmd_bnxt_get_vf_tx_drop_count;
 
 	local: *;
 };