1*2d9fd380Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606  * Copyright(c) 2014-2020 Broadcom
3*2d9fd380Sjfb8856606  * All rights reserved.
4*2d9fd380Sjfb8856606  */
5*2d9fd380Sjfb8856606 
6*2d9fd380Sjfb8856606 #include <rte_log.h>
7*2d9fd380Sjfb8856606 #include <rte_malloc.h>
8*2d9fd380Sjfb8856606 #include "bnxt.h"
9*2d9fd380Sjfb8856606 #include "ulp_template_db_enum.h"
10*2d9fd380Sjfb8856606 #include "ulp_template_struct.h"
11*2d9fd380Sjfb8856606 #include "bnxt_tf_common.h"
12*2d9fd380Sjfb8856606 #include "ulp_utils.h"
13*2d9fd380Sjfb8856606 #include "bnxt_ulp.h"
14*2d9fd380Sjfb8856606 #include "tfp.h"
15*2d9fd380Sjfb8856606 #include "tf_ext_flow_handle.h"
16*2d9fd380Sjfb8856606 #include "ulp_mark_mgr.h"
17*2d9fd380Sjfb8856606 #include "ulp_mapper.h"
18*2d9fd380Sjfb8856606 #include "ulp_flow_db.h"
19*2d9fd380Sjfb8856606 #include "tf_util.h"
20*2d9fd380Sjfb8856606 
21*2d9fd380Sjfb8856606 static struct bnxt_ulp_glb_resource_info *
ulp_mapper_glb_resource_info_list_get(uint32_t * num_entries)22*2d9fd380Sjfb8856606 ulp_mapper_glb_resource_info_list_get(uint32_t *num_entries)
23*2d9fd380Sjfb8856606 {
24*2d9fd380Sjfb8856606 	if (!num_entries)
25*2d9fd380Sjfb8856606 		return NULL;
26*2d9fd380Sjfb8856606 	*num_entries = BNXT_ULP_GLB_RESOURCE_TBL_MAX_SZ;
27*2d9fd380Sjfb8856606 	return ulp_glb_resource_tbl;
28*2d9fd380Sjfb8856606 }
29*2d9fd380Sjfb8856606 
30*2d9fd380Sjfb8856606 /*
31*2d9fd380Sjfb8856606  * Read the global resource from the mapper global resource list
32*2d9fd380Sjfb8856606  *
33*2d9fd380Sjfb8856606  * The regval is always returned in big-endian.
34*2d9fd380Sjfb8856606  *
35*2d9fd380Sjfb8856606  * returns 0 on success
36*2d9fd380Sjfb8856606  */
37*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_glb_resource_read(struct bnxt_ulp_mapper_data * mapper_data,enum tf_dir dir,uint16_t idx,uint64_t * regval)38*2d9fd380Sjfb8856606 ulp_mapper_glb_resource_read(struct bnxt_ulp_mapper_data *mapper_data,
39*2d9fd380Sjfb8856606 			     enum tf_dir dir,
40*2d9fd380Sjfb8856606 			     uint16_t idx,
41*2d9fd380Sjfb8856606 			     uint64_t *regval)
42*2d9fd380Sjfb8856606 {
43*2d9fd380Sjfb8856606 	if (!mapper_data || !regval ||
44*2d9fd380Sjfb8856606 	    dir >= TF_DIR_MAX || idx >= BNXT_ULP_GLB_REGFILE_INDEX_LAST)
45*2d9fd380Sjfb8856606 		return -EINVAL;
46*2d9fd380Sjfb8856606 
47*2d9fd380Sjfb8856606 	*regval = mapper_data->glb_res_tbl[dir][idx].resource_hndl;
48*2d9fd380Sjfb8856606 	return 0;
49*2d9fd380Sjfb8856606 }
50*2d9fd380Sjfb8856606 
51*2d9fd380Sjfb8856606 /*
52*2d9fd380Sjfb8856606  * Write a global resource to the mapper global resource list
53*2d9fd380Sjfb8856606  *
54*2d9fd380Sjfb8856606  * The regval value must be in big-endian.
55*2d9fd380Sjfb8856606  *
56*2d9fd380Sjfb8856606  * return 0 on success.
57*2d9fd380Sjfb8856606  */
58*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_glb_resource_write(struct bnxt_ulp_mapper_data * data,struct bnxt_ulp_glb_resource_info * res,uint64_t regval)59*2d9fd380Sjfb8856606 ulp_mapper_glb_resource_write(struct bnxt_ulp_mapper_data *data,
60*2d9fd380Sjfb8856606 			      struct bnxt_ulp_glb_resource_info *res,
61*2d9fd380Sjfb8856606 			      uint64_t regval)
62*2d9fd380Sjfb8856606 {
63*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_glb_resource_entry *ent;
64*2d9fd380Sjfb8856606 
65*2d9fd380Sjfb8856606 	/* validate the arguments */
66*2d9fd380Sjfb8856606 	if (!data || res->direction >= TF_DIR_MAX ||
67*2d9fd380Sjfb8856606 	    res->glb_regfile_index >= BNXT_ULP_GLB_REGFILE_INDEX_LAST)
68*2d9fd380Sjfb8856606 		return -EINVAL;
69*2d9fd380Sjfb8856606 
70*2d9fd380Sjfb8856606 	/* write to the mapper data */
71*2d9fd380Sjfb8856606 	ent = &data->glb_res_tbl[res->direction][res->glb_regfile_index];
72*2d9fd380Sjfb8856606 	ent->resource_func = res->resource_func;
73*2d9fd380Sjfb8856606 	ent->resource_type = res->resource_type;
74*2d9fd380Sjfb8856606 	ent->resource_hndl = regval;
75*2d9fd380Sjfb8856606 	return 0;
76*2d9fd380Sjfb8856606 }
77*2d9fd380Sjfb8856606 
78*2d9fd380Sjfb8856606 /*
79*2d9fd380Sjfb8856606  * Internal function to allocate identity resource and store it in mapper data.
80*2d9fd380Sjfb8856606  *
81*2d9fd380Sjfb8856606  * returns 0 on success
82*2d9fd380Sjfb8856606  */
83*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_resource_ident_allocate(struct bnxt_ulp_context * ulp_ctx,struct bnxt_ulp_mapper_data * mapper_data,struct bnxt_ulp_glb_resource_info * glb_res)84*2d9fd380Sjfb8856606 ulp_mapper_resource_ident_allocate(struct bnxt_ulp_context *ulp_ctx,
85*2d9fd380Sjfb8856606 				   struct bnxt_ulp_mapper_data *mapper_data,
86*2d9fd380Sjfb8856606 				   struct bnxt_ulp_glb_resource_info *glb_res)
87*2d9fd380Sjfb8856606 {
88*2d9fd380Sjfb8856606 	struct tf_alloc_identifier_parms iparms = { 0 };
89*2d9fd380Sjfb8856606 	struct tf_free_identifier_parms fparms;
90*2d9fd380Sjfb8856606 	uint64_t regval;
91*2d9fd380Sjfb8856606 	struct tf *tfp;
92*2d9fd380Sjfb8856606 	int32_t rc = 0;
93*2d9fd380Sjfb8856606 
94*2d9fd380Sjfb8856606 	tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
95*2d9fd380Sjfb8856606 	if (!tfp)
96*2d9fd380Sjfb8856606 		return -EINVAL;
97*2d9fd380Sjfb8856606 
98*2d9fd380Sjfb8856606 	iparms.ident_type = glb_res->resource_type;
99*2d9fd380Sjfb8856606 	iparms.dir = glb_res->direction;
100*2d9fd380Sjfb8856606 
101*2d9fd380Sjfb8856606 	/* Allocate the Identifier using tf api */
102*2d9fd380Sjfb8856606 	rc = tf_alloc_identifier(tfp, &iparms);
103*2d9fd380Sjfb8856606 	if (rc) {
104*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to alloc identifier [%s][%d]\n",
105*2d9fd380Sjfb8856606 			    (iparms.dir == TF_DIR_RX) ? "RX" : "TX",
106*2d9fd380Sjfb8856606 			    iparms.ident_type);
107*2d9fd380Sjfb8856606 		return rc;
108*2d9fd380Sjfb8856606 	}
109*2d9fd380Sjfb8856606 
110*2d9fd380Sjfb8856606 	/* entries are stored as big-endian format */
111*2d9fd380Sjfb8856606 	regval = tfp_cpu_to_be_64((uint64_t)iparms.id);
112*2d9fd380Sjfb8856606 	/* write to the mapper global resource */
113*2d9fd380Sjfb8856606 	rc = ulp_mapper_glb_resource_write(mapper_data, glb_res, regval);
114*2d9fd380Sjfb8856606 	if (rc) {
115*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to write to global resource id\n");
116*2d9fd380Sjfb8856606 		/* Free the identifier when update failed */
117*2d9fd380Sjfb8856606 		fparms.dir = iparms.dir;
118*2d9fd380Sjfb8856606 		fparms.ident_type = iparms.ident_type;
119*2d9fd380Sjfb8856606 		fparms.id = iparms.id;
120*2d9fd380Sjfb8856606 		tf_free_identifier(tfp, &fparms);
121*2d9fd380Sjfb8856606 		return rc;
122*2d9fd380Sjfb8856606 	}
123*2d9fd380Sjfb8856606 	return rc;
124*2d9fd380Sjfb8856606 }
125*2d9fd380Sjfb8856606 
126*2d9fd380Sjfb8856606 /*
127*2d9fd380Sjfb8856606  * Internal function to allocate index tbl resource and store it in mapper data.
128*2d9fd380Sjfb8856606  *
129*2d9fd380Sjfb8856606  * returns 0 on success
130*2d9fd380Sjfb8856606  */
131*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_resource_index_tbl_alloc(struct bnxt_ulp_context * ulp_ctx,struct bnxt_ulp_mapper_data * mapper_data,struct bnxt_ulp_glb_resource_info * glb_res)132*2d9fd380Sjfb8856606 ulp_mapper_resource_index_tbl_alloc(struct bnxt_ulp_context *ulp_ctx,
133*2d9fd380Sjfb8856606 				    struct bnxt_ulp_mapper_data *mapper_data,
134*2d9fd380Sjfb8856606 				    struct bnxt_ulp_glb_resource_info *glb_res)
135*2d9fd380Sjfb8856606 {
136*2d9fd380Sjfb8856606 	struct tf_alloc_tbl_entry_parms	aparms = { 0 };
137*2d9fd380Sjfb8856606 	struct tf_free_tbl_entry_parms	free_parms = { 0 };
138*2d9fd380Sjfb8856606 	uint64_t regval;
139*2d9fd380Sjfb8856606 	struct tf *tfp;
140*2d9fd380Sjfb8856606 	uint32_t tbl_scope_id;
141*2d9fd380Sjfb8856606 	int32_t rc = 0;
142*2d9fd380Sjfb8856606 
143*2d9fd380Sjfb8856606 	tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
144*2d9fd380Sjfb8856606 	if (!tfp)
145*2d9fd380Sjfb8856606 		return -EINVAL;
146*2d9fd380Sjfb8856606 
147*2d9fd380Sjfb8856606 	/* Get the scope id */
148*2d9fd380Sjfb8856606 	rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp_ctx, &tbl_scope_id);
149*2d9fd380Sjfb8856606 	if (rc) {
150*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get table scope rc=%d\n", rc);
151*2d9fd380Sjfb8856606 		return rc;
152*2d9fd380Sjfb8856606 	}
153*2d9fd380Sjfb8856606 
154*2d9fd380Sjfb8856606 	aparms.type = glb_res->resource_type;
155*2d9fd380Sjfb8856606 	aparms.dir = glb_res->direction;
156*2d9fd380Sjfb8856606 	aparms.search_enable = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO;
157*2d9fd380Sjfb8856606 	aparms.tbl_scope_id = tbl_scope_id;
158*2d9fd380Sjfb8856606 
159*2d9fd380Sjfb8856606 	/* Allocate the index tbl using tf api */
160*2d9fd380Sjfb8856606 	rc = tf_alloc_tbl_entry(tfp, &aparms);
161*2d9fd380Sjfb8856606 	if (rc) {
162*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to alloc identifier [%s][%d]\n",
163*2d9fd380Sjfb8856606 			    (aparms.dir == TF_DIR_RX) ? "RX" : "TX",
164*2d9fd380Sjfb8856606 			    aparms.type);
165*2d9fd380Sjfb8856606 		return rc;
166*2d9fd380Sjfb8856606 	}
167*2d9fd380Sjfb8856606 
168*2d9fd380Sjfb8856606 	/* entries are stored as big-endian format */
169*2d9fd380Sjfb8856606 	regval = tfp_cpu_to_be_64((uint64_t)aparms.idx);
170*2d9fd380Sjfb8856606 	/* write to the mapper global resource */
171*2d9fd380Sjfb8856606 	rc = ulp_mapper_glb_resource_write(mapper_data, glb_res, regval);
172*2d9fd380Sjfb8856606 	if (rc) {
173*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to write to global resource id\n");
174*2d9fd380Sjfb8856606 		/* Free the identifier when update failed */
175*2d9fd380Sjfb8856606 		free_parms.dir = aparms.dir;
176*2d9fd380Sjfb8856606 		free_parms.type = aparms.type;
177*2d9fd380Sjfb8856606 		free_parms.idx = aparms.idx;
178*2d9fd380Sjfb8856606 		tf_free_tbl_entry(tfp, &free_parms);
179*2d9fd380Sjfb8856606 		return rc;
180*2d9fd380Sjfb8856606 	}
181*2d9fd380Sjfb8856606 	return rc;
182*2d9fd380Sjfb8856606 }
183*2d9fd380Sjfb8856606 
184*2d9fd380Sjfb8856606 /* Retrieve the cache initialization parameters for the tbl_idx */
185*2d9fd380Sjfb8856606 static struct bnxt_ulp_cache_tbl_params *
ulp_mapper_cache_tbl_params_get(uint32_t tbl_idx)186*2d9fd380Sjfb8856606 ulp_mapper_cache_tbl_params_get(uint32_t tbl_idx)
187*2d9fd380Sjfb8856606 {
188*2d9fd380Sjfb8856606 	if (tbl_idx >= BNXT_ULP_CACHE_TBL_MAX_SZ)
189*2d9fd380Sjfb8856606 		return NULL;
190*2d9fd380Sjfb8856606 
191*2d9fd380Sjfb8856606 	return &ulp_cache_tbl_params[tbl_idx];
192*2d9fd380Sjfb8856606 }
193*2d9fd380Sjfb8856606 
194*2d9fd380Sjfb8856606 /* Retrieve the global template table */
195*2d9fd380Sjfb8856606 static uint32_t *
ulp_mapper_glb_template_table_get(uint32_t * num_entries)196*2d9fd380Sjfb8856606 ulp_mapper_glb_template_table_get(uint32_t *num_entries)
197*2d9fd380Sjfb8856606 {
198*2d9fd380Sjfb8856606 	if (!num_entries)
199*2d9fd380Sjfb8856606 		return NULL;
200*2d9fd380Sjfb8856606 	*num_entries = BNXT_ULP_GLB_TEMPLATE_TBL_MAX_SZ;
201*2d9fd380Sjfb8856606 	return ulp_glb_template_tbl;
202*2d9fd380Sjfb8856606 }
203*2d9fd380Sjfb8856606 
204*2d9fd380Sjfb8856606 /*
205*2d9fd380Sjfb8856606  * Get the size of the action property for a given index.
206*2d9fd380Sjfb8856606  *
207*2d9fd380Sjfb8856606  * idx [in] The index for the action property
208*2d9fd380Sjfb8856606  *
209*2d9fd380Sjfb8856606  * returns the size of the action property.
210*2d9fd380Sjfb8856606  */
211*2d9fd380Sjfb8856606 static uint32_t
ulp_mapper_act_prop_size_get(uint32_t idx)212*2d9fd380Sjfb8856606 ulp_mapper_act_prop_size_get(uint32_t idx)
213*2d9fd380Sjfb8856606 {
214*2d9fd380Sjfb8856606 	if (idx >= BNXT_ULP_ACT_PROP_IDX_LAST)
215*2d9fd380Sjfb8856606 		return 0;
216*2d9fd380Sjfb8856606 	return ulp_act_prop_map_table[idx];
217*2d9fd380Sjfb8856606 }
218*2d9fd380Sjfb8856606 
219*2d9fd380Sjfb8856606 /*
220*2d9fd380Sjfb8856606  * Get a list of classifier tables that implement the flow
221*2d9fd380Sjfb8856606  * Gets a device dependent list of tables that implement the class template id
222*2d9fd380Sjfb8856606  *
223*2d9fd380Sjfb8856606  * mparms [in] The mappers parms with data related to the flow.
224*2d9fd380Sjfb8856606  *
225*2d9fd380Sjfb8856606  * tid [in] The template id that matches the flow
226*2d9fd380Sjfb8856606  *
227*2d9fd380Sjfb8856606  * num_tbls [out] The number of classifier tables in the returned array
228*2d9fd380Sjfb8856606  *
229*2d9fd380Sjfb8856606  * returns An array of classifier tables to implement the flow, or NULL on
230*2d9fd380Sjfb8856606  * error
231*2d9fd380Sjfb8856606  */
232*2d9fd380Sjfb8856606 static struct bnxt_ulp_mapper_tbl_info *
ulp_mapper_tbl_list_get(struct bnxt_ulp_mapper_parms * mparms,uint32_t tid,uint32_t * num_tbls)233*2d9fd380Sjfb8856606 ulp_mapper_tbl_list_get(struct bnxt_ulp_mapper_parms *mparms,
234*2d9fd380Sjfb8856606 			uint32_t tid,
235*2d9fd380Sjfb8856606 			uint32_t *num_tbls)
236*2d9fd380Sjfb8856606 {
237*2d9fd380Sjfb8856606 	uint32_t idx;
238*2d9fd380Sjfb8856606 	const struct ulp_template_device_tbls *dev_tbls;
239*2d9fd380Sjfb8856606 
240*2d9fd380Sjfb8856606 	dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type];
241*2d9fd380Sjfb8856606 
242*2d9fd380Sjfb8856606 	idx = dev_tbls->tmpl_list[tid].start_tbl_idx;
243*2d9fd380Sjfb8856606 	*num_tbls = dev_tbls->tmpl_list[tid].num_tbls;
244*2d9fd380Sjfb8856606 
245*2d9fd380Sjfb8856606 	return &dev_tbls->tbl_list[idx];
246*2d9fd380Sjfb8856606 }
247*2d9fd380Sjfb8856606 
248*2d9fd380Sjfb8856606 /*
249*2d9fd380Sjfb8856606  * Get the list of key fields that implement the flow.
250*2d9fd380Sjfb8856606  *
251*2d9fd380Sjfb8856606  * mparms [in] The mapper parms with information about the flow
252*2d9fd380Sjfb8856606  *
253*2d9fd380Sjfb8856606  * tbl [in] A single table instance to get the key fields from
254*2d9fd380Sjfb8856606  *
255*2d9fd380Sjfb8856606  * num_flds [out] The number of key fields in the returned array
256*2d9fd380Sjfb8856606  *
257*2d9fd380Sjfb8856606  * Returns array of Key fields, or NULL on error.
258*2d9fd380Sjfb8856606  */
259*2d9fd380Sjfb8856606 static struct bnxt_ulp_mapper_key_field_info *
ulp_mapper_key_fields_get(struct bnxt_ulp_mapper_parms * mparms,struct bnxt_ulp_mapper_tbl_info * tbl,uint32_t * num_flds)260*2d9fd380Sjfb8856606 ulp_mapper_key_fields_get(struct bnxt_ulp_mapper_parms *mparms,
261*2d9fd380Sjfb8856606 			  struct bnxt_ulp_mapper_tbl_info *tbl,
262*2d9fd380Sjfb8856606 			  uint32_t *num_flds)
263*2d9fd380Sjfb8856606 {
264*2d9fd380Sjfb8856606 	uint32_t idx;
265*2d9fd380Sjfb8856606 	const struct ulp_template_device_tbls *dev_tbls;
266*2d9fd380Sjfb8856606 
267*2d9fd380Sjfb8856606 	dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type];
268*2d9fd380Sjfb8856606 	if (!dev_tbls->key_field_list) {
269*2d9fd380Sjfb8856606 		*num_flds = 0;
270*2d9fd380Sjfb8856606 		return NULL;
271*2d9fd380Sjfb8856606 	}
272*2d9fd380Sjfb8856606 
273*2d9fd380Sjfb8856606 	idx		= tbl->key_start_idx;
274*2d9fd380Sjfb8856606 	*num_flds	= tbl->key_num_fields;
275*2d9fd380Sjfb8856606 
276*2d9fd380Sjfb8856606 	return &dev_tbls->key_field_list[idx];
277*2d9fd380Sjfb8856606 }
278*2d9fd380Sjfb8856606 
279*2d9fd380Sjfb8856606 /*
280*2d9fd380Sjfb8856606  * Get the list of data fields that implement the flow.
281*2d9fd380Sjfb8856606  *
282*2d9fd380Sjfb8856606  * mparms [in] The mapper parms with information about the flow
283*2d9fd380Sjfb8856606  *
284*2d9fd380Sjfb8856606  * tbl [in] A single table instance to get the data fields from
285*2d9fd380Sjfb8856606  *
286*2d9fd380Sjfb8856606  * num_flds [out] The number of data fields in the returned array.
287*2d9fd380Sjfb8856606  *
288*2d9fd380Sjfb8856606  * num_encap_flds [out] The number of encap fields in the returned array.
289*2d9fd380Sjfb8856606  *
290*2d9fd380Sjfb8856606  * Returns array of data fields, or NULL on error.
291*2d9fd380Sjfb8856606  */
292*2d9fd380Sjfb8856606 static struct bnxt_ulp_mapper_result_field_info *
ulp_mapper_result_fields_get(struct bnxt_ulp_mapper_parms * mparms,struct bnxt_ulp_mapper_tbl_info * tbl,uint32_t * num_flds,uint32_t * num_encap_flds)293*2d9fd380Sjfb8856606 ulp_mapper_result_fields_get(struct bnxt_ulp_mapper_parms *mparms,
294*2d9fd380Sjfb8856606 			     struct bnxt_ulp_mapper_tbl_info *tbl,
295*2d9fd380Sjfb8856606 			     uint32_t *num_flds,
296*2d9fd380Sjfb8856606 			     uint32_t *num_encap_flds)
297*2d9fd380Sjfb8856606 {
298*2d9fd380Sjfb8856606 	uint32_t idx;
299*2d9fd380Sjfb8856606 	const struct ulp_template_device_tbls *dev_tbls;
300*2d9fd380Sjfb8856606 
301*2d9fd380Sjfb8856606 	dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type];
302*2d9fd380Sjfb8856606 	if (!dev_tbls->result_field_list) {
303*2d9fd380Sjfb8856606 		*num_flds = 0;
304*2d9fd380Sjfb8856606 		*num_encap_flds = 0;
305*2d9fd380Sjfb8856606 		return NULL;
306*2d9fd380Sjfb8856606 	}
307*2d9fd380Sjfb8856606 
308*2d9fd380Sjfb8856606 	idx		= tbl->result_start_idx;
309*2d9fd380Sjfb8856606 	*num_flds	= tbl->result_num_fields;
310*2d9fd380Sjfb8856606 	*num_encap_flds = tbl->encap_num_fields;
311*2d9fd380Sjfb8856606 
312*2d9fd380Sjfb8856606 	return &dev_tbls->result_field_list[idx];
313*2d9fd380Sjfb8856606 }
314*2d9fd380Sjfb8856606 
315*2d9fd380Sjfb8856606 /*
316*2d9fd380Sjfb8856606  * Get the list of ident fields that implement the flow
317*2d9fd380Sjfb8856606  *
318*2d9fd380Sjfb8856606  * tbl [in] A single table instance to get the ident fields from
319*2d9fd380Sjfb8856606  *
320*2d9fd380Sjfb8856606  * num_flds [out] The number of ident fields in the returned array
321*2d9fd380Sjfb8856606  *
322*2d9fd380Sjfb8856606  * returns array of ident fields, or NULL on error
323*2d9fd380Sjfb8856606  */
324*2d9fd380Sjfb8856606 static struct bnxt_ulp_mapper_ident_info *
ulp_mapper_ident_fields_get(struct bnxt_ulp_mapper_parms * mparms,struct bnxt_ulp_mapper_tbl_info * tbl,uint32_t * num_flds)325*2d9fd380Sjfb8856606 ulp_mapper_ident_fields_get(struct bnxt_ulp_mapper_parms *mparms,
326*2d9fd380Sjfb8856606 			    struct bnxt_ulp_mapper_tbl_info *tbl,
327*2d9fd380Sjfb8856606 			    uint32_t *num_flds)
328*2d9fd380Sjfb8856606 {
329*2d9fd380Sjfb8856606 	uint32_t idx;
330*2d9fd380Sjfb8856606 	const struct ulp_template_device_tbls *dev_tbls;
331*2d9fd380Sjfb8856606 
332*2d9fd380Sjfb8856606 	dev_tbls = &mparms->device_params->dev_tbls[mparms->tmpl_type];
333*2d9fd380Sjfb8856606 	if (!dev_tbls->ident_list) {
334*2d9fd380Sjfb8856606 		*num_flds = 0;
335*2d9fd380Sjfb8856606 		return NULL;
336*2d9fd380Sjfb8856606 	}
337*2d9fd380Sjfb8856606 
338*2d9fd380Sjfb8856606 	idx = tbl->ident_start_idx;
339*2d9fd380Sjfb8856606 	*num_flds = tbl->ident_nums;
340*2d9fd380Sjfb8856606 
341*2d9fd380Sjfb8856606 	return &dev_tbls->ident_list[idx];
342*2d9fd380Sjfb8856606 }
343*2d9fd380Sjfb8856606 
344*2d9fd380Sjfb8856606 static struct bnxt_ulp_mapper_cache_entry *
ulp_mapper_cache_entry_get(struct bnxt_ulp_context * ulp,uint32_t id,uint16_t key)345*2d9fd380Sjfb8856606 ulp_mapper_cache_entry_get(struct bnxt_ulp_context *ulp,
346*2d9fd380Sjfb8856606 			   uint32_t id,
347*2d9fd380Sjfb8856606 			   uint16_t key)
348*2d9fd380Sjfb8856606 {
349*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_data *mapper_data;
350*2d9fd380Sjfb8856606 
351*2d9fd380Sjfb8856606 	mapper_data = bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp);
352*2d9fd380Sjfb8856606 	if (!mapper_data || id >= BNXT_ULP_CACHE_TBL_MAX_SZ ||
353*2d9fd380Sjfb8856606 	    !mapper_data->cache_tbl[id]) {
354*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Unable to acquire the cache tbl (%d)\n", id);
355*2d9fd380Sjfb8856606 		return NULL;
356*2d9fd380Sjfb8856606 	}
357*2d9fd380Sjfb8856606 
358*2d9fd380Sjfb8856606 	return &mapper_data->cache_tbl[id][key];
359*2d9fd380Sjfb8856606 }
360*2d9fd380Sjfb8856606 
361*2d9fd380Sjfb8856606 /*
362*2d9fd380Sjfb8856606  * Concatenates the tbl_type and tbl_id into a 32bit value for storing in the
363*2d9fd380Sjfb8856606  * resource_type.  This is done to conserve memory since both the tbl_type and
364*2d9fd380Sjfb8856606  * tbl_id are 16bit.
365*2d9fd380Sjfb8856606  */
366*2d9fd380Sjfb8856606 static inline void
ulp_mapper_cache_res_type_set(struct ulp_flow_db_res_params * res,uint16_t tbl_type,uint16_t tbl_id)367*2d9fd380Sjfb8856606 ulp_mapper_cache_res_type_set(struct ulp_flow_db_res_params *res,
368*2d9fd380Sjfb8856606 			      uint16_t tbl_type,
369*2d9fd380Sjfb8856606 			      uint16_t tbl_id)
370*2d9fd380Sjfb8856606 {
371*2d9fd380Sjfb8856606 	res->resource_type = tbl_type;
372*2d9fd380Sjfb8856606 	res->resource_sub_type = tbl_id;
373*2d9fd380Sjfb8856606 }
374*2d9fd380Sjfb8856606 
375*2d9fd380Sjfb8856606 /* Extracts the tbl_type and tbl_id from the 32bit resource type. */
376*2d9fd380Sjfb8856606 static inline void
ulp_mapper_cache_res_type_get(struct ulp_flow_db_res_params * res,uint16_t * tbl_type,uint16_t * tbl_id)377*2d9fd380Sjfb8856606 ulp_mapper_cache_res_type_get(struct ulp_flow_db_res_params *res,
378*2d9fd380Sjfb8856606 			      uint16_t *tbl_type,
379*2d9fd380Sjfb8856606 			      uint16_t *tbl_id)
380*2d9fd380Sjfb8856606 {
381*2d9fd380Sjfb8856606 	*tbl_type = res->resource_type;
382*2d9fd380Sjfb8856606 	*tbl_id = res->resource_sub_type;
383*2d9fd380Sjfb8856606 }
384*2d9fd380Sjfb8856606 
385*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_cache_entry_free(struct bnxt_ulp_context * ulp,struct tf * tfp,struct ulp_flow_db_res_params * res)386*2d9fd380Sjfb8856606 ulp_mapper_cache_entry_free(struct bnxt_ulp_context *ulp,
387*2d9fd380Sjfb8856606 			    struct tf *tfp,
388*2d9fd380Sjfb8856606 			    struct ulp_flow_db_res_params *res)
389*2d9fd380Sjfb8856606 {
390*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_cache_entry *cache_entry;
391*2d9fd380Sjfb8856606 	struct tf_free_identifier_parms ident_parms;
392*2d9fd380Sjfb8856606 	struct tf_free_tcam_entry_parms tcam_parms;
393*2d9fd380Sjfb8856606 	uint16_t table_id, table_type;
394*2d9fd380Sjfb8856606 	int32_t rc, trc, i;
395*2d9fd380Sjfb8856606 
396*2d9fd380Sjfb8856606 	/*
397*2d9fd380Sjfb8856606 	 * The table id, used for cache, and table_type, used for tcam, are
398*2d9fd380Sjfb8856606 	 * both encoded within the resource.  We must first extract them to
399*2d9fd380Sjfb8856606 	 * formulate the args for tf calls.
400*2d9fd380Sjfb8856606 	 */
401*2d9fd380Sjfb8856606 	ulp_mapper_cache_res_type_get(res, &table_type, &table_id);
402*2d9fd380Sjfb8856606 	cache_entry = ulp_mapper_cache_entry_get(ulp, table_id,
403*2d9fd380Sjfb8856606 						 (uint16_t)res->resource_hndl);
404*2d9fd380Sjfb8856606 	if (!cache_entry || !cache_entry->ref_count) {
405*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Cache entry (%d:%d) not valid on free.\n",
406*2d9fd380Sjfb8856606 			    table_id, (uint16_t)res->resource_hndl);
407*2d9fd380Sjfb8856606 		return -EINVAL;
408*2d9fd380Sjfb8856606 	}
409*2d9fd380Sjfb8856606 
410*2d9fd380Sjfb8856606 	/*
411*2d9fd380Sjfb8856606 	 * See if we need to delete the entry.  The tcam and identifiers are all
412*2d9fd380Sjfb8856606 	 * tracked by the cached entries reference count.  All are deleted when
413*2d9fd380Sjfb8856606 	 * the reference count hit zero.
414*2d9fd380Sjfb8856606 	 */
415*2d9fd380Sjfb8856606 	cache_entry->ref_count--;
416*2d9fd380Sjfb8856606 	if (cache_entry->ref_count)
417*2d9fd380Sjfb8856606 		return 0;
418*2d9fd380Sjfb8856606 
419*2d9fd380Sjfb8856606 	/*
420*2d9fd380Sjfb8856606 	 * Need to delete the tcam entry and the allocated identifiers.
421*2d9fd380Sjfb8856606 	 * In the event of a failure, need to try to delete the remaining
422*2d9fd380Sjfb8856606 	 * resources before returning error.
423*2d9fd380Sjfb8856606 	 */
424*2d9fd380Sjfb8856606 	tcam_parms.dir = res->direction;
425*2d9fd380Sjfb8856606 	tcam_parms.tcam_tbl_type = table_type;
426*2d9fd380Sjfb8856606 	tcam_parms.idx = cache_entry->tcam_idx;
427*2d9fd380Sjfb8856606 	rc = tf_free_tcam_entry(tfp, &tcam_parms);
428*2d9fd380Sjfb8856606 	if (rc)
429*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to free tcam [%d][%s][0x%04x] rc=%d\n",
430*2d9fd380Sjfb8856606 			    table_type,
431*2d9fd380Sjfb8856606 			    (res->direction == TF_DIR_RX) ? "RX" : "TX",
432*2d9fd380Sjfb8856606 			    tcam_parms.idx, rc);
433*2d9fd380Sjfb8856606 
434*2d9fd380Sjfb8856606 	/*
435*2d9fd380Sjfb8856606 	 * Free the identifiers associated with the tcam entry.  Entries with
436*2d9fd380Sjfb8856606 	 * negative one are considered uninitialized.
437*2d9fd380Sjfb8856606 	 */
438*2d9fd380Sjfb8856606 	for (i = 0; i < BNXT_ULP_CACHE_TBL_IDENT_MAX_NUM; i++) {
439*2d9fd380Sjfb8856606 		if (cache_entry->idents[i] == ULP_IDENTS_INVALID)
440*2d9fd380Sjfb8856606 			continue;
441*2d9fd380Sjfb8856606 
442*2d9fd380Sjfb8856606 		ident_parms.dir = res->direction;
443*2d9fd380Sjfb8856606 		ident_parms.ident_type = cache_entry->ident_types[i];
444*2d9fd380Sjfb8856606 		ident_parms.id = cache_entry->idents[i];
445*2d9fd380Sjfb8856606 		trc = tf_free_identifier(tfp, &ident_parms);
446*2d9fd380Sjfb8856606 		if (trc) {
447*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Failed to free identifier "
448*2d9fd380Sjfb8856606 				    "[%d][%s][0x%04x] rc=%d\n",
449*2d9fd380Sjfb8856606 				    ident_parms.ident_type,
450*2d9fd380Sjfb8856606 				    (res->direction == TF_DIR_RX) ? "RX" : "TX",
451*2d9fd380Sjfb8856606 				    ident_parms.id, trc);
452*2d9fd380Sjfb8856606 			rc = trc;
453*2d9fd380Sjfb8856606 		}
454*2d9fd380Sjfb8856606 	}
455*2d9fd380Sjfb8856606 
456*2d9fd380Sjfb8856606 	return rc;
457*2d9fd380Sjfb8856606 }
458*2d9fd380Sjfb8856606 
459*2d9fd380Sjfb8856606 static inline int32_t
ulp_mapper_tcam_entry_free(struct bnxt_ulp_context * ulp __rte_unused,struct tf * tfp,struct ulp_flow_db_res_params * res)460*2d9fd380Sjfb8856606 ulp_mapper_tcam_entry_free(struct bnxt_ulp_context *ulp  __rte_unused,
461*2d9fd380Sjfb8856606 			   struct tf *tfp,
462*2d9fd380Sjfb8856606 			   struct ulp_flow_db_res_params *res)
463*2d9fd380Sjfb8856606 {
464*2d9fd380Sjfb8856606 	struct tf_free_tcam_entry_parms fparms = {
465*2d9fd380Sjfb8856606 		.dir		= res->direction,
466*2d9fd380Sjfb8856606 		.tcam_tbl_type	= res->resource_type,
467*2d9fd380Sjfb8856606 		.idx		= (uint16_t)res->resource_hndl
468*2d9fd380Sjfb8856606 	};
469*2d9fd380Sjfb8856606 
470*2d9fd380Sjfb8856606 	return tf_free_tcam_entry(tfp, &fparms);
471*2d9fd380Sjfb8856606 }
472*2d9fd380Sjfb8856606 
473*2d9fd380Sjfb8856606 static inline int32_t
ulp_mapper_index_entry_free(struct bnxt_ulp_context * ulp,struct tf * tfp,struct ulp_flow_db_res_params * res)474*2d9fd380Sjfb8856606 ulp_mapper_index_entry_free(struct bnxt_ulp_context *ulp,
475*2d9fd380Sjfb8856606 			    struct tf *tfp,
476*2d9fd380Sjfb8856606 			    struct ulp_flow_db_res_params *res)
477*2d9fd380Sjfb8856606 {
478*2d9fd380Sjfb8856606 	struct tf_free_tbl_entry_parms fparms = {
479*2d9fd380Sjfb8856606 		.dir	= res->direction,
480*2d9fd380Sjfb8856606 		.type	= res->resource_type,
481*2d9fd380Sjfb8856606 		.idx	= (uint32_t)res->resource_hndl
482*2d9fd380Sjfb8856606 	};
483*2d9fd380Sjfb8856606 
484*2d9fd380Sjfb8856606 	/*
485*2d9fd380Sjfb8856606 	 * Just get the table scope, it will be ignored if not necessary
486*2d9fd380Sjfb8856606 	 * by the tf_free_tbl_entry
487*2d9fd380Sjfb8856606 	 */
488*2d9fd380Sjfb8856606 	(void)bnxt_ulp_cntxt_tbl_scope_id_get(ulp, &fparms.tbl_scope_id);
489*2d9fd380Sjfb8856606 
490*2d9fd380Sjfb8856606 	return tf_free_tbl_entry(tfp, &fparms);
491*2d9fd380Sjfb8856606 }
492*2d9fd380Sjfb8856606 
493*2d9fd380Sjfb8856606 static inline int32_t
ulp_mapper_em_entry_free(struct bnxt_ulp_context * ulp,struct tf * tfp,struct ulp_flow_db_res_params * res)494*2d9fd380Sjfb8856606 ulp_mapper_em_entry_free(struct bnxt_ulp_context *ulp,
495*2d9fd380Sjfb8856606 			 struct tf *tfp,
496*2d9fd380Sjfb8856606 			 struct ulp_flow_db_res_params *res)
497*2d9fd380Sjfb8856606 {
498*2d9fd380Sjfb8856606 	struct tf_delete_em_entry_parms fparms = { 0 };
499*2d9fd380Sjfb8856606 	int32_t rc;
500*2d9fd380Sjfb8856606 
501*2d9fd380Sjfb8856606 	fparms.dir		= res->direction;
502*2d9fd380Sjfb8856606 	if (res->resource_func == BNXT_ULP_RESOURCE_FUNC_EXT_EM_TABLE)
503*2d9fd380Sjfb8856606 		fparms.mem = TF_MEM_EXTERNAL;
504*2d9fd380Sjfb8856606 	else
505*2d9fd380Sjfb8856606 		fparms.mem = TF_MEM_INTERNAL;
506*2d9fd380Sjfb8856606 	fparms.flow_handle	= res->resource_hndl;
507*2d9fd380Sjfb8856606 
508*2d9fd380Sjfb8856606 	rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp, &fparms.tbl_scope_id);
509*2d9fd380Sjfb8856606 	if (rc) {
510*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get table scope\n");
511*2d9fd380Sjfb8856606 		return -EINVAL;
512*2d9fd380Sjfb8856606 	}
513*2d9fd380Sjfb8856606 
514*2d9fd380Sjfb8856606 	return tf_delete_em_entry(tfp, &fparms);
515*2d9fd380Sjfb8856606 }
516*2d9fd380Sjfb8856606 
517*2d9fd380Sjfb8856606 static inline int32_t
ulp_mapper_ident_free(struct bnxt_ulp_context * ulp __rte_unused,struct tf * tfp,struct ulp_flow_db_res_params * res)518*2d9fd380Sjfb8856606 ulp_mapper_ident_free(struct bnxt_ulp_context *ulp __rte_unused,
519*2d9fd380Sjfb8856606 		      struct tf *tfp,
520*2d9fd380Sjfb8856606 		      struct ulp_flow_db_res_params *res)
521*2d9fd380Sjfb8856606 {
522*2d9fd380Sjfb8856606 	struct tf_free_identifier_parms fparms = {
523*2d9fd380Sjfb8856606 		.dir		= res->direction,
524*2d9fd380Sjfb8856606 		.ident_type	= res->resource_type,
525*2d9fd380Sjfb8856606 		.id		= (uint16_t)res->resource_hndl
526*2d9fd380Sjfb8856606 	};
527*2d9fd380Sjfb8856606 
528*2d9fd380Sjfb8856606 	return tf_free_identifier(tfp, &fparms);
529*2d9fd380Sjfb8856606 }
530*2d9fd380Sjfb8856606 
531*2d9fd380Sjfb8856606 static inline int32_t
ulp_mapper_mark_free(struct bnxt_ulp_context * ulp,struct ulp_flow_db_res_params * res)532*2d9fd380Sjfb8856606 ulp_mapper_mark_free(struct bnxt_ulp_context *ulp,
533*2d9fd380Sjfb8856606 		     struct ulp_flow_db_res_params *res)
534*2d9fd380Sjfb8856606 {
535*2d9fd380Sjfb8856606 	return ulp_mark_db_mark_del(ulp,
536*2d9fd380Sjfb8856606 				    res->resource_type,
537*2d9fd380Sjfb8856606 				    res->resource_hndl);
538*2d9fd380Sjfb8856606 }
539*2d9fd380Sjfb8856606 
540*2d9fd380Sjfb8856606 
541*2d9fd380Sjfb8856606 static inline int32_t
ulp_mapper_parent_flow_free(struct bnxt_ulp_context * ulp,uint32_t parent_fid,struct ulp_flow_db_res_params * res)542*2d9fd380Sjfb8856606 ulp_mapper_parent_flow_free(struct bnxt_ulp_context *ulp,
543*2d9fd380Sjfb8856606 			    uint32_t parent_fid,
544*2d9fd380Sjfb8856606 			    struct ulp_flow_db_res_params *res)
545*2d9fd380Sjfb8856606 {
546*2d9fd380Sjfb8856606 	uint32_t idx, child_fid = 0, parent_idx;
547*2d9fd380Sjfb8856606 	struct bnxt_ulp_flow_db *flow_db;
548*2d9fd380Sjfb8856606 
549*2d9fd380Sjfb8856606 	parent_idx = (uint32_t)res->resource_hndl;
550*2d9fd380Sjfb8856606 
551*2d9fd380Sjfb8856606 	/* check the validity of the parent fid */
552*2d9fd380Sjfb8856606 	if (ulp_flow_db_parent_flow_idx_get(ulp, parent_fid, &idx) ||
553*2d9fd380Sjfb8856606 	    idx != parent_idx) {
554*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "invalid parent flow id %x\n", parent_fid);
555*2d9fd380Sjfb8856606 		return -EINVAL;
556*2d9fd380Sjfb8856606 	}
557*2d9fd380Sjfb8856606 
558*2d9fd380Sjfb8856606 	/* Clear all the child flows parent index */
559*2d9fd380Sjfb8856606 	flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp);
560*2d9fd380Sjfb8856606 	while (!ulp_flow_db_parent_child_flow_next_entry_get(flow_db, idx,
561*2d9fd380Sjfb8856606 							     &child_fid)) {
562*2d9fd380Sjfb8856606 		/* update the child flows resource handle */
563*2d9fd380Sjfb8856606 		if (ulp_flow_db_child_flow_reset(ulp, BNXT_ULP_FDB_TYPE_REGULAR,
564*2d9fd380Sjfb8856606 						 child_fid)) {
565*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "failed to reset child flow %x\n",
566*2d9fd380Sjfb8856606 				    child_fid);
567*2d9fd380Sjfb8856606 			return -EINVAL;
568*2d9fd380Sjfb8856606 		}
569*2d9fd380Sjfb8856606 	}
570*2d9fd380Sjfb8856606 
571*2d9fd380Sjfb8856606 	/* free the parent entry in the parent table flow */
572*2d9fd380Sjfb8856606 	if (ulp_flow_db_parent_flow_free(ulp, parent_fid)) {
573*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "failed to free parent flow %x\n", parent_fid);
574*2d9fd380Sjfb8856606 		return -EINVAL;
575*2d9fd380Sjfb8856606 	}
576*2d9fd380Sjfb8856606 	return 0;
577*2d9fd380Sjfb8856606 }
578*2d9fd380Sjfb8856606 
579*2d9fd380Sjfb8856606 static inline int32_t
ulp_mapper_child_flow_free(struct bnxt_ulp_context * ulp,uint32_t child_fid,struct ulp_flow_db_res_params * res)580*2d9fd380Sjfb8856606 ulp_mapper_child_flow_free(struct bnxt_ulp_context *ulp,
581*2d9fd380Sjfb8856606 			   uint32_t child_fid,
582*2d9fd380Sjfb8856606 			   struct ulp_flow_db_res_params *res)
583*2d9fd380Sjfb8856606 {
584*2d9fd380Sjfb8856606 	uint32_t parent_fid;
585*2d9fd380Sjfb8856606 
586*2d9fd380Sjfb8856606 	parent_fid = (uint32_t)res->resource_hndl;
587*2d9fd380Sjfb8856606 	if (!parent_fid)
588*2d9fd380Sjfb8856606 		return 0; /* Already freed - orphan child*/
589*2d9fd380Sjfb8856606 
590*2d9fd380Sjfb8856606 	/* reset the child flow bitset*/
591*2d9fd380Sjfb8856606 	if (ulp_flow_db_parent_child_flow_set(ulp, parent_fid, child_fid, 0)) {
592*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "error in resetting child flow bitset %x:%x\n",
593*2d9fd380Sjfb8856606 			    parent_fid, child_fid);
594*2d9fd380Sjfb8856606 		return -EINVAL;
595*2d9fd380Sjfb8856606 	}
596*2d9fd380Sjfb8856606 	return 0;
597*2d9fd380Sjfb8856606 }
598*2d9fd380Sjfb8856606 
599*2d9fd380Sjfb8856606 /*
600*2d9fd380Sjfb8856606  * Process the identifier instruction and either store it in the flow database
601*2d9fd380Sjfb8856606  * or return it in the val (if not NULL) on success.  If val is NULL, the
602*2d9fd380Sjfb8856606  * identifier is to be stored in the flow database.
603*2d9fd380Sjfb8856606  */
604*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_ident_process(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl,struct bnxt_ulp_mapper_ident_info * ident,uint16_t * val)605*2d9fd380Sjfb8856606 ulp_mapper_ident_process(struct bnxt_ulp_mapper_parms *parms,
606*2d9fd380Sjfb8856606 			 struct bnxt_ulp_mapper_tbl_info *tbl,
607*2d9fd380Sjfb8856606 			 struct bnxt_ulp_mapper_ident_info *ident,
608*2d9fd380Sjfb8856606 			 uint16_t *val)
609*2d9fd380Sjfb8856606 {
610*2d9fd380Sjfb8856606 	struct ulp_flow_db_res_params	fid_parms;
611*2d9fd380Sjfb8856606 	uint64_t id = 0;
612*2d9fd380Sjfb8856606 	int32_t idx;
613*2d9fd380Sjfb8856606 	struct tf_alloc_identifier_parms iparms = { 0 };
614*2d9fd380Sjfb8856606 	struct tf_free_identifier_parms free_parms = { 0 };
615*2d9fd380Sjfb8856606 	struct tf *tfp;
616*2d9fd380Sjfb8856606 	int rc;
617*2d9fd380Sjfb8856606 
618*2d9fd380Sjfb8856606 	tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
619*2d9fd380Sjfb8856606 	if (!tfp) {
620*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get tf pointer\n");
621*2d9fd380Sjfb8856606 		return -EINVAL;
622*2d9fd380Sjfb8856606 	}
623*2d9fd380Sjfb8856606 
624*2d9fd380Sjfb8856606 	idx = ident->regfile_idx;
625*2d9fd380Sjfb8856606 
626*2d9fd380Sjfb8856606 	iparms.ident_type = ident->ident_type;
627*2d9fd380Sjfb8856606 	iparms.dir = tbl->direction;
628*2d9fd380Sjfb8856606 
629*2d9fd380Sjfb8856606 	rc = tf_alloc_identifier(tfp, &iparms);
630*2d9fd380Sjfb8856606 	if (rc) {
631*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Alloc ident %s:%d failed.\n",
632*2d9fd380Sjfb8856606 			    (iparms.dir == TF_DIR_RX) ? "RX" : "TX",
633*2d9fd380Sjfb8856606 			    iparms.ident_type);
634*2d9fd380Sjfb8856606 		return rc;
635*2d9fd380Sjfb8856606 	}
636*2d9fd380Sjfb8856606 
637*2d9fd380Sjfb8856606 	id = (uint64_t)tfp_cpu_to_be_64(iparms.id);
638*2d9fd380Sjfb8856606 	if (!ulp_regfile_write(parms->regfile, idx, id)) {
639*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Regfile[%d] write failed.\n", idx);
640*2d9fd380Sjfb8856606 		rc = -EINVAL;
641*2d9fd380Sjfb8856606 		/* Need to free the identifier, so goto error */
642*2d9fd380Sjfb8856606 		goto error;
643*2d9fd380Sjfb8856606 	}
644*2d9fd380Sjfb8856606 
645*2d9fd380Sjfb8856606 	/* Link the resource to the flow in the flow db */
646*2d9fd380Sjfb8856606 	if (!val) {
647*2d9fd380Sjfb8856606 		memset(&fid_parms, 0, sizeof(fid_parms));
648*2d9fd380Sjfb8856606 		fid_parms.direction		= tbl->direction;
649*2d9fd380Sjfb8856606 		fid_parms.resource_func	= ident->resource_func;
650*2d9fd380Sjfb8856606 		fid_parms.resource_type	= ident->ident_type;
651*2d9fd380Sjfb8856606 		fid_parms.resource_hndl	= iparms.id;
652*2d9fd380Sjfb8856606 		fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
653*2d9fd380Sjfb8856606 
654*2d9fd380Sjfb8856606 		rc = ulp_flow_db_resource_add(parms->ulp_ctx,
655*2d9fd380Sjfb8856606 					      parms->flow_type,
656*2d9fd380Sjfb8856606 					      parms->fid,
657*2d9fd380Sjfb8856606 					      &fid_parms);
658*2d9fd380Sjfb8856606 		if (rc) {
659*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Failed to link res to flow rc = %d\n",
660*2d9fd380Sjfb8856606 				    rc);
661*2d9fd380Sjfb8856606 			/* Need to free the identifier, so goto error */
662*2d9fd380Sjfb8856606 			goto error;
663*2d9fd380Sjfb8856606 		}
664*2d9fd380Sjfb8856606 	} else {
665*2d9fd380Sjfb8856606 		*val = iparms.id;
666*2d9fd380Sjfb8856606 	}
667*2d9fd380Sjfb8856606 
668*2d9fd380Sjfb8856606 	return 0;
669*2d9fd380Sjfb8856606 
670*2d9fd380Sjfb8856606 error:
671*2d9fd380Sjfb8856606 	/* Need to free the identifier */
672*2d9fd380Sjfb8856606 	free_parms.dir		= tbl->direction;
673*2d9fd380Sjfb8856606 	free_parms.ident_type	= ident->ident_type;
674*2d9fd380Sjfb8856606 	free_parms.id		= iparms.id;
675*2d9fd380Sjfb8856606 
676*2d9fd380Sjfb8856606 	(void)tf_free_identifier(tfp, &free_parms);
677*2d9fd380Sjfb8856606 
678*2d9fd380Sjfb8856606 	BNXT_TF_DBG(ERR, "Ident process failed for %s:%s\n",
679*2d9fd380Sjfb8856606 		    ident->description,
680*2d9fd380Sjfb8856606 		    (tbl->direction == TF_DIR_RX) ? "RX" : "TX");
681*2d9fd380Sjfb8856606 	return rc;
682*2d9fd380Sjfb8856606 }
683*2d9fd380Sjfb8856606 
684*2d9fd380Sjfb8856606 /*
685*2d9fd380Sjfb8856606  * Process the identifier instruction and extract it from result blob.
686*2d9fd380Sjfb8856606  * Increment the identifier reference count and store it in the flow database.
687*2d9fd380Sjfb8856606  */
688*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_ident_extract(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl,struct bnxt_ulp_mapper_ident_info * ident,struct ulp_blob * res_blob)689*2d9fd380Sjfb8856606 ulp_mapper_ident_extract(struct bnxt_ulp_mapper_parms *parms,
690*2d9fd380Sjfb8856606 			 struct bnxt_ulp_mapper_tbl_info *tbl,
691*2d9fd380Sjfb8856606 			 struct bnxt_ulp_mapper_ident_info *ident,
692*2d9fd380Sjfb8856606 			 struct ulp_blob *res_blob)
693*2d9fd380Sjfb8856606 {
694*2d9fd380Sjfb8856606 	struct ulp_flow_db_res_params	fid_parms;
695*2d9fd380Sjfb8856606 	uint64_t id = 0;
696*2d9fd380Sjfb8856606 	uint32_t idx = 0;
697*2d9fd380Sjfb8856606 	struct tf_search_identifier_parms sparms = { 0 };
698*2d9fd380Sjfb8856606 	struct tf_free_identifier_parms free_parms = { 0 };
699*2d9fd380Sjfb8856606 	struct tf *tfp;
700*2d9fd380Sjfb8856606 	int rc;
701*2d9fd380Sjfb8856606 
702*2d9fd380Sjfb8856606 	/* Get the tfp from ulp context */
703*2d9fd380Sjfb8856606 	tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
704*2d9fd380Sjfb8856606 	if (!tfp) {
705*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get tf pointer\n");
706*2d9fd380Sjfb8856606 		return -EINVAL;
707*2d9fd380Sjfb8856606 	}
708*2d9fd380Sjfb8856606 
709*2d9fd380Sjfb8856606 	/* Extract the index from the result blob */
710*2d9fd380Sjfb8856606 	rc = ulp_blob_pull(res_blob, (uint8_t *)&idx, sizeof(idx),
711*2d9fd380Sjfb8856606 			   ident->ident_bit_pos, ident->ident_bit_size);
712*2d9fd380Sjfb8856606 	if (rc) {
713*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to extract identifier from blob\n");
714*2d9fd380Sjfb8856606 		return -EIO;
715*2d9fd380Sjfb8856606 	}
716*2d9fd380Sjfb8856606 
717*2d9fd380Sjfb8856606 	/* populate the search params and search identifier shadow table */
718*2d9fd380Sjfb8856606 	sparms.ident_type = ident->ident_type;
719*2d9fd380Sjfb8856606 	sparms.dir = tbl->direction;
720*2d9fd380Sjfb8856606 	/* convert the idx into cpu format */
721*2d9fd380Sjfb8856606 	sparms.search_id = tfp_be_to_cpu_32(idx);
722*2d9fd380Sjfb8856606 
723*2d9fd380Sjfb8856606 	/* Search identifier also increase the reference count */
724*2d9fd380Sjfb8856606 	rc = tf_search_identifier(tfp, &sparms);
725*2d9fd380Sjfb8856606 	if (rc) {
726*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Search ident %s:%x failed.\n",
727*2d9fd380Sjfb8856606 			    tf_dir_2_str(sparms.dir),
728*2d9fd380Sjfb8856606 			    sparms.search_id);
729*2d9fd380Sjfb8856606 		return rc;
730*2d9fd380Sjfb8856606 	}
731*2d9fd380Sjfb8856606 	BNXT_TF_DBG(INFO, "Search ident %s:%x.success.\n",
732*2d9fd380Sjfb8856606 		    tf_dir_2_str(sparms.dir),
733*2d9fd380Sjfb8856606 		    sparms.search_id);
734*2d9fd380Sjfb8856606 
735*2d9fd380Sjfb8856606 	/* Write it to the regfile */
736*2d9fd380Sjfb8856606 	id = (uint64_t)tfp_cpu_to_be_64(sparms.search_id);
737*2d9fd380Sjfb8856606 	if (!ulp_regfile_write(parms->regfile, ident->regfile_idx, id)) {
738*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Regfile[%d] write failed.\n", idx);
739*2d9fd380Sjfb8856606 		rc = -EINVAL;
740*2d9fd380Sjfb8856606 		/* Need to free the identifier, so goto error */
741*2d9fd380Sjfb8856606 		goto error;
742*2d9fd380Sjfb8856606 	}
743*2d9fd380Sjfb8856606 
744*2d9fd380Sjfb8856606 	/* Link the resource to the flow in the flow db */
745*2d9fd380Sjfb8856606 	memset(&fid_parms, 0, sizeof(fid_parms));
746*2d9fd380Sjfb8856606 	fid_parms.direction = tbl->direction;
747*2d9fd380Sjfb8856606 	fid_parms.resource_func = ident->resource_func;
748*2d9fd380Sjfb8856606 	fid_parms.resource_type = ident->ident_type;
749*2d9fd380Sjfb8856606 	fid_parms.resource_hndl = sparms.search_id;
750*2d9fd380Sjfb8856606 	fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
751*2d9fd380Sjfb8856606 	rc = ulp_flow_db_resource_add(parms->ulp_ctx,
752*2d9fd380Sjfb8856606 				      parms->flow_type,
753*2d9fd380Sjfb8856606 				      parms->fid,
754*2d9fd380Sjfb8856606 				      &fid_parms);
755*2d9fd380Sjfb8856606 	if (rc) {
756*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to link res to flow rc = %d\n",
757*2d9fd380Sjfb8856606 			    rc);
758*2d9fd380Sjfb8856606 		/* Need to free the identifier, so goto error */
759*2d9fd380Sjfb8856606 		goto error;
760*2d9fd380Sjfb8856606 	}
761*2d9fd380Sjfb8856606 
762*2d9fd380Sjfb8856606 	return 0;
763*2d9fd380Sjfb8856606 
764*2d9fd380Sjfb8856606 error:
765*2d9fd380Sjfb8856606 	/* Need to free the identifier */
766*2d9fd380Sjfb8856606 	free_parms.dir = tbl->direction;
767*2d9fd380Sjfb8856606 	free_parms.ident_type = ident->ident_type;
768*2d9fd380Sjfb8856606 	free_parms.id = sparms.search_id;
769*2d9fd380Sjfb8856606 	(void)tf_free_identifier(tfp, &free_parms);
770*2d9fd380Sjfb8856606 	BNXT_TF_DBG(ERR, "Ident extract failed for %s:%s:%x\n",
771*2d9fd380Sjfb8856606 		    ident->description,
772*2d9fd380Sjfb8856606 		    tf_dir_2_str(tbl->direction), sparms.search_id);
773*2d9fd380Sjfb8856606 	return rc;
774*2d9fd380Sjfb8856606 }
775*2d9fd380Sjfb8856606 
776*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_result_field_process(struct bnxt_ulp_mapper_parms * parms,enum tf_dir dir,struct bnxt_ulp_mapper_result_field_info * fld,struct ulp_blob * blob,const char * name)777*2d9fd380Sjfb8856606 ulp_mapper_result_field_process(struct bnxt_ulp_mapper_parms *parms,
778*2d9fd380Sjfb8856606 				enum tf_dir dir,
779*2d9fd380Sjfb8856606 				struct bnxt_ulp_mapper_result_field_info *fld,
780*2d9fd380Sjfb8856606 				struct ulp_blob *blob,
781*2d9fd380Sjfb8856606 				const char *name)
782*2d9fd380Sjfb8856606 {
783*2d9fd380Sjfb8856606 	uint16_t idx, size_idx;
784*2d9fd380Sjfb8856606 	uint8_t	 *val = NULL;
785*2d9fd380Sjfb8856606 	uint64_t regval;
786*2d9fd380Sjfb8856606 	uint32_t val_size = 0, field_size = 0;
787*2d9fd380Sjfb8856606 	uint64_t act_bit;
788*2d9fd380Sjfb8856606 	uint8_t act_val[16];
789*2d9fd380Sjfb8856606 	uint64_t hdr_bit;
790*2d9fd380Sjfb8856606 
791*2d9fd380Sjfb8856606 	switch (fld->result_opcode) {
792*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_CONSTANT:
793*2d9fd380Sjfb8856606 		val = fld->result_operand;
794*2d9fd380Sjfb8856606 		if (!ulp_blob_push(blob, val, fld->field_bit_size)) {
795*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s failed to add field\n", name);
796*2d9fd380Sjfb8856606 			return -EINVAL;
797*2d9fd380Sjfb8856606 		}
798*2d9fd380Sjfb8856606 		break;
799*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_ACT_PROP:
800*2d9fd380Sjfb8856606 		if (!ulp_operand_read(fld->result_operand,
801*2d9fd380Sjfb8856606 				      (uint8_t *)&idx, sizeof(uint16_t))) {
802*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
803*2d9fd380Sjfb8856606 			return -EINVAL;
804*2d9fd380Sjfb8856606 		}
805*2d9fd380Sjfb8856606 		idx = tfp_be_to_cpu_16(idx);
806*2d9fd380Sjfb8856606 
807*2d9fd380Sjfb8856606 		if (idx >= BNXT_ULP_ACT_PROP_IDX_LAST) {
808*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s act_prop[%d] oob\n", name, idx);
809*2d9fd380Sjfb8856606 			return -EINVAL;
810*2d9fd380Sjfb8856606 		}
811*2d9fd380Sjfb8856606 		val = &parms->act_prop->act_details[idx];
812*2d9fd380Sjfb8856606 		field_size = ulp_mapper_act_prop_size_get(idx);
813*2d9fd380Sjfb8856606 		if (fld->field_bit_size < ULP_BYTE_2_BITS(field_size)) {
814*2d9fd380Sjfb8856606 			field_size  = field_size -
815*2d9fd380Sjfb8856606 			    ((fld->field_bit_size + 7) / 8);
816*2d9fd380Sjfb8856606 			val += field_size;
817*2d9fd380Sjfb8856606 		}
818*2d9fd380Sjfb8856606 		if (!ulp_blob_push(blob, val, fld->field_bit_size)) {
819*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s push field failed\n", name);
820*2d9fd380Sjfb8856606 			return -EINVAL;
821*2d9fd380Sjfb8856606 		}
822*2d9fd380Sjfb8856606 		break;
823*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_ACT_BIT:
824*2d9fd380Sjfb8856606 		if (!ulp_operand_read(fld->result_operand,
825*2d9fd380Sjfb8856606 				      (uint8_t *)&act_bit, sizeof(uint64_t))) {
826*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
827*2d9fd380Sjfb8856606 			return -EINVAL;
828*2d9fd380Sjfb8856606 		}
829*2d9fd380Sjfb8856606 		act_bit = tfp_be_to_cpu_64(act_bit);
830*2d9fd380Sjfb8856606 		memset(act_val, 0, sizeof(act_val));
831*2d9fd380Sjfb8856606 		if (ULP_BITMAP_ISSET(parms->act_bitmap->bits, act_bit))
832*2d9fd380Sjfb8856606 			act_val[0] = 1;
833*2d9fd380Sjfb8856606 		if (fld->field_bit_size > ULP_BYTE_2_BITS(sizeof(act_val))) {
834*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s field size is incorrect\n", name);
835*2d9fd380Sjfb8856606 			return -EINVAL;
836*2d9fd380Sjfb8856606 		}
837*2d9fd380Sjfb8856606 		if (!ulp_blob_push(blob, act_val, fld->field_bit_size)) {
838*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s push field failed\n", name);
839*2d9fd380Sjfb8856606 			return -EINVAL;
840*2d9fd380Sjfb8856606 		}
841*2d9fd380Sjfb8856606 		val = act_val;
842*2d9fd380Sjfb8856606 		break;
843*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_ENCAP_ACT_PROP_SZ:
844*2d9fd380Sjfb8856606 		if (!ulp_operand_read(fld->result_operand,
845*2d9fd380Sjfb8856606 				      (uint8_t *)&idx, sizeof(uint16_t))) {
846*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
847*2d9fd380Sjfb8856606 			return -EINVAL;
848*2d9fd380Sjfb8856606 		}
849*2d9fd380Sjfb8856606 		idx = tfp_be_to_cpu_16(idx);
850*2d9fd380Sjfb8856606 
851*2d9fd380Sjfb8856606 		if (idx >= BNXT_ULP_ACT_PROP_IDX_LAST) {
852*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s act_prop[%d] oob\n", name, idx);
853*2d9fd380Sjfb8856606 			return -EINVAL;
854*2d9fd380Sjfb8856606 		}
855*2d9fd380Sjfb8856606 		val = &parms->act_prop->act_details[idx];
856*2d9fd380Sjfb8856606 
857*2d9fd380Sjfb8856606 		/* get the size index next */
858*2d9fd380Sjfb8856606 		if (!ulp_operand_read(&fld->result_operand[sizeof(uint16_t)],
859*2d9fd380Sjfb8856606 				      (uint8_t *)&size_idx, sizeof(uint16_t))) {
860*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
861*2d9fd380Sjfb8856606 			return -EINVAL;
862*2d9fd380Sjfb8856606 		}
863*2d9fd380Sjfb8856606 		size_idx = tfp_be_to_cpu_16(size_idx);
864*2d9fd380Sjfb8856606 
865*2d9fd380Sjfb8856606 		if (size_idx >= BNXT_ULP_ACT_PROP_IDX_LAST) {
866*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "act_prop[%d] oob\n", size_idx);
867*2d9fd380Sjfb8856606 			return -EINVAL;
868*2d9fd380Sjfb8856606 		}
869*2d9fd380Sjfb8856606 		memcpy(&val_size, &parms->act_prop->act_details[size_idx],
870*2d9fd380Sjfb8856606 		       sizeof(uint32_t));
871*2d9fd380Sjfb8856606 		val_size = tfp_be_to_cpu_32(val_size);
872*2d9fd380Sjfb8856606 		val_size = ULP_BYTE_2_BITS(val_size);
873*2d9fd380Sjfb8856606 		ulp_blob_push_encap(blob, val, val_size);
874*2d9fd380Sjfb8856606 		break;
875*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_REGFILE:
876*2d9fd380Sjfb8856606 		if (!ulp_operand_read(fld->result_operand,
877*2d9fd380Sjfb8856606 				      (uint8_t *)&idx, sizeof(uint16_t))) {
878*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
879*2d9fd380Sjfb8856606 			return -EINVAL;
880*2d9fd380Sjfb8856606 		}
881*2d9fd380Sjfb8856606 
882*2d9fd380Sjfb8856606 		idx = tfp_be_to_cpu_16(idx);
883*2d9fd380Sjfb8856606 		/* Uninitialized regfile entries return 0 */
884*2d9fd380Sjfb8856606 		if (!ulp_regfile_read(parms->regfile, idx, &regval)) {
885*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s regfile[%d] read oob\n",
886*2d9fd380Sjfb8856606 				    name, idx);
887*2d9fd380Sjfb8856606 			return -EINVAL;
888*2d9fd380Sjfb8856606 		}
889*2d9fd380Sjfb8856606 
890*2d9fd380Sjfb8856606 		val = ulp_blob_push_64(blob, &regval, fld->field_bit_size);
891*2d9fd380Sjfb8856606 		if (!val) {
892*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s push field failed\n", name);
893*2d9fd380Sjfb8856606 			return -EINVAL;
894*2d9fd380Sjfb8856606 		}
895*2d9fd380Sjfb8856606 		break;
896*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_GLB_REGFILE:
897*2d9fd380Sjfb8856606 		if (!ulp_operand_read(fld->result_operand,
898*2d9fd380Sjfb8856606 				      (uint8_t *)&idx,
899*2d9fd380Sjfb8856606 				      sizeof(uint16_t))) {
900*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
901*2d9fd380Sjfb8856606 			return -EINVAL;
902*2d9fd380Sjfb8856606 		}
903*2d9fd380Sjfb8856606 		idx = tfp_be_to_cpu_16(idx);
904*2d9fd380Sjfb8856606 		if (ulp_mapper_glb_resource_read(parms->mapper_data,
905*2d9fd380Sjfb8856606 						 dir,
906*2d9fd380Sjfb8856606 						 idx, &regval)) {
907*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s regfile[%d] read failed.\n",
908*2d9fd380Sjfb8856606 				    name, idx);
909*2d9fd380Sjfb8856606 			return -EINVAL;
910*2d9fd380Sjfb8856606 		}
911*2d9fd380Sjfb8856606 		val = ulp_blob_push_64(blob, &regval, fld->field_bit_size);
912*2d9fd380Sjfb8856606 		if (!val) {
913*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
914*2d9fd380Sjfb8856606 			return -EINVAL;
915*2d9fd380Sjfb8856606 		}
916*2d9fd380Sjfb8856606 		break;
917*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_COMP_FIELD:
918*2d9fd380Sjfb8856606 		if (!ulp_operand_read(fld->result_operand,
919*2d9fd380Sjfb8856606 				      (uint8_t *)&idx,
920*2d9fd380Sjfb8856606 				      sizeof(uint16_t))) {
921*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
922*2d9fd380Sjfb8856606 			return -EINVAL;
923*2d9fd380Sjfb8856606 		}
924*2d9fd380Sjfb8856606 		idx = tfp_be_to_cpu_16(idx);
925*2d9fd380Sjfb8856606 		if (idx < BNXT_ULP_CF_IDX_LAST)
926*2d9fd380Sjfb8856606 			val = ulp_blob_push_32(blob, &parms->comp_fld[idx],
927*2d9fd380Sjfb8856606 					       fld->field_bit_size);
928*2d9fd380Sjfb8856606 		if (!val) {
929*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
930*2d9fd380Sjfb8856606 			return -EINVAL;
931*2d9fd380Sjfb8856606 		}
932*2d9fd380Sjfb8856606 		break;
933*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_ZERO:
934*2d9fd380Sjfb8856606 		if (ulp_blob_pad_push(blob, fld->field_bit_size) < 0) {
935*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s too large for blob\n", name);
936*2d9fd380Sjfb8856606 			return -EINVAL;
937*2d9fd380Sjfb8856606 		}
938*2d9fd380Sjfb8856606 
939*2d9fd380Sjfb8856606 		break;
940*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_IF_ACT_BIT_THEN_ACT_PROP_ELSE_CONST:
941*2d9fd380Sjfb8856606 		if (!ulp_operand_read(fld->result_operand,
942*2d9fd380Sjfb8856606 				      (uint8_t *)&act_bit, sizeof(uint64_t))) {
943*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
944*2d9fd380Sjfb8856606 			return -EINVAL;
945*2d9fd380Sjfb8856606 		}
946*2d9fd380Sjfb8856606 		act_bit = tfp_be_to_cpu_64(act_bit);
947*2d9fd380Sjfb8856606 		if (ULP_BITMAP_ISSET(parms->act_bitmap->bits, act_bit)) {
948*2d9fd380Sjfb8856606 			/* Action bit is set so consider operand_true */
949*2d9fd380Sjfb8856606 			if (!ulp_operand_read(fld->result_operand_true,
950*2d9fd380Sjfb8856606 					      (uint8_t *)&idx,
951*2d9fd380Sjfb8856606 					      sizeof(uint16_t))) {
952*2d9fd380Sjfb8856606 				BNXT_TF_DBG(ERR, "%s operand read failed\n",
953*2d9fd380Sjfb8856606 					    name);
954*2d9fd380Sjfb8856606 				return -EINVAL;
955*2d9fd380Sjfb8856606 			}
956*2d9fd380Sjfb8856606 			idx = tfp_be_to_cpu_16(idx);
957*2d9fd380Sjfb8856606 			if (idx >= BNXT_ULP_ACT_PROP_IDX_LAST) {
958*2d9fd380Sjfb8856606 				BNXT_TF_DBG(ERR, "%s act_prop[%d] oob\n",
959*2d9fd380Sjfb8856606 					    name, idx);
960*2d9fd380Sjfb8856606 				return -EINVAL;
961*2d9fd380Sjfb8856606 			}
962*2d9fd380Sjfb8856606 			val = &parms->act_prop->act_details[idx];
963*2d9fd380Sjfb8856606 			field_size = ulp_mapper_act_prop_size_get(idx);
964*2d9fd380Sjfb8856606 			if (fld->field_bit_size < ULP_BYTE_2_BITS(field_size)) {
965*2d9fd380Sjfb8856606 				field_size  = field_size -
966*2d9fd380Sjfb8856606 				    ((fld->field_bit_size + 7) / 8);
967*2d9fd380Sjfb8856606 				val += field_size;
968*2d9fd380Sjfb8856606 			}
969*2d9fd380Sjfb8856606 			if (!ulp_blob_push(blob, val, fld->field_bit_size)) {
970*2d9fd380Sjfb8856606 				BNXT_TF_DBG(ERR, "%s push field failed\n",
971*2d9fd380Sjfb8856606 					    name);
972*2d9fd380Sjfb8856606 				return -EINVAL;
973*2d9fd380Sjfb8856606 			}
974*2d9fd380Sjfb8856606 		} else {
975*2d9fd380Sjfb8856606 			/* action bit is not set, use the operand false */
976*2d9fd380Sjfb8856606 			val = fld->result_operand_false;
977*2d9fd380Sjfb8856606 			if (!ulp_blob_push(blob, val, fld->field_bit_size)) {
978*2d9fd380Sjfb8856606 				BNXT_TF_DBG(ERR, "%s failed to add field\n",
979*2d9fd380Sjfb8856606 					    name);
980*2d9fd380Sjfb8856606 				return -EINVAL;
981*2d9fd380Sjfb8856606 			}
982*2d9fd380Sjfb8856606 		}
983*2d9fd380Sjfb8856606 		break;
984*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_IF_ACT_BIT_THEN_CONST_ELSE_CONST:
985*2d9fd380Sjfb8856606 		if (!ulp_operand_read(fld->result_operand,
986*2d9fd380Sjfb8856606 				      (uint8_t *)&act_bit, sizeof(uint64_t))) {
987*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
988*2d9fd380Sjfb8856606 			return -EINVAL;
989*2d9fd380Sjfb8856606 		}
990*2d9fd380Sjfb8856606 		act_bit = tfp_be_to_cpu_64(act_bit);
991*2d9fd380Sjfb8856606 		if (ULP_BITMAP_ISSET(parms->act_bitmap->bits, act_bit)) {
992*2d9fd380Sjfb8856606 			/* Action bit is set so consider operand_true */
993*2d9fd380Sjfb8856606 			val = fld->result_operand_true;
994*2d9fd380Sjfb8856606 		} else {
995*2d9fd380Sjfb8856606 			/* action bit is not set, use the operand false */
996*2d9fd380Sjfb8856606 			val = fld->result_operand_false;
997*2d9fd380Sjfb8856606 		}
998*2d9fd380Sjfb8856606 		if (!ulp_blob_push(blob, val, fld->field_bit_size)) {
999*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s failed to add field\n",
1000*2d9fd380Sjfb8856606 				    name);
1001*2d9fd380Sjfb8856606 			return -EINVAL;
1002*2d9fd380Sjfb8856606 		}
1003*2d9fd380Sjfb8856606 		break;
1004*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_IF_COMP_FIELD_THEN_CF_ELSE_CF:
1005*2d9fd380Sjfb8856606 		if (!ulp_operand_read(fld->result_operand,
1006*2d9fd380Sjfb8856606 				      (uint8_t *)&idx,
1007*2d9fd380Sjfb8856606 				      sizeof(uint16_t))) {
1008*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
1009*2d9fd380Sjfb8856606 			return -EINVAL;
1010*2d9fd380Sjfb8856606 		}
1011*2d9fd380Sjfb8856606 		idx = tfp_be_to_cpu_16(idx);
1012*2d9fd380Sjfb8856606 		if (idx >= BNXT_ULP_CF_IDX_LAST) {
1013*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s invalid index %u\n", name, idx);
1014*2d9fd380Sjfb8856606 			return -EINVAL;
1015*2d9fd380Sjfb8856606 		}
1016*2d9fd380Sjfb8856606 		/* check if the computed field is set */
1017*2d9fd380Sjfb8856606 		if (ULP_COMP_FLD_IDX_RD(parms, idx))
1018*2d9fd380Sjfb8856606 			val = fld->result_operand_true;
1019*2d9fd380Sjfb8856606 		else
1020*2d9fd380Sjfb8856606 			val = fld->result_operand_false;
1021*2d9fd380Sjfb8856606 
1022*2d9fd380Sjfb8856606 		/* read the appropriate computed field */
1023*2d9fd380Sjfb8856606 		if (!ulp_operand_read(val, (uint8_t *)&idx, sizeof(uint16_t))) {
1024*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s val operand read failed\n", name);
1025*2d9fd380Sjfb8856606 			return -EINVAL;
1026*2d9fd380Sjfb8856606 		}
1027*2d9fd380Sjfb8856606 		idx = tfp_be_to_cpu_16(idx);
1028*2d9fd380Sjfb8856606 		if (idx >= BNXT_ULP_CF_IDX_LAST) {
1029*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s invalid index %u\n", name, idx);
1030*2d9fd380Sjfb8856606 			return -EINVAL;
1031*2d9fd380Sjfb8856606 		}
1032*2d9fd380Sjfb8856606 		val = ulp_blob_push_32(blob, &parms->comp_fld[idx],
1033*2d9fd380Sjfb8856606 				       fld->field_bit_size);
1034*2d9fd380Sjfb8856606 		if (!val) {
1035*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
1036*2d9fd380Sjfb8856606 			return -EINVAL;
1037*2d9fd380Sjfb8856606 		}
1038*2d9fd380Sjfb8856606 		break;
1039*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_IF_HDR_BIT_THEN_CONST_ELSE_CONST:
1040*2d9fd380Sjfb8856606 		if (!ulp_operand_read(fld->result_operand,
1041*2d9fd380Sjfb8856606 				      (uint8_t *)&hdr_bit, sizeof(uint64_t))) {
1042*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s operand read failed\n", name);
1043*2d9fd380Sjfb8856606 			return -EINVAL;
1044*2d9fd380Sjfb8856606 		}
1045*2d9fd380Sjfb8856606 		hdr_bit = tfp_be_to_cpu_64(hdr_bit);
1046*2d9fd380Sjfb8856606 		if (ULP_BITMAP_ISSET(parms->hdr_bitmap->bits, hdr_bit)) {
1047*2d9fd380Sjfb8856606 			/* Header bit is set so consider operand_true */
1048*2d9fd380Sjfb8856606 			val = fld->result_operand_true;
1049*2d9fd380Sjfb8856606 		} else {
1050*2d9fd380Sjfb8856606 			/* Header bit is not set, use the operand false */
1051*2d9fd380Sjfb8856606 			val = fld->result_operand_false;
1052*2d9fd380Sjfb8856606 		}
1053*2d9fd380Sjfb8856606 		if (!ulp_blob_push(blob, val, fld->field_bit_size)) {
1054*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s failed to add field\n",
1055*2d9fd380Sjfb8856606 				    name);
1056*2d9fd380Sjfb8856606 			return -EINVAL;
1057*2d9fd380Sjfb8856606 		}
1058*2d9fd380Sjfb8856606 		break;
1059*2d9fd380Sjfb8856606 	default:
1060*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "invalid result mapper opcode 0x%x\n",
1061*2d9fd380Sjfb8856606 			    fld->result_opcode);
1062*2d9fd380Sjfb8856606 		return -EINVAL;
1063*2d9fd380Sjfb8856606 	}
1064*2d9fd380Sjfb8856606 	return 0;
1065*2d9fd380Sjfb8856606 }
1066*2d9fd380Sjfb8856606 
1067*2d9fd380Sjfb8856606 /* Function to alloc action record and set the table. */
1068*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_keymask_field_process(struct bnxt_ulp_mapper_parms * parms,enum tf_dir dir,struct bnxt_ulp_mapper_key_field_info * f,struct ulp_blob * blob,uint8_t is_key,const char * name)1069*2d9fd380Sjfb8856606 ulp_mapper_keymask_field_process(struct bnxt_ulp_mapper_parms *parms,
1070*2d9fd380Sjfb8856606 				 enum tf_dir dir,
1071*2d9fd380Sjfb8856606 				 struct bnxt_ulp_mapper_key_field_info *f,
1072*2d9fd380Sjfb8856606 				 struct ulp_blob *blob,
1073*2d9fd380Sjfb8856606 				 uint8_t is_key,
1074*2d9fd380Sjfb8856606 				 const char *name)
1075*2d9fd380Sjfb8856606 {
1076*2d9fd380Sjfb8856606 	uint64_t val64;
1077*2d9fd380Sjfb8856606 	uint16_t idx, bitlen;
1078*2d9fd380Sjfb8856606 	uint32_t opcode;
1079*2d9fd380Sjfb8856606 	uint8_t *operand;
1080*2d9fd380Sjfb8856606 	struct ulp_regfile *regfile = parms->regfile;
1081*2d9fd380Sjfb8856606 	uint8_t *val = NULL;
1082*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_key_field_info *fld = f;
1083*2d9fd380Sjfb8856606 	uint32_t field_size;
1084*2d9fd380Sjfb8856606 
1085*2d9fd380Sjfb8856606 	if (is_key) {
1086*2d9fd380Sjfb8856606 		operand = fld->spec_operand;
1087*2d9fd380Sjfb8856606 		opcode	= fld->spec_opcode;
1088*2d9fd380Sjfb8856606 	} else {
1089*2d9fd380Sjfb8856606 		operand = fld->mask_operand;
1090*2d9fd380Sjfb8856606 		opcode	= fld->mask_opcode;
1091*2d9fd380Sjfb8856606 	}
1092*2d9fd380Sjfb8856606 
1093*2d9fd380Sjfb8856606 	bitlen = fld->field_bit_size;
1094*2d9fd380Sjfb8856606 
1095*2d9fd380Sjfb8856606 	switch (opcode) {
1096*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_CONSTANT:
1097*2d9fd380Sjfb8856606 		val = operand;
1098*2d9fd380Sjfb8856606 		if (!ulp_blob_push(blob, val, bitlen)) {
1099*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
1100*2d9fd380Sjfb8856606 			return -EINVAL;
1101*2d9fd380Sjfb8856606 		}
1102*2d9fd380Sjfb8856606 		break;
1103*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_ZERO:
1104*2d9fd380Sjfb8856606 		if (ulp_blob_pad_push(blob, bitlen) < 0) {
1105*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s pad too large for blob\n", name);
1106*2d9fd380Sjfb8856606 			return -EINVAL;
1107*2d9fd380Sjfb8856606 		}
1108*2d9fd380Sjfb8856606 
1109*2d9fd380Sjfb8856606 		break;
1110*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_HDR_FIELD:
1111*2d9fd380Sjfb8856606 		if (!ulp_operand_read(operand, (uint8_t *)&idx,
1112*2d9fd380Sjfb8856606 				      sizeof(uint16_t))) {
1113*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
1114*2d9fd380Sjfb8856606 			return -EINVAL;
1115*2d9fd380Sjfb8856606 		}
1116*2d9fd380Sjfb8856606 		idx = tfp_be_to_cpu_16(idx);
1117*2d9fd380Sjfb8856606 		if (is_key)
1118*2d9fd380Sjfb8856606 			val = parms->hdr_field[idx].spec;
1119*2d9fd380Sjfb8856606 		else
1120*2d9fd380Sjfb8856606 			val = parms->hdr_field[idx].mask;
1121*2d9fd380Sjfb8856606 
1122*2d9fd380Sjfb8856606 		/*
1123*2d9fd380Sjfb8856606 		 * Need to account for how much data was pushed to the header
1124*2d9fd380Sjfb8856606 		 * field vs how much is to be inserted in the key/mask.
1125*2d9fd380Sjfb8856606 		 */
1126*2d9fd380Sjfb8856606 		field_size = parms->hdr_field[idx].size;
1127*2d9fd380Sjfb8856606 		if (bitlen < ULP_BYTE_2_BITS(field_size)) {
1128*2d9fd380Sjfb8856606 			field_size  = field_size - ((bitlen + 7) / 8);
1129*2d9fd380Sjfb8856606 			val += field_size;
1130*2d9fd380Sjfb8856606 		}
1131*2d9fd380Sjfb8856606 
1132*2d9fd380Sjfb8856606 		if (!ulp_blob_push(blob, val, bitlen)) {
1133*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
1134*2d9fd380Sjfb8856606 			return -EINVAL;
1135*2d9fd380Sjfb8856606 		}
1136*2d9fd380Sjfb8856606 		break;
1137*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_COMP_FIELD:
1138*2d9fd380Sjfb8856606 		if (!ulp_operand_read(operand, (uint8_t *)&idx,
1139*2d9fd380Sjfb8856606 				      sizeof(uint16_t))) {
1140*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
1141*2d9fd380Sjfb8856606 			return -EINVAL;
1142*2d9fd380Sjfb8856606 		}
1143*2d9fd380Sjfb8856606 		idx = tfp_be_to_cpu_16(idx);
1144*2d9fd380Sjfb8856606 		if (idx < BNXT_ULP_CF_IDX_LAST)
1145*2d9fd380Sjfb8856606 			val = ulp_blob_push_32(blob, &parms->comp_fld[idx],
1146*2d9fd380Sjfb8856606 					       bitlen);
1147*2d9fd380Sjfb8856606 		if (!val) {
1148*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
1149*2d9fd380Sjfb8856606 			return -EINVAL;
1150*2d9fd380Sjfb8856606 		}
1151*2d9fd380Sjfb8856606 		break;
1152*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_REGFILE:
1153*2d9fd380Sjfb8856606 		if (!ulp_operand_read(operand, (uint8_t *)&idx,
1154*2d9fd380Sjfb8856606 				      sizeof(uint16_t))) {
1155*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
1156*2d9fd380Sjfb8856606 			return -EINVAL;
1157*2d9fd380Sjfb8856606 		}
1158*2d9fd380Sjfb8856606 		idx = tfp_be_to_cpu_16(idx);
1159*2d9fd380Sjfb8856606 
1160*2d9fd380Sjfb8856606 		if (!ulp_regfile_read(regfile, idx, &val64)) {
1161*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s regfile[%d] read failed.\n",
1162*2d9fd380Sjfb8856606 				    name, idx);
1163*2d9fd380Sjfb8856606 			return -EINVAL;
1164*2d9fd380Sjfb8856606 		}
1165*2d9fd380Sjfb8856606 
1166*2d9fd380Sjfb8856606 		val = ulp_blob_push_64(blob, &val64, bitlen);
1167*2d9fd380Sjfb8856606 		if (!val) {
1168*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
1169*2d9fd380Sjfb8856606 			return -EINVAL;
1170*2d9fd380Sjfb8856606 		}
1171*2d9fd380Sjfb8856606 		break;
1172*2d9fd380Sjfb8856606 	case BNXT_ULP_MAPPER_OPC_SET_TO_GLB_REGFILE:
1173*2d9fd380Sjfb8856606 		if (!ulp_operand_read(operand, (uint8_t *)&idx,
1174*2d9fd380Sjfb8856606 				      sizeof(uint16_t))) {
1175*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s key operand read failed.\n", name);
1176*2d9fd380Sjfb8856606 			return -EINVAL;
1177*2d9fd380Sjfb8856606 		}
1178*2d9fd380Sjfb8856606 		idx = tfp_be_to_cpu_16(idx);
1179*2d9fd380Sjfb8856606 		if (ulp_mapper_glb_resource_read(parms->mapper_data,
1180*2d9fd380Sjfb8856606 						 dir,
1181*2d9fd380Sjfb8856606 						 idx, &val64)) {
1182*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s regfile[%d] read failed.\n",
1183*2d9fd380Sjfb8856606 				    name, idx);
1184*2d9fd380Sjfb8856606 			return -EINVAL;
1185*2d9fd380Sjfb8856606 		}
1186*2d9fd380Sjfb8856606 		val = ulp_blob_push_64(blob, &val64, bitlen);
1187*2d9fd380Sjfb8856606 		if (!val) {
1188*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "%s push to key blob failed\n", name);
1189*2d9fd380Sjfb8856606 			return -EINVAL;
1190*2d9fd380Sjfb8856606 		}
1191*2d9fd380Sjfb8856606 		break;
1192*2d9fd380Sjfb8856606 	default:
1193*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "invalid keymask mapper opcode 0x%x\n",
1194*2d9fd380Sjfb8856606 			    opcode);
1195*2d9fd380Sjfb8856606 		return -EINVAL;
1196*2d9fd380Sjfb8856606 		break;
1197*2d9fd380Sjfb8856606 	}
1198*2d9fd380Sjfb8856606 
1199*2d9fd380Sjfb8856606 	return 0;
1200*2d9fd380Sjfb8856606 }
1201*2d9fd380Sjfb8856606 
1202*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_mark_gfid_process(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl,uint64_t flow_id)1203*2d9fd380Sjfb8856606 ulp_mapper_mark_gfid_process(struct bnxt_ulp_mapper_parms *parms,
1204*2d9fd380Sjfb8856606 			     struct bnxt_ulp_mapper_tbl_info *tbl,
1205*2d9fd380Sjfb8856606 			     uint64_t flow_id)
1206*2d9fd380Sjfb8856606 {
1207*2d9fd380Sjfb8856606 	enum bnxt_ulp_mark_db_opcode mark_op = tbl->mark_db_opcode;
1208*2d9fd380Sjfb8856606 	struct ulp_flow_db_res_params fid_parms;
1209*2d9fd380Sjfb8856606 	uint32_t mark, gfid, mark_flag;
1210*2d9fd380Sjfb8856606 	int32_t rc = 0;
1211*2d9fd380Sjfb8856606 
1212*2d9fd380Sjfb8856606 	if (mark_op == BNXT_ULP_MARK_DB_OPCODE_NOP ||
1213*2d9fd380Sjfb8856606 	    !(mark_op == BNXT_ULP_MARK_DB_OPCODE_SET_IF_MARK_ACTION &&
1214*2d9fd380Sjfb8856606 	      ULP_BITMAP_ISSET(parms->act_bitmap->bits,
1215*2d9fd380Sjfb8856606 			       BNXT_ULP_ACTION_BIT_MARK)))
1216*2d9fd380Sjfb8856606 		return rc; /* no need to perform gfid process */
1217*2d9fd380Sjfb8856606 
1218*2d9fd380Sjfb8856606 	/* Get the mark id details from action property */
1219*2d9fd380Sjfb8856606 	memcpy(&mark, &parms->act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_MARK],
1220*2d9fd380Sjfb8856606 	       sizeof(mark));
1221*2d9fd380Sjfb8856606 	mark = tfp_be_to_cpu_32(mark);
1222*2d9fd380Sjfb8856606 
1223*2d9fd380Sjfb8856606 	TF_GET_GFID_FROM_FLOW_ID(flow_id, gfid);
1224*2d9fd380Sjfb8856606 	mark_flag  = BNXT_ULP_MARK_GLOBAL_HW_FID;
1225*2d9fd380Sjfb8856606 	rc = ulp_mark_db_mark_add(parms->ulp_ctx, mark_flag,
1226*2d9fd380Sjfb8856606 				  gfid, mark);
1227*2d9fd380Sjfb8856606 	if (rc) {
1228*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to add mark to flow\n");
1229*2d9fd380Sjfb8856606 		return rc;
1230*2d9fd380Sjfb8856606 	}
1231*2d9fd380Sjfb8856606 	fid_parms.direction = tbl->direction;
1232*2d9fd380Sjfb8856606 	fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_HW_FID;
1233*2d9fd380Sjfb8856606 	fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
1234*2d9fd380Sjfb8856606 	fid_parms.resource_type	= mark_flag;
1235*2d9fd380Sjfb8856606 	fid_parms.resource_hndl	= gfid;
1236*2d9fd380Sjfb8856606 	rc = ulp_flow_db_resource_add(parms->ulp_ctx,
1237*2d9fd380Sjfb8856606 				      parms->flow_type,
1238*2d9fd380Sjfb8856606 				      parms->fid,
1239*2d9fd380Sjfb8856606 				      &fid_parms);
1240*2d9fd380Sjfb8856606 	if (rc)
1241*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Fail to link res to flow rc = %d\n", rc);
1242*2d9fd380Sjfb8856606 	return rc;
1243*2d9fd380Sjfb8856606 }
1244*2d9fd380Sjfb8856606 
1245*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_mark_act_ptr_process(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl)1246*2d9fd380Sjfb8856606 ulp_mapper_mark_act_ptr_process(struct bnxt_ulp_mapper_parms *parms,
1247*2d9fd380Sjfb8856606 				struct bnxt_ulp_mapper_tbl_info *tbl)
1248*2d9fd380Sjfb8856606 {
1249*2d9fd380Sjfb8856606 	enum bnxt_ulp_mark_db_opcode mark_op = tbl->mark_db_opcode;
1250*2d9fd380Sjfb8856606 	struct ulp_flow_db_res_params fid_parms;
1251*2d9fd380Sjfb8856606 	uint32_t act_idx, mark, mark_flag;
1252*2d9fd380Sjfb8856606 	uint64_t val64;
1253*2d9fd380Sjfb8856606 	int32_t rc = 0;
1254*2d9fd380Sjfb8856606 
1255*2d9fd380Sjfb8856606 	if (mark_op == BNXT_ULP_MARK_DB_OPCODE_NOP ||
1256*2d9fd380Sjfb8856606 	    !(mark_op == BNXT_ULP_MARK_DB_OPCODE_SET_IF_MARK_ACTION &&
1257*2d9fd380Sjfb8856606 	      ULP_BITMAP_ISSET(parms->act_bitmap->bits,
1258*2d9fd380Sjfb8856606 			       BNXT_ULP_ACTION_BIT_MARK)))
1259*2d9fd380Sjfb8856606 		return rc; /* no need to perform mark action process */
1260*2d9fd380Sjfb8856606 
1261*2d9fd380Sjfb8856606 	/* Get the mark id details from action property */
1262*2d9fd380Sjfb8856606 	memcpy(&mark, &parms->act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_MARK],
1263*2d9fd380Sjfb8856606 	       sizeof(mark));
1264*2d9fd380Sjfb8856606 	mark = tfp_be_to_cpu_32(mark);
1265*2d9fd380Sjfb8856606 
1266*2d9fd380Sjfb8856606 	if (!ulp_regfile_read(parms->regfile,
1267*2d9fd380Sjfb8856606 			      BNXT_ULP_REGFILE_INDEX_MAIN_ACTION_PTR,
1268*2d9fd380Sjfb8856606 			      &val64)) {
1269*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "read action ptr main failed\n");
1270*2d9fd380Sjfb8856606 		return -EINVAL;
1271*2d9fd380Sjfb8856606 	}
1272*2d9fd380Sjfb8856606 	act_idx = tfp_be_to_cpu_64(val64);
1273*2d9fd380Sjfb8856606 	mark_flag  = BNXT_ULP_MARK_LOCAL_HW_FID;
1274*2d9fd380Sjfb8856606 	rc = ulp_mark_db_mark_add(parms->ulp_ctx, mark_flag,
1275*2d9fd380Sjfb8856606 				  act_idx, mark);
1276*2d9fd380Sjfb8856606 	if (rc) {
1277*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to add mark to flow\n");
1278*2d9fd380Sjfb8856606 		return rc;
1279*2d9fd380Sjfb8856606 	}
1280*2d9fd380Sjfb8856606 	fid_parms.direction = tbl->direction;
1281*2d9fd380Sjfb8856606 	fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_HW_FID;
1282*2d9fd380Sjfb8856606 	fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
1283*2d9fd380Sjfb8856606 	fid_parms.resource_type	= mark_flag;
1284*2d9fd380Sjfb8856606 	fid_parms.resource_hndl	= act_idx;
1285*2d9fd380Sjfb8856606 	rc = ulp_flow_db_resource_add(parms->ulp_ctx,
1286*2d9fd380Sjfb8856606 				      parms->flow_type,
1287*2d9fd380Sjfb8856606 				      parms->fid,
1288*2d9fd380Sjfb8856606 				      &fid_parms);
1289*2d9fd380Sjfb8856606 	if (rc)
1290*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Fail to link res to flow rc = %d\n", rc);
1291*2d9fd380Sjfb8856606 	return rc;
1292*2d9fd380Sjfb8856606 }
1293*2d9fd380Sjfb8856606 
1294*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_mark_vfr_idx_process(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl)1295*2d9fd380Sjfb8856606 ulp_mapper_mark_vfr_idx_process(struct bnxt_ulp_mapper_parms *parms,
1296*2d9fd380Sjfb8856606 				struct bnxt_ulp_mapper_tbl_info *tbl)
1297*2d9fd380Sjfb8856606 {
1298*2d9fd380Sjfb8856606 	struct ulp_flow_db_res_params fid_parms;
1299*2d9fd380Sjfb8856606 	uint32_t act_idx, mark, mark_flag;
1300*2d9fd380Sjfb8856606 	uint64_t val64;
1301*2d9fd380Sjfb8856606 	enum bnxt_ulp_mark_db_opcode mark_op = tbl->mark_db_opcode;
1302*2d9fd380Sjfb8856606 	int32_t rc = 0;
1303*2d9fd380Sjfb8856606 
1304*2d9fd380Sjfb8856606 	if (mark_op == BNXT_ULP_MARK_DB_OPCODE_NOP ||
1305*2d9fd380Sjfb8856606 	    mark_op == BNXT_ULP_MARK_DB_OPCODE_SET_IF_MARK_ACTION)
1306*2d9fd380Sjfb8856606 		return rc; /* no need to perform mark action process */
1307*2d9fd380Sjfb8856606 
1308*2d9fd380Sjfb8856606 	/* Get the mark id details from the computed field of dev port id */
1309*2d9fd380Sjfb8856606 	mark = ULP_COMP_FLD_IDX_RD(parms, BNXT_ULP_CF_IDX_DEV_PORT_ID);
1310*2d9fd380Sjfb8856606 
1311*2d9fd380Sjfb8856606 	 /* Get the main action pointer */
1312*2d9fd380Sjfb8856606 	if (!ulp_regfile_read(parms->regfile,
1313*2d9fd380Sjfb8856606 			      BNXT_ULP_REGFILE_INDEX_MAIN_ACTION_PTR,
1314*2d9fd380Sjfb8856606 			      &val64)) {
1315*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "read action ptr main failed\n");
1316*2d9fd380Sjfb8856606 		return -EINVAL;
1317*2d9fd380Sjfb8856606 	}
1318*2d9fd380Sjfb8856606 	act_idx = tfp_be_to_cpu_64(val64);
1319*2d9fd380Sjfb8856606 
1320*2d9fd380Sjfb8856606 	/* Set the mark flag to local fid and vfr flag */
1321*2d9fd380Sjfb8856606 	mark_flag  = BNXT_ULP_MARK_LOCAL_HW_FID | BNXT_ULP_MARK_VFR_ID;
1322*2d9fd380Sjfb8856606 
1323*2d9fd380Sjfb8856606 	rc = ulp_mark_db_mark_add(parms->ulp_ctx, mark_flag,
1324*2d9fd380Sjfb8856606 				  act_idx, mark);
1325*2d9fd380Sjfb8856606 	if (rc) {
1326*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to add mark to flow\n");
1327*2d9fd380Sjfb8856606 		return rc;
1328*2d9fd380Sjfb8856606 	}
1329*2d9fd380Sjfb8856606 	fid_parms.direction = tbl->direction;
1330*2d9fd380Sjfb8856606 	fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_HW_FID;
1331*2d9fd380Sjfb8856606 	fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
1332*2d9fd380Sjfb8856606 	fid_parms.resource_type	= mark_flag;
1333*2d9fd380Sjfb8856606 	fid_parms.resource_hndl	= act_idx;
1334*2d9fd380Sjfb8856606 	rc = ulp_flow_db_resource_add(parms->ulp_ctx,
1335*2d9fd380Sjfb8856606 				      parms->flow_type,
1336*2d9fd380Sjfb8856606 				      parms->fid,
1337*2d9fd380Sjfb8856606 				      &fid_parms);
1338*2d9fd380Sjfb8856606 	if (rc)
1339*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Fail to link res to flow rc = %d\n", rc);
1340*2d9fd380Sjfb8856606 	return rc;
1341*2d9fd380Sjfb8856606 }
1342*2d9fd380Sjfb8856606 
1343*2d9fd380Sjfb8856606 /*
1344*2d9fd380Sjfb8856606  * Tcam table - create the result blob.
1345*2d9fd380Sjfb8856606  * data [out] - the result blob data
1346*2d9fd380Sjfb8856606  */
1347*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_tcam_tbl_result_create(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl,struct ulp_blob * data)1348*2d9fd380Sjfb8856606 ulp_mapper_tcam_tbl_result_create(struct bnxt_ulp_mapper_parms *parms,
1349*2d9fd380Sjfb8856606 				  struct bnxt_ulp_mapper_tbl_info *tbl,
1350*2d9fd380Sjfb8856606 				  struct ulp_blob *data)
1351*2d9fd380Sjfb8856606 {
1352*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_result_field_info *dflds;
1353*2d9fd380Sjfb8856606 	uint32_t num_dflds;
1354*2d9fd380Sjfb8856606 	uint32_t encap_flds = 0;
1355*2d9fd380Sjfb8856606 	uint32_t i;
1356*2d9fd380Sjfb8856606 	int32_t rc = 0;
1357*2d9fd380Sjfb8856606 
1358*2d9fd380Sjfb8856606 	/* Create the result data blob */
1359*2d9fd380Sjfb8856606 	dflds = ulp_mapper_result_fields_get(parms, tbl, &num_dflds,
1360*2d9fd380Sjfb8856606 					     &encap_flds);
1361*2d9fd380Sjfb8856606 	if (!dflds || !num_dflds || encap_flds) {
1362*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get data fields.\n");
1363*2d9fd380Sjfb8856606 		return -EINVAL;
1364*2d9fd380Sjfb8856606 	}
1365*2d9fd380Sjfb8856606 
1366*2d9fd380Sjfb8856606 	for (i = 0; i < num_dflds; i++) {
1367*2d9fd380Sjfb8856606 		rc = ulp_mapper_result_field_process(parms,
1368*2d9fd380Sjfb8856606 						     tbl->direction,
1369*2d9fd380Sjfb8856606 						     &dflds[i],
1370*2d9fd380Sjfb8856606 						     data,
1371*2d9fd380Sjfb8856606 						     "TCAM Result");
1372*2d9fd380Sjfb8856606 		if (rc) {
1373*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Failed to set data fields\n");
1374*2d9fd380Sjfb8856606 			return -EINVAL;
1375*2d9fd380Sjfb8856606 		}
1376*2d9fd380Sjfb8856606 	}
1377*2d9fd380Sjfb8856606 	return rc;
1378*2d9fd380Sjfb8856606 }
1379*2d9fd380Sjfb8856606 
1380*2d9fd380Sjfb8856606 /* Tcam table scan the identifier list and allocate each identifier */
1381*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_tcam_tbl_scan_ident_alloc(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl)1382*2d9fd380Sjfb8856606 ulp_mapper_tcam_tbl_scan_ident_alloc(struct bnxt_ulp_mapper_parms *parms,
1383*2d9fd380Sjfb8856606 				     struct bnxt_ulp_mapper_tbl_info *tbl)
1384*2d9fd380Sjfb8856606 {
1385*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_ident_info *idents;
1386*2d9fd380Sjfb8856606 	uint32_t num_idents;
1387*2d9fd380Sjfb8856606 	uint32_t i;
1388*2d9fd380Sjfb8856606 
1389*2d9fd380Sjfb8856606 	/*
1390*2d9fd380Sjfb8856606 	 * Since the cache entry is responsible for allocating
1391*2d9fd380Sjfb8856606 	 * identifiers when in use, allocate the identifiers only
1392*2d9fd380Sjfb8856606 	 * during normal processing.
1393*2d9fd380Sjfb8856606 	 */
1394*2d9fd380Sjfb8856606 	if (parms->tcam_tbl_opc ==
1395*2d9fd380Sjfb8856606 	    BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL) {
1396*2d9fd380Sjfb8856606 		idents = ulp_mapper_ident_fields_get(parms, tbl, &num_idents);
1397*2d9fd380Sjfb8856606 
1398*2d9fd380Sjfb8856606 		for (i = 0; i < num_idents; i++) {
1399*2d9fd380Sjfb8856606 			if (ulp_mapper_ident_process(parms, tbl,
1400*2d9fd380Sjfb8856606 						     &idents[i], NULL))
1401*2d9fd380Sjfb8856606 				return -EINVAL;
1402*2d9fd380Sjfb8856606 		}
1403*2d9fd380Sjfb8856606 	}
1404*2d9fd380Sjfb8856606 	return 0;
1405*2d9fd380Sjfb8856606 }
1406*2d9fd380Sjfb8856606 
1407*2d9fd380Sjfb8856606 /*
1408*2d9fd380Sjfb8856606  * Tcam table scan the identifier list and extract the identifier from
1409*2d9fd380Sjfb8856606  * the result blob.
1410*2d9fd380Sjfb8856606  */
1411*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_tcam_tbl_scan_ident_extract(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl,struct ulp_blob * data)1412*2d9fd380Sjfb8856606 ulp_mapper_tcam_tbl_scan_ident_extract(struct bnxt_ulp_mapper_parms *parms,
1413*2d9fd380Sjfb8856606 				       struct bnxt_ulp_mapper_tbl_info *tbl,
1414*2d9fd380Sjfb8856606 				       struct ulp_blob *data)
1415*2d9fd380Sjfb8856606 {
1416*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_ident_info *idents;
1417*2d9fd380Sjfb8856606 	uint32_t num_idents = 0, i;
1418*2d9fd380Sjfb8856606 	int32_t rc = 0;
1419*2d9fd380Sjfb8856606 
1420*2d9fd380Sjfb8856606 	/*
1421*2d9fd380Sjfb8856606 	 * Extract the listed identifiers from the result field,
1422*2d9fd380Sjfb8856606 	 * no need to allocate them.
1423*2d9fd380Sjfb8856606 	 */
1424*2d9fd380Sjfb8856606 	idents = ulp_mapper_ident_fields_get(parms, tbl, &num_idents);
1425*2d9fd380Sjfb8856606 	for (i = 0; i < num_idents; i++) {
1426*2d9fd380Sjfb8856606 		rc = ulp_mapper_ident_extract(parms, tbl, &idents[i], data);
1427*2d9fd380Sjfb8856606 		if (rc) {
1428*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Error in identifier extraction\n");
1429*2d9fd380Sjfb8856606 			return rc;
1430*2d9fd380Sjfb8856606 		}
1431*2d9fd380Sjfb8856606 	}
1432*2d9fd380Sjfb8856606 	return rc;
1433*2d9fd380Sjfb8856606 }
1434*2d9fd380Sjfb8856606 
1435*2d9fd380Sjfb8856606 /* Internal function to write the tcam entry */
1436*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_tcam_tbl_entry_write(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl,struct ulp_blob * key,struct ulp_blob * mask,struct ulp_blob * data,uint16_t idx)1437*2d9fd380Sjfb8856606 ulp_mapper_tcam_tbl_entry_write(struct bnxt_ulp_mapper_parms *parms,
1438*2d9fd380Sjfb8856606 				struct bnxt_ulp_mapper_tbl_info *tbl,
1439*2d9fd380Sjfb8856606 				struct ulp_blob *key,
1440*2d9fd380Sjfb8856606 				struct ulp_blob *mask,
1441*2d9fd380Sjfb8856606 				struct ulp_blob *data,
1442*2d9fd380Sjfb8856606 				uint16_t idx)
1443*2d9fd380Sjfb8856606 {
1444*2d9fd380Sjfb8856606 	struct tf_set_tcam_entry_parms sparms = { 0 };
1445*2d9fd380Sjfb8856606 	struct tf *tfp;
1446*2d9fd380Sjfb8856606 	uint16_t tmplen;
1447*2d9fd380Sjfb8856606 	int32_t rc;
1448*2d9fd380Sjfb8856606 
1449*2d9fd380Sjfb8856606 	tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
1450*2d9fd380Sjfb8856606 	if (!tfp) {
1451*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get truflow pointer\n");
1452*2d9fd380Sjfb8856606 		return -EINVAL;
1453*2d9fd380Sjfb8856606 	}
1454*2d9fd380Sjfb8856606 
1455*2d9fd380Sjfb8856606 	sparms.dir		= tbl->direction;
1456*2d9fd380Sjfb8856606 	sparms.tcam_tbl_type	= tbl->resource_type;
1457*2d9fd380Sjfb8856606 	sparms.idx		= idx;
1458*2d9fd380Sjfb8856606 	/* Already verified the key/mask lengths */
1459*2d9fd380Sjfb8856606 	sparms.key		= ulp_blob_data_get(key, &tmplen);
1460*2d9fd380Sjfb8856606 	sparms.mask		= ulp_blob_data_get(mask, &tmplen);
1461*2d9fd380Sjfb8856606 	sparms.key_sz_in_bits	= tbl->key_bit_size;
1462*2d9fd380Sjfb8856606 	sparms.result		= ulp_blob_data_get(data, &tmplen);
1463*2d9fd380Sjfb8856606 
1464*2d9fd380Sjfb8856606 	if (tbl->result_bit_size != tmplen) {
1465*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Result len (%d) != Expected (%d)\n",
1466*2d9fd380Sjfb8856606 			    tmplen, tbl->result_bit_size);
1467*2d9fd380Sjfb8856606 		return -EINVAL;
1468*2d9fd380Sjfb8856606 	}
1469*2d9fd380Sjfb8856606 	sparms.result_sz_in_bits = tbl->result_bit_size;
1470*2d9fd380Sjfb8856606 	if (tf_set_tcam_entry(tfp, &sparms)) {
1471*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "tcam[%s][%s][%x] write failed.\n",
1472*2d9fd380Sjfb8856606 			    tf_tcam_tbl_2_str(sparms.tcam_tbl_type),
1473*2d9fd380Sjfb8856606 			    tf_dir_2_str(sparms.dir), sparms.idx);
1474*2d9fd380Sjfb8856606 		return -EIO;
1475*2d9fd380Sjfb8856606 	}
1476*2d9fd380Sjfb8856606 	BNXT_TF_DBG(INFO, "tcam[%s][%s][%x] write success.\n",
1477*2d9fd380Sjfb8856606 		    tf_tcam_tbl_2_str(sparms.tcam_tbl_type),
1478*2d9fd380Sjfb8856606 		    tf_dir_2_str(sparms.dir), sparms.idx);
1479*2d9fd380Sjfb8856606 
1480*2d9fd380Sjfb8856606 	/* Update cache with TCAM index if the was cache allocated. */
1481*2d9fd380Sjfb8856606 	if (parms->tcam_tbl_opc ==
1482*2d9fd380Sjfb8856606 	    BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_ALLOC) {
1483*2d9fd380Sjfb8856606 		if (!parms->cache_ptr) {
1484*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Unable to update cache");
1485*2d9fd380Sjfb8856606 			return -EINVAL;
1486*2d9fd380Sjfb8856606 		}
1487*2d9fd380Sjfb8856606 		parms->cache_ptr->tcam_idx = idx;
1488*2d9fd380Sjfb8856606 	}
1489*2d9fd380Sjfb8856606 
1490*2d9fd380Sjfb8856606 	/* Mark action */
1491*2d9fd380Sjfb8856606 	rc = ulp_mapper_mark_act_ptr_process(parms, tbl);
1492*2d9fd380Sjfb8856606 	if (rc) {
1493*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "failed mark action processing\n");
1494*2d9fd380Sjfb8856606 		return rc;
1495*2d9fd380Sjfb8856606 	}
1496*2d9fd380Sjfb8856606 
1497*2d9fd380Sjfb8856606 	return rc;
1498*2d9fd380Sjfb8856606 }
1499*2d9fd380Sjfb8856606 
1500*2d9fd380Sjfb8856606 #define BNXT_ULP_WC_TCAM_SLICE_SIZE 80
1501*2d9fd380Sjfb8856606 /* internal function to post process the key/mask blobs for wildcard tcam tbl */
ulp_mapper_wc_tcam_tbl_post_process(struct ulp_blob * blob,uint32_t len)1502*2d9fd380Sjfb8856606 static void ulp_mapper_wc_tcam_tbl_post_process(struct ulp_blob *blob,
1503*2d9fd380Sjfb8856606 						uint32_t len)
1504*2d9fd380Sjfb8856606 {
1505*2d9fd380Sjfb8856606 	uint8_t mode[2] = {0x0, 0x0};
1506*2d9fd380Sjfb8856606 	uint32_t mode_len = len / BNXT_ULP_WC_TCAM_SLICE_SIZE;
1507*2d9fd380Sjfb8856606 	uint32_t size, idx;
1508*2d9fd380Sjfb8856606 
1509*2d9fd380Sjfb8856606 	/* Add the mode bits to the key and mask*/
1510*2d9fd380Sjfb8856606 	if (mode_len == 2)
1511*2d9fd380Sjfb8856606 		mode[1] = 2;
1512*2d9fd380Sjfb8856606 	else if (mode_len > 2)
1513*2d9fd380Sjfb8856606 		mode[1] = 3;
1514*2d9fd380Sjfb8856606 
1515*2d9fd380Sjfb8856606 	size = BNXT_ULP_WC_TCAM_SLICE_SIZE + ULP_BYTE_2_BITS(sizeof(mode));
1516*2d9fd380Sjfb8856606 	for (idx = 0; idx < mode_len; idx++)
1517*2d9fd380Sjfb8856606 		ulp_blob_insert(blob, (size * idx), mode,
1518*2d9fd380Sjfb8856606 				ULP_BYTE_2_BITS(sizeof(mode)));
1519*2d9fd380Sjfb8856606 	ulp_blob_perform_64B_word_swap(blob);
1520*2d9fd380Sjfb8856606 	ulp_blob_perform_64B_byte_swap(blob);
1521*2d9fd380Sjfb8856606 }
1522*2d9fd380Sjfb8856606 
1523*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl)1524*2d9fd380Sjfb8856606 ulp_mapper_tcam_tbl_process(struct bnxt_ulp_mapper_parms *parms,
1525*2d9fd380Sjfb8856606 			    struct bnxt_ulp_mapper_tbl_info *tbl)
1526*2d9fd380Sjfb8856606 {
1527*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_key_field_info	*kflds;
1528*2d9fd380Sjfb8856606 	struct ulp_blob key, mask, data, update_data;
1529*2d9fd380Sjfb8856606 	uint32_t i, num_kflds;
1530*2d9fd380Sjfb8856606 	struct tf *tfp;
1531*2d9fd380Sjfb8856606 	int32_t rc, trc;
1532*2d9fd380Sjfb8856606 	struct tf_alloc_tcam_entry_parms aparms		= { 0 };
1533*2d9fd380Sjfb8856606 	struct tf_search_tcam_entry_parms searchparms   = { 0 };
1534*2d9fd380Sjfb8856606 	struct ulp_flow_db_res_params	fid_parms	= { 0 };
1535*2d9fd380Sjfb8856606 	struct tf_free_tcam_entry_parms free_parms	= { 0 };
1536*2d9fd380Sjfb8856606 	enum bnxt_ulp_search_before_alloc search_flag;
1537*2d9fd380Sjfb8856606 	uint32_t hit = 0;
1538*2d9fd380Sjfb8856606 	uint16_t tmplen = 0;
1539*2d9fd380Sjfb8856606 	uint16_t idx;
1540*2d9fd380Sjfb8856606 
1541*2d9fd380Sjfb8856606 	/* Skip this if was handled by the cache. */
1542*2d9fd380Sjfb8856606 	if (parms->tcam_tbl_opc == BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_SKIP) {
1543*2d9fd380Sjfb8856606 		parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL;
1544*2d9fd380Sjfb8856606 		return 0;
1545*2d9fd380Sjfb8856606 	}
1546*2d9fd380Sjfb8856606 
1547*2d9fd380Sjfb8856606 	tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
1548*2d9fd380Sjfb8856606 	if (!tfp) {
1549*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get truflow pointer\n");
1550*2d9fd380Sjfb8856606 		return -EINVAL;
1551*2d9fd380Sjfb8856606 	}
1552*2d9fd380Sjfb8856606 
1553*2d9fd380Sjfb8856606 	kflds = ulp_mapper_key_fields_get(parms, tbl, &num_kflds);
1554*2d9fd380Sjfb8856606 	if (!kflds || !num_kflds) {
1555*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get key fields\n");
1556*2d9fd380Sjfb8856606 		return -EINVAL;
1557*2d9fd380Sjfb8856606 	}
1558*2d9fd380Sjfb8856606 
1559*2d9fd380Sjfb8856606 	if (!ulp_blob_init(&key, tbl->blob_key_bit_size,
1560*2d9fd380Sjfb8856606 			   parms->device_params->byte_order) ||
1561*2d9fd380Sjfb8856606 	    !ulp_blob_init(&mask, tbl->blob_key_bit_size,
1562*2d9fd380Sjfb8856606 			   parms->device_params->byte_order) ||
1563*2d9fd380Sjfb8856606 	    !ulp_blob_init(&data, tbl->result_bit_size,
1564*2d9fd380Sjfb8856606 			   parms->device_params->byte_order) ||
1565*2d9fd380Sjfb8856606 	    !ulp_blob_init(&update_data, tbl->result_bit_size,
1566*2d9fd380Sjfb8856606 			   parms->device_params->byte_order)) {
1567*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "blob inits failed.\n");
1568*2d9fd380Sjfb8856606 		return -EINVAL;
1569*2d9fd380Sjfb8856606 	}
1570*2d9fd380Sjfb8856606 
1571*2d9fd380Sjfb8856606 	if (tbl->resource_type == TF_TCAM_TBL_TYPE_WC_TCAM) {
1572*2d9fd380Sjfb8856606 		key.byte_order = BNXT_ULP_BYTE_ORDER_BE;
1573*2d9fd380Sjfb8856606 		mask.byte_order = BNXT_ULP_BYTE_ORDER_BE;
1574*2d9fd380Sjfb8856606 	}
1575*2d9fd380Sjfb8856606 
1576*2d9fd380Sjfb8856606 	/* create the key/mask */
1577*2d9fd380Sjfb8856606 	/*
1578*2d9fd380Sjfb8856606 	 * NOTE: The WC table will require some kind of flag to handle the
1579*2d9fd380Sjfb8856606 	 * mode bits within the key/mask
1580*2d9fd380Sjfb8856606 	 */
1581*2d9fd380Sjfb8856606 	for (i = 0; i < num_kflds; i++) {
1582*2d9fd380Sjfb8856606 		/* Setup the key */
1583*2d9fd380Sjfb8856606 		rc = ulp_mapper_keymask_field_process(parms, tbl->direction,
1584*2d9fd380Sjfb8856606 						      &kflds[i],
1585*2d9fd380Sjfb8856606 						      &key, 1, "TCAM Key");
1586*2d9fd380Sjfb8856606 		if (rc) {
1587*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Key field set failed.\n");
1588*2d9fd380Sjfb8856606 			return rc;
1589*2d9fd380Sjfb8856606 		}
1590*2d9fd380Sjfb8856606 
1591*2d9fd380Sjfb8856606 		/* Setup the mask */
1592*2d9fd380Sjfb8856606 		rc = ulp_mapper_keymask_field_process(parms, tbl->direction,
1593*2d9fd380Sjfb8856606 						      &kflds[i],
1594*2d9fd380Sjfb8856606 						      &mask, 0, "TCAM Mask");
1595*2d9fd380Sjfb8856606 		if (rc) {
1596*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Mask field set failed.\n");
1597*2d9fd380Sjfb8856606 			return rc;
1598*2d9fd380Sjfb8856606 		}
1599*2d9fd380Sjfb8856606 	}
1600*2d9fd380Sjfb8856606 
1601*2d9fd380Sjfb8856606 	if (tbl->resource_type == TF_TCAM_TBL_TYPE_WC_TCAM) {
1602*2d9fd380Sjfb8856606 		ulp_mapper_wc_tcam_tbl_post_process(&key, tbl->key_bit_size);
1603*2d9fd380Sjfb8856606 		ulp_mapper_wc_tcam_tbl_post_process(&mask, tbl->key_bit_size);
1604*2d9fd380Sjfb8856606 	}
1605*2d9fd380Sjfb8856606 
1606*2d9fd380Sjfb8856606 	if (tbl->srch_b4_alloc == BNXT_ULP_SEARCH_BEFORE_ALLOC_NO) {
1607*2d9fd380Sjfb8856606 		/*
1608*2d9fd380Sjfb8856606 		 * No search for re-use is requested, so simply allocate the
1609*2d9fd380Sjfb8856606 		 * tcam index.
1610*2d9fd380Sjfb8856606 		 */
1611*2d9fd380Sjfb8856606 		aparms.dir		= tbl->direction;
1612*2d9fd380Sjfb8856606 		aparms.tcam_tbl_type	= tbl->resource_type;
1613*2d9fd380Sjfb8856606 		aparms.search_enable	= tbl->srch_b4_alloc;
1614*2d9fd380Sjfb8856606 		aparms.key		= ulp_blob_data_get(&key, &tmplen);
1615*2d9fd380Sjfb8856606 		aparms.key_sz_in_bits	= tmplen;
1616*2d9fd380Sjfb8856606 		if (tbl->blob_key_bit_size != tmplen) {
1617*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Key len (%d) != Expected (%d)\n",
1618*2d9fd380Sjfb8856606 				    tmplen, tbl->blob_key_bit_size);
1619*2d9fd380Sjfb8856606 			return -EINVAL;
1620*2d9fd380Sjfb8856606 		}
1621*2d9fd380Sjfb8856606 
1622*2d9fd380Sjfb8856606 		aparms.mask		= ulp_blob_data_get(&mask, &tmplen);
1623*2d9fd380Sjfb8856606 		if (tbl->blob_key_bit_size != tmplen) {
1624*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Mask len (%d) != Expected (%d)\n",
1625*2d9fd380Sjfb8856606 				    tmplen, tbl->blob_key_bit_size);
1626*2d9fd380Sjfb8856606 			return -EINVAL;
1627*2d9fd380Sjfb8856606 		}
1628*2d9fd380Sjfb8856606 
1629*2d9fd380Sjfb8856606 		aparms.priority		= tbl->priority;
1630*2d9fd380Sjfb8856606 
1631*2d9fd380Sjfb8856606 		/*
1632*2d9fd380Sjfb8856606 		 * All failures after this succeeds require the entry to be
1633*2d9fd380Sjfb8856606 		 * freed. cannot return directly on failure, but needs to goto
1634*2d9fd380Sjfb8856606 		 * error.
1635*2d9fd380Sjfb8856606 		 */
1636*2d9fd380Sjfb8856606 		rc = tf_alloc_tcam_entry(tfp, &aparms);
1637*2d9fd380Sjfb8856606 		if (rc) {
1638*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "tcam alloc failed rc=%d.\n", rc);
1639*2d9fd380Sjfb8856606 			return rc;
1640*2d9fd380Sjfb8856606 		}
1641*2d9fd380Sjfb8856606 		idx = aparms.idx;
1642*2d9fd380Sjfb8856606 		hit = aparms.hit;
1643*2d9fd380Sjfb8856606 	} else {
1644*2d9fd380Sjfb8856606 		/*
1645*2d9fd380Sjfb8856606 		 * Searching before allocation to see if we already have an
1646*2d9fd380Sjfb8856606 		 * entry.  This allows re-use of a constrained resource.
1647*2d9fd380Sjfb8856606 		 */
1648*2d9fd380Sjfb8856606 		searchparms.dir = tbl->direction;
1649*2d9fd380Sjfb8856606 		searchparms.tcam_tbl_type = tbl->resource_type;
1650*2d9fd380Sjfb8856606 		searchparms.key = ulp_blob_data_get(&key, &tmplen);
1651*2d9fd380Sjfb8856606 		searchparms.key_sz_in_bits = tbl->key_bit_size;
1652*2d9fd380Sjfb8856606 		searchparms.mask = ulp_blob_data_get(&mask, &tmplen);
1653*2d9fd380Sjfb8856606 		searchparms.priority = tbl->priority;
1654*2d9fd380Sjfb8856606 		searchparms.alloc = 1;
1655*2d9fd380Sjfb8856606 		searchparms.result = ulp_blob_data_get(&data, &tmplen);
1656*2d9fd380Sjfb8856606 		searchparms.result_sz_in_bits = tbl->result_bit_size;
1657*2d9fd380Sjfb8856606 
1658*2d9fd380Sjfb8856606 		rc = tf_search_tcam_entry(tfp, &searchparms);
1659*2d9fd380Sjfb8856606 		if (rc) {
1660*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "tcam search failed rc=%d\n", rc);
1661*2d9fd380Sjfb8856606 			return rc;
1662*2d9fd380Sjfb8856606 		}
1663*2d9fd380Sjfb8856606 
1664*2d9fd380Sjfb8856606 		/* Successful search, check the result */
1665*2d9fd380Sjfb8856606 		if (searchparms.search_status == REJECT) {
1666*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "tcam alloc rejected\n");
1667*2d9fd380Sjfb8856606 			return -ENOMEM;
1668*2d9fd380Sjfb8856606 		}
1669*2d9fd380Sjfb8856606 		idx = searchparms.idx;
1670*2d9fd380Sjfb8856606 		hit = searchparms.hit;
1671*2d9fd380Sjfb8856606 	}
1672*2d9fd380Sjfb8856606 
1673*2d9fd380Sjfb8856606 	/* if it is miss then it is same as no search before alloc */
1674*2d9fd380Sjfb8856606 	if (!hit)
1675*2d9fd380Sjfb8856606 		search_flag = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO;
1676*2d9fd380Sjfb8856606 	else
1677*2d9fd380Sjfb8856606 		search_flag = tbl->srch_b4_alloc;
1678*2d9fd380Sjfb8856606 
1679*2d9fd380Sjfb8856606 	switch (search_flag) {
1680*2d9fd380Sjfb8856606 	case BNXT_ULP_SEARCH_BEFORE_ALLOC_NO:
1681*2d9fd380Sjfb8856606 		/*Scan identifier list, allocate identifier and update regfile*/
1682*2d9fd380Sjfb8856606 		rc = ulp_mapper_tcam_tbl_scan_ident_alloc(parms, tbl);
1683*2d9fd380Sjfb8856606 		/* Create the result blob */
1684*2d9fd380Sjfb8856606 		if (!rc)
1685*2d9fd380Sjfb8856606 			rc = ulp_mapper_tcam_tbl_result_create(parms, tbl,
1686*2d9fd380Sjfb8856606 							       &data);
1687*2d9fd380Sjfb8856606 		/* write the tcam entry */
1688*2d9fd380Sjfb8856606 		if (!rc)
1689*2d9fd380Sjfb8856606 			rc = ulp_mapper_tcam_tbl_entry_write(parms, tbl, &key,
1690*2d9fd380Sjfb8856606 							     &mask, &data, idx);
1691*2d9fd380Sjfb8856606 		break;
1692*2d9fd380Sjfb8856606 	case BNXT_ULP_SEARCH_BEFORE_ALLOC_SEARCH_IF_HIT_SKIP:
1693*2d9fd380Sjfb8856606 		/*Scan identifier list, extract identifier and update regfile*/
1694*2d9fd380Sjfb8856606 		rc = ulp_mapper_tcam_tbl_scan_ident_extract(parms, tbl, &data);
1695*2d9fd380Sjfb8856606 		break;
1696*2d9fd380Sjfb8856606 	case BNXT_ULP_SEARCH_BEFORE_ALLOC_SEARCH_IF_HIT_UPDATE:
1697*2d9fd380Sjfb8856606 		/*Scan identifier list, extract identifier and update regfile*/
1698*2d9fd380Sjfb8856606 		rc = ulp_mapper_tcam_tbl_scan_ident_extract(parms, tbl, &data);
1699*2d9fd380Sjfb8856606 		/* Create the result blob */
1700*2d9fd380Sjfb8856606 		if (!rc)
1701*2d9fd380Sjfb8856606 			rc = ulp_mapper_tcam_tbl_result_create(parms, tbl,
1702*2d9fd380Sjfb8856606 							       &update_data);
1703*2d9fd380Sjfb8856606 		/* Update/overwrite the tcam entry */
1704*2d9fd380Sjfb8856606 		if (!rc)
1705*2d9fd380Sjfb8856606 			rc = ulp_mapper_tcam_tbl_entry_write(parms, tbl, &key,
1706*2d9fd380Sjfb8856606 							     &mask,
1707*2d9fd380Sjfb8856606 							     &update_data, idx);
1708*2d9fd380Sjfb8856606 		break;
1709*2d9fd380Sjfb8856606 	default:
1710*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "invalid search opcode\n");
1711*2d9fd380Sjfb8856606 		rc =  -EINVAL;
1712*2d9fd380Sjfb8856606 		break;
1713*2d9fd380Sjfb8856606 	}
1714*2d9fd380Sjfb8856606 	if (rc)
1715*2d9fd380Sjfb8856606 		goto error;
1716*2d9fd380Sjfb8856606 
1717*2d9fd380Sjfb8856606 	/*
1718*2d9fd380Sjfb8856606 	 * Only link the entry to the flow db in the event that cache was not
1719*2d9fd380Sjfb8856606 	 * used.
1720*2d9fd380Sjfb8856606 	 */
1721*2d9fd380Sjfb8856606 	if (parms->tcam_tbl_opc == BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL) {
1722*2d9fd380Sjfb8856606 		fid_parms.direction = tbl->direction;
1723*2d9fd380Sjfb8856606 		fid_parms.resource_func	= tbl->resource_func;
1724*2d9fd380Sjfb8856606 		fid_parms.resource_type	= tbl->resource_type;
1725*2d9fd380Sjfb8856606 		fid_parms.critical_resource = tbl->critical_resource;
1726*2d9fd380Sjfb8856606 		fid_parms.resource_hndl	= idx;
1727*2d9fd380Sjfb8856606 		rc = ulp_flow_db_resource_add(parms->ulp_ctx,
1728*2d9fd380Sjfb8856606 					      parms->flow_type,
1729*2d9fd380Sjfb8856606 					      parms->fid,
1730*2d9fd380Sjfb8856606 					      &fid_parms);
1731*2d9fd380Sjfb8856606 		if (rc) {
1732*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR,
1733*2d9fd380Sjfb8856606 				    "Failed to link resource to flow rc = %d\n",
1734*2d9fd380Sjfb8856606 				    rc);
1735*2d9fd380Sjfb8856606 			/* Need to free the identifier, so goto error */
1736*2d9fd380Sjfb8856606 			goto error;
1737*2d9fd380Sjfb8856606 		}
1738*2d9fd380Sjfb8856606 	} else {
1739*2d9fd380Sjfb8856606 		/*
1740*2d9fd380Sjfb8856606 		 * Reset the tcam table opcode to normal in case the next tcam
1741*2d9fd380Sjfb8856606 		 * entry does not use cache.
1742*2d9fd380Sjfb8856606 		 */
1743*2d9fd380Sjfb8856606 		parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL;
1744*2d9fd380Sjfb8856606 		parms->cache_ptr = NULL;
1745*2d9fd380Sjfb8856606 	}
1746*2d9fd380Sjfb8856606 
1747*2d9fd380Sjfb8856606 	return 0;
1748*2d9fd380Sjfb8856606 error:
1749*2d9fd380Sjfb8856606 	parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL;
1750*2d9fd380Sjfb8856606 	free_parms.dir			= tbl->direction;
1751*2d9fd380Sjfb8856606 	free_parms.tcam_tbl_type	= tbl->resource_type;
1752*2d9fd380Sjfb8856606 	free_parms.idx			= idx;
1753*2d9fd380Sjfb8856606 	trc = tf_free_tcam_entry(tfp, &free_parms);
1754*2d9fd380Sjfb8856606 	if (trc)
1755*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to free tcam[%d][%d][%d] on failure\n",
1756*2d9fd380Sjfb8856606 			    tbl->resource_type, tbl->direction, idx);
1757*2d9fd380Sjfb8856606 
1758*2d9fd380Sjfb8856606 	return rc;
1759*2d9fd380Sjfb8856606 }
1760*2d9fd380Sjfb8856606 
1761*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_em_tbl_process(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl)1762*2d9fd380Sjfb8856606 ulp_mapper_em_tbl_process(struct bnxt_ulp_mapper_parms *parms,
1763*2d9fd380Sjfb8856606 			  struct bnxt_ulp_mapper_tbl_info *tbl)
1764*2d9fd380Sjfb8856606 {
1765*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_key_field_info	*kflds;
1766*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_result_field_info *dflds;
1767*2d9fd380Sjfb8856606 	struct ulp_blob key, data;
1768*2d9fd380Sjfb8856606 	uint32_t i, num_kflds, num_dflds;
1769*2d9fd380Sjfb8856606 	uint16_t tmplen;
1770*2d9fd380Sjfb8856606 	struct tf *tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
1771*2d9fd380Sjfb8856606 	struct ulp_flow_db_res_params	fid_parms = { 0 };
1772*2d9fd380Sjfb8856606 	struct tf_insert_em_entry_parms iparms = { 0 };
1773*2d9fd380Sjfb8856606 	struct tf_delete_em_entry_parms free_parms = { 0 };
1774*2d9fd380Sjfb8856606 	enum bnxt_ulp_flow_mem_type mtype;
1775*2d9fd380Sjfb8856606 	int32_t	trc;
1776*2d9fd380Sjfb8856606 	int32_t rc = 0;
1777*2d9fd380Sjfb8856606 	uint32_t encap_flds = 0;
1778*2d9fd380Sjfb8856606 
1779*2d9fd380Sjfb8856606 	rc = bnxt_ulp_cntxt_mem_type_get(parms->ulp_ctx, &mtype);
1780*2d9fd380Sjfb8856606 	if (rc) {
1781*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get the mem type for EM\n");
1782*2d9fd380Sjfb8856606 		return -EINVAL;
1783*2d9fd380Sjfb8856606 	}
1784*2d9fd380Sjfb8856606 
1785*2d9fd380Sjfb8856606 	kflds = ulp_mapper_key_fields_get(parms, tbl, &num_kflds);
1786*2d9fd380Sjfb8856606 	if (!kflds || !num_kflds) {
1787*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get key fields\n");
1788*2d9fd380Sjfb8856606 		return -EINVAL;
1789*2d9fd380Sjfb8856606 	}
1790*2d9fd380Sjfb8856606 
1791*2d9fd380Sjfb8856606 	/* Initialize the key/result blobs */
1792*2d9fd380Sjfb8856606 	if (!ulp_blob_init(&key, tbl->blob_key_bit_size,
1793*2d9fd380Sjfb8856606 			   parms->device_params->byte_order) ||
1794*2d9fd380Sjfb8856606 	    !ulp_blob_init(&data, tbl->result_bit_size,
1795*2d9fd380Sjfb8856606 			   parms->device_params->byte_order)) {
1796*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "blob inits failed.\n");
1797*2d9fd380Sjfb8856606 		return -EINVAL;
1798*2d9fd380Sjfb8856606 	}
1799*2d9fd380Sjfb8856606 
1800*2d9fd380Sjfb8856606 	/* create the key */
1801*2d9fd380Sjfb8856606 	for (i = 0; i < num_kflds; i++) {
1802*2d9fd380Sjfb8856606 		/* Setup the key */
1803*2d9fd380Sjfb8856606 		rc = ulp_mapper_keymask_field_process(parms, tbl->direction,
1804*2d9fd380Sjfb8856606 						      &kflds[i],
1805*2d9fd380Sjfb8856606 						      &key, 1, "EM Key");
1806*2d9fd380Sjfb8856606 		if (rc) {
1807*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Key field set failed.\n");
1808*2d9fd380Sjfb8856606 			return rc;
1809*2d9fd380Sjfb8856606 		}
1810*2d9fd380Sjfb8856606 	}
1811*2d9fd380Sjfb8856606 
1812*2d9fd380Sjfb8856606 	/*
1813*2d9fd380Sjfb8856606 	 * TBD: Normally should process identifiers in case of using recycle or
1814*2d9fd380Sjfb8856606 	 * loopback.  Not supporting recycle for now.
1815*2d9fd380Sjfb8856606 	 */
1816*2d9fd380Sjfb8856606 
1817*2d9fd380Sjfb8856606 	/* Create the result data blob */
1818*2d9fd380Sjfb8856606 	dflds = ulp_mapper_result_fields_get(parms, tbl,
1819*2d9fd380Sjfb8856606 					     &num_dflds, &encap_flds);
1820*2d9fd380Sjfb8856606 	if (!dflds || !num_dflds || encap_flds) {
1821*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get data fields.\n");
1822*2d9fd380Sjfb8856606 		return -EINVAL;
1823*2d9fd380Sjfb8856606 	}
1824*2d9fd380Sjfb8856606 
1825*2d9fd380Sjfb8856606 	for (i = 0; i < num_dflds; i++) {
1826*2d9fd380Sjfb8856606 		struct bnxt_ulp_mapper_result_field_info *fld;
1827*2d9fd380Sjfb8856606 
1828*2d9fd380Sjfb8856606 		fld = &dflds[i];
1829*2d9fd380Sjfb8856606 
1830*2d9fd380Sjfb8856606 		rc = ulp_mapper_result_field_process(parms,
1831*2d9fd380Sjfb8856606 						     tbl->direction,
1832*2d9fd380Sjfb8856606 						     fld,
1833*2d9fd380Sjfb8856606 						     &data,
1834*2d9fd380Sjfb8856606 						     "EM Result");
1835*2d9fd380Sjfb8856606 		if (rc) {
1836*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Failed to set data fields.\n");
1837*2d9fd380Sjfb8856606 			return rc;
1838*2d9fd380Sjfb8856606 		}
1839*2d9fd380Sjfb8856606 	}
1840*2d9fd380Sjfb8856606 
1841*2d9fd380Sjfb8856606 	/* do the transpose for the internal EM keys */
1842*2d9fd380Sjfb8856606 	if (tbl->resource_func == BNXT_ULP_RESOURCE_FUNC_INT_EM_TABLE)
1843*2d9fd380Sjfb8856606 		ulp_blob_perform_byte_reverse(&key);
1844*2d9fd380Sjfb8856606 
1845*2d9fd380Sjfb8856606 	rc = bnxt_ulp_cntxt_tbl_scope_id_get(parms->ulp_ctx,
1846*2d9fd380Sjfb8856606 					     &iparms.tbl_scope_id);
1847*2d9fd380Sjfb8856606 	if (rc) {
1848*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get table scope rc=%d\n", rc);
1849*2d9fd380Sjfb8856606 		return rc;
1850*2d9fd380Sjfb8856606 	}
1851*2d9fd380Sjfb8856606 
1852*2d9fd380Sjfb8856606 	/*
1853*2d9fd380Sjfb8856606 	 * NOTE: the actual blob size will differ from the size in the tbl
1854*2d9fd380Sjfb8856606 	 * entry due to the padding.
1855*2d9fd380Sjfb8856606 	 */
1856*2d9fd380Sjfb8856606 	iparms.dup_check		= 0;
1857*2d9fd380Sjfb8856606 	iparms.dir			= tbl->direction;
1858*2d9fd380Sjfb8856606 	iparms.mem			= tbl->resource_type;
1859*2d9fd380Sjfb8856606 	iparms.key			= ulp_blob_data_get(&key, &tmplen);
1860*2d9fd380Sjfb8856606 	iparms.key_sz_in_bits		= tbl->key_bit_size;
1861*2d9fd380Sjfb8856606 	iparms.em_record		= ulp_blob_data_get(&data, &tmplen);
1862*2d9fd380Sjfb8856606 	iparms.em_record_sz_in_bits	= tbl->result_bit_size;
1863*2d9fd380Sjfb8856606 
1864*2d9fd380Sjfb8856606 	rc = tf_insert_em_entry(tfp, &iparms);
1865*2d9fd380Sjfb8856606 	if (rc) {
1866*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to insert em entry rc=%d.\n", rc);
1867*2d9fd380Sjfb8856606 		return rc;
1868*2d9fd380Sjfb8856606 	}
1869*2d9fd380Sjfb8856606 
1870*2d9fd380Sjfb8856606 	/* Mark action process */
1871*2d9fd380Sjfb8856606 	if (mtype == BNXT_ULP_FLOW_MEM_TYPE_EXT &&
1872*2d9fd380Sjfb8856606 	    tbl->resource_type == TF_MEM_EXTERNAL)
1873*2d9fd380Sjfb8856606 		rc = ulp_mapper_mark_gfid_process(parms, tbl, iparms.flow_id);
1874*2d9fd380Sjfb8856606 	else if (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT &&
1875*2d9fd380Sjfb8856606 		 tbl->resource_type == TF_MEM_INTERNAL)
1876*2d9fd380Sjfb8856606 		rc = ulp_mapper_mark_act_ptr_process(parms, tbl);
1877*2d9fd380Sjfb8856606 	if (rc) {
1878*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to add mark to flow\n");
1879*2d9fd380Sjfb8856606 		goto error;
1880*2d9fd380Sjfb8856606 	}
1881*2d9fd380Sjfb8856606 
1882*2d9fd380Sjfb8856606 	/* Link the EM resource to the flow in the flow db */
1883*2d9fd380Sjfb8856606 	memset(&fid_parms, 0, sizeof(fid_parms));
1884*2d9fd380Sjfb8856606 	fid_parms.direction		= tbl->direction;
1885*2d9fd380Sjfb8856606 	fid_parms.resource_func		= tbl->resource_func;
1886*2d9fd380Sjfb8856606 	fid_parms.resource_type		= tbl->resource_type;
1887*2d9fd380Sjfb8856606 	fid_parms.critical_resource	= tbl->critical_resource;
1888*2d9fd380Sjfb8856606 	fid_parms.resource_hndl		= iparms.flow_handle;
1889*2d9fd380Sjfb8856606 
1890*2d9fd380Sjfb8856606 	rc = ulp_flow_db_resource_add(parms->ulp_ctx,
1891*2d9fd380Sjfb8856606 				      parms->flow_type,
1892*2d9fd380Sjfb8856606 				      parms->fid,
1893*2d9fd380Sjfb8856606 				      &fid_parms);
1894*2d9fd380Sjfb8856606 	if (rc) {
1895*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Fail to link res to flow rc = %d\n",
1896*2d9fd380Sjfb8856606 			    rc);
1897*2d9fd380Sjfb8856606 		/* Need to free the identifier, so goto error */
1898*2d9fd380Sjfb8856606 		goto error;
1899*2d9fd380Sjfb8856606 	}
1900*2d9fd380Sjfb8856606 
1901*2d9fd380Sjfb8856606 	return 0;
1902*2d9fd380Sjfb8856606 error:
1903*2d9fd380Sjfb8856606 	free_parms.dir		= iparms.dir;
1904*2d9fd380Sjfb8856606 	free_parms.mem		= iparms.mem;
1905*2d9fd380Sjfb8856606 	free_parms.tbl_scope_id	= iparms.tbl_scope_id;
1906*2d9fd380Sjfb8856606 	free_parms.flow_handle	= iparms.flow_handle;
1907*2d9fd380Sjfb8856606 
1908*2d9fd380Sjfb8856606 	trc = tf_delete_em_entry(tfp, &free_parms);
1909*2d9fd380Sjfb8856606 	if (trc)
1910*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to delete EM entry on failed add\n");
1911*2d9fd380Sjfb8856606 
1912*2d9fd380Sjfb8856606 	return rc;
1913*2d9fd380Sjfb8856606 }
1914*2d9fd380Sjfb8856606 
1915*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_index_tbl_process(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl)1916*2d9fd380Sjfb8856606 ulp_mapper_index_tbl_process(struct bnxt_ulp_mapper_parms *parms,
1917*2d9fd380Sjfb8856606 			     struct bnxt_ulp_mapper_tbl_info *tbl)
1918*2d9fd380Sjfb8856606 {
1919*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_result_field_info *flds;
1920*2d9fd380Sjfb8856606 	struct ulp_flow_db_res_params	fid_parms;
1921*2d9fd380Sjfb8856606 	struct ulp_blob	data;
1922*2d9fd380Sjfb8856606 	uint64_t idx = 0;
1923*2d9fd380Sjfb8856606 	uint16_t tmplen;
1924*2d9fd380Sjfb8856606 	uint32_t i, num_flds, index, hit;
1925*2d9fd380Sjfb8856606 	int32_t rc = 0, trc = 0;
1926*2d9fd380Sjfb8856606 	struct tf_alloc_tbl_entry_parms	aparms = { 0 };
1927*2d9fd380Sjfb8856606 	struct tf_search_tbl_entry_parms srchparms = { 0 };
1928*2d9fd380Sjfb8856606 	struct tf_set_tbl_entry_parms	sparms = { 0 };
1929*2d9fd380Sjfb8856606 	struct tf_free_tbl_entry_parms	free_parms = { 0 };
1930*2d9fd380Sjfb8856606 	uint32_t tbl_scope_id;
1931*2d9fd380Sjfb8856606 	struct tf *tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
1932*2d9fd380Sjfb8856606 	uint16_t bit_size;
1933*2d9fd380Sjfb8856606 	uint32_t encap_flds = 0;
1934*2d9fd380Sjfb8856606 
1935*2d9fd380Sjfb8856606 	/* Get the scope id first */
1936*2d9fd380Sjfb8856606 	rc = bnxt_ulp_cntxt_tbl_scope_id_get(parms->ulp_ctx, &tbl_scope_id);
1937*2d9fd380Sjfb8856606 	if (rc) {
1938*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get table scope rc=%d\n", rc);
1939*2d9fd380Sjfb8856606 		return rc;
1940*2d9fd380Sjfb8856606 	}
1941*2d9fd380Sjfb8856606 
1942*2d9fd380Sjfb8856606 	/* use the max size if encap is enabled */
1943*2d9fd380Sjfb8856606 	if (tbl->encap_num_fields)
1944*2d9fd380Sjfb8856606 		bit_size = BNXT_ULP_FLMP_BLOB_SIZE_IN_BITS;
1945*2d9fd380Sjfb8856606 	else
1946*2d9fd380Sjfb8856606 		bit_size = tbl->result_bit_size;
1947*2d9fd380Sjfb8856606 
1948*2d9fd380Sjfb8856606 	/* Initialize the blob data */
1949*2d9fd380Sjfb8856606 	if (!ulp_blob_init(&data, bit_size,
1950*2d9fd380Sjfb8856606 			   parms->device_params->byte_order)) {
1951*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed initial index table blob\n");
1952*2d9fd380Sjfb8856606 		return -EINVAL;
1953*2d9fd380Sjfb8856606 	}
1954*2d9fd380Sjfb8856606 
1955*2d9fd380Sjfb8856606 	/* Get the result fields list */
1956*2d9fd380Sjfb8856606 	flds = ulp_mapper_result_fields_get(parms, tbl, &num_flds, &encap_flds);
1957*2d9fd380Sjfb8856606 
1958*2d9fd380Sjfb8856606 	if (!flds || (!num_flds && !encap_flds)) {
1959*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "template undefined for the index table\n");
1960*2d9fd380Sjfb8856606 		return -EINVAL;
1961*2d9fd380Sjfb8856606 	}
1962*2d9fd380Sjfb8856606 
1963*2d9fd380Sjfb8856606 	/* process the result fields, loop through them */
1964*2d9fd380Sjfb8856606 	for (i = 0; i < (num_flds + encap_flds); i++) {
1965*2d9fd380Sjfb8856606 		/* set the swap index if encap swap bit is enabled */
1966*2d9fd380Sjfb8856606 		if (parms->device_params->encap_byte_swap && encap_flds &&
1967*2d9fd380Sjfb8856606 		    (i == num_flds))
1968*2d9fd380Sjfb8856606 			ulp_blob_encap_swap_idx_set(&data);
1969*2d9fd380Sjfb8856606 
1970*2d9fd380Sjfb8856606 		/* Process the result fields */
1971*2d9fd380Sjfb8856606 		rc = ulp_mapper_result_field_process(parms,
1972*2d9fd380Sjfb8856606 						     tbl->direction,
1973*2d9fd380Sjfb8856606 						     &flds[i],
1974*2d9fd380Sjfb8856606 						     &data,
1975*2d9fd380Sjfb8856606 						     "Indexed Result");
1976*2d9fd380Sjfb8856606 		if (rc) {
1977*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "data field failed\n");
1978*2d9fd380Sjfb8856606 			return rc;
1979*2d9fd380Sjfb8856606 		}
1980*2d9fd380Sjfb8856606 	}
1981*2d9fd380Sjfb8856606 
1982*2d9fd380Sjfb8856606 	/* if encap bit swap is enabled perform the bit swap */
1983*2d9fd380Sjfb8856606 	if (parms->device_params->encap_byte_swap && encap_flds) {
1984*2d9fd380Sjfb8856606 		ulp_blob_perform_encap_swap(&data);
1985*2d9fd380Sjfb8856606 	}
1986*2d9fd380Sjfb8856606 
1987*2d9fd380Sjfb8856606 	/*
1988*2d9fd380Sjfb8856606 	 * Check for index opcode, if it is Global then
1989*2d9fd380Sjfb8856606 	 * no need to allocate the table, just set the table
1990*2d9fd380Sjfb8856606 	 * and exit since it is not maintained in the flow db.
1991*2d9fd380Sjfb8856606 	 */
1992*2d9fd380Sjfb8856606 	if (tbl->index_opcode == BNXT_ULP_INDEX_OPCODE_GLOBAL) {
1993*2d9fd380Sjfb8856606 		/* get the index from index operand */
1994*2d9fd380Sjfb8856606 		if (tbl->index_operand < BNXT_ULP_GLB_REGFILE_INDEX_LAST &&
1995*2d9fd380Sjfb8856606 		    ulp_mapper_glb_resource_read(parms->mapper_data,
1996*2d9fd380Sjfb8856606 						 tbl->direction,
1997*2d9fd380Sjfb8856606 						 tbl->index_operand,
1998*2d9fd380Sjfb8856606 						 &idx)) {
1999*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Glbl regfile[%d] read failed.\n",
2000*2d9fd380Sjfb8856606 				    tbl->index_operand);
2001*2d9fd380Sjfb8856606 			return -EINVAL;
2002*2d9fd380Sjfb8856606 		}
2003*2d9fd380Sjfb8856606 		/* set the Tf index table */
2004*2d9fd380Sjfb8856606 		sparms.dir		= tbl->direction;
2005*2d9fd380Sjfb8856606 		sparms.type		= tbl->resource_type;
2006*2d9fd380Sjfb8856606 		sparms.data		= ulp_blob_data_get(&data, &tmplen);
2007*2d9fd380Sjfb8856606 		sparms.data_sz_in_bytes = ULP_BITS_2_BYTE(tmplen);
2008*2d9fd380Sjfb8856606 		sparms.idx		= tfp_be_to_cpu_64(idx);
2009*2d9fd380Sjfb8856606 		sparms.tbl_scope_id	= tbl_scope_id;
2010*2d9fd380Sjfb8856606 
2011*2d9fd380Sjfb8856606 		rc = tf_set_tbl_entry(tfp, &sparms);
2012*2d9fd380Sjfb8856606 		if (rc) {
2013*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR,
2014*2d9fd380Sjfb8856606 				    "Glbl Set table[%d][%s][%d] failed rc=%d\n",
2015*2d9fd380Sjfb8856606 				    sparms.type,
2016*2d9fd380Sjfb8856606 				    (sparms.dir == TF_DIR_RX) ? "RX" : "TX",
2017*2d9fd380Sjfb8856606 				    sparms.idx,
2018*2d9fd380Sjfb8856606 				    rc);
2019*2d9fd380Sjfb8856606 			return rc;
2020*2d9fd380Sjfb8856606 		}
2021*2d9fd380Sjfb8856606 		return 0; /* success */
2022*2d9fd380Sjfb8856606 	}
2023*2d9fd380Sjfb8856606 
2024*2d9fd380Sjfb8856606 	index = 0;
2025*2d9fd380Sjfb8856606 	hit = 0;
2026*2d9fd380Sjfb8856606 	/* Perform the tf table allocation by filling the alloc params */
2027*2d9fd380Sjfb8856606 	if (tbl->srch_b4_alloc) {
2028*2d9fd380Sjfb8856606 		memset(&srchparms, 0, sizeof(srchparms));
2029*2d9fd380Sjfb8856606 		srchparms.dir = tbl->direction;
2030*2d9fd380Sjfb8856606 		srchparms.type = tbl->resource_type;
2031*2d9fd380Sjfb8856606 		srchparms.alloc	= 1;
2032*2d9fd380Sjfb8856606 		srchparms.result = ulp_blob_data_get(&data, &tmplen);
2033*2d9fd380Sjfb8856606 		srchparms.result_sz_in_bytes = ULP_BITS_2_BYTE(tmplen);
2034*2d9fd380Sjfb8856606 		srchparms.tbl_scope_id = tbl_scope_id;
2035*2d9fd380Sjfb8856606 		rc = tf_search_tbl_entry(tfp, &srchparms);
2036*2d9fd380Sjfb8856606 		if (rc) {
2037*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Alloc table[%s][%s] failed rc=%d\n",
2038*2d9fd380Sjfb8856606 				    tf_tbl_type_2_str(tbl->resource_type),
2039*2d9fd380Sjfb8856606 				    tf_dir_2_str(tbl->direction), rc);
2040*2d9fd380Sjfb8856606 			return rc;
2041*2d9fd380Sjfb8856606 		}
2042*2d9fd380Sjfb8856606 		if (srchparms.search_status == REJECT) {
2043*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Alloc table[%s][%s] rejected.\n",
2044*2d9fd380Sjfb8856606 				    tf_tbl_type_2_str(tbl->resource_type),
2045*2d9fd380Sjfb8856606 				    tf_dir_2_str(tbl->direction));
2046*2d9fd380Sjfb8856606 			return -ENOMEM;
2047*2d9fd380Sjfb8856606 		}
2048*2d9fd380Sjfb8856606 		index = srchparms.idx;
2049*2d9fd380Sjfb8856606 		hit = srchparms.hit;
2050*2d9fd380Sjfb8856606 	} else {
2051*2d9fd380Sjfb8856606 		aparms.dir		= tbl->direction;
2052*2d9fd380Sjfb8856606 		aparms.type		= tbl->resource_type;
2053*2d9fd380Sjfb8856606 		aparms.search_enable	= tbl->srch_b4_alloc;
2054*2d9fd380Sjfb8856606 		aparms.result		= ulp_blob_data_get(&data, &tmplen);
2055*2d9fd380Sjfb8856606 		aparms.result_sz_in_bytes = ULP_BITS_2_BYTE(tmplen);
2056*2d9fd380Sjfb8856606 		aparms.tbl_scope_id	= tbl_scope_id;
2057*2d9fd380Sjfb8856606 
2058*2d9fd380Sjfb8856606 		/* All failures after the alloc succeeds require a free */
2059*2d9fd380Sjfb8856606 		rc = tf_alloc_tbl_entry(tfp, &aparms);
2060*2d9fd380Sjfb8856606 		if (rc) {
2061*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Alloc table[%s][%s] failed rc=%d\n",
2062*2d9fd380Sjfb8856606 				    tf_tbl_type_2_str(tbl->resource_type),
2063*2d9fd380Sjfb8856606 				    tf_dir_2_str(tbl->direction), rc);
2064*2d9fd380Sjfb8856606 			return rc;
2065*2d9fd380Sjfb8856606 		}
2066*2d9fd380Sjfb8856606 		index = aparms.idx;
2067*2d9fd380Sjfb8856606 	}
2068*2d9fd380Sjfb8856606 	/*
2069*2d9fd380Sjfb8856606 	 * calculate the idx for the result record, for external EM the offset
2070*2d9fd380Sjfb8856606 	 * needs to be shifted accordingly. If external non-inline table types
2071*2d9fd380Sjfb8856606 	 * are used then need to revisit this logic.
2072*2d9fd380Sjfb8856606 	 */
2073*2d9fd380Sjfb8856606 	if (tbl->resource_type == TF_TBL_TYPE_EXT)
2074*2d9fd380Sjfb8856606 		idx = TF_ACT_REC_OFFSET_2_PTR(index);
2075*2d9fd380Sjfb8856606 	else
2076*2d9fd380Sjfb8856606 		idx = index;
2077*2d9fd380Sjfb8856606 
2078*2d9fd380Sjfb8856606 	/* Always storing values in Regfile in BE */
2079*2d9fd380Sjfb8856606 	idx = tfp_cpu_to_be_64(idx);
2080*2d9fd380Sjfb8856606 	if (tbl->index_opcode == BNXT_ULP_INDEX_OPCODE_ALLOCATE) {
2081*2d9fd380Sjfb8856606 		rc = ulp_regfile_write(parms->regfile, tbl->index_operand, idx);
2082*2d9fd380Sjfb8856606 		if (!rc) {
2083*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Write regfile[%d] failed\n",
2084*2d9fd380Sjfb8856606 				    tbl->index_operand);
2085*2d9fd380Sjfb8856606 			goto error;
2086*2d9fd380Sjfb8856606 		}
2087*2d9fd380Sjfb8856606 	}
2088*2d9fd380Sjfb8856606 
2089*2d9fd380Sjfb8856606 	/* Perform the tf table set by filling the set params */
2090*2d9fd380Sjfb8856606 	if (!tbl->srch_b4_alloc || !hit) {
2091*2d9fd380Sjfb8856606 		sparms.dir		= tbl->direction;
2092*2d9fd380Sjfb8856606 		sparms.type		= tbl->resource_type;
2093*2d9fd380Sjfb8856606 		sparms.data		= ulp_blob_data_get(&data, &tmplen);
2094*2d9fd380Sjfb8856606 		sparms.data_sz_in_bytes = ULP_BITS_2_BYTE(tmplen);
2095*2d9fd380Sjfb8856606 		sparms.idx		= index;
2096*2d9fd380Sjfb8856606 		sparms.tbl_scope_id	= tbl_scope_id;
2097*2d9fd380Sjfb8856606 
2098*2d9fd380Sjfb8856606 		rc = tf_set_tbl_entry(tfp, &sparms);
2099*2d9fd380Sjfb8856606 		if (rc) {
2100*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Set table[%d][%s][%d] failed rc=%d\n",
2101*2d9fd380Sjfb8856606 				    sparms.type,
2102*2d9fd380Sjfb8856606 				    (sparms.dir == TF_DIR_RX) ? "RX" : "TX",
2103*2d9fd380Sjfb8856606 				    sparms.idx,
2104*2d9fd380Sjfb8856606 				    rc);
2105*2d9fd380Sjfb8856606 			goto error;
2106*2d9fd380Sjfb8856606 		}
2107*2d9fd380Sjfb8856606 	}
2108*2d9fd380Sjfb8856606 
2109*2d9fd380Sjfb8856606 	/* Link the resource to the flow in the flow db */
2110*2d9fd380Sjfb8856606 	memset(&fid_parms, 0, sizeof(fid_parms));
2111*2d9fd380Sjfb8856606 	fid_parms.direction	= tbl->direction;
2112*2d9fd380Sjfb8856606 	fid_parms.resource_func	= tbl->resource_func;
2113*2d9fd380Sjfb8856606 	fid_parms.resource_type	= tbl->resource_type;
2114*2d9fd380Sjfb8856606 	fid_parms.resource_sub_type = tbl->resource_sub_type;
2115*2d9fd380Sjfb8856606 	fid_parms.resource_hndl	= index;
2116*2d9fd380Sjfb8856606 	fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
2117*2d9fd380Sjfb8856606 
2118*2d9fd380Sjfb8856606 	rc = ulp_flow_db_resource_add(parms->ulp_ctx,
2119*2d9fd380Sjfb8856606 				      parms->flow_type,
2120*2d9fd380Sjfb8856606 				      parms->fid,
2121*2d9fd380Sjfb8856606 				      &fid_parms);
2122*2d9fd380Sjfb8856606 	if (rc) {
2123*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to link resource to flow rc = %d\n",
2124*2d9fd380Sjfb8856606 			    rc);
2125*2d9fd380Sjfb8856606 		goto error;
2126*2d9fd380Sjfb8856606 	}
2127*2d9fd380Sjfb8856606 
2128*2d9fd380Sjfb8856606 	/* Perform the VF rep action */
2129*2d9fd380Sjfb8856606 	rc = ulp_mapper_mark_vfr_idx_process(parms, tbl);
2130*2d9fd380Sjfb8856606 	if (rc) {
2131*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to add vfr mark rc = %d\n", rc);
2132*2d9fd380Sjfb8856606 		goto error;
2133*2d9fd380Sjfb8856606 	}
2134*2d9fd380Sjfb8856606 	return rc;
2135*2d9fd380Sjfb8856606 error:
2136*2d9fd380Sjfb8856606 	/*
2137*2d9fd380Sjfb8856606 	 * Free the allocated resource since we failed to either
2138*2d9fd380Sjfb8856606 	 * write to the entry or link the flow
2139*2d9fd380Sjfb8856606 	 */
2140*2d9fd380Sjfb8856606 	free_parms.dir	= tbl->direction;
2141*2d9fd380Sjfb8856606 	free_parms.type	= tbl->resource_type;
2142*2d9fd380Sjfb8856606 	free_parms.idx	= index;
2143*2d9fd380Sjfb8856606 	free_parms.tbl_scope_id = tbl_scope_id;
2144*2d9fd380Sjfb8856606 
2145*2d9fd380Sjfb8856606 	trc = tf_free_tbl_entry(tfp, &free_parms);
2146*2d9fd380Sjfb8856606 	if (trc)
2147*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to free tbl entry on failure\n");
2148*2d9fd380Sjfb8856606 
2149*2d9fd380Sjfb8856606 	return rc;
2150*2d9fd380Sjfb8856606 }
2151*2d9fd380Sjfb8856606 
2152*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_cache_tbl_process(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl)2153*2d9fd380Sjfb8856606 ulp_mapper_cache_tbl_process(struct bnxt_ulp_mapper_parms *parms,
2154*2d9fd380Sjfb8856606 			     struct bnxt_ulp_mapper_tbl_info *tbl)
2155*2d9fd380Sjfb8856606 {
2156*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_key_field_info *kflds;
2157*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_cache_entry *cache_entry;
2158*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_ident_info *idents;
2159*2d9fd380Sjfb8856606 	uint32_t i, num_kflds = 0, num_idents = 0;
2160*2d9fd380Sjfb8856606 	struct ulp_flow_db_res_params fid_parms;
2161*2d9fd380Sjfb8856606 	struct tf_free_identifier_parms fparms;
2162*2d9fd380Sjfb8856606 	uint16_t tmplen, tmp_ident;
2163*2d9fd380Sjfb8856606 	struct ulp_blob key;
2164*2d9fd380Sjfb8856606 	uint8_t *cache_key;
2165*2d9fd380Sjfb8856606 	uint64_t regval;
2166*2d9fd380Sjfb8856606 	uint16_t *ckey;
2167*2d9fd380Sjfb8856606 	int32_t rc;
2168*2d9fd380Sjfb8856606 
2169*2d9fd380Sjfb8856606 	/* Get the key fields list and build the key. */
2170*2d9fd380Sjfb8856606 	kflds = ulp_mapper_key_fields_get(parms, tbl, &num_kflds);
2171*2d9fd380Sjfb8856606 	if (!kflds || !num_kflds) {
2172*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get key fields\n");
2173*2d9fd380Sjfb8856606 		return -EINVAL;
2174*2d9fd380Sjfb8856606 	}
2175*2d9fd380Sjfb8856606 	if (!ulp_blob_init(&key, tbl->key_bit_size,
2176*2d9fd380Sjfb8856606 			   parms->device_params->byte_order)) {
2177*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to alloc blob\n");
2178*2d9fd380Sjfb8856606 		return -EINVAL;
2179*2d9fd380Sjfb8856606 	}
2180*2d9fd380Sjfb8856606 	for (i = 0; i < num_kflds; i++) {
2181*2d9fd380Sjfb8856606 		/* Setup the key */
2182*2d9fd380Sjfb8856606 		rc = ulp_mapper_keymask_field_process(parms, tbl->direction,
2183*2d9fd380Sjfb8856606 						      &kflds[i],
2184*2d9fd380Sjfb8856606 						      &key, 1, "Cache Key");
2185*2d9fd380Sjfb8856606 		if (rc) {
2186*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR,
2187*2d9fd380Sjfb8856606 				    "Failed to create key for Cache rc=%d\n",
2188*2d9fd380Sjfb8856606 				    rc);
2189*2d9fd380Sjfb8856606 			return -EINVAL;
2190*2d9fd380Sjfb8856606 		}
2191*2d9fd380Sjfb8856606 	}
2192*2d9fd380Sjfb8856606 
2193*2d9fd380Sjfb8856606 	/*
2194*2d9fd380Sjfb8856606 	 * Perform the lookup in the cache table with constructed key.  The
2195*2d9fd380Sjfb8856606 	 * cache_key is a byte array of tmplen, it needs to be converted to a
2196*2d9fd380Sjfb8856606 	 * index for the cache table.
2197*2d9fd380Sjfb8856606 	 */
2198*2d9fd380Sjfb8856606 	cache_key = ulp_blob_data_get(&key, &tmplen);
2199*2d9fd380Sjfb8856606 	ckey = (uint16_t *)cache_key;
2200*2d9fd380Sjfb8856606 
2201*2d9fd380Sjfb8856606 	/*
2202*2d9fd380Sjfb8856606 	 * The id computed based on resource sub type and direction where
2203*2d9fd380Sjfb8856606 	 * dir is the bit0 and rest of the bits come from resource
2204*2d9fd380Sjfb8856606 	 * sub type.
2205*2d9fd380Sjfb8856606 	 */
2206*2d9fd380Sjfb8856606 	cache_entry = ulp_mapper_cache_entry_get(parms->ulp_ctx,
2207*2d9fd380Sjfb8856606 						 (tbl->resource_sub_type << 1 |
2208*2d9fd380Sjfb8856606 						 (tbl->direction & 0x1)),
2209*2d9fd380Sjfb8856606 						 *ckey);
2210*2d9fd380Sjfb8856606 
2211*2d9fd380Sjfb8856606 	/*
2212*2d9fd380Sjfb8856606 	 * Get the identifier list for processing by both the hit and miss
2213*2d9fd380Sjfb8856606 	 * processing.
2214*2d9fd380Sjfb8856606 	 */
2215*2d9fd380Sjfb8856606 	idents = ulp_mapper_ident_fields_get(parms, tbl, &num_idents);
2216*2d9fd380Sjfb8856606 
2217*2d9fd380Sjfb8856606 	if (!cache_entry->ref_count) {
2218*2d9fd380Sjfb8856606 		/* Initialize the cache entry */
2219*2d9fd380Sjfb8856606 		cache_entry->tcam_idx = 0;
2220*2d9fd380Sjfb8856606 		cache_entry->ref_count = 0;
2221*2d9fd380Sjfb8856606 		for (i = 0; i < BNXT_ULP_CACHE_TBL_IDENT_MAX_NUM; i++)
2222*2d9fd380Sjfb8856606 			cache_entry->idents[i] = ULP_IDENTS_INVALID;
2223*2d9fd380Sjfb8856606 
2224*2d9fd380Sjfb8856606 		/* Need to allocate identifiers for storing in the cache. */
2225*2d9fd380Sjfb8856606 		for (i = 0; i < num_idents; i++) {
2226*2d9fd380Sjfb8856606 			/*
2227*2d9fd380Sjfb8856606 			 * Since we are using the cache, the identifier does not
2228*2d9fd380Sjfb8856606 			 * get added to the flow db.  Pass in the pointer to the
2229*2d9fd380Sjfb8856606 			 * tmp_ident.
2230*2d9fd380Sjfb8856606 			 */
2231*2d9fd380Sjfb8856606 			rc = ulp_mapper_ident_process(parms, tbl,
2232*2d9fd380Sjfb8856606 						      &idents[i], &tmp_ident);
2233*2d9fd380Sjfb8856606 			if (rc)
2234*2d9fd380Sjfb8856606 				goto error;
2235*2d9fd380Sjfb8856606 
2236*2d9fd380Sjfb8856606 			cache_entry->ident_types[i] = idents[i].ident_type;
2237*2d9fd380Sjfb8856606 			cache_entry->idents[i] = tmp_ident;
2238*2d9fd380Sjfb8856606 		}
2239*2d9fd380Sjfb8856606 
2240*2d9fd380Sjfb8856606 		/* Tell the TCAM processor to alloc an entry */
2241*2d9fd380Sjfb8856606 		parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_ALLOC;
2242*2d9fd380Sjfb8856606 		/* Store the cache key for use by the tcam process code */
2243*2d9fd380Sjfb8856606 		parms->cache_ptr = cache_entry;
2244*2d9fd380Sjfb8856606 	} else {
2245*2d9fd380Sjfb8856606 		/* Cache hit, get values from result. */
2246*2d9fd380Sjfb8856606 		for (i = 0; i < num_idents; i++) {
2247*2d9fd380Sjfb8856606 			regval = (uint64_t)cache_entry->idents[i];
2248*2d9fd380Sjfb8856606 			if (!ulp_regfile_write(parms->regfile,
2249*2d9fd380Sjfb8856606 					       idents[i].regfile_idx,
2250*2d9fd380Sjfb8856606 					       tfp_cpu_to_be_64(regval))) {
2251*2d9fd380Sjfb8856606 				BNXT_TF_DBG(ERR,
2252*2d9fd380Sjfb8856606 					    "Failed to write to regfile\n");
2253*2d9fd380Sjfb8856606 				return -EINVAL;
2254*2d9fd380Sjfb8856606 			}
2255*2d9fd380Sjfb8856606 		}
2256*2d9fd380Sjfb8856606 		/*
2257*2d9fd380Sjfb8856606 		 * The cached entry is being used, so let the tcam processing
2258*2d9fd380Sjfb8856606 		 * know not to process this table.
2259*2d9fd380Sjfb8856606 		 */
2260*2d9fd380Sjfb8856606 		parms->tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_CACHE_SKIP;
2261*2d9fd380Sjfb8856606 	}
2262*2d9fd380Sjfb8856606 
2263*2d9fd380Sjfb8856606 	/* Made through the cache processing, increment the reference count. */
2264*2d9fd380Sjfb8856606 	cache_entry->ref_count++;
2265*2d9fd380Sjfb8856606 
2266*2d9fd380Sjfb8856606 	/* Link the cache to the flow db. */
2267*2d9fd380Sjfb8856606 	memset(&fid_parms, 0, sizeof(fid_parms));
2268*2d9fd380Sjfb8856606 	fid_parms.direction = tbl->direction;
2269*2d9fd380Sjfb8856606 	fid_parms.resource_func	= tbl->resource_func;
2270*2d9fd380Sjfb8856606 
2271*2d9fd380Sjfb8856606 	/*
2272*2d9fd380Sjfb8856606 	 * Cache resource type is composed of table_type, resource
2273*2d9fd380Sjfb8856606 	 * sub type and direction, it needs to set appropriately via setter.
2274*2d9fd380Sjfb8856606 	 */
2275*2d9fd380Sjfb8856606 	ulp_mapper_cache_res_type_set(&fid_parms,
2276*2d9fd380Sjfb8856606 				      tbl->resource_type,
2277*2d9fd380Sjfb8856606 				      (tbl->resource_sub_type << 1 |
2278*2d9fd380Sjfb8856606 				       (tbl->direction & 0x1)));
2279*2d9fd380Sjfb8856606 	fid_parms.resource_hndl	= (uint64_t)*ckey;
2280*2d9fd380Sjfb8856606 	fid_parms.critical_resource = tbl->critical_resource;
2281*2d9fd380Sjfb8856606 	rc = ulp_flow_db_resource_add(parms->ulp_ctx,
2282*2d9fd380Sjfb8856606 				      parms->flow_type,
2283*2d9fd380Sjfb8856606 				      parms->fid,
2284*2d9fd380Sjfb8856606 				      &fid_parms);
2285*2d9fd380Sjfb8856606 	if (rc)
2286*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to add cache to flow db.\n");
2287*2d9fd380Sjfb8856606 
2288*2d9fd380Sjfb8856606 	return rc;
2289*2d9fd380Sjfb8856606 error:
2290*2d9fd380Sjfb8856606 	/*
2291*2d9fd380Sjfb8856606 	 * This error handling only gets called when the idents are being
2292*2d9fd380Sjfb8856606 	 * allocated for the cache on misses.  Using the num_idents that was
2293*2d9fd380Sjfb8856606 	 * previously set.
2294*2d9fd380Sjfb8856606 	 */
2295*2d9fd380Sjfb8856606 	for (i = 0; i < num_idents; i++) {
2296*2d9fd380Sjfb8856606 		if (cache_entry->idents[i] == ULP_IDENTS_INVALID)
2297*2d9fd380Sjfb8856606 			continue;
2298*2d9fd380Sjfb8856606 
2299*2d9fd380Sjfb8856606 		fparms.dir = tbl->direction;
2300*2d9fd380Sjfb8856606 		fparms.ident_type = idents[i].ident_type;
2301*2d9fd380Sjfb8856606 		fparms.id = cache_entry->idents[i];
2302*2d9fd380Sjfb8856606 		tf_free_identifier(parms->tfp, &fparms);
2303*2d9fd380Sjfb8856606 	}
2304*2d9fd380Sjfb8856606 
2305*2d9fd380Sjfb8856606 	return rc;
2306*2d9fd380Sjfb8856606 }
2307*2d9fd380Sjfb8856606 
2308*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_if_tbl_process(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl)2309*2d9fd380Sjfb8856606 ulp_mapper_if_tbl_process(struct bnxt_ulp_mapper_parms *parms,
2310*2d9fd380Sjfb8856606 			  struct bnxt_ulp_mapper_tbl_info *tbl)
2311*2d9fd380Sjfb8856606 {
2312*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_result_field_info *flds;
2313*2d9fd380Sjfb8856606 	struct ulp_blob	data;
2314*2d9fd380Sjfb8856606 	uint64_t idx;
2315*2d9fd380Sjfb8856606 	uint16_t tmplen;
2316*2d9fd380Sjfb8856606 	uint32_t i, num_flds;
2317*2d9fd380Sjfb8856606 	int32_t rc = 0;
2318*2d9fd380Sjfb8856606 	struct tf_set_if_tbl_entry_parms iftbl_params = { 0 };
2319*2d9fd380Sjfb8856606 	struct tf *tfp = bnxt_ulp_cntxt_tfp_get(parms->ulp_ctx);
2320*2d9fd380Sjfb8856606 	uint32_t encap_flds;
2321*2d9fd380Sjfb8856606 
2322*2d9fd380Sjfb8856606 	/* Initialize the blob data */
2323*2d9fd380Sjfb8856606 	if (!ulp_blob_init(&data, tbl->result_bit_size,
2324*2d9fd380Sjfb8856606 			   parms->device_params->byte_order)) {
2325*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed initial index table blob\n");
2326*2d9fd380Sjfb8856606 		return -EINVAL;
2327*2d9fd380Sjfb8856606 	}
2328*2d9fd380Sjfb8856606 
2329*2d9fd380Sjfb8856606 	/* Get the result fields list */
2330*2d9fd380Sjfb8856606 	flds = ulp_mapper_result_fields_get(parms, tbl, &num_flds, &encap_flds);
2331*2d9fd380Sjfb8856606 
2332*2d9fd380Sjfb8856606 	if (!flds || !num_flds || encap_flds) {
2333*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "template undefined for the IF table\n");
2334*2d9fd380Sjfb8856606 		return -EINVAL;
2335*2d9fd380Sjfb8856606 	}
2336*2d9fd380Sjfb8856606 
2337*2d9fd380Sjfb8856606 	/* process the result fields, loop through them */
2338*2d9fd380Sjfb8856606 	for (i = 0; i < num_flds; i++) {
2339*2d9fd380Sjfb8856606 		/* Process the result fields */
2340*2d9fd380Sjfb8856606 		rc = ulp_mapper_result_field_process(parms,
2341*2d9fd380Sjfb8856606 						     tbl->direction,
2342*2d9fd380Sjfb8856606 						     &flds[i],
2343*2d9fd380Sjfb8856606 						     &data,
2344*2d9fd380Sjfb8856606 						     "IFtable Result");
2345*2d9fd380Sjfb8856606 		if (rc) {
2346*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "data field failed\n");
2347*2d9fd380Sjfb8856606 			return rc;
2348*2d9fd380Sjfb8856606 		}
2349*2d9fd380Sjfb8856606 	}
2350*2d9fd380Sjfb8856606 
2351*2d9fd380Sjfb8856606 	/* Get the index details from computed field */
2352*2d9fd380Sjfb8856606 	if (tbl->index_opcode == BNXT_ULP_INDEX_OPCODE_COMP_FIELD) {
2353*2d9fd380Sjfb8856606 		idx = ULP_COMP_FLD_IDX_RD(parms, tbl->index_operand);
2354*2d9fd380Sjfb8856606 	} else if (tbl->index_opcode == BNXT_ULP_INDEX_OPCODE_CONSTANT) {
2355*2d9fd380Sjfb8856606 		idx = tbl->index_operand;
2356*2d9fd380Sjfb8856606 	} else {
2357*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Invalid tbl index opcode\n");
2358*2d9fd380Sjfb8856606 		return -EINVAL;
2359*2d9fd380Sjfb8856606 	}
2360*2d9fd380Sjfb8856606 
2361*2d9fd380Sjfb8856606 	/* Perform the tf table set by filling the set params */
2362*2d9fd380Sjfb8856606 	iftbl_params.dir = tbl->direction;
2363*2d9fd380Sjfb8856606 	iftbl_params.type = tbl->resource_type;
2364*2d9fd380Sjfb8856606 	iftbl_params.data = ulp_blob_data_get(&data, &tmplen);
2365*2d9fd380Sjfb8856606 	iftbl_params.data_sz_in_bytes = ULP_BITS_2_BYTE(tmplen);
2366*2d9fd380Sjfb8856606 	iftbl_params.idx = idx;
2367*2d9fd380Sjfb8856606 
2368*2d9fd380Sjfb8856606 	rc = tf_set_if_tbl_entry(tfp, &iftbl_params);
2369*2d9fd380Sjfb8856606 	if (rc) {
2370*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Set table[%d][%s][%d] failed rc=%d\n",
2371*2d9fd380Sjfb8856606 			    iftbl_params.type,
2372*2d9fd380Sjfb8856606 			    (iftbl_params.dir == TF_DIR_RX) ? "RX" : "TX",
2373*2d9fd380Sjfb8856606 			    iftbl_params.idx,
2374*2d9fd380Sjfb8856606 			    rc);
2375*2d9fd380Sjfb8856606 		return rc;
2376*2d9fd380Sjfb8856606 	}
2377*2d9fd380Sjfb8856606 
2378*2d9fd380Sjfb8856606 	/*
2379*2d9fd380Sjfb8856606 	 * TBD: Need to look at the need to store idx in flow db for restore
2380*2d9fd380Sjfb8856606 	 * the table to its original state on deletion of this entry.
2381*2d9fd380Sjfb8856606 	 */
2382*2d9fd380Sjfb8856606 	return rc;
2383*2d9fd380Sjfb8856606 }
2384*2d9fd380Sjfb8856606 
2385*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_glb_resource_info_init(struct bnxt_ulp_context * ulp_ctx,struct bnxt_ulp_mapper_data * mapper_data)2386*2d9fd380Sjfb8856606 ulp_mapper_glb_resource_info_init(struct bnxt_ulp_context *ulp_ctx,
2387*2d9fd380Sjfb8856606 				  struct bnxt_ulp_mapper_data *mapper_data)
2388*2d9fd380Sjfb8856606 {
2389*2d9fd380Sjfb8856606 	struct bnxt_ulp_glb_resource_info *glb_res;
2390*2d9fd380Sjfb8856606 	uint32_t num_glb_res_ids, idx;
2391*2d9fd380Sjfb8856606 	int32_t rc = 0;
2392*2d9fd380Sjfb8856606 
2393*2d9fd380Sjfb8856606 	glb_res = ulp_mapper_glb_resource_info_list_get(&num_glb_res_ids);
2394*2d9fd380Sjfb8856606 	if (!glb_res || !num_glb_res_ids) {
2395*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Invalid Arguments\n");
2396*2d9fd380Sjfb8856606 		return -EINVAL;
2397*2d9fd380Sjfb8856606 	}
2398*2d9fd380Sjfb8856606 
2399*2d9fd380Sjfb8856606 	/* Iterate the global resources and process each one */
2400*2d9fd380Sjfb8856606 	for (idx = 0; idx < num_glb_res_ids; idx++) {
2401*2d9fd380Sjfb8856606 		switch (glb_res[idx].resource_func) {
2402*2d9fd380Sjfb8856606 		case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
2403*2d9fd380Sjfb8856606 			rc = ulp_mapper_resource_ident_allocate(ulp_ctx,
2404*2d9fd380Sjfb8856606 								mapper_data,
2405*2d9fd380Sjfb8856606 								&glb_res[idx]);
2406*2d9fd380Sjfb8856606 			break;
2407*2d9fd380Sjfb8856606 		case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
2408*2d9fd380Sjfb8856606 			rc = ulp_mapper_resource_index_tbl_alloc(ulp_ctx,
2409*2d9fd380Sjfb8856606 								 mapper_data,
2410*2d9fd380Sjfb8856606 								 &glb_res[idx]);
2411*2d9fd380Sjfb8856606 			break;
2412*2d9fd380Sjfb8856606 		default:
2413*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Global resource %x not supported\n",
2414*2d9fd380Sjfb8856606 				    glb_res[idx].resource_func);
2415*2d9fd380Sjfb8856606 			rc = -EINVAL;
2416*2d9fd380Sjfb8856606 			break;
2417*2d9fd380Sjfb8856606 		}
2418*2d9fd380Sjfb8856606 		if (rc)
2419*2d9fd380Sjfb8856606 			return rc;
2420*2d9fd380Sjfb8856606 	}
2421*2d9fd380Sjfb8856606 	return rc;
2422*2d9fd380Sjfb8856606 }
2423*2d9fd380Sjfb8856606 
2424*2d9fd380Sjfb8856606 /*
2425*2d9fd380Sjfb8856606  * Function to process the conditional opcode of the mapper table.
2426*2d9fd380Sjfb8856606  * returns 1 to skip the table.
2427*2d9fd380Sjfb8856606  * return 0 to continue processing the table.
2428*2d9fd380Sjfb8856606  *
2429*2d9fd380Sjfb8856606  * defaults to skip
2430*2d9fd380Sjfb8856606  */
2431*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_tbl_cond_opcode_process(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl)2432*2d9fd380Sjfb8856606 ulp_mapper_tbl_cond_opcode_process(struct bnxt_ulp_mapper_parms *parms,
2433*2d9fd380Sjfb8856606 				   struct bnxt_ulp_mapper_tbl_info *tbl)
2434*2d9fd380Sjfb8856606 {
2435*2d9fd380Sjfb8856606 	int32_t rc = 1;
2436*2d9fd380Sjfb8856606 
2437*2d9fd380Sjfb8856606 	switch (tbl->cond_opcode) {
2438*2d9fd380Sjfb8856606 	case BNXT_ULP_COND_OPCODE_NOP:
2439*2d9fd380Sjfb8856606 		rc = 0;
2440*2d9fd380Sjfb8856606 		break;
2441*2d9fd380Sjfb8856606 	case BNXT_ULP_COND_OPCODE_COMP_FIELD_IS_SET:
2442*2d9fd380Sjfb8856606 		if (tbl->cond_operand < BNXT_ULP_CF_IDX_LAST &&
2443*2d9fd380Sjfb8856606 		    ULP_COMP_FLD_IDX_RD(parms, tbl->cond_operand))
2444*2d9fd380Sjfb8856606 			rc = 0;
2445*2d9fd380Sjfb8856606 		break;
2446*2d9fd380Sjfb8856606 	case BNXT_ULP_COND_OPCODE_ACTION_BIT_IS_SET:
2447*2d9fd380Sjfb8856606 		if (ULP_BITMAP_ISSET(parms->act_bitmap->bits,
2448*2d9fd380Sjfb8856606 				     tbl->cond_operand))
2449*2d9fd380Sjfb8856606 			rc = 0;
2450*2d9fd380Sjfb8856606 		break;
2451*2d9fd380Sjfb8856606 	case BNXT_ULP_COND_OPCODE_HDR_BIT_IS_SET:
2452*2d9fd380Sjfb8856606 		if (ULP_BITMAP_ISSET(parms->hdr_bitmap->bits,
2453*2d9fd380Sjfb8856606 				     tbl->cond_operand))
2454*2d9fd380Sjfb8856606 			rc = 0;
2455*2d9fd380Sjfb8856606 		break;
2456*2d9fd380Sjfb8856606 	case BNXT_ULP_COND_OPCODE_COMP_FIELD_NOT_SET:
2457*2d9fd380Sjfb8856606 		if (tbl->cond_operand < BNXT_ULP_CF_IDX_LAST &&
2458*2d9fd380Sjfb8856606 		    !ULP_COMP_FLD_IDX_RD(parms, tbl->cond_operand))
2459*2d9fd380Sjfb8856606 			rc = 0;
2460*2d9fd380Sjfb8856606 		break;
2461*2d9fd380Sjfb8856606 	case BNXT_ULP_COND_OPCODE_ACTION_BIT_NOT_SET:
2462*2d9fd380Sjfb8856606 		if (!ULP_BITMAP_ISSET(parms->act_bitmap->bits,
2463*2d9fd380Sjfb8856606 				      tbl->cond_operand))
2464*2d9fd380Sjfb8856606 			rc = 0;
2465*2d9fd380Sjfb8856606 		break;
2466*2d9fd380Sjfb8856606 	case BNXT_ULP_COND_OPCODE_HDR_BIT_NOT_SET:
2467*2d9fd380Sjfb8856606 		if (!ULP_BITMAP_ISSET(parms->hdr_bitmap->bits,
2468*2d9fd380Sjfb8856606 				      tbl->cond_operand))
2469*2d9fd380Sjfb8856606 			rc = 0;
2470*2d9fd380Sjfb8856606 		break;
2471*2d9fd380Sjfb8856606 	default:
2472*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR,
2473*2d9fd380Sjfb8856606 			    "Invalid arg in mapper tbl for cond opcode\n");
2474*2d9fd380Sjfb8856606 		break;
2475*2d9fd380Sjfb8856606 	}
2476*2d9fd380Sjfb8856606 	return rc;
2477*2d9fd380Sjfb8856606 }
2478*2d9fd380Sjfb8856606 
2479*2d9fd380Sjfb8856606 /*
2480*2d9fd380Sjfb8856606  * Function to process the memtype opcode of the mapper table.
2481*2d9fd380Sjfb8856606  * returns 1 to skip the table.
2482*2d9fd380Sjfb8856606  * return 0 to continue processing the table.
2483*2d9fd380Sjfb8856606  *
2484*2d9fd380Sjfb8856606  * defaults to skip
2485*2d9fd380Sjfb8856606  */
2486*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_tbl_memtype_opcode_process(struct bnxt_ulp_mapper_parms * parms,struct bnxt_ulp_mapper_tbl_info * tbl)2487*2d9fd380Sjfb8856606 ulp_mapper_tbl_memtype_opcode_process(struct bnxt_ulp_mapper_parms *parms,
2488*2d9fd380Sjfb8856606 				      struct bnxt_ulp_mapper_tbl_info *tbl)
2489*2d9fd380Sjfb8856606 {
2490*2d9fd380Sjfb8856606 	enum bnxt_ulp_flow_mem_type mtype = BNXT_ULP_FLOW_MEM_TYPE_INT;
2491*2d9fd380Sjfb8856606 	int32_t rc = 1;
2492*2d9fd380Sjfb8856606 
2493*2d9fd380Sjfb8856606 	bnxt_ulp_cntxt_mem_type_get(parms->ulp_ctx, &mtype);
2494*2d9fd380Sjfb8856606 
2495*2d9fd380Sjfb8856606 	switch (tbl->mem_type_opcode) {
2496*2d9fd380Sjfb8856606 	case BNXT_ULP_MEM_TYPE_OPCODE_EXECUTE_IF_INT:
2497*2d9fd380Sjfb8856606 		if (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT)
2498*2d9fd380Sjfb8856606 			rc = 0;
2499*2d9fd380Sjfb8856606 		break;
2500*2d9fd380Sjfb8856606 	case BNXT_ULP_MEM_TYPE_OPCODE_EXECUTE_IF_EXT:
2501*2d9fd380Sjfb8856606 		if (mtype == BNXT_ULP_FLOW_MEM_TYPE_EXT)
2502*2d9fd380Sjfb8856606 			rc = 0;
2503*2d9fd380Sjfb8856606 		break;
2504*2d9fd380Sjfb8856606 	case BNXT_ULP_MEM_TYPE_OPCODE_NOP:
2505*2d9fd380Sjfb8856606 		rc = 0;
2506*2d9fd380Sjfb8856606 		break;
2507*2d9fd380Sjfb8856606 	default:
2508*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR,
2509*2d9fd380Sjfb8856606 			    "Invalid arg in mapper in memtype opcode\n");
2510*2d9fd380Sjfb8856606 		break;
2511*2d9fd380Sjfb8856606 	}
2512*2d9fd380Sjfb8856606 	return rc;
2513*2d9fd380Sjfb8856606 }
2514*2d9fd380Sjfb8856606 
2515*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_tbls_process(struct bnxt_ulp_mapper_parms * parms,uint32_t tid)2516*2d9fd380Sjfb8856606 ulp_mapper_tbls_process(struct bnxt_ulp_mapper_parms *parms, uint32_t tid)
2517*2d9fd380Sjfb8856606 {
2518*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_tbl_info *tbls;
2519*2d9fd380Sjfb8856606 	uint32_t num_tbls, i;
2520*2d9fd380Sjfb8856606 	int32_t rc = -EINVAL;
2521*2d9fd380Sjfb8856606 
2522*2d9fd380Sjfb8856606 	tbls = ulp_mapper_tbl_list_get(parms, tid, &num_tbls);
2523*2d9fd380Sjfb8856606 	if (!tbls || !num_tbls) {
2524*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "No %s tables for %d:%d\n",
2525*2d9fd380Sjfb8856606 			    (parms->tmpl_type == BNXT_ULP_TEMPLATE_TYPE_CLASS) ?
2526*2d9fd380Sjfb8856606 			    "class" : "action", parms->dev_id, tid);
2527*2d9fd380Sjfb8856606 		return -EINVAL;
2528*2d9fd380Sjfb8856606 	}
2529*2d9fd380Sjfb8856606 
2530*2d9fd380Sjfb8856606 	for (i = 0; i < num_tbls; i++) {
2531*2d9fd380Sjfb8856606 		struct bnxt_ulp_mapper_tbl_info *tbl = &tbls[i];
2532*2d9fd380Sjfb8856606 
2533*2d9fd380Sjfb8856606 		if (ulp_mapper_tbl_memtype_opcode_process(parms, tbl))
2534*2d9fd380Sjfb8856606 			continue;
2535*2d9fd380Sjfb8856606 		if (ulp_mapper_tbl_cond_opcode_process(parms, tbl))
2536*2d9fd380Sjfb8856606 			continue;
2537*2d9fd380Sjfb8856606 
2538*2d9fd380Sjfb8856606 		switch (tbl->resource_func) {
2539*2d9fd380Sjfb8856606 		case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE:
2540*2d9fd380Sjfb8856606 			rc = ulp_mapper_tcam_tbl_process(parms, tbl);
2541*2d9fd380Sjfb8856606 			break;
2542*2d9fd380Sjfb8856606 		case BNXT_ULP_RESOURCE_FUNC_EXT_EM_TABLE:
2543*2d9fd380Sjfb8856606 		case BNXT_ULP_RESOURCE_FUNC_INT_EM_TABLE:
2544*2d9fd380Sjfb8856606 			rc = ulp_mapper_em_tbl_process(parms, tbl);
2545*2d9fd380Sjfb8856606 			break;
2546*2d9fd380Sjfb8856606 		case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
2547*2d9fd380Sjfb8856606 			rc = ulp_mapper_index_tbl_process(parms, tbl);
2548*2d9fd380Sjfb8856606 			break;
2549*2d9fd380Sjfb8856606 		case BNXT_ULP_RESOURCE_FUNC_CACHE_TABLE:
2550*2d9fd380Sjfb8856606 			rc = ulp_mapper_cache_tbl_process(parms, tbl);
2551*2d9fd380Sjfb8856606 			break;
2552*2d9fd380Sjfb8856606 		case BNXT_ULP_RESOURCE_FUNC_IF_TABLE:
2553*2d9fd380Sjfb8856606 			rc = ulp_mapper_if_tbl_process(parms, tbl);
2554*2d9fd380Sjfb8856606 			break;
2555*2d9fd380Sjfb8856606 		default:
2556*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Unexpected mapper resource %d\n",
2557*2d9fd380Sjfb8856606 				    tbl->resource_func);
2558*2d9fd380Sjfb8856606 			rc = -EINVAL;
2559*2d9fd380Sjfb8856606 			goto error;
2560*2d9fd380Sjfb8856606 		}
2561*2d9fd380Sjfb8856606 
2562*2d9fd380Sjfb8856606 		if (rc) {
2563*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Resource type %d failed\n",
2564*2d9fd380Sjfb8856606 				    tbl->resource_func);
2565*2d9fd380Sjfb8856606 			goto error;
2566*2d9fd380Sjfb8856606 		}
2567*2d9fd380Sjfb8856606 	}
2568*2d9fd380Sjfb8856606 
2569*2d9fd380Sjfb8856606 	return rc;
2570*2d9fd380Sjfb8856606 error:
2571*2d9fd380Sjfb8856606 	BNXT_TF_DBG(ERR, "%s tables failed creation for %d:%d\n",
2572*2d9fd380Sjfb8856606 		    (parms->tmpl_type == BNXT_ULP_TEMPLATE_TYPE_CLASS) ?
2573*2d9fd380Sjfb8856606 		    "class" : "action", parms->dev_id, tid);
2574*2d9fd380Sjfb8856606 	return rc;
2575*2d9fd380Sjfb8856606 }
2576*2d9fd380Sjfb8856606 
2577*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_resource_free(struct bnxt_ulp_context * ulp,uint32_t fid,struct ulp_flow_db_res_params * res)2578*2d9fd380Sjfb8856606 ulp_mapper_resource_free(struct bnxt_ulp_context *ulp,
2579*2d9fd380Sjfb8856606 			 uint32_t fid,
2580*2d9fd380Sjfb8856606 			 struct ulp_flow_db_res_params *res)
2581*2d9fd380Sjfb8856606 {
2582*2d9fd380Sjfb8856606 	struct tf *tfp;
2583*2d9fd380Sjfb8856606 	int32_t	rc = 0;
2584*2d9fd380Sjfb8856606 
2585*2d9fd380Sjfb8856606 	if (!res || !ulp) {
2586*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Unable to free resource\n ");
2587*2d9fd380Sjfb8856606 		return -EINVAL;
2588*2d9fd380Sjfb8856606 	}
2589*2d9fd380Sjfb8856606 
2590*2d9fd380Sjfb8856606 	tfp = bnxt_ulp_cntxt_tfp_get(ulp);
2591*2d9fd380Sjfb8856606 	if (!tfp) {
2592*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Unable to free resource failed to get tfp\n");
2593*2d9fd380Sjfb8856606 		return -EINVAL;
2594*2d9fd380Sjfb8856606 	}
2595*2d9fd380Sjfb8856606 
2596*2d9fd380Sjfb8856606 	switch (res->resource_func) {
2597*2d9fd380Sjfb8856606 	case BNXT_ULP_RESOURCE_FUNC_CACHE_TABLE:
2598*2d9fd380Sjfb8856606 		rc = ulp_mapper_cache_entry_free(ulp, tfp, res);
2599*2d9fd380Sjfb8856606 		break;
2600*2d9fd380Sjfb8856606 	case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE:
2601*2d9fd380Sjfb8856606 		rc = ulp_mapper_tcam_entry_free(ulp, tfp, res);
2602*2d9fd380Sjfb8856606 		break;
2603*2d9fd380Sjfb8856606 	case BNXT_ULP_RESOURCE_FUNC_EXT_EM_TABLE:
2604*2d9fd380Sjfb8856606 	case BNXT_ULP_RESOURCE_FUNC_INT_EM_TABLE:
2605*2d9fd380Sjfb8856606 		rc = ulp_mapper_em_entry_free(ulp, tfp, res);
2606*2d9fd380Sjfb8856606 		break;
2607*2d9fd380Sjfb8856606 	case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
2608*2d9fd380Sjfb8856606 		rc = ulp_mapper_index_entry_free(ulp, tfp, res);
2609*2d9fd380Sjfb8856606 		break;
2610*2d9fd380Sjfb8856606 	case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
2611*2d9fd380Sjfb8856606 		rc = ulp_mapper_ident_free(ulp, tfp, res);
2612*2d9fd380Sjfb8856606 		break;
2613*2d9fd380Sjfb8856606 	case BNXT_ULP_RESOURCE_FUNC_HW_FID:
2614*2d9fd380Sjfb8856606 		rc = ulp_mapper_mark_free(ulp, res);
2615*2d9fd380Sjfb8856606 		break;
2616*2d9fd380Sjfb8856606 	case BNXT_ULP_RESOURCE_FUNC_PARENT_FLOW:
2617*2d9fd380Sjfb8856606 		rc = ulp_mapper_parent_flow_free(ulp, fid, res);
2618*2d9fd380Sjfb8856606 		break;
2619*2d9fd380Sjfb8856606 	case BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW:
2620*2d9fd380Sjfb8856606 		rc = ulp_mapper_child_flow_free(ulp, fid, res);
2621*2d9fd380Sjfb8856606 		break;
2622*2d9fd380Sjfb8856606 	default:
2623*2d9fd380Sjfb8856606 		break;
2624*2d9fd380Sjfb8856606 	}
2625*2d9fd380Sjfb8856606 
2626*2d9fd380Sjfb8856606 	return rc;
2627*2d9fd380Sjfb8856606 }
2628*2d9fd380Sjfb8856606 
2629*2d9fd380Sjfb8856606 int32_t
ulp_mapper_resources_free(struct bnxt_ulp_context * ulp_ctx,enum bnxt_ulp_fdb_type flow_type,uint32_t fid)2630*2d9fd380Sjfb8856606 ulp_mapper_resources_free(struct bnxt_ulp_context *ulp_ctx,
2631*2d9fd380Sjfb8856606 			  enum bnxt_ulp_fdb_type flow_type,
2632*2d9fd380Sjfb8856606 			  uint32_t fid)
2633*2d9fd380Sjfb8856606 {
2634*2d9fd380Sjfb8856606 	struct ulp_flow_db_res_params res_parms = { 0 };
2635*2d9fd380Sjfb8856606 	int32_t rc, trc;
2636*2d9fd380Sjfb8856606 
2637*2d9fd380Sjfb8856606 	if (!ulp_ctx) {
2638*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Invalid parms, unable to free flow\n");
2639*2d9fd380Sjfb8856606 		return -EINVAL;
2640*2d9fd380Sjfb8856606 	}
2641*2d9fd380Sjfb8856606 
2642*2d9fd380Sjfb8856606 	/*
2643*2d9fd380Sjfb8856606 	 * Set the critical resource on the first resource del, then iterate
2644*2d9fd380Sjfb8856606 	 * while status is good
2645*2d9fd380Sjfb8856606 	 */
2646*2d9fd380Sjfb8856606 	res_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_YES;
2647*2d9fd380Sjfb8856606 	rc = ulp_flow_db_resource_del(ulp_ctx, flow_type, fid, &res_parms);
2648*2d9fd380Sjfb8856606 
2649*2d9fd380Sjfb8856606 	if (rc) {
2650*2d9fd380Sjfb8856606 		/*
2651*2d9fd380Sjfb8856606 		 * This is unexpected on the first call to resource del.
2652*2d9fd380Sjfb8856606 		 * It likely means that the flow did not exist in the flow db.
2653*2d9fd380Sjfb8856606 		 */
2654*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Flow[%d][0x%08x] failed to free (rc=%d)\n",
2655*2d9fd380Sjfb8856606 			    flow_type, fid, rc);
2656*2d9fd380Sjfb8856606 		return rc;
2657*2d9fd380Sjfb8856606 	}
2658*2d9fd380Sjfb8856606 
2659*2d9fd380Sjfb8856606 	while (!rc) {
2660*2d9fd380Sjfb8856606 		trc = ulp_mapper_resource_free(ulp_ctx, fid, &res_parms);
2661*2d9fd380Sjfb8856606 		if (trc)
2662*2d9fd380Sjfb8856606 			/*
2663*2d9fd380Sjfb8856606 			 * On fail, we still need to attempt to free the
2664*2d9fd380Sjfb8856606 			 * remaining resources.  Don't return
2665*2d9fd380Sjfb8856606 			 */
2666*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR,
2667*2d9fd380Sjfb8856606 				    "Flow[%d][0x%x] Res[%d][0x%016" PRIx64
2668*2d9fd380Sjfb8856606 				    "] failed rc=%d.\n",
2669*2d9fd380Sjfb8856606 				    flow_type, fid, res_parms.resource_func,
2670*2d9fd380Sjfb8856606 				    res_parms.resource_hndl, trc);
2671*2d9fd380Sjfb8856606 
2672*2d9fd380Sjfb8856606 		/* All subsequent call require the non-critical_resource */
2673*2d9fd380Sjfb8856606 		res_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
2674*2d9fd380Sjfb8856606 
2675*2d9fd380Sjfb8856606 		rc = ulp_flow_db_resource_del(ulp_ctx,
2676*2d9fd380Sjfb8856606 					      flow_type,
2677*2d9fd380Sjfb8856606 					      fid,
2678*2d9fd380Sjfb8856606 					      &res_parms);
2679*2d9fd380Sjfb8856606 	}
2680*2d9fd380Sjfb8856606 
2681*2d9fd380Sjfb8856606 	/* Free the Flow ID since we've removed all resources */
2682*2d9fd380Sjfb8856606 	rc = ulp_flow_db_fid_free(ulp_ctx, flow_type, fid);
2683*2d9fd380Sjfb8856606 
2684*2d9fd380Sjfb8856606 	return rc;
2685*2d9fd380Sjfb8856606 }
2686*2d9fd380Sjfb8856606 
2687*2d9fd380Sjfb8856606 static void
ulp_mapper_glb_resource_info_deinit(struct bnxt_ulp_context * ulp_ctx,struct bnxt_ulp_mapper_data * mapper_data)2688*2d9fd380Sjfb8856606 ulp_mapper_glb_resource_info_deinit(struct bnxt_ulp_context *ulp_ctx,
2689*2d9fd380Sjfb8856606 				    struct bnxt_ulp_mapper_data *mapper_data)
2690*2d9fd380Sjfb8856606 {
2691*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_glb_resource_entry *ent;
2692*2d9fd380Sjfb8856606 	struct ulp_flow_db_res_params res;
2693*2d9fd380Sjfb8856606 	uint32_t dir, idx;
2694*2d9fd380Sjfb8856606 
2695*2d9fd380Sjfb8856606 	/* Iterate the global resources and process each one */
2696*2d9fd380Sjfb8856606 	for (dir = TF_DIR_RX; dir < TF_DIR_MAX; dir++) {
2697*2d9fd380Sjfb8856606 		for (idx = 0; idx < BNXT_ULP_GLB_RESOURCE_TBL_MAX_SZ;
2698*2d9fd380Sjfb8856606 		      idx++) {
2699*2d9fd380Sjfb8856606 			ent = &mapper_data->glb_res_tbl[dir][idx];
2700*2d9fd380Sjfb8856606 			if (ent->resource_func ==
2701*2d9fd380Sjfb8856606 			    BNXT_ULP_RESOURCE_FUNC_INVALID)
2702*2d9fd380Sjfb8856606 				continue;
2703*2d9fd380Sjfb8856606 			memset(&res, 0, sizeof(struct ulp_flow_db_res_params));
2704*2d9fd380Sjfb8856606 			res.resource_func = ent->resource_func;
2705*2d9fd380Sjfb8856606 			res.direction = dir;
2706*2d9fd380Sjfb8856606 			res.resource_type = ent->resource_type;
2707*2d9fd380Sjfb8856606 			/*convert it from BE to cpu */
2708*2d9fd380Sjfb8856606 			res.resource_hndl =
2709*2d9fd380Sjfb8856606 				tfp_be_to_cpu_64(ent->resource_hndl);
2710*2d9fd380Sjfb8856606 			ulp_mapper_resource_free(ulp_ctx, 0, &res);
2711*2d9fd380Sjfb8856606 		}
2712*2d9fd380Sjfb8856606 	}
2713*2d9fd380Sjfb8856606 }
2714*2d9fd380Sjfb8856606 
2715*2d9fd380Sjfb8856606 int32_t
ulp_mapper_flow_destroy(struct bnxt_ulp_context * ulp_ctx,enum bnxt_ulp_fdb_type flow_type,uint32_t fid)2716*2d9fd380Sjfb8856606 ulp_mapper_flow_destroy(struct bnxt_ulp_context *ulp_ctx,
2717*2d9fd380Sjfb8856606 			enum bnxt_ulp_fdb_type flow_type,
2718*2d9fd380Sjfb8856606 			uint32_t fid)
2719*2d9fd380Sjfb8856606 {
2720*2d9fd380Sjfb8856606 	int32_t rc;
2721*2d9fd380Sjfb8856606 
2722*2d9fd380Sjfb8856606 	if (!ulp_ctx) {
2723*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Invalid parms, unable to free flow\n");
2724*2d9fd380Sjfb8856606 		return -EINVAL;
2725*2d9fd380Sjfb8856606 	}
2726*2d9fd380Sjfb8856606 
2727*2d9fd380Sjfb8856606 	rc = ulp_mapper_resources_free(ulp_ctx, flow_type, fid);
2728*2d9fd380Sjfb8856606 	return rc;
2729*2d9fd380Sjfb8856606 }
2730*2d9fd380Sjfb8856606 
2731*2d9fd380Sjfb8856606 /* Function to handle the default global templates that are allocated during
2732*2d9fd380Sjfb8856606  * the startup and reused later.
2733*2d9fd380Sjfb8856606  */
2734*2d9fd380Sjfb8856606 static int32_t
ulp_mapper_glb_template_table_init(struct bnxt_ulp_context * ulp_ctx)2735*2d9fd380Sjfb8856606 ulp_mapper_glb_template_table_init(struct bnxt_ulp_context *ulp_ctx)
2736*2d9fd380Sjfb8856606 {
2737*2d9fd380Sjfb8856606 	uint32_t *glbl_tmpl_list;
2738*2d9fd380Sjfb8856606 	uint32_t num_glb_tmpls, idx, dev_id;
2739*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_parms parms;
2740*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_data *mapper_data;
2741*2d9fd380Sjfb8856606 	int32_t rc = 0;
2742*2d9fd380Sjfb8856606 
2743*2d9fd380Sjfb8856606 	glbl_tmpl_list = ulp_mapper_glb_template_table_get(&num_glb_tmpls);
2744*2d9fd380Sjfb8856606 	if (!glbl_tmpl_list || !num_glb_tmpls)
2745*2d9fd380Sjfb8856606 		return rc; /* No global templates to process */
2746*2d9fd380Sjfb8856606 
2747*2d9fd380Sjfb8856606 	/* Get the device id from the ulp context */
2748*2d9fd380Sjfb8856606 	if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) {
2749*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Invalid ulp context\n");
2750*2d9fd380Sjfb8856606 		return -EINVAL;
2751*2d9fd380Sjfb8856606 	}
2752*2d9fd380Sjfb8856606 
2753*2d9fd380Sjfb8856606 	mapper_data = bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx);
2754*2d9fd380Sjfb8856606 	if (!mapper_data) {
2755*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get the ulp mapper data\n");
2756*2d9fd380Sjfb8856606 		return -EINVAL;
2757*2d9fd380Sjfb8856606 	}
2758*2d9fd380Sjfb8856606 
2759*2d9fd380Sjfb8856606 	/* Iterate the global resources and process each one */
2760*2d9fd380Sjfb8856606 	for (idx = 0; idx < num_glb_tmpls; idx++) {
2761*2d9fd380Sjfb8856606 		/* Initialize the parms structure */
2762*2d9fd380Sjfb8856606 		memset(&parms, 0, sizeof(parms));
2763*2d9fd380Sjfb8856606 		parms.tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
2764*2d9fd380Sjfb8856606 		parms.ulp_ctx = ulp_ctx;
2765*2d9fd380Sjfb8856606 		parms.dev_id = dev_id;
2766*2d9fd380Sjfb8856606 		parms.mapper_data = mapper_data;
2767*2d9fd380Sjfb8856606 		parms.flow_type = BNXT_ULP_FDB_TYPE_DEFAULT;
2768*2d9fd380Sjfb8856606 		parms.tmpl_type = BNXT_ULP_TEMPLATE_TYPE_CLASS;
2769*2d9fd380Sjfb8856606 
2770*2d9fd380Sjfb8856606 		/* Get the class table entry from dev id and class id */
2771*2d9fd380Sjfb8856606 		parms.class_tid = glbl_tmpl_list[idx];
2772*2d9fd380Sjfb8856606 
2773*2d9fd380Sjfb8856606 		parms.device_params = bnxt_ulp_device_params_get(parms.dev_id);
2774*2d9fd380Sjfb8856606 		if (!parms.device_params) {
2775*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "No device for device id %d\n",
2776*2d9fd380Sjfb8856606 				    parms.dev_id);
2777*2d9fd380Sjfb8856606 			return -EINVAL;
2778*2d9fd380Sjfb8856606 		}
2779*2d9fd380Sjfb8856606 
2780*2d9fd380Sjfb8856606 		rc = ulp_mapper_tbls_process(&parms, parms.class_tid);
2781*2d9fd380Sjfb8856606 		if (rc)
2782*2d9fd380Sjfb8856606 			return rc;
2783*2d9fd380Sjfb8856606 	}
2784*2d9fd380Sjfb8856606 	return rc;
2785*2d9fd380Sjfb8856606 }
2786*2d9fd380Sjfb8856606 
2787*2d9fd380Sjfb8856606 /* Function to handle the mapping of the Flow to be compatible
2788*2d9fd380Sjfb8856606  * with the underlying hardware.
2789*2d9fd380Sjfb8856606  */
2790*2d9fd380Sjfb8856606 int32_t
ulp_mapper_flow_create(struct bnxt_ulp_context * ulp_ctx,struct bnxt_ulp_mapper_create_parms * cparms)2791*2d9fd380Sjfb8856606 ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,
2792*2d9fd380Sjfb8856606 		       struct bnxt_ulp_mapper_create_parms *cparms)
2793*2d9fd380Sjfb8856606 {
2794*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_parms parms;
2795*2d9fd380Sjfb8856606 	struct ulp_regfile regfile;
2796*2d9fd380Sjfb8856606 	int32_t	 rc, trc;
2797*2d9fd380Sjfb8856606 
2798*2d9fd380Sjfb8856606 	if (!ulp_ctx || !cparms)
2799*2d9fd380Sjfb8856606 		return -EINVAL;
2800*2d9fd380Sjfb8856606 
2801*2d9fd380Sjfb8856606 	/* Initialize the parms structure */
2802*2d9fd380Sjfb8856606 	memset(&parms, 0, sizeof(parms));
2803*2d9fd380Sjfb8856606 	parms.act_prop = cparms->act_prop;
2804*2d9fd380Sjfb8856606 	parms.act_bitmap = cparms->act;
2805*2d9fd380Sjfb8856606 	parms.hdr_bitmap = cparms->hdr_bitmap;
2806*2d9fd380Sjfb8856606 	parms.regfile = &regfile;
2807*2d9fd380Sjfb8856606 	parms.hdr_field = cparms->hdr_field;
2808*2d9fd380Sjfb8856606 	parms.comp_fld = cparms->comp_fld;
2809*2d9fd380Sjfb8856606 	parms.tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
2810*2d9fd380Sjfb8856606 	parms.ulp_ctx = ulp_ctx;
2811*2d9fd380Sjfb8856606 	parms.tcam_tbl_opc = BNXT_ULP_MAPPER_TCAM_TBL_OPC_NORMAL;
2812*2d9fd380Sjfb8856606 	parms.act_tid = cparms->act_tid;
2813*2d9fd380Sjfb8856606 	parms.class_tid = cparms->class_tid;
2814*2d9fd380Sjfb8856606 	parms.flow_type = cparms->flow_type;
2815*2d9fd380Sjfb8856606 	parms.parent_flow = cparms->parent_flow;
2816*2d9fd380Sjfb8856606 	parms.parent_fid = cparms->parent_fid;
2817*2d9fd380Sjfb8856606 	parms.fid = cparms->flow_id;
2818*2d9fd380Sjfb8856606 	parms.tun_idx = cparms->tun_idx;
2819*2d9fd380Sjfb8856606 
2820*2d9fd380Sjfb8856606 	/* Get the device id from the ulp context */
2821*2d9fd380Sjfb8856606 	if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &parms.dev_id)) {
2822*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Invalid ulp context\n");
2823*2d9fd380Sjfb8856606 		return -EINVAL;
2824*2d9fd380Sjfb8856606 	}
2825*2d9fd380Sjfb8856606 
2826*2d9fd380Sjfb8856606 	/* Get the device params, it will be used in later processing */
2827*2d9fd380Sjfb8856606 	parms.device_params = bnxt_ulp_device_params_get(parms.dev_id);
2828*2d9fd380Sjfb8856606 	if (!parms.device_params) {
2829*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "No device parms for device id %d\n",
2830*2d9fd380Sjfb8856606 			    parms.dev_id);
2831*2d9fd380Sjfb8856606 		return -EINVAL;
2832*2d9fd380Sjfb8856606 	}
2833*2d9fd380Sjfb8856606 
2834*2d9fd380Sjfb8856606 	/*
2835*2d9fd380Sjfb8856606 	 * Get the mapper data for dynamic mapper data such as default
2836*2d9fd380Sjfb8856606 	 * ids.
2837*2d9fd380Sjfb8856606 	 */
2838*2d9fd380Sjfb8856606 	parms.mapper_data = (struct bnxt_ulp_mapper_data *)
2839*2d9fd380Sjfb8856606 		bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx);
2840*2d9fd380Sjfb8856606 	if (!parms.mapper_data) {
2841*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to get the ulp mapper data\n");
2842*2d9fd380Sjfb8856606 		return -EINVAL;
2843*2d9fd380Sjfb8856606 	}
2844*2d9fd380Sjfb8856606 
2845*2d9fd380Sjfb8856606 	/* initialize the registry file for further processing */
2846*2d9fd380Sjfb8856606 	if (!ulp_regfile_init(parms.regfile)) {
2847*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "regfile initialization failed.\n");
2848*2d9fd380Sjfb8856606 		return -EINVAL;
2849*2d9fd380Sjfb8856606 	}
2850*2d9fd380Sjfb8856606 
2851*2d9fd380Sjfb8856606 	rc = ulp_regfile_write(parms.regfile,
2852*2d9fd380Sjfb8856606 			       BNXT_ULP_REGFILE_INDEX_CLASS_TID,
2853*2d9fd380Sjfb8856606 			       tfp_cpu_to_be_64((uint64_t)parms.class_tid));
2854*2d9fd380Sjfb8856606 	if (!rc) {
2855*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Unable to write template ID to regfile\n");
2856*2d9fd380Sjfb8856606 		return -EINVAL;
2857*2d9fd380Sjfb8856606 	}
2858*2d9fd380Sjfb8856606 
2859*2d9fd380Sjfb8856606 	/* Process the action template list from the selected action table*/
2860*2d9fd380Sjfb8856606 	if (parms.act_tid) {
2861*2d9fd380Sjfb8856606 		parms.tmpl_type = BNXT_ULP_TEMPLATE_TYPE_ACTION;
2862*2d9fd380Sjfb8856606 		/* Process the action template tables */
2863*2d9fd380Sjfb8856606 		rc = ulp_mapper_tbls_process(&parms, parms.act_tid);
2864*2d9fd380Sjfb8856606 		if (rc)
2865*2d9fd380Sjfb8856606 			goto flow_error;
2866*2d9fd380Sjfb8856606 	}
2867*2d9fd380Sjfb8856606 
2868*2d9fd380Sjfb8856606 	if (parms.class_tid) {
2869*2d9fd380Sjfb8856606 		parms.tmpl_type = BNXT_ULP_TEMPLATE_TYPE_CLASS;
2870*2d9fd380Sjfb8856606 
2871*2d9fd380Sjfb8856606 		/* Process the class template tables.*/
2872*2d9fd380Sjfb8856606 		rc = ulp_mapper_tbls_process(&parms, parms.class_tid);
2873*2d9fd380Sjfb8856606 		if (rc)
2874*2d9fd380Sjfb8856606 			goto flow_error;
2875*2d9fd380Sjfb8856606 	}
2876*2d9fd380Sjfb8856606 
2877*2d9fd380Sjfb8856606 	/* setup the parent-child details */
2878*2d9fd380Sjfb8856606 	if (parms.parent_flow) {
2879*2d9fd380Sjfb8856606 		/* create a parent flow details */
2880*2d9fd380Sjfb8856606 		rc = ulp_flow_db_parent_flow_create(&parms);
2881*2d9fd380Sjfb8856606 		if (rc)
2882*2d9fd380Sjfb8856606 			goto flow_error;
2883*2d9fd380Sjfb8856606 	} else if (parms.parent_fid) {
2884*2d9fd380Sjfb8856606 		/* create a child flow details */
2885*2d9fd380Sjfb8856606 		rc = ulp_flow_db_child_flow_create(&parms);
2886*2d9fd380Sjfb8856606 		if (rc)
2887*2d9fd380Sjfb8856606 			goto flow_error;
2888*2d9fd380Sjfb8856606 	}
2889*2d9fd380Sjfb8856606 
2890*2d9fd380Sjfb8856606 	return rc;
2891*2d9fd380Sjfb8856606 
2892*2d9fd380Sjfb8856606 flow_error:
2893*2d9fd380Sjfb8856606 	/* Free all resources that were allocated during flow creation */
2894*2d9fd380Sjfb8856606 	trc = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
2895*2d9fd380Sjfb8856606 				      parms.fid);
2896*2d9fd380Sjfb8856606 	if (trc)
2897*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to free all resources rc=%d\n", trc);
2898*2d9fd380Sjfb8856606 
2899*2d9fd380Sjfb8856606 	return rc;
2900*2d9fd380Sjfb8856606 }
2901*2d9fd380Sjfb8856606 
2902*2d9fd380Sjfb8856606 int32_t
ulp_mapper_init(struct bnxt_ulp_context * ulp_ctx)2903*2d9fd380Sjfb8856606 ulp_mapper_init(struct bnxt_ulp_context *ulp_ctx)
2904*2d9fd380Sjfb8856606 {
2905*2d9fd380Sjfb8856606 	struct bnxt_ulp_cache_tbl_params *tbl;
2906*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_data *data;
2907*2d9fd380Sjfb8856606 	uint32_t i;
2908*2d9fd380Sjfb8856606 	struct tf *tfp;
2909*2d9fd380Sjfb8856606 	int32_t rc, csize;
2910*2d9fd380Sjfb8856606 
2911*2d9fd380Sjfb8856606 	if (!ulp_ctx)
2912*2d9fd380Sjfb8856606 		return -EINVAL;
2913*2d9fd380Sjfb8856606 
2914*2d9fd380Sjfb8856606 	tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
2915*2d9fd380Sjfb8856606 	if (!tfp)
2916*2d9fd380Sjfb8856606 		return -EINVAL;
2917*2d9fd380Sjfb8856606 
2918*2d9fd380Sjfb8856606 	data = rte_zmalloc("ulp_mapper_data",
2919*2d9fd380Sjfb8856606 			   sizeof(struct bnxt_ulp_mapper_data), 0);
2920*2d9fd380Sjfb8856606 	if (!data) {
2921*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to allocate the mapper data\n");
2922*2d9fd380Sjfb8856606 		return -ENOMEM;
2923*2d9fd380Sjfb8856606 	}
2924*2d9fd380Sjfb8856606 
2925*2d9fd380Sjfb8856606 	if (bnxt_ulp_cntxt_ptr2_mapper_data_set(ulp_ctx, data)) {
2926*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to set mapper data in context\n");
2927*2d9fd380Sjfb8856606 		/* Don't call deinit since the prof_func wasn't allocated. */
2928*2d9fd380Sjfb8856606 		rte_free(data);
2929*2d9fd380Sjfb8856606 		return -ENOMEM;
2930*2d9fd380Sjfb8856606 	}
2931*2d9fd380Sjfb8856606 
2932*2d9fd380Sjfb8856606 	/* Allocate the global resource ids */
2933*2d9fd380Sjfb8856606 	rc = ulp_mapper_glb_resource_info_init(ulp_ctx, data);
2934*2d9fd380Sjfb8856606 	if (rc) {
2935*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to initialize global resource ids\n");
2936*2d9fd380Sjfb8856606 		goto error;
2937*2d9fd380Sjfb8856606 	}
2938*2d9fd380Sjfb8856606 
2939*2d9fd380Sjfb8856606 	/* Allocate the ulp cache tables. */
2940*2d9fd380Sjfb8856606 	for (i = 0; i < BNXT_ULP_CACHE_TBL_MAX_SZ; i++) {
2941*2d9fd380Sjfb8856606 		tbl = ulp_mapper_cache_tbl_params_get(i);
2942*2d9fd380Sjfb8856606 		if (!tbl) {
2943*2d9fd380Sjfb8856606 			BNXT_TF_DBG(ERR, "Failed to get cache table parms (%d)",
2944*2d9fd380Sjfb8856606 				    i);
2945*2d9fd380Sjfb8856606 			goto error;
2946*2d9fd380Sjfb8856606 		}
2947*2d9fd380Sjfb8856606 		if (tbl->num_entries != 0) {
2948*2d9fd380Sjfb8856606 			csize = sizeof(struct bnxt_ulp_mapper_cache_entry) *
2949*2d9fd380Sjfb8856606 				tbl->num_entries;
2950*2d9fd380Sjfb8856606 			data->cache_tbl[i] = rte_zmalloc("ulp mapper cache tbl",
2951*2d9fd380Sjfb8856606 							 csize, 0);
2952*2d9fd380Sjfb8856606 			if (!data->cache_tbl[i]) {
2953*2d9fd380Sjfb8856606 				BNXT_TF_DBG(ERR, "Failed to allocate Cache "
2954*2d9fd380Sjfb8856606 					    "table %d.\n", i);
2955*2d9fd380Sjfb8856606 				rc = -ENOMEM;
2956*2d9fd380Sjfb8856606 				goto error;
2957*2d9fd380Sjfb8856606 			}
2958*2d9fd380Sjfb8856606 		}
2959*2d9fd380Sjfb8856606 	}
2960*2d9fd380Sjfb8856606 
2961*2d9fd380Sjfb8856606 	rc = ulp_mapper_glb_template_table_init(ulp_ctx);
2962*2d9fd380Sjfb8856606 	if (rc) {
2963*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to initialize global templates\n");
2964*2d9fd380Sjfb8856606 		goto error;
2965*2d9fd380Sjfb8856606 	}
2966*2d9fd380Sjfb8856606 
2967*2d9fd380Sjfb8856606 	return 0;
2968*2d9fd380Sjfb8856606 error:
2969*2d9fd380Sjfb8856606 	/* Ignore the return code in favor of returning the original error. */
2970*2d9fd380Sjfb8856606 	ulp_mapper_deinit(ulp_ctx);
2971*2d9fd380Sjfb8856606 	return rc;
2972*2d9fd380Sjfb8856606 }
2973*2d9fd380Sjfb8856606 
2974*2d9fd380Sjfb8856606 void
ulp_mapper_deinit(struct bnxt_ulp_context * ulp_ctx)2975*2d9fd380Sjfb8856606 ulp_mapper_deinit(struct bnxt_ulp_context *ulp_ctx)
2976*2d9fd380Sjfb8856606 {
2977*2d9fd380Sjfb8856606 	struct bnxt_ulp_mapper_data *data;
2978*2d9fd380Sjfb8856606 	uint32_t i;
2979*2d9fd380Sjfb8856606 	struct tf *tfp;
2980*2d9fd380Sjfb8856606 
2981*2d9fd380Sjfb8856606 	if (!ulp_ctx) {
2982*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR,
2983*2d9fd380Sjfb8856606 			    "Failed to acquire ulp context, so data may "
2984*2d9fd380Sjfb8856606 			    "not be released.\n");
2985*2d9fd380Sjfb8856606 		return;
2986*2d9fd380Sjfb8856606 	}
2987*2d9fd380Sjfb8856606 
2988*2d9fd380Sjfb8856606 	data = (struct bnxt_ulp_mapper_data *)
2989*2d9fd380Sjfb8856606 		bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx);
2990*2d9fd380Sjfb8856606 	if (!data) {
2991*2d9fd380Sjfb8856606 		/* Go ahead and return since there is no allocated data. */
2992*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "No data appears to have been allocated.\n");
2993*2d9fd380Sjfb8856606 		return;
2994*2d9fd380Sjfb8856606 	}
2995*2d9fd380Sjfb8856606 
2996*2d9fd380Sjfb8856606 	tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
2997*2d9fd380Sjfb8856606 	if (!tfp) {
2998*2d9fd380Sjfb8856606 		BNXT_TF_DBG(ERR, "Failed to acquire tfp.\n");
2999*2d9fd380Sjfb8856606 		/* Free the mapper data regardless of errors. */
3000*2d9fd380Sjfb8856606 		goto free_mapper_data;
3001*2d9fd380Sjfb8856606 	}
3002*2d9fd380Sjfb8856606 
3003*2d9fd380Sjfb8856606 	/* Free the global resource info table entries */
3004*2d9fd380Sjfb8856606 	ulp_mapper_glb_resource_info_deinit(ulp_ctx, data);
3005*2d9fd380Sjfb8856606 
3006*2d9fd380Sjfb8856606 free_mapper_data:
3007*2d9fd380Sjfb8856606 	/* Free the ulp cache tables */
3008*2d9fd380Sjfb8856606 	for (i = 0; i < BNXT_ULP_CACHE_TBL_MAX_SZ; i++) {
3009*2d9fd380Sjfb8856606 		rte_free(data->cache_tbl[i]);
3010*2d9fd380Sjfb8856606 		data->cache_tbl[i] = NULL;
3011*2d9fd380Sjfb8856606 	}
3012*2d9fd380Sjfb8856606 
3013*2d9fd380Sjfb8856606 	rte_free(data);
3014*2d9fd380Sjfb8856606 	/* Reset the data pointer within the ulp_ctx. */
3015*2d9fd380Sjfb8856606 	bnxt_ulp_cntxt_ptr2_mapper_data_set(ulp_ctx, NULL);
3016*2d9fd380Sjfb8856606 }
3017