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