[15/20] net/bnxt: delete VF FW rules when a representor is created

Message ID 20200723111329.21855-16-somnath.kotur@broadcom.com (mailing list archive)
State Superseded, archived
Delegated to: Ajit Khaparde
Headers
Series bnxt patches |

Checks

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

Commit Message

Somnath Kotur July 23, 2020, 11:13 a.m. UTC
  From: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>

Truflow stack adds VFR to VF and VF to VFR conduits when VF
representor is created. However, in the ingress direction the
VF's fw rules conflict with Truflow rules, resulting in not hitting
the Truflow VFR rules. To fix this, fw is going to remove it’s
VF rules when vf representor is created in Truflow mode and will
restore the removed rules when vf representor is destroyed.

This patch invokes the vf representor alloc and free hwrm commands
as part of which fw will do the above mentioned actions.

Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Shahaji Bhosle <shahaji.bhosle@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  49 ++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   2 +
 drivers/net/bnxt/bnxt_reps.c           |  19 ++++-
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 138 +++++++++++++++++++++++++++++++++
 4 files changed, 205 insertions(+), 3 deletions(-)
  

Patch

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 7ea13a8..f5f0dfe 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -5486,6 +5486,55 @@  int bnxt_hwrm_cfa_counter_qstats(struct bnxt *bp,
 	return 0;
 }
 
+int bnxt_hwrm_cfa_vfr_alloc(struct bnxt *bp, uint16_t vf_idx)
+{
+	struct hwrm_cfa_vfr_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_cfa_vfr_alloc_input req = {0};
+	int rc;
+
+	if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) {
+		PMD_DRV_LOG(DEBUG,
+			    "Not a PF or trusted VF. Command not supported\n");
+		return 0;
+	}
+
+	HWRM_PREP(&req, HWRM_CFA_VFR_ALLOC, BNXT_USE_CHIMP_MB);
+	req.vf_id = rte_cpu_to_le_16(vf_idx);
+	snprintf(req.vfr_name, sizeof(req.vfr_name), "%svfr%d",
+		 bp->eth_dev->data->name, vf_idx);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+	HWRM_CHECK_RESULT();
+
+	HWRM_UNLOCK();
+	PMD_DRV_LOG(DEBUG, "VFR %d allocated\n", vf_idx);
+	return rc;
+}
+
+int bnxt_hwrm_cfa_vfr_free(struct bnxt *bp, uint16_t vf_idx)
+{
+	struct hwrm_cfa_vfr_free_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_cfa_vfr_free_input req = {0};
+	int rc;
+
+	if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) {
+		PMD_DRV_LOG(DEBUG,
+			    "Not a PF or trusted VF. Command not supported\n");
+		return 0;
+	}
+
+	HWRM_PREP(&req, HWRM_CFA_VFR_FREE, BNXT_USE_CHIMP_MB);
+	req.vf_id = rte_cpu_to_le_16(vf_idx);
+	snprintf(req.vfr_name, sizeof(req.vfr_name), "%svfr%d",
+		 bp->eth_dev->data->name, vf_idx);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+	HWRM_CHECK_RESULT();
+	HWRM_UNLOCK();
+	PMD_DRV_LOG(DEBUG, "VFR %d freed\n", vf_idx);
+	return rc;
+}
+
 #ifdef RTE_LIBRTE_BNXT_PMD_SYSTEM
 int
 bnxt_hwrm_oem_cmd(struct bnxt *bp, uint32_t entry_num)
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 01201a7..4a2af13 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -278,4 +278,6 @@  int bnxt_hwrm_port_phy_qcaps(struct bnxt *bp);
 int bnxt_hwrm_oem_cmd(struct bnxt *bp, uint32_t entry_num);
 int bnxt_clear_one_vnic_filter(struct bnxt *bp,
 			       struct bnxt_filter_info *filter);
+int bnxt_hwrm_cfa_vfr_alloc(struct bnxt *bp, uint16_t vf_idx);
+int bnxt_hwrm_cfa_vfr_free(struct bnxt *bp, uint16_t vf_idx);
 #endif
diff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c
index c425e69..2f775e0 100644
--- a/drivers/net/bnxt/bnxt_reps.c
+++ b/drivers/net/bnxt/bnxt_reps.c
@@ -272,7 +272,7 @@  static int bnxt_tf_vfr_alloc(struct rte_eth_dev *vfr_ethdev)
 	if (rc) {
 		BNXT_TF_DBG(DEBUG,
 			    "Default flow rule creation for VFR->VF failed!\n");
-		return -EIO;
+		goto err;
 	}
 
 	BNXT_TF_DBG(DEBUG, "*** Default flow rule created for VFR->VF! ***\n");
@@ -283,7 +283,7 @@  static int bnxt_tf_vfr_alloc(struct rte_eth_dev *vfr_ethdev)
 	if (rc) {
 		BNXT_TF_DBG(DEBUG,
 			    "Failed to get action_ptr for VFR->VF dflt rule\n");
-		return -EIO;
+		goto rep2vf_free;
 	}
 	BNXT_TF_DBG(DEBUG, "tx_cfa_action = %d\n", vfr->vfr_tx_cfa_action);
 	rc = ulp_default_flow_create(parent_dev, param_list,
@@ -292,13 +292,24 @@  static int bnxt_tf_vfr_alloc(struct rte_eth_dev *vfr_ethdev)
 	if (rc) {
 		BNXT_TF_DBG(DEBUG,
 			    "Default flow rule creation for VF->VFR failed!\n");
-		return -EIO;
+		goto rep2vf_free;
 	}
 
 	BNXT_TF_DBG(DEBUG, "*** Default flow rule created for VF->VFR! ***\n");
 	BNXT_TF_DBG(DEBUG, "vfr2rep_flow_id = %d\n", vfr->vf2rep_flow_id);
 
+	rc = bnxt_hwrm_cfa_vfr_alloc(parent_bp, vfr->vf_id);
+	if (rc)
+		goto vf2rep_free;
+
 	return 0;
+
+vf2rep_free:
+	ulp_default_flow_destroy(vfr->parent_dev, vfr->vf2rep_flow_id);
+rep2vf_free:
+	ulp_default_flow_destroy(vfr->parent_dev, vfr->rep2vf_flow_id);
+err:
+	return -EIO;
 }
 
 static int bnxt_vfr_alloc(struct rte_eth_dev *vfr_ethdev)
@@ -414,6 +425,8 @@  static int bnxt_vfr_free(struct bnxt_vf_representor *vfr)
 	vfr->vfr_tx_cfa_action = 0;
 	vfr->rx_cfa_code = 0;
 
+	rc = bnxt_hwrm_cfa_vfr_free(parent_bp, vfr->vf_id);
+
 	return rc;
 }
 
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 598da71..3553935 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -35127,6 +35127,144 @@  struct hwrm_cfa_pair_info_output {
 	uint8_t	valid;
 } __rte_packed;
 
+/**********************
+ * hwrm_cfa_vfr_alloc *
+ **********************/
+
+
+/* hwrm_cfa_vfr_alloc_input (size:448b/56B) */
+struct hwrm_cfa_vfr_alloc_input {
+	/* The HWRM command request type. */
+	uint16_t	req_type;
+	/*
+	 * The completion ring to send the completion event on. This should
+	 * be the NQ ID returned from the `nq_alloc` HWRM command.
+	 */
+	uint16_t	cmpl_ring;
+	/*
+	 * The sequence ID is used by the driver for tracking multiple
+	 * commands. This ID is treated as opaque data by the firmware and
+	 * the value is returned in the `hwrm_resp_hdr` upon completion.
+	 */
+	uint16_t	seq_id;
+	/*
+	 * The target ID of the command:
+	 * * 0x0-0xFFF8 - The function ID
+	 * * 0xFFF8-0xFFFC, 0xFFFE - Reserved for internal processors
+	 * * 0xFFFD - Reserved for user-space HWRM interface
+	 * * 0xFFFF - HWRM
+	 */
+	uint16_t	target_id;
+	/*
+	 * A physical address pointer pointing to a host buffer that the
+	 * command's response data will be written. This can be either a host
+	 * physical address (HPA) or a guest physical address (GPA) and must
+	 * point to a physically contiguous block of memory.
+	 */
+	uint64_t	resp_addr;
+	/* Logical VF number (range: 0 -> MAX_VFS -1). */
+	uint16_t	vf_id;
+	/*
+	 * This field is reserved for the future use.
+	 * It shall be set to 0.
+	 */
+	uint16_t	reserved;
+	uint8_t	unused_0[4];
+	/* VF Representor name (32 byte string). */
+	char	vfr_name[32];
+} __attribute__((packed));
+
+/* hwrm_cfa_vfr_alloc_output (size:128b/16B) */
+struct hwrm_cfa_vfr_alloc_output {
+	/* The specific error status for the command. */
+	uint16_t	error_code;
+	/* The HWRM command request type. */
+	uint16_t	req_type;
+	/* The sequence ID from the original command. */
+	uint16_t	seq_id;
+	/* The length of the response data in number of bytes. */
+	uint16_t	resp_len;
+	/* Rx CFA code. */
+	uint16_t	rx_cfa_code;
+	/* Tx CFA action. */
+	uint16_t	tx_cfa_action;
+	uint8_t	unused_0[3];
+	/*
+	 * This field is used in Output records to indicate that the output
+	 * is completely written to RAM.  This field should be read as '1'
+	 * to indicate that the output has been completely written.
+	 * When writing a command completion or response to an internal processor,
+	 * the order of writes has to be such that this field is written last.
+	 */
+	uint8_t	valid;
+} __attribute__((packed));
+
+/*********************
+ * hwrm_cfa_vfr_free *
+ *********************/
+
+
+/* hwrm_cfa_vfr_free_input (size:448b/56B) */
+struct hwrm_cfa_vfr_free_input {
+	/* The HWRM command request type. */
+	uint16_t	req_type;
+	/*
+	 * The completion ring to send the completion event on. This should
+	 * be the NQ ID returned from the `nq_alloc` HWRM command.
+	 */
+	uint16_t	cmpl_ring;
+	/*
+	 * The sequence ID is used by the driver for tracking multiple
+	 * commands. This ID is treated as opaque data by the firmware and
+	 * the value is returned in the `hwrm_resp_hdr` upon completion.
+	 */
+	uint16_t	seq_id;
+	/*
+	 * The target ID of the command:
+	 * * 0x0-0xFFF8 - The function ID
+	 * * 0xFFF8-0xFFFC, 0xFFFE - Reserved for internal processors
+	 * * 0xFFFD - Reserved for user-space HWRM interface
+	 * * 0xFFFF - HWRM
+	 */
+	uint16_t	target_id;
+	/*
+	 * A physical address pointer pointing to a host buffer that the
+	 * command's response data will be written. This can be either a host
+	 * physical address (HPA) or a guest physical address (GPA) and must
+	 * point to a physically contiguous block of memory.
+	 */
+	uint64_t	resp_addr;
+	/* VF Representor name (32 byte string). */
+	char		vfr_name[32];
+	/* Logical VF number (range: 0 -> MAX_VFS -1). */
+	uint16_t	vf_id;
+	uint16_t	reserved;
+	uint8_t		unused_0[4];
+} __attribute__((packed));
+
+/* hwrm_cfa_vfr_free_output (size:128b/16B) */
+struct hwrm_cfa_vfr_free_output {
+	/* The specific error status for the command. */
+	uint16_t	error_code;
+	/* The HWRM command request type. */
+	uint16_t	req_type;
+	/* The sequence ID from the original command. */
+	uint16_t	seq_id;
+	/* The length of the response data in number of bytes. */
+	uint16_t	resp_len;
+	uint8_t	unused_0[7];
+	/*
+	 * This field is used in Output records to indicate that the output
+	 * is completely written to RAM.  This field should be read as '1'
+	 * to indicate that the output has been completely written.
+	 * When writing a command completion or response to an internal processor,
+	 * the order of writes has to be such that this field is written last.
+	 */
+	uint8_t	valid;
+} __attribute__((packed));
+
+
+
 /***************************************
  * hwrm_cfa_redirect_query_tunnel_type *
  ***************************************/