net/bnxt: fix flow match to ignore packet type
[dpdk.git] / drivers / net / bnxt / tf_ulp / ulp_def_rules.c
index d86e4c9..f421e2e 100644 (file)
@@ -81,17 +81,12 @@ ulp_set_parif_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
        if (rc)
                return rc;
 
-       if (parif_type == BNXT_ULP_PHY_PORT_PARIF) {
+       if (parif_type == BNXT_ULP_PHY_PORT_PARIF)
                idx = BNXT_ULP_CF_IDX_PHY_PORT_PARIF;
-               /* Parif needs to be reset to a free partition */
-               parif += BNXT_ULP_FREE_PARIF_BASE;
-       } else if (parif_type == BNXT_ULP_DRV_FUNC_PARIF) {
+       else if (parif_type == BNXT_ULP_DRV_FUNC_PARIF)
                idx = BNXT_ULP_CF_IDX_DRV_FUNC_PARIF;
-               /* Parif needs to be reset to a free partition */
-               parif += BNXT_ULP_FREE_PARIF_BASE;
-       } else {
+       else
                idx = BNXT_ULP_CF_IDX_VF_FUNC_PARIF;
-       }
 
        ULP_COMP_FLD_IDX_WR(mapper_params, idx, parif);
 
@@ -382,7 +377,7 @@ int32_t
 ulp_default_flow_destroy(struct rte_eth_dev *eth_dev, uint32_t flow_id)
 {
        struct bnxt_ulp_context *ulp_ctx;
-       int rc;
+       int rc = 0;
 
        ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
        if (!ulp_ctx) {
@@ -390,6 +385,11 @@ ulp_default_flow_destroy(struct rte_eth_dev *eth_dev, uint32_t flow_id)
                return -EINVAL;
        }
 
+       if (!flow_id) {
+               BNXT_TF_DBG(DEBUG, "invalid flow id zero\n");
+               return rc;
+       }
+
        rc = ulp_mapper_flow_destroy(ulp_ctx, flow_id,
                                     BNXT_ULP_DEFAULT_FLOW_TABLE);
        if (rc)
@@ -397,3 +397,227 @@ ulp_default_flow_destroy(struct rte_eth_dev *eth_dev, uint32_t flow_id)
 
        return rc;
 }
+
+void
+bnxt_ulp_destroy_df_rules(struct bnxt *bp, bool global)
+{
+       struct bnxt_ulp_df_rule_info *info;
+       uint8_t port_id;
+
+       if (!BNXT_TRUFLOW_EN(bp) ||
+           BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev))
+               return;
+
+       if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
+               return;
+
+       /* Delete default rules per port */
+       if (!global) {
+               port_id = bp->eth_dev->data->port_id;
+               info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
+               if (!info->valid)
+                       return;
+
+               ulp_default_flow_destroy(bp->eth_dev,
+                                        info->port_to_app_flow_id);
+               ulp_default_flow_destroy(bp->eth_dev,
+                                        info->app_to_port_flow_id);
+               memset(info, 0, sizeof(struct bnxt_ulp_df_rule_info));
+               return;
+       }
+
+       /* Delete default rules for all ports */
+       for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
+               info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
+               if (!info->valid)
+                       continue;
+
+               ulp_default_flow_destroy(bp->eth_dev,
+                                        info->port_to_app_flow_id);
+               ulp_default_flow_destroy(bp->eth_dev,
+                                        info->app_to_port_flow_id);
+               memset(info, 0, sizeof(struct bnxt_ulp_df_rule_info));
+       }
+}
+
+static int32_t
+bnxt_create_port_app_df_rule(struct bnxt *bp, uint8_t flow_type,
+                            uint32_t *flow_id)
+{
+       uint16_t port_id = bp->eth_dev->data->port_id;
+       struct ulp_tlv_param param_list[] = {
+               {
+                       .type = BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID,
+                       .length = 2,
+                       .value = {(port_id >> 8) & 0xff, port_id & 0xff}
+               },
+               {
+                       .type = BNXT_ULP_DF_PARAM_TYPE_LAST,
+                       .length = 0,
+                       .value = {0}
+               }
+       };
+
+       return ulp_default_flow_create(bp->eth_dev, param_list, flow_type,
+                                      flow_id);
+}
+
+int32_t
+bnxt_ulp_create_df_rules(struct bnxt *bp)
+{
+       struct bnxt_ulp_df_rule_info *info;
+       uint8_t port_id;
+       int rc;
+
+       if (!BNXT_TRUFLOW_EN(bp) ||
+           BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev) || !bp->ulp_ctx)
+               return 0;
+
+       port_id = bp->eth_dev->data->port_id;
+       info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
+       rc = bnxt_create_port_app_df_rule(bp, BNXT_ULP_DF_TPL_PORT_TO_VS,
+                                         &info->port_to_app_flow_id);
+       if (rc) {
+               BNXT_TF_DBG(ERR,
+                           "Failed to create port to app default rule\n");
+               return rc;
+       }
+
+       bp->tx_cfa_action = 0;
+       rc = bnxt_create_port_app_df_rule(bp, BNXT_ULP_DF_TPL_VS_TO_PORT,
+                                         &info->app_to_port_flow_id);
+       if (rc) {
+               BNXT_TF_DBG(ERR,
+                           "Failed to create app to port default rule\n");
+               goto port_to_app_free;
+       }
+
+       rc = ulp_default_flow_db_cfa_action_get(bp->ulp_ctx,
+                                               info->app_to_port_flow_id,
+                                               &bp->tx_cfa_action);
+       if (rc)
+               goto app_to_port_free;
+
+       info->valid = true;
+       return 0;
+
+app_to_port_free:
+       ulp_default_flow_destroy(bp->eth_dev, info->app_to_port_flow_id);
+port_to_app_free:
+       ulp_default_flow_destroy(bp->eth_dev, info->port_to_app_flow_id);
+       info->valid = false;
+
+       return rc;
+}
+
+static int32_t
+bnxt_create_port_vfr_default_rule(struct bnxt *bp,
+                                 uint8_t flow_type,
+                                 uint16_t vfr_port_id,
+                                 uint32_t *flow_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}
+               }
+       };
+       return ulp_default_flow_create(bp->eth_dev, param_list, flow_type,
+                                      flow_id);
+}
+
+int32_t
+bnxt_ulp_create_vfr_default_rules(struct rte_eth_dev *vfr_ethdev)
+{
+       struct bnxt_ulp_vfr_rule_info *info;
+       struct bnxt_representor *vfr = vfr_ethdev->data->dev_private;
+       struct rte_eth_dev *parent_dev = vfr->parent_dev;
+       struct bnxt *bp = parent_dev->data->dev_private;
+       uint16_t vfr_port_id = vfr_ethdev->data->port_id;
+       uint8_t port_id;
+       int rc;
+
+       if (!bp || !BNXT_TRUFLOW_EN(bp))
+               return 0;
+
+       port_id = vfr_ethdev->data->port_id;
+       info = bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(bp->ulp_ctx, port_id);
+
+       if (!info) {
+               BNXT_TF_DBG(ERR, "Failed to get vfr ulp context\n");
+               return -EINVAL;
+       }
+
+       if (info->valid) {
+               BNXT_TF_DBG(ERR, "VFR already allocated\n");
+               return -EINVAL;
+       }
+
+       memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));
+       rc = bnxt_create_port_vfr_default_rule(bp, BNXT_ULP_DF_TPL_VFREP_TO_VF,
+                                              vfr_port_id,
+                                              &info->rep2vf_flow_id);
+       if (rc) {
+               BNXT_TF_DBG(ERR, "Failed to create VFREP to VF default rule\n");
+               goto error;
+       }
+       rc = bnxt_create_port_vfr_default_rule(bp, BNXT_ULP_DF_TPL_VF_TO_VFREP,
+                                              vfr_port_id,
+                                              &info->vf2rep_flow_id);
+       if (rc) {
+               BNXT_TF_DBG(ERR, "Failed to create VF to VFREP default rule\n");
+               goto error;
+       }
+       rc = ulp_default_flow_db_cfa_action_get(bp->ulp_ctx,
+                                               info->rep2vf_flow_id,
+                                               &vfr->vfr_tx_cfa_action);
+       if (rc) {
+               BNXT_TF_DBG(ERR, "Failed to get the tx cfa action\n");
+               goto error;
+       }
+
+       /* Update the other details */
+       info->valid = true;
+       info->parent_port_id =  bp->eth_dev->data->port_id;
+       return 0;
+
+error:
+       if (info->rep2vf_flow_id)
+               ulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);
+       if (info->vf2rep_flow_id)
+               ulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);
+       return rc;
+}
+
+int32_t
+bnxt_ulp_delete_vfr_default_rules(struct bnxt_representor *vfr)
+{
+       struct bnxt_ulp_vfr_rule_info *info;
+       struct rte_eth_dev *parent_dev = vfr->parent_dev;
+       struct bnxt *bp = parent_dev->data->dev_private;
+
+       if (!bp || !BNXT_TRUFLOW_EN(bp))
+               return 0;
+       info = bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(bp->ulp_ctx,
+                                                   vfr->dpdk_port_id);
+       if (!info) {
+               BNXT_TF_DBG(ERR, "Failed to get vfr ulp context\n");
+               return -EINVAL;
+       }
+
+       if (!info->valid) {
+               BNXT_TF_DBG(ERR, "VFR already freed\n");
+               return -EINVAL;
+       }
+       ulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);
+       ulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);
+       vfr->vfr_tx_cfa_action = 0;
+       memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));
+       return 0;
+}