182b509d3SKishore Padmanabha /* SPDX-License-Identifier: BSD-3-Clause 26d160d77SRandy Schacher * Copyright(c) 2014-2023 Broadcom 382b509d3SKishore Padmanabha * All rights reserved. 482b509d3SKishore Padmanabha */ 582b509d3SKishore Padmanabha 682b509d3SKishore Padmanabha #include "bnxt.h" 782b509d3SKishore Padmanabha #include "bnxt_tf_common.h" 80c036a14SPeter Spreadborough #include "bnxt_ulp_utils.h" 982b509d3SKishore Padmanabha #include "ulp_rte_parser.h" 1082b509d3SKishore Padmanabha #include "ulp_matcher.h" 1182b509d3SKishore Padmanabha #include "ulp_flow_db.h" 1282b509d3SKishore Padmanabha #include "ulp_mapper.h" 13306c2d28SSomnath Kotur #include "ulp_fc_mgr.h" 14c53c2f43SKishore Padmanabha #include "ulp_port_db.h" 153184b1efSMike Baucom #include "ulp_ha_mgr.h" 16bdf4a3c6SKishore Padmanabha #include "ulp_tun.h" 1782b509d3SKishore Padmanabha #include <rte_malloc.h> 186d160d77SRandy Schacher #include "ulp_template_db_tbl.h" 196d160d77SRandy Schacher #include "tfp.h" 2082b509d3SKishore Padmanabha 2182b509d3SKishore Padmanabha static int32_t 2282b509d3SKishore Padmanabha bnxt_ulp_flow_validate_args(const struct rte_flow_attr *attr, 2382b509d3SKishore Padmanabha const struct rte_flow_item pattern[], 2482b509d3SKishore Padmanabha const struct rte_flow_action actions[], 2582b509d3SKishore Padmanabha struct rte_flow_error *error) 2682b509d3SKishore Padmanabha { 2782b509d3SKishore Padmanabha /* Perform the validation of the arguments for null */ 280c036a14SPeter Spreadborough if (unlikely(!error)) 2982b509d3SKishore Padmanabha return BNXT_TF_RC_ERROR; 3082b509d3SKishore Padmanabha 310c036a14SPeter Spreadborough if (unlikely(!pattern)) { 3282b509d3SKishore Padmanabha rte_flow_error_set(error, 3382b509d3SKishore Padmanabha EINVAL, 3482b509d3SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ITEM_NUM, 3582b509d3SKishore Padmanabha NULL, 3682b509d3SKishore Padmanabha "NULL pattern."); 3782b509d3SKishore Padmanabha return BNXT_TF_RC_ERROR; 3882b509d3SKishore Padmanabha } 3982b509d3SKishore Padmanabha 400c036a14SPeter Spreadborough if (unlikely(!actions)) { 4182b509d3SKishore Padmanabha rte_flow_error_set(error, 4282b509d3SKishore Padmanabha EINVAL, 4382b509d3SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ACTION_NUM, 4482b509d3SKishore Padmanabha NULL, 4582b509d3SKishore Padmanabha "NULL action."); 4682b509d3SKishore Padmanabha return BNXT_TF_RC_ERROR; 4782b509d3SKishore Padmanabha } 4882b509d3SKishore Padmanabha 490c036a14SPeter Spreadborough if (unlikely(!attr)) { 5082b509d3SKishore Padmanabha rte_flow_error_set(error, 5182b509d3SKishore Padmanabha EINVAL, 5282b509d3SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ATTR, 5382b509d3SKishore Padmanabha NULL, 5482b509d3SKishore Padmanabha "NULL attribute."); 5582b509d3SKishore Padmanabha return BNXT_TF_RC_ERROR; 5682b509d3SKishore Padmanabha } 5782b509d3SKishore Padmanabha 580c036a14SPeter Spreadborough if (unlikely(attr->egress && attr->ingress)) { 5982b509d3SKishore Padmanabha rte_flow_error_set(error, 6082b509d3SKishore Padmanabha EINVAL, 6182b509d3SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ATTR, 6282b509d3SKishore Padmanabha attr, 6382b509d3SKishore Padmanabha "EGRESS AND INGRESS UNSUPPORTED"); 6482b509d3SKishore Padmanabha return BNXT_TF_RC_ERROR; 6582b509d3SKishore Padmanabha } 6682b509d3SKishore Padmanabha return BNXT_TF_RC_SUCCESS; 6782b509d3SKishore Padmanabha } 6882b509d3SKishore Padmanabha 69d4b36fc5SKishore Padmanabha void 7077b359eeSKishore Padmanabha bnxt_ulp_set_dir_attributes(struct ulp_rte_parser_params *params, 7177b359eeSKishore Padmanabha const struct rte_flow_attr *attr) 7277b359eeSKishore Padmanabha { 7377b359eeSKishore Padmanabha /* Set the flow attributes */ 7477b359eeSKishore Padmanabha if (attr->egress) 7577b359eeSKishore Padmanabha params->dir_attr |= BNXT_ULP_FLOW_ATTR_EGRESS; 7677b359eeSKishore Padmanabha if (attr->ingress) 7777b359eeSKishore Padmanabha params->dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS; 783fe124d2SKishore Padmanabha #if RTE_VERSION_NUM(17, 11, 10, 16) < RTE_VERSION 7977b359eeSKishore Padmanabha if (attr->transfer) 8077b359eeSKishore Padmanabha params->dir_attr |= BNXT_ULP_FLOW_ATTR_TRANSFER; 813fe124d2SKishore Padmanabha #endif 8283f916bdSKishore Padmanabha if (attr->group) { 8383f916bdSKishore Padmanabha ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_GROUP_ID, 8483f916bdSKishore Padmanabha rte_cpu_to_le_32(attr->group)); 8583f916bdSKishore Padmanabha ULP_BITMAP_SET(params->cf_bitmap, BNXT_ULP_CF_BIT_GROUP_ID); 8683f916bdSKishore Padmanabha } 8777b359eeSKishore Padmanabha } 8877b359eeSKishore Padmanabha 89d4b36fc5SKishore Padmanabha int32_t 9022b65613SKishore Padmanabha bnxt_ulp_set_prio_attribute(struct ulp_rte_parser_params *params, 9122b65613SKishore Padmanabha const struct rte_flow_attr *attr) 9222b65613SKishore Padmanabha { 9322b65613SKishore Padmanabha uint32_t max_p = bnxt_ulp_max_flow_priority_get(params->ulp_ctx); 9422b65613SKishore Padmanabha uint32_t min_p = bnxt_ulp_min_flow_priority_get(params->ulp_ctx); 9522b65613SKishore Padmanabha 9622b65613SKishore Padmanabha if (max_p < min_p) { 970c036a14SPeter Spreadborough if (unlikely(attr->priority > min_p || attr->priority < max_p)) { 9822b65613SKishore Padmanabha BNXT_DRV_DBG(ERR, "invalid prio, not in range %u:%u\n", 9922b65613SKishore Padmanabha max_p, min_p); 10022b65613SKishore Padmanabha return -EINVAL; 10122b65613SKishore Padmanabha } 10222b65613SKishore Padmanabha params->priority = attr->priority; 10322b65613SKishore Padmanabha } else { 1040c036a14SPeter Spreadborough if (unlikely(attr->priority > max_p || attr->priority < min_p)) { 10522b65613SKishore Padmanabha BNXT_DRV_DBG(ERR, "invalid prio, not in range %u:%u\n", 10622b65613SKishore Padmanabha min_p, max_p); 10722b65613SKishore Padmanabha return -EINVAL; 10822b65613SKishore Padmanabha } 10922b65613SKishore Padmanabha params->priority = max_p - attr->priority; 11022b65613SKishore Padmanabha } 11122b65613SKishore Padmanabha /* flows with priority zero is considered as highest and put in EM */ 11222b65613SKishore Padmanabha if (attr->priority >= 11322b65613SKishore Padmanabha bnxt_ulp_default_app_priority_get(params->ulp_ctx) && 11422b65613SKishore Padmanabha attr->priority <= bnxt_ulp_max_def_priority_get(params->ulp_ctx)) { 11522b65613SKishore Padmanabha ULP_BITMAP_SET(params->cf_bitmap, BNXT_ULP_CF_BIT_DEF_PRIO); 11622b65613SKishore Padmanabha } 11722b65613SKishore Padmanabha return 0; 11822b65613SKishore Padmanabha } 11922b65613SKishore Padmanabha 120d4b36fc5SKishore Padmanabha void 1216d160d77SRandy Schacher bnxt_ulp_init_parser_cf_defaults(struct ulp_rte_parser_params *params, 1226d160d77SRandy Schacher uint16_t port_id) 1236d160d77SRandy Schacher { 1246d160d77SRandy Schacher /* Set up defaults for Comp field */ 1256d160d77SRandy Schacher ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_INCOMING_IF, port_id); 1266d160d77SRandy Schacher ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_DEV_PORT_ID, port_id); 1276d160d77SRandy Schacher ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_SVIF_FLAG, 1286d160d77SRandy Schacher BNXT_ULP_INVALID_SVIF_VAL); 1296d160d77SRandy Schacher } 1306d160d77SRandy Schacher 131dd0191d5SShuanglin Wang static void 132af50070eSKishore Padmanabha bnxt_ulp_init_cf_header_bitmap(struct bnxt_ulp_mapper_parms *params) 133dd0191d5SShuanglin Wang { 134dd0191d5SShuanglin Wang uint64_t hdr_bits = 0; 135dd0191d5SShuanglin Wang 136dd0191d5SShuanglin Wang /* Remove the internal tunnel bits */ 137af50070eSKishore Padmanabha hdr_bits = params->hdr_bitmap->bits; 138dd0191d5SShuanglin Wang ULP_BITMAP_RESET(hdr_bits, BNXT_ULP_HDR_BIT_F2); 139dd0191d5SShuanglin Wang 140dd0191d5SShuanglin Wang /* Add untag bits */ 141af50070eSKishore Padmanabha if (!ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_OO_VLAN)) 142af50070eSKishore Padmanabha ULP_BITMAP_SET(hdr_bits, BNXT_ULP_HDR_BIT_OO_UNTAGGED); 143af50070eSKishore Padmanabha if (!ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_OI_VLAN)) 144af50070eSKishore Padmanabha ULP_BITMAP_SET(hdr_bits, BNXT_ULP_HDR_BIT_OI_UNTAGGED); 145af50070eSKishore Padmanabha if (!ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_IO_VLAN)) 146af50070eSKishore Padmanabha ULP_BITMAP_SET(hdr_bits, BNXT_ULP_HDR_BIT_IO_UNTAGGED); 147af50070eSKishore Padmanabha if (!ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_II_VLAN)) 148af50070eSKishore Padmanabha ULP_BITMAP_SET(hdr_bits, BNXT_ULP_HDR_BIT_II_UNTAGGED); 149af50070eSKishore Padmanabha 150dd0191d5SShuanglin Wang /* Add non-tunnel bit */ 151af50070eSKishore Padmanabha if (!ULP_BITMAP_ISSET(params->cf_bitmap, BNXT_ULP_CF_BIT_IS_TUNNEL)) 152dd0191d5SShuanglin Wang ULP_BITMAP_SET(hdr_bits, BNXT_ULP_HDR_BIT_NON_TUNNEL); 153dd0191d5SShuanglin Wang 154af50070eSKishore Padmanabha /* Add l2 only bit */ 155af50070eSKishore Padmanabha if ((!ULP_BITMAP_ISSET(params->cf_bitmap, BNXT_ULP_CF_BIT_IS_TUNNEL) && 156af50070eSKishore Padmanabha !ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_O_IPV4) && 157af50070eSKishore Padmanabha !ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_O_IPV6)) || 158af50070eSKishore Padmanabha (ULP_BITMAP_ISSET(params->cf_bitmap, BNXT_ULP_CF_BIT_IS_TUNNEL) && 159af50070eSKishore Padmanabha !ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_I_IPV4) && 160af50070eSKishore Padmanabha !ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_I_IPV6))) { 161af50070eSKishore Padmanabha ULP_BITMAP_SET(hdr_bits, BNXT_ULP_HDR_BIT_L2_ONLY); 162af50070eSKishore Padmanabha ULP_BITMAP_SET(params->cf_bitmap, BNXT_ULP_CF_BIT_L2_ONLY); 163af50070eSKishore Padmanabha } 164af50070eSKishore Padmanabha 165af50070eSKishore Padmanabha ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_PROFILE_BITMAP, hdr_bits); 166af50070eSKishore Padmanabha 167af50070eSKishore Padmanabha /* Update the l4 protocol bits */ 168af50070eSKishore Padmanabha if ((ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_O_TCP) || 169af50070eSKishore Padmanabha ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_O_UDP))) { 170af50070eSKishore Padmanabha ULP_BITMAP_RESET(hdr_bits, BNXT_ULP_HDR_BIT_O_TCP); 171af50070eSKishore Padmanabha ULP_BITMAP_RESET(hdr_bits, BNXT_ULP_HDR_BIT_O_UDP); 172af50070eSKishore Padmanabha ULP_BITMAP_SET(hdr_bits, BNXT_ULP_HDR_BIT_O_L4_FLOW); 173af50070eSKishore Padmanabha } 174af50070eSKishore Padmanabha 175af50070eSKishore Padmanabha if ((ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_I_TCP) || 176af50070eSKishore Padmanabha ULP_BITMAP_ISSET(hdr_bits, BNXT_ULP_HDR_BIT_I_UDP))) { 177af50070eSKishore Padmanabha ULP_BITMAP_RESET(hdr_bits, BNXT_ULP_HDR_BIT_I_TCP); 178af50070eSKishore Padmanabha ULP_BITMAP_RESET(hdr_bits, BNXT_ULP_HDR_BIT_I_UDP); 179af50070eSKishore Padmanabha ULP_BITMAP_SET(hdr_bits, BNXT_ULP_HDR_BIT_I_L4_FLOW); 180af50070eSKishore Padmanabha } 181dd0191d5SShuanglin Wang /*update the comp field header bits */ 182dd0191d5SShuanglin Wang ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_HDR_BITMAP, hdr_bits); 183dd0191d5SShuanglin Wang } 184dd0191d5SShuanglin Wang 185188bf91dSVenkat Duvvuru void 186dd0191d5SShuanglin Wang bnxt_ulp_init_mapper_params(struct bnxt_ulp_mapper_parms *mparms, 187188bf91dSVenkat Duvvuru struct ulp_rte_parser_params *params, 188188bf91dSVenkat Duvvuru enum bnxt_ulp_fdb_type flow_type) 189188bf91dSVenkat Duvvuru { 19019994cc7SKishore Padmanabha uint32_t ulp_flags = 0; 19119994cc7SKishore Padmanabha 192dd0191d5SShuanglin Wang mparms->flow_type = flow_type; 193dd0191d5SShuanglin Wang mparms->app_priority = params->priority; 194dd0191d5SShuanglin Wang mparms->class_tid = params->class_id; 195dd0191d5SShuanglin Wang mparms->act_tid = params->act_tmpl; 196dd0191d5SShuanglin Wang mparms->func_id = params->func_id; 197dd0191d5SShuanglin Wang mparms->hdr_bitmap = ¶ms->hdr_bitmap; 198dd0191d5SShuanglin Wang mparms->enc_hdr_bitmap = ¶ms->enc_hdr_bitmap; 199dd0191d5SShuanglin Wang mparms->hdr_field = params->hdr_field; 200dd0191d5SShuanglin Wang mparms->enc_field = params->enc_field; 201dd0191d5SShuanglin Wang mparms->comp_fld = params->comp_fld; 202dd0191d5SShuanglin Wang mparms->act_bitmap = ¶ms->act_bitmap; 203dd0191d5SShuanglin Wang mparms->act_prop = ¶ms->act_prop; 204dd0191d5SShuanglin Wang mparms->parent_flow = params->parent_flow; 205dd0191d5SShuanglin Wang mparms->child_flow = params->child_flow; 206dd0191d5SShuanglin Wang mparms->fld_bitmap = ¶ms->fld_bitmap; 207dd0191d5SShuanglin Wang mparms->flow_pattern_id = params->flow_pattern_id; 208dd0191d5SShuanglin Wang mparms->act_pattern_id = params->act_pattern_id; 209dd0191d5SShuanglin Wang mparms->wc_field_bitmap = params->wc_field_bitmap; 210dd0191d5SShuanglin Wang mparms->app_id = params->app_id; 211dd0191d5SShuanglin Wang mparms->tun_idx = params->tun_idx; 212dd0191d5SShuanglin Wang mparms->cf_bitmap = params->cf_bitmap; 213dd0191d5SShuanglin Wang mparms->exclude_field_bitmap = params->exclude_field_bitmap; 214a2417601SKishore Padmanabha 215a2417601SKishore Padmanabha /* update the signature fields into the computed field list */ 216a2417601SKishore Padmanabha ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_HDR_SIG_ID, 217dd0191d5SShuanglin Wang params->class_info_idx); 218dd0191d5SShuanglin Wang 219dd0191d5SShuanglin Wang /* update the header bitmap */ 220af50070eSKishore Padmanabha bnxt_ulp_init_cf_header_bitmap(mparms); 221dd0191d5SShuanglin Wang 222a2417601SKishore Padmanabha ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_FLOW_SIG_ID, 223a2417601SKishore Padmanabha params->flow_sig_id); 224dd0191d5SShuanglin Wang ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_FUNCTION_ID, 225dd0191d5SShuanglin Wang params->func_id); 22619994cc7SKishore Padmanabha 227be3af03fSKishore Padmanabha if (bnxt_ulp_cntxt_ptr2_ulp_flags_get(params->ulp_ctx, &ulp_flags)) 228be3af03fSKishore Padmanabha return; 229be3af03fSKishore Padmanabha 23019994cc7SKishore Padmanabha /* update the WC Priority flag */ 231be3af03fSKishore Padmanabha if (ULP_HIGH_AVAIL_IS_ENABLED(ulp_flags)) { 2323184b1efSMike Baucom enum ulp_ha_mgr_region region = ULP_HA_REGION_LOW; 2333184b1efSMike Baucom int32_t rc; 23419994cc7SKishore Padmanabha 2353184b1efSMike Baucom rc = ulp_ha_mgr_region_get(params->ulp_ctx, ®ion); 2363184b1efSMike Baucom if (rc) 237dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get WC region\n"); 2383184b1efSMike Baucom if (region == ULP_HA_REGION_HI) 2393184b1efSMike Baucom ULP_COMP_FLD_IDX_WR(params, 2403184b1efSMike Baucom BNXT_ULP_CF_IDX_WC_IS_HA_HIGH_REG, 2413184b1efSMike Baucom 1); 2426d160d77SRandy Schacher } else { 2436d160d77SRandy Schacher ULP_COMP_FLD_IDX_WR(params, 2446d160d77SRandy Schacher BNXT_ULP_CF_IDX_HA_SUPPORT_DISABLED, 2456d160d77SRandy Schacher 1); 2463184b1efSMike Baucom } 247be3af03fSKishore Padmanabha 248be3af03fSKishore Padmanabha /* Update the socket direct flag */ 2490adfa2b6SKishore Padmanabha if (ULP_BITMAP_ISSET(params->hdr_bitmap.bits, 2500adfa2b6SKishore Padmanabha BNXT_ULP_HDR_BIT_SVIF_IGNORE)) { 2510adfa2b6SKishore Padmanabha uint32_t ifindex; 2520adfa2b6SKishore Padmanabha uint16_t vport; 2530adfa2b6SKishore Padmanabha 2540adfa2b6SKishore Padmanabha /* Get the port db ifindex */ 2550c036a14SPeter Spreadborough if (unlikely(ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx, 2560adfa2b6SKishore Padmanabha params->port_id, 2570c036a14SPeter Spreadborough &ifindex))) { 258dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port id %u\n", 2590adfa2b6SKishore Padmanabha params->port_id); 2600adfa2b6SKishore Padmanabha return; 2610adfa2b6SKishore Padmanabha } 2620adfa2b6SKishore Padmanabha /* Update the phy port of the other interface */ 2630c036a14SPeter Spreadborough if (unlikely(ulp_port_db_vport_get(params->ulp_ctx, ifindex, &vport))) { 264dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port if index %u\n", 265dd0191d5SShuanglin Wang ifindex); 2660adfa2b6SKishore Padmanabha return; 2670adfa2b6SKishore Padmanabha } 2680adfa2b6SKishore Padmanabha ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_SOCKET_DIRECT_VPORT, 2690adfa2b6SKishore Padmanabha (vport == 1) ? 2 : 1); 2700adfa2b6SKishore Padmanabha } 271d4b36fc5SKishore Padmanabha 272d4b36fc5SKishore Padmanabha /* Update the socket direct svif when socket_direct feature enabled. */ 273d4b36fc5SKishore Padmanabha if (ULP_BITMAP_ISSET(bnxt_ulp_feature_bits_get(params->ulp_ctx), 274d4b36fc5SKishore Padmanabha BNXT_ULP_FEATURE_BIT_SOCKET_DIRECT)) { 275d4b36fc5SKishore Padmanabha enum bnxt_ulp_intf_type intf_type; 276d4b36fc5SKishore Padmanabha /* For ingress flow on trusted_vf port */ 277d4b36fc5SKishore Padmanabha intf_type = bnxt_pmd_get_interface_type(params->port_id); 278d4b36fc5SKishore Padmanabha if (intf_type == BNXT_ULP_INTF_TYPE_TRUSTED_VF) { 279d4b36fc5SKishore Padmanabha uint16_t svif; 280d4b36fc5SKishore Padmanabha /* Get the socket direct svif of the given dev port */ 281d4b36fc5SKishore Padmanabha if (unlikely(ulp_port_db_dev_port_socket_direct_svif_get(params->ulp_ctx, 282d4b36fc5SKishore Padmanabha params->port_id, 283d4b36fc5SKishore Padmanabha &svif))) { 284d4b36fc5SKishore Padmanabha BNXT_DRV_DBG(ERR, "Invalid port id %u\n", 285d4b36fc5SKishore Padmanabha params->port_id); 286d4b36fc5SKishore Padmanabha return; 287d4b36fc5SKishore Padmanabha } 288d4b36fc5SKishore Padmanabha ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_SOCKET_DIRECT_SVIF, svif); 289d4b36fc5SKishore Padmanabha } 290d4b36fc5SKishore Padmanabha } 291188bf91dSVenkat Duvvuru } 292188bf91dSVenkat Duvvuru 29382b509d3SKishore Padmanabha /* Function to create the rte flow. */ 29482b509d3SKishore Padmanabha static struct rte_flow * 29582b509d3SKishore Padmanabha bnxt_ulp_flow_create(struct rte_eth_dev *dev, 29682b509d3SKishore Padmanabha const struct rte_flow_attr *attr, 29782b509d3SKishore Padmanabha const struct rte_flow_item pattern[], 29882b509d3SKishore Padmanabha const struct rte_flow_action actions[], 29982b509d3SKishore Padmanabha struct rte_flow_error *error) 30082b509d3SKishore Padmanabha { 301dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_parms mparms = { 0 }; 3023d6ba7cbSKishore Padmanabha struct ulp_rte_parser_params params; 303dc8ee812SKishore Padmanabha struct bnxt_ulp_context *ulp_ctx; 304188bf91dSVenkat Duvvuru int rc, ret = BNXT_TF_RC_ERROR; 30582b509d3SKishore Padmanabha struct rte_flow *flow_id; 306188bf91dSVenkat Duvvuru uint16_t func_id; 30782b509d3SKishore Padmanabha uint32_t fid; 30882b509d3SKishore Padmanabha 309dd0191d5SShuanglin Wang if (error != NULL) 310dd0191d5SShuanglin Wang error->type = RTE_FLOW_ERROR_TYPE_NONE; 311dd0191d5SShuanglin Wang 3120c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_flow_validate_args(attr, 31382b509d3SKishore Padmanabha pattern, actions, 3140c036a14SPeter Spreadborough error) == BNXT_TF_RC_ERROR)) { 315dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid arguments being passed\n"); 316675e31d8SVenkat Duvvuru goto flow_error; 31782b509d3SKishore Padmanabha } 31882b509d3SKishore Padmanabha 31982b509d3SKishore Padmanabha ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev); 3200c036a14SPeter Spreadborough if (unlikely(!ulp_ctx)) { 321dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "ULP context is not initialized\n"); 322675e31d8SVenkat Duvvuru goto flow_error; 32382b509d3SKishore Padmanabha } 32482b509d3SKishore Padmanabha 3253d6ba7cbSKishore Padmanabha /* Initialize the parser params */ 3263d6ba7cbSKishore Padmanabha memset(¶ms, 0, sizeof(struct ulp_rte_parser_params)); 327dc8ee812SKishore Padmanabha params.ulp_ctx = ulp_ctx; 328d4b36fc5SKishore Padmanabha params.port_id = dev->data->port_id; 32982b509d3SKishore Padmanabha 3300c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_app_id_get(params.ulp_ctx, ¶ms.app_id))) { 331dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "failed to get the app id\n"); 3325b73c859SKishore Padmanabha goto flow_error; 3335b73c859SKishore Padmanabha } 3345b73c859SKishore Padmanabha 33577b359eeSKishore Padmanabha /* Set the flow attributes */ 33677b359eeSKishore Padmanabha bnxt_ulp_set_dir_attributes(¶ms, attr); 33782b509d3SKishore Padmanabha 3380c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_set_prio_attribute(¶ms, attr))) 33922b65613SKishore Padmanabha goto flow_error; 34022b65613SKishore Padmanabha 3416d160d77SRandy Schacher bnxt_ulp_init_parser_cf_defaults(¶ms, dev->data->port_id); 34282b509d3SKishore Padmanabha 343188bf91dSVenkat Duvvuru /* Get the function id */ 3440c036a14SPeter Spreadborough if (unlikely(ulp_port_db_port_func_id_get(ulp_ctx, 345188bf91dSVenkat Duvvuru dev->data->port_id, 3460c036a14SPeter Spreadborough &func_id))) { 347dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "conversion of port to func id failed\n"); 348675e31d8SVenkat Duvvuru goto flow_error; 349188bf91dSVenkat Duvvuru } 350188bf91dSVenkat Duvvuru 351188bf91dSVenkat Duvvuru /* Protect flow creation */ 3520c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx))) { 353dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow db lock acquire failed\n"); 354675e31d8SVenkat Duvvuru goto flow_error; 355188bf91dSVenkat Duvvuru } 356188bf91dSVenkat Duvvuru 357188bf91dSVenkat Duvvuru /* Allocate a Flow ID for attaching all resources for the flow to. 358188bf91dSVenkat Duvvuru * Once allocated, all errors have to walk the list of resources and 359188bf91dSVenkat Duvvuru * free each of them. 360188bf91dSVenkat Duvvuru */ 361188bf91dSVenkat Duvvuru rc = ulp_flow_db_fid_alloc(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR, 362188bf91dSVenkat Duvvuru func_id, &fid); 3630c036a14SPeter Spreadborough if (unlikely(rc)) { 364dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to allocate flow table entry\n"); 365675e31d8SVenkat Duvvuru goto release_lock; 366188bf91dSVenkat Duvvuru } 367188bf91dSVenkat Duvvuru 36882b509d3SKishore Padmanabha /* Parse the rte flow pattern */ 3693d6ba7cbSKishore Padmanabha ret = bnxt_ulp_rte_parser_hdr_parse(pattern, ¶ms); 3700c036a14SPeter Spreadborough if (unlikely(ret != BNXT_TF_RC_SUCCESS)) 371675e31d8SVenkat Duvvuru goto free_fid; 37282b509d3SKishore Padmanabha 37382b509d3SKishore Padmanabha /* Parse the rte flow action */ 3743d6ba7cbSKishore Padmanabha ret = bnxt_ulp_rte_parser_act_parse(actions, ¶ms); 3750c036a14SPeter Spreadborough if (unlikely(ret != BNXT_TF_RC_SUCCESS)) 376675e31d8SVenkat Duvvuru goto free_fid; 37782b509d3SKishore Padmanabha 378dd0191d5SShuanglin Wang mparms.flow_id = fid; 379dd0191d5SShuanglin Wang mparms.func_id = func_id; 380dd0191d5SShuanglin Wang mparms.port_id = dev->data->port_id; 381bdf4a3c6SKishore Padmanabha 38277b359eeSKishore Padmanabha /* Perform the rte flow post process */ 383bdf4a3c6SKishore Padmanabha bnxt_ulp_rte_parser_post_process(¶ms); 384bdf4a3c6SKishore Padmanabha 385bdf4a3c6SKishore Padmanabha /* do the tunnel offload process if any */ 386bdf4a3c6SKishore Padmanabha ret = ulp_tunnel_offload_process(¶ms); 3870c036a14SPeter Spreadborough if (unlikely(ret == BNXT_TF_RC_ERROR)) 388675e31d8SVenkat Duvvuru goto free_fid; 38977b359eeSKishore Padmanabha 390675e31d8SVenkat Duvvuru ret = ulp_matcher_pattern_match(¶ms, ¶ms.class_id); 3910c036a14SPeter Spreadborough if (unlikely(ret != BNXT_TF_RC_SUCCESS)) 392675e31d8SVenkat Duvvuru goto free_fid; 39382b509d3SKishore Padmanabha 394675e31d8SVenkat Duvvuru ret = ulp_matcher_action_match(¶ms, ¶ms.act_tmpl); 3950c036a14SPeter Spreadborough if (unlikely(ret != BNXT_TF_RC_SUCCESS)) 396675e31d8SVenkat Duvvuru goto free_fid; 39782b509d3SKishore Padmanabha 398dd0191d5SShuanglin Wang bnxt_ulp_init_mapper_params(&mparms, ¶ms, 399188bf91dSVenkat Duvvuru BNXT_ULP_FDB_TYPE_REGULAR); 400072cb4a8SMike Baucom /* Call the ulp mapper to create the flow in the hardware. */ 401dd0191d5SShuanglin Wang ret = ulp_mapper_flow_create(ulp_ctx, &mparms, 402dd0191d5SShuanglin Wang (void *)error); 4030c036a14SPeter Spreadborough if (unlikely(ret)) 404675e31d8SVenkat Duvvuru goto free_fid; 405188bf91dSVenkat Duvvuru 406188bf91dSVenkat Duvvuru bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx); 407188bf91dSVenkat Duvvuru 40882b509d3SKishore Padmanabha flow_id = (struct rte_flow *)((uintptr_t)fid); 40982b509d3SKishore Padmanabha return flow_id; 41082b509d3SKishore Padmanabha 411675e31d8SVenkat Duvvuru free_fid: 412188bf91dSVenkat Duvvuru ulp_flow_db_fid_free(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR, fid); 413675e31d8SVenkat Duvvuru release_lock: 414188bf91dSVenkat Duvvuru bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx); 415675e31d8SVenkat Duvvuru flow_error: 4160c036a14SPeter Spreadborough if (unlikely(error != NULL && 4170c036a14SPeter Spreadborough error->type == RTE_FLOW_ERROR_TYPE_NONE)) 418dd0191d5SShuanglin Wang rte_flow_error_set(error, ret, 419dd0191d5SShuanglin Wang RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 42082b509d3SKishore Padmanabha "Failed to create flow."); 42182b509d3SKishore Padmanabha return NULL; 42282b509d3SKishore Padmanabha } 42382b509d3SKishore Padmanabha 424f88b99c9SKishore Padmanabha /* Function to validate the rte flow. */ 425f88b99c9SKishore Padmanabha static int 426dc8ee812SKishore Padmanabha bnxt_ulp_flow_validate(struct rte_eth_dev *dev, 427f88b99c9SKishore Padmanabha const struct rte_flow_attr *attr, 428f88b99c9SKishore Padmanabha const struct rte_flow_item pattern[], 429f88b99c9SKishore Padmanabha const struct rte_flow_action actions[], 430f88b99c9SKishore Padmanabha struct rte_flow_error *error) 431f88b99c9SKishore Padmanabha { 4323d6ba7cbSKishore Padmanabha struct ulp_rte_parser_params params; 433675e31d8SVenkat Duvvuru struct bnxt_ulp_context *ulp_ctx; 434f88b99c9SKishore Padmanabha uint32_t class_id, act_tmpl; 43509b23f8bSKishore Padmanabha int ret = BNXT_TF_RC_ERROR; 436f88b99c9SKishore Padmanabha 4370c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_flow_validate_args(attr, 438f88b99c9SKishore Padmanabha pattern, actions, 4390c036a14SPeter Spreadborough error) == BNXT_TF_RC_ERROR)) { 440dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid arguments being passed\n"); 44109b23f8bSKishore Padmanabha goto parse_error; 442f88b99c9SKishore Padmanabha } 443f88b99c9SKishore Padmanabha 444dc8ee812SKishore Padmanabha ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev); 4450c036a14SPeter Spreadborough if (unlikely(!ulp_ctx)) { 446dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "ULP context is not initialized\n"); 44709b23f8bSKishore Padmanabha goto parse_error; 448dc8ee812SKishore Padmanabha } 449dc8ee812SKishore Padmanabha 4503d6ba7cbSKishore Padmanabha /* Initialize the parser params */ 4513d6ba7cbSKishore Padmanabha memset(¶ms, 0, sizeof(struct ulp_rte_parser_params)); 452dc8ee812SKishore Padmanabha params.ulp_ctx = ulp_ctx; 4533d6ba7cbSKishore Padmanabha 4540c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_app_id_get(params.ulp_ctx, ¶ms.app_id))) { 455dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "failed to get the app id\n"); 4565b73c859SKishore Padmanabha goto parse_error; 4575b73c859SKishore Padmanabha } 4585b73c859SKishore Padmanabha 45977b359eeSKishore Padmanabha /* Set the flow attributes */ 46077b359eeSKishore Padmanabha bnxt_ulp_set_dir_attributes(¶ms, attr); 46122b65613SKishore Padmanabha 4620c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_set_prio_attribute(¶ms, attr))) 46322b65613SKishore Padmanabha goto parse_error; 46422b65613SKishore Padmanabha 4656d160d77SRandy Schacher bnxt_ulp_init_parser_cf_defaults(¶ms, dev->data->port_id); 466f88b99c9SKishore Padmanabha 467f88b99c9SKishore Padmanabha /* Parse the rte flow pattern */ 4683d6ba7cbSKishore Padmanabha ret = bnxt_ulp_rte_parser_hdr_parse(pattern, ¶ms); 4690c036a14SPeter Spreadborough if (unlikely(ret != BNXT_TF_RC_SUCCESS)) 470f88b99c9SKishore Padmanabha goto parse_error; 471f88b99c9SKishore Padmanabha 472f88b99c9SKishore Padmanabha /* Parse the rte flow action */ 4733d6ba7cbSKishore Padmanabha ret = bnxt_ulp_rte_parser_act_parse(actions, ¶ms); 4740c036a14SPeter Spreadborough if (unlikely(ret != BNXT_TF_RC_SUCCESS)) 475f88b99c9SKishore Padmanabha goto parse_error; 476f88b99c9SKishore Padmanabha 47777b359eeSKishore Padmanabha /* Perform the rte flow post process */ 478bdf4a3c6SKishore Padmanabha bnxt_ulp_rte_parser_post_process(¶ms); 479bdf4a3c6SKishore Padmanabha 480bdf4a3c6SKishore Padmanabha /* do the tunnel offload process if any */ 481bdf4a3c6SKishore Padmanabha ret = ulp_tunnel_offload_process(¶ms); 4820c036a14SPeter Spreadborough if (unlikely(ret == BNXT_TF_RC_ERROR)) 48377b359eeSKishore Padmanabha goto parse_error; 48477b359eeSKishore Padmanabha 4853d6ba7cbSKishore Padmanabha ret = ulp_matcher_pattern_match(¶ms, &class_id); 486f88b99c9SKishore Padmanabha 4870c036a14SPeter Spreadborough if (unlikely(ret != BNXT_TF_RC_SUCCESS)) 488f88b99c9SKishore Padmanabha goto parse_error; 489f88b99c9SKishore Padmanabha 4903d6ba7cbSKishore Padmanabha ret = ulp_matcher_action_match(¶ms, &act_tmpl); 4910c036a14SPeter Spreadborough if (unlikely(ret != BNXT_TF_RC_SUCCESS)) 492f88b99c9SKishore Padmanabha goto parse_error; 493f88b99c9SKishore Padmanabha 494f88b99c9SKishore Padmanabha /* all good return success */ 495f88b99c9SKishore Padmanabha return ret; 496f88b99c9SKishore Padmanabha 497f88b99c9SKishore Padmanabha parse_error: 498f88b99c9SKishore Padmanabha rte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 499f88b99c9SKishore Padmanabha "Failed to validate flow."); 500f88b99c9SKishore Padmanabha return -EINVAL; 501f88b99c9SKishore Padmanabha } 502f88b99c9SKishore Padmanabha 50377847233SKishore Padmanabha /* Function to destroy the rte flow. */ 504d0eaabd4SVenkat Duvvuru int 50577847233SKishore Padmanabha bnxt_ulp_flow_destroy(struct rte_eth_dev *dev, 50677847233SKishore Padmanabha struct rte_flow *flow, 50777847233SKishore Padmanabha struct rte_flow_error *error) 50877847233SKishore Padmanabha { 50977847233SKishore Padmanabha struct bnxt_ulp_context *ulp_ctx; 51074bcfc06SKishore Padmanabha uint32_t flow_id; 51174bcfc06SKishore Padmanabha uint16_t func_id; 512675e31d8SVenkat Duvvuru int ret; 51377847233SKishore Padmanabha 514dd0191d5SShuanglin Wang if (error != NULL) 515dd0191d5SShuanglin Wang error->type = RTE_FLOW_ERROR_TYPE_NONE; 516dd0191d5SShuanglin Wang 51777847233SKishore Padmanabha ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev); 5180c036a14SPeter Spreadborough if (unlikely(!ulp_ctx)) { 519dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "ULP context is not initialized\n"); 520d0eaabd4SVenkat Duvvuru if (error) 52177847233SKishore Padmanabha rte_flow_error_set(error, EINVAL, 52277847233SKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 52377847233SKishore Padmanabha "Failed to destroy flow."); 52477847233SKishore Padmanabha return -EINVAL; 52577847233SKishore Padmanabha } 52677847233SKishore Padmanabha 52774bcfc06SKishore Padmanabha flow_id = (uint32_t)(uintptr_t)flow; 528c53c2f43SKishore Padmanabha 5290c036a14SPeter Spreadborough if (unlikely(ulp_port_db_port_func_id_get(ulp_ctx, 530c53c2f43SKishore Padmanabha dev->data->port_id, 5310c036a14SPeter Spreadborough &func_id))) { 532dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "conversion of port to func id failed\n"); 533c53c2f43SKishore Padmanabha if (error) 534c53c2f43SKishore Padmanabha rte_flow_error_set(error, EINVAL, 535c53c2f43SKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 536c53c2f43SKishore Padmanabha "Failed to destroy flow."); 537c53c2f43SKishore Padmanabha return -EINVAL; 538c53c2f43SKishore Padmanabha } 53977847233SKishore Padmanabha 5400c036a14SPeter Spreadborough if (unlikely(ulp_flow_db_validate_flow_func(ulp_ctx, flow_id, func_id) == 5410c036a14SPeter Spreadborough false)) { 542dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Incorrect device params\n"); 543d0eaabd4SVenkat Duvvuru if (error) 54474bcfc06SKishore Padmanabha rte_flow_error_set(error, EINVAL, 54574bcfc06SKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 54674bcfc06SKishore Padmanabha "Failed to destroy flow."); 54774bcfc06SKishore Padmanabha return -EINVAL; 54874bcfc06SKishore Padmanabha } 54974bcfc06SKishore Padmanabha 5500c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx))) { 551dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow db lock acquire failed\n"); 552188bf91dSVenkat Duvvuru return -EINVAL; 553188bf91dSVenkat Duvvuru } 55430683082SKishore Padmanabha ret = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR, 555dd0191d5SShuanglin Wang flow_id, (void *)error); 5560c036a14SPeter Spreadborough if (unlikely(ret)) { 557dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to destroy flow.\n"); 558dd0191d5SShuanglin Wang if (error != NULL && 559dd0191d5SShuanglin Wang error->type == RTE_FLOW_ERROR_TYPE_NONE) 56077847233SKishore Padmanabha rte_flow_error_set(error, -ret, 56177847233SKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 56277847233SKishore Padmanabha "Failed to destroy flow."); 563d0eaabd4SVenkat Duvvuru } 564188bf91dSVenkat Duvvuru bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx); 56577847233SKishore Padmanabha 56677847233SKishore Padmanabha return ret; 56777847233SKishore Padmanabha } 56877847233SKishore Padmanabha 569edc6ca0cSKishore Padmanabha /* Function to destroy the rte flows. */ 570edc6ca0cSKishore Padmanabha static int32_t 571edc6ca0cSKishore Padmanabha bnxt_ulp_flow_flush(struct rte_eth_dev *eth_dev, 572edc6ca0cSKishore Padmanabha struct rte_flow_error *error) 573edc6ca0cSKishore Padmanabha { 574edc6ca0cSKishore Padmanabha struct bnxt_ulp_context *ulp_ctx; 57574bcfc06SKishore Padmanabha int32_t ret = 0; 57674bcfc06SKishore Padmanabha uint16_t func_id; 577edc6ca0cSKishore Padmanabha 578edc6ca0cSKishore Padmanabha ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); 5790c036a14SPeter Spreadborough if (unlikely(!ulp_ctx)) 58009b23f8bSKishore Padmanabha return ret; 581edc6ca0cSKishore Padmanabha 582edc6ca0cSKishore Padmanabha /* Free the resources for the last device */ 583c53c2f43SKishore Padmanabha if (ulp_ctx_deinit_allowed(ulp_ctx)) { 58474bcfc06SKishore Padmanabha ret = ulp_flow_db_session_flow_flush(ulp_ctx); 58574bcfc06SKishore Padmanabha } else if (bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx)) { 586c53c2f43SKishore Padmanabha ret = ulp_port_db_port_func_id_get(ulp_ctx, 587c53c2f43SKishore Padmanabha eth_dev->data->port_id, 588c53c2f43SKishore Padmanabha &func_id); 589c53c2f43SKishore Padmanabha if (!ret) 59074bcfc06SKishore Padmanabha ret = ulp_flow_db_function_flow_flush(ulp_ctx, func_id); 591c53c2f43SKishore Padmanabha else 592dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "convert port to func id failed\n"); 59374bcfc06SKishore Padmanabha } 5940c036a14SPeter Spreadborough if (unlikely(ret)) 595edc6ca0cSKishore Padmanabha rte_flow_error_set(error, ret, 596edc6ca0cSKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 597edc6ca0cSKishore Padmanabha "Failed to flush flow."); 598edc6ca0cSKishore Padmanabha return ret; 599edc6ca0cSKishore Padmanabha } 600edc6ca0cSKishore Padmanabha 60135e03bafSRandy Schacher /* 60235e03bafSRandy Schacher * Fill the rte_flow_query_rss 'rss_conf' argument passed 60335e03bafSRandy Schacher * in the rte_flow_query() with the values obtained and 60435e03bafSRandy Schacher * accumulated locally. 60535e03bafSRandy Schacher * 60635e03bafSRandy Schacher * ctxt [in] The ulp context for the flow counter manager 60735e03bafSRandy Schacher * 60835e03bafSRandy Schacher * flow_id [in] The HW flow ID 60935e03bafSRandy Schacher * 61035e03bafSRandy Schacher * rss_conf [out] The rte_flow_query_count 'data' that is set 61135e03bafSRandy Schacher * 61235e03bafSRandy Schacher */ 61335e03bafSRandy Schacher static int ulp_flow_query_rss_get(struct bnxt_ulp_context *ctxt, 61435e03bafSRandy Schacher uint32_t flow_id, 61535e03bafSRandy Schacher struct rte_flow_action_rss *rss_conf) 61635e03bafSRandy Schacher { 61735e03bafSRandy Schacher struct ulp_flow_db_res_params params; 61835e03bafSRandy Schacher uint32_t nxt_resource_index = 0; 61935e03bafSRandy Schacher bool found_cntr_resource = false; 62035e03bafSRandy Schacher struct bnxt *bp; 62135e03bafSRandy Schacher uint16_t vnic_id = 0; 62235e03bafSRandy Schacher int rc = 0; 62335e03bafSRandy Schacher 62435e03bafSRandy Schacher bp = bnxt_ulp_cntxt_bp_get(ctxt); 6250c036a14SPeter Spreadborough if (unlikely(!bp)) { 62635e03bafSRandy Schacher BNXT_DRV_DBG(ERR, "Failed to get bp from ulp cntxt\n"); 62735e03bafSRandy Schacher return -EINVAL; 62835e03bafSRandy Schacher } 62935e03bafSRandy Schacher 6300c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_acquire_fdb_lock(ctxt))) { 63135e03bafSRandy Schacher BNXT_DRV_DBG(ERR, "Flow db lock acquire failed\n"); 63235e03bafSRandy Schacher return -EINVAL; 63335e03bafSRandy Schacher } 63435e03bafSRandy Schacher do { 63535e03bafSRandy Schacher rc = ulp_flow_db_resource_get(ctxt, 63635e03bafSRandy Schacher BNXT_ULP_FDB_TYPE_REGULAR, 63735e03bafSRandy Schacher flow_id, 63835e03bafSRandy Schacher &nxt_resource_index, 63935e03bafSRandy Schacher ¶ms); 64035e03bafSRandy Schacher if (params.resource_func == 64135e03bafSRandy Schacher BNXT_ULP_RESOURCE_FUNC_VNIC_TABLE && 64235e03bafSRandy Schacher (params.resource_sub_type == 64335e03bafSRandy Schacher BNXT_ULP_RESOURCE_SUB_TYPE_VNIC_TABLE_RSS || 64435e03bafSRandy Schacher params.resource_sub_type == 64535e03bafSRandy Schacher BNXT_ULP_RESOURCE_SUB_TYPE_VNIC_TABLE_QUEUE)) { 64635e03bafSRandy Schacher vnic_id = params.resource_hndl; 64735e03bafSRandy Schacher found_cntr_resource = true; 64835e03bafSRandy Schacher break; 64935e03bafSRandy Schacher } 65035e03bafSRandy Schacher 65135e03bafSRandy Schacher } while (!rc && nxt_resource_index); 65235e03bafSRandy Schacher 65335e03bafSRandy Schacher if (found_cntr_resource) 65435e03bafSRandy Schacher bnxt_vnic_rss_query_info_fill(bp, rss_conf, vnic_id); 65535e03bafSRandy Schacher 65635e03bafSRandy Schacher bnxt_ulp_cntxt_release_fdb_lock(ctxt); 65735e03bafSRandy Schacher 65835e03bafSRandy Schacher return rc; 65935e03bafSRandy Schacher } 66035e03bafSRandy Schacher 661306c2d28SSomnath Kotur /* Function to query the rte flows. */ 662306c2d28SSomnath Kotur static int32_t 663306c2d28SSomnath Kotur bnxt_ulp_flow_query(struct rte_eth_dev *eth_dev, 664306c2d28SSomnath Kotur struct rte_flow *flow, 665306c2d28SSomnath Kotur const struct rte_flow_action *action, 666306c2d28SSomnath Kotur void *data, 667306c2d28SSomnath Kotur struct rte_flow_error *error) 668306c2d28SSomnath Kotur { 669306c2d28SSomnath Kotur int rc = 0; 670306c2d28SSomnath Kotur struct bnxt_ulp_context *ulp_ctx; 67135e03bafSRandy Schacher struct rte_flow_action_rss *rss_conf; 672306c2d28SSomnath Kotur struct rte_flow_query_count *count; 673*0513f0afSPeter Spreadborough enum bnxt_ulp_device_id dev_id; 674306c2d28SSomnath Kotur uint32_t flow_id; 675306c2d28SSomnath Kotur 676306c2d28SSomnath Kotur ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); 6770c036a14SPeter Spreadborough if (unlikely(!ulp_ctx)) { 678dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "ULP context is not initialized\n"); 679306c2d28SSomnath Kotur rte_flow_error_set(error, EINVAL, 680306c2d28SSomnath Kotur RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 681306c2d28SSomnath Kotur "Failed to query flow."); 682306c2d28SSomnath Kotur return -EINVAL; 683306c2d28SSomnath Kotur } 684306c2d28SSomnath Kotur 685*0513f0afSPeter Spreadborough rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id); 686*0513f0afSPeter Spreadborough if (rc) { 687*0513f0afSPeter Spreadborough BNXT_DRV_DBG(ERR, "Can't identify the device\n"); 688*0513f0afSPeter Spreadborough rte_flow_error_set(error, EINVAL, 689*0513f0afSPeter Spreadborough RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 690*0513f0afSPeter Spreadborough "Failed to query flow."); 691*0513f0afSPeter Spreadborough return -EINVAL; 692*0513f0afSPeter Spreadborough } 693*0513f0afSPeter Spreadborough 694306c2d28SSomnath Kotur flow_id = (uint32_t)(uintptr_t)flow; 695306c2d28SSomnath Kotur 696306c2d28SSomnath Kotur switch (action->type) { 69735e03bafSRandy Schacher case RTE_FLOW_ACTION_TYPE_RSS: 69835e03bafSRandy Schacher rss_conf = (struct rte_flow_action_rss *)data; 69935e03bafSRandy Schacher rc = ulp_flow_query_rss_get(ulp_ctx, flow_id, rss_conf); 7000c036a14SPeter Spreadborough if (unlikely(rc)) { 70135e03bafSRandy Schacher rte_flow_error_set(error, EINVAL, 70235e03bafSRandy Schacher RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 70335e03bafSRandy Schacher "Failed to query RSS info."); 70435e03bafSRandy Schacher } 70535e03bafSRandy Schacher 70635e03bafSRandy Schacher break; 707306c2d28SSomnath Kotur case RTE_FLOW_ACTION_TYPE_COUNT: 708306c2d28SSomnath Kotur count = data; 709*0513f0afSPeter Spreadborough if (dev_id == BNXT_ULP_DEVICE_ID_THOR2) 710*0513f0afSPeter Spreadborough rc = ulp_sc_mgr_query_count_get(ulp_ctx, flow_id, count); 711*0513f0afSPeter Spreadborough else 712306c2d28SSomnath Kotur rc = ulp_fc_mgr_query_count_get(ulp_ctx, flow_id, count); 713*0513f0afSPeter Spreadborough 7140c036a14SPeter Spreadborough if (unlikely(rc)) { 715306c2d28SSomnath Kotur rte_flow_error_set(error, EINVAL, 716306c2d28SSomnath Kotur RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 717306c2d28SSomnath Kotur "Failed to query flow."); 718306c2d28SSomnath Kotur } 719306c2d28SSomnath Kotur break; 720306c2d28SSomnath Kotur default: 721306c2d28SSomnath Kotur rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_ACTION_NUM, 722306c2d28SSomnath Kotur NULL, "Unsupported action item"); 723306c2d28SSomnath Kotur } 724306c2d28SSomnath Kotur 725306c2d28SSomnath Kotur return rc; 726306c2d28SSomnath Kotur } 727306c2d28SSomnath Kotur 7286d160d77SRandy Schacher static int32_t 7296d160d77SRandy Schacher bnxt_ulp_action_handle_chk_args(const struct rte_flow_action *action, 7306d160d77SRandy Schacher const struct rte_flow_indir_action_conf *conf) 7316d160d77SRandy Schacher { 7326d160d77SRandy Schacher if (!action || !conf) 7336d160d77SRandy Schacher return BNXT_TF_RC_ERROR; 7346d160d77SRandy Schacher /* shared action only allowed to have one direction */ 7356d160d77SRandy Schacher if (conf->ingress == 1 && conf->egress == 1) 7366d160d77SRandy Schacher return BNXT_TF_RC_ERROR; 7376d160d77SRandy Schacher /* shared action must have at least one direction */ 7386d160d77SRandy Schacher if (conf->ingress == 0 && conf->egress == 0) 7396d160d77SRandy Schacher return BNXT_TF_RC_ERROR; 7406d160d77SRandy Schacher return BNXT_TF_RC_SUCCESS; 7416d160d77SRandy Schacher } 7426d160d77SRandy Schacher 7436d160d77SRandy Schacher static inline void 7446d160d77SRandy Schacher bnxt_ulp_set_action_handle_dir_attr(struct ulp_rte_parser_params *params, 7456d160d77SRandy Schacher const struct rte_flow_indir_action_conf *conf) 7466d160d77SRandy Schacher { 7476d160d77SRandy Schacher if (conf->ingress == 1) 7486d160d77SRandy Schacher params->dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS; 7496d160d77SRandy Schacher else if (conf->egress == 1) 7506d160d77SRandy Schacher params->dir_attr |= BNXT_ULP_FLOW_ATTR_EGRESS; 7516d160d77SRandy Schacher } 7526d160d77SRandy Schacher 7536d160d77SRandy Schacher static struct rte_flow_action_handle * 7546d160d77SRandy Schacher bnxt_ulp_action_handle_create(struct rte_eth_dev *dev, 7556d160d77SRandy Schacher const struct rte_flow_indir_action_conf *conf, 7566d160d77SRandy Schacher const struct rte_flow_action *action, 7576d160d77SRandy Schacher struct rte_flow_error *error) 7586d160d77SRandy Schacher { 7596d160d77SRandy Schacher enum bnxt_ulp_intf_type port_type = BNXT_ULP_INTF_TYPE_INVALID; 760dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_parms mparms = { 0 }; 7616d160d77SRandy Schacher struct ulp_rte_parser_params params; 7626d160d77SRandy Schacher struct bnxt_ulp_context *ulp_ctx; 7636d160d77SRandy Schacher uint32_t act_tid; 7646d160d77SRandy Schacher uint16_t func_id; 7656d160d77SRandy Schacher uint32_t ifindex; 7666d160d77SRandy Schacher int ret = BNXT_TF_RC_ERROR; 7676d160d77SRandy Schacher const struct rte_flow_action actions[2] = { 7686d160d77SRandy Schacher { 7696d160d77SRandy Schacher .type = action->type, 7706d160d77SRandy Schacher .conf = action->conf 7716d160d77SRandy Schacher }, 7726d160d77SRandy Schacher { 7736d160d77SRandy Schacher .type = RTE_FLOW_ACTION_TYPE_END 7746d160d77SRandy Schacher } 7756d160d77SRandy Schacher }; 7766d160d77SRandy Schacher 777dd0191d5SShuanglin Wang if (error != NULL) 778dd0191d5SShuanglin Wang error->type = RTE_FLOW_ERROR_TYPE_NONE; 779dd0191d5SShuanglin Wang 7800c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_action_handle_chk_args(action, conf) != BNXT_TF_RC_SUCCESS)) 7816d160d77SRandy Schacher goto parse_error; 7826d160d77SRandy Schacher 7836d160d77SRandy Schacher ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev); 7840c036a14SPeter Spreadborough if (unlikely(!ulp_ctx)) { 785dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "ULP context is not initialized\n"); 7866d160d77SRandy Schacher goto parse_error; 7876d160d77SRandy Schacher } 7886d160d77SRandy Schacher 7896d160d77SRandy Schacher /* Initialize the parser params */ 7906d160d77SRandy Schacher memset(¶ms, 0, sizeof(struct ulp_rte_parser_params)); 7916d160d77SRandy Schacher params.ulp_ctx = ulp_ctx; 7926d160d77SRandy Schacher 7936d160d77SRandy Schacher ULP_BITMAP_SET(params.act_bitmap.bits, BNXT_ULP_ACT_BIT_SHARED); 7946d160d77SRandy Schacher 7956d160d77SRandy Schacher /* Set the shared action direction attribute */ 7966d160d77SRandy Schacher bnxt_ulp_set_action_handle_dir_attr(¶ms, conf); 7976d160d77SRandy Schacher 7986d160d77SRandy Schacher /* perform the conversion from dpdk port to bnxt ifindex */ 7990c036a14SPeter Spreadborough if (unlikely(ulp_port_db_dev_port_to_ulp_index(ulp_ctx, 8006d160d77SRandy Schacher dev->data->port_id, 8010c036a14SPeter Spreadborough &ifindex))) { 802dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Port id is not valid\n"); 8036d160d77SRandy Schacher goto parse_error; 8046d160d77SRandy Schacher } 8056d160d77SRandy Schacher port_type = ulp_port_db_port_type_get(ulp_ctx, ifindex); 8060c036a14SPeter Spreadborough if (unlikely(port_type == BNXT_ULP_INTF_TYPE_INVALID)) { 807dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Port type is not valid\n"); 8086d160d77SRandy Schacher goto parse_error; 8096d160d77SRandy Schacher } 8106d160d77SRandy Schacher 8116d160d77SRandy Schacher bnxt_ulp_init_parser_cf_defaults(¶ms, dev->data->port_id); 8126d160d77SRandy Schacher 8136d160d77SRandy Schacher /* Emulating the match port for direction processing */ 8146d160d77SRandy Schacher ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_MATCH_PORT_TYPE, 8156d160d77SRandy Schacher port_type); 8166d160d77SRandy Schacher 8176d160d77SRandy Schacher if ((params.dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS) && 8186d160d77SRandy Schacher port_type == BNXT_ULP_INTF_TYPE_VF_REP) { 8196d160d77SRandy Schacher ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_DIRECTION, 8206d160d77SRandy Schacher BNXT_ULP_DIR_EGRESS); 8216d160d77SRandy Schacher } else { 8226d160d77SRandy Schacher /* Assign the input direction */ 8236d160d77SRandy Schacher if (params.dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS) 8246d160d77SRandy Schacher ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_DIRECTION, 8256d160d77SRandy Schacher BNXT_ULP_DIR_INGRESS); 8266d160d77SRandy Schacher else 8276d160d77SRandy Schacher ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_DIRECTION, 8286d160d77SRandy Schacher BNXT_ULP_DIR_EGRESS); 8296d160d77SRandy Schacher } 8306d160d77SRandy Schacher 831032d49efSKishore Padmanabha /* perform the conversion from dpdk port to bnxt ifindex */ 8320c036a14SPeter Spreadborough if (unlikely(ulp_port_db_dev_port_to_ulp_index(ulp_ctx, 833032d49efSKishore Padmanabha dev->data->port_id, 8340c036a14SPeter Spreadborough &ifindex))) { 835dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Port id is not valid\n"); 836032d49efSKishore Padmanabha goto parse_error; 837032d49efSKishore Padmanabha } 838032d49efSKishore Padmanabha port_type = ulp_port_db_port_type_get(ulp_ctx, ifindex); 8390c036a14SPeter Spreadborough if (unlikely(port_type == BNXT_ULP_INTF_TYPE_INVALID)) { 840dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Port type is not valid\n"); 841032d49efSKishore Padmanabha goto parse_error; 842032d49efSKishore Padmanabha } 843032d49efSKishore Padmanabha 844032d49efSKishore Padmanabha bnxt_ulp_init_parser_cf_defaults(¶ms, dev->data->port_id); 845032d49efSKishore Padmanabha 846032d49efSKishore Padmanabha /* Emulating the match port for direction processing */ 847032d49efSKishore Padmanabha ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_MATCH_PORT_TYPE, 848032d49efSKishore Padmanabha port_type); 849032d49efSKishore Padmanabha 850032d49efSKishore Padmanabha if ((params.dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS) && 851032d49efSKishore Padmanabha port_type == BNXT_ULP_INTF_TYPE_VF_REP) { 852032d49efSKishore Padmanabha ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_DIRECTION, 853032d49efSKishore Padmanabha BNXT_ULP_DIR_EGRESS); 854032d49efSKishore Padmanabha } else { 855032d49efSKishore Padmanabha /* Assign the input direction */ 856032d49efSKishore Padmanabha if (params.dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS) 857032d49efSKishore Padmanabha ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_DIRECTION, 858032d49efSKishore Padmanabha BNXT_ULP_DIR_INGRESS); 859032d49efSKishore Padmanabha else 860032d49efSKishore Padmanabha ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_DIRECTION, 861032d49efSKishore Padmanabha BNXT_ULP_DIR_EGRESS); 862032d49efSKishore Padmanabha } 863dd0191d5SShuanglin Wang 8646d160d77SRandy Schacher /* Parse the shared action */ 8656d160d77SRandy Schacher ret = bnxt_ulp_rte_parser_act_parse(actions, ¶ms); 8660c036a14SPeter Spreadborough if (unlikely(ret != BNXT_TF_RC_SUCCESS)) 8676d160d77SRandy Schacher goto parse_error; 8686d160d77SRandy Schacher 8696d160d77SRandy Schacher /* Perform the rte flow post process */ 8706d160d77SRandy Schacher bnxt_ulp_rte_parser_post_process(¶ms); 8716d160d77SRandy Schacher 8726d160d77SRandy Schacher /* do the tunnel offload process if any */ 8736d160d77SRandy Schacher ret = ulp_tunnel_offload_process(¶ms); 8740c036a14SPeter Spreadborough if (unlikely(ret == BNXT_TF_RC_ERROR)) 8756d160d77SRandy Schacher goto parse_error; 8766d160d77SRandy Schacher 8776d160d77SRandy Schacher ret = ulp_matcher_action_match(¶ms, &act_tid); 8780c036a14SPeter Spreadborough if (unlikely(ret != BNXT_TF_RC_SUCCESS)) 8796d160d77SRandy Schacher goto parse_error; 8806d160d77SRandy Schacher 8816d160d77SRandy Schacher bnxt_ulp_init_mapper_params(&mparms, ¶ms, 8826d160d77SRandy Schacher BNXT_ULP_FDB_TYPE_REGULAR); 8836d160d77SRandy Schacher mparms.act_tid = act_tid; 8846d160d77SRandy Schacher 8856d160d77SRandy Schacher /* Get the function id */ 8860c036a14SPeter Spreadborough if (unlikely(ulp_port_db_port_func_id_get(ulp_ctx, 8876d160d77SRandy Schacher dev->data->port_id, 8880c036a14SPeter Spreadborough &func_id))) { 889dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "conversion of port to func id failed\n"); 8906d160d77SRandy Schacher goto parse_error; 8916d160d77SRandy Schacher } 8926d160d77SRandy Schacher 8936d160d77SRandy Schacher /* Protect flow creation */ 8940c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx))) { 895dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow db lock acquire failed\n"); 8966d160d77SRandy Schacher goto parse_error; 8976d160d77SRandy Schacher } 8986d160d77SRandy Schacher 899dd0191d5SShuanglin Wang ret = ulp_mapper_flow_create(params.ulp_ctx, &mparms, 900dd0191d5SShuanglin Wang (void *)error); 9016d160d77SRandy Schacher bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx); 9026d160d77SRandy Schacher 9030c036a14SPeter Spreadborough if (unlikely(ret)) 9046d160d77SRandy Schacher goto parse_error; 9056d160d77SRandy Schacher 9066d160d77SRandy Schacher return (struct rte_flow_action_handle *)((uintptr_t)mparms.shared_hndl); 9076d160d77SRandy Schacher 9086d160d77SRandy Schacher parse_error: 909dd0191d5SShuanglin Wang if (error != NULL && 910dd0191d5SShuanglin Wang error->type == RTE_FLOW_ERROR_TYPE_NONE) 9116d160d77SRandy Schacher rte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 9126d160d77SRandy Schacher "Failed to create shared action."); 9136d160d77SRandy Schacher return NULL; 9146d160d77SRandy Schacher } 9156d160d77SRandy Schacher 9166d160d77SRandy Schacher static int 9176d160d77SRandy Schacher bnxt_ulp_action_handle_destroy(struct rte_eth_dev *dev, 9186d160d77SRandy Schacher struct rte_flow_action_handle *shared_hndl, 9196d160d77SRandy Schacher struct rte_flow_error *error) 9206d160d77SRandy Schacher { 921dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_parms mparms = { 0 }; 9226d160d77SRandy Schacher struct bnxt_ulp_shared_act_info *act_info; 9236d160d77SRandy Schacher struct ulp_rte_parser_params params; 9246d160d77SRandy Schacher struct ulp_rte_act_prop *act_prop; 9256d160d77SRandy Schacher struct bnxt_ulp_context *ulp_ctx; 9266d160d77SRandy Schacher enum bnxt_ulp_direction_type dir; 9276d160d77SRandy Schacher uint32_t act_tid, act_info_entries; 9286d160d77SRandy Schacher int ret = BNXT_TF_RC_ERROR; 9296d160d77SRandy Schacher uint32_t shared_action_type; 9306d160d77SRandy Schacher uint64_t tmp64; 9316d160d77SRandy Schacher 932dd0191d5SShuanglin Wang if (error != NULL) 933dd0191d5SShuanglin Wang error->type = RTE_FLOW_ERROR_TYPE_NONE; 934dd0191d5SShuanglin Wang 9356d160d77SRandy Schacher ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev); 9360c036a14SPeter Spreadborough if (unlikely(!ulp_ctx)) { 937dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "ULP context is not initialized\n"); 9386d160d77SRandy Schacher goto parse_error; 9396d160d77SRandy Schacher } 9406d160d77SRandy Schacher 9410c036a14SPeter Spreadborough if (unlikely(!shared_hndl)) { 942dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid argument of shared handle\n"); 9436d160d77SRandy Schacher goto parse_error; 9446d160d77SRandy Schacher } 9456d160d77SRandy Schacher 9466d160d77SRandy Schacher act_prop = ¶ms.act_prop; 9476d160d77SRandy Schacher memset(¶ms, 0, sizeof(struct ulp_rte_parser_params)); 9486d160d77SRandy Schacher params.ulp_ctx = ulp_ctx; 9496d160d77SRandy Schacher 9500c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_app_id_get(ulp_ctx, ¶ms.app_id))) { 951dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "failed to get the app id\n"); 9526d160d77SRandy Schacher goto parse_error; 9536d160d77SRandy Schacher } 9546d160d77SRandy Schacher /* The template will delete the entry if there are no references */ 9550c036a14SPeter Spreadborough if (unlikely(bnxt_get_action_handle_type(shared_hndl, &shared_action_type))) { 956dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid shared handle\n"); 9576d160d77SRandy Schacher goto parse_error; 9586d160d77SRandy Schacher } 9596d160d77SRandy Schacher 9606d160d77SRandy Schacher act_info_entries = 0; 9616d160d77SRandy Schacher act_info = bnxt_ulp_shared_act_info_get(&act_info_entries); 9620c036a14SPeter Spreadborough if (unlikely(shared_action_type >= act_info_entries || !act_info)) { 963dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid shared handle\n"); 9646d160d77SRandy Schacher goto parse_error; 9656d160d77SRandy Schacher } 9666d160d77SRandy Schacher 9676d160d77SRandy Schacher ULP_BITMAP_SET(params.act_bitmap.bits, 9686d160d77SRandy Schacher act_info[shared_action_type].act_bitmask); 9696d160d77SRandy Schacher ULP_BITMAP_SET(params.act_bitmap.bits, BNXT_ULP_ACT_BIT_DELETE); 9706d160d77SRandy Schacher 9716d160d77SRandy Schacher ret = bnxt_get_action_handle_direction(shared_hndl, &dir); 9720c036a14SPeter Spreadborough if (unlikely(ret)) { 973dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid shared handle dir\n"); 9746d160d77SRandy Schacher goto parse_error; 9756d160d77SRandy Schacher } 9766d160d77SRandy Schacher 9776d160d77SRandy Schacher if (dir == BNXT_ULP_DIR_EGRESS) { 9786d160d77SRandy Schacher params.dir_attr = BNXT_ULP_FLOW_ATTR_EGRESS; 9796d160d77SRandy Schacher ULP_BITMAP_SET(params.act_bitmap.bits, 9806d160d77SRandy Schacher BNXT_ULP_FLOW_DIR_BITMASK_EGR); 9816d160d77SRandy Schacher } else { 9826d160d77SRandy Schacher params.dir_attr = BNXT_ULP_FLOW_ATTR_INGRESS; 9836d160d77SRandy Schacher ULP_BITMAP_SET(params.act_bitmap.bits, 9846d160d77SRandy Schacher BNXT_ULP_FLOW_DIR_BITMASK_ING); 9856d160d77SRandy Schacher } 9866d160d77SRandy Schacher 9876d160d77SRandy Schacher tmp64 = tfp_cpu_to_be_64((uint64_t) 9886d160d77SRandy Schacher bnxt_get_action_handle_index(shared_hndl)); 9896d160d77SRandy Schacher 9906d160d77SRandy Schacher memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_SHARED_HANDLE], 9916d160d77SRandy Schacher &tmp64, BNXT_ULP_ACT_PROP_SZ_SHARED_HANDLE); 9926d160d77SRandy Schacher 9936d160d77SRandy Schacher ret = ulp_matcher_action_match(¶ms, &act_tid); 9940c036a14SPeter Spreadborough if (unlikely(ret != BNXT_TF_RC_SUCCESS)) 9956d160d77SRandy Schacher goto parse_error; 9966d160d77SRandy Schacher 9976d160d77SRandy Schacher bnxt_ulp_init_mapper_params(&mparms, ¶ms, 9986d160d77SRandy Schacher BNXT_ULP_FDB_TYPE_REGULAR); 9996d160d77SRandy Schacher mparms.act_tid = act_tid; 10006d160d77SRandy Schacher 10010c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx))) { 1002dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow db lock acquire failed\n"); 10036d160d77SRandy Schacher goto parse_error; 10046d160d77SRandy Schacher } 10056d160d77SRandy Schacher 1006dd0191d5SShuanglin Wang ret = ulp_mapper_flow_create(ulp_ctx, &mparms, 1007dd0191d5SShuanglin Wang (void *)error); 10086d160d77SRandy Schacher bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx); 10090c036a14SPeter Spreadborough if (unlikely(ret)) 10106d160d77SRandy Schacher goto parse_error; 10116d160d77SRandy Schacher 10126d160d77SRandy Schacher return 0; 10136d160d77SRandy Schacher 10146d160d77SRandy Schacher parse_error: 1015dd0191d5SShuanglin Wang if (error != NULL && 1016dd0191d5SShuanglin Wang error->type == RTE_FLOW_ERROR_TYPE_NONE) 10176d160d77SRandy Schacher rte_flow_error_set(error, BNXT_TF_RC_ERROR, 10186d160d77SRandy Schacher RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 10196d160d77SRandy Schacher "Failed to destroy shared action."); 10206d160d77SRandy Schacher return -EINVAL; 10216d160d77SRandy Schacher } 10226d160d77SRandy Schacher 1023bdf4a3c6SKishore Padmanabha /* Tunnel offload Apis */ 1024bdf4a3c6SKishore Padmanabha #define BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS 1 1025bdf4a3c6SKishore Padmanabha 1026bdf4a3c6SKishore Padmanabha static int 1027bdf4a3c6SKishore Padmanabha bnxt_ulp_tunnel_decap_set(struct rte_eth_dev *eth_dev, 1028bdf4a3c6SKishore Padmanabha struct rte_flow_tunnel *tunnel, 1029bdf4a3c6SKishore Padmanabha struct rte_flow_action **pmd_actions, 1030bdf4a3c6SKishore Padmanabha uint32_t *num_of_actions, 1031bdf4a3c6SKishore Padmanabha struct rte_flow_error *error) 1032bdf4a3c6SKishore Padmanabha { 1033bdf4a3c6SKishore Padmanabha struct bnxt_ulp_context *ulp_ctx; 1034bdf4a3c6SKishore Padmanabha struct bnxt_flow_app_tun_ent *tun_entry; 1035bdf4a3c6SKishore Padmanabha int32_t rc = 0; 1036bdf4a3c6SKishore Padmanabha 1037bdf4a3c6SKishore Padmanabha ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); 10380c036a14SPeter Spreadborough if (unlikely(ulp_ctx == NULL)) { 1039dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "ULP context is not initialized\n"); 1040bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1041bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1042bdf4a3c6SKishore Padmanabha "ULP context uninitialized"); 1043bdf4a3c6SKishore Padmanabha return -EINVAL; 1044bdf4a3c6SKishore Padmanabha } 1045bdf4a3c6SKishore Padmanabha 10460c036a14SPeter Spreadborough if (unlikely(tunnel == NULL)) { 1047dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "No tunnel specified\n"); 1048bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1049bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ATTR, NULL, 1050bdf4a3c6SKishore Padmanabha "no tunnel specified"); 1051bdf4a3c6SKishore Padmanabha return -EINVAL; 1052bdf4a3c6SKishore Padmanabha } 1053bdf4a3c6SKishore Padmanabha 10540c036a14SPeter Spreadborough if (unlikely(tunnel->type != RTE_FLOW_ITEM_TYPE_VXLAN)) { 1055dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Tunnel type unsupported\n"); 1056bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1057bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ATTR, NULL, 1058bdf4a3c6SKishore Padmanabha "tunnel type unsupported"); 1059bdf4a3c6SKishore Padmanabha return -EINVAL; 1060bdf4a3c6SKishore Padmanabha } 1061bdf4a3c6SKishore Padmanabha 1062bdf4a3c6SKishore Padmanabha rc = ulp_app_tun_search_entry(ulp_ctx, tunnel, &tun_entry); 10630c036a14SPeter Spreadborough if (unlikely(rc < 0)) { 1064bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1065bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ATTR, NULL, 1066bdf4a3c6SKishore Padmanabha "tunnel decap set failed"); 1067bdf4a3c6SKishore Padmanabha return -EINVAL; 1068bdf4a3c6SKishore Padmanabha } 1069bdf4a3c6SKishore Padmanabha 1070bdf4a3c6SKishore Padmanabha rc = ulp_app_tun_entry_set_decap_action(tun_entry); 10710c036a14SPeter Spreadborough if (unlikely(rc < 0)) { 1072bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1073bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ATTR, NULL, 1074bdf4a3c6SKishore Padmanabha "tunnel decap set failed"); 1075bdf4a3c6SKishore Padmanabha return -EINVAL; 1076bdf4a3c6SKishore Padmanabha } 1077bdf4a3c6SKishore Padmanabha 1078bdf4a3c6SKishore Padmanabha *pmd_actions = &tun_entry->action; 1079bdf4a3c6SKishore Padmanabha *num_of_actions = BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS; 1080bdf4a3c6SKishore Padmanabha return 0; 1081bdf4a3c6SKishore Padmanabha } 1082bdf4a3c6SKishore Padmanabha 1083bdf4a3c6SKishore Padmanabha static int 1084bdf4a3c6SKishore Padmanabha bnxt_ulp_tunnel_match(struct rte_eth_dev *eth_dev, 1085bdf4a3c6SKishore Padmanabha struct rte_flow_tunnel *tunnel, 1086bdf4a3c6SKishore Padmanabha struct rte_flow_item **pmd_items, 1087bdf4a3c6SKishore Padmanabha uint32_t *num_of_items, 1088bdf4a3c6SKishore Padmanabha struct rte_flow_error *error) 1089bdf4a3c6SKishore Padmanabha { 1090bdf4a3c6SKishore Padmanabha struct bnxt_ulp_context *ulp_ctx; 1091bdf4a3c6SKishore Padmanabha struct bnxt_flow_app_tun_ent *tun_entry; 1092bdf4a3c6SKishore Padmanabha int32_t rc = 0; 1093bdf4a3c6SKishore Padmanabha 1094bdf4a3c6SKishore Padmanabha ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); 10950c036a14SPeter Spreadborough if (unlikely(ulp_ctx == NULL)) { 1096dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "ULP context is not initialized\n"); 1097bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1098bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1099bdf4a3c6SKishore Padmanabha "ULP context uninitialized"); 1100bdf4a3c6SKishore Padmanabha return -EINVAL; 1101bdf4a3c6SKishore Padmanabha } 1102bdf4a3c6SKishore Padmanabha 11030c036a14SPeter Spreadborough if (unlikely(tunnel == NULL)) { 1104dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "No tunnel specified\n"); 1105bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1106bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1107bdf4a3c6SKishore Padmanabha "no tunnel specified"); 1108bdf4a3c6SKishore Padmanabha return -EINVAL; 1109bdf4a3c6SKishore Padmanabha } 1110bdf4a3c6SKishore Padmanabha 11110c036a14SPeter Spreadborough if (unlikely(tunnel->type != RTE_FLOW_ITEM_TYPE_VXLAN)) { 1112dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Tunnel type unsupported\n"); 1113bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1114bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1115bdf4a3c6SKishore Padmanabha "tunnel type unsupported"); 1116bdf4a3c6SKishore Padmanabha return -EINVAL; 1117bdf4a3c6SKishore Padmanabha } 1118bdf4a3c6SKishore Padmanabha 1119bdf4a3c6SKishore Padmanabha rc = ulp_app_tun_search_entry(ulp_ctx, tunnel, &tun_entry); 11200c036a14SPeter Spreadborough if (unlikely(rc < 0)) { 1121bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1122bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ATTR, NULL, 1123bdf4a3c6SKishore Padmanabha "tunnel match set failed"); 1124bdf4a3c6SKishore Padmanabha return -EINVAL; 1125bdf4a3c6SKishore Padmanabha } 1126bdf4a3c6SKishore Padmanabha 1127bdf4a3c6SKishore Padmanabha rc = ulp_app_tun_entry_set_decap_item(tun_entry); 11280c036a14SPeter Spreadborough if (unlikely(rc < 0)) { 1129bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1130bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ATTR, NULL, 1131bdf4a3c6SKishore Padmanabha "tunnel match set failed"); 1132bdf4a3c6SKishore Padmanabha return -EINVAL; 1133bdf4a3c6SKishore Padmanabha } 1134bdf4a3c6SKishore Padmanabha 1135bdf4a3c6SKishore Padmanabha *pmd_items = &tun_entry->item; 1136bdf4a3c6SKishore Padmanabha *num_of_items = BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS; 1137bdf4a3c6SKishore Padmanabha return 0; 1138bdf4a3c6SKishore Padmanabha } 1139bdf4a3c6SKishore Padmanabha 1140bdf4a3c6SKishore Padmanabha static int 1141bdf4a3c6SKishore Padmanabha bnxt_ulp_tunnel_decap_release(struct rte_eth_dev *eth_dev, 1142bdf4a3c6SKishore Padmanabha struct rte_flow_action *pmd_actions, 1143bdf4a3c6SKishore Padmanabha uint32_t num_actions, 1144bdf4a3c6SKishore Padmanabha struct rte_flow_error *error) 1145bdf4a3c6SKishore Padmanabha { 1146bdf4a3c6SKishore Padmanabha struct bnxt_ulp_context *ulp_ctx; 1147bdf4a3c6SKishore Padmanabha struct bnxt_flow_app_tun_ent *tun_entry; 1148bdf4a3c6SKishore Padmanabha const struct rte_flow_action *action_item = pmd_actions; 1149bdf4a3c6SKishore Padmanabha 1150bdf4a3c6SKishore Padmanabha ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); 11510c036a14SPeter Spreadborough if (unlikely(ulp_ctx == NULL)) { 1152dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "ULP context is not initialized\n"); 1153bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1154bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1155bdf4a3c6SKishore Padmanabha "ULP context uninitialized"); 1156bdf4a3c6SKishore Padmanabha return -EINVAL; 1157bdf4a3c6SKishore Padmanabha } 11580c036a14SPeter Spreadborough if (unlikely(num_actions != BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS)) { 1159dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "num actions is invalid\n"); 1160bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1161bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ATTR, NULL, 1162bdf4a3c6SKishore Padmanabha "num actions is invalid"); 1163bdf4a3c6SKishore Padmanabha return -EINVAL; 1164bdf4a3c6SKishore Padmanabha } 1165bdf4a3c6SKishore Padmanabha while (action_item && action_item->type != RTE_FLOW_ACTION_TYPE_END) { 11660c036a14SPeter Spreadborough if (unlikely(action_item->type == (typeof(tun_entry->action.type)) 11670c036a14SPeter Spreadborough BNXT_RTE_FLOW_ACTION_TYPE_VXLAN_DECAP)) { 1168bdf4a3c6SKishore Padmanabha tun_entry = ulp_app_tun_match_entry(ulp_ctx, 1169bdf4a3c6SKishore Padmanabha action_item->conf); 1170bdf4a3c6SKishore Padmanabha ulp_app_tun_entry_delete(tun_entry); 1171bdf4a3c6SKishore Padmanabha } 1172bdf4a3c6SKishore Padmanabha action_item++; 1173bdf4a3c6SKishore Padmanabha } 1174bdf4a3c6SKishore Padmanabha return 0; 1175bdf4a3c6SKishore Padmanabha } 1176bdf4a3c6SKishore Padmanabha 1177bdf4a3c6SKishore Padmanabha static int 1178bdf4a3c6SKishore Padmanabha bnxt_ulp_tunnel_item_release(struct rte_eth_dev *eth_dev, 1179bdf4a3c6SKishore Padmanabha struct rte_flow_item *pmd_items, 1180bdf4a3c6SKishore Padmanabha uint32_t num_items, 1181bdf4a3c6SKishore Padmanabha struct rte_flow_error *error) 1182bdf4a3c6SKishore Padmanabha { 1183bdf4a3c6SKishore Padmanabha struct bnxt_ulp_context *ulp_ctx; 1184bdf4a3c6SKishore Padmanabha struct bnxt_flow_app_tun_ent *tun_entry; 1185bdf4a3c6SKishore Padmanabha 1186bdf4a3c6SKishore Padmanabha ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev); 11870c036a14SPeter Spreadborough if (unlikely(ulp_ctx == NULL)) { 1188dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "ULP context is not initialized\n"); 1189bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1190bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 1191bdf4a3c6SKishore Padmanabha "ULP context uninitialized"); 1192bdf4a3c6SKishore Padmanabha return -EINVAL; 1193bdf4a3c6SKishore Padmanabha } 11940c036a14SPeter Spreadborough if (unlikely(num_items != BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS)) { 1195dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "num items is invalid\n"); 1196bdf4a3c6SKishore Padmanabha rte_flow_error_set(error, EINVAL, 1197bdf4a3c6SKishore Padmanabha RTE_FLOW_ERROR_TYPE_ATTR, NULL, 1198bdf4a3c6SKishore Padmanabha "num items is invalid"); 1199bdf4a3c6SKishore Padmanabha return -EINVAL; 1200bdf4a3c6SKishore Padmanabha } 1201bdf4a3c6SKishore Padmanabha 1202bdf4a3c6SKishore Padmanabha tun_entry = ulp_app_tun_match_entry(ulp_ctx, pmd_items->spec); 1203bdf4a3c6SKishore Padmanabha ulp_app_tun_entry_delete(tun_entry); 1204bdf4a3c6SKishore Padmanabha return 0; 1205bdf4a3c6SKishore Padmanabha } 1206bdf4a3c6SKishore Padmanabha 120782b509d3SKishore Padmanabha const struct rte_flow_ops bnxt_ulp_rte_flow_ops = { 1208f88b99c9SKishore Padmanabha .validate = bnxt_ulp_flow_validate, 120982b509d3SKishore Padmanabha .create = bnxt_ulp_flow_create, 121077847233SKishore Padmanabha .destroy = bnxt_ulp_flow_destroy, 1211edc6ca0cSKishore Padmanabha .flush = bnxt_ulp_flow_flush, 1212306c2d28SSomnath Kotur .query = bnxt_ulp_flow_query, 1213bdf4a3c6SKishore Padmanabha .isolate = NULL, 12146d160d77SRandy Schacher .action_handle_create = bnxt_ulp_action_handle_create, 12156d160d77SRandy Schacher .action_handle_destroy = bnxt_ulp_action_handle_destroy, 1216bdf4a3c6SKishore Padmanabha /* Tunnel offload callbacks */ 1217bdf4a3c6SKishore Padmanabha .tunnel_decap_set = bnxt_ulp_tunnel_decap_set, 1218bdf4a3c6SKishore Padmanabha .tunnel_match = bnxt_ulp_tunnel_match, 1219bdf4a3c6SKishore Padmanabha .tunnel_action_decap_release = bnxt_ulp_tunnel_decap_release, 1220bdf4a3c6SKishore Padmanabha .tunnel_item_release = bnxt_ulp_tunnel_item_release, 1221bdf4a3c6SKishore Padmanabha .get_restore_info = NULL 122282b509d3SKishore Padmanabha }; 1223