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) {
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)
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;
+}