1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2014-2020 Broadcom
7 #include <rte_malloc.h>
9 #include "ulp_template_db_enum.h"
10 #include "ulp_template_struct.h"
11 #include "bnxt_tf_common.h"
12 #include "ulp_utils.h"
15 #include "tf_ext_flow_handle.h"
16 #include "ulp_mark_mgr.h"
17 #include "ulp_flow_db.h"
18 #include "ulp_mapper.h"
20 static struct bnxt_ulp_glb_resource_info *
21 ulp_mapper_glb_resource_info_list_get(uint32_t *num_entries)
25 *num_entries = BNXT_ULP_GLB_RESOURCE_INFO_TBL_MAX_SZ;
26 return ulp_glb_resource_tbl;
30 * Read the global resource from the mapper global resource list
32 * The regval is always returned in big-endian.
34 * returns 0 on success
37 ulp_mapper_glb_resource_read(struct bnxt_ulp_mapper_data *mapper_data,
42 if (!mapper_data || !regval ||
43 dir >= TF_DIR_MAX || idx >= BNXT_ULP_GLB_REGFILE_INDEX_LAST)
46 *regval = mapper_data->glb_res_tbl[dir][idx].resource_hndl;
51 * Write a global resource to the mapper global resource list
53 * The regval value must be in big-endian.
55 * return 0 on success.
58 ulp_mapper_glb_resource_write(struct bnxt_ulp_mapper_data *data,
59 struct bnxt_ulp_glb_resource_info *res,
62 struct bnxt_ulp_mapper_glb_resource_entry *ent;
64 /* validate the arguments */
65 if (!data || res->direction >= TF_DIR_MAX ||
66 res->glb_regfile_index >= BNXT_ULP_GLB_REGFILE_INDEX_LAST)
69 /* write to the mapper data */
70 ent = &data->glb_res_tbl[res->direction][res->glb_regfile_index];
71 ent->resource_func = res->resource_func;
72 ent->resource_type = res->resource_type;
73 ent->resource_hndl = regval;
78 * Internal function to allocate identity resource and store it in mapper data.
80 * returns 0 on success
83 ulp_mapper_resource_ident_allocate(struct tf *tfp,
84 struct bnxt_ulp_mapper_data *mapper_data,
85 struct bnxt_ulp_glb_resource_info *glb_res)
87 struct tf_alloc_identifier_parms iparms = { 0 };
88 struct tf_free_identifier_parms fparms;
92 iparms.ident_type = glb_res->resource_type;
93 iparms.dir = glb_res->direction;
95 /* Allocate the Identifier using tf api */
96 rc = tf_alloc_identifier(tfp, &iparms);
98 BNXT_TF_DBG(ERR, "Failed to alloc identifier [%s][%d]\n",
99 (iparms.dir == TF_DIR_RX) ? "RX" : "TX",
104 /* entries are stored as big-endian format */
105 regval = tfp_cpu_to_be_64((uint64_t)iparms.id);
106 /* write to the mapper global resource */
107 rc = ulp_mapper_glb_resource_write(mapper_data, glb_res, regval);
109 BNXT_TF_DBG(ERR, "Failed to write to global resource id\n");
110 /* Free the identifier when update failed */
111 fparms.dir = iparms.dir;
112 fparms.ident_type = iparms.ident_type;
113 fparms.id = iparms.id;
114 tf_free_identifier(tfp, &fparms);
117 #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
118 BNXT_TF_DBG(DEBUG, "Allocated Glb Res[%s][%d][%d] = 0x%04x\n",
119 (iparms.dir == TF_DIR_RX) ? "RX" : "TX",
120 glb_res->glb_regfile_index, iparms.ident_type, iparms.id);
125 /* Retrieve the cache initialization parameters for the tbl_idx */
126 static struct bnxt_ulp_cache_tbl_params *
127 ulp_mapper_cache_tbl_params_get(uint32_t tbl_idx)
129 if (tbl_idx >= BNXT_ULP_CACHE_TBL_MAX_SZ)
132 return &ulp_cache_tbl_params[tbl_idx];
136 * Get the size of the action property for a given index.
138 * idx [in] The index for the action property
140 * returns the size of the action property.
143 ulp_mapper_act_prop_size_get(uint32_t idx)
145 if (idx >= BNXT_ULP_ACT_PROP_IDX_LAST)
147 return ulp_act_prop_map_table[idx];
151 * Get the list of result fields that implement the flow action.
152 * Gets a device dependent list of tables that implement the action template id.
154 * dev_id [in] The device id of the forwarding element
156 * tid [in] The action template id that matches the flow
158 * num_tbls [out] The number of action tables in the returned array
160 * Returns An array of action tables to implement the flow, or NULL on error.
162 static struct bnxt_ulp_mapper_tbl_info *
163 ulp_mapper_action_tbl_list_get(uint32_t dev_id,
171 BNXT_TF_DBG(ERR, "Invalid arguments\n");
175 /* template shift and device mask */
176 tidx = ULP_DEVICE_PARAMS_INDEX(tid, dev_id);
178 /* NOTE: Need to have something from template compiler to help validate
179 * range of dev_id and act_tid
181 idx = ulp_act_tmpl_list[tidx].start_tbl_idx;
182 *num_tbls = ulp_act_tmpl_list[tidx].num_tbls;
184 return &ulp_act_tbl_list[idx];
188 * Get a list of classifier tables that implement the flow
189 * Gets a device dependent list of tables that implement the class template id
191 * dev_id [in] The device id of the forwarding element
193 * tid [in] The template id that matches the flow
195 * num_tbls [out] The number of classifier tables in the returned array
197 * fdb_tbl_idx [out] The flow database index Regular or default
199 * returns An array of classifier tables to implement the flow, or NULL on
202 static struct bnxt_ulp_mapper_tbl_info *
203 ulp_mapper_class_tbl_list_get(uint32_t dev_id,
206 uint32_t *fdb_tbl_idx)
209 uint32_t tidx = ULP_DEVICE_PARAMS_INDEX(tid, dev_id);
214 /* NOTE: Need to have something from template compiler to help validate
215 * range of dev_id and tid
217 idx = ulp_class_tmpl_list[tidx].start_tbl_idx;
218 *num_tbls = ulp_class_tmpl_list[tidx].num_tbls;
219 *fdb_tbl_idx = ulp_class_tmpl_list[tidx].flow_db_table_type;
220 return &ulp_class_tbl_list[idx];
224 * Get the list of key fields that implement the flow.
226 * ctxt [in] The ulp context
228 * tbl [in] A single table instance to get the key fields from
230 * num_flds [out] The number of key fields in the returned array
232 * Returns array of Key fields, or NULL on error.
234 static struct bnxt_ulp_mapper_class_key_field_info *
235 ulp_mapper_key_fields_get(struct bnxt_ulp_mapper_tbl_info *tbl,
240 if (!tbl || !num_flds)
243 idx = tbl->key_start_idx;
244 *num_flds = tbl->key_num_fields;
246 /* NOTE: Need template to provide range checking define */
247 return &ulp_class_key_field_list[idx];
251 * Get the list of data fields that implement the flow.
253 * ctxt [in] The ulp context
255 * tbl [in] A single table instance to get the data fields from
257 * num_flds [out] The number of data fields in the returned array.
259 * Returns array of data fields, or NULL on error.
261 static struct bnxt_ulp_mapper_result_field_info *
262 ulp_mapper_result_fields_get(struct bnxt_ulp_mapper_tbl_info *tbl,
264 uint32_t *num_encap_flds)
268 if (!tbl || !num_flds)
271 idx = tbl->result_start_idx;
272 *num_flds = tbl->result_num_fields;
273 *num_encap_flds = tbl->encap_num_fields;
275 /* NOTE: Need template to provide range checking define */
276 return &ulp_class_result_field_list[idx];
280 * Get the list of result fields that implement the flow action.
282 * tbl [in] A single table instance to get the results fields
283 * from num_flds [out] The number of data fields in the returned
286 * Returns array of data fields, or NULL on error.
288 static struct bnxt_ulp_mapper_result_field_info *
289 ulp_mapper_act_result_fields_get(struct bnxt_ulp_mapper_tbl_info *tbl,
290 uint32_t *num_rslt_flds,
291 uint32_t *num_encap_flds)
295 if (!tbl || !num_rslt_flds || !num_encap_flds)
298 idx = tbl->result_start_idx;
299 *num_rslt_flds = tbl->result_num_fields;
300 *num_encap_flds = tbl->encap_num_fields;
302 /* NOTE: Need template to provide range checking define */
303 return &ulp_act_result_field_list[idx];
307 * Get the list of ident fields that implement the flow
309 * tbl [in] A single table instance to get the ident fields from
311 * num_flds [out] The number of ident fields in the returned array
313 * returns array of ident fields, or NULL on error
315 static struct bnxt_ulp_mapper_ident_info *
316 ulp_mapper_ident_fields_get(struct bnxt_ulp_mapper_tbl_info *tbl,
321 if (!tbl || !num_flds)
324 idx = tbl->ident_start_idx;
325 *num_flds = tbl->ident_nums;
327 /* NOTE: Need template to provide range checking define */
328 return &ulp_ident_list[idx];
331 static struct bnxt_ulp_mapper_cache_entry *
332 ulp_mapper_cache_entry_get(struct bnxt_ulp_context *ulp,
336 struct bnxt_ulp_mapper_data *mapper_data;
338 mapper_data = bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp);
339 if (!mapper_data || id >= BNXT_ULP_CACHE_TBL_MAX_SZ ||
340 !mapper_data->cache_tbl[id]) {
341 BNXT_TF_DBG(ERR, "Unable to acquire the cache tbl (%d)\n", id);
345 return &mapper_data->cache_tbl[id][key];
349 * Concatenates the tbl_type and tbl_id into a 32bit value for storing in the
350 * resource_type. This is done to conserve memory since both the tbl_type and
354 ulp_mapper_cache_res_type_set(struct ulp_flow_db_res_params *res,
358 res->resource_type = tbl_type;
359 res->resource_sub_type = tbl_id;
362 /* Extracts the tbl_type and tbl_id from the 32bit resource type. */
364 ulp_mapper_cache_res_type_get(struct ulp_flow_db_res_params *res,
368 *tbl_type = res->resource_type;
369 *tbl_id = res->resource_sub_type;
373 ulp_mapper_cache_entry_free(struct bnxt_ulp_context *ulp,
375 struct ulp_flow_db_res_params *res)
377 struct bnxt_ulp_mapper_cache_entry *cache_entry;
378 struct tf_free_identifier_parms ident_parms;
379 struct tf_free_tcam_entry_parms tcam_parms;
380 uint16_t table_id, table_type;
384 * The table id, used for cache, and table_type, used for tcam, are
385 * both encoded within the resource. We must first extract them to
386 * formulate the args for tf calls.
388 ulp_mapper_cache_res_type_get(res, &table_type, &table_id);
389 cache_entry = ulp_mapper_cache_entry_get(ulp, table_id,
390 (uint16_t)res->resource_hndl);
391 if (!cache_entry || !cache_entry->ref_count) {
392 BNXT_TF_DBG(ERR, "Cache entry (%d:%d) not valid on free.\n",
393 table_id, (uint16_t)res->resource_hndl);
398 * See if we need to delete the entry. The tcam and identifiers are all
399 * tracked by the cached entries reference count. All are deleted when
400 * the reference count hit zero.
402 cache_entry->ref_count--;
403 if (cache_entry->ref_count)
407 * Need to delete the tcam entry and the allocated identifiers.
408 * In the event of a failure, need to try to delete the remaining
409 * resources before returning error.
411 tcam_parms.dir = res->direction;
412 tcam_parms.tcam_tbl_type = table_type;
413 tcam_parms.idx = cache_entry->tcam_idx;
414 rc = tf_free_tcam_entry(tfp, &tcam_parms);
416 BNXT_TF_DBG(ERR, "Failed to free tcam [%d][%s][0x%04x] rc=%d\n",
418 (res->direction == TF_DIR_RX) ? "RX" : "TX",
422 * Free the identifiers associated with the tcam entry. Entries with
423 * negative one are considered uninitialized.
425 for (i = 0; i < BNXT_ULP_CACHE_TBL_IDENT_MAX_NUM; i++) {
426 if (cache_entry->idents[i] == ULP_IDENTS_INVALID)
429 ident_parms.dir = res->direction;
430 ident_parms.ident_type = cache_entry->ident_types[i];
431 ident_parms.id = cache_entry->idents[i];
432 trc = tf_free_identifier(tfp, &ident_parms);
434 BNXT_TF_DBG(ERR, "Failed to free identifier "
435 "[%d][%s][0x%04x] rc=%d\n",
436 ident_parms.ident_type,
437 (res->direction == TF_DIR_RX) ? "RX" : "TX",
438 ident_parms.id, trc);
446 static inline int32_t
447 ulp_mapper_tcam_entry_free(struct bnxt_ulp_context *ulp __rte_unused,
449 struct ulp_flow_db_res_params *res)
451 struct tf_free_tcam_entry_parms fparms = {
452 .dir = res->direction,
453 .tcam_tbl_type = res->resource_type,
454 .idx = (uint16_t)res->resource_hndl
457 return tf_free_tcam_entry(tfp, &fparms);
460 static inline int32_t
461 ulp_mapper_index_entry_free(struct bnxt_ulp_context *ulp,
463 struct ulp_flow_db_res_params *res)
465 struct tf_free_tbl_entry_parms fparms = {
466 .dir = res->direction,
467 .type = res->resource_type,
468 .idx = (uint32_t)res->resource_hndl
472 * Just set the table scope, it will be ignored if not necessary
473 * by the tf_free_tbl_entry
475 bnxt_ulp_cntxt_tbl_scope_id_get(ulp, &fparms.tbl_scope_id);
477 return tf_free_tbl_entry(tfp, &fparms);
480 static inline int32_t
481 ulp_mapper_eem_entry_free(struct bnxt_ulp_context *ulp,
483 struct ulp_flow_db_res_params *res)
485 struct tf_delete_em_entry_parms fparms = { 0 };
488 fparms.dir = res->direction;
489 fparms.mem = TF_MEM_EXTERNAL;
490 fparms.flow_handle = res->resource_hndl;
492 rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp, &fparms.tbl_scope_id);
494 BNXT_TF_DBG(ERR, "Failed to get table scope\n");
498 return tf_delete_em_entry(tfp, &fparms);
501 static inline int32_t
502 ulp_mapper_ident_free(struct bnxt_ulp_context *ulp __rte_unused,
504 struct ulp_flow_db_res_params *res)
506 struct tf_free_identifier_parms fparms = {
507 .dir = res->direction,
508 .ident_type = res->resource_type,
509 .id = (uint16_t)res->resource_hndl
512 return tf_free_identifier(tfp, &fparms);
515 static inline int32_t
516 ulp_mapper_mark_free(struct bnxt_ulp_context *ulp,
517 struct ulp_flow_db_res_params *res)
519 return ulp_mark_db_mark_del(ulp,
525 * Process the identifier instruction and either store it in the flow database
526 * or return it in the val (if not NULL) on success. If val is NULL, the
527 * identifier is to be stored in the flow database.
530 ulp_mapper_ident_process(struct bnxt_ulp_mapper_parms *parms,
531 struct bnxt_ulp_mapper_tbl_info *tbl,
532 struct bnxt_ulp_mapper_ident_info *ident,
535 struct ulp_flow_db_res_params fid_parms;
538 struct tf_alloc_identifier_parms iparms = { 0 };
539 struct tf_free_identifier_parms free_parms = { 0 };
543 tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
545 BNXT_TF_DBG(ERR, "Failed to get tf pointer\n");
549 idx = ident->regfile_idx;
551 iparms.ident_type = ident->ident_type;
552 iparms.dir = tbl->direction;
554 rc = tf_alloc_identifier(tfp, &iparms);
556 BNXT_TF_DBG(ERR, "Alloc ident %s:%d failed.\n",
557 (iparms.dir == TF_DIR_RX) ? "RX" : "TX",
562 id = (uint64_t)tfp_cpu_to_be_64(iparms.id);
563 if (!ulp_regfile_write(parms->regfile, idx, id)) {
564 BNXT_TF_DBG(ERR, "Regfile[%d] write failed.\n", idx);
566 /* Need to free the identifier, so goto error */
570 /* Link the resource to the flow in the flow db */
572 memset(&fid_parms, 0, sizeof(fid_parms));
573 fid_parms.direction = tbl->direction;
574 fid_parms.resource_func = ident->resource_func;
575 fid_parms.resource_type = ident->ident_type;
576 fid_parms.resource_hndl = iparms.id;
577 fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
579 rc = ulp_flow_db_resource_add(parms->ulp_ctx,
584 BNXT_TF_DBG(ERR, "Failed to link res to flow rc = %d\n",
586 /* Need to free the identifier, so goto error */
596 /* Need to free the identifier */
597 free_parms.dir = tbl->direction;
598 free_parms.ident_type = ident->ident_type;
599 free_parms.id = iparms.id;
601 (void)tf_free_identifier(tfp, &free_parms);
603 BNXT_TF_DBG(ERR, "Ident process failed for %s:%s\n",
605 (tbl->direction == TF_DIR_RX) ? "RX" : "TX");
610 ulp_mapper_result_field_process(struct bnxt_ulp_mapper_parms *parms,
612 struct bnxt_ulp_mapper_result_field_info *fld,
613 struct ulp_blob *blob,
616 uint16_t idx, size_idx;
619 uint32_t val_size = 0, field_size = 0;
623 switch (fld->result_opcode) {
624 case BNXT_ULP_MAPPER_OPC_SET_TO_CONSTANT:
625 val = fld->result_operand;
626 if (!ulp_blob_push(blob, val, fld->field_bit_size)) {
627 BNXT_TF_DBG(ERR, "%s failed to add field\n", name);
631 case BNXT_ULP_MAPPER_OPC_SET_TO_ACT_PROP:
632 if (!ulp_operand_read(fld->result_operand,
633 (uint8_t *)&idx, sizeof(uint16_t))) {
634 BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
637 idx = tfp_be_to_cpu_16(idx);
639 if (idx >= BNXT_ULP_ACT_PROP_IDX_LAST) {
640 BNXT_TF_DBG(ERR, "%s act_prop[%d] oob\n", name, idx);
643 val = &parms->act_prop->act_details[idx];
644 field_size = ulp_mapper_act_prop_size_get(idx);
645 if (fld->field_bit_size < ULP_BYTE_2_BITS(field_size)) {
646 field_size = field_size -
647 ((fld->field_bit_size + 7) / 8);
650 if (!ulp_blob_push(blob, val, fld->field_bit_size)) {
651 BNXT_TF_DBG(ERR, "%s push field failed\n", name);
655 case BNXT_ULP_MAPPER_OPC_SET_TO_ACT_BIT:
656 if (!ulp_operand_read(fld->result_operand,
657 (uint8_t *)&act_bit, sizeof(uint64_t))) {
658 BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
661 act_bit = tfp_be_to_cpu_64(act_bit);
662 act_val = ULP_BITMAP_ISSET(parms->act_bitmap->bits, act_bit);
663 if (fld->field_bit_size > ULP_BYTE_2_BITS(sizeof(act_val))) {
664 BNXT_TF_DBG(ERR, "%s field size is incorrect\n", name);
667 if (!ulp_blob_push(blob, &act_val, fld->field_bit_size)) {
668 BNXT_TF_DBG(ERR, "%s push field failed\n", name);
673 case BNXT_ULP_MAPPER_OPC_SET_TO_ENCAP_ACT_PROP_SZ:
674 if (!ulp_operand_read(fld->result_operand,
675 (uint8_t *)&idx, sizeof(uint16_t))) {
676 BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
679 idx = tfp_be_to_cpu_16(idx);
681 if (idx >= BNXT_ULP_ACT_PROP_IDX_LAST) {
682 BNXT_TF_DBG(ERR, "%s act_prop[%d] oob\n", name, idx);
685 val = &parms->act_prop->act_details[idx];
687 /* get the size index next */
688 if (!ulp_operand_read(&fld->result_operand[sizeof(uint16_t)],
689 (uint8_t *)&size_idx, sizeof(uint16_t))) {
690 BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
693 size_idx = tfp_be_to_cpu_16(size_idx);
695 if (size_idx >= BNXT_ULP_ACT_PROP_IDX_LAST) {
696 BNXT_TF_DBG(ERR, "act_prop[%d] oob\n", size_idx);
699 memcpy(&val_size, &parms->act_prop->act_details[size_idx],
701 val_size = tfp_be_to_cpu_32(val_size);
702 val_size = ULP_BYTE_2_BITS(val_size);
703 ulp_blob_push_encap(blob, val, val_size);
705 case BNXT_ULP_MAPPER_OPC_SET_TO_REGFILE:
706 if (!ulp_operand_read(fld->result_operand,
707 (uint8_t *)&idx, sizeof(uint16_t))) {
708 BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
712 idx = tfp_be_to_cpu_16(idx);
713 /* Uninitialized regfile entries return 0 */
714 if (!ulp_regfile_read(parms->regfile, idx, ®val)) {
715 BNXT_TF_DBG(ERR, "%s regfile[%d] read oob\n",
720 val = ulp_blob_push_64(blob, ®val, fld->field_bit_size);
722 BNXT_TF_DBG(ERR, "%s push field failed\n", name);
726 case BNXT_ULP_MAPPER_OPC_SET_TO_GLB_REGFILE:
727 if (!ulp_operand_read(fld->result_operand,
730 BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
733 idx = tfp_be_to_cpu_16(idx);
734 if (ulp_mapper_glb_resource_read(parms->mapper_data,
737 BNXT_TF_DBG(ERR, "%s regfile[%d] read failed.\n",
741 val = ulp_blob_push_64(blob, ®val, fld->field_bit_size);
743 BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
747 case BNXT_ULP_MAPPER_OPC_SET_TO_COMP_FIELD:
748 if (!ulp_operand_read(fld->result_operand,
751 BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
754 idx = tfp_be_to_cpu_16(idx);
755 if (idx < BNXT_ULP_CF_IDX_LAST)
756 val = ulp_blob_push_32(blob, &parms->comp_fld[idx],
757 fld->field_bit_size);
759 BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
763 case BNXT_ULP_MAPPER_OPC_SET_TO_ZERO:
764 if (ulp_blob_pad_push(blob, fld->field_bit_size) < 0) {
765 BNXT_TF_DBG(ERR, "%s too large for blob\n", name);
776 /* Function to alloc action record and set the table. */
778 ulp_mapper_keymask_field_process(struct bnxt_ulp_mapper_parms *parms,
780 struct bnxt_ulp_mapper_class_key_field_info *f,
781 struct ulp_blob *blob,
786 uint16_t idx, bitlen;
789 struct ulp_regfile *regfile = parms->regfile;
791 struct bnxt_ulp_mapper_class_key_field_info *fld = f;
795 operand = fld->spec_operand;
796 opcode = fld->spec_opcode;
798 operand = fld->mask_operand;
799 opcode = fld->mask_opcode;
802 bitlen = fld->field_bit_size;
805 case BNXT_ULP_MAPPER_OPC_SET_TO_CONSTANT:
807 if (!ulp_blob_push(blob, val, bitlen)) {
808 BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
812 case BNXT_ULP_MAPPER_OPC_SET_TO_ZERO:
813 if (ulp_blob_pad_push(blob, bitlen) < 0) {
814 BNXT_TF_DBG(ERR, "%s pad too large for blob\n", name);
819 case BNXT_ULP_MAPPER_OPC_SET_TO_HDR_FIELD:
820 if (!ulp_operand_read(operand, (uint8_t *)&idx,
822 BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
825 idx = tfp_be_to_cpu_16(idx);
827 val = parms->hdr_field[idx].spec;
829 val = parms->hdr_field[idx].mask;
832 * Need to account for how much data was pushed to the header
833 * field vs how much is to be inserted in the key/mask.
835 field_size = parms->hdr_field[idx].size;
836 if (bitlen < ULP_BYTE_2_BITS(field_size)) {
837 field_size = field_size - ((bitlen + 7) / 8);
841 if (!ulp_blob_push(blob, val, bitlen)) {
842 BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
846 case BNXT_ULP_MAPPER_OPC_SET_TO_COMP_FIELD:
847 if (!ulp_operand_read(operand, (uint8_t *)&idx,
849 BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
852 idx = tfp_be_to_cpu_16(idx);
853 if (idx < BNXT_ULP_CF_IDX_LAST)
854 val = ulp_blob_push_32(blob, &parms->comp_fld[idx],
857 BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
861 case BNXT_ULP_MAPPER_OPC_SET_TO_REGFILE:
862 if (!ulp_operand_read(operand, (uint8_t *)&idx,
864 BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
867 idx = tfp_be_to_cpu_16(idx);
869 if (!ulp_regfile_read(regfile, idx, &val64)) {
870 BNXT_TF_DBG(ERR, "%s regfile[%d] read failed.\n",
875 val = ulp_blob_push_64(blob, &val64, bitlen);
877 BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
881 case BNXT_ULP_MAPPER_OPC_SET_TO_GLB_REGFILE:
882 if (!ulp_operand_read(operand, (uint8_t *)&idx,
884 BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
887 idx = tfp_be_to_cpu_16(idx);
888 if (ulp_mapper_glb_resource_read(parms->mapper_data,
891 BNXT_TF_DBG(ERR, "%s regfile[%d] read failed.\n",
895 val = ulp_blob_push_64(blob, &val64, bitlen);
897 BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
909 ulp_mapper_mark_gfid_process(struct bnxt_ulp_mapper_parms *parms,
910 struct bnxt_ulp_mapper_tbl_info *tbl,
913 enum bnxt_ulp_mark_db_opcode mark_op = tbl->mark_db_opcode;
914 struct ulp_flow_db_res_params fid_parms;
915 uint32_t mark, gfid, mark_flag;
918 if (mark_op == BNXT_ULP_MARK_DB_OPCODE_NOP ||
919 !(mark_op == BNXT_ULP_MARK_DB_OPCODE_SET_IF_MARK_ACTION &&
920 ULP_BITMAP_ISSET(parms->act_bitmap->bits,
921 BNXT_ULP_ACTION_BIT_MARK)))
922 return rc; /* no need to perform gfid process */
924 /* Get the mark id details from action property */
925 memcpy(&mark, &parms->act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_MARK],
927 mark = tfp_be_to_cpu_32(mark);
929 TF_GET_GFID_FROM_FLOW_ID(flow_id, gfid);
930 mark_flag = BNXT_ULP_MARK_GLOBAL_HW_FID;
931 rc = ulp_mark_db_mark_add(parms->ulp_ctx, mark_flag,
934 BNXT_TF_DBG(ERR, "Failed to add mark to flow\n");
937 fid_parms.direction = tbl->direction;
938 fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_HW_FID;
939 fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
940 fid_parms.resource_type = mark_flag;
941 fid_parms.resource_hndl = gfid;
942 rc = ulp_flow_db_resource_add(parms->ulp_ctx,
947 BNXT_TF_DBG(ERR, "Fail to link res to flow rc = %d\n", rc);
952 ulp_mapper_mark_act_ptr_process(struct bnxt_ulp_mapper_parms *parms,
953 struct bnxt_ulp_mapper_tbl_info *tbl)
955 enum bnxt_ulp_mark_db_opcode mark_op = tbl->mark_db_opcode;
956 struct ulp_flow_db_res_params fid_parms;
957 uint32_t act_idx, mark, mark_flag;
961 if (mark_op == BNXT_ULP_MARK_DB_OPCODE_NOP ||
962 !(mark_op == BNXT_ULP_MARK_DB_OPCODE_SET_IF_MARK_ACTION &&
963 ULP_BITMAP_ISSET(parms->act_bitmap->bits,
964 BNXT_ULP_ACTION_BIT_MARK)))
965 return rc; /* no need to perform mark action process */
967 /* Get the mark id details from action property */
968 memcpy(&mark, &parms->act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_MARK],
970 mark = tfp_be_to_cpu_32(mark);
972 if (!ulp_regfile_read(parms->regfile,
973 BNXT_ULP_REGFILE_INDEX_MAIN_ACTION_PTR,
975 BNXT_TF_DBG(ERR, "read action ptr main failed\n");
978 act_idx = tfp_be_to_cpu_64(val64);
979 mark_flag = BNXT_ULP_MARK_LOCAL_HW_FID;
980 rc = ulp_mark_db_mark_add(parms->ulp_ctx, mark_flag,
983 BNXT_TF_DBG(ERR, "Failed to add mark to flow\n");
986 fid_parms.direction = tbl->direction;
987 fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_HW_FID;
988 fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
989 fid_parms.resource_type = mark_flag;
990 fid_parms.resource_hndl = act_idx;
991 rc = ulp_flow_db_resource_add(parms->ulp_ctx,
996 BNXT_TF_DBG(ERR, "Fail to link res to flow rc = %d\n", rc);
1001 ulp_mapper_mark_vfr_idx_process(struct bnxt_ulp_mapper_parms *parms,
1002 struct bnxt_ulp_mapper_tbl_info *tbl)
1004 struct ulp_flow_db_res_params fid_parms;
1005 uint32_t act_idx, mark, mark_flag;
1007 enum bnxt_ulp_mark_db_opcode mark_op = tbl->mark_db_opcode;
1010 if (mark_op == BNXT_ULP_MARK_DB_OPCODE_NOP ||
1011 mark_op == BNXT_ULP_MARK_DB_OPCODE_SET_IF_MARK_ACTION)
1012 return rc; /* no need to perform mark action process */
1014 /* Get the mark id details from the computed field of dev port id */
1015 mark = ULP_COMP_FLD_IDX_RD(parms, BNXT_ULP_CF_IDX_DEV_PORT_ID);
1017 /* Get the main action pointer */
1018 if (!ulp_regfile_read(parms->regfile,
1019 BNXT_ULP_REGFILE_INDEX_MAIN_ACTION_PTR,
1021 BNXT_TF_DBG(ERR, "read action ptr main failed\n");
1024 act_idx = tfp_be_to_cpu_64(val64);
1026 /* Set the mark flag to local fid and vfr flag */
1027 mark_flag = BNXT_ULP_MARK_LOCAL_HW_FID | BNXT_ULP_MARK_VFR_ID;
1029 rc = ulp_mark_db_mark_add(parms->ulp_ctx, mark_flag,
1032 BNXT_TF_DBG(ERR, "Failed to add mark to flow\n");
1035 fid_parms.direction = tbl->direction;
1036 fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_HW_FID;
1037 fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
1038 fid_parms.resource_type = mark_flag;
1039 fid_parms.resource_hndl = act_idx;
1040 rc = ulp_flow_db_resource_add(parms->ulp_ctx,
1045 BNXT_TF_DBG(ERR, "Fail to link res to flow rc = %d\n", rc);
1050 ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
1051 struct bnxt_ulp_mapper_tbl_info *tbl)
1053 struct bnxt_ulp_mapper_class_key_field_info *kflds;
1054 struct ulp_blob key, mask, data;
1055 uint32_t i, num_kflds;
1058 struct tf_alloc_tcam_entry_parms aparms = { 0 };
1059 struct tf_set_tcam_entry_parms sparms = { 0 };
1060 struct ulp_flow_db_res_params fid_parms = { 0 };
1061 struct tf_free_tcam_entry_parms free_parms = { 0 };
1063 uint16_t tmplen = 0;
1065 /* Skip this if was handled by the cache. */
1066 if (parms->tcam_tbl_opc == BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_SKIP) {
1067 parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL;
1071 tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
1073 BNXT_TF_DBG(ERR, "Failed to get truflow pointer\n");
1077 kflds = ulp_mapper_key_fields_get(tbl, &num_kflds);
1078 if (!kflds || !num_kflds) {
1079 BNXT_TF_DBG(ERR, "Failed to get key fields\n");
1083 if (!ulp_blob_init(&key, tbl->key_bit_size,
1084 parms->device_params->byte_order) ||
1085 !ulp_blob_init(&mask, tbl->key_bit_size,
1086 parms->device_params->byte_order) ||
1087 !ulp_blob_init(&data, tbl->result_bit_size,
1088 parms->device_params->byte_order)) {
1089 BNXT_TF_DBG(ERR, "blob inits failed.\n");
1093 /* create the key/mask */
1095 * NOTE: The WC table will require some kind of flag to handle the
1096 * mode bits within the key/mask
1098 for (i = 0; i < num_kflds; i++) {
1100 rc = ulp_mapper_keymask_field_process(parms, tbl->direction,
1102 &key, 1, "TCAM Key");
1104 BNXT_TF_DBG(ERR, "Key field set failed.\n");
1108 /* Setup the mask */
1109 rc = ulp_mapper_keymask_field_process(parms, tbl->direction,
1111 &mask, 0, "TCAM Mask");
1113 BNXT_TF_DBG(ERR, "Mask field set failed.\n");
1118 aparms.dir = tbl->direction;
1119 aparms.tcam_tbl_type = tbl->resource_type;
1120 aparms.search_enable = tbl->srch_b4_alloc;
1121 aparms.key_sz_in_bits = tbl->key_bit_size;
1122 aparms.key = ulp_blob_data_get(&key, &tmplen);
1123 if (tbl->key_bit_size != tmplen) {
1124 BNXT_TF_DBG(ERR, "Key len (%d) != Expected (%d)\n",
1125 tmplen, tbl->key_bit_size);
1129 aparms.mask = ulp_blob_data_get(&mask, &tmplen);
1130 if (tbl->key_bit_size != tmplen) {
1131 BNXT_TF_DBG(ERR, "Mask len (%d) != Expected (%d)\n",
1132 tmplen, tbl->key_bit_size);
1136 aparms.priority = tbl->priority;
1139 * All failures after this succeeds require the entry to be freed.
1140 * cannot return directly on failure, but needs to goto error
1142 rc = tf_alloc_tcam_entry(tfp, &aparms);
1144 BNXT_TF_DBG(ERR, "tcam alloc failed rc=%d.\n", rc);
1150 /* Build the result */
1151 if (!tbl->srch_b4_alloc || !hit) {
1152 struct bnxt_ulp_mapper_result_field_info *dflds;
1153 struct bnxt_ulp_mapper_ident_info *idents;
1154 uint32_t num_dflds, num_idents;
1155 uint32_t encap_flds = 0;
1158 * Since the cache entry is responsible for allocating
1159 * identifiers when in use, allocate the identifiers only
1160 * during normal processing.
1162 if (parms->tcam_tbl_opc ==
1163 BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL) {
1164 idents = ulp_mapper_ident_fields_get(tbl, &num_idents);
1166 for (i = 0; i < num_idents; i++) {
1167 rc = ulp_mapper_ident_process(parms, tbl,
1169 /* Already logged the error, just return */
1175 /* Create the result data blob */
1176 dflds = ulp_mapper_result_fields_get(tbl, &num_dflds,
1178 if (!dflds || !num_dflds || encap_flds) {
1179 BNXT_TF_DBG(ERR, "Failed to get data fields.\n");
1184 for (i = 0; i < num_dflds; i++) {
1185 rc = ulp_mapper_result_field_process(parms,
1191 BNXT_TF_DBG(ERR, "Failed to set data fields\n");
1196 sparms.dir = aparms.dir;
1197 sparms.tcam_tbl_type = aparms.tcam_tbl_type;
1198 sparms.idx = aparms.idx;
1199 /* Already verified the key/mask lengths */
1200 sparms.key = ulp_blob_data_get(&key, &tmplen);
1201 sparms.mask = ulp_blob_data_get(&mask, &tmplen);
1202 sparms.key_sz_in_bits = tbl->key_bit_size;
1203 sparms.result = ulp_blob_data_get(&data, &tmplen);
1205 if (tbl->result_bit_size != tmplen) {
1206 BNXT_TF_DBG(ERR, "Result len (%d) != Expected (%d)\n",
1207 tmplen, tbl->result_bit_size);
1211 sparms.result_sz_in_bits = tbl->result_bit_size;
1213 rc = tf_set_tcam_entry(tfp, &sparms);
1215 BNXT_TF_DBG(ERR, "tcam[%d][%s][%d] write failed.\n",
1216 sparms.tcam_tbl_type,
1217 (sparms.dir == TF_DIR_RX) ? "RX" : "TX",
1222 /* Update cache with TCAM index if the was cache allocated. */
1223 if (parms->tcam_tbl_opc ==
1224 BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_ALLOC) {
1225 if (!parms->cache_ptr) {
1226 BNXT_TF_DBG(ERR, "Unable to update cache");
1230 parms->cache_ptr->tcam_idx = aparms.idx;
1234 rc = ulp_mapper_mark_act_ptr_process(parms, tbl);
1239 BNXT_TF_DBG(ERR, "Not supporting search before alloc now\n");
1245 * Only link the entry to the flow db in the event that cache was not
1248 if (parms->tcam_tbl_opc == BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL) {
1249 fid_parms.direction = tbl->direction;
1250 fid_parms.resource_func = tbl->resource_func;
1251 fid_parms.resource_type = tbl->resource_type;
1252 fid_parms.critical_resource = tbl->critical_resource;
1253 fid_parms.resource_hndl = aparms.idx;
1254 rc = ulp_flow_db_resource_add(parms->ulp_ctx,
1260 "Failed to link resource to flow rc = %d\n",
1262 /* Need to free the identifier, so goto error */
1267 * Reset the tcam table opcode to normal in case the next tcam
1268 * entry does not use cache.
1270 parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL;
1271 parms->cache_ptr = NULL;
1276 parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL;
1277 free_parms.dir = tbl->direction;
1278 free_parms.tcam_tbl_type = tbl->resource_type;
1279 free_parms.idx = aparms.idx;
1280 trc = tf_free_tcam_entry(tfp, &free_parms);
1282 BNXT_TF_DBG(ERR, "Failed to free tcam[%d][%d][%d] on failure\n",
1283 tbl->resource_type, tbl->direction, aparms.idx);
1289 ulp_mapper_em_tbl_process(struct bnxt_ulp_mapper_parms *parms,
1290 struct bnxt_ulp_mapper_tbl_info *tbl)
1292 struct bnxt_ulp_mapper_class_key_field_info *kflds;
1293 struct bnxt_ulp_mapper_result_field_info *dflds;
1294 struct ulp_blob key, data;
1295 uint32_t i, num_kflds, num_dflds;
1297 struct tf *tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
1298 struct ulp_flow_db_res_params fid_parms = { 0 };
1299 struct tf_insert_em_entry_parms iparms = { 0 };
1300 struct tf_delete_em_entry_parms free_parms = { 0 };
1302 enum bnxt_ulp_flow_mem_type mtype = parms->device_params->flow_mem_type;
1304 uint32_t encap_flds = 0;
1306 kflds = ulp_mapper_key_fields_get(tbl, &num_kflds);
1307 if (!kflds || !num_kflds) {
1308 BNXT_TF_DBG(ERR, "Failed to get key fields\n");
1312 /* Initialize the key/result blobs */
1313 if (!ulp_blob_init(&key, tbl->blob_key_bit_size,
1314 parms->device_params->byte_order) ||
1315 !ulp_blob_init(&data, tbl->result_bit_size,
1316 parms->device_params->byte_order)) {
1317 BNXT_TF_DBG(ERR, "blob inits failed.\n");
1321 /* create the key */
1322 for (i = 0; i < num_kflds; i++) {
1324 rc = ulp_mapper_keymask_field_process(parms, tbl->direction,
1328 BNXT_TF_DBG(ERR, "Key field set failed.\n");
1334 * TBD: Normally should process identifiers in case of using recycle or
1335 * loopback. Not supporting recycle for now.
1338 /* Create the result data blob */
1339 dflds = ulp_mapper_result_fields_get(tbl, &num_dflds, &encap_flds);
1340 if (!dflds || !num_dflds || encap_flds) {
1341 BNXT_TF_DBG(ERR, "Failed to get data fields.\n");
1345 for (i = 0; i < num_dflds; i++) {
1346 struct bnxt_ulp_mapper_result_field_info *fld;
1350 rc = ulp_mapper_result_field_process(parms,
1356 BNXT_TF_DBG(ERR, "Failed to set data fields.\n");
1360 #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
1361 ulp_mapper_result_dump("EEM Result", tbl, &data);
1364 /* do the transpose for the internal EM keys */
1365 if (tbl->resource_type == TF_MEM_INTERNAL)
1366 ulp_blob_perform_byte_reverse(&key);
1368 rc = bnxt_ulp_cntxt_tbl_scope_id_get(parms->ulp_ctx,
1369 &iparms.tbl_scope_id);
1371 BNXT_TF_DBG(ERR, "Failed to get table scope rc=%d\n", rc);
1376 * NOTE: the actual blob size will differ from the size in the tbl
1377 * entry due to the padding.
1379 iparms.dup_check = 0;
1380 iparms.dir = tbl->direction;
1381 iparms.mem = tbl->resource_type;
1382 iparms.key = ulp_blob_data_get(&key, &tmplen);
1383 iparms.key_sz_in_bits = tbl->key_bit_size;
1384 iparms.em_record = ulp_blob_data_get(&data, &tmplen);
1385 iparms.em_record_sz_in_bits = tbl->result_bit_size;
1387 rc = tf_insert_em_entry(tfp, &iparms);
1389 BNXT_TF_DBG(ERR, "Failed to insert em entry rc=%d.\n", rc);
1393 /* Mark action process */
1394 if (mtype == BNXT_ULP_FLOW_MEM_TYPE_EXT &&
1395 tbl->resource_type == TF_MEM_EXTERNAL)
1396 rc = ulp_mapper_mark_gfid_process(parms, tbl, iparms.flow_id);
1397 else if (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT &&
1398 tbl->resource_type == TF_MEM_INTERNAL)
1399 rc = ulp_mapper_mark_act_ptr_process(parms, tbl);
1401 BNXT_TF_DBG(ERR, "Failed to add mark to flow\n");
1405 /* Link the EM resource to the flow in the flow db */
1406 memset(&fid_parms, 0, sizeof(fid_parms));
1407 fid_parms.direction = tbl->direction;
1408 fid_parms.resource_func = tbl->resource_func;
1409 fid_parms.resource_type = tbl->resource_type;
1410 fid_parms.critical_resource = tbl->critical_resource;
1411 fid_parms.resource_hndl = iparms.flow_handle;
1413 rc = ulp_flow_db_resource_add(parms->ulp_ctx,
1418 BNXT_TF_DBG(ERR, "Fail to link res to flow rc = %d\n",
1420 /* Need to free the identifier, so goto error */
1426 free_parms.dir = iparms.dir;
1427 free_parms.mem = iparms.mem;
1428 free_parms.tbl_scope_id = iparms.tbl_scope_id;
1429 free_parms.flow_handle = iparms.flow_handle;
1431 trc = tf_delete_em_entry(tfp, &free_parms);
1433 BNXT_TF_DBG(ERR, "Failed to delete EM entry on failed add\n");
1439 ulp_mapper_index_tbl_process(struct bnxt_ulp_mapper_parms *parms,
1440 struct bnxt_ulp_mapper_tbl_info *tbl,
1443 struct bnxt_ulp_mapper_result_field_info *flds;
1444 struct ulp_flow_db_res_params fid_parms;
1445 struct ulp_blob data;
1448 uint32_t i, num_flds;
1449 int32_t rc = 0, trc = 0;
1450 struct tf_alloc_tbl_entry_parms aparms = { 0 };
1451 struct tf_set_tbl_entry_parms sparms = { 0 };
1452 struct tf_free_tbl_entry_parms free_parms = { 0 };
1453 uint32_t tbl_scope_id;
1454 struct tf *tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
1456 uint32_t encap_flds = 0;
1458 /* Get the scope id first */
1459 rc = bnxt_ulp_cntxt_tbl_scope_id_get(parms->ulp_ctx, &tbl_scope_id);
1461 BNXT_TF_DBG(ERR, "Failed to get table scope rc=%d\n", rc);
1465 /* use the max size if encap is enabled */
1466 if (tbl->encap_num_fields)
1467 bit_size = BNXT_ULP_FLMP_BLOB_SIZE_IN_BITS;
1469 bit_size = tbl->result_bit_size;
1471 /* Initialize the blob data */
1472 if (!ulp_blob_init(&data, bit_size,
1473 parms->device_params->byte_order)) {
1474 BNXT_TF_DBG(ERR, "Failed initial index table blob\n");
1478 /* Get the result fields list */
1480 flds = ulp_mapper_result_fields_get(tbl, &num_flds,
1483 flds = ulp_mapper_act_result_fields_get(tbl, &num_flds,
1486 if (!flds || (!num_flds && !encap_flds)) {
1487 BNXT_TF_DBG(ERR, "template undefined for the index table\n");
1491 /* process the result fields, loop through them */
1492 for (i = 0; i < (num_flds + encap_flds); i++) {
1493 /* set the swap index if encap swap bit is enabled */
1494 if (parms->device_params->encap_byte_swap && encap_flds &&
1496 ulp_blob_encap_swap_idx_set(&data);
1498 /* Process the result fields */
1499 rc = ulp_mapper_result_field_process(parms,
1505 BNXT_TF_DBG(ERR, "data field failed\n");
1510 /* if encap bit swap is enabled perform the bit swap */
1511 if (parms->device_params->encap_byte_swap && encap_flds) {
1512 ulp_blob_perform_encap_swap(&data);
1513 #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
1514 BNXT_TF_DBG(INFO, "Dump after encap swap\n");
1515 ulp_mapper_blob_dump(&data);
1519 /* Perform the tf table allocation by filling the alloc params */
1520 aparms.dir = tbl->direction;
1521 aparms.type = tbl->resource_type;
1522 aparms.search_enable = tbl->srch_b4_alloc;
1523 aparms.result = ulp_blob_data_get(&data, &tmplen);
1524 aparms.result_sz_in_bytes = ULP_BITS_2_BYTE(tmplen);
1525 aparms.tbl_scope_id = tbl_scope_id;
1527 /* All failures after the alloc succeeds require a free */
1528 rc = tf_alloc_tbl_entry(tfp, &aparms);
1530 BNXT_TF_DBG(ERR, "Alloc table[%d][%s] failed rc=%d\n",
1532 (aparms.dir == TF_DIR_RX) ? "RX" : "TX",
1538 * calculate the idx for the result record, for external EM the offset
1539 * needs to be shifted accordingly. If external non-inline table types
1540 * are used then need to revisit this logic.
1542 if (aparms.type == TF_TBL_TYPE_EXT)
1543 idx = TF_ACT_REC_OFFSET_2_PTR(aparms.idx);
1547 /* Always storing values in Regfile in BE */
1548 idx = tfp_cpu_to_be_64(idx);
1549 rc = ulp_regfile_write(parms->regfile, tbl->regfile_idx, idx);
1551 BNXT_TF_DBG(ERR, "Write regfile[%d] failed\n",
1556 /* Perform the tf table set by filling the set params */
1557 if (!tbl->srch_b4_alloc || !aparms.hit) {
1558 sparms.dir = tbl->direction;
1559 sparms.type = tbl->resource_type;
1560 sparms.data = ulp_blob_data_get(&data, &tmplen);
1561 sparms.data_sz_in_bytes = ULP_BITS_2_BYTE(tmplen);
1562 sparms.idx = aparms.idx;
1563 sparms.tbl_scope_id = tbl_scope_id;
1565 rc = tf_set_tbl_entry(tfp, &sparms);
1567 BNXT_TF_DBG(ERR, "Set table[%d][%s][%d] failed rc=%d\n",
1569 (sparms.dir == TF_DIR_RX) ? "RX" : "TX",
1576 /* Link the resource to the flow in the flow db */
1577 memset(&fid_parms, 0, sizeof(fid_parms));
1578 fid_parms.direction = tbl->direction;
1579 fid_parms.resource_func = tbl->resource_func;
1580 fid_parms.resource_type = tbl->resource_type;
1581 fid_parms.resource_hndl = aparms.idx;
1582 fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
1584 rc = ulp_flow_db_resource_add(parms->ulp_ctx,
1589 BNXT_TF_DBG(ERR, "Failed to link resource to flow rc = %d\n",
1594 /* Perform the VF rep action */
1595 rc = ulp_mapper_mark_vfr_idx_process(parms, tbl);
1597 BNXT_TF_DBG(ERR, "Failed to add vfr mark rc = %d\n", rc);
1603 * Free the allocated resource since we failed to either
1604 * write to the entry or link the flow
1606 free_parms.dir = tbl->direction;
1607 free_parms.type = tbl->resource_type;
1608 free_parms.idx = aparms.idx;
1609 free_parms.tbl_scope_id = tbl_scope_id;
1611 trc = tf_free_tbl_entry(tfp, &free_parms);
1613 BNXT_TF_DBG(ERR, "Failed to free tbl entry on failure\n");
1619 ulp_mapper_cache_tbl_process(struct bnxt_ulp_mapper_parms *parms,
1620 struct bnxt_ulp_mapper_tbl_info *tbl)
1622 struct bnxt_ulp_mapper_class_key_field_info *kflds;
1623 struct bnxt_ulp_mapper_cache_entry *cache_entry;
1624 struct bnxt_ulp_mapper_ident_info *idents;
1625 uint32_t i, num_kflds = 0, num_idents = 0;
1626 struct ulp_flow_db_res_params fid_parms;
1627 struct tf_free_identifier_parms fparms;
1628 uint16_t tmplen, tmp_ident;
1629 struct ulp_blob key;
1635 /* Get the key fields list and build the key. */
1636 kflds = ulp_mapper_key_fields_get(tbl, &num_kflds);
1637 if (!kflds || !num_kflds) {
1638 BNXT_TF_DBG(ERR, "Failed to get key fields\n");
1641 if (!ulp_blob_init(&key, tbl->key_bit_size,
1642 parms->device_params->byte_order)) {
1643 BNXT_TF_DBG(ERR, "Failed to alloc blob\n");
1646 for (i = 0; i < num_kflds; i++) {
1648 rc = ulp_mapper_keymask_field_process(parms, tbl->direction,
1650 &key, 1, "Cache Key");
1653 "Failed to create key for Cache rc=%d\n",
1660 * Perform the lookup in the cache table with constructed key. The
1661 * cache_key is a byte array of tmplen, it needs to be converted to a
1662 * index for the cache table.
1664 cache_key = ulp_blob_data_get(&key, &tmplen);
1665 ckey = (uint16_t *)cache_key;
1668 * The id computed based on resource sub type and direction where
1669 * dir is the bit0 and rest of the bits come from resource
1672 cache_entry = ulp_mapper_cache_entry_get(parms->ulp_ctx,
1673 (tbl->resource_sub_type << 1 |
1674 (tbl->direction & 0x1)),
1678 * Get the identifier list for processing by both the hit and miss
1681 idents = ulp_mapper_ident_fields_get(tbl, &num_idents);
1683 if (!cache_entry->ref_count) {
1684 /* Initialize the cache entry */
1685 cache_entry->tcam_idx = 0;
1686 cache_entry->ref_count = 0;
1687 for (i = 0; i < BNXT_ULP_CACHE_TBL_IDENT_MAX_NUM; i++)
1688 cache_entry->idents[i] = ULP_IDENTS_INVALID;
1690 /* Need to allocate identifiers for storing in the cache. */
1691 for (i = 0; i < num_idents; i++) {
1693 * Since we are using the cache, the identifier does not
1694 * get added to the flow db. Pass in the pointer to the
1697 rc = ulp_mapper_ident_process(parms, tbl,
1698 &idents[i], &tmp_ident);
1702 cache_entry->ident_types[i] = idents[i].ident_type;
1703 cache_entry->idents[i] = tmp_ident;
1706 /* Tell the TCAM processor to alloc an entry */
1707 parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_ALLOC;
1708 /* Store the cache key for use by the tcam process code */
1709 parms->cache_ptr = cache_entry;
1711 /* Cache hit, get values from result. */
1712 for (i = 0; i < num_idents; i++) {
1713 regval = (uint64_t)cache_entry->idents[i];
1714 if (!ulp_regfile_write(parms->regfile,
1715 idents[i].regfile_idx,
1716 tfp_cpu_to_be_64(regval))) {
1718 "Failed to write to regfile\n");
1723 * The cached entry is being used, so let the tcam processing
1724 * know not to process this table.
1726 parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_SKIP;
1729 /* Made through the cache processing, increment the reference count. */
1730 cache_entry->ref_count++;
1732 /* Link the cache to the flow db. */
1733 memset(&fid_parms, 0, sizeof(fid_parms));
1734 fid_parms.direction = tbl->direction;
1735 fid_parms.resource_func = tbl->resource_func;
1738 * Cache resource type is composed of table_type, resource
1739 * sub type and direction, it needs to set appropriately via setter.
1741 ulp_mapper_cache_res_type_set(&fid_parms,
1743 (tbl->resource_sub_type << 1 |
1744 (tbl->direction & 0x1)));
1745 fid_parms.resource_hndl = (uint64_t)*ckey;
1746 fid_parms.critical_resource = tbl->critical_resource;
1747 rc = ulp_flow_db_resource_add(parms->ulp_ctx,
1752 BNXT_TF_DBG(ERR, "Failed to add cache to flow db.\n");
1757 * This error handling only gets called when the idents are being
1758 * allocated for the cache on misses. Using the num_idents that was
1761 for (i = 0; i < num_idents; i++) {
1762 if (cache_entry->idents[i] == ULP_IDENTS_INVALID)
1765 fparms.dir = tbl->direction;
1766 fparms.ident_type = idents[i].ident_type;
1767 fparms.id = cache_entry->idents[i];
1768 tf_free_identifier(parms->tfp, &fparms);
1775 ulp_mapper_if_tbl_process(struct bnxt_ulp_mapper_parms *parms,
1776 struct bnxt_ulp_mapper_tbl_info *tbl)
1778 struct bnxt_ulp_mapper_result_field_info *flds;
1779 struct ulp_blob data;
1782 uint32_t i, num_flds;
1784 struct tf_set_if_tbl_entry_parms iftbl_params = { 0 };
1785 struct tf *tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
1786 uint32_t encap_flds;
1788 /* Initialize the blob data */
1789 if (!ulp_blob_init(&data, tbl->result_bit_size,
1790 parms->device_params->byte_order)) {
1791 BNXT_TF_DBG(ERR, "Failed initial index table blob\n");
1795 /* Get the result fields list */
1796 flds = ulp_mapper_result_fields_get(tbl, &num_flds, &encap_flds);
1798 if (!flds || !num_flds || encap_flds) {
1799 BNXT_TF_DBG(ERR, "template undefined for the IF table\n");
1803 /* process the result fields, loop through them */
1804 for (i = 0; i < num_flds; i++) {
1805 /* Process the result fields */
1806 rc = ulp_mapper_result_field_process(parms,
1812 BNXT_TF_DBG(ERR, "data field failed\n");
1817 /* Get the index details from computed field */
1818 idx = ULP_COMP_FLD_IDX_RD(parms, tbl->comp_field_idx);
1820 /* Perform the tf table set by filling the set params */
1821 iftbl_params.dir = tbl->direction;
1822 iftbl_params.type = tbl->resource_type;
1823 iftbl_params.data = ulp_blob_data_get(&data, &tmplen);
1824 iftbl_params.data_sz_in_bytes = ULP_BITS_2_BYTE(tmplen);
1825 iftbl_params.idx = idx;
1827 rc = tf_set_if_tbl_entry(tfp, &iftbl_params);
1829 BNXT_TF_DBG(ERR, "Set table[%d][%s][%d] failed rc=%d\n",
1831 (iftbl_params.dir == TF_DIR_RX) ? "RX" : "TX",
1838 * TBD: Need to look at the need to store idx in flow db for restore
1839 * the table to its original state on deletion of this entry.
1845 ulp_mapper_glb_resource_info_init(struct tf *tfp,
1846 struct bnxt_ulp_mapper_data *mapper_data)
1848 struct bnxt_ulp_glb_resource_info *glb_res;
1849 uint32_t num_glb_res_ids, idx;
1852 glb_res = ulp_mapper_glb_resource_info_list_get(&num_glb_res_ids);
1853 if (!glb_res || !num_glb_res_ids) {
1854 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
1858 /* Iterate the global resources and process each one */
1859 for (idx = 0; idx < num_glb_res_ids; idx++) {
1860 switch (glb_res[idx].resource_func) {
1861 case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
1862 rc = ulp_mapper_resource_ident_allocate(tfp,
1867 BNXT_TF_DBG(ERR, "Global resource %x not supported\n",
1868 glb_res[idx].resource_func);
1876 * Function to process the action template. Iterate through the list
1877 * action info templates and process it.
1880 ulp_mapper_action_tbls_process(struct bnxt_ulp_mapper_parms *parms)
1884 struct bnxt_ulp_mapper_tbl_info *tbl;
1886 if (!parms->atbls || !parms->num_atbls) {
1887 BNXT_TF_DBG(ERR, "No action tables for template[%d][%d].\n",
1888 parms->dev_id, parms->act_tid);
1892 for (i = 0; i < parms->num_atbls; i++) {
1893 tbl = &parms->atbls[i];
1894 switch (tbl->resource_func) {
1895 case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
1896 rc = ulp_mapper_index_tbl_process(parms, tbl, false);
1898 BNXT_TF_DBG(ERR, "Resource type %d failed\n",
1899 tbl->resource_func);
1904 BNXT_TF_DBG(ERR, "Unexpected action resource %d\n",
1905 tbl->resource_func);
1913 /* Create the classifier table entries for a flow. */
1915 ulp_mapper_class_tbls_process(struct bnxt_ulp_mapper_parms *parms)
1923 if (!parms->ctbls || !parms->num_ctbls) {
1924 BNXT_TF_DBG(ERR, "No class tables for template[%d][%d].\n",
1925 parms->dev_id, parms->class_tid);
1929 for (i = 0; i < parms->num_ctbls; i++) {
1930 struct bnxt_ulp_mapper_tbl_info *tbl = &parms->ctbls[i];
1932 switch (tbl->resource_func) {
1933 case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE:
1934 rc = ulp_mapper_tcam_tbl_process(parms, tbl);
1936 case BNXT_ULP_RESOURCE_FUNC_EM_TABLE:
1937 rc = ulp_mapper_em_tbl_process(parms, tbl);
1939 case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
1940 rc = ulp_mapper_index_tbl_process(parms, tbl, true);
1942 case BNXT_ULP_RESOURCE_FUNC_CACHE_TABLE:
1943 rc = ulp_mapper_cache_tbl_process(parms, tbl);
1945 case BNXT_ULP_RESOURCE_FUNC_IF_TABLE:
1946 rc = ulp_mapper_if_tbl_process(parms, tbl);
1949 BNXT_TF_DBG(ERR, "Unexpected class resource %d\n",
1950 tbl->resource_func);
1955 BNXT_TF_DBG(ERR, "Resource type %d failed\n",
1956 tbl->resource_func);
1965 ulp_mapper_resource_free(struct bnxt_ulp_context *ulp,
1966 struct ulp_flow_db_res_params *res)
1972 BNXT_TF_DBG(ERR, "Unable to free resource\n ");
1976 tfp = bnxt_ulp_cntxt_tfp_get(ulp);
1978 BNXT_TF_DBG(ERR, "Unable to free resource failed to get tfp\n");
1982 switch (res->resource_func) {
1983 case BNXT_ULP_RESOURCE_FUNC_CACHE_TABLE:
1984 rc = ulp_mapper_cache_entry_free(ulp, tfp, res);
1986 case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE:
1987 rc = ulp_mapper_tcam_entry_free(ulp, tfp, res);
1989 case BNXT_ULP_RESOURCE_FUNC_EM_TABLE:
1990 rc = ulp_mapper_eem_entry_free(ulp, tfp, res);
1992 case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
1993 rc = ulp_mapper_index_entry_free(ulp, tfp, res);
1995 case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
1996 rc = ulp_mapper_ident_free(ulp, tfp, res);
1998 case BNXT_ULP_RESOURCE_FUNC_HW_FID:
1999 rc = ulp_mapper_mark_free(ulp, res);
2009 ulp_mapper_resources_free(struct bnxt_ulp_context *ulp_ctx,
2011 enum bnxt_ulp_flow_db_tables tbl_type)
2013 struct ulp_flow_db_res_params res_parms = { 0 };
2017 BNXT_TF_DBG(ERR, "Invalid parms, unable to free flow\n");
2022 * Set the critical resource on the first resource del, then iterate
2023 * while status is good
2025 res_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_YES;
2026 rc = ulp_flow_db_resource_del(ulp_ctx, tbl_type, fid, &res_parms);
2030 * This is unexpected on the first call to resource del.
2031 * It likely means that the flow did not exist in the flow db.
2033 BNXT_TF_DBG(ERR, "Flow[%d][0x%08x] failed to free (rc=%d)\n",
2039 trc = ulp_mapper_resource_free(ulp_ctx, &res_parms);
2042 * On fail, we still need to attempt to free the
2043 * remaining resources. Don't return
2046 "Flow[%d][0x%x] Res[%d][0x%016" PRIx64
2047 "] failed rc=%d.\n",
2048 tbl_type, fid, res_parms.resource_func,
2049 res_parms.resource_hndl, trc);
2051 /* All subsequent call require the non-critical_resource */
2052 res_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
2054 rc = ulp_flow_db_resource_del(ulp_ctx,
2060 /* Free the Flow ID since we've removed all resources */
2061 rc = ulp_flow_db_fid_free(ulp_ctx, tbl_type, fid);
2067 ulp_mapper_glb_resource_info_deinit(struct bnxt_ulp_context *ulp_ctx,
2068 struct bnxt_ulp_mapper_data *mapper_data)
2070 struct bnxt_ulp_mapper_glb_resource_entry *ent;
2071 struct ulp_flow_db_res_params res;
2074 /* Iterate the global resources and process each one */
2075 for (dir = TF_DIR_RX; dir < TF_DIR_MAX; dir++) {
2076 for (idx = 0; idx < BNXT_ULP_GLB_RESOURCE_INFO_TBL_MAX_SZ;
2078 ent = &mapper_data->glb_res_tbl[dir][idx];
2079 if (ent->resource_func ==
2080 BNXT_ULP_RESOURCE_FUNC_INVALID)
2082 memset(&res, 0, sizeof(struct ulp_flow_db_res_params));
2083 res.resource_func = ent->resource_func;
2084 res.direction = dir;
2085 res.resource_type = ent->resource_type;
2086 res.resource_hndl = ent->resource_hndl;
2087 ulp_mapper_resource_free(ulp_ctx, &res);
2093 ulp_mapper_flow_destroy(struct bnxt_ulp_context *ulp_ctx, uint32_t fid)
2096 BNXT_TF_DBG(ERR, "Invalid parms, unable to free flow\n");
2100 return ulp_mapper_resources_free(ulp_ctx,
2102 BNXT_ULP_REGULAR_FLOW_TABLE);
2105 /* Function to handle the mapping of the Flow to be compatible
2106 * with the underlying hardware.
2109 ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,
2110 struct bnxt_ulp_mapper_create_parms *cparms,
2113 struct bnxt_ulp_mapper_parms parms;
2114 struct ulp_regfile regfile;
2117 if (!ulp_ctx || !cparms)
2120 /* Initialize the parms structure */
2121 memset(&parms, 0, sizeof(parms));
2122 parms.act_prop = cparms->act_prop;
2123 parms.act_bitmap = cparms->act;
2124 parms.regfile = ®file;
2125 parms.hdr_field = cparms->hdr_field;
2126 parms.comp_fld = cparms->comp_fld;
2127 parms.tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
2128 parms.ulp_ctx = ulp_ctx;
2129 parms.tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL;
2131 /* Get the device id from the ulp context */
2132 if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &parms.dev_id)) {
2133 BNXT_TF_DBG(ERR, "Invalid ulp context\n");
2138 * Get the mapper data for dynamic mapper data such as default
2141 parms.mapper_data = (struct bnxt_ulp_mapper_data *)
2142 bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx);
2143 if (!parms.mapper_data) {
2144 BNXT_TF_DBG(ERR, "Failed to get the ulp mapper data\n");
2148 /* Get the action table entry from device id and act context id */
2149 parms.act_tid = cparms->act_tid;
2152 * Perform the action table get only if act template is not zero
2153 * for act template zero like for default rules ignore the action
2156 if (parms.act_tid) {
2157 parms.atbls = ulp_mapper_action_tbl_list_get(parms.dev_id,
2160 if (!parms.atbls || !parms.num_atbls) {
2161 BNXT_TF_DBG(ERR, "No action tables for %d:%d\n",
2162 parms.dev_id, parms.act_tid);
2167 /* Get the class table entry from device id and act context id */
2168 parms.class_tid = cparms->class_tid;
2169 parms.ctbls = ulp_mapper_class_tbl_list_get(parms.dev_id,
2173 if (!parms.ctbls || !parms.num_ctbls) {
2174 BNXT_TF_DBG(ERR, "No class tables for %d:%d\n",
2175 parms.dev_id, parms.class_tid);
2179 /* Get the device params, it will be used in later processing */
2180 parms.device_params = bnxt_ulp_device_params_get(parms.dev_id);
2181 if (!parms.device_params) {
2182 BNXT_TF_DBG(ERR, "No class tables for %d:%d\n",
2183 parms.dev_id, parms.class_tid);
2187 /* initialize the registry file for further processing */
2188 if (!ulp_regfile_init(parms.regfile)) {
2189 BNXT_TF_DBG(ERR, "regfile initialization failed.\n");
2193 rc = ulp_regfile_write(parms.regfile,
2194 BNXT_ULP_REGFILE_INDEX_CLASS_TID,
2195 tfp_cpu_to_be_64((uint64_t)parms.class_tid));
2197 BNXT_TF_DBG(ERR, "Unable to write template ID to regfile\n");
2201 /* Allocate a Flow ID for attaching all resources for the flow to.
2202 * Once allocated, all errors have to walk the list of resources and
2203 * free each of them.
2205 rc = ulp_flow_db_fid_alloc(ulp_ctx,
2210 BNXT_TF_DBG(ERR, "Unable to allocate flow table entry\n");
2214 /* Process the action template list from the selected action table*/
2215 if (parms.act_tid) {
2216 rc = ulp_mapper_action_tbls_process(&parms);
2219 "action tables failed creation for %d:%d\n",
2220 parms.dev_id, parms.act_tid);
2225 /* All good. Now process the class template */
2226 rc = ulp_mapper_class_tbls_process(&parms);
2228 BNXT_TF_DBG(ERR, "class tables failed creation for %d:%d\n",
2229 parms.dev_id, parms.class_tid);
2233 *flowid = parms.fid;
2238 /* Free all resources that were allocated during flow creation */
2239 trc = ulp_mapper_flow_destroy(ulp_ctx, parms.fid);
2241 BNXT_TF_DBG(ERR, "Failed to free all resources rc=%d\n", trc);
2247 ulp_mapper_init(struct bnxt_ulp_context *ulp_ctx)
2249 struct bnxt_ulp_cache_tbl_params *tbl;
2250 struct bnxt_ulp_mapper_data *data;
2258 tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
2262 data = rte_zmalloc("ulp_mapper_data",
2263 sizeof(struct bnxt_ulp_mapper_data), 0);
2265 BNXT_TF_DBG(ERR, "Failed to allocate the mapper data\n");
2269 if (bnxt_ulp_cntxt_ptr2_mapper_data_set(ulp_ctx, data)) {
2270 BNXT_TF_DBG(ERR, "Failed to set mapper data in context\n");
2271 /* Don't call deinit since the prof_func wasn't allocated. */
2276 /* Allocate the global resource ids */
2277 rc = ulp_mapper_glb_resource_info_init(tfp, data);
2279 BNXT_TF_DBG(ERR, "Failed to initialize global resource ids\n");
2283 /* Allocate the ulp cache tables. */
2284 for (i = 0; i < BNXT_ULP_CACHE_TBL_MAX_SZ; i++) {
2285 tbl = ulp_mapper_cache_tbl_params_get(i);
2287 BNXT_TF_DBG(ERR, "Failed to get cache table parms (%d)",
2291 if (tbl->num_entries != 0) {
2292 csize = sizeof(struct bnxt_ulp_mapper_cache_entry) *
2294 data->cache_tbl[i] = rte_zmalloc("ulp mapper cache tbl",
2296 if (!data->cache_tbl[i]) {
2297 BNXT_TF_DBG(ERR, "Failed to allocate Cache "
2307 /* Ignore the return code in favor of returning the original error. */
2308 ulp_mapper_deinit(ulp_ctx);
2313 ulp_mapper_deinit(struct bnxt_ulp_context *ulp_ctx)
2315 struct bnxt_ulp_mapper_data *data;
2321 "Failed to acquire ulp context, so data may "
2322 "not be released.\n");
2326 data = (struct bnxt_ulp_mapper_data *)
2327 bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx);
2329 /* Go ahead and return since there is no allocated data. */
2330 BNXT_TF_DBG(ERR, "No data appears to have been allocated.\n");
2334 tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
2336 BNXT_TF_DBG(ERR, "Failed to acquire tfp.\n");
2337 /* Free the mapper data regardless of errors. */
2338 goto free_mapper_data;
2341 /* Free the global resource info table entries */
2342 ulp_mapper_glb_resource_info_deinit(ulp_ctx, data);
2345 /* Free the ulp cache tables */
2346 for (i = 0; i < BNXT_ULP_CACHE_TBL_MAX_SZ; i++) {
2347 rte_free(data->cache_tbl[i]);
2348 data->cache_tbl[i] = NULL;
2352 /* Reset the data pointer within the ulp_ctx. */
2353 bnxt_ulp_cntxt_ptr2_mapper_data_set(ulp_ctx, NULL);