[dpdk-dev,5/7] net/bnxt: fix automatic clearing of VF stats

Message ID 20170629025142.19404-6-ajit.khaparde@broadcom.com (mailing list archive)
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/checkpatch success coding style OK

Commit Message

Ajit Khaparde June 29, 2017, 2:51 a.m. UTC
  Add code to avoid automatic clearing of VF stats on a function
reset or a stat context free.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |  1 +
 drivers/net/bnxt/bnxt_hwrm.c           |  5 +--
 drivers/net/bnxt/bnxt_hwrm.h           |  3 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h |  9 ++++++
 drivers/net/bnxt/rte_pmd_bnxt.c        | 59 +++++++++++++++++++++++++++++++---
 drivers/net/bnxt/rte_pmd_bnxt.h        | 18 +++++++++++
 6 files changed, 88 insertions(+), 7 deletions(-)
  

Comments

Ferruh Yigit June 29, 2017, 10:53 a.m. UTC | #1
On 6/29/2017 3:51 AM, Ajit Khaparde wrote:
> Add code to avoid automatic clearing of VF stats on a function
> reset or a stat context free.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

<...>

> +
> +/**
> + * Enable/Disable VF statistics retention
> + *
> + * @param port
> + *    The port identifier of the Ethernet device.
> + * @param vf
> + *   VF id.
> + * @param on
> + *    1 - Prevent VF statistics from automatically resetting
> + *    0 - Allow VF statistics to automatically reset
> + *
> + * @return
> + *   - (0) if successful.
> + *   - (-ENODEV) if *port* invalid.
> + *   - (-EINVAL) if bad parameter.
> + */
> +int rte_pmd_bnxt_set_vf_persist_stats(uint8_t port, uint16_t vf, uint8_t on);
>  #endif /* _PMD_BNXT_H_ */
> 

This patch adds a new PMD specific API, .map file should be updated too
for shared library builds.

This is not easy to catch because API not used anywhere, what do you
think updating testpmd to use this API, which also lets testing the API?
  

Patch

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index d39baf1..44b1ac5 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -109,6 +109,7 @@  struct bnxt_child_vf_info {
 	uint8_t			mac_spoof_en;
 	uint8_t			vlan_spoof_en;
 	bool			random_mac;
+	bool			persist_stats;
 };
 
 struct bnxt_pf_info {
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index eccfe7f..3d2d408 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2367,7 +2367,8 @@  int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 	return rc;
 }
 
-int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf)
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf,
+					uint32_t flags)
 {
 	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
 	struct hwrm_func_cfg_input req = {0};
@@ -2375,7 +2376,7 @@  int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf)
 
 	HWRM_PREP(req, FUNC_CFG, -1, resp);
 	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
-	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.flags = rte_cpu_to_le_32(flags);
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 	HWRM_CHECK_RESULT;
 
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 82cca3a..dd0999a 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -142,7 +142,8 @@  int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
-int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf,
+					uint32_t flags);
 void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp);
 int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_vf_vnic_count(struct bnxt *bp, uint16_t vf);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index c2335d0..1eb8d33 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -3190,6 +3190,15 @@  struct hwrm_func_cfg_input {
 	 * command will be persistent over warm boot.
 	 */
 	#define HWRM_FUNC_CFG_INPUT_FLAGS_VIRT_MAC_PERSIST	UINT32_C(0x800)
+	/*
+	 * This bit only applies to the VF. If this bit is set, the
+	 * statistic context counters will not be cleared when the
+	 * statistic context is freed or a function reset is called on
+	 * VF. This bit will be cleared when the PF is unloaded or a
+	 * function reset is called on the PF.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC	\
+		UINT32_C(0x1000)
 	uint32_t enables;
 	/* This bit must be '1' for the mtu field to be configured. */
 	#define HWRM_FUNC_CFG_INPUT_ENABLES_MTU	UINT32_C(0x1)
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 1bd5aee..1903101 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -274,6 +274,8 @@  int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
 		return 0;
 
 	func_flags = bp->pf.vf_info[vf].func_cfg_flags;
+	func_flags &= ~(HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE |
+	    HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE);
 
 	if (on)
 		func_flags |=
@@ -282,11 +284,11 @@  int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
 		func_flags |=
 			HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE;
 
-	bp->pf.vf_info[vf].func_cfg_flags = func_flags;
-
-	rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf);
-	if (!rc)
+	rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags);
+	if (!rc) {
 		bp->pf.vf_info[vf].mac_spoof_en = on;
+		bp->pf.vf_info[vf].func_cfg_flags = func_flags;
+	}
 
 	return rc;
 }
@@ -754,3 +756,52 @@  rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
 
 	return rc;
 }
+
+int rte_pmd_bnxt_set_vf_persist_stats(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_dev *dev;
+	uint32_t func_flags;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set persist stats on non-PF port %d!\n",
+			port);
+		return -EINVAL;
+	}
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	/* Prev setting same as new setting. */
+	if (on == bp->pf.vf_info[vf].persist_stats)
+		return 0;
+
+	func_flags = bp->pf.vf_info[vf].func_cfg_flags;
+
+	if (on)
+		func_flags |=
+			HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC;
+	else
+		func_flags &=
+			~HWRM_FUNC_CFG_INPUT_FLAGS_NO_AUTOCLEAR_STATISTIC;
+
+	rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf, func_flags);
+	if (!rc) {
+		bp->pf.vf_info[vf].persist_stats = on;
+		bp->pf.vf_info[vf].func_cfg_flags = func_flags;
+	}
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 964aa97..c4c4770 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -333,4 +333,22 @@  int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
  */
 int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *mac_addr,
 				uint32_t vf_id);
+
+/**
+ * Enable/Disable VF statistics retention
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param on
+ *    1 - Prevent VF statistics from automatically resetting
+ *    0 - Allow VF statistics to automatically reset
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_persist_stats(uint8_t port, uint16_t vf, uint8_t on);
 #endif /* _PMD_BNXT_H_ */