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