1dd0191d5SShuanglin Wang /* SPDX-License-Identifier: BSD-3-Clause 2dd0191d5SShuanglin Wang * Copyright(c) 2014-2023 Broadcom 3dd0191d5SShuanglin Wang * All rights reserved. 4dd0191d5SShuanglin Wang */ 5dd0191d5SShuanglin Wang 6dd0191d5SShuanglin Wang #include "ulp_mapper.h" 7dd0191d5SShuanglin Wang #include "ulp_flow_db.h" 8dd0191d5SShuanglin Wang #include "ulp_ha_mgr.h" 9dd0191d5SShuanglin Wang #include "tfp.h" 10dd0191d5SShuanglin Wang #include "tf_util.h" 11*0c036a14SPeter Spreadborough #include "bnxt_ulp_utils.h" 12dd0191d5SShuanglin Wang #include "bnxt_ulp_tf.h" 13dd0191d5SShuanglin Wang 14dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 15dd0191d5SShuanglin Wang #include "ulp_template_debug_proto.h" 16dd0191d5SShuanglin Wang #include "ulp_tf_debug.h" 17dd0191d5SShuanglin Wang #endif 18dd0191d5SShuanglin Wang 19dd0191d5SShuanglin Wang /* Internal function to write the tcam entry */ 20dd0191d5SShuanglin Wang static int32_t 21dd0191d5SShuanglin Wang ulp_mapper_tf_tcam_tbl_entry_write(struct bnxt_ulp_mapper_parms *parms, 22dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl, 23dd0191d5SShuanglin Wang struct ulp_blob *key, 24dd0191d5SShuanglin Wang struct ulp_blob *mask, 25dd0191d5SShuanglin Wang struct ulp_blob *data, 26dd0191d5SShuanglin Wang uint16_t idx) 27dd0191d5SShuanglin Wang { 28dd0191d5SShuanglin Wang struct tf_set_tcam_entry_parms sparms = { 0 }; 29dd0191d5SShuanglin Wang struct tf *tfp; 30dd0191d5SShuanglin Wang uint16_t tmplen; 31dd0191d5SShuanglin Wang int32_t rc; 32dd0191d5SShuanglin Wang 33dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx, tbl->session_type); 34dd0191d5SShuanglin Wang if (!tfp) { 35dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get truflow pointer\n"); 36dd0191d5SShuanglin Wang return -EINVAL; 37dd0191d5SShuanglin Wang } 38dd0191d5SShuanglin Wang 39dd0191d5SShuanglin Wang sparms.dir = tbl->direction; 40dd0191d5SShuanglin Wang sparms.tcam_tbl_type = tbl->resource_type; 41dd0191d5SShuanglin Wang sparms.idx = idx; 42dd0191d5SShuanglin Wang sparms.key = ulp_blob_data_get(key, &tmplen); 43dd0191d5SShuanglin Wang sparms.key_sz_in_bits = tmplen; 44dd0191d5SShuanglin Wang sparms.mask = ulp_blob_data_get(mask, &tmplen); 45dd0191d5SShuanglin Wang sparms.result = ulp_blob_data_get(data, &tmplen); 46dd0191d5SShuanglin Wang sparms.result_sz_in_bits = tmplen; 47dd0191d5SShuanglin Wang if (tf_set_tcam_entry(tfp, &sparms)) { 48dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "tcam[%s][%s][%x] write failed.\n", 49dd0191d5SShuanglin Wang tf_tcam_tbl_2_str(sparms.tcam_tbl_type), 50dd0191d5SShuanglin Wang tf_dir_2_str(sparms.dir), sparms.idx); 51dd0191d5SShuanglin Wang return -EIO; 52dd0191d5SShuanglin Wang } 53dd0191d5SShuanglin Wang BNXT_DRV_INF("tcam[%s][%s][%x] write success.\n", 54dd0191d5SShuanglin Wang tf_tcam_tbl_2_str(sparms.tcam_tbl_type), 55dd0191d5SShuanglin Wang tf_dir_2_str(sparms.dir), sparms.idx); 56dd0191d5SShuanglin Wang 57dd0191d5SShuanglin Wang /* Mark action */ 58dd0191d5SShuanglin Wang rc = ulp_mapper_mark_act_ptr_process(parms, tbl); 59dd0191d5SShuanglin Wang if (rc) { 60dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "failed mark action processing\n"); 61dd0191d5SShuanglin Wang return rc; 62dd0191d5SShuanglin Wang } 63dd0191d5SShuanglin Wang 64dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 65dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 66dd0191d5SShuanglin Wang ulp_mapper_tcam_entry_dump("TCAM", idx, tbl, key, mask, data); 67dd0191d5SShuanglin Wang #endif 68dd0191d5SShuanglin Wang #endif 69dd0191d5SShuanglin Wang return rc; 70dd0191d5SShuanglin Wang } 71dd0191d5SShuanglin Wang 72dd0191d5SShuanglin Wang static 73dd0191d5SShuanglin Wang int32_t ulp_mapper_tf_tcam_is_wc_tcam(struct bnxt_ulp_mapper_tbl_info *tbl) 74dd0191d5SShuanglin Wang { 75dd0191d5SShuanglin Wang if (tbl->resource_type == TF_TCAM_TBL_TYPE_WC_TCAM || 76dd0191d5SShuanglin Wang tbl->resource_type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH || 77dd0191d5SShuanglin Wang tbl->resource_type == TF_TCAM_TBL_TYPE_WC_TCAM_LOW) 78dd0191d5SShuanglin Wang return 1; 79dd0191d5SShuanglin Wang return 0; 80dd0191d5SShuanglin Wang } 81dd0191d5SShuanglin Wang 82dd0191d5SShuanglin Wang static int32_t 83dd0191d5SShuanglin Wang ulp_mapper_tf_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms, 84dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl) 85dd0191d5SShuanglin Wang { 86dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_key_info *kflds; 87dd0191d5SShuanglin Wang struct ulp_blob okey, omask, data, update_data; 88dd0191d5SShuanglin Wang struct ulp_blob tkey, tmask; /* transform key and mask */ 89dd0191d5SShuanglin Wang struct ulp_blob *key, *mask; 90dd0191d5SShuanglin Wang uint32_t i, num_kflds; 91dd0191d5SShuanglin Wang struct tf *tfp; 92dd0191d5SShuanglin Wang int32_t rc, trc; 93dd0191d5SShuanglin Wang struct bnxt_ulp_device_params *dparms = parms->device_params; 94dd0191d5SShuanglin Wang struct tf_alloc_tcam_entry_parms aparms = { 0 }; 95dd0191d5SShuanglin Wang struct ulp_flow_db_res_params fid_parms = { 0 }; 96dd0191d5SShuanglin Wang struct tf_free_tcam_entry_parms free_parms = { 0 }; 97dd0191d5SShuanglin Wang uint16_t tmplen = 0; 98dd0191d5SShuanglin Wang uint16_t idx = 0; 99dd0191d5SShuanglin Wang enum bnxt_ulp_byte_order key_byte_order; 100dd0191d5SShuanglin Wang 101dd0191d5SShuanglin Wang /* Set the key and mask to the original key and mask. */ 102dd0191d5SShuanglin Wang key = &okey; 103dd0191d5SShuanglin Wang mask = &omask; 104dd0191d5SShuanglin Wang 105dd0191d5SShuanglin Wang /* Skip this tcam table opcode is NOP */ 106dd0191d5SShuanglin Wang if (tbl->tbl_opcode == BNXT_ULP_TCAM_TBL_OPC_NOT_USED || 107dd0191d5SShuanglin Wang tbl->tbl_opcode >= BNXT_ULP_TCAM_TBL_OPC_LAST) { 108dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid tcam table opcode %d\n", 109dd0191d5SShuanglin Wang tbl->tbl_opcode); 110dd0191d5SShuanglin Wang return 0; 111dd0191d5SShuanglin Wang } 112dd0191d5SShuanglin Wang 113dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx, tbl->session_type); 114dd0191d5SShuanglin Wang if (!tfp) { 115dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get truflow pointer\n"); 116dd0191d5SShuanglin Wang return -EINVAL; 117dd0191d5SShuanglin Wang } 118dd0191d5SShuanglin Wang 119dd0191d5SShuanglin Wang /* If only allocation of identifier then perform and exit */ 120dd0191d5SShuanglin Wang if (tbl->tbl_opcode == BNXT_ULP_TCAM_TBL_OPC_ALLOC_IDENT) { 121dd0191d5SShuanglin Wang rc = ulp_mapper_tcam_tbl_ident_alloc(parms, tbl); 122dd0191d5SShuanglin Wang return rc; 123dd0191d5SShuanglin Wang } 124dd0191d5SShuanglin Wang 125dd0191d5SShuanglin Wang if (tbl->key_recipe_opcode == BNXT_ULP_KEY_RECIPE_OPC_DYN_KEY) 126dd0191d5SShuanglin Wang kflds = ulp_mapper_key_recipe_fields_get(parms, tbl, &num_kflds); 127dd0191d5SShuanglin Wang else 128dd0191d5SShuanglin Wang kflds = ulp_mapper_key_fields_get(parms, tbl, &num_kflds); 129dd0191d5SShuanglin Wang if (!kflds || !num_kflds) { 130dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get key fields\n"); 131dd0191d5SShuanglin Wang return -EINVAL; 132dd0191d5SShuanglin Wang } 133dd0191d5SShuanglin Wang 134dd0191d5SShuanglin Wang if (ulp_mapper_tf_tcam_is_wc_tcam(tbl)) 135dd0191d5SShuanglin Wang key_byte_order = dparms->wc_key_byte_order; 136dd0191d5SShuanglin Wang else 137dd0191d5SShuanglin Wang key_byte_order = dparms->key_byte_order; 138dd0191d5SShuanglin Wang 139c569279aSShuanglin Wang if (ulp_blob_init(key, tbl->blob_key_bit_size, key_byte_order) || 140c569279aSShuanglin Wang ulp_blob_init(mask, tbl->blob_key_bit_size, key_byte_order) || 141c569279aSShuanglin Wang ulp_blob_init(&data, tbl->result_bit_size, 142dd0191d5SShuanglin Wang dparms->result_byte_order) || 143c569279aSShuanglin Wang ulp_blob_init(&update_data, tbl->result_bit_size, 144dd0191d5SShuanglin Wang dparms->result_byte_order)) { 145dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "blob inits failed.\n"); 146dd0191d5SShuanglin Wang return -EINVAL; 147dd0191d5SShuanglin Wang } 148dd0191d5SShuanglin Wang 149dd0191d5SShuanglin Wang /* create the key/mask */ 150dd0191d5SShuanglin Wang /* 151dd0191d5SShuanglin Wang * NOTE: The WC table will require some kind of flag to handle the 152dd0191d5SShuanglin Wang * mode bits within the key/mask 153dd0191d5SShuanglin Wang */ 154dd0191d5SShuanglin Wang for (i = 0; i < num_kflds; i++) { 155dd0191d5SShuanglin Wang /* Setup the key */ 156dd0191d5SShuanglin Wang rc = ulp_mapper_field_opc_process(parms, tbl->direction, 157dd0191d5SShuanglin Wang &kflds[i].field_info_spec, 158dd0191d5SShuanglin Wang key, 1, "TCAM Key"); 159dd0191d5SShuanglin Wang if (rc) { 160dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Key field set failed %s\n", 161dd0191d5SShuanglin Wang kflds[i].field_info_spec.description); 162dd0191d5SShuanglin Wang return rc; 163dd0191d5SShuanglin Wang } 164dd0191d5SShuanglin Wang 165dd0191d5SShuanglin Wang /* Setup the mask */ 166dd0191d5SShuanglin Wang rc = ulp_mapper_field_opc_process(parms, tbl->direction, 167dd0191d5SShuanglin Wang &kflds[i].field_info_mask, 168dd0191d5SShuanglin Wang mask, 0, "TCAM Mask"); 169dd0191d5SShuanglin Wang if (rc) { 170dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Mask field set failed %s\n", 171dd0191d5SShuanglin Wang kflds[i].field_info_mask.description); 172dd0191d5SShuanglin Wang return rc; 173dd0191d5SShuanglin Wang } 174dd0191d5SShuanglin Wang } 175dd0191d5SShuanglin Wang 176dd0191d5SShuanglin Wang /* For wild card tcam perform the post process to swap the blob */ 177dd0191d5SShuanglin Wang if (ulp_mapper_tf_tcam_is_wc_tcam(tbl)) { 178dd0191d5SShuanglin Wang if (dparms->wc_dynamic_pad_en) { 179dd0191d5SShuanglin Wang /* Sets up the slices for writing to the WC TCAM */ 180dd0191d5SShuanglin Wang rc = ulp_mapper_wc_tcam_tbl_dyn_post_process(dparms, 181dd0191d5SShuanglin Wang key, mask, 182dd0191d5SShuanglin Wang &tkey, 183dd0191d5SShuanglin Wang &tmask); 184dd0191d5SShuanglin Wang if (rc) { 185dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 186dd0191d5SShuanglin Wang "Failed to post proc WC entry.\n"); 187dd0191d5SShuanglin Wang return rc; 188dd0191d5SShuanglin Wang } 189dd0191d5SShuanglin Wang /* Now need to use the transform Key/Mask */ 190dd0191d5SShuanglin Wang key = &tkey; 191dd0191d5SShuanglin Wang mask = &tmask; 192dd0191d5SShuanglin Wang } else { 193dd0191d5SShuanglin Wang ulp_mapper_wc_tcam_tbl_post_process(key); 194dd0191d5SShuanglin Wang ulp_mapper_wc_tcam_tbl_post_process(mask); 195dd0191d5SShuanglin Wang } 196dd0191d5SShuanglin Wang } 197dd0191d5SShuanglin Wang 198dd0191d5SShuanglin Wang if (tbl->tbl_opcode == BNXT_ULP_TCAM_TBL_OPC_ALLOC_WR_REGFILE) { 199dd0191d5SShuanglin Wang /* allocate the tcam index */ 200dd0191d5SShuanglin Wang aparms.dir = tbl->direction; 201dd0191d5SShuanglin Wang aparms.tcam_tbl_type = tbl->resource_type; 202dd0191d5SShuanglin Wang aparms.key = ulp_blob_data_get(key, &tmplen); 203dd0191d5SShuanglin Wang aparms.key_sz_in_bits = tmplen; 204dd0191d5SShuanglin Wang aparms.mask = ulp_blob_data_get(mask, &tmplen); 205dd0191d5SShuanglin Wang 206dd0191d5SShuanglin Wang /* calculate the entry priority */ 207dd0191d5SShuanglin Wang rc = ulp_mapper_priority_opc_process(parms, tbl, 208dd0191d5SShuanglin Wang &aparms.priority); 209dd0191d5SShuanglin Wang if (rc) { 210dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "entry priority process failed\n"); 211dd0191d5SShuanglin Wang return rc; 212dd0191d5SShuanglin Wang } 213dd0191d5SShuanglin Wang 214dd0191d5SShuanglin Wang rc = tf_alloc_tcam_entry(tfp, &aparms); 215dd0191d5SShuanglin Wang if (rc) { 216dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "tcam alloc failed rc=%d.\n", rc); 217dd0191d5SShuanglin Wang return rc; 218dd0191d5SShuanglin Wang } 219dd0191d5SShuanglin Wang idx = aparms.idx; 220dd0191d5SShuanglin Wang } 221dd0191d5SShuanglin Wang 222dd0191d5SShuanglin Wang /* Write the tcam index into the regfile*/ 223dd0191d5SShuanglin Wang if (ulp_regfile_write(parms->regfile, tbl->tbl_operand, 224dd0191d5SShuanglin Wang (uint64_t)tfp_cpu_to_be_64(idx))) { 225dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Regfile[%d] write failed.\n", 226dd0191d5SShuanglin Wang tbl->tbl_operand); 227dd0191d5SShuanglin Wang rc = -EINVAL; 228dd0191d5SShuanglin Wang /* Need to free the tcam idx, so goto error */ 229dd0191d5SShuanglin Wang goto error; 230dd0191d5SShuanglin Wang } 231dd0191d5SShuanglin Wang 232dd0191d5SShuanglin Wang /* if it is miss then it is same as no search before alloc */ 233dd0191d5SShuanglin Wang if (tbl->tbl_opcode == BNXT_ULP_TCAM_TBL_OPC_ALLOC_WR_REGFILE) { 234dd0191d5SShuanglin Wang /*Scan identifier list, allocate identifier and update regfile*/ 235dd0191d5SShuanglin Wang rc = ulp_mapper_tcam_tbl_ident_alloc(parms, tbl); 236dd0191d5SShuanglin Wang /* Create the result blob */ 237dd0191d5SShuanglin Wang if (!rc) 238dd0191d5SShuanglin Wang rc = ulp_mapper_tbl_result_build(parms, tbl, &data, 239dd0191d5SShuanglin Wang "TCAM Result"); 240dd0191d5SShuanglin Wang /* write the tcam entry */ 241dd0191d5SShuanglin Wang if (!rc) 242dd0191d5SShuanglin Wang rc = ulp_mapper_tf_tcam_tbl_entry_write(parms, tbl, key, 243dd0191d5SShuanglin Wang mask, &data, 244dd0191d5SShuanglin Wang idx); 245dd0191d5SShuanglin Wang } 246dd0191d5SShuanglin Wang 247dd0191d5SShuanglin Wang if (rc) 248dd0191d5SShuanglin Wang goto error; 249dd0191d5SShuanglin Wang 250dd0191d5SShuanglin Wang /* Add the tcam index to the flow database */ 251dd0191d5SShuanglin Wang fid_parms.direction = tbl->direction; 252dd0191d5SShuanglin Wang fid_parms.resource_func = tbl->resource_func; 253dd0191d5SShuanglin Wang fid_parms.resource_type = tbl->resource_type; 254dd0191d5SShuanglin Wang fid_parms.critical_resource = tbl->critical_resource; 255dd0191d5SShuanglin Wang fid_parms.resource_hndl = idx; 256dd0191d5SShuanglin Wang ulp_flow_db_shared_session_set(&fid_parms, tbl->session_type); 257dd0191d5SShuanglin Wang 258dd0191d5SShuanglin Wang rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 259dd0191d5SShuanglin Wang if (rc) { 260dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to link resource to flow rc = %d\n", 261dd0191d5SShuanglin Wang rc); 262dd0191d5SShuanglin Wang /* Need to free the identifier, so goto error */ 263dd0191d5SShuanglin Wang goto error; 264dd0191d5SShuanglin Wang } 265dd0191d5SShuanglin Wang 266dd0191d5SShuanglin Wang return 0; 267dd0191d5SShuanglin Wang error: 268dd0191d5SShuanglin Wang free_parms.dir = tbl->direction; 269dd0191d5SShuanglin Wang free_parms.tcam_tbl_type = tbl->resource_type; 270dd0191d5SShuanglin Wang free_parms.idx = idx; 271dd0191d5SShuanglin Wang trc = tf_free_tcam_entry(tfp, &free_parms); 272dd0191d5SShuanglin Wang if (trc) 273dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to free tcam[%d][%d][%d] on failure\n", 274dd0191d5SShuanglin Wang tbl->resource_type, tbl->direction, idx); 275dd0191d5SShuanglin Wang return rc; 276dd0191d5SShuanglin Wang } 277dd0191d5SShuanglin Wang 278dd0191d5SShuanglin Wang static int32_t 279dd0191d5SShuanglin Wang ulp_mapper_tf_em_tbl_process(struct bnxt_ulp_mapper_parms *parms, 280dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl, 281af50070eSKishore Padmanabha void *error) 282dd0191d5SShuanglin Wang { 283dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_key_info *kflds; 284dd0191d5SShuanglin Wang struct ulp_blob key, data; 285dd0191d5SShuanglin Wang uint32_t i, num_kflds; 286dd0191d5SShuanglin Wang uint16_t tmplen; 287dd0191d5SShuanglin Wang struct tf *tfp; 288dd0191d5SShuanglin Wang struct ulp_flow_db_res_params fid_parms = { 0 }; 289dd0191d5SShuanglin Wang struct tf_insert_em_entry_parms iparms = { 0 }; 290dd0191d5SShuanglin Wang struct tf_delete_em_entry_parms free_parms = { 0 }; 291dd0191d5SShuanglin Wang enum bnxt_ulp_flow_mem_type mtype; 292dd0191d5SShuanglin Wang struct bnxt_ulp_device_params *dparms = parms->device_params; 293dd0191d5SShuanglin Wang int32_t trc; 294dd0191d5SShuanglin Wang int32_t rc = 0; 295dd0191d5SShuanglin Wang int32_t pad = 0; 296dd0191d5SShuanglin Wang enum bnxt_ulp_byte_order key_order, res_order; 297dd0191d5SShuanglin Wang 298dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx, tbl->session_type); 299dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_mem_type_get(parms->ulp_ctx, &mtype); 300dd0191d5SShuanglin Wang if (rc) { 301dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get the mem type for EM\n"); 302dd0191d5SShuanglin Wang return -EINVAL; 303dd0191d5SShuanglin Wang } 304dd0191d5SShuanglin Wang 305dd0191d5SShuanglin Wang if (tbl->key_recipe_opcode == BNXT_ULP_KEY_RECIPE_OPC_DYN_KEY) 306dd0191d5SShuanglin Wang kflds = ulp_mapper_key_recipe_fields_get(parms, tbl, &num_kflds); 307dd0191d5SShuanglin Wang else 308dd0191d5SShuanglin Wang kflds = ulp_mapper_key_fields_get(parms, tbl, &num_kflds); 309dd0191d5SShuanglin Wang if (!kflds || !num_kflds) { 310dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get key fields\n"); 311dd0191d5SShuanglin Wang return -EINVAL; 312dd0191d5SShuanglin Wang } 313dd0191d5SShuanglin Wang 314dd0191d5SShuanglin Wang key_order = dparms->em_byte_order; 315dd0191d5SShuanglin Wang res_order = dparms->em_byte_order; 316dd0191d5SShuanglin Wang 317dd0191d5SShuanglin Wang /* Initialize the key/result blobs */ 318c569279aSShuanglin Wang if (ulp_blob_init(&key, tbl->blob_key_bit_size, key_order) || 319c569279aSShuanglin Wang ulp_blob_init(&data, tbl->result_bit_size, res_order)) { 320dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "blob inits failed.\n"); 321dd0191d5SShuanglin Wang return -EINVAL; 322dd0191d5SShuanglin Wang } 323dd0191d5SShuanglin Wang 324dd0191d5SShuanglin Wang /* create the key */ 325dd0191d5SShuanglin Wang for (i = 0; i < num_kflds; i++) { 326dd0191d5SShuanglin Wang /* Setup the key */ 327dd0191d5SShuanglin Wang rc = ulp_mapper_field_opc_process(parms, tbl->direction, 328dd0191d5SShuanglin Wang &kflds[i].field_info_spec, 329dd0191d5SShuanglin Wang &key, 1, "EM Key"); 330dd0191d5SShuanglin Wang if (rc) { 331dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Key field set failed.\n"); 332dd0191d5SShuanglin Wang return rc; 333dd0191d5SShuanglin Wang } 334dd0191d5SShuanglin Wang } 335dd0191d5SShuanglin Wang 336dd0191d5SShuanglin Wang /* if dynamic padding is enabled then add padding to result data */ 337dd0191d5SShuanglin Wang if (dparms->em_dynamic_pad_en) { 338dd0191d5SShuanglin Wang /* add padding to make sure key is at byte boundary */ 339dd0191d5SShuanglin Wang ulp_blob_pad_align(&key, ULP_BUFFER_ALIGN_8_BITS); 340dd0191d5SShuanglin Wang 341dd0191d5SShuanglin Wang /* add the pad */ 342dd0191d5SShuanglin Wang pad = dparms->em_blk_align_bits - dparms->em_blk_size_bits; 343dd0191d5SShuanglin Wang if (pad < 0) { 344dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid em blk size and align\n"); 345dd0191d5SShuanglin Wang return -EINVAL; 346dd0191d5SShuanglin Wang } 347dd0191d5SShuanglin Wang ulp_blob_pad_push(&data, (uint32_t)pad); 348dd0191d5SShuanglin Wang } 349dd0191d5SShuanglin Wang 350dd0191d5SShuanglin Wang /* Create the result data blob */ 351dd0191d5SShuanglin Wang rc = ulp_mapper_tbl_result_build(parms, tbl, &data, "EM Result"); 352dd0191d5SShuanglin Wang if (rc) { 353dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to build the result blob\n"); 354dd0191d5SShuanglin Wang return rc; 355dd0191d5SShuanglin Wang } 356dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 357dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 358dd0191d5SShuanglin Wang ulp_mapper_result_dump("EM Result", tbl, &data); 359dd0191d5SShuanglin Wang #endif 360dd0191d5SShuanglin Wang #endif 361dd0191d5SShuanglin Wang if (dparms->em_dynamic_pad_en) { 362dd0191d5SShuanglin Wang uint32_t abits = dparms->em_blk_align_bits; 363dd0191d5SShuanglin Wang 364dd0191d5SShuanglin Wang /* when dynamic padding is enabled merge result + key */ 365dd0191d5SShuanglin Wang rc = ulp_blob_block_merge(&data, &key, abits, pad); 366dd0191d5SShuanglin Wang if (rc) { 367dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to merge the result blob\n"); 368dd0191d5SShuanglin Wang return rc; 369dd0191d5SShuanglin Wang } 370dd0191d5SShuanglin Wang 371dd0191d5SShuanglin Wang /* add padding to make sure merged result is at slice boundary*/ 372dd0191d5SShuanglin Wang ulp_blob_pad_align(&data, abits); 373dd0191d5SShuanglin Wang 374dd0191d5SShuanglin Wang ulp_blob_perform_byte_reverse(&data, ULP_BITS_2_BYTE(abits)); 375dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 376dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 377dd0191d5SShuanglin Wang ulp_mapper_result_dump("EM Merged Result", tbl, &data); 378dd0191d5SShuanglin Wang #endif 379dd0191d5SShuanglin Wang #endif 380dd0191d5SShuanglin Wang } 381dd0191d5SShuanglin Wang 382dd0191d5SShuanglin Wang /* do the transpose for the internal EM keys */ 383dd0191d5SShuanglin Wang if (tbl->resource_type == TF_MEM_INTERNAL) { 384dd0191d5SShuanglin Wang if (dparms->em_key_align_bytes) { 385dd0191d5SShuanglin Wang int32_t b = ULP_BYTE_2_BITS(dparms->em_key_align_bytes); 386dd0191d5SShuanglin Wang 387dd0191d5SShuanglin Wang tmplen = ulp_blob_data_len_get(&key); 388dd0191d5SShuanglin Wang ulp_blob_pad_push(&key, b - tmplen); 389dd0191d5SShuanglin Wang } 390dd0191d5SShuanglin Wang tmplen = ulp_blob_data_len_get(&key); 391dd0191d5SShuanglin Wang ulp_blob_perform_byte_reverse(&key, ULP_BITS_2_BYTE(tmplen)); 392dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 393dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 394dd0191d5SShuanglin Wang ulp_mapper_result_dump("EM Key Transpose", tbl, &key); 395dd0191d5SShuanglin Wang #endif 396dd0191d5SShuanglin Wang #endif 397dd0191d5SShuanglin Wang } 398dd0191d5SShuanglin Wang 399dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_tbl_scope_id_get(parms->ulp_ctx, 400dd0191d5SShuanglin Wang &iparms.tbl_scope_id); 401dd0191d5SShuanglin Wang if (rc) { 402dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get table scope rc=%d\n", rc); 403dd0191d5SShuanglin Wang return rc; 404dd0191d5SShuanglin Wang } 405dd0191d5SShuanglin Wang 406dd0191d5SShuanglin Wang /* 407dd0191d5SShuanglin Wang * NOTE: the actual blob size will differ from the size in the tbl 408dd0191d5SShuanglin Wang * entry due to the padding. 409dd0191d5SShuanglin Wang */ 410dd0191d5SShuanglin Wang iparms.dup_check = 0; 411dd0191d5SShuanglin Wang iparms.dir = tbl->direction; 412dd0191d5SShuanglin Wang iparms.mem = tbl->resource_type; 413dd0191d5SShuanglin Wang iparms.key = ulp_blob_data_get(&key, &tmplen); 414dd0191d5SShuanglin Wang iparms.key_sz_in_bits = tbl->key_bit_size; 415dd0191d5SShuanglin Wang iparms.em_record = ulp_blob_data_get(&data, &tmplen); 416dd0191d5SShuanglin Wang if (tbl->result_bit_size) 417dd0191d5SShuanglin Wang iparms.em_record_sz_in_bits = tbl->result_bit_size; 418dd0191d5SShuanglin Wang else 419dd0191d5SShuanglin Wang iparms.em_record_sz_in_bits = tmplen; 420dd0191d5SShuanglin Wang 421dd0191d5SShuanglin Wang rc = tf_insert_em_entry(tfp, &iparms); 422dd0191d5SShuanglin Wang if (rc) { 423af50070eSKishore Padmanabha /* Set the error flag in reg file */ 424af50070eSKishore Padmanabha if (tbl->tbl_opcode == BNXT_ULP_EM_TBL_OPC_WR_REGFILE) { 425af50070eSKishore Padmanabha uint64_t val = 0; 426af50070eSKishore Padmanabha 427af50070eSKishore Padmanabha /* over max flows or hash collision */ 428af50070eSKishore Padmanabha if (rc == -EIO || rc == -ENOMEM) { 429af50070eSKishore Padmanabha val = 1; 430af50070eSKishore Padmanabha rc = 0; 431af50070eSKishore Padmanabha BNXT_DRV_DBG(DEBUG, 432af50070eSKishore Padmanabha "Fail to insert EM, shall add to wc\n"); 433af50070eSKishore Padmanabha } 434af50070eSKishore Padmanabha ulp_regfile_write(parms->regfile, tbl->tbl_operand, 435af50070eSKishore Padmanabha tfp_cpu_to_be_64(val)); 436af50070eSKishore Padmanabha } 437af50070eSKishore Padmanabha if (rc) 438af50070eSKishore Padmanabha BNXT_DRV_DBG(ERR, 439af50070eSKishore Padmanabha "Failed to insert em entry rc=%d.\n", rc); 440af50070eSKishore Padmanabha if (rc && error != NULL) 441af50070eSKishore Padmanabha rte_flow_error_set((struct rte_flow_error *)error, EIO, 442af50070eSKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 443af50070eSKishore Padmanabha "error adding EM entry"); 444dd0191d5SShuanglin Wang return rc; 445dd0191d5SShuanglin Wang } 446dd0191d5SShuanglin Wang 447dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 448dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 449dd0191d5SShuanglin Wang ulp_mapper_em_dump("EM", &key, &data, &iparms); 450dd0191d5SShuanglin Wang /* tf_dump_tables(tfp, iparms.tbl_scope_id); */ 451dd0191d5SShuanglin Wang #endif 452dd0191d5SShuanglin Wang #endif 453dd0191d5SShuanglin Wang /* Mark action process */ 454dd0191d5SShuanglin Wang if (mtype == BNXT_ULP_FLOW_MEM_TYPE_EXT && 455dd0191d5SShuanglin Wang tbl->resource_type == TF_MEM_EXTERNAL) 456dd0191d5SShuanglin Wang rc = ulp_mapper_mark_gfid_process(parms, tbl, iparms.flow_id); 457dd0191d5SShuanglin Wang else if (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT && 458dd0191d5SShuanglin Wang tbl->resource_type == TF_MEM_INTERNAL) 459dd0191d5SShuanglin Wang rc = ulp_mapper_mark_act_ptr_process(parms, tbl); 460dd0191d5SShuanglin Wang if (rc) { 461dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to add mark to flow\n"); 462dd0191d5SShuanglin Wang goto error; 463dd0191d5SShuanglin Wang } 464dd0191d5SShuanglin Wang 465dd0191d5SShuanglin Wang /* Link the EM resource to the flow in the flow db */ 466dd0191d5SShuanglin Wang memset(&fid_parms, 0, sizeof(fid_parms)); 467dd0191d5SShuanglin Wang fid_parms.direction = tbl->direction; 468dd0191d5SShuanglin Wang fid_parms.resource_func = tbl->resource_func; 469dd0191d5SShuanglin Wang fid_parms.resource_type = tbl->resource_type; 470dd0191d5SShuanglin Wang fid_parms.critical_resource = tbl->critical_resource; 471dd0191d5SShuanglin Wang fid_parms.resource_hndl = iparms.flow_handle; 472dd0191d5SShuanglin Wang 473dd0191d5SShuanglin Wang rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 474dd0191d5SShuanglin Wang if (rc) { 475dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Fail to link res to flow rc = %d\n", 476dd0191d5SShuanglin Wang rc); 477dd0191d5SShuanglin Wang /* Need to free the identifier, so goto error */ 478dd0191d5SShuanglin Wang goto error; 479dd0191d5SShuanglin Wang } 480dd0191d5SShuanglin Wang 481dd0191d5SShuanglin Wang return 0; 482dd0191d5SShuanglin Wang error: 483dd0191d5SShuanglin Wang free_parms.dir = iparms.dir; 484dd0191d5SShuanglin Wang free_parms.mem = iparms.mem; 485dd0191d5SShuanglin Wang free_parms.tbl_scope_id = iparms.tbl_scope_id; 486dd0191d5SShuanglin Wang free_parms.flow_handle = iparms.flow_handle; 487dd0191d5SShuanglin Wang 488dd0191d5SShuanglin Wang trc = tf_delete_em_entry(tfp, &free_parms); 489dd0191d5SShuanglin Wang if (trc) 490dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to delete EM entry on failed add\n"); 491dd0191d5SShuanglin Wang 492af50070eSKishore Padmanabha if (error != NULL) 493af50070eSKishore Padmanabha rte_flow_error_set((struct rte_flow_error *)error, EIO, 494af50070eSKishore Padmanabha RTE_FLOW_ERROR_TYPE_HANDLE, NULL, 495af50070eSKishore Padmanabha "error adding EM entry"); 496dd0191d5SShuanglin Wang return rc; 497dd0191d5SShuanglin Wang } 498dd0191d5SShuanglin Wang 499dd0191d5SShuanglin Wang static uint16_t 500dd0191d5SShuanglin Wang ulp_mapper_tf_dyn_blob_size_get(struct bnxt_ulp_mapper_parms *mparms, 501dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl) 502dd0191d5SShuanglin Wang { 503dd0191d5SShuanglin Wang struct bnxt_ulp_device_params *d_params = mparms->device_params; 504dd0191d5SShuanglin Wang 505dd0191d5SShuanglin Wang if (d_params->dynamic_sram_en) { 506dd0191d5SShuanglin Wang switch (tbl->resource_type) { 507dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_ENCAP_8B: 508dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_ENCAP_16B: 509dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_ENCAP_32B: 510dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_ENCAP_64B: 511dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_MODIFY_8B: 512dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_MODIFY_16B: 513dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_MODIFY_32B: 514dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_MODIFY_64B: 515dd0191d5SShuanglin Wang /* return max size */ 516dd0191d5SShuanglin Wang return BNXT_ULP_FLMP_BLOB_SIZE_IN_BITS; 517dd0191d5SShuanglin Wang default: 518dd0191d5SShuanglin Wang break; 519dd0191d5SShuanglin Wang } 520dd0191d5SShuanglin Wang } else if (tbl->encap_num_fields) { 521dd0191d5SShuanglin Wang return BNXT_ULP_FLMP_BLOB_SIZE_IN_BITS; 522dd0191d5SShuanglin Wang } 523dd0191d5SShuanglin Wang return tbl->result_bit_size; 524dd0191d5SShuanglin Wang } 525dd0191d5SShuanglin Wang 526dd0191d5SShuanglin Wang static int32_t 527dd0191d5SShuanglin Wang ulp_mapper_tf_em_entry_free(struct bnxt_ulp_context *ulp, 528dd0191d5SShuanglin Wang struct ulp_flow_db_res_params *res, 529dd0191d5SShuanglin Wang __rte_unused void *error) 530dd0191d5SShuanglin Wang { 531dd0191d5SShuanglin Wang struct tf_delete_em_entry_parms fparms = { 0 }; 532dd0191d5SShuanglin Wang struct tf *tfp; 533dd0191d5SShuanglin Wang uint32_t session_type; 534dd0191d5SShuanglin Wang int32_t rc; 535dd0191d5SShuanglin Wang 536dd0191d5SShuanglin Wang session_type = ulp_flow_db_shared_session_get(res); 537dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(ulp, session_type); 538dd0191d5SShuanglin Wang if (!tfp) { 539dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get tf pointer\n"); 540dd0191d5SShuanglin Wang return -EINVAL; 541dd0191d5SShuanglin Wang } 542dd0191d5SShuanglin Wang 543dd0191d5SShuanglin Wang fparms.dir = res->direction; 544dd0191d5SShuanglin Wang fparms.flow_handle = res->resource_hndl; 545dd0191d5SShuanglin Wang 546dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp, &fparms.tbl_scope_id); 547dd0191d5SShuanglin Wang if (rc) { 548dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get table scope\n"); 549dd0191d5SShuanglin Wang return -EINVAL; 550dd0191d5SShuanglin Wang } 551dd0191d5SShuanglin Wang 552dd0191d5SShuanglin Wang return tf_delete_em_entry(tfp, &fparms); 553dd0191d5SShuanglin Wang } 554dd0191d5SShuanglin Wang 555dd0191d5SShuanglin Wang static uint32_t 556dd0191d5SShuanglin Wang ulp_mapper_tf_dyn_tbl_type_get(struct bnxt_ulp_mapper_parms *mparms, 557dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl, 558dd0191d5SShuanglin Wang uint16_t blob_len, 559dd0191d5SShuanglin Wang uint16_t *out_len) 560dd0191d5SShuanglin Wang { 561dd0191d5SShuanglin Wang struct bnxt_ulp_device_params *d_params = mparms->device_params; 562dd0191d5SShuanglin Wang struct bnxt_ulp_dyn_size_map *size_map; 563dd0191d5SShuanglin Wang uint32_t i; 564dd0191d5SShuanglin Wang 565dd0191d5SShuanglin Wang if (d_params->dynamic_sram_en) { 566dd0191d5SShuanglin Wang switch (tbl->resource_type) { 567dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_ENCAP_8B: 568dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_ENCAP_16B: 569dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_ENCAP_32B: 570dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_ENCAP_64B: 571dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_ENCAP_128B: 572dd0191d5SShuanglin Wang size_map = d_params->dyn_encap_sizes; 573dd0191d5SShuanglin Wang for (i = 0; i < d_params->dyn_encap_list_size; i++) { 574dd0191d5SShuanglin Wang if (blob_len <= size_map[i].slab_size) { 575dd0191d5SShuanglin Wang *out_len = size_map[i].slab_size; 576dd0191d5SShuanglin Wang return size_map[i].tbl_type; 577dd0191d5SShuanglin Wang } 578dd0191d5SShuanglin Wang } 579dd0191d5SShuanglin Wang break; 580dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_MODIFY_8B: 581dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_MODIFY_16B: 582dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_MODIFY_32B: 583dd0191d5SShuanglin Wang case TF_TBL_TYPE_ACT_MODIFY_64B: 584dd0191d5SShuanglin Wang size_map = d_params->dyn_modify_sizes; 585dd0191d5SShuanglin Wang for (i = 0; i < d_params->dyn_modify_list_size; i++) { 586dd0191d5SShuanglin Wang if (blob_len <= size_map[i].slab_size) { 587dd0191d5SShuanglin Wang *out_len = size_map[i].slab_size; 588dd0191d5SShuanglin Wang return size_map[i].tbl_type; 589dd0191d5SShuanglin Wang } 590dd0191d5SShuanglin Wang } 591dd0191d5SShuanglin Wang break; 592dd0191d5SShuanglin Wang default: 593dd0191d5SShuanglin Wang break; 594dd0191d5SShuanglin Wang } 595dd0191d5SShuanglin Wang } 596dd0191d5SShuanglin Wang return tbl->resource_type; 597dd0191d5SShuanglin Wang } 598dd0191d5SShuanglin Wang 599dd0191d5SShuanglin Wang static int32_t 600dd0191d5SShuanglin Wang ulp_mapper_tf_index_tbl_process(struct bnxt_ulp_mapper_parms *parms, 601dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl) 602dd0191d5SShuanglin Wang { 603dd0191d5SShuanglin Wang struct ulp_flow_db_res_params fid_parms; 604dd0191d5SShuanglin Wang struct ulp_blob data; 605dd0191d5SShuanglin Wang uint64_t regval = 0; 606dd0191d5SShuanglin Wang uint16_t tmplen; 607dd0191d5SShuanglin Wang uint32_t index; 608dd0191d5SShuanglin Wang int32_t rc = 0, trc = 0; 609dd0191d5SShuanglin Wang struct tf_alloc_tbl_entry_parms aparms = { 0 }; 610dd0191d5SShuanglin Wang struct tf_set_tbl_entry_parms sparms = { 0 }; 611dd0191d5SShuanglin Wang struct tf_get_tbl_entry_parms gparms = { 0 }; 612dd0191d5SShuanglin Wang struct tf_free_tbl_entry_parms free_parms = { 0 }; 613dd0191d5SShuanglin Wang uint32_t tbl_scope_id; 614dd0191d5SShuanglin Wang struct tf *tfp; 615dd0191d5SShuanglin Wang struct bnxt_ulp_glb_resource_info glb_res = { 0 }; 616dd0191d5SShuanglin Wang uint16_t bit_size; 617dd0191d5SShuanglin Wang bool alloc = false; 618dd0191d5SShuanglin Wang bool write = false; 619dd0191d5SShuanglin Wang bool global = false; 620dd0191d5SShuanglin Wang uint64_t act_rec_size; 621dd0191d5SShuanglin Wang bool shared = false; 622dd0191d5SShuanglin Wang enum tf_tbl_type tbl_type = tbl->resource_type; 623dd0191d5SShuanglin Wang uint16_t blob_len; 624dd0191d5SShuanglin Wang 625dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx, tbl->session_type); 626dd0191d5SShuanglin Wang /* compute the blob size */ 627dd0191d5SShuanglin Wang bit_size = ulp_mapper_tf_dyn_blob_size_get(parms, tbl); 628dd0191d5SShuanglin Wang 629dd0191d5SShuanglin Wang /* Initialize the blob data */ 630c569279aSShuanglin Wang if (ulp_blob_init(&data, bit_size, 631dd0191d5SShuanglin Wang parms->device_params->result_byte_order)) { 632dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to initialize index table blob\n"); 633dd0191d5SShuanglin Wang return -EINVAL; 634dd0191d5SShuanglin Wang } 635dd0191d5SShuanglin Wang 636dd0191d5SShuanglin Wang /* Get the scope id first */ 637dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_tbl_scope_id_get(parms->ulp_ctx, &tbl_scope_id); 638dd0191d5SShuanglin Wang if (rc) { 639dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get table scope rc=%d\n", rc); 640dd0191d5SShuanglin Wang return rc; 641dd0191d5SShuanglin Wang } 642dd0191d5SShuanglin Wang 643dd0191d5SShuanglin Wang switch (tbl->tbl_opcode) { 644dd0191d5SShuanglin Wang case BNXT_ULP_INDEX_TBL_OPC_ALLOC_REGFILE: 645dd0191d5SShuanglin Wang alloc = true; 646dd0191d5SShuanglin Wang break; 647dd0191d5SShuanglin Wang case BNXT_ULP_INDEX_TBL_OPC_ALLOC_WR_REGFILE: 648dd0191d5SShuanglin Wang /* 649dd0191d5SShuanglin Wang * Build the entry, alloc an index, write the table, and store 650dd0191d5SShuanglin Wang * the data in the regfile. 651dd0191d5SShuanglin Wang */ 652dd0191d5SShuanglin Wang alloc = true; 653dd0191d5SShuanglin Wang write = true; 654dd0191d5SShuanglin Wang break; 655dd0191d5SShuanglin Wang case BNXT_ULP_INDEX_TBL_OPC_WR_REGFILE: 656dd0191d5SShuanglin Wang /* 657dd0191d5SShuanglin Wang * get the index to write to from the regfile and then write 658dd0191d5SShuanglin Wang * the table entry. 659dd0191d5SShuanglin Wang */ 660c569279aSShuanglin Wang if (ulp_regfile_read(parms->regfile, 661dd0191d5SShuanglin Wang tbl->tbl_operand, 662dd0191d5SShuanglin Wang ®val)) { 663dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 664dd0191d5SShuanglin Wang "Failed to get tbl idx from regfile[%d].\n", 665dd0191d5SShuanglin Wang tbl->tbl_operand); 666dd0191d5SShuanglin Wang return -EINVAL; 667dd0191d5SShuanglin Wang } 668dd0191d5SShuanglin Wang index = tfp_be_to_cpu_64(regval); 669dd0191d5SShuanglin Wang /* For external, we need to reverse shift */ 670dd0191d5SShuanglin Wang if (tbl->resource_type == TF_TBL_TYPE_EXT) 671dd0191d5SShuanglin Wang index = TF_ACT_REC_PTR_2_OFFSET(index); 672dd0191d5SShuanglin Wang 673dd0191d5SShuanglin Wang write = true; 674dd0191d5SShuanglin Wang break; 675dd0191d5SShuanglin Wang case BNXT_ULP_INDEX_TBL_OPC_ALLOC_WR_GLB_REGFILE: 676dd0191d5SShuanglin Wang /* 677dd0191d5SShuanglin Wang * Build the entry, alloc an index, write the table, and store 678dd0191d5SShuanglin Wang * the data in the global regfile. 679dd0191d5SShuanglin Wang */ 680dd0191d5SShuanglin Wang alloc = true; 681dd0191d5SShuanglin Wang global = true; 682dd0191d5SShuanglin Wang write = true; 683dd0191d5SShuanglin Wang glb_res.direction = tbl->direction; 684dd0191d5SShuanglin Wang glb_res.resource_func = tbl->resource_func; 685dd0191d5SShuanglin Wang glb_res.resource_type = tbl->resource_type; 686dd0191d5SShuanglin Wang glb_res.glb_regfile_index = tbl->tbl_operand; 687dd0191d5SShuanglin Wang break; 688dd0191d5SShuanglin Wang case BNXT_ULP_INDEX_TBL_OPC_WR_GLB_REGFILE: 689dd0191d5SShuanglin Wang if (tbl->fdb_opcode != BNXT_ULP_FDB_OPC_NOP) { 690dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Template error, wrong fdb opcode\n"); 691dd0191d5SShuanglin Wang return -EINVAL; 692dd0191d5SShuanglin Wang } 693dd0191d5SShuanglin Wang /* 694dd0191d5SShuanglin Wang * get the index to write to from the global regfile and then 695dd0191d5SShuanglin Wang * write the table. 696dd0191d5SShuanglin Wang */ 697dd0191d5SShuanglin Wang if (ulp_mapper_glb_resource_read(parms->mapper_data, 698dd0191d5SShuanglin Wang tbl->direction, 699dd0191d5SShuanglin Wang tbl->tbl_operand, 700dd0191d5SShuanglin Wang ®val, &shared)) { 701dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 702dd0191d5SShuanglin Wang "Failed to get tbl idx from Glb RF[%d].\n", 703dd0191d5SShuanglin Wang tbl->tbl_operand); 704dd0191d5SShuanglin Wang return -EINVAL; 705dd0191d5SShuanglin Wang } 706dd0191d5SShuanglin Wang index = tfp_be_to_cpu_64(regval); 707dd0191d5SShuanglin Wang /* For external, we need to reverse shift */ 708dd0191d5SShuanglin Wang if (tbl->resource_type == TF_TBL_TYPE_EXT) 709dd0191d5SShuanglin Wang index = TF_ACT_REC_PTR_2_OFFSET(index); 710dd0191d5SShuanglin Wang write = true; 711dd0191d5SShuanglin Wang break; 712dd0191d5SShuanglin Wang case BNXT_ULP_INDEX_TBL_OPC_RD_REGFILE: 713dd0191d5SShuanglin Wang /* 714dd0191d5SShuanglin Wang * The read is different from the rest and can be handled here 715dd0191d5SShuanglin Wang * instead of trying to use common code. Simply read the table 716dd0191d5SShuanglin Wang * with the index from the regfile, scan and store the 717dd0191d5SShuanglin Wang * identifiers, and return. 718dd0191d5SShuanglin Wang */ 719dd0191d5SShuanglin Wang if (tbl->resource_type == TF_TBL_TYPE_EXT) { 720dd0191d5SShuanglin Wang /* Not currently supporting with EXT */ 721dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 722dd0191d5SShuanglin Wang "Ext Table Read Opcode not supported.\n"); 723dd0191d5SShuanglin Wang return -EINVAL; 724dd0191d5SShuanglin Wang } 725c569279aSShuanglin Wang if (ulp_regfile_read(parms->regfile, 726dd0191d5SShuanglin Wang tbl->tbl_operand, ®val)) { 727dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 728dd0191d5SShuanglin Wang "Failed to get tbl idx from regfile[%d]\n", 729dd0191d5SShuanglin Wang tbl->tbl_operand); 730dd0191d5SShuanglin Wang return -EINVAL; 731dd0191d5SShuanglin Wang } 732dd0191d5SShuanglin Wang index = tfp_be_to_cpu_64(regval); 733dd0191d5SShuanglin Wang gparms.dir = tbl->direction; 734dd0191d5SShuanglin Wang gparms.type = tbl->resource_type; 735dd0191d5SShuanglin Wang gparms.data = ulp_blob_data_get(&data, &tmplen); 736dd0191d5SShuanglin Wang gparms.data_sz_in_bytes = ULP_BITS_2_BYTE(tbl->result_bit_size); 737dd0191d5SShuanglin Wang gparms.idx = index; 738dd0191d5SShuanglin Wang rc = tf_get_tbl_entry(tfp, &gparms); 739dd0191d5SShuanglin Wang if (rc) { 740dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 741dd0191d5SShuanglin Wang "Failed to read the tbl entry %d:%d\n", 742dd0191d5SShuanglin Wang tbl->resource_type, index); 743dd0191d5SShuanglin Wang return rc; 744dd0191d5SShuanglin Wang } 745dd0191d5SShuanglin Wang /* 746dd0191d5SShuanglin Wang * Scan the fields in the entry and push them into the regfile. 747dd0191d5SShuanglin Wang */ 748dd0191d5SShuanglin Wang rc = ulp_mapper_tbl_ident_scan_ext(parms, tbl, 749dd0191d5SShuanglin Wang gparms.data, 750dd0191d5SShuanglin Wang gparms.data_sz_in_bytes, 751dd0191d5SShuanglin Wang data.byte_order); 752dd0191d5SShuanglin Wang if (rc) { 753dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 754dd0191d5SShuanglin Wang "Failed to get flds on tbl read rc=%d\n", 755dd0191d5SShuanglin Wang rc); 756dd0191d5SShuanglin Wang return rc; 757dd0191d5SShuanglin Wang } 758dd0191d5SShuanglin Wang return 0; 759dd0191d5SShuanglin Wang default: 760dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid index table opcode %d\n", 761dd0191d5SShuanglin Wang tbl->tbl_opcode); 762dd0191d5SShuanglin Wang return -EINVAL; 763dd0191d5SShuanglin Wang } 764dd0191d5SShuanglin Wang 765dd0191d5SShuanglin Wang if (write) { 766dd0191d5SShuanglin Wang /* Get the result fields list */ 767dd0191d5SShuanglin Wang rc = ulp_mapper_tbl_result_build(parms, 768dd0191d5SShuanglin Wang tbl, 769dd0191d5SShuanglin Wang &data, 770dd0191d5SShuanglin Wang "Indexed Result"); 771dd0191d5SShuanglin Wang if (rc) { 772dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to build the result blob\n"); 773dd0191d5SShuanglin Wang return rc; 774dd0191d5SShuanglin Wang } 775dd0191d5SShuanglin Wang } 776dd0191d5SShuanglin Wang 777dd0191d5SShuanglin Wang if (alloc) { 778dd0191d5SShuanglin Wang aparms.dir = tbl->direction; 779dd0191d5SShuanglin Wang blob_len = ulp_blob_data_len_get(&data); 780dd0191d5SShuanglin Wang tbl_type = ulp_mapper_tf_dyn_tbl_type_get(parms, tbl, 781dd0191d5SShuanglin Wang blob_len, 782dd0191d5SShuanglin Wang &tmplen); 783dd0191d5SShuanglin Wang aparms.type = tbl_type; 784dd0191d5SShuanglin Wang aparms.tbl_scope_id = tbl_scope_id; 785dd0191d5SShuanglin Wang 786dd0191d5SShuanglin Wang /* All failures after the alloc succeeds require a free */ 787dd0191d5SShuanglin Wang rc = tf_alloc_tbl_entry(tfp, &aparms); 788dd0191d5SShuanglin Wang if (rc) { 789dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Alloc table[%s][%s] failed rc=%d\n", 790dd0191d5SShuanglin Wang tf_tbl_type_2_str(aparms.type), 791dd0191d5SShuanglin Wang tf_dir_2_str(tbl->direction), rc); 792dd0191d5SShuanglin Wang return rc; 793dd0191d5SShuanglin Wang } 794dd0191d5SShuanglin Wang index = aparms.idx; 795dd0191d5SShuanglin Wang 796dd0191d5SShuanglin Wang /* 797dd0191d5SShuanglin Wang * Store the index in the regfile since we either allocated it 798dd0191d5SShuanglin Wang * or it was a hit. 799dd0191d5SShuanglin Wang * 800dd0191d5SShuanglin Wang * Calculate the idx for the result record, for external EM the 801dd0191d5SShuanglin Wang * offset needs to be shifted accordingly. 802dd0191d5SShuanglin Wang * If external non-inline table types are used then need to 803dd0191d5SShuanglin Wang * revisit this logic. 804dd0191d5SShuanglin Wang */ 805dd0191d5SShuanglin Wang if (tbl->resource_type == TF_TBL_TYPE_EXT) 806dd0191d5SShuanglin Wang regval = TF_ACT_REC_OFFSET_2_PTR(index); 807dd0191d5SShuanglin Wang else 808dd0191d5SShuanglin Wang regval = index; 809dd0191d5SShuanglin Wang regval = tfp_cpu_to_be_64(regval); 810dd0191d5SShuanglin Wang 811dd0191d5SShuanglin Wang if (global) { 812dd0191d5SShuanglin Wang /* 813dd0191d5SShuanglin Wang * Shared resources are never allocated through this 814dd0191d5SShuanglin Wang * method, so the shared flag is always false. 815dd0191d5SShuanglin Wang */ 816dd0191d5SShuanglin Wang rc = ulp_mapper_glb_resource_write(parms->mapper_data, 817dd0191d5SShuanglin Wang &glb_res, regval, 818dd0191d5SShuanglin Wang false); 819dd0191d5SShuanglin Wang } else { 820dd0191d5SShuanglin Wang rc = ulp_regfile_write(parms->regfile, 821dd0191d5SShuanglin Wang tbl->tbl_operand, regval); 822dd0191d5SShuanglin Wang } 823dd0191d5SShuanglin Wang if (rc) { 824dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 825dd0191d5SShuanglin Wang "Failed to write %s regfile[%d] rc=%d\n", 826dd0191d5SShuanglin Wang (global) ? "global" : "reg", 827dd0191d5SShuanglin Wang tbl->tbl_operand, rc); 828dd0191d5SShuanglin Wang goto error; 829dd0191d5SShuanglin Wang } 830dd0191d5SShuanglin Wang } 831dd0191d5SShuanglin Wang 832dd0191d5SShuanglin Wang if (write) { 833dd0191d5SShuanglin Wang sparms.dir = tbl->direction; 834dd0191d5SShuanglin Wang sparms.data = ulp_blob_data_get(&data, &tmplen); 835dd0191d5SShuanglin Wang blob_len = ulp_blob_data_len_get(&data); 836dd0191d5SShuanglin Wang tbl_type = ulp_mapper_tf_dyn_tbl_type_get(parms, tbl, 837dd0191d5SShuanglin Wang blob_len, 838dd0191d5SShuanglin Wang &tmplen); 839dd0191d5SShuanglin Wang sparms.type = tbl_type; 840dd0191d5SShuanglin Wang sparms.data_sz_in_bytes = ULP_BITS_2_BYTE(tmplen); 841dd0191d5SShuanglin Wang sparms.idx = index; 842dd0191d5SShuanglin Wang sparms.tbl_scope_id = tbl_scope_id; 843dd0191d5SShuanglin Wang if (shared) 844dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx, 845dd0191d5SShuanglin Wang tbl->session_type); 846dd0191d5SShuanglin Wang rc = tf_set_tbl_entry(tfp, &sparms); 847dd0191d5SShuanglin Wang if (rc) { 848dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 849dd0191d5SShuanglin Wang "Index table[%s][%s][%x] write fail rc=%d\n", 850dd0191d5SShuanglin Wang tf_tbl_type_2_str(sparms.type), 851dd0191d5SShuanglin Wang tf_dir_2_str(sparms.dir), 852dd0191d5SShuanglin Wang sparms.idx, rc); 853dd0191d5SShuanglin Wang goto error; 854dd0191d5SShuanglin Wang } 855dd0191d5SShuanglin Wang BNXT_DRV_INF("Index table[%s][%s][%x] write successful.\n", 856dd0191d5SShuanglin Wang tf_tbl_type_2_str(sparms.type), 857dd0191d5SShuanglin Wang tf_dir_2_str(sparms.dir), sparms.idx); 858dd0191d5SShuanglin Wang 859dd0191d5SShuanglin Wang /* Calculate action record size */ 860dd0191d5SShuanglin Wang if (tbl->resource_type == TF_TBL_TYPE_EXT) { 861dd0191d5SShuanglin Wang act_rec_size = (ULP_BITS_2_BYTE_NR(tmplen) + 15) / 16; 862dd0191d5SShuanglin Wang act_rec_size--; 863dd0191d5SShuanglin Wang if (ulp_regfile_write(parms->regfile, 864dd0191d5SShuanglin Wang BNXT_ULP_RF_IDX_ACTION_REC_SIZE, 865dd0191d5SShuanglin Wang tfp_cpu_to_be_64(act_rec_size))) 866dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 867dd0191d5SShuanglin Wang "Failed write the act rec size\n"); 868dd0191d5SShuanglin Wang } 869dd0191d5SShuanglin Wang } 870dd0191d5SShuanglin Wang 871dd0191d5SShuanglin Wang /* Link the resource to the flow in the flow db */ 872dd0191d5SShuanglin Wang memset(&fid_parms, 0, sizeof(fid_parms)); 873dd0191d5SShuanglin Wang fid_parms.direction = tbl->direction; 874dd0191d5SShuanglin Wang fid_parms.resource_func = tbl->resource_func; 875dd0191d5SShuanglin Wang fid_parms.resource_type = tbl_type; 876dd0191d5SShuanglin Wang fid_parms.resource_sub_type = tbl->resource_sub_type; 877dd0191d5SShuanglin Wang fid_parms.resource_hndl = index; 878dd0191d5SShuanglin Wang fid_parms.critical_resource = tbl->critical_resource; 879dd0191d5SShuanglin Wang ulp_flow_db_shared_session_set(&fid_parms, tbl->session_type); 880dd0191d5SShuanglin Wang 881dd0191d5SShuanglin Wang rc = ulp_mapper_fdb_opc_process(parms, tbl, &fid_parms); 882dd0191d5SShuanglin Wang if (rc) { 883dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to link resource to flow rc = %d\n", 884dd0191d5SShuanglin Wang rc); 885dd0191d5SShuanglin Wang goto error; 886dd0191d5SShuanglin Wang } 887dd0191d5SShuanglin Wang 888dd0191d5SShuanglin Wang /* Perform the VF rep action */ 889dd0191d5SShuanglin Wang rc = ulp_mapper_mark_vfr_idx_process(parms, tbl); 890dd0191d5SShuanglin Wang if (rc) { 891dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to add vfr mark rc = %d\n", rc); 892dd0191d5SShuanglin Wang goto error; 893dd0191d5SShuanglin Wang } 894dd0191d5SShuanglin Wang return rc; 895dd0191d5SShuanglin Wang error: 896dd0191d5SShuanglin Wang /* Shared resources are not freed */ 897dd0191d5SShuanglin Wang if (shared) 898dd0191d5SShuanglin Wang return rc; 899dd0191d5SShuanglin Wang /* 900dd0191d5SShuanglin Wang * Free the allocated resource since we failed to either 901dd0191d5SShuanglin Wang * write to the entry or link the flow 902dd0191d5SShuanglin Wang */ 903dd0191d5SShuanglin Wang free_parms.dir = tbl->direction; 904dd0191d5SShuanglin Wang free_parms.type = tbl_type; 905dd0191d5SShuanglin Wang free_parms.idx = index; 906dd0191d5SShuanglin Wang free_parms.tbl_scope_id = tbl_scope_id; 907dd0191d5SShuanglin Wang 908dd0191d5SShuanglin Wang trc = tf_free_tbl_entry(tfp, &free_parms); 909dd0191d5SShuanglin Wang if (trc) 910dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to free tbl entry on failure\n"); 911dd0191d5SShuanglin Wang 912dd0191d5SShuanglin Wang return rc; 913dd0191d5SShuanglin Wang } 914dd0191d5SShuanglin Wang 915dd0191d5SShuanglin Wang static int32_t 916dd0191d5SShuanglin Wang ulp_mapper_tf_cmm_tbl_process(struct bnxt_ulp_mapper_parms *parms __rte_unused, 917dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl __rte_unused, 918dd0191d5SShuanglin Wang void *error __rte_unused) 919dd0191d5SShuanglin Wang { 920dd0191d5SShuanglin Wang /* CMM does not exist in TF library*/ 921dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid resource func,CMM is not supported on TF\n"); 922dd0191d5SShuanglin Wang return 0; 923dd0191d5SShuanglin Wang } 924dd0191d5SShuanglin Wang 925dd0191d5SShuanglin Wang static int32_t 926dd0191d5SShuanglin Wang ulp_mapper_tf_cmm_entry_free(struct bnxt_ulp_context *ulp __rte_unused, 927dd0191d5SShuanglin Wang struct ulp_flow_db_res_params *res __rte_unused, 928dd0191d5SShuanglin Wang void *error __rte_unused) 929dd0191d5SShuanglin Wang { 930dd0191d5SShuanglin Wang /* CMM does not exist in TF library*/ 931dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid resource func,CMM is not supported on TF\n"); 932dd0191d5SShuanglin Wang return 0; 933dd0191d5SShuanglin Wang } 934dd0191d5SShuanglin Wang 935dd0191d5SShuanglin Wang static int32_t 936dd0191d5SShuanglin Wang ulp_mapper_tf_if_tbl_process(struct bnxt_ulp_mapper_parms *parms, 937dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_tbl_info *tbl) 938dd0191d5SShuanglin Wang { 939dd0191d5SShuanglin Wang struct ulp_blob data, res_blob; 940*0c036a14SPeter Spreadborough uint64_t idx = 0; 941dd0191d5SShuanglin Wang uint16_t tmplen; 942dd0191d5SShuanglin Wang int32_t rc = 0; 943dd0191d5SShuanglin Wang struct tf_set_if_tbl_entry_parms iftbl_params = { 0 }; 944dd0191d5SShuanglin Wang struct tf_get_if_tbl_entry_parms get_parms = { 0 }; 945dd0191d5SShuanglin Wang struct tf *tfp; 946dd0191d5SShuanglin Wang enum bnxt_ulp_if_tbl_opc if_opc = tbl->tbl_opcode; 947dd0191d5SShuanglin Wang uint32_t res_size; 948dd0191d5SShuanglin Wang 949dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx, tbl->session_type); 950dd0191d5SShuanglin Wang /* Initialize the blob data */ 951c569279aSShuanglin Wang if (ulp_blob_init(&data, tbl->result_bit_size, 952dd0191d5SShuanglin Wang parms->device_params->result_byte_order)) { 953dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed initial index table blob\n"); 954dd0191d5SShuanglin Wang return -EINVAL; 955dd0191d5SShuanglin Wang } 956dd0191d5SShuanglin Wang 957dd0191d5SShuanglin Wang /* create the result blob */ 958dd0191d5SShuanglin Wang rc = ulp_mapper_tbl_result_build(parms, tbl, &data, "IFtable Result"); 959dd0191d5SShuanglin Wang if (rc) { 960dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to build the result blob\n"); 961dd0191d5SShuanglin Wang return rc; 962dd0191d5SShuanglin Wang } 963dd0191d5SShuanglin Wang 964dd0191d5SShuanglin Wang /* Get the index details */ 965dd0191d5SShuanglin Wang switch (if_opc) { 966dd0191d5SShuanglin Wang case BNXT_ULP_IF_TBL_OPC_WR_COMP_FIELD: 967dd0191d5SShuanglin Wang idx = ULP_COMP_FLD_IDX_RD(parms, tbl->tbl_operand); 968dd0191d5SShuanglin Wang break; 969dd0191d5SShuanglin Wang case BNXT_ULP_IF_TBL_OPC_WR_REGFILE: 970c569279aSShuanglin Wang if (ulp_regfile_read(parms->regfile, tbl->tbl_operand, &idx)) { 971dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "regfile[%d] read oob\n", 972dd0191d5SShuanglin Wang tbl->tbl_operand); 973dd0191d5SShuanglin Wang return -EINVAL; 974dd0191d5SShuanglin Wang } 975dd0191d5SShuanglin Wang idx = tfp_be_to_cpu_64(idx); 976dd0191d5SShuanglin Wang break; 977dd0191d5SShuanglin Wang case BNXT_ULP_IF_TBL_OPC_WR_CONST: 978dd0191d5SShuanglin Wang idx = tbl->tbl_operand; 979dd0191d5SShuanglin Wang break; 980dd0191d5SShuanglin Wang case BNXT_ULP_IF_TBL_OPC_RD_COMP_FIELD: 981dd0191d5SShuanglin Wang /* Initialize the result blob */ 982c569279aSShuanglin Wang if (ulp_blob_init(&res_blob, tbl->result_bit_size, 983dd0191d5SShuanglin Wang parms->device_params->result_byte_order)) { 984dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed initial result blob\n"); 985dd0191d5SShuanglin Wang return -EINVAL; 986dd0191d5SShuanglin Wang } 987dd0191d5SShuanglin Wang 988dd0191d5SShuanglin Wang /* read the interface table */ 989dd0191d5SShuanglin Wang idx = ULP_COMP_FLD_IDX_RD(parms, tbl->tbl_operand); 990dd0191d5SShuanglin Wang res_size = ULP_BITS_2_BYTE(tbl->result_bit_size); 991dd0191d5SShuanglin Wang get_parms.dir = tbl->direction; 992dd0191d5SShuanglin Wang get_parms.type = tbl->resource_type; 993dd0191d5SShuanglin Wang get_parms.idx = idx; 994dd0191d5SShuanglin Wang get_parms.data = ulp_blob_data_get(&res_blob, &tmplen); 995dd0191d5SShuanglin Wang get_parms.data_sz_in_bytes = res_size; 996dd0191d5SShuanglin Wang 997dd0191d5SShuanglin Wang rc = tf_get_if_tbl_entry(tfp, &get_parms); 998dd0191d5SShuanglin Wang if (rc) { 999dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Get table[%d][%s][%x] failed rc=%d\n", 1000dd0191d5SShuanglin Wang get_parms.type, 1001dd0191d5SShuanglin Wang tf_dir_2_str(get_parms.dir), 1002dd0191d5SShuanglin Wang get_parms.idx, rc); 1003dd0191d5SShuanglin Wang return rc; 1004dd0191d5SShuanglin Wang } 1005dd0191d5SShuanglin Wang rc = ulp_mapper_tbl_ident_scan_ext(parms, tbl, 1006dd0191d5SShuanglin Wang res_blob.data, 1007dd0191d5SShuanglin Wang res_size, 1008dd0191d5SShuanglin Wang res_blob.byte_order); 1009dd0191d5SShuanglin Wang if (rc) 1010dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Scan and extract failed rc=%d\n", 1011dd0191d5SShuanglin Wang rc); 1012dd0191d5SShuanglin Wang return rc; 1013dd0191d5SShuanglin Wang case BNXT_ULP_IF_TBL_OPC_NOT_USED: 1014dd0191d5SShuanglin Wang return rc; /* skip it */ 1015dd0191d5SShuanglin Wang default: 1016dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid tbl index opcode\n"); 1017dd0191d5SShuanglin Wang return -EINVAL; 1018dd0191d5SShuanglin Wang } 1019dd0191d5SShuanglin Wang 1020dd0191d5SShuanglin Wang /* Perform the tf table set by filling the set params */ 1021dd0191d5SShuanglin Wang iftbl_params.dir = tbl->direction; 1022dd0191d5SShuanglin Wang iftbl_params.type = tbl->resource_type; 1023dd0191d5SShuanglin Wang iftbl_params.data = ulp_blob_data_get(&data, &tmplen); 1024dd0191d5SShuanglin Wang iftbl_params.data_sz_in_bytes = ULP_BITS_2_BYTE(tmplen); 1025dd0191d5SShuanglin Wang iftbl_params.idx = idx; 1026dd0191d5SShuanglin Wang 1027dd0191d5SShuanglin Wang rc = tf_set_if_tbl_entry(tfp, &iftbl_params); 1028dd0191d5SShuanglin Wang if (rc) { 1029dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Set table[%d][%s][%x] failed rc=%d\n", 1030dd0191d5SShuanglin Wang iftbl_params.type,/* TBD: add tf_if_tbl_2_str */ 1031dd0191d5SShuanglin Wang tf_dir_2_str(iftbl_params.dir), 1032dd0191d5SShuanglin Wang iftbl_params.idx, rc); 1033dd0191d5SShuanglin Wang return rc; 1034dd0191d5SShuanglin Wang } 1035dd0191d5SShuanglin Wang BNXT_DRV_INF("Set table[%s][%s][%x] success.\n", 1036dd0191d5SShuanglin Wang tf_if_tbl_2_str(iftbl_params.type), 1037dd0191d5SShuanglin Wang tf_dir_2_str(iftbl_params.dir), 1038dd0191d5SShuanglin Wang iftbl_params.idx); 1039dd0191d5SShuanglin Wang 1040dd0191d5SShuanglin Wang /* 1041dd0191d5SShuanglin Wang * TBD: Need to look at the need to store idx in flow db for restore 1042dd0191d5SShuanglin Wang * the table to its original state on deletion of this entry. 1043dd0191d5SShuanglin Wang */ 1044dd0191d5SShuanglin Wang return rc; 1045dd0191d5SShuanglin Wang } 1046dd0191d5SShuanglin Wang 1047dd0191d5SShuanglin Wang static int32_t 1048dd0191d5SShuanglin Wang ulp_mapper_tf_ident_alloc(struct bnxt_ulp_context *ulp_ctx, 1049dd0191d5SShuanglin Wang uint32_t session_type, 1050dd0191d5SShuanglin Wang uint16_t ident_type, 1051dd0191d5SShuanglin Wang uint8_t direction, 10522aa70990SKishore Padmanabha enum cfa_track_type tt __rte_unused, 1053dd0191d5SShuanglin Wang uint64_t *identifier_id) 1054dd0191d5SShuanglin Wang { 1055dd0191d5SShuanglin Wang struct tf_alloc_identifier_parms iparms = {0}; 1056dd0191d5SShuanglin Wang struct tf *tfp; 1057dd0191d5SShuanglin Wang int32_t rc = 0; 1058dd0191d5SShuanglin Wang 1059dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, session_type); 1060dd0191d5SShuanglin Wang if (!tfp) { 1061dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get tf pointer\n"); 1062dd0191d5SShuanglin Wang return -EINVAL; 1063dd0191d5SShuanglin Wang } 1064dd0191d5SShuanglin Wang 1065dd0191d5SShuanglin Wang iparms.ident_type = ident_type; 1066dd0191d5SShuanglin Wang iparms.dir = direction; 1067dd0191d5SShuanglin Wang 1068dd0191d5SShuanglin Wang rc = tf_alloc_identifier(tfp, &iparms); 1069dd0191d5SShuanglin Wang if (rc) { 1070dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Alloc ident %s:%s failed.\n", 1071dd0191d5SShuanglin Wang tf_dir_2_str(iparms.dir), 1072dd0191d5SShuanglin Wang tf_ident_2_str(iparms.ident_type)); 1073dd0191d5SShuanglin Wang return rc; 1074dd0191d5SShuanglin Wang } 1075dd0191d5SShuanglin Wang *identifier_id = iparms.id; 1076dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 1077dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 1078dd0191d5SShuanglin Wang BNXT_DRV_INF("Allocated Identifier [%s]:[%s] = 0x%X\n", 1079dd0191d5SShuanglin Wang tf_dir_2_str(iparms.dir), 1080dd0191d5SShuanglin Wang tf_ident_2_str(iparms.ident_type), iparms.id); 1081dd0191d5SShuanglin Wang #endif 1082dd0191d5SShuanglin Wang #endif 1083dd0191d5SShuanglin Wang return rc; 1084dd0191d5SShuanglin Wang } 1085dd0191d5SShuanglin Wang 1086dd0191d5SShuanglin Wang static int32_t 1087dd0191d5SShuanglin Wang ulp_mapper_tf_ident_free(struct bnxt_ulp_context *ulp_ctx, 1088dd0191d5SShuanglin Wang struct ulp_flow_db_res_params *res) 1089dd0191d5SShuanglin Wang { 1090dd0191d5SShuanglin Wang struct tf_free_identifier_parms free_parms = { 0 }; 1091dd0191d5SShuanglin Wang uint32_t session_type; 1092dd0191d5SShuanglin Wang struct tf *tfp; 1093dd0191d5SShuanglin Wang int32_t rc = 0; 1094dd0191d5SShuanglin Wang 1095dd0191d5SShuanglin Wang session_type = ulp_flow_db_shared_session_get(res); 1096dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, session_type); 1097dd0191d5SShuanglin Wang if (!tfp) { 1098dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get tf pointer\n"); 1099dd0191d5SShuanglin Wang return -EINVAL; 1100dd0191d5SShuanglin Wang } 1101dd0191d5SShuanglin Wang 1102dd0191d5SShuanglin Wang free_parms.ident_type = res->resource_type; 1103dd0191d5SShuanglin Wang free_parms.dir = res->direction; 1104dd0191d5SShuanglin Wang free_parms.id = res->resource_hndl; 1105dd0191d5SShuanglin Wang 1106dd0191d5SShuanglin Wang (void)tf_free_identifier(tfp, &free_parms); 1107dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 1108dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 1109dd0191d5SShuanglin Wang BNXT_DRV_INF("Freed Identifier [%s]:[%s] = 0x%X\n", 1110dd0191d5SShuanglin Wang tf_dir_2_str(free_parms.dir), 1111dd0191d5SShuanglin Wang tf_ident_2_str(free_parms.ident_type), 1112dd0191d5SShuanglin Wang (uint32_t)free_parms.id); 1113dd0191d5SShuanglin Wang #endif 1114dd0191d5SShuanglin Wang #endif 1115dd0191d5SShuanglin Wang return rc; 1116dd0191d5SShuanglin Wang } 1117dd0191d5SShuanglin Wang 1118dd0191d5SShuanglin Wang static inline int32_t 1119dd0191d5SShuanglin Wang ulp_mapper_tf_tcam_entry_free(struct bnxt_ulp_context *ulp, 1120dd0191d5SShuanglin Wang struct ulp_flow_db_res_params *res) 1121dd0191d5SShuanglin Wang { 1122dd0191d5SShuanglin Wang struct tf *tfp; 1123dd0191d5SShuanglin Wang struct tf_free_tcam_entry_parms fparms = { 1124dd0191d5SShuanglin Wang .dir = res->direction, 1125dd0191d5SShuanglin Wang .tcam_tbl_type = res->resource_type, 1126dd0191d5SShuanglin Wang .idx = (uint16_t)res->resource_hndl 1127dd0191d5SShuanglin Wang }; 1128dd0191d5SShuanglin Wang 1129dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(ulp, ulp_flow_db_shared_session_get(res)); 1130dd0191d5SShuanglin Wang if (!tfp) { 1131dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to free resource failed to get tfp\n"); 1132dd0191d5SShuanglin Wang return -EINVAL; 1133dd0191d5SShuanglin Wang } 1134dd0191d5SShuanglin Wang 1135dd0191d5SShuanglin Wang /* If HA is enabled, we may have to remap the TF Type */ 1136dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_ha_enabled(ulp)) { 1137dd0191d5SShuanglin Wang enum ulp_ha_mgr_region region; 1138dd0191d5SShuanglin Wang int32_t rc; 1139dd0191d5SShuanglin Wang 1140dd0191d5SShuanglin Wang switch (res->resource_type) { 1141dd0191d5SShuanglin Wang case TF_TCAM_TBL_TYPE_WC_TCAM_HIGH: 1142dd0191d5SShuanglin Wang case TF_TCAM_TBL_TYPE_WC_TCAM_LOW: 1143dd0191d5SShuanglin Wang rc = ulp_ha_mgr_region_get(ulp, ®ion); 1144dd0191d5SShuanglin Wang if (rc) 1145dd0191d5SShuanglin Wang /* Log this, but assume region is correct */ 1146dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 1147dd0191d5SShuanglin Wang "Unable to get HA region (%d)\n", 1148dd0191d5SShuanglin Wang rc); 1149dd0191d5SShuanglin Wang else 1150dd0191d5SShuanglin Wang fparms.tcam_tbl_type = 1151dd0191d5SShuanglin Wang (region == ULP_HA_REGION_LOW) ? 1152dd0191d5SShuanglin Wang TF_TCAM_TBL_TYPE_WC_TCAM_LOW : 1153dd0191d5SShuanglin Wang TF_TCAM_TBL_TYPE_WC_TCAM_HIGH; 1154dd0191d5SShuanglin Wang break; 1155dd0191d5SShuanglin Wang default: 1156dd0191d5SShuanglin Wang break; 1157dd0191d5SShuanglin Wang } 1158dd0191d5SShuanglin Wang } 1159dd0191d5SShuanglin Wang return tf_free_tcam_entry(tfp, &fparms); 1160dd0191d5SShuanglin Wang } 1161dd0191d5SShuanglin Wang 1162dd0191d5SShuanglin Wang static int32_t 1163dd0191d5SShuanglin Wang ulp_mapper_clear_full_action_record(struct tf *tfp, 1164dd0191d5SShuanglin Wang struct bnxt_ulp_context *ulp_ctx, 1165dd0191d5SShuanglin Wang struct tf_free_tbl_entry_parms *fparms) 1166dd0191d5SShuanglin Wang { 1167dd0191d5SShuanglin Wang struct tf_set_tbl_entry_parms sparms = { 0 }; 1168dd0191d5SShuanglin Wang static uint8_t fld_zeros[16] = { 0 }; 1169dd0191d5SShuanglin Wang uint32_t dev_id = BNXT_ULP_DEVICE_ID_LAST; 1170dd0191d5SShuanglin Wang int32_t rc = 0; 1171dd0191d5SShuanglin Wang 1172dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id); 1173dd0191d5SShuanglin Wang if (rc) { 1174dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get the dev id from ulp.\n"); 1175dd0191d5SShuanglin Wang return rc; 1176dd0191d5SShuanglin Wang } 1177dd0191d5SShuanglin Wang 1178dd0191d5SShuanglin Wang if (dev_id == BNXT_ULP_DEVICE_ID_THOR) { 1179dd0191d5SShuanglin Wang sparms.dir = fparms->dir; 1180dd0191d5SShuanglin Wang sparms.data = fld_zeros; 1181dd0191d5SShuanglin Wang sparms.type = fparms->type; 1182dd0191d5SShuanglin Wang sparms.data_sz_in_bytes = 16; /* FULL ACT REC SIZE - THOR */ 1183dd0191d5SShuanglin Wang sparms.idx = fparms->idx; 1184dd0191d5SShuanglin Wang sparms.tbl_scope_id = fparms->tbl_scope_id; 1185dd0191d5SShuanglin Wang rc = tf_set_tbl_entry(tfp, &sparms); 1186dd0191d5SShuanglin Wang if (rc) { 1187dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 1188dd0191d5SShuanglin Wang "Index table[%s][%s][%x] write fail %d\n", 1189dd0191d5SShuanglin Wang tf_tbl_type_2_str(sparms.type), 1190dd0191d5SShuanglin Wang tf_dir_2_str(sparms.dir), 1191dd0191d5SShuanglin Wang sparms.idx, rc); 1192dd0191d5SShuanglin Wang return rc; 1193dd0191d5SShuanglin Wang } 1194dd0191d5SShuanglin Wang } 1195dd0191d5SShuanglin Wang return 0; 1196dd0191d5SShuanglin Wang } 1197dd0191d5SShuanglin Wang 1198dd0191d5SShuanglin Wang static inline int32_t 1199dd0191d5SShuanglin Wang ulp_mapper_tf_index_entry_free(struct bnxt_ulp_context *ulp, 1200dd0191d5SShuanglin Wang struct ulp_flow_db_res_params *res) 1201dd0191d5SShuanglin Wang { 1202dd0191d5SShuanglin Wang struct tf *tfp; 1203dd0191d5SShuanglin Wang struct tf_free_tbl_entry_parms fparms = { 1204dd0191d5SShuanglin Wang .dir = res->direction, 1205dd0191d5SShuanglin Wang .type = res->resource_type, 1206dd0191d5SShuanglin Wang .idx = (uint32_t)res->resource_hndl 1207dd0191d5SShuanglin Wang }; 1208dd0191d5SShuanglin Wang 1209dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(ulp, ulp_flow_db_shared_session_get(res)); 1210dd0191d5SShuanglin Wang if (!tfp) { 1211dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 1212dd0191d5SShuanglin Wang "Unable to free resource failed to get tfp\n"); 1213dd0191d5SShuanglin Wang return -EINVAL; 1214dd0191d5SShuanglin Wang } 1215dd0191d5SShuanglin Wang 1216dd0191d5SShuanglin Wang /* Get the table scope, it may be ignored */ 1217dd0191d5SShuanglin Wang (void)bnxt_ulp_cntxt_tbl_scope_id_get(ulp, &fparms.tbl_scope_id); 1218dd0191d5SShuanglin Wang 1219dd0191d5SShuanglin Wang if (fparms.type == TF_TBL_TYPE_FULL_ACT_RECORD) 1220dd0191d5SShuanglin Wang (void)ulp_mapper_clear_full_action_record(tfp, ulp, &fparms); 1221dd0191d5SShuanglin Wang 1222dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 1223dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 1224dd0191d5SShuanglin Wang BNXT_DRV_INF("Free index table [%s]:[%s] = 0x%X\n", 1225dd0191d5SShuanglin Wang tf_dir_2_str(fparms.dir), 1226dd0191d5SShuanglin Wang tf_tbl_type_2_str(fparms.type), 1227dd0191d5SShuanglin Wang (uint32_t)fparms.idx); 1228dd0191d5SShuanglin Wang #endif 1229dd0191d5SShuanglin Wang #endif 1230dd0191d5SShuanglin Wang return tf_free_tbl_entry(tfp, &fparms); 1231dd0191d5SShuanglin Wang } 1232dd0191d5SShuanglin Wang 1233dd0191d5SShuanglin Wang static int32_t 1234dd0191d5SShuanglin Wang ulp_mapper_tf_index_tbl_alloc_process(struct bnxt_ulp_context *ulp, 1235dd0191d5SShuanglin Wang uint32_t session_type, 1236dd0191d5SShuanglin Wang uint16_t table_type, 1237dd0191d5SShuanglin Wang uint8_t direction, 1238dd0191d5SShuanglin Wang uint64_t *index) 1239dd0191d5SShuanglin Wang { 1240dd0191d5SShuanglin Wang struct tf_alloc_tbl_entry_parms aparms = { 0 }; 1241dd0191d5SShuanglin Wang struct tf *tfp; 1242dd0191d5SShuanglin Wang uint32_t tbl_scope_id; 1243dd0191d5SShuanglin Wang int32_t rc = 0; 1244dd0191d5SShuanglin Wang 1245dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(ulp, session_type); 1246dd0191d5SShuanglin Wang if (!tfp) 1247dd0191d5SShuanglin Wang return -EINVAL; 1248dd0191d5SShuanglin Wang 1249dd0191d5SShuanglin Wang /* Get the scope id */ 1250dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp, &tbl_scope_id); 1251dd0191d5SShuanglin Wang if (rc) { 1252dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get table scope rc=%d\n", rc); 1253dd0191d5SShuanglin Wang return rc; 1254dd0191d5SShuanglin Wang } 1255dd0191d5SShuanglin Wang 1256dd0191d5SShuanglin Wang aparms.type = table_type; 1257dd0191d5SShuanglin Wang aparms.dir = direction; 1258dd0191d5SShuanglin Wang aparms.tbl_scope_id = tbl_scope_id; 1259dd0191d5SShuanglin Wang 1260dd0191d5SShuanglin Wang /* Allocate the index tbl using tf api */ 1261dd0191d5SShuanglin Wang rc = tf_alloc_tbl_entry(tfp, &aparms); 1262dd0191d5SShuanglin Wang if (rc) { 1263dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to alloc index table [%s][%d]\n", 1264dd0191d5SShuanglin Wang tf_dir_2_str(aparms.dir), aparms.type); 1265dd0191d5SShuanglin Wang return rc; 1266dd0191d5SShuanglin Wang } 1267dd0191d5SShuanglin Wang 1268dd0191d5SShuanglin Wang *index = aparms.idx; 1269dd0191d5SShuanglin Wang 1270dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 1271dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG_MAPPER 1272dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Allocated Table Index [%s][%s] = 0x%04x\n", 1273dd0191d5SShuanglin Wang tf_tbl_type_2_str(aparms.type), 1274dd0191d5SShuanglin Wang tf_dir_2_str(aparms.dir), 1275dd0191d5SShuanglin Wang aparms.idx); 1276dd0191d5SShuanglin Wang #endif 1277dd0191d5SShuanglin Wang #endif 1278dd0191d5SShuanglin Wang return rc; 1279dd0191d5SShuanglin Wang } 1280dd0191d5SShuanglin Wang 1281dd0191d5SShuanglin Wang static int32_t 1282dd0191d5SShuanglin Wang ulp_mapper_tf_app_glb_resource_info_init(struct bnxt_ulp_context *ulp_ctx, 1283dd0191d5SShuanglin Wang struct bnxt_ulp_mapper_data *mapper_data) 1284dd0191d5SShuanglin Wang { 1285dd0191d5SShuanglin Wang struct bnxt_ulp_glb_resource_info *glb_res; 1286dd0191d5SShuanglin Wang uint32_t num_entries, idx, dev_id; 1287dd0191d5SShuanglin Wang uint8_t app_id; 1288dd0191d5SShuanglin Wang int32_t rc = 0; 1289dd0191d5SShuanglin Wang 1290dd0191d5SShuanglin Wang glb_res = bnxt_ulp_app_glb_resource_info_list_get(&num_entries); 1291dd0191d5SShuanglin Wang /* Check if there are no resources */ 1292dd0191d5SShuanglin Wang if (!num_entries) 1293dd0191d5SShuanglin Wang return 0; 1294dd0191d5SShuanglin Wang 1295dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id); 1296dd0191d5SShuanglin Wang if (rc) { 1297dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get device id for glb init (%d)\n", 1298dd0191d5SShuanglin Wang rc); 1299dd0191d5SShuanglin Wang return rc; 1300dd0191d5SShuanglin Wang } 1301dd0191d5SShuanglin Wang 1302dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id); 1303dd0191d5SShuanglin Wang if (rc) { 1304dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get app id for glb init (%d)\n", 1305dd0191d5SShuanglin Wang rc); 1306dd0191d5SShuanglin Wang return rc; 1307dd0191d5SShuanglin Wang } 1308dd0191d5SShuanglin Wang 1309dd0191d5SShuanglin Wang /* Iterate the global resources and process each one */ 1310dd0191d5SShuanglin Wang for (idx = 0; idx < num_entries; idx++) { 1311dd0191d5SShuanglin Wang if (dev_id != glb_res[idx].device_id || 1312dd0191d5SShuanglin Wang glb_res[idx].app_id != app_id) 1313dd0191d5SShuanglin Wang continue; 1314dd0191d5SShuanglin Wang switch (glb_res[idx].resource_func) { 1315dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER: 1316dd0191d5SShuanglin Wang rc = ulp_mapper_resource_ident_allocate(ulp_ctx, 1317dd0191d5SShuanglin Wang mapper_data, 1318dd0191d5SShuanglin Wang &glb_res[idx], 1319dd0191d5SShuanglin Wang true); 1320dd0191d5SShuanglin Wang break; 1321dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE: 1322dd0191d5SShuanglin Wang rc = ulp_mapper_resource_index_tbl_alloc(ulp_ctx, 1323dd0191d5SShuanglin Wang mapper_data, 1324dd0191d5SShuanglin Wang &glb_res[idx], 1325dd0191d5SShuanglin Wang true); 1326dd0191d5SShuanglin Wang break; 1327dd0191d5SShuanglin Wang default: 1328dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Global resource %x not supported\n", 1329dd0191d5SShuanglin Wang glb_res[idx].resource_func); 1330dd0191d5SShuanglin Wang rc = -EINVAL; 1331dd0191d5SShuanglin Wang break; 1332dd0191d5SShuanglin Wang } 1333dd0191d5SShuanglin Wang if (rc) 1334dd0191d5SShuanglin Wang return rc; 1335dd0191d5SShuanglin Wang } 1336dd0191d5SShuanglin Wang return rc; 1337dd0191d5SShuanglin Wang } 1338dd0191d5SShuanglin Wang 1339dd0191d5SShuanglin Wang static int32_t 1340dd0191d5SShuanglin Wang ulp_mapper_tf_handle_to_offset(struct bnxt_ulp_mapper_parms *parms __rte_unused, 1341dd0191d5SShuanglin Wang uint64_t handle __rte_unused, 1342dd0191d5SShuanglin Wang uint32_t offset __rte_unused, 1343dd0191d5SShuanglin Wang uint64_t *result __rte_unused) 1344dd0191d5SShuanglin Wang { 1345dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "handle to offset not supported in tf\n"); 1346dd0191d5SShuanglin Wang return -EINVAL; 1347dd0191d5SShuanglin Wang } 1348dd0191d5SShuanglin Wang 1349dd0191d5SShuanglin Wang static int 1350dd0191d5SShuanglin Wang ulp_mapper_tf_mpc_batch_start(struct tfc_mpc_batch_info_t *batch_info __rte_unused) 1351dd0191d5SShuanglin Wang { 1352dd0191d5SShuanglin Wang return 0; 1353dd0191d5SShuanglin Wang } 1354dd0191d5SShuanglin Wang 1355dd0191d5SShuanglin Wang static int 1356dd0191d5SShuanglin Wang ulp_mapper_tf_mpc_batch_end(struct tfc *tfcp __rte_unused, 1357dd0191d5SShuanglin Wang struct tfc_mpc_batch_info_t *batch_info __rte_unused) 1358dd0191d5SShuanglin Wang { 1359dd0191d5SShuanglin Wang return 0; 1360dd0191d5SShuanglin Wang } 1361dd0191d5SShuanglin Wang 1362dd0191d5SShuanglin Wang static bool 1363dd0191d5SShuanglin Wang ulp_mapper_tf_mpc_batch_started(struct tfc_mpc_batch_info_t *batch_info __rte_unused) 1364dd0191d5SShuanglin Wang { 1365dd0191d5SShuanglin Wang return false; 1366dd0191d5SShuanglin Wang } 1367dd0191d5SShuanglin Wang 1368dd0191d5SShuanglin Wang const struct ulp_mapper_core_ops ulp_mapper_tf_core_ops = { 1369dd0191d5SShuanglin Wang .ulp_mapper_core_tcam_tbl_process = ulp_mapper_tf_tcam_tbl_process, 1370dd0191d5SShuanglin Wang .ulp_mapper_core_tcam_entry_free = ulp_mapper_tf_tcam_entry_free, 1371dd0191d5SShuanglin Wang .ulp_mapper_core_em_tbl_process = ulp_mapper_tf_em_tbl_process, 1372dd0191d5SShuanglin Wang .ulp_mapper_core_em_entry_free = ulp_mapper_tf_em_entry_free, 1373dd0191d5SShuanglin Wang .ulp_mapper_core_index_tbl_process = ulp_mapper_tf_index_tbl_process, 1374dd0191d5SShuanglin Wang .ulp_mapper_core_index_entry_free = ulp_mapper_tf_index_entry_free, 1375dd0191d5SShuanglin Wang .ulp_mapper_core_cmm_tbl_process = ulp_mapper_tf_cmm_tbl_process, 1376dd0191d5SShuanglin Wang .ulp_mapper_core_cmm_entry_free = ulp_mapper_tf_cmm_entry_free, 1377dd0191d5SShuanglin Wang .ulp_mapper_core_if_tbl_process = ulp_mapper_tf_if_tbl_process, 1378dd0191d5SShuanglin Wang .ulp_mapper_core_ident_alloc_process = ulp_mapper_tf_ident_alloc, 1379dd0191d5SShuanglin Wang .ulp_mapper_core_ident_free = ulp_mapper_tf_ident_free, 1380dd0191d5SShuanglin Wang .ulp_mapper_core_dyn_tbl_type_get = ulp_mapper_tf_dyn_tbl_type_get, 1381dd0191d5SShuanglin Wang .ulp_mapper_core_index_tbl_alloc_process = 1382dd0191d5SShuanglin Wang ulp_mapper_tf_index_tbl_alloc_process, 1383dd0191d5SShuanglin Wang .ulp_mapper_core_app_glb_res_info_init = 1384dd0191d5SShuanglin Wang ulp_mapper_tf_app_glb_resource_info_init, 1385dd0191d5SShuanglin Wang .ulp_mapper_core_handle_to_offset = ulp_mapper_tf_handle_to_offset, 1386dd0191d5SShuanglin Wang .ulp_mapper_mpc_batch_started = ulp_mapper_tf_mpc_batch_started, 1387dd0191d5SShuanglin Wang .ulp_mapper_mpc_batch_start = ulp_mapper_tf_mpc_batch_start, 1388dd0191d5SShuanglin Wang .ulp_mapper_mpc_batch_end = ulp_mapper_tf_mpc_batch_end 1389dd0191d5SShuanglin Wang }; 1390