@@ -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)
@@ -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
@@ -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;
}
@@ -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 *
***************************************/