1696843ccSMike Baucom /* SPDX-License-Identifier: BSD-3-Clause 2d9e70b1dSRandy Schacher * Copyright(c) 2014-2023 Broadcom 3696843ccSMike Baucom * All rights reserved. 4696843ccSMike Baucom */ 5696843ccSMike Baucom 6696843ccSMike Baucom #include <rte_log.h> 7072cb4a8SMike Baucom #include <rte_malloc.h> 8696843ccSMike Baucom #include "bnxt.h" 98ce17d56SKishore Padmanabha #include "ulp_template_db_enum.h" 10696843ccSMike Baucom #include "ulp_template_struct.h" 11696843ccSMike Baucom #include "bnxt_tf_common.h" 12696843ccSMike Baucom #include "ulp_utils.h" 13696843ccSMike Baucom #include "bnxt_ulp.h" 140c036a14SPeter Spreadborough #include "bnxt_ulp_utils.h" 15696843ccSMike Baucom #include "tfp.h" 16696843ccSMike Baucom #include "tf_ext_flow_handle.h" 17696843ccSMike Baucom #include "ulp_mark_mgr.h" 18696843ccSMike Baucom #include "ulp_mapper.h" 19be8acb27SKishore Padmanabha #include "ulp_flow_db.h" 2056388182SKishore Padmanabha #include "tf_util.h" 21c5d06df4SMike Baucom #include "ulp_template_db_tbl.h" 22ddaf0afaSKishore Padmanabha #include "ulp_port_db.h" 233184b1efSMike Baucom #include "ulp_ha_mgr.h" 241993b267SShahaji Bhosle #include "bnxt_tf_pmd_shim.h" 25288becfbSShuanglin Wang #ifdef TF_FLOW_SCALE_QUERY 26288becfbSShuanglin Wang #include "tf_resources.h" 27ffbc3529SShuanglin Wang #include "tfc_resources.h" 28288becfbSShuanglin Wang #endif /* TF_FLOW_SCALE_QUERY */ 29696843ccSMike Baucom 30286569d5SKishore Padmanabha static uint8_t mapper_fld_zeros[16] = { 0 }; 31286569d5SKishore Padmanabha 32255add67SKishore Padmanabha static uint8_t mapper_fld_ones[16] = { 33255add67SKishore Padmanabha 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 34255add67SKishore Padmanabha 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 35255add67SKishore Padmanabha }; 36255add67SKishore Padmanabha 37286569d5SKishore Padmanabha static uint8_t mapper_fld_one[16] = { 38286569d5SKishore Padmanabha 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 39286569d5SKishore Padmanabha 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 40286569d5SKishore Padmanabha }; 41286569d5SKishore Padmanabha 42dd0191d5SShuanglin Wang static int32_t 43dd0191d5SShuanglin Wang ulp_mapper_cond_opc_list_process(struct bnxt_ulp_mapper_parms *parms, 44dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_cond_list_info *info, 45dd0191d5SShuanglin Wang int32_t *res); 46dd0191d5SShuanglin Wang 47dd0191d5SShuanglin Wang static const struct ulp_mapper_core_ops * 48dd0191d5SShuanglin Wang bnxt_ulp_mapper_ops_get(struct bnxt *bp) 49dd0191d5SShuanglin Wang { 50dd0191d5SShuanglin Wang int32_t rc; 51dd0191d5SShuanglin Wang enum bnxt_ulp_device_id dev_id; 52dd0191d5SShuanglin Wang const struct ulp_mapper_core_ops *func_ops; 53dd0191d5SShuanglin Wang 54dd0191d5SShuanglin Wang rc = bnxt_ulp_devid_get(bp, &dev_id); 550c036a14SPeter Spreadborough if (unlikely(rc)) 56dd0191d5SShuanglin Wang return NULL; 57dd0191d5SShuanglin Wang 58dd0191d5SShuanglin Wang switch (dev_id) { 59dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_THOR2: 60dd0191d5SShuanglin Wang func_ops = &ulp_mapper_tfc_core_ops; 61dd0191d5SShuanglin Wang break; 62dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_THOR: 63dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_STINGRAY: 64dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_WH_PLUS: 65dd0191d5SShuanglin Wang func_ops = &ulp_mapper_tf_core_ops; 66dd0191d5SShuanglin Wang break; 67dd0191d5SShuanglin Wang default: 68dd0191d5SShuanglin Wang func_ops = NULL; 69dd0191d5SShuanglin Wang break; 70dd0191d5SShuanglin Wang } 71dd0191d5SShuanglin Wang return func_ops; 72dd0191d5SShuanglin Wang } 73dd0191d5SShuanglin Wang 74dd0191d5SShuanglin Wang static const struct ulp_mapper_core_ops * 75dd0191d5SShuanglin Wang ulp_mapper_data_oper_get(struct bnxt_ulp_context *ulp_ctx) 76dd0191d5SShuanglin Wang { 77dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_data *m_data; 78dd0191d5SShuanglin Wang 79dd0191d5SShuanglin Wang m_data = (struct bnxt_ulp_mapper_data *)ulp_ctx->cfg_data->mapper_data; 80dd0191d5SShuanglin Wang return m_data->mapper_oper; 81dd0191d5SShuanglin Wang } 82dd0191d5SShuanglin Wang 83a2417601SKishore Padmanabha static const char * 84a2417601SKishore Padmanabha ulp_mapper_tmpl_name_str(enum bnxt_ulp_template_type tmpl_type) 85a2417601SKishore Padmanabha { 86a2417601SKishore Padmanabha switch (tmpl_type) { 87a2417601SKishore Padmanabha case BNXT_ULP_TEMPLATE_TYPE_CLASS: 88a2417601SKishore Padmanabha return "class"; 89a2417601SKishore Padmanabha case BNXT_ULP_TEMPLATE_TYPE_ACTION: 90a2417601SKishore Padmanabha return "action"; 91a2417601SKishore Padmanabha default: 92a2417601SKishore Padmanabha return "invalid template type"; 93a2417601SKishore Padmanabha } 94a2417601SKishore Padmanabha } 95a2417601SKishore Padmanabha 96bfcaae8fSKishore Padmanabha static struct bnxt_ulp_glb_resource_info * 97bfcaae8fSKishore Padmanabha ulp_mapper_glb_resource_info_list_get(uint32_t *num_entries) 98072cb4a8SMike Baucom { 990c036a14SPeter Spreadborough if (unlikely(!num_entries)) 100072cb4a8SMike Baucom return NULL; 1015b648b90SKishore Padmanabha *num_entries = BNXT_ULP_GLB_RESOURCE_TBL_MAX_SZ; 102bfcaae8fSKishore Padmanabha return ulp_glb_resource_tbl; 103072cb4a8SMike Baucom } 104072cb4a8SMike Baucom 105072cb4a8SMike Baucom /* 106bfcaae8fSKishore Padmanabha * Read the global resource from the mapper global resource list 107072cb4a8SMike Baucom * 108072cb4a8SMike Baucom * The regval is always returned in big-endian. 109072cb4a8SMike Baucom * 110072cb4a8SMike Baucom * returns 0 on success 111072cb4a8SMike Baucom */ 112dd0191d5SShuanglin Wang int32_t 113bfcaae8fSKishore Padmanabha ulp_mapper_glb_resource_read(struct bnxt_ulp_mapper_data *mapper_data, 114072cb4a8SMike Baucom enum tf_dir dir, 115072cb4a8SMike Baucom uint16_t idx, 116c6062ec0SMike Baucom uint64_t *regval, 117c6062ec0SMike Baucom bool *shared) 118072cb4a8SMike Baucom { 1190c036a14SPeter Spreadborough if (unlikely(!mapper_data || !regval || !shared || 1200c036a14SPeter Spreadborough dir >= TF_DIR_MAX || idx >= BNXT_ULP_GLB_RF_IDX_LAST)) 121072cb4a8SMike Baucom return -EINVAL; 122bfcaae8fSKishore Padmanabha 123bfcaae8fSKishore Padmanabha *regval = mapper_data->glb_res_tbl[dir][idx].resource_hndl; 124c6062ec0SMike Baucom *shared = mapper_data->glb_res_tbl[dir][idx].shared; 125072cb4a8SMike Baucom return 0; 126072cb4a8SMike Baucom } 127072cb4a8SMike Baucom 128072cb4a8SMike Baucom /* 129bfcaae8fSKishore Padmanabha * Write a global resource to the mapper global resource list 130072cb4a8SMike Baucom * 131072cb4a8SMike Baucom * The regval value must be in big-endian. 132072cb4a8SMike Baucom * 133072cb4a8SMike Baucom * return 0 on success. 134072cb4a8SMike Baucom */ 135dd0191d5SShuanglin Wang int32_t 136bfcaae8fSKishore Padmanabha ulp_mapper_glb_resource_write(struct bnxt_ulp_mapper_data *data, 137bfcaae8fSKishore Padmanabha struct bnxt_ulp_glb_resource_info *res, 138c6062ec0SMike Baucom uint64_t regval, bool shared) 139072cb4a8SMike Baucom { 140bfcaae8fSKishore Padmanabha struct bnxt_ulp_mapper_glb_resource_entry *ent; 141bfcaae8fSKishore Padmanabha 142bfcaae8fSKishore Padmanabha /* validate the arguments */ 1430c036a14SPeter Spreadborough if (unlikely(!data || res->direction >= TF_DIR_MAX || 1440c036a14SPeter Spreadborough res->glb_regfile_index >= BNXT_ULP_GLB_RF_IDX_LAST)) 145072cb4a8SMike Baucom return -EINVAL; 146bfcaae8fSKishore Padmanabha 147bfcaae8fSKishore Padmanabha /* write to the mapper data */ 148bfcaae8fSKishore Padmanabha ent = &data->glb_res_tbl[res->direction][res->glb_regfile_index]; 149bfcaae8fSKishore Padmanabha ent->resource_func = res->resource_func; 150bfcaae8fSKishore Padmanabha ent->resource_type = res->resource_type; 151bfcaae8fSKishore Padmanabha ent->resource_hndl = regval; 152c6062ec0SMike Baucom ent->shared = shared; 153072cb4a8SMike Baucom return 0; 154072cb4a8SMike Baucom } 155072cb4a8SMike Baucom 156bfcaae8fSKishore Padmanabha /* 157bfcaae8fSKishore Padmanabha * Internal function to allocate identity resource and store it in mapper data. 158bfcaae8fSKishore Padmanabha * 159bfcaae8fSKishore Padmanabha * returns 0 on success 160bfcaae8fSKishore Padmanabha */ 161dd0191d5SShuanglin Wang int32_t 162d097b460SKishore Padmanabha ulp_mapper_resource_ident_allocate(struct bnxt_ulp_context *ulp_ctx, 163bfcaae8fSKishore Padmanabha struct bnxt_ulp_mapper_data *mapper_data, 164d9e70b1dSRandy Schacher struct bnxt_ulp_glb_resource_info *glb_res, 165d9e70b1dSRandy Schacher bool shared) 166bfcaae8fSKishore Padmanabha { 167dd0191d5SShuanglin Wang const struct ulp_mapper_core_ops *op = mapper_data->mapper_oper; 168dd0191d5SShuanglin Wang uint32_t session_type = BNXT_ULP_SESSION_TYPE_DEFAULT; 169dd0191d5SShuanglin Wang struct ulp_flow_db_res_params res = { 0 }; 170dd0191d5SShuanglin Wang uint64_t regval, id = 0; 171bfcaae8fSKishore Padmanabha int32_t rc = 0; 172bfcaae8fSKishore Padmanabha 173dd0191d5SShuanglin Wang session_type = shared ? BNXT_ULP_SESSION_TYPE_SHARED : 174dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_DEFAULT; 175d097b460SKishore Padmanabha 1762aa70990SKishore Padmanabha /* Global identifiers are tracked by session */ 177dd0191d5SShuanglin Wang rc = op->ulp_mapper_core_ident_alloc_process(ulp_ctx, 178dd0191d5SShuanglin Wang session_type, 179dd0191d5SShuanglin Wang glb_res->resource_type, 1802aa70990SKishore Padmanabha glb_res->direction, 1812aa70990SKishore Padmanabha CFA_TRACK_TYPE_SID, 1822aa70990SKishore Padmanabha &id); 1830c036a14SPeter Spreadborough if (unlikely(rc)) 184bfcaae8fSKishore Padmanabha return rc; 185bfcaae8fSKishore Padmanabha 186bfcaae8fSKishore Padmanabha /* entries are stored as big-endian format */ 187dd0191d5SShuanglin Wang regval = tfp_cpu_to_be_64(id); 188c6062ec0SMike Baucom /* 189c6062ec0SMike Baucom * write to the mapper global resource 190c6062ec0SMike Baucom * Shared resources are never allocated through this method, so the 191c6062ec0SMike Baucom * shared flag is always false. 192c6062ec0SMike Baucom */ 1936d160d77SRandy Schacher rc = ulp_mapper_glb_resource_write(mapper_data, glb_res, regval, shared); 1940c036a14SPeter Spreadborough if (unlikely(rc)) { 195dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to write to global resource id\n"); 196bfcaae8fSKishore Padmanabha /* Free the identifier when update failed */ 197dd0191d5SShuanglin Wang res.direction = glb_res->direction; 198dd0191d5SShuanglin Wang res.resource_type = glb_res->resource_type; 199dd0191d5SShuanglin Wang res.resource_hndl = id; 200dd0191d5SShuanglin Wang op->ulp_mapper_core_ident_free(ulp_ctx, &res); 201bfcaae8fSKishore Padmanabha return rc; 202bfcaae8fSKishore Padmanabha } 203bfcaae8fSKishore Padmanabha return rc; 204bfcaae8fSKishore Padmanabha } 205bfcaae8fSKishore Padmanabha 206d097b460SKishore Padmanabha /* 207d097b460SKishore Padmanabha * Internal function to allocate index tbl resource and store it in mapper data. 208d097b460SKishore Padmanabha * 209d097b460SKishore Padmanabha * returns 0 on success 210d097b460SKishore Padmanabha */ 211dd0191d5SShuanglin Wang int32_t 212d097b460SKishore Padmanabha ulp_mapper_resource_index_tbl_alloc(struct bnxt_ulp_context *ulp_ctx, 213d097b460SKishore Padmanabha struct bnxt_ulp_mapper_data *mapper_data, 214d9e70b1dSRandy Schacher struct bnxt_ulp_glb_resource_info *glb_res, 215d9e70b1dSRandy Schacher bool shared) 216d097b460SKishore Padmanabha { 217dd0191d5SShuanglin Wang const struct ulp_mapper_core_ops *op = mapper_data->mapper_oper; 218dd0191d5SShuanglin Wang uint32_t session_type = BNXT_ULP_SESSION_TYPE_DEFAULT; 219dd0191d5SShuanglin Wang struct ulp_flow_db_res_params res = { 0 }; 220dd0191d5SShuanglin Wang uint64_t regval, index = 0; 221d097b460SKishore Padmanabha int32_t rc = 0; 222d097b460SKishore Padmanabha 223dd0191d5SShuanglin Wang session_type = shared ? BNXT_ULP_SESSION_TYPE_SHARED : 224dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_DEFAULT; 225d097b460SKishore Padmanabha 226dd0191d5SShuanglin Wang op->ulp_mapper_core_index_tbl_alloc_process(ulp_ctx, session_type, 227dd0191d5SShuanglin Wang glb_res->resource_type, 228dd0191d5SShuanglin Wang glb_res->direction, &index); 229d097b460SKishore Padmanabha 230d097b460SKishore Padmanabha /* entries are stored as big-endian format */ 231dd0191d5SShuanglin Wang regval = tfp_cpu_to_be_64((uint64_t)index); 232c6062ec0SMike Baucom /* 233c6062ec0SMike Baucom * write to the mapper global resource 234c6062ec0SMike Baucom * Shared resources are never allocated through this method, so the 235c6062ec0SMike Baucom * shared flag is always false. 236c6062ec0SMike Baucom */ 2376d160d77SRandy Schacher rc = ulp_mapper_glb_resource_write(mapper_data, glb_res, regval, shared); 2380c036a14SPeter Spreadborough if (unlikely(rc)) { 239dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to write to global resource id\n"); 240dd0191d5SShuanglin Wang /* Free the index when update failed */ 241dd0191d5SShuanglin Wang res.direction = glb_res->direction; 242dd0191d5SShuanglin Wang res.resource_type = glb_res->resource_type; 243dd0191d5SShuanglin Wang res.resource_hndl = index; 244dd0191d5SShuanglin Wang rc = op->ulp_mapper_core_cmm_entry_free(ulp_ctx, &res, NULL); 245d097b460SKishore Padmanabha return rc; 246d097b460SKishore Padmanabha } 247d097b460SKishore Padmanabha return rc; 248d097b460SKishore Padmanabha } 249d097b460SKishore Padmanabha 250a2417601SKishore Padmanabha static int32_t 251a2417601SKishore Padmanabha ulp_mapper_glb_field_tbl_get(struct bnxt_ulp_mapper_parms *parms, 252a2417601SKishore Padmanabha uint32_t operand, 253a2417601SKishore Padmanabha uint8_t *val) 254c5d06df4SMike Baucom { 255a2417601SKishore Padmanabha uint32_t t_idx; 256a2417601SKishore Padmanabha 2570c036a14SPeter Spreadborough if (unlikely(operand >= BNXT_ULP_GLB_FIELD_TBL_SIZE)) { 258dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid hdr field index %x:%x\n", 259dd0191d5SShuanglin Wang parms->class_tid, operand); 260a2417601SKishore Padmanabha *val = 0; 261a2417601SKishore Padmanabha return -EINVAL; /* error */ 262a2417601SKishore Padmanabha } 263dd0191d5SShuanglin Wang 264dd0191d5SShuanglin Wang t_idx = ULP_COMP_FLD_IDX_RD(parms, BNXT_ULP_CF_IDX_HDR_SIG_ID); 265dd0191d5SShuanglin Wang *val = ulp_class_match_list[t_idx].field_list[operand]; 266a2417601SKishore Padmanabha return 0; 267c5d06df4SMike Baucom } 268c5d06df4SMike Baucom 269696843ccSMike Baucom /* 270696843ccSMike Baucom * Get the size of the action property for a given index. 271696843ccSMike Baucom * 272696843ccSMike Baucom * idx [in] The index for the action property 273696843ccSMike Baucom * 274696843ccSMike Baucom * returns the size of the action property. 275696843ccSMike Baucom */ 276696843ccSMike Baucom static uint32_t 277696843ccSMike Baucom ulp_mapper_act_prop_size_get(uint32_t idx) 278696843ccSMike Baucom { 2790c036a14SPeter Spreadborough if (unlikely(idx >= BNXT_ULP_ACT_PROP_IDX_LAST)) 280696843ccSMike Baucom return 0; 281696843ccSMike Baucom return ulp_act_prop_map_table[idx]; 282696843ccSMike Baucom } 283696843ccSMike Baucom 284dd0191d5SShuanglin Wang static struct bnxt_ulp_mapper_cond_list_info * 285c5d06df4SMike Baucom ulp_mapper_tmpl_reject_list_get(struct bnxt_ulp_mapper_parms *mparms, 286dd0191d5SShuanglin Wang uint32_t tid) 287c5d06df4SMike Baucom { 2889cbfa4cfSKishore Padmanabha const struct bnxt_ulp_template_device_tbls *dev_tbls; 289c5d06df4SMike Baucom 290c5d06df4SMike Baucom dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type]; 291dd0191d5SShuanglin Wang return &dev_tbls->tmpl_list[tid].reject_info; 292dd0191d5SShuanglin Wang } 293c5d06df4SMike Baucom 294dd0191d5SShuanglin Wang static struct bnxt_ulp_mapper_cond_list_info * 295dd0191d5SShuanglin Wang ulp_mapper_cond_oper_list_get(struct bnxt_ulp_mapper_parms *mparms, 296dd0191d5SShuanglin Wang uint32_t idx) 297dd0191d5SShuanglin Wang { 298dd0191d5SShuanglin Wang const struct bnxt_ulp_template_device_tbls *dev_tbls; 299dd0191d5SShuanglin Wang 300dd0191d5SShuanglin Wang dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type]; 3010c036a14SPeter Spreadborough if (unlikely(idx >= dev_tbls->cond_oper_list_size)) 302dd0191d5SShuanglin Wang return NULL; 303dd0191d5SShuanglin Wang return &dev_tbls->cond_oper_list[idx]; 304c5d06df4SMike Baucom } 305c5d06df4SMike Baucom 306c5d06df4SMike Baucom static struct bnxt_ulp_mapper_cond_info * 307dd0191d5SShuanglin Wang ulp_mapper_tmpl_cond_list_get(struct bnxt_ulp_mapper_parms *mparms, 308dd0191d5SShuanglin Wang uint32_t idx) 309c5d06df4SMike Baucom { 3109cbfa4cfSKishore Padmanabha const struct bnxt_ulp_template_device_tbls *dev_tbls; 311c5d06df4SMike Baucom 312c5d06df4SMike Baucom dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type]; 3130c036a14SPeter Spreadborough if (unlikely(idx >= dev_tbls->cond_list_size)) 314dd0191d5SShuanglin Wang return NULL; 315c5d06df4SMike Baucom return &dev_tbls->cond_list[idx]; 316c5d06df4SMike Baucom } 317c5d06df4SMike Baucom 318696843ccSMike Baucom /* 31955aeaac3SKishore Padmanabha * Get a list of classifier tables that implement the flow 3208f153057SMike Baucom * Gets a device dependent list of tables that implement the class template id 3218f153057SMike Baucom * 322a4638284SMike Baucom * mparms [in] The mappers parms with data related to the flow. 3238f153057SMike Baucom * 3248f153057SMike Baucom * tid [in] The template id that matches the flow 3258f153057SMike Baucom * 3268f153057SMike Baucom * num_tbls [out] The number of classifier tables in the returned array 3278f153057SMike Baucom * 3288f153057SMike Baucom * returns An array of classifier tables to implement the flow, or NULL on 3298f153057SMike Baucom * error 3308f153057SMike Baucom */ 3318608c099SKishore Padmanabha static struct bnxt_ulp_mapper_tbl_info * 3320c9fe336SMike Baucom ulp_mapper_tbl_list_get(struct bnxt_ulp_mapper_parms *mparms, 3338f153057SMike Baucom uint32_t tid, 3340c9fe336SMike Baucom uint32_t *num_tbls) 3358f153057SMike Baucom { 3368f153057SMike Baucom uint32_t idx; 3379cbfa4cfSKishore Padmanabha const struct bnxt_ulp_template_device_tbls *dev_tbls; 3388f153057SMike Baucom 3390c9fe336SMike Baucom dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type]; 3408f153057SMike Baucom 3410c9fe336SMike Baucom idx = dev_tbls->tmpl_list[tid].start_tbl_idx; 3420c9fe336SMike Baucom *num_tbls = dev_tbls->tmpl_list[tid].num_tbls; 343a4638284SMike Baucom 3440c9fe336SMike Baucom return &dev_tbls->tbl_list[idx]; 3458f153057SMike Baucom } 3468f153057SMike Baucom 3478f153057SMike Baucom /* 3488f153057SMike Baucom * Get the list of key fields that implement the flow. 349696843ccSMike Baucom * 350a4638284SMike Baucom * mparms [in] The mapper parms with information about the flow 351ae905028SMike Baucom * 352ae905028SMike Baucom * tbl [in] A single table instance to get the key fields from 353ae905028SMike Baucom * 354ae905028SMike Baucom * num_flds [out] The number of key fields in the returned array 355ae905028SMike Baucom * 3568f153057SMike Baucom * Returns array of Key fields, or NULL on error. 357ae905028SMike Baucom */ 358dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_key_info * 359a4638284SMike Baucom ulp_mapper_key_fields_get(struct bnxt_ulp_mapper_parms *mparms, 360a4638284SMike Baucom struct bnxt_ulp_mapper_tbl_info *tbl, 361ae905028SMike Baucom uint32_t *num_flds) 362ae905028SMike Baucom { 363ae905028SMike Baucom uint32_t idx; 3649cbfa4cfSKishore Padmanabha const struct bnxt_ulp_template_device_tbls *dev_tbls; 365ae905028SMike Baucom 3660c9fe336SMike Baucom dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type]; 3670c036a14SPeter Spreadborough if (unlikely(!dev_tbls->key_info_list)) { 3680c9fe336SMike Baucom *num_flds = 0; 3690c9fe336SMike Baucom return NULL; 3700c9fe336SMike Baucom } 371ae905028SMike Baucom 372ae905028SMike Baucom idx = tbl->key_start_idx; 373ae905028SMike Baucom *num_flds = tbl->key_num_fields; 374ae905028SMike Baucom 375a2417601SKishore Padmanabha return &dev_tbls->key_info_list[idx]; 376ae905028SMike Baucom } 377ae905028SMike Baucom 378ae905028SMike Baucom /* 379af50070eSKishore Padmanabha * Get the list of partial key fields that implement the flow. 380af50070eSKishore Padmanabha * 381af50070eSKishore Padmanabha * mparms [in] The mapper parms with information about the flow 382af50070eSKishore Padmanabha * 383af50070eSKishore Padmanabha * tbl [in] A single table instance to get the key fields from 384af50070eSKishore Padmanabha * 385af50070eSKishore Padmanabha * Return number of partial fields.return 0 if no partial fields 386af50070eSKishore Padmanabha */ 387af50070eSKishore Padmanabha uint32_t 388af50070eSKishore Padmanabha ulp_mapper_partial_key_fields_get(struct bnxt_ulp_mapper_parms *mparms, 389af50070eSKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl) 390af50070eSKishore Padmanabha { 391af50070eSKishore Padmanabha const struct bnxt_ulp_template_device_tbls *dev_tbls; 392af50070eSKishore Padmanabha 393af50070eSKishore Padmanabha dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type]; 394af50070eSKishore Padmanabha if (!dev_tbls->key_info_list) 395af50070eSKishore Padmanabha return 0; 396af50070eSKishore Padmanabha return tbl->partial_key_num_fields; 397af50070eSKishore Padmanabha } 398af50070eSKishore Padmanabha 399af50070eSKishore Padmanabha /* 400ae905028SMike Baucom * Get the list of data fields that implement the flow. 401ae905028SMike Baucom * 402a4638284SMike Baucom * mparms [in] The mapper parms with information about the flow 403ae905028SMike Baucom * 404ae905028SMike Baucom * tbl [in] A single table instance to get the data fields from 405ae905028SMike Baucom * 406ae905028SMike Baucom * num_flds [out] The number of data fields in the returned array. 407ae905028SMike Baucom * 408a4638284SMike Baucom * num_encap_flds [out] The number of encap fields in the returned array. 409a4638284SMike Baucom * 410ae905028SMike Baucom * Returns array of data fields, or NULL on error. 411ae905028SMike Baucom */ 412a2417601SKishore Padmanabha static struct bnxt_ulp_mapper_field_info * 413a4638284SMike Baucom ulp_mapper_result_fields_get(struct bnxt_ulp_mapper_parms *mparms, 414a4638284SMike Baucom struct bnxt_ulp_mapper_tbl_info *tbl, 41555aeaac3SKishore Padmanabha uint32_t *num_flds, 41655aeaac3SKishore Padmanabha uint32_t *num_encap_flds) 417ae905028SMike Baucom { 418ae905028SMike Baucom uint32_t idx; 4199cbfa4cfSKishore Padmanabha const struct bnxt_ulp_template_device_tbls *dev_tbls; 420ae905028SMike Baucom 4210c9fe336SMike Baucom dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type]; 4220c036a14SPeter Spreadborough if (unlikely(!dev_tbls->result_field_list)) { 4230c9fe336SMike Baucom *num_flds = 0; 4240c9fe336SMike Baucom *num_encap_flds = 0; 4250c9fe336SMike Baucom return NULL; 4260c9fe336SMike Baucom } 427ae905028SMike Baucom 428ae905028SMike Baucom idx = tbl->result_start_idx; 429ae905028SMike Baucom *num_flds = tbl->result_num_fields; 43055aeaac3SKishore Padmanabha *num_encap_flds = tbl->encap_num_fields; 431ae905028SMike Baucom 4320c9fe336SMike Baucom return &dev_tbls->result_field_list[idx]; 433696843ccSMike Baucom } 434696843ccSMike Baucom 435ae905028SMike Baucom /* 436ae905028SMike Baucom * Get the list of ident fields that implement the flow 437ae905028SMike Baucom * 438ae905028SMike Baucom * tbl [in] A single table instance to get the ident fields from 439ae905028SMike Baucom * 440ae905028SMike Baucom * num_flds [out] The number of ident fields in the returned array 441ae905028SMike Baucom * 442ae905028SMike Baucom * returns array of ident fields, or NULL on error 443ae905028SMike Baucom */ 444ae905028SMike Baucom static struct bnxt_ulp_mapper_ident_info * 445a4638284SMike Baucom ulp_mapper_ident_fields_get(struct bnxt_ulp_mapper_parms *mparms, 446a4638284SMike Baucom struct bnxt_ulp_mapper_tbl_info *tbl, 447ae905028SMike Baucom uint32_t *num_flds) 448ae905028SMike Baucom { 449ae905028SMike Baucom uint32_t idx; 4509cbfa4cfSKishore Padmanabha const struct bnxt_ulp_template_device_tbls *dev_tbls; 4510c9fe336SMike Baucom 4520c9fe336SMike Baucom dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type]; 4530c036a14SPeter Spreadborough if (unlikely(!dev_tbls->ident_list)) { 4540c9fe336SMike Baucom *num_flds = 0; 4550c9fe336SMike Baucom return NULL; 4560c9fe336SMike Baucom } 457ae905028SMike Baucom 458ae905028SMike Baucom idx = tbl->ident_start_idx; 459ae905028SMike Baucom *num_flds = tbl->ident_nums; 460ae905028SMike Baucom 4610c9fe336SMike Baucom return &dev_tbls->ident_list[idx]; 462ae905028SMike Baucom } 463ae905028SMike Baucom 464dd0191d5SShuanglin Wang static struct bnxt_ulp_mapper_field_info * 465dd0191d5SShuanglin Wang ulp_mapper_tmpl_key_ext_list_get(struct bnxt_ulp_mapper_parms *mparms, 466dd0191d5SShuanglin Wang uint32_t idx) 467dbd29c42SKishore Padmanabha { 468dd0191d5SShuanglin Wang const struct bnxt_ulp_template_device_tbls *dev_tbls; 469dbd29c42SKishore Padmanabha 470dd0191d5SShuanglin Wang dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type]; 4710c036a14SPeter Spreadborough if (unlikely(idx >= dev_tbls->key_ext_list_size)) 472dd0191d5SShuanglin Wang return NULL; 473dd0191d5SShuanglin Wang return &dev_tbls->key_ext_list[idx]; 47405a11d7dSMike Baucom } 47505a11d7dSMike Baucom 47605a11d7dSMike Baucom static inline int32_t 47705a11d7dSMike Baucom ulp_mapper_mark_free(struct bnxt_ulp_context *ulp, 47805a11d7dSMike Baucom struct ulp_flow_db_res_params *res) 47905a11d7dSMike Baucom { 48005a11d7dSMike Baucom return ulp_mark_db_mark_del(ulp, 4818a32d5c4SKishore Padmanabha res->resource_type, 4828a32d5c4SKishore Padmanabha res->resource_hndl); 48305a11d7dSMike Baucom } 48405a11d7dSMike Baucom 485be8acb27SKishore Padmanabha static inline int32_t 486be8acb27SKishore Padmanabha ulp_mapper_parent_flow_free(struct bnxt_ulp_context *ulp, 487be8acb27SKishore Padmanabha uint32_t parent_fid, 488be8acb27SKishore Padmanabha struct ulp_flow_db_res_params *res) 489be8acb27SKishore Padmanabha { 490bdf4a3c6SKishore Padmanabha uint32_t pc_idx; 491be8acb27SKishore Padmanabha 492bdf4a3c6SKishore Padmanabha pc_idx = (uint32_t)res->resource_hndl; 493be8acb27SKishore Padmanabha 494bdf4a3c6SKishore Padmanabha /* reset the child flow bitset*/ 4950c036a14SPeter Spreadborough if (unlikely(ulp_flow_db_pc_db_parent_flow_set(ulp, pc_idx, parent_fid, 0))) { 496dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "error in reset parent flow bitset %x:%x\n", 497bdf4a3c6SKishore Padmanabha pc_idx, parent_fid); 498be8acb27SKishore Padmanabha return -EINVAL; 499be8acb27SKishore Padmanabha } 500be8acb27SKishore Padmanabha return 0; 501be8acb27SKishore Padmanabha } 502be8acb27SKishore Padmanabha 503be8acb27SKishore Padmanabha static inline int32_t 504be8acb27SKishore Padmanabha ulp_mapper_child_flow_free(struct bnxt_ulp_context *ulp, 505be8acb27SKishore Padmanabha uint32_t child_fid, 506be8acb27SKishore Padmanabha struct ulp_flow_db_res_params *res) 507be8acb27SKishore Padmanabha { 508bdf4a3c6SKishore Padmanabha uint32_t pc_idx; 509be8acb27SKishore Padmanabha 510bdf4a3c6SKishore Padmanabha pc_idx = (uint32_t)res->resource_hndl; 511be8acb27SKishore Padmanabha 512be8acb27SKishore Padmanabha /* reset the child flow bitset*/ 5130c036a14SPeter Spreadborough if (unlikely(ulp_flow_db_pc_db_child_flow_set(ulp, pc_idx, child_fid, 0))) { 514dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 515dd0191d5SShuanglin Wang "error in resetting child flow bitset %x:%x\n", 516bdf4a3c6SKishore Padmanabha pc_idx, child_fid); 517be8acb27SKishore Padmanabha return -EINVAL; 518be8acb27SKishore Padmanabha } 519be8acb27SKishore Padmanabha return 0; 520be8acb27SKishore Padmanabha } 521be8acb27SKishore Padmanabha 5224bc32a80SMike Baucom /* 523a2417601SKishore Padmanabha * Process the flow database opcode alloc action. 524a2417601SKishore Padmanabha * returns 0 on success 525a2417601SKishore Padmanabha */ 526a2417601SKishore Padmanabha static int32_t 527a2417601SKishore Padmanabha ulp_mapper_fdb_opc_alloc_rid(struct bnxt_ulp_mapper_parms *parms, 528a2417601SKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl) 529a2417601SKishore Padmanabha { 530a2417601SKishore Padmanabha uint32_t rid = 0; 531a2417601SKishore Padmanabha uint64_t val64; 532a2417601SKishore Padmanabha int32_t rc = 0; 533a2417601SKishore Padmanabha 534a2417601SKishore Padmanabha /* allocate a new fid */ 535a2417601SKishore Padmanabha rc = ulp_flow_db_fid_alloc(parms->ulp_ctx, 536a2417601SKishore Padmanabha BNXT_ULP_FDB_TYPE_RID, 537a2417601SKishore Padmanabha 0, &rid); 5380c036a14SPeter Spreadborough if (unlikely(rc)) { 539dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 540a2417601SKishore Padmanabha "Unable to allocate flow table entry\n"); 541a2417601SKishore Padmanabha return -EINVAL; 542a2417601SKishore Padmanabha } 543a2417601SKishore Padmanabha /* Store the allocated fid in regfile*/ 544a2417601SKishore Padmanabha val64 = rid; 545a2417601SKishore Padmanabha rc = ulp_regfile_write(parms->regfile, tbl->fdb_operand, 546a2417601SKishore Padmanabha tfp_cpu_to_be_64(val64)); 5470c036a14SPeter Spreadborough if (unlikely(rc)) { 548dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Write regfile[%d] failed\n", 549a2417601SKishore Padmanabha tbl->fdb_operand); 550a2417601SKishore Padmanabha ulp_flow_db_fid_free(parms->ulp_ctx, 551a2417601SKishore Padmanabha BNXT_ULP_FDB_TYPE_RID, rid); 552a2417601SKishore Padmanabha return -EINVAL; 553a2417601SKishore Padmanabha } 5546d160d77SRandy Schacher /* save the rid into the parms in case a flow fails before pushing the 5556d160d77SRandy Schacher * rid into the fid 5566d160d77SRandy Schacher */ 5576d160d77SRandy Schacher parms->rid = rid; 558a2417601SKishore Padmanabha return 0; 559a2417601SKishore Padmanabha } 560a2417601SKishore Padmanabha 561a2417601SKishore Padmanabha /* 5620117293cSKishore Padmanabha * Process the flow database opcode action. 5630117293cSKishore Padmanabha * returns 0 on success. 5640117293cSKishore Padmanabha */ 565dd0191d5SShuanglin Wang int32_t 5660117293cSKishore Padmanabha ulp_mapper_fdb_opc_process(struct bnxt_ulp_mapper_parms *parms, 5670117293cSKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl, 5680117293cSKishore Padmanabha struct ulp_flow_db_res_params *fid_parms) 5690117293cSKishore Padmanabha { 570a2417601SKishore Padmanabha uint32_t push_fid; 5710c036a14SPeter Spreadborough uint64_t val64 = 0; 572a2417601SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type; 5730117293cSKishore Padmanabha int32_t rc = 0; 5740117293cSKishore Padmanabha 5750117293cSKishore Padmanabha switch (tbl->fdb_opcode) { 576255add67SKishore Padmanabha case BNXT_ULP_FDB_OPC_PUSH_FID: 577dd0191d5SShuanglin Wang push_fid = parms->flow_id; 578a2417601SKishore Padmanabha flow_type = parms->flow_type; 5790117293cSKishore Padmanabha break; 580255add67SKishore Padmanabha case BNXT_ULP_FDB_OPC_PUSH_RID_REGFILE: 5810117293cSKishore Padmanabha /* get the fid from the regfile */ 582a2417601SKishore Padmanabha rc = ulp_regfile_read(parms->regfile, tbl->fdb_operand, 5830117293cSKishore Padmanabha &val64); 5840c036a14SPeter Spreadborough if (unlikely(rc)) { 585dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "regfile[%d] read oob\n", 586a2417601SKishore Padmanabha tbl->fdb_operand); 5870117293cSKishore Padmanabha return -EINVAL; 5880117293cSKishore Padmanabha } 5890117293cSKishore Padmanabha /* Use the extracted fid to update the flow resource */ 590a2417601SKishore Padmanabha push_fid = (uint32_t)tfp_be_to_cpu_64(val64); 591a2417601SKishore Padmanabha flow_type = BNXT_ULP_FDB_TYPE_RID; 5920117293cSKishore Padmanabha break; 59349cdf043SKishore Padmanabha case BNXT_ULP_FDB_OPC_PUSH_FID_SW_ONLY: 59449cdf043SKishore Padmanabha push_fid = parms->flow_id; 59549cdf043SKishore Padmanabha flow_type = parms->flow_type; 596f6e12015SKishore Padmanabha fid_parms->fdb_flags = ULP_FDB_FLAG_SW_ONLY; 59749cdf043SKishore Padmanabha break; 5980117293cSKishore Padmanabha default: 5990117293cSKishore Padmanabha return rc; /* Nothing to be done */ 6000117293cSKishore Padmanabha } 6010117293cSKishore Padmanabha 6020117293cSKishore Padmanabha /* Add the resource to the flow database */ 603a2417601SKishore Padmanabha rc = ulp_flow_db_resource_add(parms->ulp_ctx, flow_type, 6040117293cSKishore Padmanabha push_fid, fid_parms); 6050c036a14SPeter Spreadborough if (unlikely(rc)) 606dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to add res to flow %x rc = %d\n", 6070117293cSKishore Padmanabha push_fid, rc); 608dd0191d5SShuanglin Wang 6090117293cSKishore Padmanabha return rc; 6100117293cSKishore Padmanabha } 6110117293cSKishore Padmanabha 6120117293cSKishore Padmanabha /* 6139cbfa4cfSKishore Padmanabha * Process the flow database opcode action. 6149cbfa4cfSKishore Padmanabha * returns 0 on success. 6159cbfa4cfSKishore Padmanabha */ 616dd0191d5SShuanglin Wang int32_t 6179cbfa4cfSKishore Padmanabha ulp_mapper_priority_opc_process(struct bnxt_ulp_mapper_parms *parms, 6189cbfa4cfSKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl, 6199cbfa4cfSKishore Padmanabha uint32_t *priority) 6209cbfa4cfSKishore Padmanabha { 621af50070eSKishore Padmanabha uint64_t regval = 0; 6229cbfa4cfSKishore Padmanabha int32_t rc = 0; 6239cbfa4cfSKishore Padmanabha 6249cbfa4cfSKishore Padmanabha switch (tbl->pri_opcode) { 6259cbfa4cfSKishore Padmanabha case BNXT_ULP_PRI_OPC_NOT_USED: 62674cab005SRandy Schacher *priority = bnxt_ulp_default_app_priority_get(parms->ulp_ctx); 6279cbfa4cfSKishore Padmanabha break; 6289cbfa4cfSKishore Padmanabha case BNXT_ULP_PRI_OPC_CONST: 6299cbfa4cfSKishore Padmanabha *priority = tbl->pri_operand; 6309cbfa4cfSKishore Padmanabha break; 6319cbfa4cfSKishore Padmanabha case BNXT_ULP_PRI_OPC_APP_PRI: 6329cbfa4cfSKishore Padmanabha *priority = parms->app_priority; 6339cbfa4cfSKishore Padmanabha break; 634d9e70b1dSRandy Schacher case BNXT_ULP_PRI_OPC_APP_PRI_OR_CONST: 635d9e70b1dSRandy Schacher if (parms->app_priority) 636d9e70b1dSRandy Schacher *priority = parms->app_priority; 637d9e70b1dSRandy Schacher else 638d9e70b1dSRandy Schacher *priority = tbl->pri_operand; 639d9e70b1dSRandy Schacher break; 640af50070eSKishore Padmanabha case BNXT_ULP_PRI_OPC_REGFILE: 6410c036a14SPeter Spreadborough if (unlikely(ulp_regfile_read(parms->regfile, tbl->pri_operand, 6420c036a14SPeter Spreadborough ®val))) { 643af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, "regfile[%u] read oob\n", 644af50070eSKishore Padmanabha tbl->pri_operand); 645af50070eSKishore Padmanabha rc = -EINVAL; 646af50070eSKishore Padmanabha } 647af50070eSKishore Padmanabha *priority = (uint32_t)tfp_be_to_cpu_64(regval); 648af50070eSKishore Padmanabha break; 649af50070eSKishore Padmanabha case BNXT_ULP_PRI_OPC_COMP_FIELD: 6500c036a14SPeter Spreadborough if (likely(tbl->pri_operand < BNXT_ULP_CF_IDX_LAST)) { 651af50070eSKishore Padmanabha regval = ULP_COMP_FLD_IDX_RD(parms, tbl->pri_operand); 652af50070eSKishore Padmanabha *priority = regval; 653af50070eSKishore Padmanabha } else { 654af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, "comp field out of bounds %u\n", 655af50070eSKishore Padmanabha tbl->pri_operand); 656af50070eSKishore Padmanabha rc = -EINVAL; 657af50070eSKishore Padmanabha } 658af50070eSKishore Padmanabha break; 6599cbfa4cfSKishore Padmanabha default: 660dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Priority opcode not supported %d\n", 6619cbfa4cfSKishore Padmanabha tbl->pri_opcode); 6629cbfa4cfSKishore Padmanabha rc = -EINVAL; 6639cbfa4cfSKishore Padmanabha break; 6649cbfa4cfSKishore Padmanabha } 66522b65613SKishore Padmanabha #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 66622b65613SKishore Padmanabha #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 66722b65613SKishore Padmanabha if (!rc) 66822b65613SKishore Padmanabha BNXT_DRV_DBG(DEBUG, "Tcam priority = 0x%x\n", *priority); 66922b65613SKishore Padmanabha #endif 67022b65613SKishore Padmanabha #endif 6719cbfa4cfSKishore Padmanabha return rc; 6729cbfa4cfSKishore Padmanabha } 6739cbfa4cfSKishore Padmanabha 6749cbfa4cfSKishore Padmanabha /* 675aebe3cb7SKishore Padmanabha * Process the identifier list in the given table. 676aebe3cb7SKishore Padmanabha * Extract the ident from the table entry and 677aebe3cb7SKishore Padmanabha * write it to the reg file. 678aebe3cb7SKishore Padmanabha * returns 0 on success. 679aebe3cb7SKishore Padmanabha */ 680dd0191d5SShuanglin Wang int32_t 681aebe3cb7SKishore Padmanabha ulp_mapper_tbl_ident_scan_ext(struct bnxt_ulp_mapper_parms *parms, 682aebe3cb7SKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl, 683aebe3cb7SKishore Padmanabha uint8_t *byte_data, 684aebe3cb7SKishore Padmanabha uint32_t byte_data_size, 685aebe3cb7SKishore Padmanabha enum bnxt_ulp_byte_order byte_order) 686aebe3cb7SKishore Padmanabha { 687aebe3cb7SKishore Padmanabha struct bnxt_ulp_mapper_ident_info *idents; 688aebe3cb7SKishore Padmanabha uint32_t i, num_idents = 0; 689aebe3cb7SKishore Padmanabha uint64_t val64; 690aebe3cb7SKishore Padmanabha 691aebe3cb7SKishore Padmanabha /* validate the null arguments */ 6920c036a14SPeter Spreadborough if (unlikely(!byte_data)) { 693dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "invalid argument\n"); 694aebe3cb7SKishore Padmanabha return -EINVAL; 695aebe3cb7SKishore Padmanabha } 696aebe3cb7SKishore Padmanabha 697aebe3cb7SKishore Padmanabha /* Get the ident list and process each one */ 698aebe3cb7SKishore Padmanabha idents = ulp_mapper_ident_fields_get(parms, tbl, &num_idents); 699aebe3cb7SKishore Padmanabha 700aebe3cb7SKishore Padmanabha for (i = 0; i < num_idents; i++) { 701aebe3cb7SKishore Padmanabha /* check the size of the buffer for validation */ 7020c036a14SPeter Spreadborough if (unlikely((idents[i].ident_bit_pos + idents[i].ident_bit_size) > 703aebe3cb7SKishore Padmanabha ULP_BYTE_2_BITS(byte_data_size) || 7040c036a14SPeter Spreadborough idents[i].ident_bit_size > ULP_BYTE_2_BITS(sizeof(val64)))) { 705dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "invalid offset or length %x:%x:%x\n", 706aebe3cb7SKishore Padmanabha idents[i].ident_bit_pos, 707aebe3cb7SKishore Padmanabha idents[i].ident_bit_size, 708aebe3cb7SKishore Padmanabha byte_data_size); 709aebe3cb7SKishore Padmanabha return -EINVAL; 710aebe3cb7SKishore Padmanabha } 711a2417601SKishore Padmanabha val64 = 0; 712aebe3cb7SKishore Padmanabha if (byte_order == BNXT_ULP_BYTE_ORDER_LE) 713aebe3cb7SKishore Padmanabha ulp_bs_pull_lsb(byte_data, (uint8_t *)&val64, 714aebe3cb7SKishore Padmanabha sizeof(val64), 715aebe3cb7SKishore Padmanabha idents[i].ident_bit_pos, 716aebe3cb7SKishore Padmanabha idents[i].ident_bit_size); 717aebe3cb7SKishore Padmanabha else 718aebe3cb7SKishore Padmanabha ulp_bs_pull_msb(byte_data, (uint8_t *)&val64, 719aebe3cb7SKishore Padmanabha idents[i].ident_bit_pos, 720aebe3cb7SKishore Padmanabha idents[i].ident_bit_size); 721aebe3cb7SKishore Padmanabha 722aebe3cb7SKishore Padmanabha /* Write it to the regfile, val64 is already in big-endian*/ 7230c036a14SPeter Spreadborough if (unlikely(ulp_regfile_write(parms->regfile, 7240c036a14SPeter Spreadborough idents[i].regfile_idx, val64))) { 725dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Regfile[%d] write failed.\n", 726aebe3cb7SKishore Padmanabha idents[i].regfile_idx); 727aebe3cb7SKishore Padmanabha return -EINVAL; 728aebe3cb7SKishore Padmanabha } 729aebe3cb7SKishore Padmanabha } 730aebe3cb7SKishore Padmanabha return 0; 731aebe3cb7SKishore Padmanabha } 732aebe3cb7SKishore Padmanabha 733aebe3cb7SKishore Padmanabha /* 7344bc32a80SMike Baucom * Process the identifier instruction and either store it in the flow database 7354bc32a80SMike Baucom * or return it in the val (if not NULL) on success. If val is NULL, the 7364bc32a80SMike Baucom * identifier is to be stored in the flow database. 7374bc32a80SMike Baucom */ 738ae905028SMike Baucom static int32_t 739ae905028SMike Baucom ulp_mapper_ident_process(struct bnxt_ulp_mapper_parms *parms, 7408608c099SKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl, 7414bc32a80SMike Baucom struct bnxt_ulp_mapper_ident_info *ident, 7424bc32a80SMike Baucom uint16_t *val) 743ae905028SMike Baucom { 744dd0191d5SShuanglin Wang const struct ulp_mapper_core_ops *op = parms->mapper_data->mapper_oper; 745dd0191d5SShuanglin Wang struct ulp_flow_db_res_params fid_parms = { 0 }; 746ae905028SMike Baucom uint64_t id = 0; 747ae905028SMike Baucom int32_t idx; 748ae905028SMike Baucom int rc; 749ae905028SMike Baucom 750dd0191d5SShuanglin Wang fid_parms.direction = tbl->direction; 751dd0191d5SShuanglin Wang fid_parms.resource_func = ident->resource_func; 752dd0191d5SShuanglin Wang fid_parms.resource_type = ident->ident_type; 753dd0191d5SShuanglin Wang fid_parms.critical_resource = tbl->critical_resource; 754dd0191d5SShuanglin Wang ulp_flow_db_shared_session_set(&fid_parms, tbl->session_type); 755ae905028SMike Baucom 756dd0191d5SShuanglin Wang rc = op->ulp_mapper_core_ident_alloc_process(parms->ulp_ctx, 757dd0191d5SShuanglin Wang tbl->session_type, 758dd0191d5SShuanglin Wang ident->ident_type, 7592aa70990SKishore Padmanabha tbl->direction, 7602aa70990SKishore Padmanabha tbl->track_type, 7612aa70990SKishore Padmanabha &id); 7620c036a14SPeter Spreadborough if (unlikely(rc)) { 763dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "identifier process failed\n"); 764ae905028SMike Baucom return rc; 765ae905028SMike Baucom } 766ae905028SMike Baucom 767dd0191d5SShuanglin Wang fid_parms.resource_hndl = id; 768dd0191d5SShuanglin Wang idx = ident->regfile_idx; 7690c036a14SPeter Spreadborough if (unlikely(ulp_regfile_write(parms->regfile, idx, tfp_cpu_to_be_64(id)))) { 770dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Regfile[%d] write failed.\n", idx); 771ae905028SMike Baucom rc = -EINVAL; 772ae905028SMike Baucom /* Need to free the identifier, so goto error */ 773ae905028SMike Baucom goto error; 774ae905028SMike Baucom } 775ae905028SMike Baucom 776ae905028SMike Baucom /* Link the resource to the flow in the flow db */ 7774bc32a80SMike Baucom if (!val) { 7780117293cSKishore Padmanabha rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 7790c036a14SPeter Spreadborough if (unlikely(rc)) { 780dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 781dd0191d5SShuanglin Wang "Failed to link res to flow rc = %d\n", 782ae905028SMike Baucom rc); 783ae905028SMike Baucom /* Need to free the identifier, so goto error */ 784ae905028SMike Baucom goto error; 785ae905028SMike Baucom } 7864bc32a80SMike Baucom } else { 787dd0191d5SShuanglin Wang *val = id; 7884bc32a80SMike Baucom } 789ae905028SMike Baucom return 0; 790ae905028SMike Baucom 791ae905028SMike Baucom error: 792ae905028SMike Baucom /* Need to free the identifier */ 793dd0191d5SShuanglin Wang op->ulp_mapper_core_ident_free(parms->ulp_ctx, &fid_parms); 79456388182SKishore Padmanabha return rc; 79556388182SKishore Padmanabha } 79656388182SKishore Padmanabha 797696843ccSMike Baucom static int32_t 798ddaf0afaSKishore Padmanabha ulp_mapper_field_port_db_process(struct bnxt_ulp_mapper_parms *parms, 799ddaf0afaSKishore Padmanabha uint32_t port_id, 800ddaf0afaSKishore Padmanabha uint16_t val16, 801ddaf0afaSKishore Padmanabha uint8_t **val) 802ddaf0afaSKishore Padmanabha { 803ddaf0afaSKishore Padmanabha enum bnxt_ulp_port_table port_data = val16; 804ddaf0afaSKishore Padmanabha 805ddaf0afaSKishore Padmanabha switch (port_data) { 806ddaf0afaSKishore Padmanabha case BNXT_ULP_PORT_TABLE_DRV_FUNC_PARENT_MAC: 8070c036a14SPeter Spreadborough if (unlikely(ulp_port_db_parent_mac_addr_get(parms->ulp_ctx, port_id, 8080c036a14SPeter Spreadborough val))) { 809dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port id %u\n", port_id); 810ddaf0afaSKishore Padmanabha return -EINVAL; 811ddaf0afaSKishore Padmanabha } 812ddaf0afaSKishore Padmanabha break; 8133fe124d2SKishore Padmanabha case BNXT_ULP_PORT_TABLE_DRV_FUNC_MAC: 8140c036a14SPeter Spreadborough if (unlikely(ulp_port_db_drv_mac_addr_get(parms->ulp_ctx, port_id, 8150c036a14SPeter Spreadborough val))) { 816dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port id %u\n", port_id); 8173fe124d2SKishore Padmanabha return -EINVAL; 8183fe124d2SKishore Padmanabha } 8193fe124d2SKishore Padmanabha break; 8203fe124d2SKishore Padmanabha case BNXT_ULP_PORT_TABLE_DRV_FUNC_PARENT_VNIC: 8210c036a14SPeter Spreadborough if (unlikely(ulp_port_db_parent_vnic_get(parms->ulp_ctx, port_id, 8220c036a14SPeter Spreadborough val))) { 823dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port id %u\n", port_id); 8243fe124d2SKishore Padmanabha return -EINVAL; 8253fe124d2SKishore Padmanabha } 8263fe124d2SKishore Padmanabha break; 8276d160d77SRandy Schacher case BNXT_ULP_PORT_TABLE_PORT_IS_PF: 8280c036a14SPeter Spreadborough if (unlikely(ulp_port_db_port_is_pf_get(parms->ulp_ctx, port_id, 8290c036a14SPeter Spreadborough val))) { 830dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port id %u\n", port_id); 8316d160d77SRandy Schacher return -EINVAL; 8326d160d77SRandy Schacher } 8336d160d77SRandy Schacher break; 8346d160d77SRandy Schacher case BNXT_ULP_PORT_TABLE_VF_FUNC_METADATA: 8350c036a14SPeter Spreadborough if (unlikely(ulp_port_db_port_meta_data_get(parms->ulp_ctx, port_id, 8360c036a14SPeter Spreadborough val))) { 837dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port id %u\n", port_id); 838dd0191d5SShuanglin Wang return -EINVAL; 839dd0191d5SShuanglin Wang } 840dd0191d5SShuanglin Wang break; 841dd0191d5SShuanglin Wang case BNXT_ULP_PORT_TABLE_TABLE_SCOPE: 8420c036a14SPeter Spreadborough if (unlikely(ulp_port_db_port_table_scope_get(parms->ulp_ctx, 8430c036a14SPeter Spreadborough port_id, val))) { 844dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port id %u\n", port_id); 8456d160d77SRandy Schacher return -EINVAL; 8466d160d77SRandy Schacher } 8476d160d77SRandy Schacher break; 848032d49efSKishore Padmanabha case BNXT_ULP_PORT_TABLE_VF_FUNC_FID: 8490c036a14SPeter Spreadborough if (unlikely(ulp_port_db_port_vf_fid_get(parms->ulp_ctx, port_id, val))) { 850dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port id %u\n", port_id); 851032d49efSKishore Padmanabha return -EINVAL; 852032d49efSKishore Padmanabha } 853032d49efSKishore Padmanabha break; 854ddaf0afaSKishore Padmanabha default: 855dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port_data %d\n", port_data); 856ddaf0afaSKishore Padmanabha return -EINVAL; 857ddaf0afaSKishore Padmanabha } 858ddaf0afaSKishore Padmanabha return 0; 859ddaf0afaSKishore Padmanabha } 860ddaf0afaSKishore Padmanabha 861ddaf0afaSKishore Padmanabha static int32_t 862d4b36fc5SKishore Padmanabha ulp_mapper_field_port_db_write(struct bnxt_ulp_mapper_parms *parms, 863d4b36fc5SKishore Padmanabha uint32_t port_id, 864d4b36fc5SKishore Padmanabha uint16_t idx, 865d4b36fc5SKishore Padmanabha uint8_t *val, 866d4b36fc5SKishore Padmanabha uint32_t length) 867d4b36fc5SKishore Padmanabha { 868d4b36fc5SKishore Padmanabha enum bnxt_ulp_port_table port_data = idx; 869d4b36fc5SKishore Padmanabha uint32_t val32; 870d4b36fc5SKishore Padmanabha 871d4b36fc5SKishore Padmanabha switch (port_data) { 872d4b36fc5SKishore Padmanabha case BNXT_ULP_PORT_TABLE_PHY_PORT_MIRROR_ID: 873d4b36fc5SKishore Padmanabha if (ULP_BITS_2_BYTE(length) > sizeof(val32)) { 874d4b36fc5SKishore Padmanabha BNXT_DRV_DBG(ERR, "Invalid data length %u\n", length); 875d4b36fc5SKishore Padmanabha return -EINVAL; 876d4b36fc5SKishore Padmanabha } 877d4b36fc5SKishore Padmanabha memcpy(&val32, val, ULP_BITS_2_BYTE(length)); 878d4b36fc5SKishore Padmanabha if (unlikely(ulp_port_db_port_table_mirror_set(parms->ulp_ctx, 879d4b36fc5SKishore Padmanabha port_id, 880d4b36fc5SKishore Padmanabha val32))) { 881d4b36fc5SKishore Padmanabha BNXT_DRV_DBG(ERR, "Invalid port id %u\n", port_id); 882d4b36fc5SKishore Padmanabha return -EINVAL; 883d4b36fc5SKishore Padmanabha } 884d4b36fc5SKishore Padmanabha break; 885d4b36fc5SKishore Padmanabha default: 886d4b36fc5SKishore Padmanabha BNXT_DRV_DBG(ERR, "Invalid port_data %d\n", port_data); 887d4b36fc5SKishore Padmanabha return -EINVAL; 888d4b36fc5SKishore Padmanabha } 889d4b36fc5SKishore Padmanabha return 0; 890d4b36fc5SKishore Padmanabha } 891d4b36fc5SKishore Padmanabha 892d4b36fc5SKishore Padmanabha static int32_t 893286569d5SKishore Padmanabha ulp_mapper_field_src_process(struct bnxt_ulp_mapper_parms *parms, 894286569d5SKishore Padmanabha enum bnxt_ulp_field_src field_src, 895286569d5SKishore Padmanabha uint8_t *field_opr, 896072cb4a8SMike Baucom enum tf_dir dir, 897a2417601SKishore Padmanabha uint8_t is_key, 898286569d5SKishore Padmanabha uint32_t bitlen, 899286569d5SKishore Padmanabha uint8_t **val, 900286569d5SKishore Padmanabha uint32_t *val_len, 901286569d5SKishore Padmanabha uint64_t *value) 902696843ccSMike Baucom { 903dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_cond_list_info info = { 0 }; 904286569d5SKishore Padmanabha struct bnxt_ulp_mapper_data *m; 905a2417601SKishore Padmanabha uint8_t bit; 906286569d5SKishore Padmanabha uint32_t port_id, val_size, field_size; 90730d7102dSKishore Padmanabha uint16_t idx = 0, size_idx = 0, offset = 0; 908286569d5SKishore Padmanabha uint32_t bytelen = ULP_BITS_2_BYTE(bitlen); 909286569d5SKishore Padmanabha uint8_t *buffer; 910286569d5SKishore Padmanabha uint64_t lregval; 911dd0191d5SShuanglin Wang int32_t cond_res; 912c6062ec0SMike Baucom bool shared; 9136d160d77SRandy Schacher uint8_t i = 0; 9146167c20cSKishore Padmanabha 915286569d5SKishore Padmanabha *val_len = bitlen; 916286569d5SKishore Padmanabha *value = 0; 91759ae4961SKishore Padmanabha /* Perform the action */ 918286569d5SKishore Padmanabha switch (field_src) { 91959ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_ZERO: 920286569d5SKishore Padmanabha *val = mapper_fld_zeros; 921a2417601SKishore Padmanabha break; 92259ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_CONST: 923286569d5SKishore Padmanabha *val = field_opr; 92459ae4961SKishore Padmanabha break; 925255add67SKishore Padmanabha case BNXT_ULP_FIELD_SRC_ONES: 926286569d5SKishore Padmanabha *val = mapper_fld_ones; 927286569d5SKishore Padmanabha *value = 1; 928255add67SKishore Padmanabha break; 92959ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_CF: 9300c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 9310c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 932dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "CF operand read failed\n"); 93359ae4961SKishore Padmanabha return -EINVAL; 93459ae4961SKishore Padmanabha } 93559ae4961SKishore Padmanabha idx = tfp_be_to_cpu_16(idx); 9360c036a14SPeter Spreadborough if (unlikely(idx >= BNXT_ULP_CF_IDX_LAST || bytelen > sizeof(uint64_t))) { 937dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "comp field [%d] read oob %d\n", idx, 938286569d5SKishore Padmanabha bytelen); 9396167c20cSKishore Padmanabha return -EINVAL; 9406167c20cSKishore Padmanabha } 941286569d5SKishore Padmanabha buffer = (uint8_t *)&parms->comp_fld[idx]; 9421993b267SShahaji Bhosle *val = &buffer[sizeof(uint64_t) - bytelen]; 943286569d5SKishore Padmanabha *value = ULP_COMP_FLD_IDX_RD(parms, idx); 94459ae4961SKishore Padmanabha break; 94559ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_RF: 9460c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 9470c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 948dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "RF operand read failed\n"); 949a2417601SKishore Padmanabha return -EINVAL; 950a2417601SKishore Padmanabha } 951a2417601SKishore Padmanabha 952a2417601SKishore Padmanabha idx = tfp_be_to_cpu_16(idx); 953a2417601SKishore Padmanabha /* Uninitialized regfile entries return 0 */ 9540c036a14SPeter Spreadborough if (unlikely(ulp_regfile_read(parms->regfile, idx, &lregval)) || 955286569d5SKishore Padmanabha sizeof(uint64_t) < bytelen) { 956dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "regfile[%d] read oob %u\n", idx, 957286569d5SKishore Padmanabha bytelen); 958a2417601SKishore Padmanabha return -EINVAL; 959a2417601SKishore Padmanabha } 960286569d5SKishore Padmanabha buffer = (uint8_t *)&parms->regfile->entry[idx].data; 961286569d5SKishore Padmanabha *val = &buffer[sizeof(uint64_t) - bytelen]; 962286569d5SKishore Padmanabha *value = tfp_be_to_cpu_64(lregval); 963a2417601SKishore Padmanabha break; 96459ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_ACT_PROP: 9650c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 9660c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 967dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Action operand read failed\n"); 96859ae4961SKishore Padmanabha return -EINVAL; 96959ae4961SKishore Padmanabha } 97059ae4961SKishore Padmanabha idx = tfp_be_to_cpu_16(idx); 9710c036a14SPeter Spreadborough if (unlikely(idx >= BNXT_ULP_ACT_PROP_IDX_LAST)) { 972dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "act_prop[%d] oob\n", idx); 97359ae4961SKishore Padmanabha return -EINVAL; 97459ae4961SKishore Padmanabha } 975286569d5SKishore Padmanabha buffer = &parms->act_prop->act_details[idx]; 97659ae4961SKishore Padmanabha field_size = ulp_mapper_act_prop_size_get(idx); 9770c036a14SPeter Spreadborough if (unlikely(bytelen > field_size)) { 978dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "act_prop[%d] field size small %u\n", 979286569d5SKishore Padmanabha idx, field_size); 98059ae4961SKishore Padmanabha return -EINVAL; 98159ae4961SKishore Padmanabha } 982286569d5SKishore Padmanabha *val = &buffer[field_size - bytelen]; 9836d160d77SRandy Schacher if (sizeof(*value) >= field_size) { 9846d160d77SRandy Schacher *value = buffer[0]; 9856d160d77SRandy Schacher for (i = 1; i < field_size; i++) 9866d160d77SRandy Schacher *value = (*value << 8) | buffer[i]; 9876d160d77SRandy Schacher } 98859ae4961SKishore Padmanabha break; 98959ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_ACT_PROP_SZ: 9900c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 9910c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 992dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Action sz operand read failed\n"); 99359ae4961SKishore Padmanabha return -EINVAL; 99459ae4961SKishore Padmanabha } 99559ae4961SKishore Padmanabha idx = tfp_be_to_cpu_16(idx); 99659ae4961SKishore Padmanabha 9970c036a14SPeter Spreadborough if (unlikely(idx >= BNXT_ULP_ACT_PROP_IDX_LAST)) { 998dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "act_prop_sz[%d] oob\n", idx); 99959ae4961SKishore Padmanabha return -EINVAL; 100059ae4961SKishore Padmanabha } 1001286569d5SKishore Padmanabha *val = &parms->act_prop->act_details[idx]; 100259ae4961SKishore Padmanabha 100359ae4961SKishore Padmanabha /* get the size index next */ 10040c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(&field_opr[sizeof(uint16_t)], 10050c036a14SPeter Spreadborough (uint8_t *)&size_idx, sizeof(uint16_t)))) { 1006dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Action sz operand read failed\n"); 100759ae4961SKishore Padmanabha return -EINVAL; 100859ae4961SKishore Padmanabha } 100959ae4961SKishore Padmanabha size_idx = tfp_be_to_cpu_16(size_idx); 10100c036a14SPeter Spreadborough if (unlikely(size_idx >= BNXT_ULP_ACT_PROP_IDX_LAST)) { 1011dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "act_prop[%d] oob\n", size_idx); 101259ae4961SKishore Padmanabha return -EINVAL; 101359ae4961SKishore Padmanabha } 101459ae4961SKishore Padmanabha memcpy(&val_size, &parms->act_prop->act_details[size_idx], 101559ae4961SKishore Padmanabha sizeof(uint32_t)); 101659ae4961SKishore Padmanabha val_size = tfp_be_to_cpu_32(val_size); 1017286569d5SKishore Padmanabha *val_len = ULP_BYTE_2_BITS(val_size); 101859ae4961SKishore Padmanabha break; 101959ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_GLB_RF: 10200c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 10210c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 1022dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Global regfile read failed\n"); 1023a2417601SKishore Padmanabha return -EINVAL; 1024a2417601SKishore Padmanabha } 1025a2417601SKishore Padmanabha idx = tfp_be_to_cpu_16(idx); 10260c036a14SPeter Spreadborough if (unlikely(ulp_mapper_glb_resource_read(parms->mapper_data, 1027286569d5SKishore Padmanabha dir, idx, &lregval, &shared) || 10280c036a14SPeter Spreadborough sizeof(uint64_t) < bytelen)) { 1029dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Global regfile[%d] read failed %u\n", 1030286569d5SKishore Padmanabha idx, bytelen); 1031a2417601SKishore Padmanabha return -EINVAL; 1032a2417601SKishore Padmanabha } 1033286569d5SKishore Padmanabha m = parms->mapper_data; 1034286569d5SKishore Padmanabha buffer = (uint8_t *)&m->glb_res_tbl[dir][idx].resource_hndl; 1035286569d5SKishore Padmanabha *val = &buffer[sizeof(uint64_t) - bytelen]; 1036286569d5SKishore Padmanabha *value = tfp_be_to_cpu_64(lregval); 1037a2417601SKishore Padmanabha break; 103859ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_HF: 1039286569d5SKishore Padmanabha case BNXT_ULP_FIELD_SRC_SUB_HF: 10400c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 10410c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 1042dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Header field read failed\n"); 1043072cb4a8SMike Baucom return -EINVAL; 1044072cb4a8SMike Baucom } 1045072cb4a8SMike Baucom idx = tfp_be_to_cpu_16(idx); 1046a2417601SKishore Padmanabha /* get the index from the global field list */ 10470c036a14SPeter Spreadborough if (unlikely(ulp_mapper_glb_field_tbl_get(parms, idx, &bit))) { 1048dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "invalid ulp_glb_field_tbl idx %d\n", 1049a2417601SKishore Padmanabha idx); 1050072cb4a8SMike Baucom return -EINVAL; 1051072cb4a8SMike Baucom } 1052a2417601SKishore Padmanabha if (is_key) 1053286569d5SKishore Padmanabha buffer = parms->hdr_field[bit].spec; 1054a2417601SKishore Padmanabha else 1055286569d5SKishore Padmanabha buffer = parms->hdr_field[bit].mask; 1056a4651725SMike Baucom 1057a2417601SKishore Padmanabha field_size = parms->hdr_field[bit].size; 1058af50070eSKishore Padmanabha if (!field_size) { 1059af50070eSKishore Padmanabha /* To support field processing of undefined fields */ 1060af50070eSKishore Padmanabha *val = mapper_fld_zeros; 1061af50070eSKishore Padmanabha break; 10620c036a14SPeter Spreadborough } else if (unlikely(bytelen > field_size)) { 1063dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Hdr field[%d] size small %u\n", 1064286569d5SKishore Padmanabha bit, field_size); 1065a2e216f8SKishore Padmanabha return -EINVAL; 1066a2e216f8SKishore Padmanabha } 1067286569d5SKishore Padmanabha if (field_src == BNXT_ULP_FIELD_SRC_HF) { 1068286569d5SKishore Padmanabha *val = &buffer[field_size - bytelen]; 1069286569d5SKishore Padmanabha } else { 1070286569d5SKishore Padmanabha /* get the offset next */ 10710c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(&field_opr[sizeof(uint16_t)], 1072286569d5SKishore Padmanabha (uint8_t *)&offset, 10730c036a14SPeter Spreadborough sizeof(uint16_t)))) { 1074dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Hdr fld size read failed\n"); 1075286569d5SKishore Padmanabha return -EINVAL; 1076286569d5SKishore Padmanabha } 1077286569d5SKishore Padmanabha offset = tfp_be_to_cpu_16(offset); 1078286569d5SKishore Padmanabha offset = ULP_BITS_2_BYTE_NR(offset); 10790c036a14SPeter Spreadborough if (unlikely((offset + bytelen) > field_size)) { 1080dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Hdr field[%d] oob\n", bit); 1081286569d5SKishore Padmanabha return -EINVAL; 1082286569d5SKishore Padmanabha } 1083286569d5SKishore Padmanabha *val = &buffer[offset]; 1084286569d5SKishore Padmanabha } 1085a2e216f8SKishore Padmanabha break; 108659ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_HDR_BIT: 10870c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 10880c036a14SPeter Spreadborough (uint8_t *)&lregval, sizeof(uint64_t)))) { 1089dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Header bit read failed\n"); 109059ae4961SKishore Padmanabha return -EINVAL; 109159ae4961SKishore Padmanabha } 1092286569d5SKishore Padmanabha lregval = tfp_be_to_cpu_64(lregval); 10930c036a14SPeter Spreadborough if (unlikely(ULP_BITMAP_ISSET(parms->hdr_bitmap->bits, lregval))) { 1094286569d5SKishore Padmanabha *val = mapper_fld_one; 1095286569d5SKishore Padmanabha *value = 1; 1096286569d5SKishore Padmanabha } else { 1097286569d5SKishore Padmanabha *val = mapper_fld_zeros; 109859ae4961SKishore Padmanabha } 109959ae4961SKishore Padmanabha break; 110059ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_ACT_BIT: 11010c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 11020c036a14SPeter Spreadborough (uint8_t *)&lregval, sizeof(uint64_t)))) { 1103dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Action bit read failed\n"); 110459ae4961SKishore Padmanabha return -EINVAL; 110559ae4961SKishore Padmanabha } 1106286569d5SKishore Padmanabha lregval = tfp_be_to_cpu_64(lregval); 11070c036a14SPeter Spreadborough if (unlikely(ULP_BITMAP_ISSET(parms->act_bitmap->bits, lregval))) { 1108286569d5SKishore Padmanabha *val = mapper_fld_one; 1109286569d5SKishore Padmanabha *value = 1; 1110286569d5SKishore Padmanabha } else { 1111286569d5SKishore Padmanabha *val = mapper_fld_zeros; 111259ae4961SKishore Padmanabha } 111359ae4961SKishore Padmanabha break; 111459ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_FIELD_BIT: 11150c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 11160c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 1117dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Field bit read failed\n"); 111859ae4961SKishore Padmanabha return -EINVAL; 111959ae4961SKishore Padmanabha } 112059ae4961SKishore Padmanabha idx = tfp_be_to_cpu_16(idx); 112159ae4961SKishore Padmanabha /* get the index from the global field list */ 11220c036a14SPeter Spreadborough if (unlikely(ulp_mapper_glb_field_tbl_get(parms, idx, &bit))) { 1123dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "invalid ulp_glb_field_tbl idx %d\n", 112459ae4961SKishore Padmanabha idx); 112559ae4961SKishore Padmanabha return -EINVAL; 112659ae4961SKishore Padmanabha } 11270c036a14SPeter Spreadborough if (unlikely(ULP_INDEX_BITMAP_GET(parms->fld_bitmap->bits, bit))) { 1128286569d5SKishore Padmanabha *val = mapper_fld_one; 1129286569d5SKishore Padmanabha *value = 1; 1130286569d5SKishore Padmanabha } else { 1131286569d5SKishore Padmanabha *val = mapper_fld_zeros; 113259ae4961SKishore Padmanabha } 113359ae4961SKishore Padmanabha break; 1134286569d5SKishore Padmanabha case BNXT_ULP_FIELD_SRC_PORT_TABLE: 11350c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 11360c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 1137dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "CF operand read failed\n"); 11386d160d77SRandy Schacher return -EINVAL; 11396d160d77SRandy Schacher } 11406d160d77SRandy Schacher idx = tfp_be_to_cpu_16(idx); 11410c036a14SPeter Spreadborough if (unlikely(idx >= BNXT_ULP_CF_IDX_LAST || bytelen > sizeof(uint64_t))) { 1142dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "comp field [%d] read oob %d\n", idx, 11436d160d77SRandy Schacher bytelen); 11446d160d77SRandy Schacher return -EINVAL; 11456d160d77SRandy Schacher } 11466d160d77SRandy Schacher 11476d160d77SRandy Schacher /* The port id is present in the comp field list */ 11486d160d77SRandy Schacher port_id = ULP_COMP_FLD_IDX_RD(parms, idx); 11496d160d77SRandy Schacher /* get the port table enum */ 11500c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr + sizeof(uint16_t), 11510c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 1152dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Port table enum read failed\n"); 1153286569d5SKishore Padmanabha return -EINVAL; 1154286569d5SKishore Padmanabha } 1155286569d5SKishore Padmanabha idx = tfp_be_to_cpu_16(idx); 11560c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_port_db_process(parms, port_id, idx, 11570c036a14SPeter Spreadborough val))) { 1158dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "field port table failed\n"); 1159286569d5SKishore Padmanabha return -EINVAL; 1160286569d5SKishore Padmanabha } 1161f63aa27dSKishore Padmanabha break; 1162f63aa27dSKishore Padmanabha case BNXT_ULP_FIELD_SRC_ENC_HDR_BIT: 11630c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 11640c036a14SPeter Spreadborough (uint8_t *)&lregval, sizeof(uint64_t)))) { 1165dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Header bit read failed\n"); 1166f63aa27dSKishore Padmanabha return -EINVAL; 1167f63aa27dSKishore Padmanabha } 1168f63aa27dSKishore Padmanabha lregval = tfp_be_to_cpu_64(lregval); 1169f63aa27dSKishore Padmanabha if (ULP_BITMAP_ISSET(parms->enc_hdr_bitmap->bits, lregval)) { 1170f63aa27dSKishore Padmanabha *val = mapper_fld_one; 1171f63aa27dSKishore Padmanabha *value = 1; 1172f63aa27dSKishore Padmanabha } else { 1173f63aa27dSKishore Padmanabha *val = mapper_fld_zeros; 1174f63aa27dSKishore Padmanabha } 1175f63aa27dSKishore Padmanabha break; 1176f63aa27dSKishore Padmanabha case BNXT_ULP_FIELD_SRC_ENC_FIELD: 11770c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 11780c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 1179dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Header field read failed\n"); 1180f63aa27dSKishore Padmanabha return -EINVAL; 1181f63aa27dSKishore Padmanabha } 1182f63aa27dSKishore Padmanabha idx = tfp_be_to_cpu_16(idx); 1183f63aa27dSKishore Padmanabha /* get the index from the global field list */ 11840c036a14SPeter Spreadborough if (unlikely(idx >= BNXT_ULP_ENC_FIELD_LAST)) { 1185dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "invalid encap field tbl idx %d\n", 1186f63aa27dSKishore Padmanabha idx); 1187f63aa27dSKishore Padmanabha return -EINVAL; 1188f63aa27dSKishore Padmanabha } 1189f63aa27dSKishore Padmanabha buffer = parms->enc_field[idx].spec; 1190f63aa27dSKishore Padmanabha field_size = parms->enc_field[idx].size; 11910c036a14SPeter Spreadborough if (unlikely(bytelen > field_size)) { 1192dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Encap field[%d] size small %u\n", 1193f63aa27dSKishore Padmanabha idx, field_size); 1194f63aa27dSKishore Padmanabha return -EINVAL; 1195f63aa27dSKishore Padmanabha } 1196f63aa27dSKishore Padmanabha *val = &buffer[field_size - bytelen]; 1197f63aa27dSKishore Padmanabha break; 119859ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_SKIP: 119959ae4961SKishore Padmanabha /* do nothing */ 1200f63aa27dSKishore Padmanabha *val = mapper_fld_zeros; 1201f63aa27dSKishore Padmanabha *val_len = 0; 120259ae4961SKishore Padmanabha break; 120359ae4961SKishore Padmanabha case BNXT_ULP_FIELD_SRC_REJECT: 120459ae4961SKishore Padmanabha return -EINVAL; 1205dd0191d5SShuanglin Wang case BNXT_ULP_FIELD_SRC_LIST_AND: 1206dd0191d5SShuanglin Wang case BNXT_ULP_FIELD_SRC_LIST_OR: 1207dd0191d5SShuanglin Wang /* read the cond table index and count */ 12080c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 12090c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 1210dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Cond idx operand read failed\n"); 1211dd0191d5SShuanglin Wang return -EINVAL; 1212dd0191d5SShuanglin Wang } 1213dd0191d5SShuanglin Wang idx = tfp_be_to_cpu_16(idx); 1214dd0191d5SShuanglin Wang 12150c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr + sizeof(uint16_t), 12160c036a14SPeter Spreadborough (uint8_t *)&size_idx, sizeof(uint16_t)))) { 1217dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Cond count operand read failed\n"); 1218dd0191d5SShuanglin Wang return -EINVAL; 1219dd0191d5SShuanglin Wang } 1220dd0191d5SShuanglin Wang size_idx = tfp_be_to_cpu_16(size_idx); 1221dd0191d5SShuanglin Wang 1222dd0191d5SShuanglin Wang /* populate the extracted vales to create a temp cond list */ 1223dd0191d5SShuanglin Wang if (field_src == BNXT_ULP_FIELD_SRC_LIST_AND) 1224dd0191d5SShuanglin Wang info.cond_list_opcode = BNXT_ULP_COND_LIST_OPC_AND; 1225dd0191d5SShuanglin Wang else 1226dd0191d5SShuanglin Wang info.cond_list_opcode = BNXT_ULP_COND_LIST_OPC_OR; 1227dd0191d5SShuanglin Wang info.cond_start_idx = idx; 1228dd0191d5SShuanglin Wang info.cond_nums = size_idx; 12290c036a14SPeter Spreadborough if (unlikely(ulp_mapper_cond_opc_list_process(parms, &info, &cond_res))) { 1230dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Cond evaluation failed\n"); 1231dd0191d5SShuanglin Wang return -EINVAL; 1232dd0191d5SShuanglin Wang } 1233dd0191d5SShuanglin Wang if (cond_res) { 1234dd0191d5SShuanglin Wang *val = mapper_fld_one; 1235dd0191d5SShuanglin Wang *value = 1; 1236dd0191d5SShuanglin Wang } else { 1237dd0191d5SShuanglin Wang *val = mapper_fld_zeros; 1238dd0191d5SShuanglin Wang *value = 0; 1239dd0191d5SShuanglin Wang } 1240dd0191d5SShuanglin Wang break; 124194dbd6cfSKishore Padmanabha case BNXT_ULP_FIELD_SRC_CF_BIT: 12420c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 12430c036a14SPeter Spreadborough (uint8_t *)&lregval, sizeof(uint64_t)))) { 124494dbd6cfSKishore Padmanabha BNXT_DRV_DBG(ERR, "CF operand read failed\n"); 124594dbd6cfSKishore Padmanabha return -EINVAL; 124694dbd6cfSKishore Padmanabha } 124794dbd6cfSKishore Padmanabha lregval = tfp_be_to_cpu_64(lregval); 12480c036a14SPeter Spreadborough if (unlikely(ULP_BITMAP_ISSET(parms->cf_bitmap, lregval))) { 124994dbd6cfSKishore Padmanabha *val = mapper_fld_one; 125094dbd6cfSKishore Padmanabha *value = 1; 125194dbd6cfSKishore Padmanabha } else { 125294dbd6cfSKishore Padmanabha *val = mapper_fld_zeros; 125394dbd6cfSKishore Padmanabha } 125494dbd6cfSKishore Padmanabha break; 1255696843ccSMike Baucom default: 1256dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "invalid field opcode 0x%x\n", field_src); 1257696843ccSMike Baucom return -EINVAL; 1258696843ccSMike Baucom } 1259696843ccSMike Baucom return 0; 1260696843ccSMike Baucom } 1261696843ccSMike Baucom 1262286569d5SKishore Padmanabha static int32_t ulp_mapper_field_buffer_eval(uint8_t *buffer, uint32_t bitlen, 1263286569d5SKishore Padmanabha uint64_t *output) 1264286569d5SKishore Padmanabha { 1265286569d5SKishore Padmanabha uint16_t val_16; 1266286569d5SKishore Padmanabha uint32_t val_32; 1267286569d5SKishore Padmanabha uint64_t val_64; 1268286569d5SKishore Padmanabha uint32_t bytelen; 1269286569d5SKishore Padmanabha 1270286569d5SKishore Padmanabha bytelen = ULP_BITS_2_BYTE(bitlen); 1271286569d5SKishore Padmanabha if (bytelen == sizeof(uint8_t)) { 1272286569d5SKishore Padmanabha *output = *((uint8_t *)buffer); 1273286569d5SKishore Padmanabha } else if (bytelen == sizeof(uint16_t)) { 1274286569d5SKishore Padmanabha val_16 = *((uint16_t *)buffer); 1275286569d5SKishore Padmanabha *output = tfp_be_to_cpu_16(val_16); 1276286569d5SKishore Padmanabha } else if (bytelen == sizeof(uint32_t)) { 1277286569d5SKishore Padmanabha val_32 = *((uint32_t *)buffer); 1278286569d5SKishore Padmanabha *output = tfp_be_to_cpu_32(val_32); 1279286569d5SKishore Padmanabha } else if (bytelen == sizeof(val_64)) { 1280286569d5SKishore Padmanabha val_64 = *((uint64_t *)buffer); 1281286569d5SKishore Padmanabha *output = tfp_be_to_cpu_64(val_64); 1282286569d5SKishore Padmanabha } else { 1283286569d5SKishore Padmanabha *output = 0; 1284286569d5SKishore Padmanabha return -EINVAL; 1285286569d5SKishore Padmanabha } 1286286569d5SKishore Padmanabha return 0; 1287286569d5SKishore Padmanabha } 1288286569d5SKishore Padmanabha 1289286569d5SKishore Padmanabha static int32_t ulp_mapper_field_blob_write(enum bnxt_ulp_field_src fld_src, 1290286569d5SKishore Padmanabha struct ulp_blob *blob, 1291286569d5SKishore Padmanabha uint8_t *val, 1292286569d5SKishore Padmanabha uint32_t val_len, 1293286569d5SKishore Padmanabha uint8_t **out_val) 1294286569d5SKishore Padmanabha { 1295286569d5SKishore Padmanabha if (fld_src == BNXT_ULP_FIELD_SRC_ZERO) { 12960c036a14SPeter Spreadborough if (unlikely(ulp_blob_pad_push(blob, val_len) < 0)) { 1297dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "too large for blob\n"); 1298286569d5SKishore Padmanabha return -EINVAL; 1299286569d5SKishore Padmanabha } 1300286569d5SKishore Padmanabha } else if (fld_src == BNXT_ULP_FIELD_SRC_ACT_PROP_SZ) { 13010c036a14SPeter Spreadborough if (unlikely(ulp_blob_push_encap(blob, val, val_len) < 0)) { 1302dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "encap blob push failed\n"); 1303286569d5SKishore Padmanabha return -EINVAL; 1304286569d5SKishore Padmanabha } 1305f63aa27dSKishore Padmanabha } else if (fld_src == BNXT_ULP_FIELD_SRC_SKIP) { 1306f63aa27dSKishore Padmanabha /* do nothing */ 1307286569d5SKishore Padmanabha } else { 13080c036a14SPeter Spreadborough if (unlikely(ulp_blob_push(blob, val, val_len))) { 1309dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "push of val1 failed\n"); 1310286569d5SKishore Padmanabha return -EINVAL; 1311286569d5SKishore Padmanabha } 1312286569d5SKishore Padmanabha } 1313286569d5SKishore Padmanabha *out_val = val; 1314286569d5SKishore Padmanabha return 0; 1315286569d5SKishore Padmanabha } 1316286569d5SKishore Padmanabha 1317286569d5SKishore Padmanabha static int32_t 1318dd0191d5SShuanglin Wang ulp_mapper_field_opc_next(struct bnxt_ulp_mapper_parms *parms, 1319dd0191d5SShuanglin Wang enum tf_dir dir, 1320dd0191d5SShuanglin Wang uint8_t *field_opr, 1321dd0191d5SShuanglin Wang struct ulp_blob *blob, 1322dd0191d5SShuanglin Wang uint8_t is_key, 1323dd0191d5SShuanglin Wang const char *name) 1324dd0191d5SShuanglin Wang { 1325dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_field_info *field_info; 132630d7102dSKishore Padmanabha uint16_t idx = 0; 1327dd0191d5SShuanglin Wang 1328dd0191d5SShuanglin Wang /* read the cond table index and count */ 13290c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 13300c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 1331dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "field idx operand read failed\n"); 1332dd0191d5SShuanglin Wang return -EINVAL; 1333dd0191d5SShuanglin Wang } 1334dd0191d5SShuanglin Wang idx = tfp_be_to_cpu_16(idx); 1335dd0191d5SShuanglin Wang 1336dd0191d5SShuanglin Wang field_info = ulp_mapper_tmpl_key_ext_list_get(parms, idx); 13370c036a14SPeter Spreadborough if (unlikely(field_info == NULL)) { 1338dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid field idx %d\n", idx); 1339dd0191d5SShuanglin Wang return -EINVAL; 1340dd0191d5SShuanglin Wang } 1341dd0191d5SShuanglin Wang 1342dd0191d5SShuanglin Wang return ulp_mapper_field_opc_process(parms, dir, field_info, 1343dd0191d5SShuanglin Wang blob, is_key, name); 1344dd0191d5SShuanglin Wang } 1345dd0191d5SShuanglin Wang 1346dd0191d5SShuanglin Wang static void 1347dd0191d5SShuanglin Wang ulp_mapper_key_recipe_tbl_deinit(struct bnxt_ulp_mapper_data *mdata) 1348dd0191d5SShuanglin Wang { 13494a925aa7SKishore Padmanabha struct bnxt_ulp_key_recipe_entry **recipes; 1350dd0191d5SShuanglin Wang enum bnxt_ulp_direction dir; 13514a925aa7SKishore Padmanabha uint32_t idx, ftype; 13524a925aa7SKishore Padmanabha 13534a925aa7SKishore Padmanabha /* If recipe table is not initialized then exit */ 13544a925aa7SKishore Padmanabha if (!mdata->key_recipe_info.num_recipes) 13554a925aa7SKishore Padmanabha return; 1356dd0191d5SShuanglin Wang 1357dd0191d5SShuanglin Wang for (dir = 0; dir < BNXT_ULP_DIRECTION_LAST; dir++) { 13584a925aa7SKishore Padmanabha for (ftype = 0; ftype < ULP_RECIPE_TYPE_MAX; ftype++) { 13594a925aa7SKishore Padmanabha recipes = mdata->key_recipe_info.recipes[dir][ftype]; 13604a925aa7SKishore Padmanabha for (idx = 0; idx < mdata->key_recipe_info.num_recipes; 13614a925aa7SKishore Padmanabha idx++) { 13624a925aa7SKishore Padmanabha if (recipes[idx]) 13634a925aa7SKishore Padmanabha rte_free(recipes[idx]); 1364dd0191d5SShuanglin Wang } 13654a925aa7SKishore Padmanabha rte_free(mdata->key_recipe_info.recipes[dir][ftype]); 13664a925aa7SKishore Padmanabha mdata->key_recipe_info.recipes[dir][ftype] = NULL; 136761a7ca1fSKishore Padmanabha rte_free(mdata->key_recipe_info.recipe_ba[dir][ftype]); 136861a7ca1fSKishore Padmanabha mdata->key_recipe_info.recipe_ba[dir][ftype] = NULL; 13694a925aa7SKishore Padmanabha } 13704a925aa7SKishore Padmanabha } 13714a925aa7SKishore Padmanabha mdata->key_recipe_info.num_recipes = 0; 1372dd0191d5SShuanglin Wang } 1373dd0191d5SShuanglin Wang 1374dd0191d5SShuanglin Wang static int32_t 1375dd0191d5SShuanglin Wang ulp_mapper_key_recipe_tbl_init(struct bnxt_ulp_context *ulp_ctx, 1376dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_data *mdata) 1377dd0191d5SShuanglin Wang { 13784a925aa7SKishore Padmanabha struct bnxt_ulp_key_recipe_entry **recipes; 1379dd0191d5SShuanglin Wang enum bnxt_ulp_direction dir; 13804a925aa7SKishore Padmanabha uint32_t dev_id = 0, size_val; 138161a7ca1fSKishore Padmanabha uint32_t num_recipes, ftype, pool_size; 1382dd0191d5SShuanglin Wang int32_t rc = 0; 138361a7ca1fSKishore Padmanabha struct bitalloc *recipe_ba; 1384dd0191d5SShuanglin Wang 1385dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id); 13860c036a14SPeter Spreadborough if (unlikely(rc)) { 1387dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n"); 13884a925aa7SKishore Padmanabha return -EINVAL; 1389dd0191d5SShuanglin Wang } 1390dd0191d5SShuanglin Wang num_recipes = bnxt_ulp_num_key_recipes_get(ulp_ctx); 1391dd0191d5SShuanglin Wang if (!num_recipes) 13924a925aa7SKishore Padmanabha return rc; 1393dd0191d5SShuanglin Wang 139461a7ca1fSKishore Padmanabha /* Need to write these values so that a failure will result in freeing 139561a7ca1fSKishore Padmanabha * the memory in the deinit 139661a7ca1fSKishore Padmanabha */ 139761a7ca1fSKishore Padmanabha mdata->key_recipe_info.num_recipes = num_recipes; 139861a7ca1fSKishore Padmanabha mdata->key_recipe_info.max_fields = BNXT_ULP_KEY_RECIPE_MAX_FLDS; 139961a7ca1fSKishore Padmanabha 14004a925aa7SKishore Padmanabha size_val = sizeof(struct bnxt_ulp_key_recipe_entry *); 140161a7ca1fSKishore Padmanabha pool_size = BITALLOC_SIZEOF(num_recipes); 140261a7ca1fSKishore Padmanabha 140361a7ca1fSKishore Padmanabha /* The caller will deinit if failures occur, so just return fail instead 140461a7ca1fSKishore Padmanabha * of attempting to free allocated memory 140561a7ca1fSKishore Padmanabha **/ 1406dd0191d5SShuanglin Wang for (dir = 0; dir < BNXT_ULP_DIRECTION_LAST; dir++) { 14074a925aa7SKishore Padmanabha for (ftype = 0; ftype < ULP_RECIPE_TYPE_MAX; ftype++) { 14084a925aa7SKishore Padmanabha recipes = rte_zmalloc("key_recipe_list", 14094a925aa7SKishore Padmanabha size_val * num_recipes, 0); 14100c036a14SPeter Spreadborough if (unlikely(!recipes)) { 141161a7ca1fSKishore Padmanabha BNXT_DRV_DBG(ERR, "Unable to alloc memory\n"); 1412dd0191d5SShuanglin Wang return -ENOMEM; 1413dd0191d5SShuanglin Wang } 14144a925aa7SKishore Padmanabha mdata->key_recipe_info.recipes[dir][ftype] = recipes; 141561a7ca1fSKishore Padmanabha 141661a7ca1fSKishore Padmanabha recipe_ba = rte_malloc("key_recipe_ba", pool_size, 0); 14170c036a14SPeter Spreadborough if (unlikely(!recipe_ba)) { 141861a7ca1fSKishore Padmanabha BNXT_DRV_DBG(ERR, "Unable to alloc memory\n"); 141961a7ca1fSKishore Padmanabha return -ENOMEM; 142061a7ca1fSKishore Padmanabha } 142161a7ca1fSKishore Padmanabha mdata->key_recipe_info.recipe_ba[dir][ftype] = 142261a7ca1fSKishore Padmanabha recipe_ba; 142361a7ca1fSKishore Padmanabha rc = ba_init(recipe_ba, num_recipes, true); 14240c036a14SPeter Spreadborough if (unlikely(rc)) { 142561a7ca1fSKishore Padmanabha BNXT_DRV_DBG(ERR, 142661a7ca1fSKishore Padmanabha "Unable to alloc recipe ba\n"); 142761a7ca1fSKishore Padmanabha return -ENOMEM; 14284a925aa7SKishore Padmanabha } 14294a925aa7SKishore Padmanabha } 143061a7ca1fSKishore Padmanabha } 14314a925aa7SKishore Padmanabha return rc; 14324a925aa7SKishore Padmanabha } 1433dd0191d5SShuanglin Wang 14344a925aa7SKishore Padmanabha static struct bnxt_ulp_mapper_data * 14354a925aa7SKishore Padmanabha ulp_mapper_key_recipe_args_validate(struct bnxt_ulp_context *ulp_ctx, 1436dd0191d5SShuanglin Wang enum bnxt_ulp_direction dir, 1437dd0191d5SShuanglin Wang enum bnxt_ulp_resource_sub_type stype, 143861a7ca1fSKishore Padmanabha uint32_t recipe_id) 1439dd0191d5SShuanglin Wang { 1440dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_data *mdata; 1441dd0191d5SShuanglin Wang 1442dd0191d5SShuanglin Wang mdata = (struct bnxt_ulp_mapper_data *) 1443dd0191d5SShuanglin Wang bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx); 14440c036a14SPeter Spreadborough if (unlikely(!mdata)) { 1445dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get mapper data.\n"); 1446dd0191d5SShuanglin Wang return NULL; 1447dd0191d5SShuanglin Wang } 14480c036a14SPeter Spreadborough if (unlikely(dir >= BNXT_ULP_DIRECTION_LAST)) { 1449dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid dir (%d) in key recipe\n", dir); 1450dd0191d5SShuanglin Wang return NULL; 1451dd0191d5SShuanglin Wang } 14520c036a14SPeter Spreadborough if (unlikely(mdata->key_recipe_info.num_recipes == 0)) { 1453dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Recipes are not supported\n"); 1454dd0191d5SShuanglin Wang return NULL; 1455dd0191d5SShuanglin Wang } 14560c036a14SPeter Spreadborough if (unlikely(stype != BNXT_ULP_RESOURCE_SUB_TYPE_KEY_RECIPE_TABLE_WM && 14570c036a14SPeter Spreadborough stype != BNXT_ULP_RESOURCE_SUB_TYPE_KEY_RECIPE_TABLE_EM)) { 14584a925aa7SKishore Padmanabha BNXT_DRV_DBG(ERR, "Invalid type (%d) in key recipe\n", stype); 1459dd0191d5SShuanglin Wang return NULL; 14604a925aa7SKishore Padmanabha } 14610c036a14SPeter Spreadborough if (unlikely(recipe_id >= mdata->key_recipe_info.num_recipes || 14620c036a14SPeter Spreadborough !mdata->key_recipe_info.num_recipes)) { 146361a7ca1fSKishore Padmanabha BNXT_DRV_DBG(ERR, "Key recipe id out of range(%u >= %u)\n", 1464dd0191d5SShuanglin Wang recipe_id, mdata->key_recipe_info.num_recipes); 1465dd0191d5SShuanglin Wang return NULL; 1466dd0191d5SShuanglin Wang } 14674a925aa7SKishore Padmanabha return mdata; 1468dd0191d5SShuanglin Wang } 1469dd0191d5SShuanglin Wang 1470dd0191d5SShuanglin Wang static struct bnxt_ulp_key_recipe_entry * 1471dd0191d5SShuanglin Wang ulp_mapper_key_recipe_alloc(struct bnxt_ulp_context *ulp_ctx, 1472dd0191d5SShuanglin Wang enum bnxt_ulp_direction dir, 1473dd0191d5SShuanglin Wang enum bnxt_ulp_resource_sub_type stype, 147461a7ca1fSKishore Padmanabha uint32_t recipe_id, bool alloc_only, 147561a7ca1fSKishore Padmanabha uint8_t *max_fields) 1476dd0191d5SShuanglin Wang { 14774a925aa7SKishore Padmanabha struct bnxt_ulp_key_recipe_entry **recipes; 14784a925aa7SKishore Padmanabha struct bnxt_ulp_mapper_data *mdata = NULL; 14794a925aa7SKishore Padmanabha uint32_t size_s = sizeof(struct bnxt_ulp_key_recipe_entry); 1480dd0191d5SShuanglin Wang 14814a925aa7SKishore Padmanabha mdata = ulp_mapper_key_recipe_args_validate(ulp_ctx, dir, 14824a925aa7SKishore Padmanabha stype, recipe_id); 14830c036a14SPeter Spreadborough if (unlikely(mdata == NULL)) 14844a925aa7SKishore Padmanabha return NULL; 14854a925aa7SKishore Padmanabha 14864a925aa7SKishore Padmanabha recipes = mdata->key_recipe_info.recipes[dir][stype]; 148761a7ca1fSKishore Padmanabha if (alloc_only && recipes[recipe_id] == NULL) { 14884a925aa7SKishore Padmanabha recipes[recipe_id] = rte_zmalloc("key_recipe_entry", size_s, 0); 14894a925aa7SKishore Padmanabha if (recipes[recipe_id] == NULL) { 14904a925aa7SKishore Padmanabha BNXT_DRV_DBG(ERR, "Unable to alloc key recipe\n"); 1491dd0191d5SShuanglin Wang return NULL; 1492dd0191d5SShuanglin Wang } 14934a925aa7SKishore Padmanabha #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 14944a925aa7SKishore Padmanabha #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 14954a925aa7SKishore Padmanabha BNXT_DRV_INF("Alloc key recipe [%s]:[%s] = 0x%X\n", 14964a925aa7SKishore Padmanabha (dir == BNXT_ULP_DIRECTION_INGRESS) ? "rx" : "tx", 14974a925aa7SKishore Padmanabha ulp_mapper_key_recipe_type_to_str(stype), recipe_id); 14984a925aa7SKishore Padmanabha #endif 14994a925aa7SKishore Padmanabha #endif 150061a7ca1fSKishore Padmanabha } else if (alloc_only) { 150161a7ca1fSKishore Padmanabha BNXT_DRV_DBG(ERR, "Recipe ID (%d) already allocated\n", 150261a7ca1fSKishore Padmanabha recipe_id); 150361a7ca1fSKishore Padmanabha } 15044a925aa7SKishore Padmanabha *max_fields = mdata->key_recipe_info.max_fields; 15054a925aa7SKishore Padmanabha return recipes[recipe_id]; 1506dd0191d5SShuanglin Wang } 1507dd0191d5SShuanglin Wang 1508dd0191d5SShuanglin Wang /* The free just marks the entry as not in use and resets the number of entries 1509dd0191d5SShuanglin Wang * to zero. 1510dd0191d5SShuanglin Wang */ 1511dd0191d5SShuanglin Wang static int32_t 1512dd0191d5SShuanglin Wang ulp_mapper_key_recipe_free(struct bnxt_ulp_context *ulp_ctx, 1513dd0191d5SShuanglin Wang uint8_t dir, 1514dd0191d5SShuanglin Wang enum bnxt_ulp_resource_sub_type stype, 1515dd0191d5SShuanglin Wang uint32_t index) 1516dd0191d5SShuanglin Wang { 15174a925aa7SKishore Padmanabha struct bnxt_ulp_key_recipe_entry **recipes; 15184a925aa7SKishore Padmanabha struct bnxt_ulp_mapper_data *mdata = NULL; 151961a7ca1fSKishore Padmanabha struct bitalloc *recipe_ba = NULL; 152061a7ca1fSKishore Padmanabha int32_t rc; 1521dd0191d5SShuanglin Wang 15224a925aa7SKishore Padmanabha mdata = ulp_mapper_key_recipe_args_validate(ulp_ctx, dir, 15234a925aa7SKishore Padmanabha stype, index); 15240c036a14SPeter Spreadborough if (unlikely(mdata == NULL)) 1525dd0191d5SShuanglin Wang return -EINVAL; 1526dd0191d5SShuanglin Wang 152761a7ca1fSKishore Padmanabha recipe_ba = mdata->key_recipe_info.recipe_ba[dir][stype]; 152861a7ca1fSKishore Padmanabha rc = ba_free(recipe_ba, index); 15290c036a14SPeter Spreadborough if (unlikely(rc < 0)) 153061a7ca1fSKishore Padmanabha BNXT_DRV_DBG(DEBUG, "Unable to free recipe id[%s][%u] = (%d)\n", 153161a7ca1fSKishore Padmanabha (dir == BNXT_ULP_DIRECTION_INGRESS) ? "rx" : "tx", 153261a7ca1fSKishore Padmanabha stype, index); 153361a7ca1fSKishore Padmanabha 15344a925aa7SKishore Padmanabha recipes = mdata->key_recipe_info.recipes[dir][stype]; 15350c036a14SPeter Spreadborough if (unlikely(recipes[index] == NULL)) { 153661a7ca1fSKishore Padmanabha BNXT_DRV_DBG(DEBUG, "recipe id[%s][%u] = (%d) already freed\n", 153761a7ca1fSKishore Padmanabha (dir == BNXT_ULP_DIRECTION_INGRESS) ? "rx" : "tx", 153861a7ca1fSKishore Padmanabha stype, index); 153961a7ca1fSKishore Padmanabha return 0; 154061a7ca1fSKishore Padmanabha } 15414a925aa7SKishore Padmanabha rte_free(recipes[index]); 15424a925aa7SKishore Padmanabha recipes[index] = NULL; 1543dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 1544dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 1545dd0191d5SShuanglin Wang BNXT_DRV_INF("Free key recipe [%s]:[%s] = 0x%X\n", 1546dd0191d5SShuanglin Wang (dir == BNXT_ULP_DIRECTION_INGRESS) ? "rx" : "tx", 1547dd0191d5SShuanglin Wang ulp_mapper_key_recipe_type_to_str(stype), index); 1548dd0191d5SShuanglin Wang #endif 1549dd0191d5SShuanglin Wang #endif 1550dd0191d5SShuanglin Wang return 0; 1551dd0191d5SShuanglin Wang } 1552dd0191d5SShuanglin Wang 1553dd0191d5SShuanglin Wang static void 1554dd0191d5SShuanglin Wang ulp_mapper_key_recipe_copy_to_src1(struct bnxt_ulp_mapper_field_info *dst, 1555dd0191d5SShuanglin Wang enum bnxt_ulp_field_src field_src, 1556dd0191d5SShuanglin Wang uint8_t *field_opr, 1557dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_field_info *src, 1558dd0191d5SShuanglin Wang bool *written) 1559dd0191d5SShuanglin Wang { 1560dd0191d5SShuanglin Wang if (field_src != BNXT_ULP_FIELD_SRC_SKIP) { 1561dd0191d5SShuanglin Wang dst->field_opc = BNXT_ULP_FIELD_OPC_SRC1; 1562dd0191d5SShuanglin Wang dst->field_src1 = field_src; 1563dd0191d5SShuanglin Wang memcpy(dst->field_opr1, field_opr, 16); 1564dd0191d5SShuanglin Wang memcpy(dst->description, src->description, 64); 1565dd0191d5SShuanglin Wang dst->field_bit_size = src->field_bit_size; 1566dd0191d5SShuanglin Wang *written = true; 1567dd0191d5SShuanglin Wang } 1568dd0191d5SShuanglin Wang } 1569dd0191d5SShuanglin Wang 1570dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_key_info * 1571dd0191d5SShuanglin Wang ulp_mapper_key_recipe_fields_get(struct bnxt_ulp_mapper_parms *parms, 1572dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl, 1573dd0191d5SShuanglin Wang uint32_t *num_flds) 1574dd0191d5SShuanglin Wang { 15754a925aa7SKishore Padmanabha struct bnxt_ulp_key_recipe_entry **recipes; 1576dd0191d5SShuanglin Wang enum bnxt_ulp_resource_sub_type stype; 15774a925aa7SKishore Padmanabha struct bnxt_ulp_mapper_data *mdata = NULL; 157861a7ca1fSKishore Padmanabha uint64_t regval = 0; 157961a7ca1fSKishore Padmanabha uint32_t recipe_id = 0; 1580dd0191d5SShuanglin Wang 1581dd0191d5SShuanglin Wang /* Don't like this, but need to convert from a tbl resource func to the 1582dd0191d5SShuanglin Wang * subtype for key_recipes. 1583dd0191d5SShuanglin Wang */ 1584dd0191d5SShuanglin Wang switch (tbl->resource_func) { 1585dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_EM_TABLE: 1586dd0191d5SShuanglin Wang stype = BNXT_ULP_RESOURCE_SUB_TYPE_KEY_RECIPE_TABLE_EM; 1587dd0191d5SShuanglin Wang break; 1588dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE: 1589dd0191d5SShuanglin Wang stype = BNXT_ULP_RESOURCE_SUB_TYPE_KEY_RECIPE_TABLE_WM; 1590dd0191d5SShuanglin Wang break; 1591dd0191d5SShuanglin Wang default: 1592dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid res func(%d) for recipe fields\n", 1593dd0191d5SShuanglin Wang tbl->resource_func); 1594dd0191d5SShuanglin Wang return NULL; 1595dd0191d5SShuanglin Wang }; 1596dd0191d5SShuanglin Wang 1597dd0191d5SShuanglin Wang /* Get the recipe index from the registry file */ 1598c569279aSShuanglin Wang if (ulp_regfile_read(parms->regfile, tbl->key_recipe_operand, 159961a7ca1fSKishore Padmanabha ®val)) { 16004a925aa7SKishore Padmanabha BNXT_DRV_DBG(ERR, "Failed to get tbl idx from regfile[%d].\n", 1601dd0191d5SShuanglin Wang tbl->tbl_operand); 1602dd0191d5SShuanglin Wang return NULL; 1603dd0191d5SShuanglin Wang } 160461a7ca1fSKishore Padmanabha recipe_id = (uint32_t)tfp_be_to_cpu_64(regval); 16054a925aa7SKishore Padmanabha mdata = ulp_mapper_key_recipe_args_validate(parms->ulp_ctx, 16064a925aa7SKishore Padmanabha tbl->direction, 16074a925aa7SKishore Padmanabha stype, recipe_id); 16084a925aa7SKishore Padmanabha if (mdata == NULL) 1609dd0191d5SShuanglin Wang return NULL; 1610dd0191d5SShuanglin Wang 16114a925aa7SKishore Padmanabha recipes = mdata->key_recipe_info.recipes[tbl->direction][stype]; 16124a925aa7SKishore Padmanabha if (recipes[recipe_id] == NULL) 16134a925aa7SKishore Padmanabha return NULL; 16144a925aa7SKishore Padmanabha 16154a925aa7SKishore Padmanabha *num_flds = recipes[recipe_id]->cnt; 16164a925aa7SKishore Padmanabha return &recipes[recipe_id]->flds[0]; 1617dd0191d5SShuanglin Wang } 1618dd0191d5SShuanglin Wang 1619dd0191d5SShuanglin Wang static int32_t 1620dd0191d5SShuanglin Wang ulp_mapper_key_recipe_field_opc_next(struct bnxt_ulp_mapper_parms *parms, 1621dd0191d5SShuanglin Wang enum bnxt_ulp_direction dir, 1622dd0191d5SShuanglin Wang uint8_t *field_opr, 1623dd0191d5SShuanglin Wang uint8_t is_key, 1624dd0191d5SShuanglin Wang const char *name, 1625dd0191d5SShuanglin Wang bool *written, 1626dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_field_info *ofld) 1627dd0191d5SShuanglin Wang { 1628dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_field_info *field_info; 162930d7102dSKishore Padmanabha uint16_t idx = 0; 1630dd0191d5SShuanglin Wang 1631dd0191d5SShuanglin Wang /* read the cond table index and count */ 16320c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(field_opr, 16330c036a14SPeter Spreadborough (uint8_t *)&idx, sizeof(uint16_t)))) { 1634dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "field idx operand read failed\n"); 1635dd0191d5SShuanglin Wang return -EINVAL; 1636dd0191d5SShuanglin Wang } 1637dd0191d5SShuanglin Wang idx = tfp_be_to_cpu_16(idx); 1638dd0191d5SShuanglin Wang 1639dd0191d5SShuanglin Wang field_info = ulp_mapper_tmpl_key_ext_list_get(parms, idx); 16400c036a14SPeter Spreadborough if (unlikely(field_info == NULL)) { 1641dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid field idx %d\n", idx); 1642dd0191d5SShuanglin Wang return -EINVAL; 1643dd0191d5SShuanglin Wang } 1644dd0191d5SShuanglin Wang 1645dd0191d5SShuanglin Wang return ulp_mapper_key_recipe_field_opc_process(parms, dir, field_info, 1646dd0191d5SShuanglin Wang is_key, name, 1647dd0191d5SShuanglin Wang written, ofld); 1648dd0191d5SShuanglin Wang } 1649dd0191d5SShuanglin Wang 1650dd0191d5SShuanglin Wang int32_t 1651dd0191d5SShuanglin Wang ulp_mapper_key_recipe_field_opc_process(struct bnxt_ulp_mapper_parms *parms, 1652dd0191d5SShuanglin Wang uint8_t dir, 1653dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_field_info *fld, 1654dd0191d5SShuanglin Wang uint8_t is_key, 1655dd0191d5SShuanglin Wang const char *name, 1656dd0191d5SShuanglin Wang bool *written, 1657dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_field_info *ofld) 1658dd0191d5SShuanglin Wang { 1659dd0191d5SShuanglin Wang uint8_t process_src1 = 0; 1660dd0191d5SShuanglin Wang uint32_t val1_len = 0; 1661dd0191d5SShuanglin Wang uint64_t value1 = 0; 1662dd0191d5SShuanglin Wang int32_t rc = 0; 1663dd0191d5SShuanglin Wang uint8_t *val1; 1664dd0191d5SShuanglin Wang 1665dd0191d5SShuanglin Wang /* prepare the field source and values */ 1666dd0191d5SShuanglin Wang switch (fld->field_opc) { 1667dd0191d5SShuanglin Wang case BNXT_ULP_FIELD_OPC_SRC1: 1668dd0191d5SShuanglin Wang /* No logic, just take SRC1 and return */ 1669dd0191d5SShuanglin Wang ulp_mapper_key_recipe_copy_to_src1(ofld, fld->field_src1, 1670dd0191d5SShuanglin Wang fld->field_opr1, fld, 1671dd0191d5SShuanglin Wang written); 1672dd0191d5SShuanglin Wang return rc; 1673dd0191d5SShuanglin Wang case BNXT_ULP_FIELD_OPC_SKIP: 1674dd0191d5SShuanglin Wang *written = false; 1675dd0191d5SShuanglin Wang return rc; 1676dd0191d5SShuanglin Wang case BNXT_ULP_FIELD_OPC_SRC1_THEN_SRC2_ELSE_SRC3: 1677dd0191d5SShuanglin Wang case BNXT_ULP_FIELD_OPC_TERNARY_LIST: 1678dd0191d5SShuanglin Wang process_src1 = 1; 1679dd0191d5SShuanglin Wang break; 1680dd0191d5SShuanglin Wang default: 1681dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid fld opcode %u\n", fld->field_opc); 1682dd0191d5SShuanglin Wang rc = -EINVAL; 1683dd0191d5SShuanglin Wang return rc; 1684dd0191d5SShuanglin Wang } 1685dd0191d5SShuanglin Wang 1686dd0191d5SShuanglin Wang /* process the src1 opcode */ 1687dd0191d5SShuanglin Wang if (process_src1) { 16880c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_src_process(parms, fld->field_src1, 1689dd0191d5SShuanglin Wang fld->field_opr1, dir, is_key, 1690dd0191d5SShuanglin Wang fld->field_bit_size, &val1, 16910c036a14SPeter Spreadborough &val1_len, &value1))) { 1692dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "fld src1 process failed\n"); 1693dd0191d5SShuanglin Wang return -EINVAL; 1694dd0191d5SShuanglin Wang } 1695dd0191d5SShuanglin Wang } 1696dd0191d5SShuanglin Wang 1697dd0191d5SShuanglin Wang if (fld->field_opc == BNXT_ULP_FIELD_OPC_SRC1_THEN_SRC2_ELSE_SRC3) { 1698dd0191d5SShuanglin Wang if (value1) 1699dd0191d5SShuanglin Wang ulp_mapper_key_recipe_copy_to_src1(ofld, 1700dd0191d5SShuanglin Wang fld->field_src2, 1701dd0191d5SShuanglin Wang fld->field_opr2, 1702dd0191d5SShuanglin Wang fld, written); 1703dd0191d5SShuanglin Wang else 1704dd0191d5SShuanglin Wang ulp_mapper_key_recipe_copy_to_src1(ofld, 1705dd0191d5SShuanglin Wang fld->field_src3, 1706dd0191d5SShuanglin Wang fld->field_opr3, 1707dd0191d5SShuanglin Wang fld, written); 1708dd0191d5SShuanglin Wang } else if (fld->field_opc == BNXT_ULP_FIELD_OPC_TERNARY_LIST) { 1709dd0191d5SShuanglin Wang if (value1) { 1710dd0191d5SShuanglin Wang /* check if src2 is next */ 1711dd0191d5SShuanglin Wang if (fld->field_src2 == BNXT_ULP_FIELD_SRC_NEXT) { 1712dd0191d5SShuanglin Wang /* get the next field info */ 17130c036a14SPeter Spreadborough if (unlikely(ulp_mapper_key_recipe_field_opc_next(parms, 1714dd0191d5SShuanglin Wang dir, 1715dd0191d5SShuanglin Wang fld->field_opr2, 1716dd0191d5SShuanglin Wang is_key, 1717dd0191d5SShuanglin Wang name, 1718dd0191d5SShuanglin Wang written, 17190c036a14SPeter Spreadborough ofld))) { 1720dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 1721dd0191d5SShuanglin Wang "recipe fld next process fail\n"); 1722dd0191d5SShuanglin Wang return -EINVAL; 1723dd0191d5SShuanglin Wang } else { 1724dd0191d5SShuanglin Wang return rc; 1725dd0191d5SShuanglin Wang } 1726dd0191d5SShuanglin Wang } else { 1727dd0191d5SShuanglin Wang ulp_mapper_key_recipe_copy_to_src1(ofld, 1728dd0191d5SShuanglin Wang fld->field_src2, 1729dd0191d5SShuanglin Wang fld->field_opr2, 1730dd0191d5SShuanglin Wang fld, written); 1731dd0191d5SShuanglin Wang } 1732dd0191d5SShuanglin Wang } else { 1733dd0191d5SShuanglin Wang /* check if src3 is next */ 1734dd0191d5SShuanglin Wang if (fld->field_src3 == BNXT_ULP_FIELD_SRC_NEXT) { 1735dd0191d5SShuanglin Wang /* get the next field info */ 17360c036a14SPeter Spreadborough if (unlikely(ulp_mapper_key_recipe_field_opc_next(parms, 1737dd0191d5SShuanglin Wang dir, 1738dd0191d5SShuanglin Wang fld->field_opr3, 1739dd0191d5SShuanglin Wang is_key, 1740dd0191d5SShuanglin Wang name, 1741dd0191d5SShuanglin Wang written, 17420c036a14SPeter Spreadborough ofld))) { 1743dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 1744dd0191d5SShuanglin Wang "recipt fld next process fail\n"); 1745dd0191d5SShuanglin Wang return -EINVAL; 1746dd0191d5SShuanglin Wang } else { 1747dd0191d5SShuanglin Wang return rc; 1748dd0191d5SShuanglin Wang } 1749dd0191d5SShuanglin Wang } else { 1750dd0191d5SShuanglin Wang ulp_mapper_key_recipe_copy_to_src1(ofld, 1751dd0191d5SShuanglin Wang fld->field_src3, 1752dd0191d5SShuanglin Wang fld->field_opr3, 1753dd0191d5SShuanglin Wang fld, written); 1754dd0191d5SShuanglin Wang } 1755dd0191d5SShuanglin Wang } 1756dd0191d5SShuanglin Wang } 1757af50070eSKishore Padmanabha #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 1758af50070eSKishore Padmanabha #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 1759af50070eSKishore Padmanabha if (*written && is_key) 1760af50070eSKishore Padmanabha BNXT_DRV_DBG(DEBUG, "%-20s bits = %-3d\n", fld->description, 1761af50070eSKishore Padmanabha fld->field_bit_size); 1762af50070eSKishore Padmanabha #endif 1763af50070eSKishore Padmanabha #endif 1764dd0191d5SShuanglin Wang return rc; 1765dd0191d5SShuanglin Wang } 1766dd0191d5SShuanglin Wang 1767dd0191d5SShuanglin Wang static int32_t 1768dd0191d5SShuanglin Wang ulp_mapper_key_recipe_tbl_process(struct bnxt_ulp_mapper_parms *parms, 1769dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl) 1770dd0191d5SShuanglin Wang { 177161a7ca1fSKishore Padmanabha bool alloc = false, write = false, regfile = false; 1772dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_key_info *kflds, *rflds; 1773dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_field_info *kfld, *rfld; 177461a7ca1fSKishore Padmanabha struct bnxt_ulp_mapper_data *mdata = NULL; 1775dd0191d5SShuanglin Wang struct bnxt_ulp_key_recipe_entry *recipe; 1776dd0191d5SShuanglin Wang struct ulp_flow_db_res_params fid_parms; 177761a7ca1fSKishore Padmanabha int32_t rc = 0, free_rc, tmp_recipe_id; 177861a7ca1fSKishore Padmanabha enum bnxt_ulp_resource_sub_type stype; 177961a7ca1fSKishore Padmanabha uint8_t max_rflds = 0, rnum_flds = 0; 178061a7ca1fSKishore Padmanabha enum bnxt_ulp_direction dir; 178161a7ca1fSKishore Padmanabha struct bitalloc *recipe_ba = NULL; 178261a7ca1fSKishore Padmanabha uint32_t recipe_id = 0; 1783dd0191d5SShuanglin Wang uint32_t i, num_kflds; 1784dd0191d5SShuanglin Wang bool written = false; 1785dd0191d5SShuanglin Wang uint64_t regval = 0; 1786dd0191d5SShuanglin Wang 178761a7ca1fSKishore Padmanabha dir = tbl->direction; 178861a7ca1fSKishore Padmanabha stype = tbl->resource_sub_type; 178961a7ca1fSKishore Padmanabha 179061a7ca1fSKishore Padmanabha switch (tbl->tbl_opcode) { 179161a7ca1fSKishore Padmanabha case BNXT_ULP_KEY_RECIPE_TBL_OPC_ALLOC_WR_REGFILE: 179261a7ca1fSKishore Padmanabha alloc = true; 179361a7ca1fSKishore Padmanabha write = true; 179461a7ca1fSKishore Padmanabha regfile = true; 179561a7ca1fSKishore Padmanabha break; 179661a7ca1fSKishore Padmanabha case BNXT_ULP_KEY_RECIPE_TBL_OPC_ALLOC_REGFILE: 179761a7ca1fSKishore Padmanabha alloc = true; 179861a7ca1fSKishore Padmanabha regfile = true; 179961a7ca1fSKishore Padmanabha break; 180061a7ca1fSKishore Padmanabha case BNXT_ULP_KEY_RECIPE_TBL_OPC_WR_REGFILE: 180161a7ca1fSKishore Padmanabha alloc = false; 180261a7ca1fSKishore Padmanabha regfile = true; 180361a7ca1fSKishore Padmanabha write = true; 1804dd0191d5SShuanglin Wang break; 1805dd0191d5SShuanglin Wang default: 1806dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid recipe table opcode %d\n", 1807dd0191d5SShuanglin Wang tbl->tbl_opcode); 1808dd0191d5SShuanglin Wang return -EINVAL; 1809dd0191d5SShuanglin Wang }; 1810dd0191d5SShuanglin Wang 181161a7ca1fSKishore Padmanabha /* Get the recipe_id from the regfile */ 181261a7ca1fSKishore Padmanabha if (!alloc && regfile) { 18130c036a14SPeter Spreadborough if (unlikely(ulp_regfile_read(parms->regfile, 181461a7ca1fSKishore Padmanabha tbl->tbl_operand, 18150c036a14SPeter Spreadborough ®val))) { 181661a7ca1fSKishore Padmanabha BNXT_DRV_DBG(ERR, 181761a7ca1fSKishore Padmanabha "Fail to get tbl idx from regfile[%d].\n", 181861a7ca1fSKishore Padmanabha tbl->tbl_operand); 181961a7ca1fSKishore Padmanabha return -EINVAL; 182061a7ca1fSKishore Padmanabha } 182161a7ca1fSKishore Padmanabha recipe_id = rte_be_to_cpu_64(regval); 182261a7ca1fSKishore Padmanabha } 182361a7ca1fSKishore Padmanabha 182461a7ca1fSKishore Padmanabha if (alloc) { 182561a7ca1fSKishore Padmanabha /* Allocate a recipe id based on the direction and type 182661a7ca1fSKishore Padmanabha * only supported types are EM and WC for now. 182761a7ca1fSKishore Padmanabha */ 182861a7ca1fSKishore Padmanabha mdata = ulp_mapper_key_recipe_args_validate(parms->ulp_ctx, dir, 182961a7ca1fSKishore Padmanabha stype, 0); 18300c036a14SPeter Spreadborough if (unlikely(mdata == NULL)) 183161a7ca1fSKishore Padmanabha return -EINVAL; 183261a7ca1fSKishore Padmanabha 183361a7ca1fSKishore Padmanabha recipe_ba = mdata->key_recipe_info.recipe_ba[dir][stype]; 183461a7ca1fSKishore Padmanabha tmp_recipe_id = ba_alloc(recipe_ba); 18350c036a14SPeter Spreadborough if (unlikely(tmp_recipe_id < 0)) { 183661a7ca1fSKishore Padmanabha BNXT_DRV_DBG(ERR, "Failed to allocate a recipe id\n"); 183761a7ca1fSKishore Padmanabha return -EINVAL; 18380c036a14SPeter Spreadborough } else if (unlikely((uint32_t)tmp_recipe_id >= 18390c036a14SPeter Spreadborough mdata->key_recipe_info.num_recipes)) { 184061a7ca1fSKishore Padmanabha /* Shouldn't get here, but could be an issue with the 184161a7ca1fSKishore Padmanabha * allocator, so free the recipe_id 184261a7ca1fSKishore Padmanabha */ 184361a7ca1fSKishore Padmanabha BNXT_DRV_DBG(ERR, 184461a7ca1fSKishore Padmanabha "Allocated recipe id(%d) >= max(%d)\n", 184561a7ca1fSKishore Padmanabha tmp_recipe_id, 184661a7ca1fSKishore Padmanabha mdata->key_recipe_info.num_recipes); 184761a7ca1fSKishore Padmanabha (void)ba_free(recipe_ba, tmp_recipe_id); 184861a7ca1fSKishore Padmanabha return -EINVAL; 184961a7ca1fSKishore Padmanabha } 185061a7ca1fSKishore Padmanabha /* any error after this must goto error in order to free 185161a7ca1fSKishore Padmanabha * the recipe_id 185261a7ca1fSKishore Padmanabha */ 185361a7ca1fSKishore Padmanabha recipe_id = tmp_recipe_id; 185461a7ca1fSKishore Padmanabha } 185561a7ca1fSKishore Padmanabha 185661a7ca1fSKishore Padmanabha if (alloc && regfile) { 185761a7ca1fSKishore Padmanabha regval = rte_cpu_to_be_64(recipe_id); 185861a7ca1fSKishore Padmanabha rc = ulp_regfile_write(parms->regfile, tbl->tbl_operand, 185961a7ca1fSKishore Padmanabha regval); 18600c036a14SPeter Spreadborough if (unlikely(rc)) { 186161a7ca1fSKishore Padmanabha BNXT_DRV_DBG(ERR, "Failed to write regfile[%d] rc=%d\n", 186261a7ca1fSKishore Padmanabha tbl->tbl_operand, rc); 186361a7ca1fSKishore Padmanabha if (recipe_ba) 186461a7ca1fSKishore Padmanabha (void)ba_free(recipe_ba, recipe_id); 186561a7ca1fSKishore Padmanabha return -EINVAL; 186661a7ca1fSKishore Padmanabha } 186761a7ca1fSKishore Padmanabha } 186861a7ca1fSKishore Padmanabha 186961a7ca1fSKishore Padmanabha /* allocate or Get the recipe entry based on alloc */ 187061a7ca1fSKishore Padmanabha recipe = ulp_mapper_key_recipe_alloc(parms->ulp_ctx, dir, stype, 187161a7ca1fSKishore Padmanabha recipe_id, alloc, &max_rflds); 18720c036a14SPeter Spreadborough if (unlikely(!recipe || !max_rflds)) { 187361a7ca1fSKishore Padmanabha BNXT_DRV_DBG(ERR, "Failed to get the recipe slot\n"); 187461a7ca1fSKishore Padmanabha if (recipe_ba) 187561a7ca1fSKishore Padmanabha (void)ba_free(recipe_ba, recipe_id); 187661a7ca1fSKishore Padmanabha return -EINVAL; 187761a7ca1fSKishore Padmanabha } 187861a7ca1fSKishore Padmanabha 187961a7ca1fSKishore Padmanabha /* We have a recipe_id by now, write the data */ 188061a7ca1fSKishore Padmanabha if (write) { 1881dd0191d5SShuanglin Wang /* Get the key fields to process */ 1882dd0191d5SShuanglin Wang kflds = ulp_mapper_key_fields_get(parms, tbl, &num_kflds); 18830c036a14SPeter Spreadborough if (unlikely(!kflds || !num_kflds)) { 1884dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get the key fields\n"); 188561a7ca1fSKishore Padmanabha rc = -EINVAL; 188661a7ca1fSKishore Padmanabha goto error; 1887dd0191d5SShuanglin Wang } 1888dd0191d5SShuanglin Wang 1889dd0191d5SShuanglin Wang rflds = &recipe->flds[0]; 1890dd0191d5SShuanglin Wang /* iterate over the key fields and write the recipe */ 1891dd0191d5SShuanglin Wang for (i = 0; i < num_kflds; i++) { 18920c036a14SPeter Spreadborough if (unlikely(rnum_flds >= max_rflds)) { 189361a7ca1fSKishore Padmanabha BNXT_DRV_DBG(ERR, 189461a7ca1fSKishore Padmanabha "Max recipe fields exceeded (%d)\n", 1895dd0191d5SShuanglin Wang rnum_flds); 1896dd0191d5SShuanglin Wang goto error; 1897dd0191d5SShuanglin Wang } 1898dd0191d5SShuanglin Wang written = false; 1899dd0191d5SShuanglin Wang kfld = &kflds[i].field_info_spec; 1900dd0191d5SShuanglin Wang rfld = &rflds[rnum_flds].field_info_spec; 1901dd0191d5SShuanglin Wang 190261a7ca1fSKishore Padmanabha rc = ulp_mapper_key_recipe_field_opc_process(parms, 190361a7ca1fSKishore Padmanabha dir, 190461a7ca1fSKishore Padmanabha kfld, 1, 190561a7ca1fSKishore Padmanabha "KEY", 190661a7ca1fSKishore Padmanabha &written, 190761a7ca1fSKishore Padmanabha rfld); 19080c036a14SPeter Spreadborough if (unlikely(rc)) 1909dd0191d5SShuanglin Wang goto error; 1910dd0191d5SShuanglin Wang 191161a7ca1fSKishore Padmanabha if (stype == 1912dd0191d5SShuanglin Wang BNXT_ULP_RESOURCE_SUB_TYPE_KEY_RECIPE_TABLE_WM) { 1913dd0191d5SShuanglin Wang kfld = &kflds[i].field_info_mask; 1914dd0191d5SShuanglin Wang rfld = &rflds[rnum_flds].field_info_mask; 1915dd0191d5SShuanglin Wang rc = ulp_mapper_key_recipe_field_opc_process(parms, 191661a7ca1fSKishore Padmanabha dir, 191761a7ca1fSKishore Padmanabha kfld, 191861a7ca1fSKishore Padmanabha 0, 191961a7ca1fSKishore Padmanabha "MASK", 192061a7ca1fSKishore Padmanabha &written, 192161a7ca1fSKishore Padmanabha rfld); 19220c036a14SPeter Spreadborough if (unlikely(rc)) 1923dd0191d5SShuanglin Wang goto error; 1924dd0191d5SShuanglin Wang } 1925dd0191d5SShuanglin Wang if (written) 1926dd0191d5SShuanglin Wang rnum_flds++; 1927dd0191d5SShuanglin Wang } 1928dd0191d5SShuanglin Wang recipe->cnt = rnum_flds; 192961a7ca1fSKishore Padmanabha } 1930dd0191d5SShuanglin Wang 1931dd0191d5SShuanglin Wang memset(&fid_parms, 0, sizeof(fid_parms)); 1932dd0191d5SShuanglin Wang fid_parms.direction = tbl->direction; 1933dd0191d5SShuanglin Wang fid_parms.resource_func = tbl->resource_func; 1934dd0191d5SShuanglin Wang fid_parms.resource_type = tbl->resource_type; 1935dd0191d5SShuanglin Wang fid_parms.resource_sub_type = tbl->resource_sub_type; 1936dd0191d5SShuanglin Wang fid_parms.resource_hndl = recipe_id; 1937dd0191d5SShuanglin Wang fid_parms.critical_resource = tbl->critical_resource; 1938dd0191d5SShuanglin Wang 1939dd0191d5SShuanglin Wang rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 19400c036a14SPeter Spreadborough if (unlikely(rc)) { 1941dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to link resource to flow rc = %d\n", 1942dd0191d5SShuanglin Wang rc); 1943dd0191d5SShuanglin Wang goto error; 1944dd0191d5SShuanglin Wang } 1945dd0191d5SShuanglin Wang 1946dd0191d5SShuanglin Wang return rc; 1947dd0191d5SShuanglin Wang error: 194861a7ca1fSKishore Padmanabha /* Free the actual recipe */ 1949dd0191d5SShuanglin Wang free_rc = ulp_mapper_key_recipe_free(parms->ulp_ctx, tbl->direction, 1950dd0191d5SShuanglin Wang tbl->resource_sub_type, recipe_id); 1951dd0191d5SShuanglin Wang if (free_rc) 1952dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to free recipe on error: %d\n", 1953dd0191d5SShuanglin Wang free_rc); 1954dd0191d5SShuanglin Wang return rc; 1955dd0191d5SShuanglin Wang } 1956dd0191d5SShuanglin Wang 1957dd0191d5SShuanglin Wang int32_t 1958286569d5SKishore Padmanabha ulp_mapper_field_opc_process(struct bnxt_ulp_mapper_parms *parms, 1959286569d5SKishore Padmanabha enum tf_dir dir, 1960286569d5SKishore Padmanabha struct bnxt_ulp_mapper_field_info *fld, 1961286569d5SKishore Padmanabha struct ulp_blob *blob, 1962286569d5SKishore Padmanabha uint8_t is_key, 1963286569d5SKishore Padmanabha const char *name) 1964286569d5SKishore Padmanabha { 1965286569d5SKishore Padmanabha uint16_t write_idx = blob->write_idx; 1966286569d5SKishore Padmanabha uint8_t *val = NULL, *val1, *val2, *val3; 1967286569d5SKishore Padmanabha uint32_t val_len = 0, val1_len = 0, val2_len = 0, val3_len = 0; 1968286569d5SKishore Padmanabha uint8_t process_src1 = 0, process_src2 = 0, process_src3 = 0; 1969286569d5SKishore Padmanabha uint8_t eval_src1 = 0, eval_src2 = 0, eval_src3 = 0; 1970286569d5SKishore Padmanabha uint64_t val_int = 0, val1_int = 0, val2_int = 0, val3_int = 0; 1971286569d5SKishore Padmanabha uint64_t value1 = 0, value2 = 0, value3 = 0; 1972286569d5SKishore Padmanabha int32_t rc = 0; 1973286569d5SKishore Padmanabha 1974286569d5SKishore Padmanabha /* prepare the field source and values */ 1975286569d5SKishore Padmanabha switch (fld->field_opc) { 1976286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1: 1977286569d5SKishore Padmanabha process_src1 = 1; 1978286569d5SKishore Padmanabha break; 1979286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_THEN_SRC2_ELSE_SRC3: 1980dd0191d5SShuanglin Wang case BNXT_ULP_FIELD_OPC_TERNARY_LIST: 1981286569d5SKishore Padmanabha process_src1 = 1; 1982286569d5SKishore Padmanabha break; 1983286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_OR_SRC2_OR_SRC3: 1984286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_AND_SRC2_OR_SRC3: 1985286569d5SKishore Padmanabha process_src3 = 1; 1986286569d5SKishore Padmanabha eval_src3 = 1; 1987286569d5SKishore Padmanabha process_src1 = 1; 1988286569d5SKishore Padmanabha process_src2 = 1; 1989286569d5SKishore Padmanabha eval_src1 = 1; 1990286569d5SKishore Padmanabha eval_src2 = 1; 1991286569d5SKishore Padmanabha break; 1992286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_PLUS_SRC2: 1993286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_MINUS_SRC2: 1994286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_PLUS_SRC2_POST: 1995286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_MINUS_SRC2_POST: 1996286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_OR_SRC2: 1997286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_AND_SRC2: 1998286569d5SKishore Padmanabha process_src1 = 1; 1999286569d5SKishore Padmanabha process_src2 = 1; 2000286569d5SKishore Padmanabha eval_src1 = 1; 2001286569d5SKishore Padmanabha eval_src2 = 1; 2002286569d5SKishore Padmanabha break; 2003286569d5SKishore Padmanabha default: 2004286569d5SKishore Padmanabha break; 2005286569d5SKishore Padmanabha } 2006286569d5SKishore Padmanabha 2007286569d5SKishore Padmanabha /* process the src1 opcode */ 2008286569d5SKishore Padmanabha if (process_src1) { 20090c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_src_process(parms, fld->field_src1, 2010286569d5SKishore Padmanabha fld->field_opr1, dir, is_key, 2011286569d5SKishore Padmanabha fld->field_bit_size, &val1, 20120c036a14SPeter Spreadborough &val1_len, &value1))) { 2013dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "fld src1 process failed\n"); 2014286569d5SKishore Padmanabha goto error; 2015286569d5SKishore Padmanabha } 2016286569d5SKishore Padmanabha if (eval_src1) { 20170c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_buffer_eval(val1, val1_len, 20180c036a14SPeter Spreadborough &val1_int))) { 2019dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "fld src1 eval failed\n"); 2020286569d5SKishore Padmanabha goto error; 2021286569d5SKishore Padmanabha } 2022286569d5SKishore Padmanabha } 2023286569d5SKishore Padmanabha } 2024286569d5SKishore Padmanabha 2025286569d5SKishore Padmanabha /* for "if then clause" set the correct process */ 2026286569d5SKishore Padmanabha if (fld->field_opc == BNXT_ULP_FIELD_OPC_SRC1_THEN_SRC2_ELSE_SRC3) { 2027286569d5SKishore Padmanabha if (value1) 2028286569d5SKishore Padmanabha process_src2 = 1; 2029286569d5SKishore Padmanabha else 2030286569d5SKishore Padmanabha process_src3 = 1; 2031dd0191d5SShuanglin Wang } else if (fld->field_opc == BNXT_ULP_FIELD_OPC_TERNARY_LIST) { 2032dd0191d5SShuanglin Wang if (value1) { 2033dd0191d5SShuanglin Wang /* check if src2 is next */ 2034dd0191d5SShuanglin Wang if (fld->field_src2 == BNXT_ULP_FIELD_SRC_NEXT) { 2035dd0191d5SShuanglin Wang /* get the next field info */ 20360c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_opc_next(parms, dir, 2037dd0191d5SShuanglin Wang fld->field_opr2, 2038dd0191d5SShuanglin Wang blob, is_key, 20390c036a14SPeter Spreadborough name))) { 2040dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 2041dd0191d5SShuanglin Wang "fld next process fail\n"); 2042dd0191d5SShuanglin Wang goto error; 2043dd0191d5SShuanglin Wang } else { 2044dd0191d5SShuanglin Wang return rc; 2045dd0191d5SShuanglin Wang } 2046dd0191d5SShuanglin Wang } else { 2047dd0191d5SShuanglin Wang process_src2 = 1; 2048dd0191d5SShuanglin Wang } 2049dd0191d5SShuanglin Wang } else { 2050dd0191d5SShuanglin Wang /* check if src2 is next */ 2051dd0191d5SShuanglin Wang if (fld->field_src3 == BNXT_ULP_FIELD_SRC_NEXT) { 2052dd0191d5SShuanglin Wang /* get the next field info */ 20530c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_opc_next(parms, dir, 2054dd0191d5SShuanglin Wang fld->field_opr3, 2055dd0191d5SShuanglin Wang blob, is_key, 20560c036a14SPeter Spreadborough name))) { 2057dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 2058dd0191d5SShuanglin Wang "fld next process fail\n"); 2059dd0191d5SShuanglin Wang goto error; 2060dd0191d5SShuanglin Wang } else { 2061dd0191d5SShuanglin Wang return rc; 2062dd0191d5SShuanglin Wang } 2063dd0191d5SShuanglin Wang } else { 2064dd0191d5SShuanglin Wang process_src3 = 1; 2065dd0191d5SShuanglin Wang } 2066dd0191d5SShuanglin Wang } 2067286569d5SKishore Padmanabha } 2068286569d5SKishore Padmanabha 2069286569d5SKishore Padmanabha /* process src2 opcode */ 2070286569d5SKishore Padmanabha if (process_src2) { 20710c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_src_process(parms, fld->field_src2, 2072286569d5SKishore Padmanabha fld->field_opr2, dir, is_key, 2073286569d5SKishore Padmanabha fld->field_bit_size, &val2, 20740c036a14SPeter Spreadborough &val2_len, &value2))) { 2075dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "fld src2 process failed\n"); 2076286569d5SKishore Padmanabha goto error; 2077286569d5SKishore Padmanabha } 2078286569d5SKishore Padmanabha if (eval_src2) { 20790c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_buffer_eval(val2, val2_len, 20800c036a14SPeter Spreadborough &val2_int))) { 2081dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "fld src2 eval failed\n"); 2082286569d5SKishore Padmanabha goto error; 2083286569d5SKishore Padmanabha } 2084286569d5SKishore Padmanabha } 2085286569d5SKishore Padmanabha } 2086286569d5SKishore Padmanabha 2087286569d5SKishore Padmanabha /* process src3 opcode */ 2088286569d5SKishore Padmanabha if (process_src3) { 20890c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_src_process(parms, fld->field_src3, 2090286569d5SKishore Padmanabha fld->field_opr3, dir, is_key, 2091286569d5SKishore Padmanabha fld->field_bit_size, &val3, 20920c036a14SPeter Spreadborough &val3_len, &value3))) { 2093dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "fld src3 process failed\n"); 2094286569d5SKishore Padmanabha goto error; 2095286569d5SKishore Padmanabha } 2096286569d5SKishore Padmanabha if (eval_src3) { 20970c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_buffer_eval(val3, val3_len, 20980c036a14SPeter Spreadborough &val3_int))) { 2099dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "fld src3 eval failed\n"); 2100286569d5SKishore Padmanabha goto error; 2101286569d5SKishore Padmanabha } 2102286569d5SKishore Padmanabha } 2103286569d5SKishore Padmanabha } 2104286569d5SKishore Padmanabha 2105286569d5SKishore Padmanabha val_len = fld->field_bit_size; 2106286569d5SKishore Padmanabha /* process the field opcodes */ 2107286569d5SKishore Padmanabha switch (fld->field_opc) { 2108286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1: 21095b73c859SKishore Padmanabha rc = ulp_mapper_field_blob_write(fld->field_src1, 21105b73c859SKishore Padmanabha blob, val1, val1_len, &val); 2111286569d5SKishore Padmanabha val_len = val1_len; 2112286569d5SKishore Padmanabha break; 2113286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_THEN_SRC2_ELSE_SRC3: 2114dd0191d5SShuanglin Wang case BNXT_ULP_FIELD_OPC_TERNARY_LIST: 2115286569d5SKishore Padmanabha if (value1) { 21165b73c859SKishore Padmanabha rc = ulp_mapper_field_blob_write(fld->field_src2, blob, 21175b73c859SKishore Padmanabha val2, val2_len, &val); 2118286569d5SKishore Padmanabha val_len = val2_len; 2119286569d5SKishore Padmanabha } else { 21205b73c859SKishore Padmanabha rc = ulp_mapper_field_blob_write(fld->field_src3, blob, 21215b73c859SKishore Padmanabha val3, val3_len, &val); 2122286569d5SKishore Padmanabha val_len = val3_len; 2123286569d5SKishore Padmanabha } 2124286569d5SKishore Padmanabha break; 2125286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_PLUS_SRC2: 2126286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_PLUS_SRC2_POST: 2127286569d5SKishore Padmanabha val_int = val1_int + val2_int; 2128286569d5SKishore Padmanabha val_int = tfp_cpu_to_be_64(val_int); 2129286569d5SKishore Padmanabha val = ulp_blob_push_64(blob, &val_int, fld->field_bit_size); 21300c036a14SPeter Spreadborough if (unlikely(!val)) 21315b73c859SKishore Padmanabha rc = -EINVAL; 2132286569d5SKishore Padmanabha break; 2133286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_MINUS_SRC2: 2134286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_MINUS_SRC2_POST: 2135286569d5SKishore Padmanabha val_int = val1_int - val2_int; 2136286569d5SKishore Padmanabha val_int = tfp_cpu_to_be_64(val_int); 2137286569d5SKishore Padmanabha val = ulp_blob_push_64(blob, &val_int, fld->field_bit_size); 21380c036a14SPeter Spreadborough if (unlikely(!val)) 21395b73c859SKishore Padmanabha rc = -EINVAL; 2140286569d5SKishore Padmanabha break; 2141286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_OR_SRC2: 2142286569d5SKishore Padmanabha val_int = val1_int | val2_int; 2143286569d5SKishore Padmanabha val_int = tfp_cpu_to_be_64(val_int); 2144286569d5SKishore Padmanabha val = ulp_blob_push_64(blob, &val_int, fld->field_bit_size); 21450c036a14SPeter Spreadborough if (unlikely(!val)) 21465b73c859SKishore Padmanabha rc = -EINVAL; 2147286569d5SKishore Padmanabha break; 2148286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_OR_SRC2_OR_SRC3: 2149286569d5SKishore Padmanabha val_int = val1_int | val2_int | val3_int; 2150286569d5SKishore Padmanabha val_int = tfp_cpu_to_be_64(val_int); 2151286569d5SKishore Padmanabha val = ulp_blob_push_64(blob, &val_int, fld->field_bit_size); 21520c036a14SPeter Spreadborough if (unlikely(!val)) 21535b73c859SKishore Padmanabha rc = -EINVAL; 2154286569d5SKishore Padmanabha break; 2155286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_AND_SRC2: 2156286569d5SKishore Padmanabha val_int = val1_int & val2_int; 2157286569d5SKishore Padmanabha val_int = tfp_cpu_to_be_64(val_int); 2158286569d5SKishore Padmanabha val = ulp_blob_push_64(blob, &val_int, fld->field_bit_size); 21590c036a14SPeter Spreadborough if (unlikely(!val)) 21605b73c859SKishore Padmanabha rc = -EINVAL; 2161286569d5SKishore Padmanabha break; 2162286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SRC1_AND_SRC2_OR_SRC3: 2163286569d5SKishore Padmanabha val_int = val1_int & (val2_int | val3_int); 2164286569d5SKishore Padmanabha val_int = tfp_cpu_to_be_64(val_int); 2165286569d5SKishore Padmanabha val = ulp_blob_push_64(blob, &val_int, fld->field_bit_size); 21660c036a14SPeter Spreadborough if (unlikely(!val)) 21675b73c859SKishore Padmanabha rc = -EINVAL; 2168286569d5SKishore Padmanabha break; 2169286569d5SKishore Padmanabha case BNXT_ULP_FIELD_OPC_SKIP: 2170286569d5SKishore Padmanabha break; 2171286569d5SKishore Padmanabha default: 2172dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid fld opcode %u\n", fld->field_opc); 21735b73c859SKishore Padmanabha rc = -EINVAL; 2174286569d5SKishore Padmanabha break; 2175286569d5SKishore Padmanabha } 2176286569d5SKishore Padmanabha 21776d160d77SRandy Schacher if (!rc) 2178286569d5SKishore Padmanabha return rc; 2179286569d5SKishore Padmanabha error: 2180dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Error in %s:%s process %u:%u\n", name, 2181286569d5SKishore Padmanabha fld->description, (val) ? write_idx : 0, val_len); 2182286569d5SKishore Padmanabha return -EINVAL; 2183286569d5SKishore Padmanabha } 2184286569d5SKishore Padmanabha 2185aebe3cb7SKishore Padmanabha /* 2186aebe3cb7SKishore Padmanabha * Result table process and fill the result blob. 2187aebe3cb7SKishore Padmanabha * data [out] - the result blob data 2188aebe3cb7SKishore Padmanabha */ 2189dd0191d5SShuanglin Wang int32_t 2190aebe3cb7SKishore Padmanabha ulp_mapper_tbl_result_build(struct bnxt_ulp_mapper_parms *parms, 2191aebe3cb7SKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl, 2192aebe3cb7SKishore Padmanabha struct ulp_blob *data, 2193aebe3cb7SKishore Padmanabha const char *name) 2194aebe3cb7SKishore Padmanabha { 2195a2417601SKishore Padmanabha struct bnxt_ulp_mapper_field_info *dflds; 2196f63aa27dSKishore Padmanabha uint32_t i = 0, num_flds = 0, encap_flds = 0; 2197dd0191d5SShuanglin Wang const struct ulp_mapper_core_ops *oper; 2198f63aa27dSKishore Padmanabha struct ulp_blob encap_blob; 2199aebe3cb7SKishore Padmanabha int32_t rc = 0; 2200aebe3cb7SKishore Padmanabha 2201aebe3cb7SKishore Padmanabha /* Get the result field list */ 2202aebe3cb7SKishore Padmanabha dflds = ulp_mapper_result_fields_get(parms, tbl, &num_flds, 2203aebe3cb7SKishore Padmanabha &encap_flds); 2204aebe3cb7SKishore Padmanabha 2205aebe3cb7SKishore Padmanabha /* validate the result field list counts */ 22060c036a14SPeter Spreadborough if (unlikely(!dflds || (!num_flds && !encap_flds))) { 2207dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get data fields %x:%x\n", 2208aebe3cb7SKishore Padmanabha num_flds, encap_flds); 2209aebe3cb7SKishore Padmanabha return -EINVAL; 2210aebe3cb7SKishore Padmanabha } 2211aebe3cb7SKishore Padmanabha 2212f63aa27dSKishore Padmanabha /* process the result fields */ 2213f63aa27dSKishore Padmanabha for (i = 0; i < num_flds; i++) { 2214286569d5SKishore Padmanabha rc = ulp_mapper_field_opc_process(parms, tbl->direction, 2215a2417601SKishore Padmanabha &dflds[i], data, 0, name); 22160c036a14SPeter Spreadborough if (unlikely(rc)) { 2217dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "result field processing failed\n"); 2218aebe3cb7SKishore Padmanabha return rc; 2219aebe3cb7SKishore Padmanabha } 2220aebe3cb7SKishore Padmanabha } 2221aebe3cb7SKishore Padmanabha 2222f63aa27dSKishore Padmanabha /* process encap fields if any */ 2223f63aa27dSKishore Padmanabha if (encap_flds) { 2224f63aa27dSKishore Padmanabha uint32_t pad = 0; 2225f63aa27dSKishore Padmanabha /* Initialize the encap blob */ 22260c036a14SPeter Spreadborough if (unlikely(ulp_blob_init(&encap_blob, 2227f63aa27dSKishore Padmanabha ULP_BYTE_2_BITS(tbl->record_size), 22280c036a14SPeter Spreadborough parms->device_params->encap_byte_order))) { 2229dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "blob inits failed.\n"); 2230f63aa27dSKishore Padmanabha return -EINVAL; 2231f63aa27dSKishore Padmanabha } 2232f63aa27dSKishore Padmanabha for (; i < encap_flds; i++) { 2233f63aa27dSKishore Padmanabha rc = ulp_mapper_field_opc_process(parms, tbl->direction, 2234f63aa27dSKishore Padmanabha &dflds[i], 2235f63aa27dSKishore Padmanabha &encap_blob, 0, name); 22360c036a14SPeter Spreadborough if (unlikely(rc)) { 2237dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 2238f63aa27dSKishore Padmanabha "encap field processing failed\n"); 2239f63aa27dSKishore Padmanabha return rc; 2240f63aa27dSKishore Padmanabha } 2241f63aa27dSKishore Padmanabha } 2242f63aa27dSKishore Padmanabha /* add the dynamic pad push */ 2243dbd29c42SKishore Padmanabha if (parms->device_params->dynamic_sram_en) { 2244dbd29c42SKishore Padmanabha uint16_t rec_s = ULP_BYTE_2_BITS(tbl->record_size); 2245dd0191d5SShuanglin Wang uint16_t blob_len; 2246dbd29c42SKishore Padmanabha 2247dd0191d5SShuanglin Wang oper = parms->mapper_data->mapper_oper; 2248dd0191d5SShuanglin Wang blob_len = ulp_blob_data_len_get(&encap_blob); 2249dd0191d5SShuanglin Wang 2250dd0191d5SShuanglin Wang /* Get the padding size */ 2251dd0191d5SShuanglin Wang oper->ulp_mapper_core_dyn_tbl_type_get(parms, tbl, 2252dd0191d5SShuanglin Wang blob_len, 2253dd0191d5SShuanglin Wang &rec_s); 2254dd0191d5SShuanglin Wang pad = rec_s - blob_len; 2255dbd29c42SKishore Padmanabha } else { 2256f63aa27dSKishore Padmanabha pad = ULP_BYTE_2_BITS(tbl->record_size) - 2257f63aa27dSKishore Padmanabha ulp_blob_data_len_get(&encap_blob); 2258dbd29c42SKishore Padmanabha } 22590c036a14SPeter Spreadborough if (unlikely(ulp_blob_pad_push(&encap_blob, pad) < 0)) { 2260dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "encap buffer padding failed\n"); 2261dbd29c42SKishore Padmanabha return -EINVAL; 2262dbd29c42SKishore Padmanabha } 2263dbd29c42SKishore Padmanabha 2264f63aa27dSKishore Padmanabha /* perform the 64 bit byte swap */ 2265f63aa27dSKishore Padmanabha ulp_blob_perform_64B_byte_swap(&encap_blob); 2266f63aa27dSKishore Padmanabha /* Append encap blob to the result blob */ 2267f63aa27dSKishore Padmanabha rc = ulp_blob_buffer_copy(data, &encap_blob); 22680c036a14SPeter Spreadborough if (unlikely(rc)) { 2269dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "encap buffer copy failed\n"); 2270f63aa27dSKishore Padmanabha return rc; 2271f63aa27dSKishore Padmanabha } 2272f63aa27dSKishore Padmanabha } 2273aebe3cb7SKishore Padmanabha return rc; 2274aebe3cb7SKishore Padmanabha } 2275aebe3cb7SKishore Padmanabha 2276dd0191d5SShuanglin Wang int32_t 2277494f03ffSKishore Padmanabha ulp_mapper_mark_gfid_process(struct bnxt_ulp_mapper_parms *parms, 22788608c099SKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl, 2279494f03ffSKishore Padmanabha uint64_t flow_id) 2280494f03ffSKishore Padmanabha { 2281494f03ffSKishore Padmanabha struct ulp_flow_db_res_params fid_parms; 22828ce17d56SKishore Padmanabha uint32_t mark, gfid, mark_flag; 22839cbfa4cfSKishore Padmanabha enum bnxt_ulp_mark_db_opc mark_op = tbl->mark_db_opcode; 2284494f03ffSKishore Padmanabha int32_t rc = 0; 2285494f03ffSKishore Padmanabha 22869cbfa4cfSKishore Padmanabha if (mark_op == BNXT_ULP_MARK_DB_OPC_NOP || 22879cbfa4cfSKishore Padmanabha !(mark_op == BNXT_ULP_MARK_DB_OPC_PUSH_IF_MARK_ACTION && 22888ce17d56SKishore Padmanabha ULP_BITMAP_ISSET(parms->act_bitmap->bits, 228959ae4961SKishore Padmanabha BNXT_ULP_ACT_BIT_MARK))) 2290494f03ffSKishore Padmanabha return rc; /* no need to perform gfid process */ 2291494f03ffSKishore Padmanabha 2292494f03ffSKishore Padmanabha /* Get the mark id details from action property */ 2293494f03ffSKishore Padmanabha memcpy(&mark, &parms->act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_MARK], 2294494f03ffSKishore Padmanabha sizeof(mark)); 2295494f03ffSKishore Padmanabha mark = tfp_be_to_cpu_32(mark); 2296494f03ffSKishore Padmanabha 2297494f03ffSKishore Padmanabha TF_GET_GFID_FROM_FLOW_ID(flow_id, gfid); 2298494f03ffSKishore Padmanabha mark_flag = BNXT_ULP_MARK_GLOBAL_HW_FID; 2299f634204bSKishore Padmanabha 2300494f03ffSKishore Padmanabha rc = ulp_mark_db_mark_add(parms->ulp_ctx, mark_flag, 2301494f03ffSKishore Padmanabha gfid, mark); 23020c036a14SPeter Spreadborough if (unlikely(rc)) { 2303dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to add mark to flow\n"); 2304494f03ffSKishore Padmanabha return rc; 2305494f03ffSKishore Padmanabha } 2306494f03ffSKishore Padmanabha fid_parms.direction = tbl->direction; 2307494f03ffSKishore Padmanabha fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_HW_FID; 2308aebe3cb7SKishore Padmanabha fid_parms.critical_resource = tbl->critical_resource; 2309494f03ffSKishore Padmanabha fid_parms.resource_type = mark_flag; 2310494f03ffSKishore Padmanabha fid_parms.resource_hndl = gfid; 2311d9e70b1dSRandy Schacher ulp_flow_db_shared_session_set(&fid_parms, tbl->session_type); 231219994cc7SKishore Padmanabha 23130117293cSKishore Padmanabha rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 23140c036a14SPeter Spreadborough if (unlikely(rc)) 2315dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Fail to link res to flow rc = %d\n", rc); 2316494f03ffSKishore Padmanabha return rc; 2317494f03ffSKishore Padmanabha } 2318494f03ffSKishore Padmanabha 2319dd0191d5SShuanglin Wang int32_t 2320494f03ffSKishore Padmanabha ulp_mapper_mark_act_ptr_process(struct bnxt_ulp_mapper_parms *parms, 23218608c099SKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl) 2322494f03ffSKishore Padmanabha { 2323494f03ffSKishore Padmanabha struct ulp_flow_db_res_params fid_parms; 23248ce17d56SKishore Padmanabha uint32_t act_idx, mark, mark_flag; 23250c036a14SPeter Spreadborough uint64_t val64 = 0; 23269cbfa4cfSKishore Padmanabha enum bnxt_ulp_mark_db_opc mark_op = tbl->mark_db_opcode; 2327494f03ffSKishore Padmanabha int32_t rc = 0; 2328494f03ffSKishore Padmanabha 23299cbfa4cfSKishore Padmanabha if (mark_op == BNXT_ULP_MARK_DB_OPC_NOP || 23309cbfa4cfSKishore Padmanabha !(mark_op == BNXT_ULP_MARK_DB_OPC_PUSH_IF_MARK_ACTION && 23318ce17d56SKishore Padmanabha ULP_BITMAP_ISSET(parms->act_bitmap->bits, 233259ae4961SKishore Padmanabha BNXT_ULP_ACT_BIT_MARK))) 2333494f03ffSKishore Padmanabha return rc; /* no need to perform mark action process */ 2334494f03ffSKishore Padmanabha 2335494f03ffSKishore Padmanabha /* Get the mark id details from action property */ 2336494f03ffSKishore Padmanabha memcpy(&mark, &parms->act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_MARK], 2337494f03ffSKishore Padmanabha sizeof(mark)); 2338494f03ffSKishore Padmanabha mark = tfp_be_to_cpu_32(mark); 2339494f03ffSKishore Padmanabha 23400c036a14SPeter Spreadborough if (unlikely(ulp_regfile_read(parms->regfile, 2341a2417601SKishore Padmanabha BNXT_ULP_RF_IDX_MAIN_ACTION_PTR, 23420c036a14SPeter Spreadborough &val64))) { 2343dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "read action ptr main failed\n"); 2344494f03ffSKishore Padmanabha return -EINVAL; 2345494f03ffSKishore Padmanabha } 2346494f03ffSKishore Padmanabha act_idx = tfp_be_to_cpu_64(val64); 2347494f03ffSKishore Padmanabha mark_flag = BNXT_ULP_MARK_LOCAL_HW_FID; 2348494f03ffSKishore Padmanabha rc = ulp_mark_db_mark_add(parms->ulp_ctx, mark_flag, 2349494f03ffSKishore Padmanabha act_idx, mark); 23500c036a14SPeter Spreadborough if (unlikely(rc)) { 2351dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to add mark to flow\n"); 2352494f03ffSKishore Padmanabha return rc; 2353494f03ffSKishore Padmanabha } 2354494f03ffSKishore Padmanabha fid_parms.direction = tbl->direction; 2355494f03ffSKishore Padmanabha fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_HW_FID; 2356aebe3cb7SKishore Padmanabha fid_parms.critical_resource = tbl->critical_resource; 2357494f03ffSKishore Padmanabha fid_parms.resource_type = mark_flag; 2358494f03ffSKishore Padmanabha fid_parms.resource_hndl = act_idx; 2359d9e70b1dSRandy Schacher ulp_flow_db_shared_session_set(&fid_parms, tbl->session_type); 236019994cc7SKishore Padmanabha 23610117293cSKishore Padmanabha rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 23620c036a14SPeter Spreadborough if (unlikely(rc)) 2363dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Fail to link res to flow rc = %d\n", rc); 2364494f03ffSKishore Padmanabha return rc; 2365494f03ffSKishore Padmanabha } 2366494f03ffSKishore Padmanabha 2367dd0191d5SShuanglin Wang int32_t 23687e3a1670SKishore Padmanabha ulp_mapper_mark_vfr_idx_process(struct bnxt_ulp_mapper_parms *parms, 23697e3a1670SKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl) 23707e3a1670SKishore Padmanabha { 23717e3a1670SKishore Padmanabha struct ulp_flow_db_res_params fid_parms; 23727e3a1670SKishore Padmanabha uint32_t act_idx, mark, mark_flag; 23730c036a14SPeter Spreadborough uint64_t val64 = 0; 23749cbfa4cfSKishore Padmanabha enum bnxt_ulp_mark_db_opc mark_op = tbl->mark_db_opcode; 23757e3a1670SKishore Padmanabha int32_t rc = 0; 23767e3a1670SKishore Padmanabha 23779cbfa4cfSKishore Padmanabha if (mark_op == BNXT_ULP_MARK_DB_OPC_NOP || 23789cbfa4cfSKishore Padmanabha mark_op == BNXT_ULP_MARK_DB_OPC_PUSH_IF_MARK_ACTION) 23797e3a1670SKishore Padmanabha return rc; /* no need to perform mark action process */ 23807e3a1670SKishore Padmanabha 23817e3a1670SKishore Padmanabha /* Get the mark id details from the computed field of dev port id */ 23827e3a1670SKishore Padmanabha mark = ULP_COMP_FLD_IDX_RD(parms, BNXT_ULP_CF_IDX_DEV_PORT_ID); 23837e3a1670SKishore Padmanabha 23847e3a1670SKishore Padmanabha /* Get the main action pointer */ 23850c036a14SPeter Spreadborough if (unlikely(ulp_regfile_read(parms->regfile, 2386a2417601SKishore Padmanabha BNXT_ULP_RF_IDX_MAIN_ACTION_PTR, 23870c036a14SPeter Spreadborough &val64))) { 2388dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "read action ptr main failed\n"); 23897e3a1670SKishore Padmanabha return -EINVAL; 23907e3a1670SKishore Padmanabha } 23917e3a1670SKishore Padmanabha act_idx = tfp_be_to_cpu_64(val64); 23927e3a1670SKishore Padmanabha 23937e3a1670SKishore Padmanabha /* Set the mark flag to local fid and vfr flag */ 23947e3a1670SKishore Padmanabha mark_flag = BNXT_ULP_MARK_LOCAL_HW_FID | BNXT_ULP_MARK_VFR_ID; 23957e3a1670SKishore Padmanabha 23967e3a1670SKishore Padmanabha rc = ulp_mark_db_mark_add(parms->ulp_ctx, mark_flag, 23977e3a1670SKishore Padmanabha act_idx, mark); 23980c036a14SPeter Spreadborough if (unlikely(rc)) { 2399dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to add mark to flow\n"); 24007e3a1670SKishore Padmanabha return rc; 24017e3a1670SKishore Padmanabha } 24027e3a1670SKishore Padmanabha fid_parms.direction = tbl->direction; 24037e3a1670SKishore Padmanabha fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_HW_FID; 2404aebe3cb7SKishore Padmanabha fid_parms.critical_resource = tbl->critical_resource; 24057e3a1670SKishore Padmanabha fid_parms.resource_type = mark_flag; 24067e3a1670SKishore Padmanabha fid_parms.resource_hndl = act_idx; 2407d9e70b1dSRandy Schacher ulp_flow_db_shared_session_set(&fid_parms, tbl->session_type); 240819994cc7SKishore Padmanabha 24090117293cSKishore Padmanabha rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 24100c036a14SPeter Spreadborough if (unlikely(rc)) 2411dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Fail to link res to flow rc = %d\n", rc); 24127e3a1670SKishore Padmanabha return rc; 24137e3a1670SKishore Padmanabha } 24147e3a1670SKishore Padmanabha 2415dcb8901bSKishore Padmanabha /* Tcam table scan the identifier list and allocate each identifier */ 2416dd0191d5SShuanglin Wang int32_t 2417dd0191d5SShuanglin Wang ulp_mapper_tcam_tbl_ident_alloc(struct bnxt_ulp_mapper_parms *parms, 2418dcb8901bSKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl) 2419dcb8901bSKishore Padmanabha { 2420dcb8901bSKishore Padmanabha struct bnxt_ulp_mapper_ident_info *idents; 2421dcb8901bSKishore Padmanabha uint32_t num_idents; 2422dcb8901bSKishore Padmanabha uint32_t i; 2423dcb8901bSKishore Padmanabha 2424a4638284SMike Baucom idents = ulp_mapper_ident_fields_get(parms, tbl, &num_idents); 2425dcb8901bSKishore Padmanabha for (i = 0; i < num_idents; i++) { 24260c036a14SPeter Spreadborough if (unlikely(ulp_mapper_ident_process(parms, tbl, 24270c036a14SPeter Spreadborough &idents[i], NULL))) 2428dcb8901bSKishore Padmanabha return -EINVAL; 2429dcb8901bSKishore Padmanabha } 2430dcb8901bSKishore Padmanabha return 0; 2431dcb8901bSKishore Padmanabha } 2432dcb8901bSKishore Padmanabha 2433dcb8901bSKishore Padmanabha /* 24343fe124d2SKishore Padmanabha * internal function to post process key/mask blobs for dynamic pad WC tcam tbl 24353fe124d2SKishore Padmanabha * 24363fe124d2SKishore Padmanabha * parms [in] The mappers parms with data related to the flow. 24373fe124d2SKishore Padmanabha * 24383fe124d2SKishore Padmanabha * key [in] The original key to be transformed 24393fe124d2SKishore Padmanabha * 24403fe124d2SKishore Padmanabha * mask [in] The original mask to be transformed 24413fe124d2SKishore Padmanabha * 24423fe124d2SKishore Padmanabha * tkey [in/out] The transformed key 24433fe124d2SKishore Padmanabha * 24443fe124d2SKishore Padmanabha * tmask [in/out] The transformed mask 24453fe124d2SKishore Padmanabha * 24463fe124d2SKishore Padmanabha * returns zero on success, non-zero on failure 24473fe124d2SKishore Padmanabha */ 2448dd0191d5SShuanglin Wang uint32_t 24493fe124d2SKishore Padmanabha ulp_mapper_wc_tcam_tbl_dyn_post_process(struct bnxt_ulp_device_params *dparms, 24503fe124d2SKishore Padmanabha struct ulp_blob *key, 24513fe124d2SKishore Padmanabha struct ulp_blob *mask, 24523fe124d2SKishore Padmanabha struct ulp_blob *tkey, 24533fe124d2SKishore Padmanabha struct ulp_blob *tmask) 24543fe124d2SKishore Padmanabha { 24553fe124d2SKishore Padmanabha uint16_t tlen, blen, clen, slice_width, num_slices, max_slices, offset; 24563fe124d2SKishore Padmanabha uint32_t cword, i, rc; 24573fe124d2SKishore Padmanabha int32_t pad; 24583fe124d2SKishore Padmanabha uint8_t *val; 24593fe124d2SKishore Padmanabha 24603fe124d2SKishore Padmanabha slice_width = dparms->wc_slice_width; 24613fe124d2SKishore Padmanabha clen = dparms->wc_ctl_size_bits; 24623fe124d2SKishore Padmanabha max_slices = dparms->wc_max_slices; 24633fe124d2SKishore Padmanabha blen = ulp_blob_data_len_get(key); 24643fe124d2SKishore Padmanabha 24653fe124d2SKishore Padmanabha /* Get the length of the key based on number of slices and width */ 24663fe124d2SKishore Padmanabha num_slices = 1; 24673fe124d2SKishore Padmanabha tlen = slice_width; 24683fe124d2SKishore Padmanabha while (tlen < blen && 24693fe124d2SKishore Padmanabha num_slices <= max_slices) { 24703fe124d2SKishore Padmanabha num_slices = num_slices << 1; 24713fe124d2SKishore Padmanabha tlen = tlen << 1; 24723fe124d2SKishore Padmanabha } 24733fe124d2SKishore Padmanabha 24740c036a14SPeter Spreadborough if (unlikely(num_slices > max_slices)) { 2475dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Key size (%d) too large for WC\n", blen); 24763fe124d2SKishore Padmanabha return -EINVAL; 24773fe124d2SKishore Padmanabha } 24783fe124d2SKishore Padmanabha 24793fe124d2SKishore Padmanabha /* The key/mask may not be on a natural slice boundary, pad it */ 24803fe124d2SKishore Padmanabha pad = tlen - blen; 24810c036a14SPeter Spreadborough if (unlikely(ulp_blob_pad_push(key, pad) < 0 || 24820c036a14SPeter Spreadborough ulp_blob_pad_push(mask, pad) < 0)) { 2483dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to pad key/mask\n"); 24843fe124d2SKishore Padmanabha return -EINVAL; 24853fe124d2SKishore Padmanabha } 24863fe124d2SKishore Padmanabha 24873fe124d2SKishore Padmanabha /* The new length accounts for the ctrl word length and num slices */ 24883fe124d2SKishore Padmanabha tlen = tlen + clen * num_slices; 24890c036a14SPeter Spreadborough if (unlikely(ulp_blob_init(tkey, tlen, key->byte_order) || 24900c036a14SPeter Spreadborough ulp_blob_init(tmask, tlen, mask->byte_order))) { 2491dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to post process wc tcam entry\n"); 24923fe124d2SKishore Padmanabha return -EINVAL; 24933fe124d2SKishore Padmanabha } 24943fe124d2SKishore Padmanabha 24953fe124d2SKishore Padmanabha /* Build the transformed key/mask */ 24963fe124d2SKishore Padmanabha cword = dparms->wc_mode_list[num_slices - 1]; 24973fe124d2SKishore Padmanabha cword = tfp_cpu_to_be_32(cword); 24983fe124d2SKishore Padmanabha offset = 0; 24993fe124d2SKishore Padmanabha for (i = 0; i < num_slices; i++) { 25003fe124d2SKishore Padmanabha val = ulp_blob_push_32(tkey, &cword, clen); 25010c036a14SPeter Spreadborough if (unlikely(!val)) { 2502dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Key ctrl word push failed\n"); 25033fe124d2SKishore Padmanabha return -EINVAL; 25043fe124d2SKishore Padmanabha } 25053fe124d2SKishore Padmanabha val = ulp_blob_push_32(tmask, &cword, clen); 25060c036a14SPeter Spreadborough if (unlikely(!val)) { 2507dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Mask ctrl word push failed\n"); 25083fe124d2SKishore Padmanabha return -EINVAL; 25093fe124d2SKishore Padmanabha } 25103fe124d2SKishore Padmanabha rc = ulp_blob_append(tkey, key, offset, slice_width); 25110c036a14SPeter Spreadborough if (unlikely(rc)) { 2512dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Key blob append failed\n"); 25133fe124d2SKishore Padmanabha return rc; 25143fe124d2SKishore Padmanabha } 25153fe124d2SKishore Padmanabha rc = ulp_blob_append(tmask, mask, offset, slice_width); 25160c036a14SPeter Spreadborough if (unlikely(rc)) { 2517dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Mask blob append failed\n"); 25183fe124d2SKishore Padmanabha return rc; 25193fe124d2SKishore Padmanabha } 25203fe124d2SKishore Padmanabha offset += slice_width; 25213fe124d2SKishore Padmanabha } 25223fe124d2SKishore Padmanabha 25233fe124d2SKishore Padmanabha /* The key/mask are byte reversed on every 4 byte chunk */ 25243fe124d2SKishore Padmanabha ulp_blob_perform_byte_reverse(tkey, 4); 25253fe124d2SKishore Padmanabha ulp_blob_perform_byte_reverse(tmask, 4); 25263fe124d2SKishore Padmanabha 25273fe124d2SKishore Padmanabha return 0; 25283fe124d2SKishore Padmanabha } 25293fe124d2SKishore Padmanabha 2530dd0191d5SShuanglin Wang /* Post process the key/mask blobs for wildcard tcam tbl */ 2531dd0191d5SShuanglin Wang void ulp_mapper_wc_tcam_tbl_post_process(struct ulp_blob *blob) 25327e604e7fSKishore Padmanabha { 25337e604e7fSKishore Padmanabha ulp_blob_perform_64B_word_swap(blob); 25347e604e7fSKishore Padmanabha ulp_blob_perform_64B_byte_swap(blob); 25357e604e7fSKishore Padmanabha } 25367e604e7fSKishore Padmanabha 2537f634204bSKishore Padmanabha static int32_t 25386d160d77SRandy Schacher ulp_mapper_gen_tbl_ref_cnt_process(struct bnxt_ulp_mapper_parms *parms, 25396d160d77SRandy Schacher struct bnxt_ulp_mapper_tbl_info *tbl, 25406d160d77SRandy Schacher struct ulp_mapper_gen_tbl_entry *entry) 25416d160d77SRandy Schacher { 25426d160d77SRandy Schacher int32_t rc = 0; 25436d160d77SRandy Schacher uint64_t val64; 25446d160d77SRandy Schacher 25456d160d77SRandy Schacher /* Allow the template to manage the reference count */ 25466d160d77SRandy Schacher switch (tbl->ref_cnt_opcode) { 25476d160d77SRandy Schacher case BNXT_ULP_REF_CNT_OPC_INC: 25486d160d77SRandy Schacher ULP_GEN_TBL_REF_CNT_INC(entry); 25496d160d77SRandy Schacher break; 25506d160d77SRandy Schacher case BNXT_ULP_REF_CNT_OPC_DEC: 25516d160d77SRandy Schacher /* writes never decrement the ref count */ 25526d160d77SRandy Schacher if (tbl->tbl_opcode == BNXT_ULP_GENERIC_TBL_OPC_WRITE) 25536d160d77SRandy Schacher return -EINVAL; 25546d160d77SRandy Schacher 25556d160d77SRandy Schacher ULP_GEN_TBL_REF_CNT_DEC(entry); 25566d160d77SRandy Schacher break; 25576d160d77SRandy Schacher case BNXT_ULP_REF_CNT_OPC_NOP: 25586d160d77SRandy Schacher /* Nothing to be done, generally used when 25596d160d77SRandy Schacher * template gets the ref_cnt to make a decision 25606d160d77SRandy Schacher */ 25616d160d77SRandy Schacher break; 25626d160d77SRandy Schacher case BNXT_ULP_REF_CNT_OPC_DEFAULT: 25636d160d77SRandy Schacher /* This is the default case and is backward 25646d160d77SRandy Schacher * compatible with older templates 25656d160d77SRandy Schacher */ 25666d160d77SRandy Schacher if (tbl->fdb_opcode != BNXT_ULP_FDB_OPC_NOP) 25676d160d77SRandy Schacher ULP_GEN_TBL_REF_CNT_INC(entry); 25686d160d77SRandy Schacher break; 25696d160d77SRandy Schacher default: 2570dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid REF_CNT_OPC %d\n", 25716d160d77SRandy Schacher tbl->ref_cnt_opcode); 25726d160d77SRandy Schacher return -EINVAL; 25736d160d77SRandy Schacher } 25746d160d77SRandy Schacher 25756d160d77SRandy Schacher if (tbl->tbl_opcode == BNXT_ULP_GENERIC_TBL_OPC_READ) { 25766d160d77SRandy Schacher /* Add ref_cnt to the regfile for template to use. */ 25776d160d77SRandy Schacher val64 = (uint32_t)ULP_GEN_TBL_REF_CNT(entry); 25786d160d77SRandy Schacher val64 = tfp_cpu_to_be_64(val64); 25796d160d77SRandy Schacher rc = ulp_regfile_write(parms->regfile, 25806d160d77SRandy Schacher BNXT_ULP_RF_IDX_REF_CNT, 25816d160d77SRandy Schacher val64); 25820c036a14SPeter Spreadborough if (unlikely(rc)) { 2583dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to write regfile[ref_cnt]\n"); 25846d160d77SRandy Schacher return rc; 25856d160d77SRandy Schacher } 25866d160d77SRandy Schacher } 25876d160d77SRandy Schacher 25886d160d77SRandy Schacher return rc; 25896d160d77SRandy Schacher } 25906d160d77SRandy Schacher 25916d160d77SRandy Schacher static int32_t 2592f634204bSKishore Padmanabha ulp_mapper_gen_tbl_process(struct bnxt_ulp_mapper_parms *parms, 2593f634204bSKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl) 2594f634204bSKishore Padmanabha { 25950001cc58SKishore Padmanabha struct ulp_mapper_gen_tbl_list *gen_tbl_list; 2596a2417601SKishore Padmanabha struct bnxt_ulp_mapper_key_info *kflds; 2597f634204bSKishore Padmanabha struct ulp_flow_db_res_params fid_parms; 2598aebe3cb7SKishore Padmanabha struct ulp_mapper_gen_tbl_entry gen_tbl_ent, *g; 25990001cc58SKishore Padmanabha struct ulp_gen_hash_entry_params hash_entry; 2600af50070eSKishore Padmanabha enum ulp_gen_list_search_flag list_srch = ULP_GEN_LIST_SEARCH_MISSED; 2601af50070eSKishore Padmanabha uint16_t keylen, datalen = 0; 2602aebe3cb7SKishore Padmanabha struct ulp_blob key, data; 2603f634204bSKishore Padmanabha uint8_t *cache_key; 2604f634204bSKishore Padmanabha int32_t tbl_idx; 2605af50070eSKishore Padmanabha uint32_t i, num_kflds = 0, key_index = 0, num_par_kflds = 0, pad = 0; 26060001cc58SKishore Padmanabha uint32_t gen_tbl_miss = 1, fdb_write = 0; 2607af50070eSKishore Padmanabha uint8_t *byte_data; 2608f634204bSKishore Padmanabha int32_t rc = 0; 2609f634204bSKishore Padmanabha 2610f634204bSKishore Padmanabha /* Get the key fields list and build the key. */ 2611f634204bSKishore Padmanabha kflds = ulp_mapper_key_fields_get(parms, tbl, &num_kflds); 26120c036a14SPeter Spreadborough if (unlikely(!kflds || !num_kflds)) { 2613dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get key fields\n"); 2614f634204bSKishore Padmanabha return -EINVAL; 2615f634204bSKishore Padmanabha } 26160001cc58SKishore Padmanabha 2617af50070eSKishore Padmanabha /* Get the partial key list number*/ 2618af50070eSKishore Padmanabha num_par_kflds = ulp_mapper_partial_key_fields_get(parms, tbl); 2619af50070eSKishore Padmanabha 2620af50070eSKishore Padmanabha if (num_par_kflds) 2621af50070eSKishore Padmanabha pad = ULP_BYTE_2_BITS(sizeof(uint8_t)) - 2622af50070eSKishore Padmanabha ULP_BITS_IS_BYTE_NOT_ALIGNED(tbl->key_bit_size); 2623af50070eSKishore Padmanabha 26240c036a14SPeter Spreadborough if (unlikely(ulp_blob_init(&key, tbl->key_bit_size + pad + 2625af50070eSKishore Padmanabha tbl->partial_key_bit_size, 26260c036a14SPeter Spreadborough parms->device_params->key_byte_order))) { 2627dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to alloc blob\n"); 2628f634204bSKishore Padmanabha return -EINVAL; 2629f634204bSKishore Padmanabha } 2630af50070eSKishore Padmanabha for (i = 0; i < num_kflds + num_par_kflds; i++) { 2631f634204bSKishore Padmanabha /* Setup the key */ 2632286569d5SKishore Padmanabha rc = ulp_mapper_field_opc_process(parms, tbl->direction, 2633a2417601SKishore Padmanabha &kflds[i].field_info_spec, 2634f634204bSKishore Padmanabha &key, 1, "Gen Tbl Key"); 26350c036a14SPeter Spreadborough if (unlikely(rc)) { 2636dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 2637f634204bSKishore Padmanabha "Failed to create key for Gen tbl rc=%d\n", 2638f634204bSKishore Padmanabha rc); 2639f634204bSKishore Padmanabha return -EINVAL; 2640f634204bSKishore Padmanabha } 2641af50070eSKishore Padmanabha /* pad for the alignment between exact key and partial key */ 2642af50070eSKishore Padmanabha if (num_par_kflds && i == num_kflds - 1) { 26430c036a14SPeter Spreadborough if (unlikely(ulp_blob_pad_push(&key, pad) < 0)) { 2644af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, "key padding failed\n"); 2645af50070eSKishore Padmanabha return -EINVAL; 2646af50070eSKishore Padmanabha } 2647af50070eSKishore Padmanabha } 2648f634204bSKishore Padmanabha } 2649f634204bSKishore Padmanabha 2650f634204bSKishore Padmanabha /* Calculate the table index for the generic table*/ 2651f634204bSKishore Padmanabha tbl_idx = ulp_mapper_gen_tbl_idx_calculate(tbl->resource_sub_type, 2652f634204bSKishore Padmanabha tbl->direction); 26530c036a14SPeter Spreadborough if (unlikely(tbl_idx < 0)) { 2654dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid table index %x:%x\n", 2655f634204bSKishore Padmanabha tbl->resource_sub_type, tbl->direction); 2656f634204bSKishore Padmanabha return -EINVAL; 2657f634204bSKishore Padmanabha } 2658f634204bSKishore Padmanabha 2659f634204bSKishore Padmanabha /* The_key is a byte array convert it to a search index */ 2660af50070eSKishore Padmanabha cache_key = ulp_blob_data_get(&key, &keylen); 26616d160d77SRandy Schacher 26620001cc58SKishore Padmanabha /* get the generic table */ 26630001cc58SKishore Padmanabha gen_tbl_list = &parms->mapper_data->gen_tbl_list[tbl_idx]; 26640001cc58SKishore Padmanabha 2665dd0191d5SShuanglin Wang /* perform basic validation of generic table */ 26660c036a14SPeter Spreadborough if (unlikely((gen_tbl_list->tbl_type == BNXT_ULP_GEN_TBL_TYPE_HASH_LIST && 2667dd0191d5SShuanglin Wang gen_tbl_list->hash_tbl == NULL) || 26680c036a14SPeter Spreadborough gen_tbl_list->mem_data == NULL)) { 2669dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Uninitialized gen table index %x:%x\n", 2670dd0191d5SShuanglin Wang tbl->resource_sub_type, tbl->direction); 2671dd0191d5SShuanglin Wang return -EINVAL; 2672dd0191d5SShuanglin Wang } 2673dd0191d5SShuanglin Wang 26740001cc58SKishore Padmanabha /* Check if generic hash table */ 2675dd0191d5SShuanglin Wang if (gen_tbl_list->tbl_type == BNXT_ULP_GEN_TBL_TYPE_HASH_LIST) { 26760c036a14SPeter Spreadborough if (unlikely(tbl->gen_tbl_lkup_type != 26770c036a14SPeter Spreadborough BNXT_ULP_GENERIC_TBL_LKUP_TYPE_HASH)) { 2678dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "%s: Invalid template lkup type\n", 26790001cc58SKishore Padmanabha gen_tbl_list->gen_tbl_name); 26800001cc58SKishore Padmanabha return -EINVAL; 26810001cc58SKishore Padmanabha } 26820001cc58SKishore Padmanabha hash_entry.key_data = cache_key; 2683af50070eSKishore Padmanabha hash_entry.key_length = ULP_BITS_2_BYTE(keylen); 26840001cc58SKishore Padmanabha rc = ulp_gen_hash_tbl_list_key_search(gen_tbl_list->hash_tbl, 26850001cc58SKishore Padmanabha &hash_entry); 26860c036a14SPeter Spreadborough if (unlikely(rc)) { 2687dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "%s: hash tbl search failed\n", 26880001cc58SKishore Padmanabha gen_tbl_list->gen_tbl_name); 26890001cc58SKishore Padmanabha return rc; 26900001cc58SKishore Padmanabha } 26910001cc58SKishore Padmanabha if (hash_entry.search_flag == ULP_GEN_HASH_SEARCH_FOUND) { 26920001cc58SKishore Padmanabha key_index = hash_entry.key_idx; 26930001cc58SKishore Padmanabha /* Get the generic table entry */ 26940c036a14SPeter Spreadborough if (unlikely(ulp_mapper_gen_tbl_entry_get(gen_tbl_list, 26950001cc58SKishore Padmanabha key_index, 26960c036a14SPeter Spreadborough &gen_tbl_ent))) 26970001cc58SKishore Padmanabha return -EINVAL; 26980001cc58SKishore Padmanabha /* store the hash index in the fdb */ 26990001cc58SKishore Padmanabha key_index = hash_entry.hash_index; 27000001cc58SKishore Padmanabha } 2701dd0191d5SShuanglin Wang } else if (gen_tbl_list->tbl_type == BNXT_ULP_GEN_TBL_TYPE_KEY_LIST) { 27020001cc58SKishore Padmanabha /* convert key to index directly */ 27030c036a14SPeter Spreadborough if (unlikely(ULP_BITS_2_BYTE(keylen) > (int32_t)sizeof(key_index))) { 2704dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "%s: keysize is bigger then 4 bytes\n", 270519994cc7SKishore Padmanabha gen_tbl_list->gen_tbl_name); 270619994cc7SKishore Padmanabha return -EINVAL; 270719994cc7SKishore Padmanabha } 2708af50070eSKishore Padmanabha memcpy(&key_index, cache_key, ULP_BITS_2_BYTE(keylen)); 27090001cc58SKishore Padmanabha /* Get the generic table entry */ 27100c036a14SPeter Spreadborough if (unlikely(ulp_mapper_gen_tbl_entry_get(gen_tbl_list, key_index, 27110c036a14SPeter Spreadborough &gen_tbl_ent))) 2712f634204bSKishore Padmanabha return -EINVAL; 2713af50070eSKishore Padmanabha } else if (gen_tbl_list->tbl_type == 2714af50070eSKishore Padmanabha BNXT_ULP_GEN_TBL_TYPE_SIMPLE_LIST) { 2715af50070eSKishore Padmanabha list_srch = ulp_gen_tbl_simple_list_search(gen_tbl_list, 2716af50070eSKishore Padmanabha cache_key, 2717af50070eSKishore Padmanabha &key_index); 2718af50070eSKishore Padmanabha /* Get the generic table entry */ 27190c036a14SPeter Spreadborough if (unlikely(ulp_mapper_gen_tbl_entry_get(gen_tbl_list, 2720af50070eSKishore Padmanabha key_index, 27210c036a14SPeter Spreadborough &gen_tbl_ent))) 2722dd0191d5SShuanglin Wang return -EINVAL; 2723f634204bSKishore Padmanabha } 2724dd0191d5SShuanglin Wang 2725f634204bSKishore Padmanabha switch (tbl->tbl_opcode) { 2726f634204bSKishore Padmanabha case BNXT_ULP_GENERIC_TBL_OPC_READ: 2727af50070eSKishore Padmanabha if (gen_tbl_list->tbl_type == BNXT_ULP_GEN_TBL_TYPE_HASH_LIST && 2728af50070eSKishore Padmanabha gen_tbl_list->hash_tbl) { 27290001cc58SKishore Padmanabha if (hash_entry.search_flag != ULP_GEN_HASH_SEARCH_FOUND) 27300001cc58SKishore Padmanabha break; /* nothing to be done , no entry */ 2731af50070eSKishore Padmanabha } else if (gen_tbl_list->tbl_type == 2732af50070eSKishore Padmanabha BNXT_ULP_GEN_TBL_TYPE_SIMPLE_LIST) { 2733af50070eSKishore Padmanabha if (list_srch == ULP_GEN_LIST_SEARCH_MISSED || 2734af50070eSKishore Padmanabha list_srch == ULP_GEN_LIST_SEARCH_FULL) 2735af50070eSKishore Padmanabha break; 27360001cc58SKishore Padmanabha } 27370001cc58SKishore Padmanabha 2738f634204bSKishore Padmanabha /* check the reference count */ 2739f634204bSKishore Padmanabha if (ULP_GEN_TBL_REF_CNT(&gen_tbl_ent)) { 2740aebe3cb7SKishore Padmanabha g = &gen_tbl_ent; 2741f634204bSKishore Padmanabha /* Scan ident list and create the result blob*/ 2742aebe3cb7SKishore Padmanabha rc = ulp_mapper_tbl_ident_scan_ext(parms, tbl, 2743aebe3cb7SKishore Padmanabha g->byte_data, 2744aebe3cb7SKishore Padmanabha g->byte_data_size, 2745aebe3cb7SKishore Padmanabha g->byte_order); 27460c036a14SPeter Spreadborough if (unlikely(rc)) { 2747dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 2748f634204bSKishore Padmanabha "Failed to scan ident list\n"); 2749f634204bSKishore Padmanabha return -EINVAL; 2750f634204bSKishore Padmanabha } 2751f634204bSKishore Padmanabha 2752f634204bSKishore Padmanabha /* it is a hit */ 27530001cc58SKishore Padmanabha gen_tbl_miss = 0; 2754f634204bSKishore Padmanabha fdb_write = 1; 2755f634204bSKishore Padmanabha } 2756f634204bSKishore Padmanabha break; 2757f634204bSKishore Padmanabha case BNXT_ULP_GENERIC_TBL_OPC_WRITE: 2758af50070eSKishore Padmanabha if (gen_tbl_list->tbl_type == BNXT_ULP_GEN_TBL_TYPE_HASH_LIST && 2759af50070eSKishore Padmanabha gen_tbl_list->hash_tbl) { 27600001cc58SKishore Padmanabha rc = ulp_mapper_gen_tbl_hash_entry_add(gen_tbl_list, 27610001cc58SKishore Padmanabha &hash_entry, 27620001cc58SKishore Padmanabha &gen_tbl_ent); 27630c036a14SPeter Spreadborough if (unlikely(rc)) 27640001cc58SKishore Padmanabha return rc; 27650001cc58SKishore Padmanabha /* store the hash index in the fdb */ 27660001cc58SKishore Padmanabha key_index = hash_entry.hash_index; 2767af50070eSKishore Padmanabha } else if (gen_tbl_list->tbl_type == 2768af50070eSKishore Padmanabha BNXT_ULP_GEN_TBL_TYPE_SIMPLE_LIST) { 27690c036a14SPeter Spreadborough if (unlikely(list_srch == ULP_GEN_LIST_SEARCH_FULL)) { 2770af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, "failed to add gen entry\n"); 2771af50070eSKishore Padmanabha return -ENOMEM; 2772af50070eSKishore Padmanabha } 27730001cc58SKishore Padmanabha } 27746d160d77SRandy Schacher 27756d160d77SRandy Schacher /* check the reference count and ignore ref_cnt if NOP. 27766d160d77SRandy Schacher * NOP allows a write as an update. 27776d160d77SRandy Schacher */ 27780c036a14SPeter Spreadborough if (unlikely(tbl->ref_cnt_opcode != BNXT_ULP_REF_CNT_OPC_NOP && 27790c036a14SPeter Spreadborough ULP_GEN_TBL_REF_CNT(&gen_tbl_ent))) { 2780f634204bSKishore Padmanabha /* a hit then error */ 2781dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "generic entry already present\n"); 2782f634204bSKishore Padmanabha return -EINVAL; /* success */ 2783f634204bSKishore Padmanabha } 2784f634204bSKishore Padmanabha 2785aebe3cb7SKishore Padmanabha /* Initialize the blob data */ 27860c036a14SPeter Spreadborough if (unlikely(ulp_blob_init(&data, tbl->result_bit_size, 27870c036a14SPeter Spreadborough gen_tbl_ent.byte_order))) { 2788dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed initial index table blob\n"); 2789aebe3cb7SKishore Padmanabha return -EINVAL; 2790aebe3cb7SKishore Padmanabha } 2791aebe3cb7SKishore Padmanabha 2792aebe3cb7SKishore Padmanabha /* Get the result fields list */ 2793aebe3cb7SKishore Padmanabha rc = ulp_mapper_tbl_result_build(parms, tbl, &data, 2794aebe3cb7SKishore Padmanabha "Gen tbl Result"); 27950c036a14SPeter Spreadborough if (unlikely(rc)) { 2796dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to build the result blob\n"); 2797aebe3cb7SKishore Padmanabha return rc; 2798aebe3cb7SKishore Padmanabha } 2799af50070eSKishore Padmanabha byte_data = ulp_blob_data_get(&data, &datalen); 2800af50070eSKishore Padmanabha rc = ulp_mapper_gen_tbl_entry_data_set(gen_tbl_list, 2801af50070eSKishore Padmanabha &gen_tbl_ent, 2802af50070eSKishore Padmanabha cache_key, 2803af50070eSKishore Padmanabha ULP_BITS_2_BYTE(keylen), 2804af50070eSKishore Padmanabha byte_data, 2805af50070eSKishore Padmanabha ULP_BITS_2_BYTE(datalen) 2806af50070eSKishore Padmanabha ); 28070c036a14SPeter Spreadborough if (unlikely(rc)) { 2808dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to write generic table\n"); 2809f634204bSKishore Padmanabha return -EINVAL; 2810f634204bSKishore Padmanabha } 2811f634204bSKishore Padmanabha 2812f634204bSKishore Padmanabha fdb_write = 1; 28130001cc58SKishore Padmanabha parms->shared_hndl = (uint64_t)tbl_idx << 32 | key_index; 2814f634204bSKishore Padmanabha break; 2815f634204bSKishore Padmanabha default: 2816dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid table opcode %x\n", tbl->tbl_opcode); 2817f634204bSKishore Padmanabha return -EINVAL; 2818f634204bSKishore Padmanabha } 2819f634204bSKishore Padmanabha 2820f634204bSKishore Padmanabha /* Set the generic entry hit */ 2821f634204bSKishore Padmanabha rc = ulp_regfile_write(parms->regfile, 28220001cc58SKishore Padmanabha BNXT_ULP_RF_IDX_GENERIC_TBL_MISS, 28230001cc58SKishore Padmanabha tfp_cpu_to_be_64(gen_tbl_miss)); 28240c036a14SPeter Spreadborough if (unlikely(rc)) { 2825dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Write regfile[%d] failed\n", 28260001cc58SKishore Padmanabha BNXT_ULP_RF_IDX_GENERIC_TBL_MISS); 2827f634204bSKishore Padmanabha return -EIO; 2828f634204bSKishore Padmanabha } 2829f634204bSKishore Padmanabha 2830f634204bSKishore Padmanabha /* add the entry to the flow database */ 2831f634204bSKishore Padmanabha if (fdb_write) { 2832f634204bSKishore Padmanabha memset(&fid_parms, 0, sizeof(fid_parms)); 2833f634204bSKishore Padmanabha fid_parms.direction = tbl->direction; 2834f634204bSKishore Padmanabha fid_parms.resource_func = tbl->resource_func; 2835f634204bSKishore Padmanabha fid_parms.resource_sub_type = tbl->resource_sub_type; 28360001cc58SKishore Padmanabha fid_parms.resource_hndl = key_index; 2837f634204bSKishore Padmanabha fid_parms.critical_resource = tbl->critical_resource; 2838d9e70b1dSRandy Schacher ulp_flow_db_shared_session_set(&fid_parms, tbl->session_type); 283919994cc7SKishore Padmanabha 28400117293cSKishore Padmanabha rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 28410c036a14SPeter Spreadborough if (unlikely(rc)) { 2842dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Fail to add gen ent flowdb %d\n", 2843dd0191d5SShuanglin Wang rc); 28446d160d77SRandy Schacher return rc; 2845f634204bSKishore Padmanabha } 28466d160d77SRandy Schacher 28476d160d77SRandy Schacher /* Reset the in-flight RID when generic table is written and the 28486d160d77SRandy Schacher * rid has been pushed into a handle (rid or fid). Once it has 28496d160d77SRandy Schacher * been written, we have persistent accounting of the resources. 28506d160d77SRandy Schacher */ 28516d160d77SRandy Schacher if (tbl->tbl_opcode == BNXT_ULP_GENERIC_TBL_OPC_WRITE && 28526d160d77SRandy Schacher (tbl->fdb_opcode == BNXT_ULP_FDB_OPC_PUSH_RID_REGFILE || 28536d160d77SRandy Schacher tbl->fdb_opcode == BNXT_ULP_FDB_OPC_PUSH_FID)) 28546d160d77SRandy Schacher parms->rid = 0; 28556d160d77SRandy Schacher 28566d160d77SRandy Schacher rc = ulp_mapper_gen_tbl_ref_cnt_process(parms, tbl, 28576d160d77SRandy Schacher &gen_tbl_ent); 28586d160d77SRandy Schacher } 28596d160d77SRandy Schacher 2860f634204bSKishore Padmanabha return rc; 2861f634204bSKishore Padmanabha } 2862f634204bSKishore Padmanabha 286355aeaac3SKishore Padmanabha static int32_t 2864255add67SKishore Padmanabha ulp_mapper_ctrl_tbl_process(struct bnxt_ulp_mapper_parms *parms, 2865255add67SKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl) 2866255add67SKishore Padmanabha { 2867255add67SKishore Padmanabha int32_t rc = 0; 28686d160d77SRandy Schacher uint64_t val64 = 0; 28696d160d77SRandy Schacher uint32_t rid; 2870255add67SKishore Padmanabha 2871255add67SKishore Padmanabha /* process the fdb opcode for alloc push */ 2872255add67SKishore Padmanabha if (tbl->fdb_opcode == BNXT_ULP_FDB_OPC_ALLOC_RID_REGFILE) { 2873255add67SKishore Padmanabha rc = ulp_mapper_fdb_opc_alloc_rid(parms, tbl); 28740c036a14SPeter Spreadborough if (unlikely(rc)) { 2875dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to do fdb alloc\n"); 2876255add67SKishore Padmanabha return rc; 2877255add67SKishore Padmanabha } 28786d160d77SRandy Schacher } else if (tbl->fdb_opcode == BNXT_ULP_FDB_OPC_DELETE_RID_REGFILE) { 28796d160d77SRandy Schacher rc = ulp_regfile_read(parms->regfile, tbl->fdb_operand, &val64); 28800c036a14SPeter Spreadborough if (unlikely(rc)) { 2881dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get RID from regfile\n"); 28826d160d77SRandy Schacher return rc; 2883255add67SKishore Padmanabha } 28846d160d77SRandy Schacher rid = (uint32_t)tfp_be_to_cpu_64(val64); 28856d160d77SRandy Schacher rc = ulp_mapper_resources_free(parms->ulp_ctx, 28866d160d77SRandy Schacher BNXT_ULP_FDB_TYPE_RID, 2887dd0191d5SShuanglin Wang rid, 2888dd0191d5SShuanglin Wang NULL); 28896d160d77SRandy Schacher } 28906d160d77SRandy Schacher 28916d160d77SRandy Schacher return rc; 28926d160d77SRandy Schacher } 28936d160d77SRandy Schacher 28946d160d77SRandy Schacher static int32_t 28956d160d77SRandy Schacher ulp_mapper_vnic_tbl_process(struct bnxt_ulp_mapper_parms *parms, 28966d160d77SRandy Schacher struct bnxt_ulp_mapper_tbl_info *tbl) 28976d160d77SRandy Schacher { 28986d160d77SRandy Schacher struct ulp_flow_db_res_params fid_parms; 28996d160d77SRandy Schacher uint16_t vnic_idx = 0, vnic_id = 0; 29006d160d77SRandy Schacher int32_t rc = 0; 29016d160d77SRandy Schacher 29026d160d77SRandy Schacher switch (tbl->resource_sub_type) { 29036d160d77SRandy Schacher case BNXT_ULP_RESOURCE_SUB_TYPE_VNIC_TABLE_RSS: 29040c036a14SPeter Spreadborough if (unlikely(tbl->tbl_opcode != BNXT_ULP_VNIC_TBL_OPC_ALLOC_WR_REGFILE)) { 2905dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid vnic table opcode\n"); 29066d160d77SRandy Schacher return -EINVAL; 29076d160d77SRandy Schacher } 29086d160d77SRandy Schacher rc = bnxt_pmd_rss_action_create(parms, &vnic_idx, &vnic_id); 29090c036a14SPeter Spreadborough if (unlikely(rc)) { 2910dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed create rss action\n"); 29116d160d77SRandy Schacher return rc; 29126d160d77SRandy Schacher } 29136d160d77SRandy Schacher break; 29146d160d77SRandy Schacher case BNXT_ULP_RESOURCE_SUB_TYPE_VNIC_TABLE_QUEUE: 29150c036a14SPeter Spreadborough if (unlikely(tbl->tbl_opcode != BNXT_ULP_VNIC_TBL_OPC_ALLOC_WR_REGFILE)) { 2916dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid vnic table opcode\n"); 29176d160d77SRandy Schacher return -EINVAL; 29186d160d77SRandy Schacher } 29196d160d77SRandy Schacher rc = bnxt_pmd_queue_action_create(parms, &vnic_idx, &vnic_id); 29200c036a14SPeter Spreadborough if (unlikely(rc)) { 2921dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed create queue action\n"); 29226d160d77SRandy Schacher return rc; 29236d160d77SRandy Schacher } 29246d160d77SRandy Schacher break; 29256d160d77SRandy Schacher default: 2926dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid vnic table sub type\n"); 29276d160d77SRandy Schacher return -EINVAL; 29286d160d77SRandy Schacher } 29296d160d77SRandy Schacher 29306d160d77SRandy Schacher /* Link the created vnic to the flow in the flow db */ 29316d160d77SRandy Schacher memset(&fid_parms, 0, sizeof(fid_parms)); 29326d160d77SRandy Schacher fid_parms.direction = tbl->direction; 29336d160d77SRandy Schacher fid_parms.resource_func = tbl->resource_func; 29346d160d77SRandy Schacher fid_parms.resource_type = tbl->resource_type; 29356d160d77SRandy Schacher fid_parms.resource_sub_type = tbl->resource_sub_type; 29366d160d77SRandy Schacher fid_parms.resource_hndl = vnic_idx; 29376d160d77SRandy Schacher fid_parms.critical_resource = tbl->critical_resource; 29386d160d77SRandy Schacher rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 29390c036a14SPeter Spreadborough if (unlikely(rc)) { 2940dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to link resource to flow rc = %d\n", 29416d160d77SRandy Schacher rc); 29426d160d77SRandy Schacher return rc; 29436d160d77SRandy Schacher } 29446d160d77SRandy Schacher rc = ulp_regfile_write(parms->regfile, tbl->tbl_operand, 29456d160d77SRandy Schacher (uint64_t)tfp_cpu_to_be_64(vnic_id)); 29460c036a14SPeter Spreadborough if (unlikely(rc)) 2947dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to write regfile[%d] rc=%d\n", 29486d160d77SRandy Schacher tbl->tbl_operand, rc); 29496d160d77SRandy Schacher 29506d160d77SRandy Schacher return rc; 29516d160d77SRandy Schacher } 29526d160d77SRandy Schacher 2953*0513f0afSPeter Spreadborough static int32_t 2954*0513f0afSPeter Spreadborough ulp_mapper_stats_cache_tbl_process(struct bnxt_ulp_mapper_parms *parms, 2955*0513f0afSPeter Spreadborough struct bnxt_ulp_mapper_tbl_info *tbl) 2956*0513f0afSPeter Spreadborough { 2957*0513f0afSPeter Spreadborough struct ulp_flow_db_res_params fid_parms; 2958*0513f0afSPeter Spreadborough uint64_t counter_handle; 2959*0513f0afSPeter Spreadborough struct ulp_blob data; 2960*0513f0afSPeter Spreadborough uint16_t data_len = 0; 2961*0513f0afSPeter Spreadborough uint8_t *tmp_data; 2962*0513f0afSPeter Spreadborough int32_t rc = 0; 2963*0513f0afSPeter Spreadborough 2964*0513f0afSPeter Spreadborough /* Initialize the blob data */ 2965*0513f0afSPeter Spreadborough if (unlikely(ulp_blob_init(&data, tbl->result_bit_size, 2966*0513f0afSPeter Spreadborough BNXT_ULP_BYTE_ORDER_BE))) { 2967*0513f0afSPeter Spreadborough BNXT_DRV_DBG(ERR, "Failed initial ulp_global table blob\n"); 2968*0513f0afSPeter Spreadborough return -EINVAL; 2969*0513f0afSPeter Spreadborough } 2970*0513f0afSPeter Spreadborough 2971*0513f0afSPeter Spreadborough /* read the arguments from the result table */ 2972*0513f0afSPeter Spreadborough rc = ulp_mapper_tbl_result_build(parms, tbl, &data, 2973*0513f0afSPeter Spreadborough "ULP Global Result"); 2974*0513f0afSPeter Spreadborough if (unlikely(rc)) { 2975*0513f0afSPeter Spreadborough BNXT_DRV_DBG(ERR, "Failed to build the result blob\n"); 2976*0513f0afSPeter Spreadborough return rc; 2977*0513f0afSPeter Spreadborough } 2978*0513f0afSPeter Spreadborough 2979*0513f0afSPeter Spreadborough tmp_data = ulp_blob_data_get(&data, &data_len); 2980*0513f0afSPeter Spreadborough counter_handle = *(uint64_t *)tmp_data; 2981*0513f0afSPeter Spreadborough counter_handle = tfp_be_to_cpu_64(counter_handle); 2982*0513f0afSPeter Spreadborough 2983*0513f0afSPeter Spreadborough memset(&fid_parms, 0, sizeof(fid_parms)); 2984*0513f0afSPeter Spreadborough fid_parms.direction = tbl->direction; 2985*0513f0afSPeter Spreadborough fid_parms.resource_func = tbl->resource_func; 2986*0513f0afSPeter Spreadborough fid_parms.resource_type = tbl->resource_type; 2987*0513f0afSPeter Spreadborough fid_parms.resource_sub_type = tbl->resource_sub_type; 2988*0513f0afSPeter Spreadborough fid_parms.resource_hndl = counter_handle; 2989*0513f0afSPeter Spreadborough fid_parms.critical_resource = tbl->critical_resource; 2990*0513f0afSPeter Spreadborough rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 2991*0513f0afSPeter Spreadborough if (unlikely(rc)) { 2992*0513f0afSPeter Spreadborough BNXT_DRV_DBG(ERR, "Failed to link resource to flow rc = %d\n", 2993*0513f0afSPeter Spreadborough rc); 2994*0513f0afSPeter Spreadborough return rc; 2995*0513f0afSPeter Spreadborough } 2996*0513f0afSPeter Spreadborough 2997*0513f0afSPeter Spreadborough rc = ulp_sc_mgr_entry_alloc(parms, counter_handle, tbl); 2998*0513f0afSPeter Spreadborough if (unlikely(rc)) { 2999*0513f0afSPeter Spreadborough BNXT_DRV_DBG(ERR, "Failed to link resource to flow rc = %d\n", 3000*0513f0afSPeter Spreadborough rc); 3001*0513f0afSPeter Spreadborough return rc; 3002*0513f0afSPeter Spreadborough } 3003*0513f0afSPeter Spreadborough #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 3004*0513f0afSPeter Spreadborough #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 3005*0513f0afSPeter Spreadborough BNXT_DRV_DBG(DEBUG, "flow id =0x%x\n", parms->flow_id); 3006*0513f0afSPeter Spreadborough #endif 3007*0513f0afSPeter Spreadborough #endif 3008*0513f0afSPeter Spreadborough return rc; 3009*0513f0afSPeter Spreadborough } 3010*0513f0afSPeter Spreadborough 3011*0513f0afSPeter Spreadborough static int32_t 3012*0513f0afSPeter Spreadborough ulp_mapper_stats_cache_tbl_res_free(struct bnxt_ulp_context *ulp, 3013*0513f0afSPeter Spreadborough uint32_t fid) 3014*0513f0afSPeter Spreadborough { 3015*0513f0afSPeter Spreadborough ulp_sc_mgr_entry_free(ulp, fid); 3016*0513f0afSPeter Spreadborough return 0; 3017*0513f0afSPeter Spreadborough } 3018*0513f0afSPeter Spreadborough 30196d160d77SRandy Schacher /* Free the vnic resource */ 30206d160d77SRandy Schacher static int32_t 30216d160d77SRandy Schacher ulp_mapper_vnic_tbl_res_free(struct bnxt_ulp_context *ulp __rte_unused, 3022dd0191d5SShuanglin Wang struct bnxt *bp, 30236d160d77SRandy Schacher struct ulp_flow_db_res_params *res) 30246d160d77SRandy Schacher { 30256d160d77SRandy Schacher uint16_t vnic_idx = res->resource_hndl; 30266d160d77SRandy Schacher 30276d160d77SRandy Schacher if (res->resource_sub_type == 30286d160d77SRandy Schacher BNXT_ULP_RESOURCE_SUB_TYPE_VNIC_TABLE_QUEUE) 3029dd0191d5SShuanglin Wang return bnxt_pmd_queue_action_delete(bp, vnic_idx); 30306d160d77SRandy Schacher else 3031dd0191d5SShuanglin Wang return bnxt_pmd_rss_action_delete(bp, vnic_idx); 30326d160d77SRandy Schacher } 30336d160d77SRandy Schacher 30346d160d77SRandy Schacher static int32_t 303594dbd6cfSKishore Padmanabha ulp_mapper_global_res_free(struct bnxt_ulp_context *ulp, 3036dd0191d5SShuanglin Wang struct bnxt *bp __rte_unused, 30376d160d77SRandy Schacher struct ulp_flow_db_res_params *res) 30386d160d77SRandy Schacher { 303994dbd6cfSKishore Padmanabha uint64_t handle = res->resource_hndl; 30406d160d77SRandy Schacher 304194dbd6cfSKishore Padmanabha return bnxt_pmd_global_tunnel_set(ulp, 0, res->resource_sub_type, 304294dbd6cfSKishore Padmanabha 0, &handle); 30436d160d77SRandy Schacher } 30446d160d77SRandy Schacher 30456d160d77SRandy Schacher static int32_t 30466d160d77SRandy Schacher ulp_mapper_global_register_tbl_process(struct bnxt_ulp_mapper_parms *parms, 30476d160d77SRandy Schacher struct bnxt_ulp_mapper_tbl_info *tbl) 30486d160d77SRandy Schacher { 30496d160d77SRandy Schacher struct ulp_flow_db_res_params fid_parms = { 0 }; 30506d160d77SRandy Schacher struct ulp_blob data; 30516d160d77SRandy Schacher uint16_t data_len = 0; 30526d160d77SRandy Schacher uint8_t *tmp_data; 30536d160d77SRandy Schacher uint16_t udp_port; 305494dbd6cfSKishore Padmanabha uint64_t handle; 30556d160d77SRandy Schacher int32_t rc = 0, write_reg = 0; 30566d160d77SRandy Schacher 30576d160d77SRandy Schacher /* Initialize the blob data */ 30580c036a14SPeter Spreadborough if (unlikely(ulp_blob_init(&data, tbl->result_bit_size, 30590c036a14SPeter Spreadborough BNXT_ULP_BYTE_ORDER_BE))) { 3060dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed initial ulp_global table blob\n"); 30616d160d77SRandy Schacher return -EINVAL; 30626d160d77SRandy Schacher } 30636d160d77SRandy Schacher 30646d160d77SRandy Schacher /* read the arguments from the result table */ 30656d160d77SRandy Schacher rc = ulp_mapper_tbl_result_build(parms, tbl, &data, 30666d160d77SRandy Schacher "ULP Global Result"); 30670c036a14SPeter Spreadborough if (unlikely(rc)) { 3068dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to build the result blob\n"); 30696d160d77SRandy Schacher return rc; 30706d160d77SRandy Schacher } 30716d160d77SRandy Schacher 30726d160d77SRandy Schacher switch (tbl->tbl_opcode) { 30736d160d77SRandy Schacher case BNXT_ULP_GLOBAL_REGISTER_TBL_OPC_WR_REGFILE: 30746d160d77SRandy Schacher write_reg = 1; 30756d160d77SRandy Schacher break; 30766d160d77SRandy Schacher case BNXT_ULP_GLOBAL_REGISTER_TBL_OPC_NOT_USED: 30776d160d77SRandy Schacher break; 30786d160d77SRandy Schacher default: 3079dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid global table opcode %d\n", 30806d160d77SRandy Schacher tbl->tbl_opcode); 30816d160d77SRandy Schacher return -EINVAL; 30826d160d77SRandy Schacher } 30836d160d77SRandy Schacher 308474cab005SRandy Schacher tmp_data = ulp_blob_data_get(&data, &data_len); 308574cab005SRandy Schacher udp_port = *((uint16_t *)tmp_data); 308674cab005SRandy Schacher udp_port = tfp_be_to_cpu_16(udp_port); 308774cab005SRandy Schacher 308894dbd6cfSKishore Padmanabha rc = bnxt_pmd_global_tunnel_set(parms->ulp_ctx, 308994dbd6cfSKishore Padmanabha parms->port_id, tbl->resource_sub_type, 309094dbd6cfSKishore Padmanabha udp_port, &handle); 30910c036a14SPeter Spreadborough if (unlikely(rc)) { 309294dbd6cfSKishore Padmanabha BNXT_DRV_DBG(ERR, "Unable to set Type %d port\n", 309394dbd6cfSKishore Padmanabha tbl->resource_sub_type); 309474cab005SRandy Schacher return rc; 309574cab005SRandy Schacher } 309674cab005SRandy Schacher 30976d160d77SRandy Schacher /* Set the common pieces of fid parms */ 30986d160d77SRandy Schacher fid_parms.direction = tbl->direction; 30996d160d77SRandy Schacher fid_parms.resource_func = tbl->resource_func; 31006d160d77SRandy Schacher fid_parms.resource_sub_type = tbl->resource_sub_type; 31016d160d77SRandy Schacher fid_parms.critical_resource = tbl->critical_resource; 31026d160d77SRandy Schacher fid_parms.resource_hndl = handle; 31036d160d77SRandy Schacher 31046d160d77SRandy Schacher rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 31056d160d77SRandy Schacher 31060c036a14SPeter Spreadborough if (unlikely(rc)) 31076d160d77SRandy Schacher return rc; 31086d160d77SRandy Schacher 31096d160d77SRandy Schacher /* write to the regfile if opcode is set */ 31106d160d77SRandy Schacher if (write_reg) { 31116d160d77SRandy Schacher rc = ulp_regfile_write(parms->regfile, 31126d160d77SRandy Schacher tbl->tbl_operand, 311394dbd6cfSKishore Padmanabha tfp_cpu_to_be_64(handle)); 31146d160d77SRandy Schacher if (rc) 3115dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Regfile[%d] write failed.\n", 31166d160d77SRandy Schacher tbl->tbl_operand); 31176d160d77SRandy Schacher } 31186d160d77SRandy Schacher 3119255add67SKishore Padmanabha return rc; 3120255add67SKishore Padmanabha } 3121255add67SKishore Padmanabha 3122255add67SKishore Padmanabha static int32_t 3123d097b460SKishore Padmanabha ulp_mapper_glb_resource_info_init(struct bnxt_ulp_context *ulp_ctx, 3124bfcaae8fSKishore Padmanabha struct bnxt_ulp_mapper_data *mapper_data) 3125bfcaae8fSKishore Padmanabha { 3126bfcaae8fSKishore Padmanabha struct bnxt_ulp_glb_resource_info *glb_res; 31272921498cSMike Baucom uint32_t num_entries = 0, idx, dev_id; 3128c6062ec0SMike Baucom uint8_t app_id; 3129bfcaae8fSKishore Padmanabha int32_t rc = 0; 3130bfcaae8fSKishore Padmanabha 31312921498cSMike Baucom glb_res = ulp_mapper_glb_resource_info_list_get(&num_entries); 31322921498cSMike Baucom /* Check if there are no resources */ 31332921498cSMike Baucom if (!num_entries) 31342921498cSMike Baucom return 0; 3135bfcaae8fSKishore Padmanabha 3136c6062ec0SMike Baucom rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id); 31370c036a14SPeter Spreadborough if (unlikely(rc)) { 3138dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get device id for glb init (%d)\n", 31396b70a956SMike Baucom rc); 3140c6062ec0SMike Baucom return rc; 3141c6062ec0SMike Baucom } 3142c6062ec0SMike Baucom 3143c6062ec0SMike Baucom rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id); 31440c036a14SPeter Spreadborough if (unlikely(rc)) { 3145dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get app id for glb init (%d)\n", 31466b70a956SMike Baucom rc); 3147c6062ec0SMike Baucom return rc; 3148c6062ec0SMike Baucom } 3149c6062ec0SMike Baucom 3150bfcaae8fSKishore Padmanabha /* Iterate the global resources and process each one */ 31512921498cSMike Baucom for (idx = 0; idx < num_entries; idx++) { 3152c6062ec0SMike Baucom if (dev_id != glb_res[idx].device_id || 3153c6062ec0SMike Baucom glb_res[idx].app_id != app_id) 3154c6062ec0SMike Baucom continue; 3155bfcaae8fSKishore Padmanabha switch (glb_res[idx].resource_func) { 3156bfcaae8fSKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER: 3157d097b460SKishore Padmanabha rc = ulp_mapper_resource_ident_allocate(ulp_ctx, 3158d097b460SKishore Padmanabha mapper_data, 3159d9e70b1dSRandy Schacher &glb_res[idx], 3160d9e70b1dSRandy Schacher false); 3161d097b460SKishore Padmanabha break; 3162d097b460SKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE: 3163d097b460SKishore Padmanabha rc = ulp_mapper_resource_index_tbl_alloc(ulp_ctx, 3164bfcaae8fSKishore Padmanabha mapper_data, 3165d9e70b1dSRandy Schacher &glb_res[idx], 3166d9e70b1dSRandy Schacher false); 3167bfcaae8fSKishore Padmanabha break; 3168bfcaae8fSKishore Padmanabha default: 3169dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Global resource %x not supported\n", 3170bfcaae8fSKishore Padmanabha glb_res[idx].resource_func); 3171d097b460SKishore Padmanabha rc = -EINVAL; 3172bfcaae8fSKishore Padmanabha break; 3173bfcaae8fSKishore Padmanabha } 3174d097b460SKishore Padmanabha if (rc) 3175d097b460SKishore Padmanabha return rc; 3176bfcaae8fSKishore Padmanabha } 3177bfcaae8fSKishore Padmanabha return rc; 3178bfcaae8fSKishore Padmanabha } 3179bfcaae8fSKishore Padmanabha 3180dd0191d5SShuanglin Wang /* 3181dd0191d5SShuanglin Wang * Iterate over the shared resources assigned during tf_open_session and store 3182dd0191d5SShuanglin Wang * them in the global regfile with the shared flag. 3183dd0191d5SShuanglin Wang */ 3184c6062ec0SMike Baucom static int32_t 3185c6062ec0SMike Baucom ulp_mapper_app_glb_resource_info_init(struct bnxt_ulp_context *ulp_ctx, 3186c6062ec0SMike Baucom struct bnxt_ulp_mapper_data *mapper_data) 3187c6062ec0SMike Baucom { 3188dd0191d5SShuanglin Wang const struct ulp_mapper_core_ops *op = mapper_data->mapper_oper; 3189c6062ec0SMike Baucom 3190dd0191d5SShuanglin Wang return op->ulp_mapper_core_app_glb_res_info_init(ulp_ctx, mapper_data); 3191c6062ec0SMike Baucom } 3192c6062ec0SMike Baucom 3193c6062ec0SMike Baucom /* 3194c5d06df4SMike Baucom * Common conditional opcode process routine that is used for both the template 3195c5d06df4SMike Baucom * rejection and table conditional execution. 3196c5d06df4SMike Baucom */ 3197c5d06df4SMike Baucom static int32_t 3198c5d06df4SMike Baucom ulp_mapper_cond_opc_process(struct bnxt_ulp_mapper_parms *parms, 3199c5d06df4SMike Baucom enum bnxt_ulp_cond_opc opc, 3200d9e70b1dSRandy Schacher uint64_t operand, 3201c5d06df4SMike Baucom int32_t *res) 3202c5d06df4SMike Baucom { 3203741172beSKishore Padmanabha enum bnxt_ulp_flow_mem_type mtype = BNXT_ULP_FLOW_MEM_TYPE_INT; 3204d9e70b1dSRandy Schacher uint32_t field_size = 0; 3205c5d06df4SMike Baucom int32_t rc = 0; 3206d9e70b1dSRandy Schacher uint8_t bit, tmp; 32070c036a14SPeter Spreadborough uint64_t regval = 0, result = 0; 3208c5d06df4SMike Baucom 3209c5d06df4SMike Baucom switch (opc) { 321059ae4961SKishore Padmanabha case BNXT_ULP_COND_OPC_CF_IS_SET: 3211c5d06df4SMike Baucom if (operand < BNXT_ULP_CF_IDX_LAST) { 3212d9e70b1dSRandy Schacher result = ULP_COMP_FLD_IDX_RD(parms, operand); 3213c5d06df4SMike Baucom } else { 3214dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3215d9e70b1dSRandy Schacher "comp field out of bounds %" PRIu64 "\n", 3216c5d06df4SMike Baucom operand); 3217c5d06df4SMike Baucom rc = -EINVAL; 3218c5d06df4SMike Baucom } 3219c5d06df4SMike Baucom break; 322059ae4961SKishore Padmanabha case BNXT_ULP_COND_OPC_CF_NOT_SET: 32210c036a14SPeter Spreadborough if (likely(operand < BNXT_ULP_CF_IDX_LAST)) { 3222d9e70b1dSRandy Schacher result = !ULP_COMP_FLD_IDX_RD(parms, operand); 3223c5d06df4SMike Baucom } else { 3224dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3225d9e70b1dSRandy Schacher "comp field out of bounds %" PRIu64 "\n", 3226c5d06df4SMike Baucom operand); 3227c5d06df4SMike Baucom rc = -EINVAL; 3228c5d06df4SMike Baucom } 3229c5d06df4SMike Baucom break; 323059ae4961SKishore Padmanabha case BNXT_ULP_COND_OPC_ACT_BIT_IS_SET: 32310c036a14SPeter Spreadborough if (likely(operand < BNXT_ULP_ACT_BIT_LAST)) { 3232d9e70b1dSRandy Schacher result = ULP_BITMAP_ISSET(parms->act_bitmap->bits, 3233c5d06df4SMike Baucom operand); 3234c5d06df4SMike Baucom } else { 3235dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3236d9e70b1dSRandy Schacher "action bit out of bounds %" PRIu64 "\n", 3237c5d06df4SMike Baucom operand); 3238c5d06df4SMike Baucom rc = -EINVAL; 3239c5d06df4SMike Baucom } 3240c5d06df4SMike Baucom break; 324159ae4961SKishore Padmanabha case BNXT_ULP_COND_OPC_ACT_BIT_NOT_SET: 32420c036a14SPeter Spreadborough if (likely(operand < BNXT_ULP_ACT_BIT_LAST)) { 3243d9e70b1dSRandy Schacher result = !ULP_BITMAP_ISSET(parms->act_bitmap->bits, 3244c5d06df4SMike Baucom operand); 3245c5d06df4SMike Baucom } else { 3246dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3247d9e70b1dSRandy Schacher "action bit out of bounds %" PRIu64 "\n", 3248c5d06df4SMike Baucom operand); 3249c5d06df4SMike Baucom rc = -EINVAL; 3250c5d06df4SMike Baucom } 3251c5d06df4SMike Baucom break; 3252c5d06df4SMike Baucom case BNXT_ULP_COND_OPC_HDR_BIT_IS_SET: 32530c036a14SPeter Spreadborough if (likely(operand < BNXT_ULP_HDR_BIT_LAST)) { 3254d9e70b1dSRandy Schacher result = ULP_BITMAP_ISSET(parms->hdr_bitmap->bits, 3255c5d06df4SMike Baucom operand); 3256c5d06df4SMike Baucom } else { 3257dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3258d9e70b1dSRandy Schacher "header bit out of bounds %" PRIu64 "\n", 3259c5d06df4SMike Baucom operand); 3260c5d06df4SMike Baucom rc = -EINVAL; 3261c5d06df4SMike Baucom } 3262c5d06df4SMike Baucom break; 3263c5d06df4SMike Baucom case BNXT_ULP_COND_OPC_HDR_BIT_NOT_SET: 32640c036a14SPeter Spreadborough if (likely(operand < BNXT_ULP_HDR_BIT_LAST)) { 3265d9e70b1dSRandy Schacher result = !ULP_BITMAP_ISSET(parms->hdr_bitmap->bits, 3266c5d06df4SMike Baucom operand); 3267c5d06df4SMike Baucom } else { 3268dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3269d9e70b1dSRandy Schacher "header bit out of bounds %" PRIu64 "\n", 3270c5d06df4SMike Baucom operand); 3271c5d06df4SMike Baucom rc = -EINVAL; 3272c5d06df4SMike Baucom } 3273c5d06df4SMike Baucom break; 3274c5d06df4SMike Baucom case BNXT_ULP_COND_OPC_FIELD_BIT_IS_SET: 3275a2417601SKishore Padmanabha rc = ulp_mapper_glb_field_tbl_get(parms, operand, &bit); 32760c036a14SPeter Spreadborough if (unlikely(rc)) { 3277dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3278d9e70b1dSRandy Schacher "invalid ulp_glb_field_tbl idx %" PRIu64 "\n", 3279a2417601SKishore Padmanabha operand); 3280c5d06df4SMike Baucom return -EINVAL; 3281c5d06df4SMike Baucom } 3282d9e70b1dSRandy Schacher result = ULP_INDEX_BITMAP_GET(parms->fld_bitmap->bits, bit); 3283c5d06df4SMike Baucom break; 3284c5d06df4SMike Baucom case BNXT_ULP_COND_OPC_FIELD_BIT_NOT_SET: 3285a2417601SKishore Padmanabha rc = ulp_mapper_glb_field_tbl_get(parms, operand, &bit); 32860c036a14SPeter Spreadborough if (unlikely(rc)) { 3287dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3288d9e70b1dSRandy Schacher "invalid ulp_glb_field_tbl idx %" PRIu64 "\n", 3289a2417601SKishore Padmanabha operand); 3290c5d06df4SMike Baucom return -EINVAL; 3291c5d06df4SMike Baucom } 3292d9e70b1dSRandy Schacher result = !ULP_INDEX_BITMAP_GET(parms->fld_bitmap->bits, bit); 3293c5d06df4SMike Baucom break; 329459ae4961SKishore Padmanabha case BNXT_ULP_COND_OPC_RF_IS_SET: 3295c569279aSShuanglin Wang if (ulp_regfile_read(parms->regfile, operand, ®val)) { 3296dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3297d9e70b1dSRandy Schacher "regfile[%" PRIu64 "] read oob\n", 3298d9e70b1dSRandy Schacher operand); 3299c5d06df4SMike Baucom return -EINVAL; 3300c5d06df4SMike Baucom } 3301d9e70b1dSRandy Schacher result = regval != 0; 3302c5d06df4SMike Baucom break; 330359ae4961SKishore Padmanabha case BNXT_ULP_COND_OPC_RF_NOT_SET: 33040c036a14SPeter Spreadborough if (unlikely(ulp_regfile_read(parms->regfile, operand, ®val))) { 3305dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3306d9e70b1dSRandy Schacher "regfile[%" PRIu64 "] read oob\n", operand); 3307c5d06df4SMike Baucom return -EINVAL; 3308c5d06df4SMike Baucom } 3309d9e70b1dSRandy Schacher result = regval == 0; 3310c5d06df4SMike Baucom break; 3311255add67SKishore Padmanabha case BNXT_ULP_COND_OPC_FLOW_PAT_MATCH: 3312d9e70b1dSRandy Schacher result = parms->flow_pattern_id == operand; 3313255add67SKishore Padmanabha break; 3314255add67SKishore Padmanabha case BNXT_ULP_COND_OPC_ACT_PAT_MATCH: 3315d9e70b1dSRandy Schacher result = parms->act_pattern_id == operand; 3316255add67SKishore Padmanabha break; 3317741172beSKishore Padmanabha case BNXT_ULP_COND_OPC_EXT_MEM_IS_SET: 33180c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_mem_type_get(parms->ulp_ctx, &mtype))) { 3319dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get the mem type\n"); 3320741172beSKishore Padmanabha return -EINVAL; 3321741172beSKishore Padmanabha } 3322d9e70b1dSRandy Schacher result = (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT) ? 0 : 1; 3323741172beSKishore Padmanabha break; 3324741172beSKishore Padmanabha case BNXT_ULP_COND_OPC_EXT_MEM_NOT_SET: 33250c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_mem_type_get(parms->ulp_ctx, &mtype))) { 3326dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get the mem type\n"); 3327741172beSKishore Padmanabha return -EINVAL; 3328741172beSKishore Padmanabha } 3329d9e70b1dSRandy Schacher result = (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT) ? 1 : 0; 3330741172beSKishore Padmanabha break; 3331f63aa27dSKishore Padmanabha case BNXT_ULP_COND_OPC_ENC_HDR_BIT_IS_SET: 33320c036a14SPeter Spreadborough if (likely(operand < BNXT_ULP_HDR_BIT_LAST)) { 3333d9e70b1dSRandy Schacher result = ULP_BITMAP_ISSET(parms->enc_hdr_bitmap->bits, 3334f63aa27dSKishore Padmanabha operand); 3335f63aa27dSKishore Padmanabha } else { 3336dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3337d9e70b1dSRandy Schacher "header bit out of bounds %" PRIu64 "\n", 3338f63aa27dSKishore Padmanabha operand); 3339f63aa27dSKishore Padmanabha rc = -EINVAL; 3340f63aa27dSKishore Padmanabha } 3341f63aa27dSKishore Padmanabha break; 3342f63aa27dSKishore Padmanabha case BNXT_ULP_COND_OPC_ENC_HDR_BIT_NOT_SET: 33430c036a14SPeter Spreadborough if (likely(operand < BNXT_ULP_HDR_BIT_LAST)) { 3344d9e70b1dSRandy Schacher result = !ULP_BITMAP_ISSET(parms->enc_hdr_bitmap->bits, 3345f63aa27dSKishore Padmanabha operand); 3346f63aa27dSKishore Padmanabha } else { 3347dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3348d9e70b1dSRandy Schacher "header bit out of bounds %" PRIu64 "\n", 3349f63aa27dSKishore Padmanabha operand); 3350f63aa27dSKishore Padmanabha rc = -EINVAL; 3351f63aa27dSKishore Padmanabha } 3352f63aa27dSKishore Padmanabha break; 3353d9e70b1dSRandy Schacher case BNXT_ULP_COND_OPC_ACT_PROP_IS_SET: 3354d9e70b1dSRandy Schacher case BNXT_ULP_COND_OPC_ACT_PROP_NOT_SET: 3355d9e70b1dSRandy Schacher /* only supporting 1-byte action properties for now */ 33560c036a14SPeter Spreadborough if (unlikely(operand >= BNXT_ULP_ACT_PROP_IDX_LAST)) { 3357dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3358d9e70b1dSRandy Schacher "act_prop[%" PRIu64 "] oob\n", operand); 3359d9e70b1dSRandy Schacher return -EINVAL; 3360d9e70b1dSRandy Schacher } 3361d9e70b1dSRandy Schacher field_size = ulp_mapper_act_prop_size_get(operand); 33620c036a14SPeter Spreadborough if (unlikely(sizeof(tmp) != field_size)) { 3363dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3364d9e70b1dSRandy Schacher "act_prop[%" PRIu64 "] field mismatch %u\n", 3365d9e70b1dSRandy Schacher operand, field_size); 3366d9e70b1dSRandy Schacher return -EINVAL; 3367d9e70b1dSRandy Schacher } 3368d9e70b1dSRandy Schacher tmp = parms->act_prop->act_details[operand]; 3369d9e70b1dSRandy Schacher if (opc == BNXT_ULP_COND_OPC_ACT_PROP_IS_SET) 3370d9e70b1dSRandy Schacher result = (int32_t)(tmp); 3371d9e70b1dSRandy Schacher else 3372d9e70b1dSRandy Schacher result = (int32_t)(!tmp); 3373d9e70b1dSRandy Schacher break; 3374dd0191d5SShuanglin Wang case BNXT_ULP_COND_OPC_CF_BIT_IS_SET: 3375dd0191d5SShuanglin Wang case BNXT_ULP_COND_OPC_CF_BIT_NOT_SET: 33760c036a14SPeter Spreadborough if (likely(operand < BNXT_ULP_CF_BIT_LAST)) { 3377dd0191d5SShuanglin Wang result = ULP_BITMAP_ISSET(parms->cf_bitmap, operand); 3378dd0191d5SShuanglin Wang } else { 3379dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3380dd0191d5SShuanglin Wang "CF bit out of bounds %" PRIx64 "\n", 3381dd0191d5SShuanglin Wang operand); 3382dd0191d5SShuanglin Wang rc = -EINVAL; 3383dd0191d5SShuanglin Wang } 3384dd0191d5SShuanglin Wang if (opc == BNXT_ULP_COND_OPC_CF_BIT_NOT_SET) 3385dd0191d5SShuanglin Wang result = !result; 3386dd0191d5SShuanglin Wang break; 3387dd0191d5SShuanglin Wang case BNXT_ULP_COND_OPC_WC_FIELD_BIT_IS_SET: 3388dd0191d5SShuanglin Wang case BNXT_ULP_COND_OPC_WC_FIELD_BIT_NOT_SET: 3389dd0191d5SShuanglin Wang rc = ulp_mapper_glb_field_tbl_get(parms, operand, &bit); 33900c036a14SPeter Spreadborough if (unlikely(rc)) { 3391dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3392dd0191d5SShuanglin Wang "invalid ulp_glb_field idx %" PRIu64 "\n", 3393dd0191d5SShuanglin Wang operand); 3394dd0191d5SShuanglin Wang return -EINVAL; 3395dd0191d5SShuanglin Wang } 3396dd0191d5SShuanglin Wang result = ULP_INDEX_BITMAP_GET(parms->wc_field_bitmap, bit); 3397dd0191d5SShuanglin Wang if (opc == BNXT_ULP_COND_OPC_WC_FIELD_BIT_NOT_SET) 3398dd0191d5SShuanglin Wang result = !result; 3399dd0191d5SShuanglin Wang break; 3400dd0191d5SShuanglin Wang case BNXT_ULP_COND_OPC_EXCLUDE_FIELD_BIT_IS_SET: 3401dd0191d5SShuanglin Wang case BNXT_ULP_COND_OPC_EXCLUDE_FIELD_BIT_NOT_SET: 3402dd0191d5SShuanglin Wang rc = ulp_mapper_glb_field_tbl_get(parms, operand, &bit); 34030c036a14SPeter Spreadborough if (unlikely(rc)) { 3404dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3405dd0191d5SShuanglin Wang "invalid ulp_glb_field idx %" PRIu64 "\n", 3406dd0191d5SShuanglin Wang operand); 3407dd0191d5SShuanglin Wang return -EINVAL; 3408dd0191d5SShuanglin Wang } 3409dd0191d5SShuanglin Wang result = ULP_INDEX_BITMAP_GET(parms->exclude_field_bitmap, bit); 3410dd0191d5SShuanglin Wang if (opc == BNXT_ULP_COND_OPC_EXCLUDE_FIELD_BIT_NOT_SET) 3411dd0191d5SShuanglin Wang result = !result; 3412dd0191d5SShuanglin Wang break; 341332bdbf44SKishore Padmanabha case BNXT_ULP_COND_OPC_FEATURE_BIT_IS_SET: 341432bdbf44SKishore Padmanabha case BNXT_ULP_COND_OPC_FEATURE_BIT_NOT_SET: 341532bdbf44SKishore Padmanabha regval = bnxt_ulp_feature_bits_get(parms->ulp_ctx); 341632bdbf44SKishore Padmanabha result = ULP_BITMAP_ISSET(regval, operand); 341732bdbf44SKishore Padmanabha if (opc == BNXT_ULP_COND_OPC_FEATURE_BIT_NOT_SET) 341832bdbf44SKishore Padmanabha result = !ULP_BITMAP_ISSET(regval, operand); 341932bdbf44SKishore Padmanabha break; 3420c5d06df4SMike Baucom default: 3421dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid conditional opcode %d\n", opc); 3422c5d06df4SMike Baucom rc = -EINVAL; 3423c5d06df4SMike Baucom break; 3424c5d06df4SMike Baucom } 3425d9e70b1dSRandy Schacher 3426d9e70b1dSRandy Schacher *res = !!result; 3427c5d06df4SMike Baucom return (rc); 3428c5d06df4SMike Baucom } 3429c5d06df4SMike Baucom 3430741172beSKishore Padmanabha static int32_t 34311993b267SShahaji Bhosle ulp_mapper_func_opr_compute(struct bnxt_ulp_mapper_parms *parms, 3432741172beSKishore Padmanabha enum tf_dir dir, 34331993b267SShahaji Bhosle enum bnxt_ulp_func_src func_src, 3434dd0191d5SShuanglin Wang uint64_t func_opr, 3435741172beSKishore Padmanabha uint64_t *result) 3436741172beSKishore Padmanabha { 3437741172beSKishore Padmanabha uint64_t regval; 3438c6062ec0SMike Baucom bool shared; 3439741172beSKishore Padmanabha 3440741172beSKishore Padmanabha *result = false; 34411993b267SShahaji Bhosle switch (func_src) { 34421993b267SShahaji Bhosle case BNXT_ULP_FUNC_SRC_COMP_FIELD: 34430c036a14SPeter Spreadborough if (unlikely(func_opr >= BNXT_ULP_CF_IDX_LAST)) { 3444dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "invalid index %u\n", 3445dd0191d5SShuanglin Wang (uint32_t)func_opr); 3446741172beSKishore Padmanabha return -EINVAL; 3447741172beSKishore Padmanabha } 34481993b267SShahaji Bhosle *result = ULP_COMP_FLD_IDX_RD(parms, func_opr); 3449741172beSKishore Padmanabha break; 34501993b267SShahaji Bhosle case BNXT_ULP_FUNC_SRC_REGFILE: 34510c036a14SPeter Spreadborough if (unlikely(ulp_regfile_read(parms->regfile, func_opr, ®val))) { 3452dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "regfile[%d] read oob\n", 3453dd0191d5SShuanglin Wang (uint32_t)func_opr); 3454741172beSKishore Padmanabha return -EINVAL; 3455741172beSKishore Padmanabha } 3456741172beSKishore Padmanabha *result = tfp_be_to_cpu_64(regval); 3457741172beSKishore Padmanabha break; 34581993b267SShahaji Bhosle case BNXT_ULP_FUNC_SRC_GLB_REGFILE: 34590c036a14SPeter Spreadborough if (unlikely(ulp_mapper_glb_resource_read(parms->mapper_data, dir, 34600c036a14SPeter Spreadborough func_opr, ®val, &shared))) { 3461dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "global regfile[%d] read failed.\n", 3462dd0191d5SShuanglin Wang (uint32_t)func_opr); 3463741172beSKishore Padmanabha return -EINVAL; 3464741172beSKishore Padmanabha } 3465741172beSKishore Padmanabha *result = tfp_be_to_cpu_64(regval); 3466741172beSKishore Padmanabha break; 34671993b267SShahaji Bhosle case BNXT_ULP_FUNC_SRC_CONST: 34681993b267SShahaji Bhosle *result = func_opr; 3469286569d5SKishore Padmanabha break; 3470dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_SRC_ACTION_BITMAP: 3471dd0191d5SShuanglin Wang *result = parms->act_bitmap->bits; 3472dd0191d5SShuanglin Wang break; 3473dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_SRC_HEADER_BITMAP: 3474dd0191d5SShuanglin Wang *result = parms->hdr_bitmap->bits; 3475dd0191d5SShuanglin Wang break; 3476741172beSKishore Padmanabha default: 3477dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "invalid src code %u\n", func_src); 3478741172beSKishore Padmanabha return -EINVAL; 3479741172beSKishore Padmanabha } 3480741172beSKishore Padmanabha return 0; 3481741172beSKishore Padmanabha } 3482741172beSKishore Padmanabha 3483741172beSKishore Padmanabha static int32_t 3484dd0191d5SShuanglin Wang ulp_mapper_vfr_mark_set(struct bnxt_ulp_mapper_parms *parms, 3485dd0191d5SShuanglin Wang uint32_t key, uint16_t port_id, 3486dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl) 3487dd0191d5SShuanglin Wang { 3488dd0191d5SShuanglin Wang struct ulp_flow_db_res_params fid_parms; 3489dd0191d5SShuanglin Wang uint32_t mark_flag; 3490dd0191d5SShuanglin Wang int32_t rc; 3491dd0191d5SShuanglin Wang 3492dd0191d5SShuanglin Wang /* Set the mark flag to local fid and vfr flag */ 3493dd0191d5SShuanglin Wang mark_flag = BNXT_ULP_MARK_LOCAL_HW_FID | BNXT_ULP_MARK_VFR_ID; 3494dd0191d5SShuanglin Wang 3495dd0191d5SShuanglin Wang rc = ulp_mark_db_mark_add(parms->ulp_ctx, mark_flag, 3496dd0191d5SShuanglin Wang key, port_id); 34970c036a14SPeter Spreadborough if (unlikely(rc)) { 3498dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to add mark to flow\n"); 3499dd0191d5SShuanglin Wang return rc; 3500dd0191d5SShuanglin Wang } 3501dd0191d5SShuanglin Wang fid_parms.direction = tbl->direction; 3502dd0191d5SShuanglin Wang fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_HW_FID; 3503dd0191d5SShuanglin Wang fid_parms.critical_resource = tbl->critical_resource; 3504dd0191d5SShuanglin Wang fid_parms.resource_type = mark_flag; 3505dd0191d5SShuanglin Wang fid_parms.resource_hndl = key; 3506dd0191d5SShuanglin Wang fid_parms.resource_sub_type = 0; 3507dd0191d5SShuanglin Wang ulp_flow_db_shared_session_set(&fid_parms, tbl->session_type); 3508dd0191d5SShuanglin Wang 3509dd0191d5SShuanglin Wang rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 3510dd0191d5SShuanglin Wang if (rc) { 3511dd0191d5SShuanglin Wang int32_t trc = 0; 3512dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Fail to link res to flow rc = %d\n", rc); 3513dd0191d5SShuanglin Wang trc = ulp_mark_db_mark_del(parms->ulp_ctx, mark_flag, key); 3514dd0191d5SShuanglin Wang if (trc) 3515dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3516dd0191d5SShuanglin Wang "Failed to cleanup mark rc = %d\n", rc); 3517dd0191d5SShuanglin Wang } 3518dd0191d5SShuanglin Wang return rc; 3519dd0191d5SShuanglin Wang } 3520dd0191d5SShuanglin Wang 3521dd0191d5SShuanglin Wang static int32_t 3522dd0191d5SShuanglin Wang ulp_mapper_bd_act_set(struct bnxt_ulp_mapper_parms *parms __rte_unused, 3523dd0191d5SShuanglin Wang uint16_t port_id, uint32_t action) 3524dd0191d5SShuanglin Wang { 3525dd0191d5SShuanglin Wang return bnxt_pmd_bd_act_set(port_id, action); 3526dd0191d5SShuanglin Wang } 3527dd0191d5SShuanglin Wang 352832bdbf44SKishore Padmanabha /* oper size is in bits and res size are in bytes */ 3529dd0191d5SShuanglin Wang static int32_t 3530af50070eSKishore Padmanabha ulp_mapper_func_cond_list_process(struct bnxt_ulp_mapper_parms *parms, 3531af50070eSKishore Padmanabha uint32_t idx, uint8_t dir, 353232bdbf44SKishore Padmanabha uint32_t oper_size, uint64_t *res, 353332bdbf44SKishore Padmanabha uint32_t res_size) 3534af50070eSKishore Padmanabha { 3535af50070eSKishore Padmanabha struct bnxt_ulp_mapper_field_info *fld; 3536af50070eSKishore Padmanabha uint8_t *val = NULL; 3537af50070eSKishore Padmanabha uint32_t val_len = 0; 3538af50070eSKishore Padmanabha uint64_t value = 0; 3539af50070eSKishore Padmanabha uint16_t ext_idx = 0; 354032bdbf44SKishore Padmanabha uint8_t *res_local = (uint8_t *)res; 3541af50070eSKishore Padmanabha 3542af50070eSKishore Padmanabha /* Get the field info from the key ext list */ 3543af50070eSKishore Padmanabha fld = ulp_mapper_tmpl_key_ext_list_get(parms, idx); 35440c036a14SPeter Spreadborough if (unlikely(fld == NULL || fld->field_opc != 35450c036a14SPeter Spreadborough BNXT_ULP_FIELD_OPC_TERNARY_LIST)) { 3546af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, "Invalid field idx %d\n", idx); 3547af50070eSKishore Padmanabha return -EINVAL; 3548af50070eSKishore Padmanabha } 3549af50070eSKishore Padmanabha 3550af50070eSKishore Padmanabha /* process the condition list */ 35510c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_src_process(parms, fld->field_src1, 3552af50070eSKishore Padmanabha fld->field_opr1, dir, 355332bdbf44SKishore Padmanabha 1, oper_size, &val, 35540c036a14SPeter Spreadborough &val_len, &value))) { 3555af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, "error processing func opcode %u\n", 3556af50070eSKishore Padmanabha idx); 3557af50070eSKishore Padmanabha return -EINVAL; 3558af50070eSKishore Padmanabha } 3559af50070eSKishore Padmanabha if (value) { 3560af50070eSKishore Padmanabha if (fld->field_src2 == BNXT_ULP_FIELD_SRC_NEXT) { 3561af50070eSKishore Padmanabha /* read the next key ext table index */ 35620c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(fld->field_opr2, 3563af50070eSKishore Padmanabha (uint8_t *)&ext_idx, 35640c036a14SPeter Spreadborough sizeof(uint16_t)))) { 3565af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, 3566af50070eSKishore Padmanabha "field idx operand read failed\n"); 3567af50070eSKishore Padmanabha return -EINVAL; 3568af50070eSKishore Padmanabha } 3569af50070eSKishore Padmanabha ext_idx = tfp_be_to_cpu_16(ext_idx); 3570af50070eSKishore Padmanabha return ulp_mapper_func_cond_list_process(parms, ext_idx, 357132bdbf44SKishore Padmanabha dir, oper_size, 357232bdbf44SKishore Padmanabha res, res_size); 3573af50070eSKishore Padmanabha } else { 3574af50070eSKishore Padmanabha /* get the value from then part */ 35750c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_src_process(parms, fld->field_src2, 3576af50070eSKishore Padmanabha fld->field_opr2, dir, 357732bdbf44SKishore Padmanabha 1, oper_size, 3578af50070eSKishore Padmanabha &val, &val_len, 35790c036a14SPeter Spreadborough &value))) { 3580af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, 3581af50070eSKishore Padmanabha "error processing func oper %u\n", 3582af50070eSKishore Padmanabha ext_idx); 3583af50070eSKishore Padmanabha return -EINVAL; 3584af50070eSKishore Padmanabha } 3585af50070eSKishore Padmanabha } 3586af50070eSKishore Padmanabha } else { 3587af50070eSKishore Padmanabha if (fld->field_src3 == BNXT_ULP_FIELD_SRC_NEXT) { 3588af50070eSKishore Padmanabha /* read the next key ext table index */ 35890c036a14SPeter Spreadborough if (unlikely(ulp_operand_read(fld->field_opr3, 3590af50070eSKishore Padmanabha (uint8_t *)&ext_idx, 35910c036a14SPeter Spreadborough sizeof(uint16_t)))) { 3592af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, 3593af50070eSKishore Padmanabha "field idx operand read failed\n"); 3594af50070eSKishore Padmanabha return -EINVAL; 3595af50070eSKishore Padmanabha } 3596af50070eSKishore Padmanabha ext_idx = tfp_be_to_cpu_16(ext_idx); 3597af50070eSKishore Padmanabha return ulp_mapper_func_cond_list_process(parms, ext_idx, 359832bdbf44SKishore Padmanabha dir, oper_size, 359932bdbf44SKishore Padmanabha res, res_size); 3600af50070eSKishore Padmanabha } else { 3601af50070eSKishore Padmanabha /* get the value from else part */ 36020c036a14SPeter Spreadborough if (unlikely(ulp_mapper_field_src_process(parms, fld->field_src3, 3603af50070eSKishore Padmanabha fld->field_opr3, dir, 360432bdbf44SKishore Padmanabha 1, oper_size, 3605af50070eSKishore Padmanabha &val, &val_len, 36060c036a14SPeter Spreadborough &value))) { 3607af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, 3608af50070eSKishore Padmanabha "error processing func oper %u\n", 3609af50070eSKishore Padmanabha ext_idx); 3610af50070eSKishore Padmanabha return -EINVAL; 3611af50070eSKishore Padmanabha } 3612af50070eSKishore Padmanabha } 3613af50070eSKishore Padmanabha } 3614af50070eSKishore Padmanabha /* write the value into result */ 361532bdbf44SKishore Padmanabha ulp_operand_read(val, res_local + res_size - 361632bdbf44SKishore Padmanabha ULP_BITS_2_BYTE_NR(oper_size), 361732bdbf44SKishore Padmanabha ULP_BITS_2_BYTE_NR(val_len)); 361832bdbf44SKishore Padmanabha 361932bdbf44SKishore Padmanabha /* convert the data to cpu format */ 362032bdbf44SKishore Padmanabha *res = tfp_be_to_cpu_64(*res); 3621af50070eSKishore Padmanabha return 0; 3622af50070eSKishore Padmanabha } 3623af50070eSKishore Padmanabha 3624af50070eSKishore Padmanabha static int32_t 36251993b267SShahaji Bhosle ulp_mapper_func_info_process(struct bnxt_ulp_mapper_parms *parms, 3626741172beSKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl) 3627741172beSKishore Padmanabha { 3628dd0191d5SShuanglin Wang const struct ulp_mapper_core_ops *op = parms->mapper_data->mapper_oper; 36291993b267SShahaji Bhosle struct bnxt_ulp_mapper_func_info *func_info = &tbl->func_info; 36301993b267SShahaji Bhosle uint64_t res = 0, res1 = 0, res2 = 0; 3631741172beSKishore Padmanabha int32_t rc = 0; 36321993b267SShahaji Bhosle uint32_t process_src1 = 0, process_src2 = 0; 3633741172beSKishore Padmanabha 36341993b267SShahaji Bhosle /* determine which functional operands to compute */ 36351993b267SShahaji Bhosle switch (func_info->func_opc) { 36361993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_NOP: 3637741172beSKishore Padmanabha return rc; 36381993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_EQ: 36391993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_NE: 36401993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_GE: 36411993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_GT: 36421993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_LE: 36431993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_LT: 3644dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_LEFT_SHIFT: 3645dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_RIGHT_SHIFT: 3646dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_BIT_OR: 3647dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_BIT_AND: 3648dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_BIT_XOR: 3649dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_LOG_OR: 3650dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_LOG_AND: 3651987f2ec9SManish Kurup case BNXT_ULP_FUNC_OPC_ADD: 3652987f2ec9SManish Kurup case BNXT_ULP_FUNC_OPC_SUB: 36531993b267SShahaji Bhosle process_src1 = 1; 36541993b267SShahaji Bhosle process_src2 = 1; 3655741172beSKishore Padmanabha break; 36561993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_COPY_SRC1_TO_RF: 36571993b267SShahaji Bhosle process_src1 = 1; 36581993b267SShahaji Bhosle break; 3659dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_HANDLE_TO_OFFSET: 3660dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_VFR_MARK_SET: 3661dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_BD_ACT_SET: 3662dd0191d5SShuanglin Wang process_src1 = 1; 3663dd0191d5SShuanglin Wang process_src2 = 1; 3664dd0191d5SShuanglin Wang break; 3665dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_NOT_NOT: 3666dd0191d5SShuanglin Wang process_src1 = 1; 3667af50070eSKishore Padmanabha case BNXT_ULP_FUNC_OPC_COND_LIST: 3668af50070eSKishore Padmanabha break; 3669d4b36fc5SKishore Padmanabha case BNXT_ULP_FUNC_OPC_PORT_TABLE: 3670d4b36fc5SKishore Padmanabha process_src1 = 1; 3671d4b36fc5SKishore Padmanabha process_src2 = 1; 3672d4b36fc5SKishore Padmanabha break; 36731993b267SShahaji Bhosle default: 36741993b267SShahaji Bhosle break; 36751993b267SShahaji Bhosle } 36761993b267SShahaji Bhosle 36771993b267SShahaji Bhosle if (process_src1) { 36781993b267SShahaji Bhosle rc = ulp_mapper_func_opr_compute(parms, tbl->direction, 36791993b267SShahaji Bhosle func_info->func_src1, 36801993b267SShahaji Bhosle func_info->func_opr1, &res1); 36811993b267SShahaji Bhosle if (rc) 36821993b267SShahaji Bhosle return rc; 36831993b267SShahaji Bhosle } 36841993b267SShahaji Bhosle 36851993b267SShahaji Bhosle if (process_src2) { 36861993b267SShahaji Bhosle rc = ulp_mapper_func_opr_compute(parms, tbl->direction, 36871993b267SShahaji Bhosle func_info->func_src2, 36881993b267SShahaji Bhosle func_info->func_opr2, &res2); 36891993b267SShahaji Bhosle if (rc) 36901993b267SShahaji Bhosle return rc; 36911993b267SShahaji Bhosle } 36921993b267SShahaji Bhosle 36931993b267SShahaji Bhosle /* perform the functional opcode operations */ 36941993b267SShahaji Bhosle switch (func_info->func_opc) { 36951993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_EQ: 3696741172beSKishore Padmanabha if (res1 == res2) 3697741172beSKishore Padmanabha res = 1; 3698741172beSKishore Padmanabha break; 36991993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_NE: 3700741172beSKishore Padmanabha if (res1 != res2) 3701741172beSKishore Padmanabha res = 1; 3702741172beSKishore Padmanabha break; 37031993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_GE: 3704741172beSKishore Padmanabha if (res1 >= res2) 3705741172beSKishore Padmanabha res = 1; 3706741172beSKishore Padmanabha break; 37071993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_GT: 3708741172beSKishore Padmanabha if (res1 > res2) 3709741172beSKishore Padmanabha res = 1; 3710741172beSKishore Padmanabha break; 37111993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_LE: 3712741172beSKishore Padmanabha if (res1 <= res2) 3713741172beSKishore Padmanabha res = 1; 3714741172beSKishore Padmanabha break; 37151993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_LT: 3716741172beSKishore Padmanabha if (res1 < res2) 3717741172beSKishore Padmanabha res = 1; 3718741172beSKishore Padmanabha break; 3719dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_LEFT_SHIFT: 3720dd0191d5SShuanglin Wang res = res1 << res2; 3721dd0191d5SShuanglin Wang break; 3722dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_RIGHT_SHIFT: 3723dd0191d5SShuanglin Wang res = res1 >> res2; 3724dd0191d5SShuanglin Wang break; 3725987f2ec9SManish Kurup case BNXT_ULP_FUNC_OPC_ADD: 3726987f2ec9SManish Kurup res = res1 + res2; 3727987f2ec9SManish Kurup break; 3728987f2ec9SManish Kurup case BNXT_ULP_FUNC_OPC_SUB: 3729987f2ec9SManish Kurup res = res1 - res2; 3730987f2ec9SManish Kurup break; 3731dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_NOT_NOT: 3732dd0191d5SShuanglin Wang res = !!res1; 3733dd0191d5SShuanglin Wang break; 3734dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_BIT_AND: 3735dd0191d5SShuanglin Wang res = res1 & res2; 3736dd0191d5SShuanglin Wang break; 3737dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_BIT_OR: 3738dd0191d5SShuanglin Wang res = res1 | res2; 3739dd0191d5SShuanglin Wang break; 3740dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_BIT_XOR: 3741dd0191d5SShuanglin Wang res = res1 ^ res2; 3742dd0191d5SShuanglin Wang break; 3743dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_LOG_AND: 3744dd0191d5SShuanglin Wang res = res1 && res2; 3745dd0191d5SShuanglin Wang break; 3746dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_LOG_OR: 3747dd0191d5SShuanglin Wang res = res1 || res2; 3748dd0191d5SShuanglin Wang break; 37491993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_COPY_SRC1_TO_RF: 37501993b267SShahaji Bhosle res = res1; 37511993b267SShahaji Bhosle break; 37521993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_RSS_CONFIG: 37531993b267SShahaji Bhosle /* apply the rss config using pmd method */ 37541993b267SShahaji Bhosle return bnxt_rss_config_action_apply(parms); 37551993b267SShahaji Bhosle case BNXT_ULP_FUNC_OPC_GET_PARENT_MAC_ADDR: 37561993b267SShahaji Bhosle rc = bnxt_pmd_get_parent_mac_addr(parms, (uint8_t *)&res); 37570c036a14SPeter Spreadborough if (unlikely(rc)) 37581993b267SShahaji Bhosle return -EINVAL; 37591993b267SShahaji Bhosle res = tfp_be_to_cpu_64(res); 37601993b267SShahaji Bhosle break; 3761dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_HANDLE_TO_OFFSET: 3762dd0191d5SShuanglin Wang rc = op->ulp_mapper_core_handle_to_offset(parms, res1, 3763dd0191d5SShuanglin Wang res2, &res); 3764dd0191d5SShuanglin Wang break; 3765dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_VFR_MARK_SET: 3766dd0191d5SShuanglin Wang /* res1 is key, res2 is portid */ 3767dd0191d5SShuanglin Wang return ulp_mapper_vfr_mark_set(parms, res1, res2, tbl); 3768dd0191d5SShuanglin Wang case BNXT_ULP_FUNC_OPC_BD_ACT_SET: 3769dd0191d5SShuanglin Wang /* res1 is port_id, res2 is action */ 3770dd0191d5SShuanglin Wang return ulp_mapper_bd_act_set(parms, res1, res2); 3771af50070eSKishore Padmanabha case BNXT_ULP_FUNC_OPC_COND_LIST: 37720c036a14SPeter Spreadborough if (unlikely(func_info->func_src1 != BNXT_ULP_FUNC_SRC_KEY_EXT_LIST)) { 3773af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, "invalid func source %u\n", 3774af50070eSKishore Padmanabha func_info->func_opc); 3775af50070eSKishore Padmanabha return -EINVAL; 3776af50070eSKishore Padmanabha } 3777af50070eSKishore Padmanabha if (ulp_mapper_func_cond_list_process(parms, 3778af50070eSKishore Padmanabha func_info->func_opr1, 3779af50070eSKishore Padmanabha tbl->direction, 378032bdbf44SKishore Padmanabha func_info->func_oper_size, 378132bdbf44SKishore Padmanabha &res, sizeof(res))) 3782af50070eSKishore Padmanabha return -EINVAL; 3783af50070eSKishore Padmanabha break; 3784d4b36fc5SKishore Padmanabha case BNXT_ULP_FUNC_OPC_PORT_TABLE: 3785d4b36fc5SKishore Padmanabha rc = ulp_mapper_field_port_db_write(parms, res1, 3786d4b36fc5SKishore Padmanabha func_info->func_dst_opr, 3787d4b36fc5SKishore Padmanabha (uint8_t *)&res2, 3788d4b36fc5SKishore Padmanabha func_info->func_oper_size); 3789d4b36fc5SKishore Padmanabha return rc; 37901993b267SShahaji Bhosle default: 3791dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "invalid func code %u\n", 3792dd0191d5SShuanglin Wang func_info->func_opc); 3793741172beSKishore Padmanabha return -EINVAL; 3794741172beSKishore Padmanabha } 37950c036a14SPeter Spreadborough if (unlikely(ulp_regfile_write(parms->regfile, func_info->func_dst_opr, 37960c036a14SPeter Spreadborough tfp_cpu_to_be_64(res)))) { 3797dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed write the func_opc %u\n", 37981993b267SShahaji Bhosle func_info->func_dst_opr); 3799741172beSKishore Padmanabha return -EINVAL; 3800741172beSKishore Padmanabha } 3801af50070eSKishore Padmanabha #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 3802af50070eSKishore Padmanabha #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 38034a925aa7SKishore Padmanabha BNXT_DRV_DBG(DEBUG, "write the %" PRIX64 " into func_opc %u\n", res, 3804af50070eSKishore Padmanabha func_info->func_dst_opr); 3805af50070eSKishore Padmanabha #endif 3806af50070eSKishore Padmanabha #endif 3807741172beSKishore Padmanabha 3808741172beSKishore Padmanabha return rc; 3809741172beSKishore Padmanabha } 3810741172beSKishore Padmanabha 3811c5d06df4SMike Baucom /* 3812c5d06df4SMike Baucom * Processes a list of conditions and returns both a status and result of the 3813c5d06df4SMike Baucom * list. The status must be checked prior to verifying the result. 3814c5d06df4SMike Baucom * 3815c5d06df4SMike Baucom * returns 0 for success, negative on failure 3816c5d06df4SMike Baucom * returns res = 1 for true, res = 0 for false. 3817c5d06df4SMike Baucom */ 3818c5d06df4SMike Baucom static int32_t 3819c5d06df4SMike Baucom ulp_mapper_cond_opc_list_process(struct bnxt_ulp_mapper_parms *parms, 3820dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_cond_list_info *info, 3821c5d06df4SMike Baucom int32_t *res) 3822c5d06df4SMike Baucom { 3823dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_cond_info *cond_list; 3824255add67SKishore Padmanabha int32_t rc = 0, trc = 0; 3825dd0191d5SShuanglin Wang uint32_t i; 3826c5d06df4SMike Baucom 3827dd0191d5SShuanglin Wang switch (info->cond_list_opcode) { 3828c5d06df4SMike Baucom case BNXT_ULP_COND_LIST_OPC_AND: 3829c5d06df4SMike Baucom /* AND Defaults to true. */ 3830c5d06df4SMike Baucom *res = 1; 3831c5d06df4SMike Baucom break; 3832c5d06df4SMike Baucom case BNXT_ULP_COND_LIST_OPC_OR: 3833c5d06df4SMike Baucom /* OR Defaults to false. */ 3834c5d06df4SMike Baucom *res = 0; 3835c5d06df4SMike Baucom break; 3836c5d06df4SMike Baucom case BNXT_ULP_COND_LIST_OPC_TRUE: 3837c5d06df4SMike Baucom *res = 1; 3838c5d06df4SMike Baucom return rc; 3839c5d06df4SMike Baucom case BNXT_ULP_COND_LIST_OPC_FALSE: 3840c5d06df4SMike Baucom *res = 0; 3841c5d06df4SMike Baucom return rc; 3842c5d06df4SMike Baucom default: 3843dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid conditional list opcode %d\n", 3844dd0191d5SShuanglin Wang info->cond_list_opcode); 3845741172beSKishore Padmanabha *res = 0; 3846c5d06df4SMike Baucom return -EINVAL; 3847c5d06df4SMike Baucom } 3848c5d06df4SMike Baucom 3849dd0191d5SShuanglin Wang cond_list = ulp_mapper_tmpl_cond_list_get(parms, info->cond_start_idx); 3850dd0191d5SShuanglin Wang for (i = 0; i < info->cond_nums; i++) { 3851c5d06df4SMike Baucom rc = ulp_mapper_cond_opc_process(parms, 3852dd0191d5SShuanglin Wang cond_list[i].cond_opcode, 3853dd0191d5SShuanglin Wang cond_list[i].cond_operand, 3854c5d06df4SMike Baucom &trc); 38550c036a14SPeter Spreadborough if (unlikely(rc)) 3856c5d06df4SMike Baucom return rc; 3857c5d06df4SMike Baucom 3858dd0191d5SShuanglin Wang if (info->cond_list_opcode == BNXT_ULP_COND_LIST_OPC_AND) { 3859c5d06df4SMike Baucom /* early return if result is ever zero */ 3860c5d06df4SMike Baucom if (!trc) { 3861c5d06df4SMike Baucom *res = trc; 3862c5d06df4SMike Baucom return rc; 3863c5d06df4SMike Baucom } 3864c5d06df4SMike Baucom } else { 3865c5d06df4SMike Baucom /* early return if result is ever non-zero */ 3866c5d06df4SMike Baucom if (trc) { 3867c5d06df4SMike Baucom *res = trc; 3868c5d06df4SMike Baucom return rc; 3869c5d06df4SMike Baucom } 3870c5d06df4SMike Baucom } 3871c5d06df4SMike Baucom } 3872c5d06df4SMike Baucom 3873c5d06df4SMike Baucom return rc; 3874c5d06df4SMike Baucom } 3875c5d06df4SMike Baucom 3876dd0191d5SShuanglin Wang static int32_t 3877dd0191d5SShuanglin Wang ulp_mapper_cond_reject_list_process(struct bnxt_ulp_mapper_parms *parms, 3878dd0191d5SShuanglin Wang uint32_t tid, int32_t *res) 3879dd0191d5SShuanglin Wang { 3880dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_cond_list_info *reject_info; 3881dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_cond_list_info *oper; 3882dd0191d5SShuanglin Wang int32_t cond_list_res = 0, cond_res = 0, rc = 0; 3883dd0191d5SShuanglin Wang uint32_t idx; 3884dd0191d5SShuanglin Wang 3885dd0191d5SShuanglin Wang /* set the rejection result to accept */ 3886dd0191d5SShuanglin Wang *res = 0; 3887dd0191d5SShuanglin Wang 3888dd0191d5SShuanglin Wang /* get the reject condition list */ 3889dd0191d5SShuanglin Wang reject_info = ulp_mapper_tmpl_reject_list_get(parms, tid); 3890dd0191d5SShuanglin Wang 3891f6e12015SKishore Padmanabha if (reject_info->cond_list_opcode == BNXT_ULP_COND_LIST_OPC_TRUE) { 3892f6e12015SKishore Padmanabha cond_list_res = 1; 3893f6e12015SKishore Padmanabha goto jump_exit; 3894f6e12015SKishore Padmanabha } 3895f6e12015SKishore Padmanabha 3896dd0191d5SShuanglin Wang /* If there are no reject conditions then skip */ 3897dd0191d5SShuanglin Wang if (!reject_info->cond_nums) 3898dd0191d5SShuanglin Wang return rc; 3899dd0191d5SShuanglin Wang 3900dd0191d5SShuanglin Wang /* Iterate the list to process the conditions */ 3901dd0191d5SShuanglin Wang if (reject_info->cond_list_opcode == BNXT_ULP_COND_LIST_OPC_LIST_AND || 3902dd0191d5SShuanglin Wang reject_info->cond_list_opcode == BNXT_ULP_COND_LIST_OPC_LIST_OR) { 3903dd0191d5SShuanglin Wang /* Initialize the cond result */ 3904dd0191d5SShuanglin Wang if (reject_info->cond_list_opcode == 3905dd0191d5SShuanglin Wang BNXT_ULP_COND_LIST_OPC_LIST_AND) 3906dd0191d5SShuanglin Wang cond_res = 1; 3907dd0191d5SShuanglin Wang 3908dd0191d5SShuanglin Wang for (idx = reject_info->cond_start_idx; 3909dd0191d5SShuanglin Wang idx < reject_info->cond_start_idx + 3910dd0191d5SShuanglin Wang reject_info->cond_nums; idx++) { 3911dd0191d5SShuanglin Wang oper = ulp_mapper_cond_oper_list_get(parms, idx); 39120c036a14SPeter Spreadborough if (unlikely(!oper)) { 3913dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3914dd0191d5SShuanglin Wang "Invalid cond oper idx %d\n", 3915dd0191d5SShuanglin Wang idx); 3916dd0191d5SShuanglin Wang return -EINVAL; 3917dd0191d5SShuanglin Wang } 3918dd0191d5SShuanglin Wang rc = ulp_mapper_cond_opc_list_process(parms, oper, 3919dd0191d5SShuanglin Wang &cond_list_res); 3920dd0191d5SShuanglin Wang /* if any error, then return */ 3921dd0191d5SShuanglin Wang if (rc) 3922dd0191d5SShuanglin Wang goto jump_exit; 3923dd0191d5SShuanglin Wang 3924dd0191d5SShuanglin Wang /* early return if result is ever zero */ 3925dd0191d5SShuanglin Wang if (cond_res /*and */ && !cond_list_res /*false*/) 3926dd0191d5SShuanglin Wang goto jump_exit; 3927dd0191d5SShuanglin Wang 3928dd0191d5SShuanglin Wang /* early return if result is ever non-zero */ 3929dd0191d5SShuanglin Wang if (!cond_res /*or */ && cond_list_res /*true*/) 3930dd0191d5SShuanglin Wang goto jump_exit; 3931dd0191d5SShuanglin Wang } 3932dd0191d5SShuanglin Wang } else { 3933dd0191d5SShuanglin Wang rc = ulp_mapper_cond_opc_list_process(parms, reject_info, 3934dd0191d5SShuanglin Wang &cond_list_res); 3935dd0191d5SShuanglin Wang } 3936dd0191d5SShuanglin Wang jump_exit: 3937dd0191d5SShuanglin Wang *res = cond_list_res; 3938dd0191d5SShuanglin Wang /* Reject the template if True */ 3939dd0191d5SShuanglin Wang if (cond_list_res) 3940dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "%s Template %d rejected.\n", 3941dd0191d5SShuanglin Wang ulp_mapper_tmpl_name_str(parms->tmpl_type), tid); 3942dd0191d5SShuanglin Wang return rc; 3943dd0191d5SShuanglin Wang } 3944dd0191d5SShuanglin Wang 3945dd0191d5SShuanglin Wang static int32_t 3946dd0191d5SShuanglin Wang ulp_mapper_cond_execute_list_process(struct bnxt_ulp_mapper_parms *parms, 3947dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl, 3948dd0191d5SShuanglin Wang int32_t *res) 3949dd0191d5SShuanglin Wang { 3950dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_cond_list_info *execute_info; 3951dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_cond_list_info *oper; 3952dd0191d5SShuanglin Wang int32_t cond_list_res = 0, cond_res = 0, rc = 0; 3953dd0191d5SShuanglin Wang uint32_t idx; 3954dd0191d5SShuanglin Wang 3955dd0191d5SShuanglin Wang /* set the execute result to true */ 3956dd0191d5SShuanglin Wang *res = 1; 3957dd0191d5SShuanglin Wang execute_info = &tbl->execute_info; 3958dd0191d5SShuanglin Wang 3959dd0191d5SShuanglin Wang /* If there are no execute conditions then skip */ 3960dd0191d5SShuanglin Wang if (!execute_info->cond_nums) 3961dd0191d5SShuanglin Wang return rc; 3962dd0191d5SShuanglin Wang 3963dd0191d5SShuanglin Wang /* Iterate the list to process the conditions */ 3964dd0191d5SShuanglin Wang if (execute_info->cond_list_opcode == BNXT_ULP_COND_LIST_OPC_LIST_AND || 3965dd0191d5SShuanglin Wang execute_info->cond_list_opcode == BNXT_ULP_COND_LIST_OPC_LIST_OR) { 3966dd0191d5SShuanglin Wang /* Initialize the cond result */ 3967dd0191d5SShuanglin Wang if (execute_info->cond_list_opcode == 3968dd0191d5SShuanglin Wang BNXT_ULP_COND_LIST_OPC_LIST_AND) 3969dd0191d5SShuanglin Wang cond_res = 1; 3970dd0191d5SShuanglin Wang 3971dd0191d5SShuanglin Wang for (idx = execute_info->cond_start_idx; 3972dd0191d5SShuanglin Wang idx < execute_info->cond_start_idx + 3973dd0191d5SShuanglin Wang execute_info->cond_nums; idx++) { 3974dd0191d5SShuanglin Wang oper = ulp_mapper_cond_oper_list_get(parms, idx); 39750c036a14SPeter Spreadborough if (unlikely(!oper)) { 3976dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 3977dd0191d5SShuanglin Wang "Invalid cond oper idx %d\n", 3978dd0191d5SShuanglin Wang idx); 3979dd0191d5SShuanglin Wang return -EINVAL; 3980dd0191d5SShuanglin Wang } 3981dd0191d5SShuanglin Wang rc = ulp_mapper_cond_opc_list_process(parms, oper, 3982dd0191d5SShuanglin Wang &cond_list_res); 3983dd0191d5SShuanglin Wang /* if any error, then return */ 3984dd0191d5SShuanglin Wang if (rc) 3985dd0191d5SShuanglin Wang goto jump_exit; 3986dd0191d5SShuanglin Wang 3987dd0191d5SShuanglin Wang /* early return if result is ever zero */ 3988dd0191d5SShuanglin Wang if (cond_res /*and */ && !cond_list_res /*false*/) 3989dd0191d5SShuanglin Wang goto jump_exit; 3990dd0191d5SShuanglin Wang 3991dd0191d5SShuanglin Wang /* early return if result is ever non-zero */ 3992dd0191d5SShuanglin Wang if (!cond_res /*or */ && cond_list_res /*true*/) 3993dd0191d5SShuanglin Wang goto jump_exit; 3994dd0191d5SShuanglin Wang } 3995dd0191d5SShuanglin Wang } else { 3996dd0191d5SShuanglin Wang rc = ulp_mapper_cond_opc_list_process(parms, execute_info, 3997dd0191d5SShuanglin Wang &cond_list_res); 3998dd0191d5SShuanglin Wang } 3999dd0191d5SShuanglin Wang jump_exit: 4000dd0191d5SShuanglin Wang *res = cond_list_res; 4001dd0191d5SShuanglin Wang return rc; 4002dd0191d5SShuanglin Wang } 4003dd0191d5SShuanglin Wang 4004a2417601SKishore Padmanabha /* 4005a2417601SKishore Padmanabha * Processes conflict resolution and returns both a status and result. 4006a2417601SKishore Padmanabha * The status must be checked prior to verifying the result. 4007a2417601SKishore Padmanabha * 4008a2417601SKishore Padmanabha * returns 0 for success, negative on failure 4009a2417601SKishore Padmanabha * returns res = 1 for true, res = 0 for false. 4010a2417601SKishore Padmanabha */ 4011a2417601SKishore Padmanabha static int32_t 4012a2417601SKishore Padmanabha ulp_mapper_conflict_resolution_process(struct bnxt_ulp_mapper_parms *parms, 4013a2417601SKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl, 4014a2417601SKishore Padmanabha int32_t *res) 4015a2417601SKishore Padmanabha { 4016a2417601SKishore Padmanabha int32_t rc = 0; 40170c036a14SPeter Spreadborough uint64_t regval = 0; 40181993b267SShahaji Bhosle uint64_t comp_sig; 4019a2417601SKishore Padmanabha 4020a2417601SKishore Padmanabha *res = 0; 4021a2417601SKishore Padmanabha switch (tbl->accept_opcode) { 4022a2417601SKishore Padmanabha case BNXT_ULP_ACCEPT_OPC_ALWAYS: 4023a2417601SKishore Padmanabha *res = 1; 4024a2417601SKishore Padmanabha break; 4025a2417601SKishore Padmanabha case BNXT_ULP_ACCEPT_OPC_FLOW_SIG_ID_MATCH: 4026a2417601SKishore Padmanabha /* perform the signature validation*/ 4027a2417601SKishore Padmanabha if (tbl->resource_func == 4028a2417601SKishore Padmanabha BNXT_ULP_RESOURCE_FUNC_GENERIC_TABLE) { 4029a2417601SKishore Padmanabha /* Perform the check that generic table is hit or not */ 40300c036a14SPeter Spreadborough if (unlikely(ulp_regfile_read(parms->regfile, 40310001cc58SKishore Padmanabha BNXT_ULP_RF_IDX_GENERIC_TBL_MISS, 40320c036a14SPeter Spreadborough ®val))) { 4033dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "regfile[%d] read oob\n", 40340001cc58SKishore Padmanabha BNXT_ULP_RF_IDX_GENERIC_TBL_MISS); 4035a2417601SKishore Padmanabha return -EINVAL; 4036a2417601SKishore Padmanabha } 40370001cc58SKishore Padmanabha if (regval) { 4038a2417601SKishore Padmanabha /* not a hit so no need to check flow sign*/ 4039a2417601SKishore Padmanabha *res = 1; 4040a2417601SKishore Padmanabha return rc; 4041a2417601SKishore Padmanabha } 4042a2417601SKishore Padmanabha } 4043a2417601SKishore Padmanabha /* compare the new flow signature against stored one */ 40440c036a14SPeter Spreadborough if (unlikely(ulp_regfile_read(parms->regfile, 4045a2417601SKishore Padmanabha BNXT_ULP_RF_IDX_FLOW_SIG_ID, 40460c036a14SPeter Spreadborough ®val))) { 4047dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "regfile[%d] read oob\n", 4048a2417601SKishore Padmanabha BNXT_ULP_RF_IDX_FLOW_SIG_ID); 4049a2417601SKishore Padmanabha return -EINVAL; 4050a2417601SKishore Padmanabha } 40511993b267SShahaji Bhosle comp_sig = ULP_COMP_FLD_IDX_RD(parms, 4052a2417601SKishore Padmanabha BNXT_ULP_CF_IDX_FLOW_SIG_ID); 4053a2417601SKishore Padmanabha regval = tfp_be_to_cpu_64(regval); 40540c036a14SPeter Spreadborough if (likely(comp_sig == regval)) 4055a2417601SKishore Padmanabha *res = 1; 4056a2417601SKishore Padmanabha else 4057dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "failed signature match 0x%016" 40581993b267SShahaji Bhosle PRIX64 ":%x\n", comp_sig, (uint32_t)regval); 4059a2417601SKishore Padmanabha break; 4060a2417601SKishore Padmanabha default: 4061dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid accept opcode %d\n", 4062a2417601SKishore Padmanabha tbl->accept_opcode); 4063a2417601SKishore Padmanabha return -EINVAL; 4064a2417601SKishore Padmanabha } 4065a2417601SKishore Padmanabha return rc; 4066a2417601SKishore Padmanabha } 4067a2417601SKishore Padmanabha 40688f153057SMike Baucom static int32_t 406983f916bdSKishore Padmanabha ulp_mapper_allocator_tbl_process(struct bnxt_ulp_mapper_parms *parms, 407083f916bdSKishore Padmanabha struct bnxt_ulp_mapper_tbl_info *tbl) 407183f916bdSKishore Padmanabha { 407283f916bdSKishore Padmanabha struct ulp_flow_db_res_params fid_parms; 407383f916bdSKishore Padmanabha int32_t alloc_index, rc = 0; 407483f916bdSKishore Padmanabha uint64_t regval = 0; 407583f916bdSKishore Padmanabha 407683f916bdSKishore Padmanabha /* Only Alloc opcode is supported for now */ 407783f916bdSKishore Padmanabha if (tbl->tbl_opcode != BNXT_ULP_ALLOC_TBL_OPC_ALLOC) 407883f916bdSKishore Padmanabha return 0; /* nothing to done */ 407983f916bdSKishore Padmanabha 408083f916bdSKishore Padmanabha /* allocate the index from the allocator */ 408183f916bdSKishore Padmanabha rc = ulp_allocator_tbl_list_alloc(parms->mapper_data, 408283f916bdSKishore Padmanabha tbl->resource_sub_type, 408383f916bdSKishore Padmanabha tbl->direction, &alloc_index); 40840c036a14SPeter Spreadborough if (unlikely(rc)) { 408583f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "unable to alloc index %x:%x\n", 408683f916bdSKishore Padmanabha tbl->resource_sub_type, tbl->direction); 408783f916bdSKishore Padmanabha return -EINVAL; 408883f916bdSKishore Padmanabha } 408983f916bdSKishore Padmanabha 409083f916bdSKishore Padmanabha /* Write to the regfile */ 409183f916bdSKishore Padmanabha regval = rte_cpu_to_be_64(alloc_index); 409283f916bdSKishore Padmanabha rc = ulp_regfile_write(parms->regfile, tbl->tbl_operand, regval); 40930c036a14SPeter Spreadborough if (unlikely(rc)) { 409483f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "Failed to write regfile[%d] rc=%d\n", 409583f916bdSKishore Padmanabha tbl->tbl_operand, rc); 409683f916bdSKishore Padmanabha return -EINVAL; 409783f916bdSKishore Padmanabha } 409883f916bdSKishore Padmanabha 409983f916bdSKishore Padmanabha /* update the flow database */ 410083f916bdSKishore Padmanabha memset(&fid_parms, 0, sizeof(fid_parms)); 410183f916bdSKishore Padmanabha fid_parms.direction = tbl->direction; 410283f916bdSKishore Padmanabha fid_parms.resource_func = tbl->resource_func; 410383f916bdSKishore Padmanabha fid_parms.resource_type = tbl->resource_type; 410483f916bdSKishore Padmanabha fid_parms.resource_sub_type = tbl->resource_sub_type; 410583f916bdSKishore Padmanabha fid_parms.resource_hndl = alloc_index; 410683f916bdSKishore Padmanabha fid_parms.critical_resource = tbl->critical_resource; 410783f916bdSKishore Padmanabha 410883f916bdSKishore Padmanabha rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 41090c036a14SPeter Spreadborough if (unlikely(rc)) { 411083f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "Failed to link resource to flow rc = %d\n", 411183f916bdSKishore Padmanabha rc); 411283f916bdSKishore Padmanabha goto error; 411383f916bdSKishore Padmanabha } 411483f916bdSKishore Padmanabha return rc; 411583f916bdSKishore Padmanabha error: 411683f916bdSKishore Padmanabha /* Free the allocated index */ 411783f916bdSKishore Padmanabha (void)ulp_allocator_tbl_list_free(parms->mapper_data, 411883f916bdSKishore Padmanabha tbl->resource_sub_type, 411983f916bdSKishore Padmanabha tbl->direction, alloc_index); 412083f916bdSKishore Padmanabha return rc; 412183f916bdSKishore Padmanabha } 412283f916bdSKishore Padmanabha 412383f916bdSKishore Padmanabha static int32_t 4124dd0191d5SShuanglin Wang ulp_mapper_tbls_process(struct bnxt_ulp_mapper_parms *parms, void *error) 4125696843ccSMike Baucom { 41260c9fe336SMike Baucom struct bnxt_ulp_mapper_tbl_info *tbls; 4127c5d06df4SMike Baucom struct bnxt_ulp_mapper_tbl_info *tbl; 4128dd0191d5SShuanglin Wang uint32_t num_tbls, tbl_idx; 4129dd0191d5SShuanglin Wang const struct ulp_mapper_core_ops *oper; 4130c5d06df4SMike Baucom int32_t rc = -EINVAL, cond_rc = 0; 4131255add67SKishore Padmanabha int32_t cond_goto = 1; 4132dd0191d5SShuanglin Wang uint32_t tid; 4133c5d06df4SMike Baucom 4134dd0191d5SShuanglin Wang oper = parms->mapper_data->mapper_oper; 4135c5d06df4SMike Baucom 4136dd0191d5SShuanglin Wang /* assign the template id based on template type */ 4137dd0191d5SShuanglin Wang tid = (parms->tmpl_type == BNXT_ULP_TEMPLATE_TYPE_ACTION) ? 4138dd0191d5SShuanglin Wang parms->act_tid : parms->class_tid; 4139dd0191d5SShuanglin Wang 4140dd0191d5SShuanglin Wang rc = ulp_mapper_cond_reject_list_process(parms, tid, &cond_rc); 4141dd0191d5SShuanglin Wang /* if rc is failure or cond_rc is a reject then exit tbl processing */ 41420c036a14SPeter Spreadborough if (unlikely(rc || cond_rc)) 4143c5d06df4SMike Baucom return -EINVAL; 4144696843ccSMike Baucom 41450c9fe336SMike Baucom tbls = ulp_mapper_tbl_list_get(parms, tid, &num_tbls); 41460c036a14SPeter Spreadborough if (unlikely(!tbls || !num_tbls)) { 4147dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "No %s tables for %d:%d\n", 4148a2417601SKishore Padmanabha ulp_mapper_tmpl_name_str(parms->tmpl_type), 4149a2417601SKishore Padmanabha parms->dev_id, tid); 4150696843ccSMike Baucom return -EINVAL; 4151696843ccSMike Baucom } 4152696843ccSMike Baucom 415359ae4961SKishore Padmanabha for (tbl_idx = 0; tbl_idx < num_tbls && cond_goto;) { 415459ae4961SKishore Padmanabha tbl = &tbls[tbl_idx]; 41551993b267SShahaji Bhosle cond_goto = tbl->execute_info.cond_true_goto; 41561993b267SShahaji Bhosle /* Process the conditional func code opcodes */ 41570c036a14SPeter Spreadborough if (unlikely(ulp_mapper_func_info_process(parms, tbl))) { 4158dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to process cond update\n"); 4159741172beSKishore Padmanabha rc = -EINVAL; 4160741172beSKishore Padmanabha goto error; 416159ae4961SKishore Padmanabha } 416259ae4961SKishore Padmanabha 4163dd0191d5SShuanglin Wang /* process the execute info of the table */ 4164dd0191d5SShuanglin Wang rc = ulp_mapper_cond_execute_list_process(parms, tbl, &cond_rc); 41650c036a14SPeter Spreadborough if (unlikely(rc)) { 4166dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to proc cond opc list (%d)\n", 41676b70a956SMike Baucom rc); 4168741172beSKishore Padmanabha goto error; 4169c5d06df4SMike Baucom } 4170c5d06df4SMike Baucom /* Skip the table if False */ 417159ae4961SKishore Padmanabha if (!cond_rc) { 4172255add67SKishore Padmanabha cond_goto = tbl->execute_info.cond_false_goto; 4173255add67SKishore Padmanabha goto next_iteration; 4174a2417601SKishore Padmanabha } 4175a2417601SKishore Padmanabha 4176ae905028SMike Baucom switch (tbl->resource_func) { 4177ae905028SMike Baucom case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE: 4178dd0191d5SShuanglin Wang rc = oper->ulp_mapper_core_tcam_tbl_process(parms, tbl); 4179ae905028SMike Baucom break; 4180ddaf0afaSKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_EM_TABLE: 4181dd0191d5SShuanglin Wang rc = oper->ulp_mapper_core_em_tbl_process(parms, tbl, 4182dd0191d5SShuanglin Wang error); 4183ae905028SMike Baucom break; 4184ae905028SMike Baucom case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE: 4185dd0191d5SShuanglin Wang rc = oper->ulp_mapper_core_index_tbl_process(parms, 4186dd0191d5SShuanglin Wang tbl); 4187ae905028SMike Baucom break; 418855aeaac3SKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_IF_TABLE: 4189dd0191d5SShuanglin Wang rc = oper->ulp_mapper_core_if_tbl_process(parms, tbl); 419055aeaac3SKishore Padmanabha break; 4191f634204bSKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_GENERIC_TABLE: 4192f634204bSKishore Padmanabha rc = ulp_mapper_gen_tbl_process(parms, tbl); 4193f634204bSKishore Padmanabha break; 4194255add67SKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_CTRL_TABLE: 4195255add67SKishore Padmanabha rc = ulp_mapper_ctrl_tbl_process(parms, tbl); 4196255add67SKishore Padmanabha break; 41976d160d77SRandy Schacher case BNXT_ULP_RESOURCE_FUNC_VNIC_TABLE: 41986d160d77SRandy Schacher rc = ulp_mapper_vnic_tbl_process(parms, tbl); 41996d160d77SRandy Schacher break; 42006d160d77SRandy Schacher case BNXT_ULP_RESOURCE_FUNC_GLOBAL_REGISTER_TABLE: 42016d160d77SRandy Schacher rc = ulp_mapper_global_register_tbl_process(parms, tbl); 42026d160d77SRandy Schacher break; 4203dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_CMM_TABLE: 4204dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_CMM_STAT: 4205dd0191d5SShuanglin Wang rc = oper->ulp_mapper_core_cmm_tbl_process(parms, tbl, 4206dd0191d5SShuanglin Wang error); 4207dd0191d5SShuanglin Wang break; 4208f634204bSKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_INVALID: 4209f634204bSKishore Padmanabha rc = 0; 4210f634204bSKishore Padmanabha break; 4211dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_KEY_RECIPE_TABLE: 4212dd0191d5SShuanglin Wang rc = ulp_mapper_key_recipe_tbl_process(parms, tbl); 4213dd0191d5SShuanglin Wang break; 421483f916bdSKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_ALLOCATOR_TABLE: 421583f916bdSKishore Padmanabha rc = ulp_mapper_allocator_tbl_process(parms, tbl); 421683f916bdSKishore Padmanabha break; 4217*0513f0afSPeter Spreadborough case BNXT_ULP_RESOURCE_FUNC_STATS_CACHE: 4218*0513f0afSPeter Spreadborough rc = ulp_mapper_stats_cache_tbl_process(parms, tbl); 4219*0513f0afSPeter Spreadborough break; 4220ae905028SMike Baucom default: 4221dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unexpected mapper resource %d\n", 4222ae905028SMike Baucom tbl->resource_func); 42230c9fe336SMike Baucom rc = -EINVAL; 42240c9fe336SMike Baucom goto error; 4225ae905028SMike Baucom } 4226ae905028SMike Baucom 4227ae905028SMike Baucom if (rc) { 4228dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Resource type %d failed\n", 4229ae905028SMike Baucom tbl->resource_func); 42300c9fe336SMike Baucom goto error; 4231ae905028SMike Baucom } 4232a2417601SKishore Padmanabha 4233a2417601SKishore Padmanabha /* perform the post table process */ 4234a2417601SKishore Padmanabha rc = ulp_mapper_conflict_resolution_process(parms, tbl, 4235a2417601SKishore Padmanabha &cond_rc); 42360c036a14SPeter Spreadborough if (unlikely(rc || !cond_rc)) { 4237dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed due to conflict resolution\n"); 4238a2417601SKishore Padmanabha rc = -EINVAL; 4239a2417601SKishore Padmanabha goto error; 4240a2417601SKishore Padmanabha } 4241255add67SKishore Padmanabha next_iteration: 424294dbd6cfSKishore Padmanabha if (cond_goto < 0) { 42430c036a14SPeter Spreadborough if (unlikely(((int32_t)tbl_idx + cond_goto) < 0)) { 424494dbd6cfSKishore Padmanabha BNXT_DRV_DBG(ERR, 424594dbd6cfSKishore Padmanabha "invalid conditional goto %d\n", 424694dbd6cfSKishore Padmanabha cond_goto); 424794dbd6cfSKishore Padmanabha goto error; 424894dbd6cfSKishore Padmanabha } 424994dbd6cfSKishore Padmanabha } else if (cond_goto == BNXT_ULP_COND_GOTO_REJECT) { 4250af50070eSKishore Padmanabha if (tbl->false_message || tbl->true_message) { 4251af50070eSKishore Padmanabha const char *msg = (tbl->false_message) ? 4252af50070eSKishore Padmanabha tbl->false_message : 4253af50070eSKishore Padmanabha tbl->true_message; 4254af50070eSKishore Padmanabha 4255af50070eSKishore Padmanabha BNXT_DRV_DBG(DEBUG, "%s\n", msg); 42560c036a14SPeter Spreadborough if (unlikely(error)) 4257dd0191d5SShuanglin Wang rte_flow_error_set(error, EINVAL, 4258dd0191d5SShuanglin Wang RTE_FLOW_ERROR_TYPE_ITEM, 4259af50070eSKishore Padmanabha NULL, msg); 4260dd0191d5SShuanglin Wang return -EINVAL; 4261dd0191d5SShuanglin Wang } 4262dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "reject the flow\n"); 4263741172beSKishore Padmanabha rc = -EINVAL; 4264741172beSKishore Padmanabha goto error; 4265741172beSKishore Padmanabha } else if (cond_goto & BNXT_ULP_COND_GOTO_RF) { 426694dbd6cfSKishore Padmanabha int32_t rf_idx; 42670c036a14SPeter Spreadborough uint64_t regval = 0; 4268741172beSKishore Padmanabha 4269741172beSKishore Padmanabha /* least significant 16 bits from reg_file index */ 427094dbd6cfSKishore Padmanabha rf_idx = (int32_t)(cond_goto & 0xFFFF); 42710c036a14SPeter Spreadborough if (unlikely(ulp_regfile_read(parms->regfile, rf_idx, 42720c036a14SPeter Spreadborough ®val))) { 4273dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "regfile[%d] read oob\n", 4274741172beSKishore Padmanabha rf_idx); 4275741172beSKishore Padmanabha rc = -EINVAL; 4276741172beSKishore Padmanabha goto error; 4277741172beSKishore Padmanabha } 4278741172beSKishore Padmanabha cond_goto = (int32_t)regval; 4279741172beSKishore Padmanabha } 428059ae4961SKishore Padmanabha tbl_idx += cond_goto; 4281ae905028SMike Baucom } 4282ae905028SMike Baucom 4283ae905028SMike Baucom return rc; 42840c9fe336SMike Baucom error: 4285dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "%s tables failed operation for %d:%d\n", 4286a2417601SKishore Padmanabha ulp_mapper_tmpl_name_str(parms->tmpl_type), 4287a2417601SKishore Padmanabha parms->dev_id, tid); 42880c9fe336SMike Baucom return rc; 4289ae905028SMike Baucom } 429005a11d7dSMike Baucom 429105a11d7dSMike Baucom static int32_t 429205a11d7dSMike Baucom ulp_mapper_resource_free(struct bnxt_ulp_context *ulp, 4293be8acb27SKishore Padmanabha uint32_t fid, 4294dd0191d5SShuanglin Wang struct ulp_flow_db_res_params *res, 4295dd0191d5SShuanglin Wang void *error) 429605a11d7dSMike Baucom { 4297dd0191d5SShuanglin Wang const struct ulp_mapper_core_ops *mapper_op; 429883f916bdSKishore Padmanabha struct bnxt_ulp_mapper_data *mdata; 429905a11d7dSMike Baucom int32_t rc = 0; 430005a11d7dSMike Baucom 43010c036a14SPeter Spreadborough if (unlikely(!res || !ulp)) { 4302dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to free resource\n "); 430305a11d7dSMike Baucom return -EINVAL; 430405a11d7dSMike Baucom } 430505a11d7dSMike Baucom 4306dd0191d5SShuanglin Wang mapper_op = ulp_mapper_data_oper_get(ulp); 430705a11d7dSMike Baucom switch (res->resource_func) { 430805a11d7dSMike Baucom case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE: 4309dd0191d5SShuanglin Wang rc = mapper_op->ulp_mapper_core_tcam_entry_free(ulp, res); 431005a11d7dSMike Baucom break; 4311ddaf0afaSKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_EM_TABLE: 4312dd0191d5SShuanglin Wang rc = mapper_op->ulp_mapper_core_em_entry_free(ulp, res, error); 431305a11d7dSMike Baucom break; 431405a11d7dSMike Baucom case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE: 4315dd0191d5SShuanglin Wang rc = mapper_op->ulp_mapper_core_index_entry_free(ulp, res); 4316dd0191d5SShuanglin Wang break; 4317dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_CMM_TABLE: 4318dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_CMM_STAT: 4319dd0191d5SShuanglin Wang rc = mapper_op->ulp_mapper_core_cmm_entry_free(ulp, res, error); 432005a11d7dSMike Baucom break; 432105a11d7dSMike Baucom case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER: 4322dd0191d5SShuanglin Wang rc = mapper_op->ulp_mapper_core_ident_free(ulp, res); 432305a11d7dSMike Baucom break; 432405a11d7dSMike Baucom case BNXT_ULP_RESOURCE_FUNC_HW_FID: 432505a11d7dSMike Baucom rc = ulp_mapper_mark_free(ulp, res); 432605a11d7dSMike Baucom break; 4327be8acb27SKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_PARENT_FLOW: 4328be8acb27SKishore Padmanabha rc = ulp_mapper_parent_flow_free(ulp, fid, res); 4329be8acb27SKishore Padmanabha break; 4330be8acb27SKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW: 4331be8acb27SKishore Padmanabha rc = ulp_mapper_child_flow_free(ulp, fid, res); 4332be8acb27SKishore Padmanabha break; 4333f634204bSKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_GENERIC_TABLE: 43346d160d77SRandy Schacher rc = ulp_mapper_gen_tbl_res_free(ulp, fid, res); 43356d160d77SRandy Schacher break; 43366d160d77SRandy Schacher case BNXT_ULP_RESOURCE_FUNC_VNIC_TABLE: 4337dd0191d5SShuanglin Wang rc = ulp_mapper_vnic_tbl_res_free(ulp, ulp->bp, res); 43386d160d77SRandy Schacher break; 43396d160d77SRandy Schacher case BNXT_ULP_RESOURCE_FUNC_GLOBAL_REGISTER_TABLE: 4340dd0191d5SShuanglin Wang rc = ulp_mapper_global_res_free(ulp, ulp->bp, res); 4341dd0191d5SShuanglin Wang break; 4342dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_KEY_RECIPE_TABLE: 4343dd0191d5SShuanglin Wang rc = ulp_mapper_key_recipe_free(ulp, res->direction, 4344dd0191d5SShuanglin Wang res->resource_sub_type, 4345dd0191d5SShuanglin Wang res->resource_hndl); 4346f634204bSKishore Padmanabha break; 434783f916bdSKishore Padmanabha case BNXT_ULP_RESOURCE_FUNC_ALLOCATOR_TABLE: 434883f916bdSKishore Padmanabha mdata = bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp); 43490c036a14SPeter Spreadborough if (unlikely(!mdata)) { 435083f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "Unable to get mapper data\n"); 435183f916bdSKishore Padmanabha return -EINVAL; 435283f916bdSKishore Padmanabha } 435383f916bdSKishore Padmanabha rc = ulp_allocator_tbl_list_free(mdata, 435483f916bdSKishore Padmanabha res->resource_sub_type, 435583f916bdSKishore Padmanabha res->direction, 435683f916bdSKishore Padmanabha res->resource_hndl); 435783f916bdSKishore Padmanabha break; 4358*0513f0afSPeter Spreadborough case BNXT_ULP_RESOURCE_FUNC_STATS_CACHE: 4359*0513f0afSPeter Spreadborough rc = ulp_mapper_stats_cache_tbl_res_free(ulp, 4360*0513f0afSPeter Spreadborough fid); 4361*0513f0afSPeter Spreadborough break; 436205a11d7dSMike Baucom default: 436305a11d7dSMike Baucom break; 436405a11d7dSMike Baucom } 436505a11d7dSMike Baucom 436605a11d7dSMike Baucom return rc; 436705a11d7dSMike Baucom } 436805a11d7dSMike Baucom 436905a11d7dSMike Baucom int32_t 437005a11d7dSMike Baucom ulp_mapper_resources_free(struct bnxt_ulp_context *ulp_ctx, 437130683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 4372dd0191d5SShuanglin Wang uint32_t fid, 4373dd0191d5SShuanglin Wang void *error) 437405a11d7dSMike Baucom { 437505a11d7dSMike Baucom struct ulp_flow_db_res_params res_parms = { 0 }; 4376dd0191d5SShuanglin Wang int32_t rc, trc, frc = 0; 437705a11d7dSMike Baucom 43780c036a14SPeter Spreadborough if (unlikely(!ulp_ctx)) { 4379dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid parms, unable to free flow\n"); 438005a11d7dSMike Baucom return -EINVAL; 438105a11d7dSMike Baucom } 438205a11d7dSMike Baucom 438305a11d7dSMike Baucom /* 438405a11d7dSMike Baucom * Set the critical resource on the first resource del, then iterate 438505a11d7dSMike Baucom * while status is good 438605a11d7dSMike Baucom */ 4387f4875133SKishore Padmanabha res_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_YES; 4388255add67SKishore Padmanabha 438930683082SKishore Padmanabha rc = ulp_flow_db_resource_del(ulp_ctx, flow_type, fid, &res_parms); 439005a11d7dSMike Baucom 439105a11d7dSMike Baucom if (rc) { 439205a11d7dSMike Baucom /* 439305a11d7dSMike Baucom * This is unexpected on the first call to resource del. 439405a11d7dSMike Baucom * It likely means that the flow did not exist in the flow db. 439505a11d7dSMike Baucom */ 4396dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow[%d][0x%08x] failed to free (rc=%d)\n", 439730683082SKishore Padmanabha flow_type, fid, rc); 439805a11d7dSMike Baucom return rc; 439905a11d7dSMike Baucom } 440005a11d7dSMike Baucom 440105a11d7dSMike Baucom while (!rc) { 4402dd0191d5SShuanglin Wang trc = ulp_mapper_resource_free(ulp_ctx, fid, &res_parms, error); 4403dd0191d5SShuanglin Wang if (trc) { 440405a11d7dSMike Baucom /* 440505a11d7dSMike Baucom * On fail, we still need to attempt to free the 440605a11d7dSMike Baucom * remaining resources. Don't return 440705a11d7dSMike Baucom */ 4408dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 44090001cc58SKishore Padmanabha "Flow[%d][0x%x] Res[%d][0x%016" PRIX64 441005a11d7dSMike Baucom "] failed rc=%d.\n", 441130683082SKishore Padmanabha flow_type, fid, res_parms.resource_func, 441205a11d7dSMike Baucom res_parms.resource_hndl, trc); 441305a11d7dSMike Baucom 4414dd0191d5SShuanglin Wang /* Capture error in final rc */ 4415dd0191d5SShuanglin Wang frc = trc; 4416dd0191d5SShuanglin Wang } 4417f4875133SKishore Padmanabha /* All subsequent call require the non-critical_resource */ 4418f4875133SKishore Padmanabha res_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO; 441905a11d7dSMike Baucom 442005a11d7dSMike Baucom rc = ulp_flow_db_resource_del(ulp_ctx, 442130683082SKishore Padmanabha flow_type, 442205a11d7dSMike Baucom fid, 442305a11d7dSMike Baucom &res_parms); 442405a11d7dSMike Baucom } 442505a11d7dSMike Baucom 4426dd0191d5SShuanglin Wang /* Expected that flow_db should return no entry */ 4427dd0191d5SShuanglin Wang if (rc != -ENOENT) 4428dd0191d5SShuanglin Wang frc = rc; 4429dd0191d5SShuanglin Wang 443005a11d7dSMike Baucom /* Free the Flow ID since we've removed all resources */ 443130683082SKishore Padmanabha rc = ulp_flow_db_fid_free(ulp_ctx, flow_type, fid); 443205a11d7dSMike Baucom 4433dd0191d5SShuanglin Wang /* Ensure that any error will be reported */ 4434dd0191d5SShuanglin Wang if (rc) 4435dd0191d5SShuanglin Wang frc = rc; 4436dd0191d5SShuanglin Wang 4437288becfbSShuanglin Wang #ifdef TF_FLOW_SCALE_QUERY 4438288becfbSShuanglin Wang /* update for regular flows only */ 4439288becfbSShuanglin Wang if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR) 4440ffbc3529SShuanglin Wang ulp_resc_usage_sync(ulp_ctx); 4441288becfbSShuanglin Wang #endif /* TF_FLOW_SCALE_QUERY */ 4442288becfbSShuanglin Wang 4443dd0191d5SShuanglin Wang return frc; 444405a11d7dSMike Baucom } 444505a11d7dSMike Baucom 4446bfcaae8fSKishore Padmanabha static void 4447bfcaae8fSKishore Padmanabha ulp_mapper_glb_resource_info_deinit(struct bnxt_ulp_context *ulp_ctx, 4448bfcaae8fSKishore Padmanabha struct bnxt_ulp_mapper_data *mapper_data) 4449bfcaae8fSKishore Padmanabha { 4450bfcaae8fSKishore Padmanabha struct bnxt_ulp_mapper_glb_resource_entry *ent; 4451bfcaae8fSKishore Padmanabha struct ulp_flow_db_res_params res; 4452bfcaae8fSKishore Padmanabha uint32_t dir, idx; 4453bfcaae8fSKishore Padmanabha 4454bfcaae8fSKishore Padmanabha /* Iterate the global resources and process each one */ 4455bfcaae8fSKishore Padmanabha for (dir = TF_DIR_RX; dir < TF_DIR_MAX; dir++) { 4456c6062ec0SMike Baucom for (idx = 0; idx < BNXT_ULP_GLB_RF_IDX_LAST; idx++) { 4457bfcaae8fSKishore Padmanabha ent = &mapper_data->glb_res_tbl[dir][idx]; 4458bfcaae8fSKishore Padmanabha if (ent->resource_func == 4459c6062ec0SMike Baucom BNXT_ULP_RESOURCE_FUNC_INVALID || 4460c6062ec0SMike Baucom ent->shared) 4461bfcaae8fSKishore Padmanabha continue; 4462bfcaae8fSKishore Padmanabha memset(&res, 0, sizeof(struct ulp_flow_db_res_params)); 4463bfcaae8fSKishore Padmanabha res.resource_func = ent->resource_func; 4464bfcaae8fSKishore Padmanabha res.direction = dir; 4465bfcaae8fSKishore Padmanabha res.resource_type = ent->resource_type; 4466d097b460SKishore Padmanabha /*convert it from BE to cpu */ 4467d097b460SKishore Padmanabha res.resource_hndl = 4468d097b460SKishore Padmanabha tfp_be_to_cpu_64(ent->resource_hndl); 4469dd0191d5SShuanglin Wang ulp_mapper_resource_free(ulp_ctx, 0, &res, NULL); 4470bfcaae8fSKishore Padmanabha } 4471bfcaae8fSKishore Padmanabha } 4472bfcaae8fSKishore Padmanabha } 4473bfcaae8fSKishore Padmanabha 447405a11d7dSMike Baucom int32_t 447530683082SKishore Padmanabha ulp_mapper_flow_destroy(struct bnxt_ulp_context *ulp_ctx, 447630683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 4477dd0191d5SShuanglin Wang uint32_t fid, 4478dd0191d5SShuanglin Wang void *error) 447905a11d7dSMike Baucom { 44806c7cbc80SKishore Padmanabha int32_t rc; 44816c7cbc80SKishore Padmanabha 44820c036a14SPeter Spreadborough if (unlikely(!ulp_ctx)) { 4483dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid parms, unable to free flow\n"); 448405a11d7dSMike Baucom return -EINVAL; 448505a11d7dSMike Baucom } 448605a11d7dSMike Baucom 4487dd0191d5SShuanglin Wang rc = ulp_mapper_resources_free(ulp_ctx, flow_type, fid, error); 44886c7cbc80SKishore Padmanabha return rc; 448905a11d7dSMike Baucom } 44908f153057SMike Baucom 44918f153057SMike Baucom /* Function to handle the mapping of the Flow to be compatible 44928f153057SMike Baucom * with the underlying hardware. 44938f153057SMike Baucom */ 44948f153057SMike Baucom int32_t 44958f153057SMike Baucom ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx, 4496dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_parms *parms, void *error) 44978f153057SMike Baucom { 4498dd0191d5SShuanglin Wang const struct ulp_mapper_core_ops *oper; 4499aa0fa4d9SMike Baucom struct ulp_regfile regfile; 4500a2417601SKishore Padmanabha int32_t rc = 0, trc; 45018f153057SMike Baucom 45020c036a14SPeter Spreadborough if (unlikely(!ulp_ctx || !parms)) 4503aa0fa4d9SMike Baucom return -EINVAL; 4504aa0fa4d9SMike Baucom 4505dd0191d5SShuanglin Wang parms->regfile = ®file; 4506dd0191d5SShuanglin Wang parms->ulp_ctx = ulp_ctx; 4507dd0191d5SShuanglin Wang 4508dd0191d5SShuanglin Wang oper = ulp_mapper_data_oper_get(ulp_ctx); 45098f153057SMike Baucom 45108f153057SMike Baucom /* Get the device id from the ulp context */ 45110c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &parms->dev_id))) { 4512dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid ulp context\n"); 4513dd0191d5SShuanglin Wang return -EINVAL; 4514dd0191d5SShuanglin Wang } 45150c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_fid_get(ulp_ctx, &parms->fw_fid))) { 4516dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get the func_id\n"); 45178f153057SMike Baucom return -EINVAL; 45188f153057SMike Baucom } 45198f153057SMike Baucom 4520a4638284SMike Baucom /* Get the device params, it will be used in later processing */ 4521dd0191d5SShuanglin Wang parms->device_params = bnxt_ulp_device_params_get(parms->dev_id); 45220c036a14SPeter Spreadborough if (unlikely(!parms->device_params)) { 4523dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "No device parms for device id %d\n", 4524dd0191d5SShuanglin Wang parms->dev_id); 4525a4638284SMike Baucom return -EINVAL; 4526a4638284SMike Baucom } 4527a4638284SMike Baucom 4528072cb4a8SMike Baucom /* 4529072cb4a8SMike Baucom * Get the mapper data for dynamic mapper data such as default 4530072cb4a8SMike Baucom * ids. 4531072cb4a8SMike Baucom */ 4532dd0191d5SShuanglin Wang parms->mapper_data = (struct bnxt_ulp_mapper_data *) 4533072cb4a8SMike Baucom bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx); 45340c036a14SPeter Spreadborough if (unlikely(!parms->mapper_data)) { 4535dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get the ulp mapper data\n"); 4536072cb4a8SMike Baucom return -EINVAL; 4537072cb4a8SMike Baucom } 4538072cb4a8SMike Baucom 45398f153057SMike Baucom /* initialize the registry file for further processing */ 45400c036a14SPeter Spreadborough if (unlikely(ulp_regfile_init(parms->regfile))) { 4541dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "regfile initialization failed.\n"); 4542dd0191d5SShuanglin Wang return -EINVAL; 4543dd0191d5SShuanglin Wang } 4544dd0191d5SShuanglin Wang 4545dd0191d5SShuanglin Wang /* Start batching */ 4546dd0191d5SShuanglin Wang rc = oper->ulp_mapper_mpc_batch_start(&parms->batch_info); 4547dd0191d5SShuanglin Wang if (unlikely(rc)) { 4548dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "MPC Batch start failed\n"); 45498f153057SMike Baucom return -EINVAL; 45508f153057SMike Baucom } 45518f153057SMike Baucom 4552188bf91dSVenkat Duvvuru /* Process the action template list from the selected action table*/ 4553dd0191d5SShuanglin Wang if (parms->act_tid) { 4554dd0191d5SShuanglin Wang parms->tmpl_type = BNXT_ULP_TEMPLATE_TYPE_ACTION; 45550c9fe336SMike Baucom /* Process the action template tables */ 4556dd0191d5SShuanglin Wang rc = ulp_mapper_tbls_process(parms, error); 45570c036a14SPeter Spreadborough if (unlikely(rc)) 4558dd0191d5SShuanglin Wang goto batch_error; 45598f153057SMike Baucom } 45608f153057SMike Baucom 4561dd0191d5SShuanglin Wang if (parms->class_tid) { 4562dd0191d5SShuanglin Wang parms->tmpl_type = BNXT_ULP_TEMPLATE_TYPE_CLASS; 45630c9fe336SMike Baucom /* Process the class template tables.*/ 4564dd0191d5SShuanglin Wang rc = ulp_mapper_tbls_process(parms, error); 45650c036a14SPeter Spreadborough if (unlikely(rc)) 4566dd0191d5SShuanglin Wang goto batch_error; 4567dd0191d5SShuanglin Wang } 4568dd0191d5SShuanglin Wang 4569dd0191d5SShuanglin Wang if (oper->ulp_mapper_mpc_batch_started(&parms->batch_info)) { 4570dd0191d5SShuanglin Wang /* Should only get here is there were no EM inserts */ 4571dd0191d5SShuanglin Wang rc = oper->ulp_mapper_mpc_batch_end(&ulp_ctx->bp->tfcp, 4572dd0191d5SShuanglin Wang &parms->batch_info); 4573dd0191d5SShuanglin Wang if (unlikely(rc)) { 4574dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "MPC Batch end failed\n"); 45758f153057SMike Baucom goto flow_error; 45768f153057SMike Baucom } 4577dd0191d5SShuanglin Wang } 45788f153057SMike Baucom 4579be8acb27SKishore Padmanabha /* setup the parent-child details */ 4580dd0191d5SShuanglin Wang if (parms->parent_flow) { 4581be8acb27SKishore Padmanabha /* create a parent flow details */ 4582dd0191d5SShuanglin Wang rc = ulp_flow_db_parent_flow_create(parms); 45830c036a14SPeter Spreadborough if (unlikely(rc)) 4584be8acb27SKishore Padmanabha goto flow_error; 4585dd0191d5SShuanglin Wang } else if (parms->child_flow) { 4586be8acb27SKishore Padmanabha /* create a child flow details */ 4587dd0191d5SShuanglin Wang rc = ulp_flow_db_child_flow_create(parms); 45880c036a14SPeter Spreadborough if (unlikely(rc)) 4589be8acb27SKishore Padmanabha goto flow_error; 4590be8acb27SKishore Padmanabha } 4591be8acb27SKishore Padmanabha 4592288becfbSShuanglin Wang #ifdef TF_FLOW_SCALE_QUERY 4593ffbc3529SShuanglin Wang ulp_resc_usage_sync(ulp_ctx); 4594288becfbSShuanglin Wang #endif /* TF_FLOW_SCALE_QUERY */ 4595288becfbSShuanglin Wang 45968f153057SMike Baucom return rc; 45978f153057SMike Baucom 4598dd0191d5SShuanglin Wang batch_error: 4599dd0191d5SShuanglin Wang /* 4600dd0191d5SShuanglin Wang * An error occurred after batching had started but before it 4601dd0191d5SShuanglin Wang * ended. Call batch end and ignore any errors. 4602dd0191d5SShuanglin Wang */ 4603dd0191d5SShuanglin Wang if (oper->ulp_mapper_mpc_batch_started(&parms->batch_info)) 4604dd0191d5SShuanglin Wang oper->ulp_mapper_mpc_batch_end(&ulp_ctx->bp->tfcp, 4605dd0191d5SShuanglin Wang &parms->batch_info); 4606dd0191d5SShuanglin Wang 46078f153057SMike Baucom flow_error: 4608dd0191d5SShuanglin Wang if (parms->rid) { 46096d160d77SRandy Schacher /* An RID was in-flight but not pushed, free the resources */ 46106d160d77SRandy Schacher trc = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_RID, 4611dd0191d5SShuanglin Wang parms->rid, NULL); 46126d160d77SRandy Schacher if (trc) 4613dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 46146d160d77SRandy Schacher "Failed to free resources rid=0x%08x rc=%d\n", 4615dd0191d5SShuanglin Wang parms->rid, trc); 4616dd0191d5SShuanglin Wang parms->rid = 0; 46176d160d77SRandy Schacher } 46186d160d77SRandy Schacher 46198f153057SMike Baucom /* Free all resources that were allocated during flow creation */ 4620dd0191d5SShuanglin Wang if (parms->flow_id) { 4621dd0191d5SShuanglin Wang trc = ulp_mapper_flow_destroy(ulp_ctx, parms->flow_type, 4622dd0191d5SShuanglin Wang parms->flow_id, NULL); 46238f153057SMike Baucom if (trc) 4624dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 46256d160d77SRandy Schacher "Failed to free resources fid=0x%08x rc=%d\n", 4626dd0191d5SShuanglin Wang parms->flow_id, trc); 46276d160d77SRandy Schacher } 46288f153057SMike Baucom 46298f153057SMike Baucom return rc; 46308f153057SMike Baucom } 4631072cb4a8SMike Baucom 4632ffbc3529SShuanglin Wang #ifdef TF_FLOW_SCALE_QUERY 4633ffbc3529SShuanglin Wang /* Sync resource usage state with firmware */ 4634ffbc3529SShuanglin Wang int ulp_resc_usage_sync(struct bnxt_ulp_context *ulp_ctx) 4635ffbc3529SShuanglin Wang { 4636ffbc3529SShuanglin Wang uint32_t dev_id; 4637ffbc3529SShuanglin Wang if (unlikely(bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id))) { 4638ffbc3529SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid ulp context\n"); 4639ffbc3529SShuanglin Wang return -EINVAL; 4640ffbc3529SShuanglin Wang } 4641ffbc3529SShuanglin Wang 4642ffbc3529SShuanglin Wang if (dev_id == BNXT_ULP_DEVICE_ID_THOR) { 4643ffbc3529SShuanglin Wang tf_resc_resume_usage_update(); 4644ffbc3529SShuanglin Wang tf_resc_usage_update_all(ulp_ctx->bp); 4645ffbc3529SShuanglin Wang } else if (dev_id == BNXT_ULP_DEVICE_ID_THOR2) { 4646ffbc3529SShuanglin Wang tfc_resc_usage_query_all(ulp_ctx->bp); 4647ffbc3529SShuanglin Wang } 4648ffbc3529SShuanglin Wang 4649ffbc3529SShuanglin Wang return 0; 4650ffbc3529SShuanglin Wang } 4651ffbc3529SShuanglin Wang #endif /* TF_FLOW_SCALE_QUERY */ 4652ffbc3529SShuanglin Wang 4653072cb4a8SMike Baucom int32_t 4654072cb4a8SMike Baucom ulp_mapper_init(struct bnxt_ulp_context *ulp_ctx) 4655072cb4a8SMike Baucom { 4656072cb4a8SMike Baucom struct bnxt_ulp_mapper_data *data; 4657f634204bSKishore Padmanabha int32_t rc; 4658072cb4a8SMike Baucom 4659072cb4a8SMike Baucom if (!ulp_ctx) 4660072cb4a8SMike Baucom return -EINVAL; 4661072cb4a8SMike Baucom 4662072cb4a8SMike Baucom data = rte_zmalloc("ulp_mapper_data", 4663072cb4a8SMike Baucom sizeof(struct bnxt_ulp_mapper_data), 0); 46640c036a14SPeter Spreadborough if (unlikely(!data)) { 4665dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to allocate the mapper data\n"); 4666dd0191d5SShuanglin Wang return -ENOMEM; 4667dd0191d5SShuanglin Wang } 4668dd0191d5SShuanglin Wang 4669dd0191d5SShuanglin Wang /* set the mapper operations for the current platform */ 4670dd0191d5SShuanglin Wang data->mapper_oper = bnxt_ulp_mapper_ops_get(ulp_ctx->bp); 46710c036a14SPeter Spreadborough if (unlikely(data->mapper_oper == NULL)) { 4672dd0191d5SShuanglin Wang rte_free(data); 4673dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get mapper ops\n"); 4674072cb4a8SMike Baucom return -ENOMEM; 4675072cb4a8SMike Baucom } 4676072cb4a8SMike Baucom 46770c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_ptr2_mapper_data_set(ulp_ctx, data))) { 4678dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to set mapper data in context\n"); 4679072cb4a8SMike Baucom /* Don't call deinit since the prof_func wasn't allocated. */ 4680072cb4a8SMike Baucom rte_free(data); 4681072cb4a8SMike Baucom return -ENOMEM; 4682072cb4a8SMike Baucom } 4683072cb4a8SMike Baucom 4684bfcaae8fSKishore Padmanabha /* Allocate the global resource ids */ 4685d097b460SKishore Padmanabha rc = ulp_mapper_glb_resource_info_init(ulp_ctx, data); 46860c036a14SPeter Spreadborough if (unlikely(rc)) { 4687dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to initialize global resource ids\n"); 4688072cb4a8SMike Baucom goto error; 4689072cb4a8SMike Baucom } 4690072cb4a8SMike Baucom 4691c6062ec0SMike Baucom /* 4692c6062ec0SMike Baucom * Only initialize the app global resources if a shared session was 4693c6062ec0SMike Baucom * created. 4694c6062ec0SMike Baucom */ 4695c6062ec0SMike Baucom if (bnxt_ulp_cntxt_shared_session_enabled(ulp_ctx)) { 4696c6062ec0SMike Baucom rc = ulp_mapper_app_glb_resource_info_init(ulp_ctx, data); 46970c036a14SPeter Spreadborough if (unlikely(rc)) { 4698dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to init app glb resources\n"); 4699c6062ec0SMike Baucom goto error; 4700c6062ec0SMike Baucom } 4701c6062ec0SMike Baucom } 4702c6062ec0SMike Baucom 4703f634204bSKishore Padmanabha /* Allocate the generic table list */ 4704dd0191d5SShuanglin Wang rc = ulp_mapper_generic_tbl_list_init(ulp_ctx, data); 47050c036a14SPeter Spreadborough if (unlikely(rc)) { 4706dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to initialize generic tbl list\n"); 4707dd0191d5SShuanglin Wang goto error; 4708dd0191d5SShuanglin Wang } 4709dd0191d5SShuanglin Wang 4710dd0191d5SShuanglin Wang rc = ulp_mapper_key_recipe_tbl_init(ulp_ctx, data); 47110c036a14SPeter Spreadborough if (unlikely(rc)) { 4712dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to initialize key_recipe tbl\n"); 47134bc32a80SMike Baucom goto error; 47144bc32a80SMike Baucom } 47154bc32a80SMike Baucom 471683f916bdSKishore Padmanabha rc = ulp_allocator_tbl_list_init(ulp_ctx, data); 47170c036a14SPeter Spreadborough if (unlikely(rc)) { 471883f916bdSKishore Padmanabha BNXT_DRV_DBG(ERR, "Failed to initialize allocator tbl\n"); 471983f916bdSKishore Padmanabha goto error; 472083f916bdSKishore Padmanabha } 472183f916bdSKishore Padmanabha 4722072cb4a8SMike Baucom return 0; 4723072cb4a8SMike Baucom error: 4724072cb4a8SMike Baucom /* Ignore the return code in favor of returning the original error. */ 4725072cb4a8SMike Baucom ulp_mapper_deinit(ulp_ctx); 4726072cb4a8SMike Baucom return rc; 4727072cb4a8SMike Baucom } 4728072cb4a8SMike Baucom 4729072cb4a8SMike Baucom void 4730072cb4a8SMike Baucom ulp_mapper_deinit(struct bnxt_ulp_context *ulp_ctx) 4731072cb4a8SMike Baucom { 4732072cb4a8SMike Baucom struct bnxt_ulp_mapper_data *data; 4733072cb4a8SMike Baucom 47340c036a14SPeter Spreadborough if (unlikely(!ulp_ctx)) { 4735dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 47366b70a956SMike Baucom "Failed to acquire ulp context, so data may not be released.\n"); 4737072cb4a8SMike Baucom return; 4738072cb4a8SMike Baucom } 4739072cb4a8SMike Baucom 4740072cb4a8SMike Baucom data = (struct bnxt_ulp_mapper_data *) 4741072cb4a8SMike Baucom bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx); 47420c036a14SPeter Spreadborough if (unlikely(!data)) { 4743072cb4a8SMike Baucom /* Go ahead and return since there is no allocated data. */ 4744dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "No data appears to have been allocated.\n"); 4745072cb4a8SMike Baucom return; 4746072cb4a8SMike Baucom } 4747072cb4a8SMike Baucom 4748bfcaae8fSKishore Padmanabha /* Free the global resource info table entries */ 4749bfcaae8fSKishore Padmanabha ulp_mapper_glb_resource_info_deinit(ulp_ctx, data); 4750072cb4a8SMike Baucom 4751f634204bSKishore Padmanabha /* Free the generic table */ 4752f634204bSKishore Padmanabha (void)ulp_mapper_generic_tbl_list_deinit(data); 47534bc32a80SMike Baucom 4754dd0191d5SShuanglin Wang /* Free the key recipe table */ 4755dd0191d5SShuanglin Wang (void)ulp_mapper_key_recipe_tbl_deinit(data); 4756dd0191d5SShuanglin Wang 475783f916bdSKishore Padmanabha /* Free the allocator table */ 475883f916bdSKishore Padmanabha (void)ulp_allocator_tbl_list_deinit(data); 475983f916bdSKishore Padmanabha 4760072cb4a8SMike Baucom rte_free(data); 4761072cb4a8SMike Baucom /* Reset the data pointer within the ulp_ctx. */ 4762072cb4a8SMike Baucom bnxt_ulp_cntxt_ptr2_mapper_data_set(ulp_ctx, NULL); 4763072cb4a8SMike Baucom } 4764