+static int bnxt_tf_vfr_alloc(struct rte_eth_dev *vfr_ethdev)
+{
+ int rc;
+ struct bnxt_vf_representor *vfr = vfr_ethdev->data->dev_private;
+ struct rte_eth_dev *parent_dev = vfr->parent_dev;
+ struct bnxt *parent_bp = parent_dev->data->dev_private;
+ uint16_t vfr_port_id = vfr_ethdev->data->port_id;
+ struct ulp_tlv_param param_list[] = {
+ {
+ .type = BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID,
+ .length = 2,
+ .value = {(vfr_port_id >> 8) & 0xff, vfr_port_id & 0xff}
+ },
+ {
+ .type = BNXT_ULP_DF_PARAM_TYPE_LAST,
+ .length = 0,
+ .value = {0}
+ }
+ };
+
+ ulp_port_db_dev_port_intf_update(parent_bp->ulp_ctx, vfr_ethdev);
+
+ rc = ulp_default_flow_create(parent_dev, param_list,
+ BNXT_ULP_DF_TPL_VFREP_TO_VF,
+ &vfr->rep2vf_flow_id);
+ if (rc) {
+ BNXT_TF_DBG(DEBUG,
+ "Default flow rule creation for VFR->VF failed!\n");
+ goto err;
+ }
+
+ BNXT_TF_DBG(DEBUG, "*** Default flow rule created for VFR->VF! ***\n");
+ BNXT_TF_DBG(DEBUG, "rep2vf_flow_id = %d\n", vfr->rep2vf_flow_id);
+ rc = ulp_default_flow_db_cfa_action_get(parent_bp->ulp_ctx,
+ vfr->rep2vf_flow_id,
+ &vfr->vfr_tx_cfa_action);
+ if (rc) {
+ BNXT_TF_DBG(DEBUG,
+ "Failed to get action_ptr for VFR->VF dflt rule\n");
+ 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,
+ BNXT_ULP_DF_TPL_VF_TO_VFREP,
+ &vfr->vf2rep_flow_id);
+ if (rc) {
+ BNXT_TF_DBG(DEBUG,
+ "Default flow rule creation for VF->VFR failed!\n");
+ 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)
+{
+ int rc = 0;
+ struct bnxt_vf_representor *vfr = vfr_ethdev->data->dev_private;
+
+ if (!vfr || !vfr->parent_dev) {
+ PMD_DRV_LOG(ERR,
+ "No memory allocated for representor\n");
+ return -ENOMEM;
+ }
+
+ /* Check if representor has been already allocated in FW */
+ if (vfr->vfr_tx_cfa_action)
+ return 0;
+
+ /*
+ * Alloc VF rep rules in CFA after default VNIC is created.
+ * Otherwise the FW will create the VF-rep rules with
+ * default drop action.
+ */
+ rc = bnxt_tf_vfr_alloc(vfr_ethdev);
+ if (!rc)
+ PMD_DRV_LOG(DEBUG, "allocated representor %d in FW\n",
+ vfr->vf_id);
+ else
+ PMD_DRV_LOG(ERR,
+ "Failed to alloc representor %d in FW\n",
+ vfr->vf_id);
+
+ return rc;
+}
+
+static void bnxt_vf_rep_free_rx_mbufs(struct bnxt_vf_representor *rep_bp)
+{
+ struct bnxt_rx_queue *rxq;
+ unsigned int i;
+
+ for (i = 0; i < rep_bp->rx_nr_rings; i++) {
+ rxq = rep_bp->rx_queues[i];
+ bnxt_rx_queue_release_mbufs(rxq);
+ }
+}
+