X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Ftf_ulp%2Fbnxt_ulp_flow.c;h=2fec79a388c93c8fa18c43b8bf686ebb2ff0223f;hb=06d1a5d056b30dd18b1e4abc98c19cde57a8016c;hp=ec272c3a8ffac45df53ce5623eac6988d2ecf8cd;hpb=255add6762e224f7d2bb35ce57466fbd3bd83154;p=dpdk.git diff --git a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c index ec272c3a8f..2fec79a388 100644 --- a/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c +++ b/drivers/net/bnxt/tf_ulp/bnxt_ulp_flow.c @@ -11,6 +11,8 @@ #include "ulp_mapper.h" #include "ulp_fc_mgr.h" #include "ulp_port_db.h" +#include "ulp_ha_mgr.h" +#include "ulp_tun.h" #include static int32_t @@ -70,8 +72,10 @@ bnxt_ulp_set_dir_attributes(struct ulp_rte_parser_params *params, params->dir_attr |= BNXT_ULP_FLOW_ATTR_EGRESS; if (attr->ingress) params->dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS; +#if RTE_VERSION_NUM(17, 11, 10, 16) < RTE_VERSION if (attr->transfer) params->dir_attr |= BNXT_ULP_FLOW_ATTR_TRANSFER; +#endif } void @@ -79,6 +83,9 @@ bnxt_ulp_init_mapper_params(struct bnxt_ulp_mapper_create_parms *mapper_cparms, struct ulp_rte_parser_params *params, enum bnxt_ulp_fdb_type flow_type) { + uint32_t ulp_flags = 0; + + memset(mapper_cparms, 0, sizeof(*mapper_cparms)); mapper_cparms->flow_type = flow_type; mapper_cparms->app_priority = params->priority; mapper_cparms->dir_attr = params->dir_attr; @@ -86,22 +93,42 @@ bnxt_ulp_init_mapper_params(struct bnxt_ulp_mapper_create_parms *mapper_cparms, mapper_cparms->act_tid = params->act_tmpl; mapper_cparms->func_id = params->func_id; mapper_cparms->hdr_bitmap = ¶ms->hdr_bitmap; + mapper_cparms->enc_hdr_bitmap = ¶ms->enc_hdr_bitmap; mapper_cparms->hdr_field = params->hdr_field; + mapper_cparms->enc_field = params->enc_field; mapper_cparms->comp_fld = params->comp_fld; mapper_cparms->act = ¶ms->act_bitmap; mapper_cparms->act_prop = ¶ms->act_prop; mapper_cparms->flow_id = params->fid; mapper_cparms->parent_flow = params->parent_flow; - mapper_cparms->parent_fid = params->parent_fid; + mapper_cparms->child_flow = params->child_flow; mapper_cparms->fld_bitmap = ¶ms->fld_bitmap; mapper_cparms->flow_pattern_id = params->flow_pattern_id; mapper_cparms->act_pattern_id = params->act_pattern_id; + mapper_cparms->app_id = params->app_id; + mapper_cparms->port_id = params->port_id; + mapper_cparms->tun_idx = params->tun_idx; /* update the signature fields into the computed field list */ ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_HDR_SIG_ID, params->hdr_sig_id); ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_FLOW_SIG_ID, params->flow_sig_id); + + /* update the WC Priority flag */ + if (!bnxt_ulp_cntxt_ptr2_ulp_flags_get(params->ulp_ctx, &ulp_flags) && + ULP_HIGH_AVAIL_IS_ENABLED(ulp_flags)) { + enum ulp_ha_mgr_region region = ULP_HA_REGION_LOW; + int32_t rc; + + rc = ulp_ha_mgr_region_get(params->ulp_ctx, ®ion); + if (rc) + BNXT_TF_DBG(ERR, "Unable to get WC region\n"); + if (region == ULP_HA_REGION_HI) + ULP_COMP_FLD_IDX_WR(params, + BNXT_ULP_CF_IDX_WC_IS_HA_HIGH_REG, + 1); + } } /* Function to create the rte flow. */ @@ -137,12 +164,19 @@ bnxt_ulp_flow_create(struct rte_eth_dev *dev, memset(¶ms, 0, sizeof(struct ulp_rte_parser_params)); params.ulp_ctx = ulp_ctx; + if (bnxt_ulp_cntxt_app_id_get(params.ulp_ctx, ¶ms.app_id)) { + BNXT_TF_DBG(ERR, "failed to get the app id\n"); + goto flow_error; + } + /* Set the flow attributes */ bnxt_ulp_set_dir_attributes(¶ms, attr); /* copy the device port id and direction for further processing */ ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_INCOMING_IF, dev->data->port_id); + ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_DEV_PORT_ID, + dev->data->port_id); ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_SVIF_FLAG, BNXT_ULP_INVALID_SVIF_VAL); @@ -184,12 +218,15 @@ bnxt_ulp_flow_create(struct rte_eth_dev *dev, params.fid = fid; params.func_id = func_id; params.priority = attr->priority; + params.port_id = dev->data->port_id; + /* Perform the rte flow post process */ - ret = bnxt_ulp_rte_parser_post_process(¶ms); + bnxt_ulp_rte_parser_post_process(¶ms); + + /* do the tunnel offload process if any */ + ret = ulp_tunnel_offload_process(¶ms); if (ret == BNXT_TF_RC_ERROR) goto free_fid; - else if (ret == BNXT_TF_RC_FID) - goto return_fid; ret = ulp_matcher_pattern_match(¶ms, ¶ms.class_id); if (ret != BNXT_TF_RC_SUCCESS) @@ -206,7 +243,6 @@ bnxt_ulp_flow_create(struct rte_eth_dev *dev, if (ret) goto free_fid; -return_fid: bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx); flow_id = (struct rte_flow *)((uintptr_t)fid); @@ -252,6 +288,11 @@ bnxt_ulp_flow_validate(struct rte_eth_dev *dev, memset(¶ms, 0, sizeof(struct ulp_rte_parser_params)); params.ulp_ctx = ulp_ctx; + if (bnxt_ulp_cntxt_app_id_get(params.ulp_ctx, ¶ms.app_id)) { + BNXT_TF_DBG(ERR, "failed to get the app id\n"); + goto parse_error; + } + /* Set the flow attributes */ bnxt_ulp_set_dir_attributes(¶ms, attr); @@ -266,11 +307,12 @@ bnxt_ulp_flow_validate(struct rte_eth_dev *dev, goto parse_error; /* Perform the rte flow post process */ - ret = bnxt_ulp_rte_parser_post_process(¶ms); + bnxt_ulp_rte_parser_post_process(¶ms); + + /* do the tunnel offload process if any */ + ret = ulp_tunnel_offload_process(¶ms); if (ret == BNXT_TF_RC_ERROR) goto parse_error; - else if (ret == BNXT_TF_RC_FID) - return 0; ret = ulp_matcher_pattern_match(¶ms, &class_id); @@ -427,11 +469,201 @@ bnxt_ulp_flow_query(struct rte_eth_dev *eth_dev, return rc; } +/* Tunnel offload Apis */ +#define BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS 1 + +static int +bnxt_ulp_tunnel_decap_set(struct rte_eth_dev *eth_dev, + struct rte_flow_tunnel *tunnel, + struct rte_flow_action **pmd_actions, + uint32_t *num_of_actions, + struct rte_flow_error *error) +{ + struct bnxt_ulp_context *ulp_ctx; + struct bnxt_flow_app_tun_ent *tun_entry; + int32_t rc = 0; + + ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); + if (ulp_ctx == NULL) { + BNXT_TF_DBG(ERR, "ULP context is not initialized\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "ULP context uninitialized"); + return -EINVAL; + } + + if (tunnel == NULL) { + BNXT_TF_DBG(ERR, "No tunnel specified\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR, NULL, + "no tunnel specified"); + return -EINVAL; + } + + if (tunnel->type != RTE_FLOW_ITEM_TYPE_VXLAN) { + BNXT_TF_DBG(ERR, "Tunnel type unsupported\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR, NULL, + "tunnel type unsupported"); + return -EINVAL; + } + + rc = ulp_app_tun_search_entry(ulp_ctx, tunnel, &tun_entry); + if (rc < 0) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR, NULL, + "tunnel decap set failed"); + return -EINVAL; + } + + rc = ulp_app_tun_entry_set_decap_action(tun_entry); + if (rc < 0) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR, NULL, + "tunnel decap set failed"); + return -EINVAL; + } + + *pmd_actions = &tun_entry->action; + *num_of_actions = BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS; + return 0; +} + +static int +bnxt_ulp_tunnel_match(struct rte_eth_dev *eth_dev, + struct rte_flow_tunnel *tunnel, + struct rte_flow_item **pmd_items, + uint32_t *num_of_items, + struct rte_flow_error *error) +{ + struct bnxt_ulp_context *ulp_ctx; + struct bnxt_flow_app_tun_ent *tun_entry; + int32_t rc = 0; + + ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); + if (ulp_ctx == NULL) { + BNXT_TF_DBG(ERR, "ULP context is not initialized\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "ULP context uninitialized"); + return -EINVAL; + } + + if (tunnel == NULL) { + BNXT_TF_DBG(ERR, "No tunnel specified\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "no tunnel specified"); + return -EINVAL; + } + + if (tunnel->type != RTE_FLOW_ITEM_TYPE_VXLAN) { + BNXT_TF_DBG(ERR, "Tunnel type unsupported\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "tunnel type unsupported"); + return -EINVAL; + } + + rc = ulp_app_tun_search_entry(ulp_ctx, tunnel, &tun_entry); + if (rc < 0) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR, NULL, + "tunnel match set failed"); + return -EINVAL; + } + + rc = ulp_app_tun_entry_set_decap_item(tun_entry); + if (rc < 0) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR, NULL, + "tunnel match set failed"); + return -EINVAL; + } + + *pmd_items = &tun_entry->item; + *num_of_items = BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS; + return 0; +} + +static int +bnxt_ulp_tunnel_decap_release(struct rte_eth_dev *eth_dev, + struct rte_flow_action *pmd_actions, + uint32_t num_actions, + struct rte_flow_error *error) +{ + struct bnxt_ulp_context *ulp_ctx; + struct bnxt_flow_app_tun_ent *tun_entry; + const struct rte_flow_action *action_item = pmd_actions; + + ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); + if (ulp_ctx == NULL) { + BNXT_TF_DBG(ERR, "ULP context is not initialized\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "ULP context uninitialized"); + return -EINVAL; + } + if (num_actions != BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS) { + BNXT_TF_DBG(ERR, "num actions is invalid\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR, NULL, + "num actions is invalid"); + return -EINVAL; + } + while (action_item && action_item->type != RTE_FLOW_ACTION_TYPE_END) { + if (action_item->type == (typeof(tun_entry->action.type)) + BNXT_RTE_FLOW_ACTION_TYPE_VXLAN_DECAP) { + tun_entry = ulp_app_tun_match_entry(ulp_ctx, + action_item->conf); + ulp_app_tun_entry_delete(tun_entry); + } + action_item++; + } + return 0; +} + +static int +bnxt_ulp_tunnel_item_release(struct rte_eth_dev *eth_dev, + struct rte_flow_item *pmd_items, + uint32_t num_items, + struct rte_flow_error *error) +{ + struct bnxt_ulp_context *ulp_ctx; + struct bnxt_flow_app_tun_ent *tun_entry; + + ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); + if (ulp_ctx == NULL) { + BNXT_TF_DBG(ERR, "ULP context is not initialized\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "ULP context uninitialized"); + return -EINVAL; + } + if (num_items != BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS) { + BNXT_TF_DBG(ERR, "num items is invalid\n"); + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR, NULL, + "num items is invalid"); + return -EINVAL; + } + + tun_entry = ulp_app_tun_match_entry(ulp_ctx, pmd_items->spec); + ulp_app_tun_entry_delete(tun_entry); + return 0; +} + const struct rte_flow_ops bnxt_ulp_rte_flow_ops = { .validate = bnxt_ulp_flow_validate, .create = bnxt_ulp_flow_create, .destroy = bnxt_ulp_flow_destroy, .flush = bnxt_ulp_flow_flush, .query = bnxt_ulp_flow_query, - .isolate = NULL + .isolate = NULL, + /* Tunnel offload callbacks */ + .tunnel_decap_set = bnxt_ulp_tunnel_decap_set, + .tunnel_match = bnxt_ulp_tunnel_match, + .tunnel_action_decap_release = bnxt_ulp_tunnel_decap_release, + .tunnel_item_release = bnxt_ulp_tunnel_item_release, + .get_restore_info = NULL };