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