xref: /dpdk/drivers/net/bnxt/tf_ulp/bnxt_ulp_tfc.c (revision 7d32c003ac175d7ac8669dc11684c75cc7eb56b8)
1dd0191d5SShuanglin Wang /* SPDX-License-Identifier: BSD-3-Clause
2dd0191d5SShuanglin Wang  * Copyright(c) 2019-2021 Broadcom
3dd0191d5SShuanglin Wang  * All rights reserved.
4dd0191d5SShuanglin Wang  */
5dd0191d5SShuanglin Wang 
6dd0191d5SShuanglin Wang #include <rte_log.h>
7dd0191d5SShuanglin Wang #include <rte_malloc.h>
8dd0191d5SShuanglin Wang #include <rte_flow.h>
9dd0191d5SShuanglin Wang #include <rte_flow_driver.h>
10dd0191d5SShuanglin Wang #include <rte_tailq.h>
11dd0191d5SShuanglin Wang #include <rte_spinlock.h>
1280d760e1SJay Ding #include <rte_mtr.h>
1380d760e1SJay Ding #include <rte_version.h>
14b14da654SPeter Spreadborough #include <rte_hash_crc.h>
15dd0191d5SShuanglin Wang 
16dd0191d5SShuanglin Wang #include "bnxt.h"
17dd0191d5SShuanglin Wang #include "bnxt_ulp.h"
180c036a14SPeter Spreadborough #include "bnxt_ulp_utils.h"
19dd0191d5SShuanglin Wang #include "bnxt_ulp_tfc.h"
20dd0191d5SShuanglin Wang #include "bnxt_tf_common.h"
21dd0191d5SShuanglin Wang #include "hsi_struct_def_dpdk.h"
22dd0191d5SShuanglin Wang #include "tf_core.h"
23dd0191d5SShuanglin Wang #include "tf_ext_flow_handle.h"
24dd0191d5SShuanglin Wang 
25dd0191d5SShuanglin Wang #include "ulp_template_db_enum.h"
26dd0191d5SShuanglin Wang #include "ulp_template_struct.h"
27dd0191d5SShuanglin Wang #include "ulp_mark_mgr.h"
28dd0191d5SShuanglin Wang #include "ulp_fc_mgr.h"
290513f0afSPeter Spreadborough #include "ulp_sc_mgr.h"
30dd0191d5SShuanglin Wang #include "ulp_flow_db.h"
31dd0191d5SShuanglin Wang #include "ulp_mapper.h"
32dd0191d5SShuanglin Wang #include "ulp_matcher.h"
33dd0191d5SShuanglin Wang #include "ulp_port_db.h"
34dd0191d5SShuanglin Wang #include "ulp_tun.h"
35dd0191d5SShuanglin Wang #include "ulp_ha_mgr.h"
36dd0191d5SShuanglin Wang #include "bnxt_tf_pmd_shim.h"
37dd0191d5SShuanglin Wang #include "ulp_template_db_tbl.h"
38ffbc3529SShuanglin Wang #include "tfc_resources.h"
39dd0191d5SShuanglin Wang 
40dd0191d5SShuanglin Wang /* define to enable shared table scope */
41dd0191d5SShuanglin Wang #define TFC_SHARED_TBL_SCOPE_ENABLE 0
42dd0191d5SShuanglin Wang 
43dd0191d5SShuanglin Wang bool
44dd0191d5SShuanglin Wang bnxt_ulp_cntxt_shared_tbl_scope_enabled(struct bnxt_ulp_context *ulp_ctx)
45dd0191d5SShuanglin Wang {
46dd0191d5SShuanglin Wang 	uint32_t flags = 0;
47dd0191d5SShuanglin Wang 	int rc;
48dd0191d5SShuanglin Wang 
49dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_ptr2_ulp_flags_get(ulp_ctx, &flags);
50dd0191d5SShuanglin Wang 	if (rc)
51dd0191d5SShuanglin Wang 		return false;
52dd0191d5SShuanglin Wang 	return !!(flags & BNXT_ULP_SHARED_TBL_SCOPE_ENABLED);
53dd0191d5SShuanglin Wang }
54dd0191d5SShuanglin Wang 
55dd0191d5SShuanglin Wang int32_t
56dd0191d5SShuanglin Wang bnxt_ulp_cntxt_tfcp_set(struct bnxt_ulp_context *ulp, struct tfc *tfcp)
57dd0191d5SShuanglin Wang {
58dd0191d5SShuanglin Wang 	enum bnxt_ulp_tfo_type tfo_type = BNXT_ULP_TFO_TYPE_TFC;
59dd0191d5SShuanglin Wang 
60dd0191d5SShuanglin Wang 	if (ulp == NULL)
61dd0191d5SShuanglin Wang 		return -EINVAL;
62dd0191d5SShuanglin Wang 
63dd0191d5SShuanglin Wang 	/* If NULL, this is invalidating an entry */
64dd0191d5SShuanglin Wang 	if (tfcp == NULL)
65dd0191d5SShuanglin Wang 		tfo_type = BNXT_ULP_TFO_TYPE_INVALID;
66dd0191d5SShuanglin Wang 	ulp->tfo_type = tfo_type;
67dd0191d5SShuanglin Wang 	ulp->tfcp = tfcp;
68dd0191d5SShuanglin Wang 
69dd0191d5SShuanglin Wang 	return 0;
70dd0191d5SShuanglin Wang }
71dd0191d5SShuanglin Wang 
72dd0191d5SShuanglin Wang struct tfc *
73dd0191d5SShuanglin Wang bnxt_ulp_cntxt_tfcp_get(struct bnxt_ulp_context *ulp)
74dd0191d5SShuanglin Wang {
75dd0191d5SShuanglin Wang 	if (ulp == NULL)
76dd0191d5SShuanglin Wang 		return NULL;
77dd0191d5SShuanglin Wang 
78dd0191d5SShuanglin Wang 	if (ulp->tfo_type != BNXT_ULP_TFO_TYPE_TFC) {
79dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Wrong tf type %d != %d\n",
80dd0191d5SShuanglin Wang 			     ulp->tfo_type, BNXT_ULP_TFO_TYPE_TFC);
81dd0191d5SShuanglin Wang 		return NULL;
82dd0191d5SShuanglin Wang 	}
83dd0191d5SShuanglin Wang 
84dd0191d5SShuanglin Wang 	return (struct tfc *)ulp->tfcp;
85dd0191d5SShuanglin Wang }
86dd0191d5SShuanglin Wang 
87dd0191d5SShuanglin Wang uint32_t
88dd0191d5SShuanglin Wang bnxt_ulp_cntxt_tbl_scope_max_pools_get(struct bnxt_ulp_context *ulp_ctx)
89dd0191d5SShuanglin Wang {
90dd0191d5SShuanglin Wang 	/* Max pools can be 1 or greater, always return workable value */
91dd0191d5SShuanglin Wang 	if (ulp_ctx != NULL &&
92dd0191d5SShuanglin Wang 	    ulp_ctx->cfg_data != NULL &&
93dd0191d5SShuanglin Wang 	    ulp_ctx->cfg_data->max_pools)
94dd0191d5SShuanglin Wang 		return ulp_ctx->cfg_data->max_pools;
95dd0191d5SShuanglin Wang 	return 1;
96dd0191d5SShuanglin Wang }
97dd0191d5SShuanglin Wang 
98dd0191d5SShuanglin Wang int32_t
99dd0191d5SShuanglin Wang bnxt_ulp_cntxt_tbl_scope_max_pools_set(struct bnxt_ulp_context *ulp_ctx,
100dd0191d5SShuanglin Wang 				       uint32_t max)
101dd0191d5SShuanglin Wang {
102dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
103dd0191d5SShuanglin Wang 		return -EINVAL;
104dd0191d5SShuanglin Wang 
105dd0191d5SShuanglin Wang 	/* make sure that max is at least 1 */
106dd0191d5SShuanglin Wang 	if (max == 0)
107dd0191d5SShuanglin Wang 		max = 1;
108dd0191d5SShuanglin Wang 
109dd0191d5SShuanglin Wang 	ulp_ctx->cfg_data->max_pools = max;
110dd0191d5SShuanglin Wang 	return 0;
111dd0191d5SShuanglin Wang }
112dd0191d5SShuanglin Wang 
113dd0191d5SShuanglin Wang enum tfc_tbl_scope_bucket_factor
114dd0191d5SShuanglin Wang bnxt_ulp_cntxt_em_mulitplier_get(struct bnxt_ulp_context *ulp_ctx)
115dd0191d5SShuanglin Wang {
116dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
117dd0191d5SShuanglin Wang 		return TFC_TBL_SCOPE_BUCKET_FACTOR_1;
118dd0191d5SShuanglin Wang 
119dd0191d5SShuanglin Wang 	return ulp_ctx->cfg_data->em_multiplier;
120dd0191d5SShuanglin Wang }
121dd0191d5SShuanglin Wang 
122dd0191d5SShuanglin Wang int32_t
123dd0191d5SShuanglin Wang bnxt_ulp_cntxt_em_mulitplier_set(struct bnxt_ulp_context *ulp_ctx,
124dd0191d5SShuanglin Wang 				 enum tfc_tbl_scope_bucket_factor factor)
125dd0191d5SShuanglin Wang {
126dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
127dd0191d5SShuanglin Wang 		return -EINVAL;
128dd0191d5SShuanglin Wang 	ulp_ctx->cfg_data->em_multiplier = factor;
129dd0191d5SShuanglin Wang 	return 0;
130dd0191d5SShuanglin Wang }
131dd0191d5SShuanglin Wang 
132dd0191d5SShuanglin Wang uint32_t
133dd0191d5SShuanglin Wang bnxt_ulp_cntxt_num_rx_flows_get(struct bnxt_ulp_context *ulp_ctx)
134dd0191d5SShuanglin Wang {
135dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
136dd0191d5SShuanglin Wang 		return 0;
137dd0191d5SShuanglin Wang 	return ulp_ctx->cfg_data->num_rx_flows;
138dd0191d5SShuanglin Wang }
139dd0191d5SShuanglin Wang 
140dd0191d5SShuanglin Wang int32_t
141dd0191d5SShuanglin Wang bnxt_ulp_cntxt_num_rx_flows_set(struct bnxt_ulp_context *ulp_ctx, uint32_t num)
142dd0191d5SShuanglin Wang {
143dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
144dd0191d5SShuanglin Wang 		return -EINVAL;
145dd0191d5SShuanglin Wang 	ulp_ctx->cfg_data->num_rx_flows = num;
146dd0191d5SShuanglin Wang 	return 0;
147dd0191d5SShuanglin Wang }
148dd0191d5SShuanglin Wang 
149dd0191d5SShuanglin Wang uint32_t
150dd0191d5SShuanglin Wang bnxt_ulp_cntxt_num_tx_flows_get(struct bnxt_ulp_context *ulp_ctx)
151dd0191d5SShuanglin Wang {
152dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
153dd0191d5SShuanglin Wang 		return 0;
154dd0191d5SShuanglin Wang 	return ulp_ctx->cfg_data->num_tx_flows;
155dd0191d5SShuanglin Wang }
156dd0191d5SShuanglin Wang 
157dd0191d5SShuanglin Wang int32_t
158dd0191d5SShuanglin Wang bnxt_ulp_cntxt_num_tx_flows_set(struct bnxt_ulp_context *ulp_ctx, uint32_t num)
159dd0191d5SShuanglin Wang {
160dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
161dd0191d5SShuanglin Wang 		return -EINVAL;
162dd0191d5SShuanglin Wang 	ulp_ctx->cfg_data->num_tx_flows = num;
163dd0191d5SShuanglin Wang 	return 0;
164dd0191d5SShuanglin Wang }
165dd0191d5SShuanglin Wang 
166dd0191d5SShuanglin Wang uint16_t
167dd0191d5SShuanglin Wang bnxt_ulp_cntxt_em_rx_key_max_sz_get(struct bnxt_ulp_context *ulp_ctx)
168dd0191d5SShuanglin Wang {
169dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
170dd0191d5SShuanglin Wang 		return 0;
171dd0191d5SShuanglin Wang 	return ulp_ctx->cfg_data->em_rx_key_max_sz;
172dd0191d5SShuanglin Wang }
173dd0191d5SShuanglin Wang 
174dd0191d5SShuanglin Wang int32_t
175dd0191d5SShuanglin Wang bnxt_ulp_cntxt_em_rx_key_max_sz_set(struct bnxt_ulp_context *ulp_ctx,
176dd0191d5SShuanglin Wang 				    uint16_t max)
177dd0191d5SShuanglin Wang {
178dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
179dd0191d5SShuanglin Wang 		return -EINVAL;
180dd0191d5SShuanglin Wang 
181dd0191d5SShuanglin Wang 	ulp_ctx->cfg_data->em_rx_key_max_sz = max;
182dd0191d5SShuanglin Wang 	return 0;
183dd0191d5SShuanglin Wang }
184dd0191d5SShuanglin Wang 
185dd0191d5SShuanglin Wang uint16_t
186dd0191d5SShuanglin Wang bnxt_ulp_cntxt_em_tx_key_max_sz_get(struct bnxt_ulp_context *ulp_ctx)
187dd0191d5SShuanglin Wang {
188dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
189dd0191d5SShuanglin Wang 		return 0;
190dd0191d5SShuanglin Wang 	return ulp_ctx->cfg_data->em_tx_key_max_sz;
191dd0191d5SShuanglin Wang }
192dd0191d5SShuanglin Wang 
193dd0191d5SShuanglin Wang int32_t
194dd0191d5SShuanglin Wang bnxt_ulp_cntxt_em_tx_key_max_sz_set(struct bnxt_ulp_context *ulp_ctx,
195dd0191d5SShuanglin Wang 				    uint16_t max)
196dd0191d5SShuanglin Wang {
197dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
198dd0191d5SShuanglin Wang 		return -EINVAL;
199dd0191d5SShuanglin Wang 
200dd0191d5SShuanglin Wang 	ulp_ctx->cfg_data->em_tx_key_max_sz = max;
201dd0191d5SShuanglin Wang 	return 0;
202dd0191d5SShuanglin Wang }
203dd0191d5SShuanglin Wang 
204dd0191d5SShuanglin Wang uint16_t
205dd0191d5SShuanglin Wang bnxt_ulp_cntxt_act_rec_rx_max_sz_get(struct bnxt_ulp_context *ulp_ctx)
206dd0191d5SShuanglin Wang {
207dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
208dd0191d5SShuanglin Wang 		return 0;
209dd0191d5SShuanglin Wang 	return ulp_ctx->cfg_data->act_rx_max_sz;
210dd0191d5SShuanglin Wang }
211dd0191d5SShuanglin Wang 
212dd0191d5SShuanglin Wang int32_t
213dd0191d5SShuanglin Wang bnxt_ulp_cntxt_act_rec_rx_max_sz_set(struct bnxt_ulp_context *ulp_ctx,
214dd0191d5SShuanglin Wang 				     int16_t max)
215dd0191d5SShuanglin Wang {
216dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
217dd0191d5SShuanglin Wang 		return -EINVAL;
218dd0191d5SShuanglin Wang 
219dd0191d5SShuanglin Wang 	ulp_ctx->cfg_data->act_rx_max_sz = max;
220dd0191d5SShuanglin Wang 	return 0;
221dd0191d5SShuanglin Wang }
222dd0191d5SShuanglin Wang 
223dd0191d5SShuanglin Wang uint16_t
224dd0191d5SShuanglin Wang bnxt_ulp_cntxt_act_rec_tx_max_sz_get(struct bnxt_ulp_context *ulp_ctx)
225dd0191d5SShuanglin Wang {
226dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
227dd0191d5SShuanglin Wang 		return 0;
228dd0191d5SShuanglin Wang 	return ulp_ctx->cfg_data->act_tx_max_sz;
229dd0191d5SShuanglin Wang }
230dd0191d5SShuanglin Wang 
231dd0191d5SShuanglin Wang int32_t
232dd0191d5SShuanglin Wang bnxt_ulp_cntxt_act_rec_tx_max_sz_set(struct bnxt_ulp_context *ulp_ctx,
233dd0191d5SShuanglin Wang 				     int16_t max)
234dd0191d5SShuanglin Wang {
235dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
236dd0191d5SShuanglin Wang 		return -EINVAL;
237dd0191d5SShuanglin Wang 
238dd0191d5SShuanglin Wang 	ulp_ctx->cfg_data->act_tx_max_sz = max;
239dd0191d5SShuanglin Wang 	return 0;
240dd0191d5SShuanglin Wang }
241dd0191d5SShuanglin Wang 
242dd0191d5SShuanglin Wang uint32_t
243dd0191d5SShuanglin Wang bnxt_ulp_cntxt_page_sz_get(struct bnxt_ulp_context *ulp_ctx)
244dd0191d5SShuanglin Wang {
245dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL)
246dd0191d5SShuanglin Wang 		return 0;
247dd0191d5SShuanglin Wang 
248dd0191d5SShuanglin Wang 	return ulp_ctx->cfg_data->page_sz;
249dd0191d5SShuanglin Wang }
250dd0191d5SShuanglin Wang 
251dd0191d5SShuanglin Wang int32_t
252dd0191d5SShuanglin Wang bnxt_ulp_cntxt_page_sz_set(struct bnxt_ulp_context *ulp_ctx,
253dd0191d5SShuanglin Wang 			   uint32_t page_sz)
254dd0191d5SShuanglin Wang {
255dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL)
256dd0191d5SShuanglin Wang 		return -EINVAL;
257dd0191d5SShuanglin Wang 	ulp_ctx->cfg_data->page_sz = page_sz;
258dd0191d5SShuanglin Wang 	return 0;
259dd0191d5SShuanglin Wang }
260dd0191d5SShuanglin Wang 
261dd0191d5SShuanglin Wang static int32_t
262dd0191d5SShuanglin Wang ulp_tfc_dparms_init(struct bnxt *bp,
263dd0191d5SShuanglin Wang 		    struct bnxt_ulp_context *ulp_ctx,
264dd0191d5SShuanglin Wang 		    uint32_t dev_id)
265dd0191d5SShuanglin Wang {
266dd0191d5SShuanglin Wang 	struct bnxt_ulp_device_params *dparms;
267dd0191d5SShuanglin Wang 	uint32_t num_flows = 0, num_rx_flows = 0, num_tx_flows = 0;
268dd0191d5SShuanglin Wang 
269dd0191d5SShuanglin Wang 	/* The max_num_kflows were set, so move to external */
270dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_mem_type_set(ulp_ctx, BNXT_ULP_FLOW_MEM_TYPE_EXT))
271dd0191d5SShuanglin Wang 		return -EINVAL;
272dd0191d5SShuanglin Wang 
273dd0191d5SShuanglin Wang 	dparms = bnxt_ulp_device_params_get(dev_id);
274dd0191d5SShuanglin Wang 	if (!dparms) {
275dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Failed to get device parms\n");
276dd0191d5SShuanglin Wang 		return -EINVAL;
277dd0191d5SShuanglin Wang 	}
278dd0191d5SShuanglin Wang 
279dd0191d5SShuanglin Wang 	if (bp->max_num_kflows) {
280dd0191d5SShuanglin Wang 		num_flows = bp->max_num_kflows * 1024;
281dd0191d5SShuanglin Wang 		dparms->ext_flow_db_num_entries = bp->max_num_kflows * 1024;
282dd0191d5SShuanglin Wang 	} else {
283dd0191d5SShuanglin Wang 		num_rx_flows = bnxt_ulp_cntxt_num_rx_flows_get(ulp_ctx);
284dd0191d5SShuanglin Wang 		num_tx_flows = bnxt_ulp_cntxt_num_tx_flows_get(ulp_ctx);
285dd0191d5SShuanglin Wang 		num_flows = num_rx_flows + num_tx_flows;
286dd0191d5SShuanglin Wang 	}
287dd0191d5SShuanglin Wang 
288dd0191d5SShuanglin Wang 	dparms->ext_flow_db_num_entries = num_flows;
289dd0191d5SShuanglin Wang 
290dd0191d5SShuanglin Wang 	/* GFID =  2 * num_flows */
291dd0191d5SShuanglin Wang 	dparms->mark_db_gfid_entries = dparms->ext_flow_db_num_entries * 2;
292dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "Set the number of flows = %" PRIu64 "\n",
293dd0191d5SShuanglin Wang 		    dparms->ext_flow_db_num_entries);
294dd0191d5SShuanglin Wang 
295dd0191d5SShuanglin Wang 	return 0;
296dd0191d5SShuanglin Wang }
297dd0191d5SShuanglin Wang 
298dd0191d5SShuanglin Wang static void
299dd0191d5SShuanglin Wang ulp_tfc_tbl_scope_deinit(struct bnxt *bp)
300dd0191d5SShuanglin Wang {
301dd0191d5SShuanglin Wang 	uint16_t fid = 0, fid_cnt = 0;
302dd0191d5SShuanglin Wang 	struct tfc *tfcp;
303dd0191d5SShuanglin Wang 	uint8_t tsid = 0;
304dd0191d5SShuanglin Wang 	int32_t rc;
305dd0191d5SShuanglin Wang 
306dd0191d5SShuanglin Wang 	tfcp = bnxt_ulp_cntxt_tfcp_get(bp->ulp_ctx);
307dd0191d5SShuanglin Wang 	if (tfcp == NULL)
308dd0191d5SShuanglin Wang 		return;
309dd0191d5SShuanglin Wang 
310dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_tsid_get(bp->ulp_ctx, &tsid);
311dd0191d5SShuanglin Wang 
312dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_fid_get(bp->ulp_ctx, &fid);
313dd0191d5SShuanglin Wang 	if (rc)
314dd0191d5SShuanglin Wang 		return;
315dd0191d5SShuanglin Wang 
316dd0191d5SShuanglin Wang 	rc = tfc_tbl_scope_cpm_free(tfcp, tsid);
317dd0191d5SShuanglin Wang 	if (rc)
318dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed Freeing CPM TSID:%d FID:%d\n",
319dd0191d5SShuanglin Wang 			     tsid, fid);
320dd0191d5SShuanglin Wang 	else
321dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Freed CPM TSID:%d FID: %d\n", tsid, fid);
322dd0191d5SShuanglin Wang 
323dd0191d5SShuanglin Wang 	rc = tfc_tbl_scope_mem_free(tfcp, fid, tsid);
324dd0191d5SShuanglin Wang 	if (rc)
325dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed freeing tscope mem TSID:%d FID:%d\n",
326dd0191d5SShuanglin Wang 			     tsid, fid);
327dd0191d5SShuanglin Wang 	else
328dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Freed tscope mem TSID:%d FID:%d\n",
329dd0191d5SShuanglin Wang 			     tsid, fid);
330dd0191d5SShuanglin Wang 
331dd0191d5SShuanglin Wang 	rc = tfc_tbl_scope_fid_rem(tfcp, fid, tsid, &fid_cnt);
332dd0191d5SShuanglin Wang 	if (rc)
333dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed removing FID from TSID:%d FID:%d\n",
334dd0191d5SShuanglin Wang 			     tsid, fid);
335dd0191d5SShuanglin Wang 	else
336dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Removed FID from TSID:%d FID:%d\n",
337dd0191d5SShuanglin Wang 			     tsid, fid);
338dd0191d5SShuanglin Wang }
339dd0191d5SShuanglin Wang 
340dd0191d5SShuanglin Wang static int32_t
341dd0191d5SShuanglin Wang ulp_tfc_tbl_scope_init(struct bnxt *bp)
342dd0191d5SShuanglin Wang {
343dd0191d5SShuanglin Wang 	struct tfc_tbl_scope_mem_alloc_parms mem_parms;
344dd0191d5SShuanglin Wang 	struct tfc_tbl_scope_size_query_parms qparms =  { 0 };
345be4732e8SMike Baucom 	uint16_t max_lkup_sz[CFA_DIR_MAX], max_act_sz[CFA_DIR_MAX];
346dd0191d5SShuanglin Wang 	struct tfc_tbl_scope_cpm_alloc_parms cparms;
347dd0191d5SShuanglin Wang 	uint16_t fid, max_pools;
348dd0191d5SShuanglin Wang 	bool first = true, shared = false;
349dd0191d5SShuanglin Wang 	uint8_t tsid = 0;
350dd0191d5SShuanglin Wang 	struct tfc *tfcp;
351dd0191d5SShuanglin Wang 	int32_t rc = 0;
352dd0191d5SShuanglin Wang 
353dd0191d5SShuanglin Wang 	tfcp = bnxt_ulp_cntxt_tfcp_get(bp->ulp_ctx);
354dd0191d5SShuanglin Wang 	if (tfcp == NULL)
355dd0191d5SShuanglin Wang 		return -EINVAL;
356dd0191d5SShuanglin Wang 
357dd0191d5SShuanglin Wang 	fid = bp->fw_fid;
358dd0191d5SShuanglin Wang 
359dd0191d5SShuanglin Wang 	max_pools = bnxt_ulp_cntxt_tbl_scope_max_pools_get(bp->ulp_ctx);
360dd0191d5SShuanglin Wang 	max_lkup_sz[CFA_DIR_RX] =
361dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_em_rx_key_max_sz_get(bp->ulp_ctx);
362dd0191d5SShuanglin Wang 	max_lkup_sz[CFA_DIR_TX] =
363dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_em_tx_key_max_sz_get(bp->ulp_ctx);
364dd0191d5SShuanglin Wang 	max_act_sz[CFA_DIR_RX] =
365dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_act_rec_rx_max_sz_get(bp->ulp_ctx);
366dd0191d5SShuanglin Wang 	max_act_sz[CFA_DIR_TX] =
367dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_act_rec_tx_max_sz_get(bp->ulp_ctx);
368dd0191d5SShuanglin Wang 
369dd0191d5SShuanglin Wang 	shared = bnxt_ulp_cntxt_shared_tbl_scope_enabled(bp->ulp_ctx);
370dd0191d5SShuanglin Wang 
371dd0191d5SShuanglin Wang #if (TFC_SHARED_TBL_SCOPE_ENABLE == 1)
372dd0191d5SShuanglin Wang 	/* Temporary code for testing shared table scopes until ULP
373dd0191d5SShuanglin Wang 	 * usage defined.
374dd0191d5SShuanglin Wang 	 */
375dd0191d5SShuanglin Wang 	if (!BNXT_PF(bp)) {
376dd0191d5SShuanglin Wang 		shared = true;
377dd0191d5SShuanglin Wang 		max_pools = 8;
378dd0191d5SShuanglin Wang 	}
379dd0191d5SShuanglin Wang #endif
380dd0191d5SShuanglin Wang 	/* Calculate the sizes for setting up memory */
381dd0191d5SShuanglin Wang 	qparms.shared = shared;
382dd0191d5SShuanglin Wang 	qparms.max_pools = max_pools;
383dd0191d5SShuanglin Wang 	qparms.factor = bnxt_ulp_cntxt_em_mulitplier_get(bp->ulp_ctx);
384dd0191d5SShuanglin Wang 	qparms.flow_cnt[CFA_DIR_RX] =
385dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_num_rx_flows_get(bp->ulp_ctx);
386dd0191d5SShuanglin Wang 	qparms.flow_cnt[CFA_DIR_TX] =
387dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_num_tx_flows_get(bp->ulp_ctx);
388dd0191d5SShuanglin Wang 	qparms.key_sz_in_bytes[CFA_DIR_RX] = max_lkup_sz[CFA_DIR_RX];
389dd0191d5SShuanglin Wang 	qparms.key_sz_in_bytes[CFA_DIR_TX] = max_lkup_sz[CFA_DIR_TX];
390dd0191d5SShuanglin Wang 	qparms.act_rec_sz_in_bytes[CFA_DIR_RX] = max_act_sz[CFA_DIR_RX];
391dd0191d5SShuanglin Wang 	qparms.act_rec_sz_in_bytes[CFA_DIR_TX] = max_act_sz[CFA_DIR_TX];
392dd0191d5SShuanglin Wang 	rc = tfc_tbl_scope_size_query(tfcp, &qparms);
393dd0191d5SShuanglin Wang 	if (rc)
394dd0191d5SShuanglin Wang 		return rc;
395dd0191d5SShuanglin Wang 
396dd0191d5SShuanglin Wang 
397dd0191d5SShuanglin Wang 
398dd0191d5SShuanglin Wang 	rc = tfc_tbl_scope_id_alloc(tfcp, shared, CFA_APP_TYPE_TF, &tsid,
399dd0191d5SShuanglin Wang 				    &first);
400dd0191d5SShuanglin Wang 	if (rc) {
401dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to allocate tscope\n");
402dd0191d5SShuanglin Wang 		return rc;
403dd0191d5SShuanglin Wang 	}
404dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "Allocated tscope TSID:%d\n", tsid);
405dd0191d5SShuanglin Wang 
406dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_tsid_set(bp->ulp_ctx, tsid);
407dd0191d5SShuanglin Wang 	if (rc)
408dd0191d5SShuanglin Wang 		return rc;
409dd0191d5SShuanglin Wang 
410dd0191d5SShuanglin Wang 	/* If we are shared and not the first table scope creator
411dd0191d5SShuanglin Wang 	 */
412dd0191d5SShuanglin Wang 	if (shared && !first) {
413dd0191d5SShuanglin Wang 		bool configured;
414dd0191d5SShuanglin Wang 		#define ULP_SHARED_TSID_WAIT_TIMEOUT 5000
415dd0191d5SShuanglin Wang 		#define ULP_SHARED_TSID_WAIT_TIME 50
416dd0191d5SShuanglin Wang 		int32_t timeout = ULP_SHARED_TSID_WAIT_TIMEOUT;
417dd0191d5SShuanglin Wang 		do {
418dd0191d5SShuanglin Wang 			rte_delay_ms(ULP_SHARED_TSID_WAIT_TIME);
419dd0191d5SShuanglin Wang 			rc = tfc_tbl_scope_config_state_get(tfcp, tsid, &configured);
420dd0191d5SShuanglin Wang 			if (rc) {
421dd0191d5SShuanglin Wang 				BNXT_DRV_DBG(ERR,
422dd0191d5SShuanglin Wang 					     "Failed get tsid(%d) config state\n",
423dd0191d5SShuanglin Wang 					     rc);
424dd0191d5SShuanglin Wang 				return rc;
425dd0191d5SShuanglin Wang 			}
426dd0191d5SShuanglin Wang 			timeout -= ULP_SHARED_TSID_WAIT_TIME;
427dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(INFO,
428dd0191d5SShuanglin Wang 				     "Waiting %d ms for shared tsid(%d)\n",
429dd0191d5SShuanglin Wang 				     timeout, tsid);
430dd0191d5SShuanglin Wang 		} while (!configured && timeout > 0);
431dd0191d5SShuanglin Wang 		if (timeout <= 0) {
432dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR, "Timed out on shared tsid(%d)\n",
433dd0191d5SShuanglin Wang 				     tsid);
434dd0191d5SShuanglin Wang 			return -ETIMEDOUT;
435dd0191d5SShuanglin Wang 		}
436dd0191d5SShuanglin Wang 	}
437dd0191d5SShuanglin Wang 	mem_parms.first = first;
438dd0191d5SShuanglin Wang 	mem_parms.static_bucket_cnt_exp[CFA_DIR_RX] =
439dd0191d5SShuanglin Wang 		qparms.static_bucket_cnt_exp[CFA_DIR_RX];
440dd0191d5SShuanglin Wang 	mem_parms.static_bucket_cnt_exp[CFA_DIR_TX] =
441dd0191d5SShuanglin Wang 		qparms.static_bucket_cnt_exp[CFA_DIR_TX];
442dd0191d5SShuanglin Wang 	mem_parms.lkup_rec_cnt[CFA_DIR_RX] = qparms.lkup_rec_cnt[CFA_DIR_RX];
443dd0191d5SShuanglin Wang 	mem_parms.lkup_rec_cnt[CFA_DIR_TX] = qparms.lkup_rec_cnt[CFA_DIR_TX];
444dd0191d5SShuanglin Wang 	mem_parms.act_rec_cnt[CFA_DIR_RX] = qparms.act_rec_cnt[CFA_DIR_RX];
445dd0191d5SShuanglin Wang 	mem_parms.act_rec_cnt[CFA_DIR_TX] = qparms.act_rec_cnt[CFA_DIR_TX];
446dd0191d5SShuanglin Wang 	mem_parms.pbl_page_sz_in_bytes =
447dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_page_sz_get(bp->ulp_ctx);
448dd0191d5SShuanglin Wang 	mem_parms.max_pools = max_pools;
449dd0191d5SShuanglin Wang 
450dd0191d5SShuanglin Wang 	mem_parms.lkup_pool_sz_exp[CFA_DIR_RX] =
451dd0191d5SShuanglin Wang 		qparms.lkup_pool_sz_exp[CFA_DIR_RX];
452dd0191d5SShuanglin Wang 	mem_parms.lkup_pool_sz_exp[CFA_DIR_TX] =
453dd0191d5SShuanglin Wang 		qparms.lkup_pool_sz_exp[CFA_DIR_TX];
454dd0191d5SShuanglin Wang 
455dd0191d5SShuanglin Wang 	mem_parms.act_pool_sz_exp[CFA_DIR_RX] =
456dd0191d5SShuanglin Wang 		qparms.act_pool_sz_exp[CFA_DIR_RX];
457dd0191d5SShuanglin Wang 	mem_parms.act_pool_sz_exp[CFA_DIR_TX] =
458dd0191d5SShuanglin Wang 		qparms.act_pool_sz_exp[CFA_DIR_TX];
459dd0191d5SShuanglin Wang 	mem_parms.local = true;
460dd0191d5SShuanglin Wang 	rc = tfc_tbl_scope_mem_alloc(tfcp, fid, tsid, &mem_parms);
461dd0191d5SShuanglin Wang 	if (rc) {
462dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR,
463dd0191d5SShuanglin Wang 			     "Failed to allocate tscope mem TSID:%d on FID:%d\n",
464dd0191d5SShuanglin Wang 			     tsid, fid);
465dd0191d5SShuanglin Wang 		return rc;
466dd0191d5SShuanglin Wang 		}
467dd0191d5SShuanglin Wang 
468dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "Allocated or set tscope mem TSID:%d on FID:%d\n",
469dd0191d5SShuanglin Wang 		     tsid, fid);
470dd0191d5SShuanglin Wang 
471dd0191d5SShuanglin Wang 
472dd0191d5SShuanglin Wang 	/* The max contiguous is in 32 Bytes records, so convert Bytes to 32
473dd0191d5SShuanglin Wang 	 * Byte records.
474dd0191d5SShuanglin Wang 	 */
475dd0191d5SShuanglin Wang 	cparms.lkup_max_contig_rec[CFA_DIR_RX] = (max_lkup_sz[CFA_DIR_RX] + 31) / 32;
476dd0191d5SShuanglin Wang 	cparms.lkup_max_contig_rec[CFA_DIR_TX] = (max_lkup_sz[CFA_DIR_TX] + 31) / 32;
477dd0191d5SShuanglin Wang 	cparms.act_max_contig_rec[CFA_DIR_RX] = (max_act_sz[CFA_DIR_RX] + 31) / 32;
478dd0191d5SShuanglin Wang 	cparms.act_max_contig_rec[CFA_DIR_TX] = (max_act_sz[CFA_DIR_TX] + 31) / 32;
479dd0191d5SShuanglin Wang 	cparms.max_pools = max_pools;
480dd0191d5SShuanglin Wang 
481dd0191d5SShuanglin Wang 	rc = tfc_tbl_scope_cpm_alloc(tfcp, tsid, &cparms);
482dd0191d5SShuanglin Wang 	if (rc)
483dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to allocate CPM TSID:%d FID:%d\n",
484dd0191d5SShuanglin Wang 			     tsid, fid);
485dd0191d5SShuanglin Wang 	else
486dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Allocated CPM TSID:%d FID:%d\n", tsid, fid);
487dd0191d5SShuanglin Wang 
488dd0191d5SShuanglin Wang 	return rc;
489dd0191d5SShuanglin Wang }
490dd0191d5SShuanglin Wang 
491dd0191d5SShuanglin Wang static int32_t
492dd0191d5SShuanglin Wang ulp_tfc_cntxt_app_caps_init(struct bnxt *bp, uint8_t app_id, uint32_t dev_id)
493dd0191d5SShuanglin Wang {
494dd0191d5SShuanglin Wang 	struct bnxt_ulp_app_capabilities_info *info;
495dd0191d5SShuanglin Wang 	struct bnxt_ulp_context *ulp_ctx = bp->ulp_ctx;
496dd0191d5SShuanglin Wang 	uint32_t num = 0, rc;
497dd0191d5SShuanglin Wang 	bool found = false;
498dd0191d5SShuanglin Wang 	uint16_t i;
499dd0191d5SShuanglin Wang 
500dd0191d5SShuanglin Wang 	if (ULP_APP_DEV_UNSUPPORTED_ENABLED(ulp_ctx->cfg_data->ulp_flags)) {
501dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
502dd0191d5SShuanglin Wang 			    app_id, dev_id);
503dd0191d5SShuanglin Wang 		return -EINVAL;
504dd0191d5SShuanglin Wang 	}
505dd0191d5SShuanglin Wang 
506dd0191d5SShuanglin Wang 	info = bnxt_ulp_app_cap_list_get(&num);
507dd0191d5SShuanglin Wang 	if (!info || !num) {
508dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to get app capabilities.\n");
509dd0191d5SShuanglin Wang 		return -EINVAL;
510dd0191d5SShuanglin Wang 	}
511dd0191d5SShuanglin Wang 
512dd0191d5SShuanglin Wang 	for (i = 0; i < num && !found; i++) {
513dd0191d5SShuanglin Wang 		if (info[i].app_id != app_id || info[i].device_id != dev_id)
514dd0191d5SShuanglin Wang 			continue;
515dd0191d5SShuanglin Wang 		found = true;
516dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_SHARED_EN)
517dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
518dd0191d5SShuanglin Wang 				BNXT_ULP_SHARED_SESSION_ENABLED;
519dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_HOT_UPGRADE_EN)
520dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
521dd0191d5SShuanglin Wang 				BNXT_ULP_HIGH_AVAIL_ENABLED;
522dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_UNICAST_ONLY)
523dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
524dd0191d5SShuanglin Wang 				BNXT_ULP_APP_UNICAST_ONLY;
525dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_IP_TOS_PROTO_SUPPORT)
526dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
527dd0191d5SShuanglin Wang 				BNXT_ULP_APP_TOS_PROTO_SUPPORT;
528dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_BC_MC_SUPPORT)
529dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
530dd0191d5SShuanglin Wang 				BNXT_ULP_APP_BC_MC_SUPPORT;
531dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_SOCKET_DIRECT) {
532dd0191d5SShuanglin Wang 			/* Enable socket direction only if MR is enabled in fw*/
533dd0191d5SShuanglin Wang 			if (BNXT_MULTIROOT_EN(bp)) {
534dd0191d5SShuanglin Wang 				ulp_ctx->cfg_data->ulp_flags |=
535dd0191d5SShuanglin Wang 					BNXT_ULP_APP_SOCKET_DIRECT;
536dd0191d5SShuanglin Wang 				BNXT_DRV_DBG(DEBUG,
537dd0191d5SShuanglin Wang 					    "Socket Direct feature is enabled\n");
538dd0191d5SShuanglin Wang 			}
539dd0191d5SShuanglin Wang 		}
540b413ab0aSKishore Padmanabha 		/* Update the capability feature bits*/
541b413ab0aSKishore Padmanabha 		if (bnxt_ulp_cap_feat_process(info[i].feature_bits,
542b413ab0aSKishore Padmanabha 					      &ulp_ctx->cfg_data->feature_bits))
543b413ab0aSKishore Padmanabha 			return -EINVAL;
544b413ab0aSKishore Padmanabha 
54530d7102dSKishore Padmanabha 		bnxt_ulp_default_app_priority_set(ulp_ctx,
54630d7102dSKishore Padmanabha 						  info[i].default_priority);
54730d7102dSKishore Padmanabha 		bnxt_ulp_max_def_priority_set(ulp_ctx,
54830d7102dSKishore Padmanabha 					      info[i].max_def_priority);
54930d7102dSKishore Padmanabha 		bnxt_ulp_min_flow_priority_set(ulp_ctx,
55030d7102dSKishore Padmanabha 					       info[i].min_flow_priority);
55130d7102dSKishore Padmanabha 		bnxt_ulp_max_flow_priority_set(ulp_ctx,
55230d7102dSKishore Padmanabha 					       info[i].max_flow_priority);
55330d7102dSKishore Padmanabha 
5542aa70990SKishore Padmanabha 		bnxt_ulp_cntxt_ptr2_default_class_bits_set(ulp_ctx,
5552aa70990SKishore Padmanabha 							   info[i].default_class_bits);
5562aa70990SKishore Padmanabha 		bnxt_ulp_cntxt_ptr2_default_act_bits_set(ulp_ctx,
5572aa70990SKishore Padmanabha 							 info[i].default_act_bits);
558dd0191d5SShuanglin Wang 
559dd0191d5SShuanglin Wang 		rc = bnxt_ulp_cntxt_tbl_scope_max_pools_set(ulp_ctx,
560dd0191d5SShuanglin Wang 							    info[i].max_pools);
561dd0191d5SShuanglin Wang 		if (rc)
562dd0191d5SShuanglin Wang 			return rc;
563dd0191d5SShuanglin Wang 		rc = bnxt_ulp_cntxt_em_mulitplier_set(ulp_ctx,
564dd0191d5SShuanglin Wang 						      info[i].em_multiplier);
565dd0191d5SShuanglin Wang 		if (rc)
566dd0191d5SShuanglin Wang 			return rc;
567dd0191d5SShuanglin Wang 
568dd0191d5SShuanglin Wang 		rc = bnxt_ulp_cntxt_num_rx_flows_set(ulp_ctx,
569dd0191d5SShuanglin Wang 						     info[i].num_rx_flows);
570dd0191d5SShuanglin Wang 		if (rc)
571dd0191d5SShuanglin Wang 			return rc;
572dd0191d5SShuanglin Wang 
573dd0191d5SShuanglin Wang 		rc = bnxt_ulp_cntxt_num_tx_flows_set(ulp_ctx,
574dd0191d5SShuanglin Wang 						     info[i].num_tx_flows);
575dd0191d5SShuanglin Wang 		if (rc)
576dd0191d5SShuanglin Wang 			return rc;
577dd0191d5SShuanglin Wang 
578dd0191d5SShuanglin Wang 		rc = bnxt_ulp_cntxt_em_rx_key_max_sz_set(ulp_ctx,
579dd0191d5SShuanglin Wang 							 info[i].em_rx_key_max_sz);
580dd0191d5SShuanglin Wang 		if (rc)
581dd0191d5SShuanglin Wang 			return rc;
582dd0191d5SShuanglin Wang 
583dd0191d5SShuanglin Wang 		rc = bnxt_ulp_cntxt_em_tx_key_max_sz_set(ulp_ctx,
584dd0191d5SShuanglin Wang 							 info[i].em_tx_key_max_sz);
585dd0191d5SShuanglin Wang 		if (rc)
586dd0191d5SShuanglin Wang 			return rc;
587dd0191d5SShuanglin Wang 
588dd0191d5SShuanglin Wang 		rc = bnxt_ulp_cntxt_act_rec_rx_max_sz_set(ulp_ctx,
589dd0191d5SShuanglin Wang 							  info[i].act_rx_max_sz);
590dd0191d5SShuanglin Wang 		if (rc)
591dd0191d5SShuanglin Wang 			return rc;
592dd0191d5SShuanglin Wang 
593dd0191d5SShuanglin Wang 		rc = bnxt_ulp_cntxt_act_rec_tx_max_sz_set(ulp_ctx,
594dd0191d5SShuanglin Wang 							  info[i].act_tx_max_sz);
595dd0191d5SShuanglin Wang 		if (rc)
596dd0191d5SShuanglin Wang 			return rc;
597dd0191d5SShuanglin Wang 
598dd0191d5SShuanglin Wang 		rc = bnxt_ulp_cntxt_page_sz_set(ulp_ctx,
599dd0191d5SShuanglin Wang 						info[i].pbl_page_sz_in_bytes);
600dd0191d5SShuanglin Wang 		if (rc)
601dd0191d5SShuanglin Wang 			return rc;
602dd0191d5SShuanglin Wang 		bnxt_ulp_num_key_recipes_set(ulp_ctx,
603dd0191d5SShuanglin Wang 					     info[i].num_key_recipes_per_dir);
604dd0191d5SShuanglin Wang 	}
605dd0191d5SShuanglin Wang 	if (!found) {
606dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
607dd0191d5SShuanglin Wang 			    app_id, dev_id);
608dd0191d5SShuanglin Wang 		ulp_ctx->cfg_data->ulp_flags |= BNXT_ULP_APP_DEV_UNSUPPORTED;
609dd0191d5SShuanglin Wang 		return -EINVAL;
610dd0191d5SShuanglin Wang 	}
611dd0191d5SShuanglin Wang 
612dd0191d5SShuanglin Wang 	return 0;
613dd0191d5SShuanglin Wang }
614dd0191d5SShuanglin Wang 
615dd0191d5SShuanglin Wang /* The function to free and deinit the ulp context data. */
616dd0191d5SShuanglin Wang static int32_t
617dd0191d5SShuanglin Wang ulp_tfc_ctx_deinit(struct bnxt *bp,
618dd0191d5SShuanglin Wang 		   struct bnxt_ulp_session_state *session)
619dd0191d5SShuanglin Wang {
620dd0191d5SShuanglin Wang 	/* Free the contents */
621dd0191d5SShuanglin Wang 	if (session->cfg_data) {
622dd0191d5SShuanglin Wang 		rte_free(session->cfg_data);
623dd0191d5SShuanglin Wang 		bp->ulp_ctx->cfg_data = NULL;
624dd0191d5SShuanglin Wang 		session->cfg_data = NULL;
625dd0191d5SShuanglin Wang 	}
626dd0191d5SShuanglin Wang 	return 0;
627dd0191d5SShuanglin Wang }
628dd0191d5SShuanglin Wang 
629dd0191d5SShuanglin Wang /* The function to allocate and initialize the ulp context data. */
630dd0191d5SShuanglin Wang static int32_t
631dd0191d5SShuanglin Wang ulp_tfc_ctx_init(struct bnxt *bp,
632dd0191d5SShuanglin Wang 		 struct bnxt_ulp_session_state *session)
633dd0191d5SShuanglin Wang {
634dd0191d5SShuanglin Wang 	struct bnxt_ulp_data	*ulp_data;
635dd0191d5SShuanglin Wang 	enum bnxt_ulp_device_id devid;
636dd0191d5SShuanglin Wang 	int32_t	rc = 0;
637dd0191d5SShuanglin Wang 
638dd0191d5SShuanglin Wang 	/* Initialize the context entries list */
639dd0191d5SShuanglin Wang 	bnxt_ulp_cntxt_list_init();
640dd0191d5SShuanglin Wang 
641dd0191d5SShuanglin Wang 	/* Allocate memory to hold ulp context data. */
642dd0191d5SShuanglin Wang 	ulp_data = rte_zmalloc("bnxt_ulp_data",
643dd0191d5SShuanglin Wang 			       sizeof(struct bnxt_ulp_data), 0);
644dd0191d5SShuanglin Wang 	if (!ulp_data) {
645dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to allocate memory for ulp data\n");
646dd0191d5SShuanglin Wang 		return -ENOMEM;
647dd0191d5SShuanglin Wang 	}
648dd0191d5SShuanglin Wang 
649dd0191d5SShuanglin Wang 	/* Increment the ulp context data reference count usage. */
650dd0191d5SShuanglin Wang 	bp->ulp_ctx->cfg_data = ulp_data;
651dd0191d5SShuanglin Wang 	session->cfg_data = ulp_data;
652dd0191d5SShuanglin Wang 	ulp_data->ref_cnt++;
653dd0191d5SShuanglin Wang 	ulp_data->ulp_flags |= BNXT_ULP_VF_REP_ENABLED;
654dd0191d5SShuanglin Wang 
65594dbd6cfSKishore Padmanabha 	/* Add the context to the context entries list */
65694dbd6cfSKishore Padmanabha 	rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx);
65794dbd6cfSKishore Padmanabha 	if (rc) {
65894dbd6cfSKishore Padmanabha 		BNXT_DRV_DBG(ERR, "Failed to add the context list entry\n");
65994dbd6cfSKishore Padmanabha 		goto error_deinit;
66094dbd6cfSKishore Padmanabha 	}
66194dbd6cfSKishore Padmanabha 
662dd0191d5SShuanglin Wang 	rc = bnxt_ulp_devid_get(bp, &devid);
663dd0191d5SShuanglin Wang 	if (rc) {
664dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to determine device for ULP init.\n");
665dd0191d5SShuanglin Wang 		goto error_deinit;
666dd0191d5SShuanglin Wang 	}
667dd0191d5SShuanglin Wang 
668dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_dev_id_set(bp->ulp_ctx, devid);
669dd0191d5SShuanglin Wang 	if (rc) {
670dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to set device for ULP init.\n");
671dd0191d5SShuanglin Wang 		goto error_deinit;
672dd0191d5SShuanglin Wang 	}
673dd0191d5SShuanglin Wang 
674dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_app_id_set(bp->ulp_ctx, bp->app_id);
675dd0191d5SShuanglin Wang 	if (rc) {
676dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to set app_id for ULP init.\n");
677dd0191d5SShuanglin Wang 		goto error_deinit;
678dd0191d5SShuanglin Wang 	}
679dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "Ulp initialized with app id %d\n", bp->app_id);
680dd0191d5SShuanglin Wang 
681dd0191d5SShuanglin Wang 	rc = ulp_tfc_dparms_init(bp, bp->ulp_ctx, devid);
682dd0191d5SShuanglin Wang 	if (rc) {
683dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to init dparms for app(%x)/dev(%x)\n",
684dd0191d5SShuanglin Wang 			    bp->app_id, devid);
685dd0191d5SShuanglin Wang 		goto error_deinit;
686dd0191d5SShuanglin Wang 	}
687dd0191d5SShuanglin Wang 
688dd0191d5SShuanglin Wang 	rc = ulp_tfc_cntxt_app_caps_init(bp, bp->app_id, devid);
689dd0191d5SShuanglin Wang 	if (rc) {
690dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to set caps for app(%x)/dev(%x)\n",
691dd0191d5SShuanglin Wang 			    bp->app_id, devid);
692dd0191d5SShuanglin Wang 		goto error_deinit;
693dd0191d5SShuanglin Wang 	}
694dd0191d5SShuanglin Wang 
695dd0191d5SShuanglin Wang 	if (BNXT_TESTPMD_EN(bp)) {
696dd0191d5SShuanglin Wang 		ulp_data->ulp_flags &= ~BNXT_ULP_VF_REP_ENABLED;
697dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Enabled Testpmd forward mode\n");
698dd0191d5SShuanglin Wang 	}
699dd0191d5SShuanglin Wang 
700dd0191d5SShuanglin Wang 	return rc;
701dd0191d5SShuanglin Wang 
702dd0191d5SShuanglin Wang error_deinit:
703dd0191d5SShuanglin Wang 	session->session_opened[BNXT_ULP_SESSION_TYPE_DEFAULT] = 1;
704dd0191d5SShuanglin Wang 	(void)ulp_tfc_ctx_deinit(bp, session);
705dd0191d5SShuanglin Wang 	return rc;
706dd0191d5SShuanglin Wang }
707dd0191d5SShuanglin Wang 
708dd0191d5SShuanglin Wang static int32_t
709be4732e8SMike Baucom ulp_tfc_vfr_session_fid_add(struct bnxt_ulp_context *ulp_ctx, uint16_t rep_fid)
710be4732e8SMike Baucom {
711be4732e8SMike Baucom 	uint16_t fid_cnt = 0, sid = 0;
712be4732e8SMike Baucom 	struct tfc *tfcp = NULL;
713be4732e8SMike Baucom 	int rc;
714be4732e8SMike Baucom 
715be4732e8SMike Baucom 	tfcp = bnxt_ulp_cntxt_tfcp_get(ulp_ctx);
716be4732e8SMike Baucom 	if (!tfcp) {
717be4732e8SMike Baucom 		PMD_DRV_LOG_LINE(ERR, "Unable to get tfcp from ulp_ctx");
718be4732e8SMike Baucom 		return -EINVAL;
719be4732e8SMike Baucom 	}
720be4732e8SMike Baucom 
721be4732e8SMike Baucom 	/* Get the session id */
722be4732e8SMike Baucom 	rc = bnxt_ulp_cntxt_sid_get(ulp_ctx, &sid);
723be4732e8SMike Baucom 	if (rc) {
724be4732e8SMike Baucom 		PMD_DRV_LOG_LINE(ERR, "Unable to get SID for VFR FID=%d", rep_fid);
725be4732e8SMike Baucom 		return rc;
726be4732e8SMike Baucom 	}
727be4732e8SMike Baucom 
728be4732e8SMike Baucom 	rc = tfc_session_fid_add(tfcp, rep_fid, sid, &fid_cnt);
729be4732e8SMike Baucom 	if (!rc)
730be4732e8SMike Baucom 		PMD_DRV_LOG_LINE(DEBUG,
731be4732e8SMike Baucom 				 "EFID=%d added to SID=%d, %d total",
732be4732e8SMike Baucom 				 rep_fid, sid, fid_cnt);
733be4732e8SMike Baucom 	else
734be4732e8SMike Baucom 		PMD_DRV_LOG_LINE(ERR,
735be4732e8SMike Baucom 				 "Failed to add EFID=%d to SID=%d",
736be4732e8SMike Baucom 				 rep_fid, sid);
737be4732e8SMike Baucom 	return rc;
738be4732e8SMike Baucom }
739be4732e8SMike Baucom 
740be4732e8SMike Baucom static int32_t
741be4732e8SMike Baucom ulp_tfc_vfr_session_fid_rem(struct bnxt_ulp_context *ulp_ctx, uint16_t rep_fid)
742be4732e8SMike Baucom {
743be4732e8SMike Baucom 	uint16_t fid_cnt = 0, sid = 0;
744be4732e8SMike Baucom 	struct tfc *tfcp = NULL;
745be4732e8SMike Baucom 	int rc;
746be4732e8SMike Baucom 
747be4732e8SMike Baucom 	tfcp = bnxt_ulp_cntxt_tfcp_get(ulp_ctx);
748be4732e8SMike Baucom 	if (!tfcp) {
749be4732e8SMike Baucom 		PMD_DRV_LOG_LINE(ERR, "Unable tfcp from ulp_ctx");
750be4732e8SMike Baucom 		return -EINVAL;
751be4732e8SMike Baucom 	}
752be4732e8SMike Baucom 
753be4732e8SMike Baucom 	/* Get the session id */
754be4732e8SMike Baucom 	rc = bnxt_ulp_cntxt_sid_get(ulp_ctx, &sid);
755be4732e8SMike Baucom 	if (rc) {
756be4732e8SMike Baucom 		PMD_DRV_LOG_LINE(ERR, "Unable to get SID for VFR FID=%d", rep_fid);
757be4732e8SMike Baucom 		return rc;
758be4732e8SMike Baucom 	}
759be4732e8SMike Baucom 
760be4732e8SMike Baucom 	rc = tfc_session_fid_rem(tfcp, rep_fid, &fid_cnt);
761be4732e8SMike Baucom 	if (!rc)
762be4732e8SMike Baucom 		PMD_DRV_LOG_LINE(DEBUG,
763be4732e8SMike Baucom 				 "Removed EFID=%d from SID=%d, %d remain",
764be4732e8SMike Baucom 				 rep_fid, sid, fid_cnt);
765be4732e8SMike Baucom 	else
766be4732e8SMike Baucom 		PMD_DRV_LOG_LINE(ERR,
767be4732e8SMike Baucom 				 "Failed to remove EFID=%d from SID=%d",
768be4732e8SMike Baucom 				 rep_fid, sid);
769be4732e8SMike Baucom 
770be4732e8SMike Baucom 	return rc;
771be4732e8SMike Baucom }
772be4732e8SMike Baucom 
773be4732e8SMike Baucom static int32_t
774dd0191d5SShuanglin Wang ulp_tfc_ctx_attach(struct bnxt *bp,
775dd0191d5SShuanglin Wang 		   struct bnxt_ulp_session_state *session)
776dd0191d5SShuanglin Wang {
777dd0191d5SShuanglin Wang 	uint32_t flags, dev_id = BNXT_ULP_DEVICE_ID_LAST;
778dd0191d5SShuanglin Wang 	uint16_t fid_cnt = 0;
779dd0191d5SShuanglin Wang 	int32_t rc = 0;
780dd0191d5SShuanglin Wang 	uint8_t app_id;
781dd0191d5SShuanglin Wang 
782dd0191d5SShuanglin Wang 	bp->tfcp.bp = bp;
783dd0191d5SShuanglin Wang 	rc = tfc_open(&bp->tfcp);
784dd0191d5SShuanglin Wang 	if (rc) {
785dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to initialize the tfc object\n");
786dd0191d5SShuanglin Wang 		return rc;
787dd0191d5SShuanglin Wang 	}
788dd0191d5SShuanglin Wang 
789dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_tfcp_set(bp->ulp_ctx, &bp->tfcp);
790dd0191d5SShuanglin Wang 	if (rc) {
791dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to add tfcp to ulp ctxt\n");
792dd0191d5SShuanglin Wang 		return rc;
793dd0191d5SShuanglin Wang 	}
794dd0191d5SShuanglin Wang 
795be4732e8SMike Baucom 	rc = bnxt_ulp_devid_get(bp, &dev_id);
796be4732e8SMike Baucom 	if (rc) {
797be4732e8SMike Baucom 		BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n");
798be4732e8SMike Baucom 		return rc;
799be4732e8SMike Baucom 	}
800be4732e8SMike Baucom 
801dd0191d5SShuanglin Wang 	/* Increment the ulp context data reference count usage. */
802dd0191d5SShuanglin Wang 	bp->ulp_ctx->cfg_data = session->cfg_data;
803dd0191d5SShuanglin Wang 	bp->ulp_ctx->cfg_data->ref_cnt++;
804dd0191d5SShuanglin Wang 
805dd0191d5SShuanglin Wang 	rc = tfc_session_fid_add(&bp->tfcp, bp->fw_fid,
806dd0191d5SShuanglin Wang 				 session->session_id, &fid_cnt);
807dd0191d5SShuanglin Wang 	if (rc) {
808be4732e8SMike Baucom 		BNXT_DRV_DBG(ERR, "Failed to add RFID:%d to SID:%d.\n",
809dd0191d5SShuanglin Wang 			     bp->fw_fid, session->session_id);
810dd0191d5SShuanglin Wang 		return rc;
811dd0191d5SShuanglin Wang 	}
812be4732e8SMike Baucom 	BNXT_DRV_DBG(DEBUG, "RFID:%d added to SID:%d\n",
813be4732e8SMike Baucom 		     bp->fw_fid, session->session_id);
814dd0191d5SShuanglin Wang 
815dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_sid_set(bp->ulp_ctx, session->session_id);
816dd0191d5SShuanglin Wang 	if (rc) {
817dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to add fid to session.\n");
818dd0191d5SShuanglin Wang 		return rc;
819dd0191d5SShuanglin Wang 	}
820dd0191d5SShuanglin Wang 
821dd0191d5SShuanglin Wang 	/* Add the context to the context entries list */
822dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx);
823dd0191d5SShuanglin Wang 	if (rc) {
824dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to add the context list entry\n");
825dd0191d5SShuanglin Wang 		return -EINVAL;
826dd0191d5SShuanglin Wang 	}
827dd0191d5SShuanglin Wang 
828dd0191d5SShuanglin Wang 	/*
829dd0191d5SShuanglin Wang 	 * The supported flag will be set during the init. Use it now to
830dd0191d5SShuanglin Wang 	 * know if we should go through the attach.
831dd0191d5SShuanglin Wang 	 */
832dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id);
833dd0191d5SShuanglin Wang 	if (rc) {
834dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the app id from ulp.\n");
835dd0191d5SShuanglin Wang 		return -EINVAL;
836dd0191d5SShuanglin Wang 	}
837dd0191d5SShuanglin Wang 	flags = bp->ulp_ctx->cfg_data->ulp_flags;
838dd0191d5SShuanglin Wang 	if (ULP_APP_DEV_UNSUPPORTED_ENABLED(flags)) {
839dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
840dd0191d5SShuanglin Wang 			    app_id, dev_id);
841dd0191d5SShuanglin Wang 		return -EINVAL;
842dd0191d5SShuanglin Wang 	}
843dd0191d5SShuanglin Wang 
844dd0191d5SShuanglin Wang 	rc = ulp_tfc_tbl_scope_init(bp);
845dd0191d5SShuanglin Wang 
846dd0191d5SShuanglin Wang 	return rc;
847dd0191d5SShuanglin Wang }
848dd0191d5SShuanglin Wang 
849dd0191d5SShuanglin Wang static void
850dd0191d5SShuanglin Wang ulp_tfc_ctx_detach(struct bnxt *bp,
851dd0191d5SShuanglin Wang 		   struct bnxt_ulp_session_state *session)
852dd0191d5SShuanglin Wang {
853dd0191d5SShuanglin Wang 	uint16_t fid_cnt = 0;
854dd0191d5SShuanglin Wang 	int32_t rc;
855dd0191d5SShuanglin Wang 
856dd0191d5SShuanglin Wang 	ulp_tfc_tbl_scope_deinit(bp);
857dd0191d5SShuanglin Wang 
858dd0191d5SShuanglin Wang 	rc = tfc_session_fid_rem(&bp->tfcp, bp->fw_fid, &fid_cnt);
859dd0191d5SShuanglin Wang 	if (rc)
860be4732e8SMike Baucom 		BNXT_DRV_DBG(ERR, "Failed to remove RFID:%d from SID:%d\n",
861dd0191d5SShuanglin Wang 			     bp->fw_fid, session->session_id);
862dd0191d5SShuanglin Wang 	else
863be4732e8SMike Baucom 		BNXT_DRV_DBG(DEBUG, "Removed RFID:%d from SID:%d CNT:%d\n",
864be4732e8SMike Baucom 			     bp->fw_fid, session->session_id, fid_cnt);
865dd0191d5SShuanglin Wang 	bnxt_ulp_cntxt_sid_reset(bp->ulp_ctx);
866dd0191d5SShuanglin Wang 	(void)tfc_close(&bp->tfcp);
867dd0191d5SShuanglin Wang }
868dd0191d5SShuanglin Wang 
869dd0191d5SShuanglin Wang /*
870dd0191d5SShuanglin Wang  * When a port is deinit'ed by dpdk. This function is called
871dd0191d5SShuanglin Wang  * and this function clears the ULP context and rest of the
872dd0191d5SShuanglin Wang  * infrastructure associated with it.
873dd0191d5SShuanglin Wang  */
874dd0191d5SShuanglin Wang static void
875dd0191d5SShuanglin Wang ulp_tfc_deinit(struct bnxt *bp,
876dd0191d5SShuanglin Wang 	       struct bnxt_ulp_session_state *session)
877dd0191d5SShuanglin Wang {
878dd0191d5SShuanglin Wang 	bool ha_enabled;
879dd0191d5SShuanglin Wang 	uint16_t fid_cnt = 0;
880dd0191d5SShuanglin Wang 	int32_t rc;
881dd0191d5SShuanglin Wang 
882dd0191d5SShuanglin Wang 	if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
883dd0191d5SShuanglin Wang 		return;
884dd0191d5SShuanglin Wang 
885dd0191d5SShuanglin Wang 	ha_enabled = bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx);
886dd0191d5SShuanglin Wang 	if (ha_enabled) {
887dd0191d5SShuanglin Wang 		rc = ulp_ha_mgr_close(bp->ulp_ctx);
888dd0191d5SShuanglin Wang 		if (rc)
889dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR, "Failed to close HA (%d)\n", rc);
890dd0191d5SShuanglin Wang 	}
891dd0191d5SShuanglin Wang 
8920513f0afSPeter Spreadborough 	/* Delete the Stats Counter Manager */
8930513f0afSPeter Spreadborough 	ulp_sc_mgr_deinit(bp->ulp_ctx);
8940513f0afSPeter Spreadborough 
895dd0191d5SShuanglin Wang 	/* cleanup the flow database */
896dd0191d5SShuanglin Wang 	ulp_flow_db_deinit(bp->ulp_ctx);
897dd0191d5SShuanglin Wang 
898dd0191d5SShuanglin Wang 	/* Delete the Mark database */
899dd0191d5SShuanglin Wang 	ulp_mark_db_deinit(bp->ulp_ctx);
900dd0191d5SShuanglin Wang 
901dd0191d5SShuanglin Wang 	/* cleanup the ulp mapper */
902dd0191d5SShuanglin Wang 	ulp_mapper_deinit(bp->ulp_ctx);
903dd0191d5SShuanglin Wang 
904dd0191d5SShuanglin Wang 	/* cleanup the ulp matcher */
905dd0191d5SShuanglin Wang 	ulp_matcher_deinit(bp->ulp_ctx);
906dd0191d5SShuanglin Wang 
907dd0191d5SShuanglin Wang 	/* Delete the Flow Counter Manager */
908dd0191d5SShuanglin Wang 	ulp_fc_mgr_deinit(bp->ulp_ctx);
909dd0191d5SShuanglin Wang 
910dd0191d5SShuanglin Wang 	/* Delete the Port database */
911dd0191d5SShuanglin Wang 	ulp_port_db_deinit(bp->ulp_ctx);
912dd0191d5SShuanglin Wang 
913dd0191d5SShuanglin Wang 	/* free the flow db lock */
914dd0191d5SShuanglin Wang 	pthread_mutex_destroy(&bp->ulp_ctx->cfg_data->flow_db_lock);
915dd0191d5SShuanglin Wang 
916dd0191d5SShuanglin Wang 	ulp_tfc_tbl_scope_deinit(bp);
917dd0191d5SShuanglin Wang 
918dd0191d5SShuanglin Wang 	rc = tfc_session_fid_rem(&bp->tfcp, bp->fw_fid, &fid_cnt);
919dd0191d5SShuanglin Wang 	if (rc)
920be4732e8SMike Baucom 		BNXT_DRV_DBG(ERR, "Failed to remove RFID:%d from SID:%d\n",
921dd0191d5SShuanglin Wang 			     bp->fw_fid, session->session_id);
922dd0191d5SShuanglin Wang 	else
923be4732e8SMike Baucom 		BNXT_DRV_DBG(DEBUG, "Removed RFID:%d from SID:%d CNT:%d\n",
924be4732e8SMike Baucom 			     bp->fw_fid, session->session_id, fid_cnt);
925dd0191d5SShuanglin Wang 	bnxt_ulp_cntxt_sid_reset(bp->ulp_ctx);
926dd0191d5SShuanglin Wang 	(void)tfc_close(&bp->tfcp);
927dd0191d5SShuanglin Wang 
928dd0191d5SShuanglin Wang 	/* Delete the ulp context and tf session and free the ulp context */
929dd0191d5SShuanglin Wang 	ulp_tfc_ctx_deinit(bp, session);
930dd0191d5SShuanglin Wang 
931dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "ulp ctx has been deinitialized\n");
932dd0191d5SShuanglin Wang }
933dd0191d5SShuanglin Wang 
934dd0191d5SShuanglin Wang /*
935dd0191d5SShuanglin Wang  * When a port is initialized by dpdk. This functions is called
936dd0191d5SShuanglin Wang  * and this function initializes the ULP context and rest of the
937dd0191d5SShuanglin Wang  * infrastructure associated with it.
938dd0191d5SShuanglin Wang  */
939dd0191d5SShuanglin Wang static int32_t
940dd0191d5SShuanglin Wang ulp_tfc_init(struct bnxt *bp,
941dd0191d5SShuanglin Wang 	     struct bnxt_ulp_session_state *session)
942dd0191d5SShuanglin Wang {
943dd0191d5SShuanglin Wang 	uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
944dd0191d5SShuanglin Wang 	uint16_t sid;
945dd0191d5SShuanglin Wang 	int rc;
946dd0191d5SShuanglin Wang 
947b14da654SPeter Spreadborough 	/* Select 64bit SSE4.2 intrinsic if available */
948b14da654SPeter Spreadborough 	rte_hash_crc_set_alg(CRC32_SSE42_x64);
949b14da654SPeter Spreadborough 
950be4732e8SMike Baucom 	rc = bnxt_ulp_devid_get(bp, &ulp_dev_id);
951be4732e8SMike Baucom 	if (rc) {
952be4732e8SMike Baucom 		BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n");
953be4732e8SMike Baucom 		return rc;
954be4732e8SMike Baucom 	}
955be4732e8SMike Baucom 
956dd0191d5SShuanglin Wang 	bp->tfcp.bp = bp;
957dd0191d5SShuanglin Wang 	rc = tfc_open(&bp->tfcp);
958dd0191d5SShuanglin Wang 	if (rc) {
959dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to initialize the tfc object\n");
960dd0191d5SShuanglin Wang 		return rc;
961dd0191d5SShuanglin Wang 	}
962dd0191d5SShuanglin Wang 
963dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_tfcp_set(bp->ulp_ctx, &bp->tfcp);
964dd0191d5SShuanglin Wang 	if (rc) {
965dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to add tfcp to ulp cntxt\n");
966dd0191d5SShuanglin Wang 		return rc;
967dd0191d5SShuanglin Wang 	}
968dd0191d5SShuanglin Wang 
969dd0191d5SShuanglin Wang 	/* First time, so allocate a session and save it. */
970dd0191d5SShuanglin Wang 	rc = tfc_session_id_alloc(&bp->tfcp, bp->fw_fid, &sid);
971dd0191d5SShuanglin Wang 	if (rc) {
972dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to allocate a session id\n");
973dd0191d5SShuanglin Wang 		return rc;
974dd0191d5SShuanglin Wang 	}
975be4732e8SMike Baucom 	BNXT_DRV_DBG(DEBUG, "SID:%d allocated with RFID:%d\n", sid, bp->fw_fid);
976dd0191d5SShuanglin Wang 	session->session_id = sid;
977dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_sid_set(bp->ulp_ctx, sid);
978dd0191d5SShuanglin Wang 	if (rc) {
979dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to sid to ulp cntxt\n");
980dd0191d5SShuanglin Wang 		return rc;
981dd0191d5SShuanglin Wang 	}
982dd0191d5SShuanglin Wang 
983dd0191d5SShuanglin Wang 	/* Allocate and Initialize the ulp context. */
984dd0191d5SShuanglin Wang 	rc = ulp_tfc_ctx_init(bp, session);
985dd0191d5SShuanglin Wang 	if (rc) {
986dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to create the ulp context\n");
987dd0191d5SShuanglin Wang 		goto jump_to_error;
988dd0191d5SShuanglin Wang 	}
989dd0191d5SShuanglin Wang 
990dd0191d5SShuanglin Wang 	rc = ulp_tfc_tbl_scope_init(bp);
991dd0191d5SShuanglin Wang 	if (rc) {
992dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to create the ulp context\n");
993dd0191d5SShuanglin Wang 		goto jump_to_error;
994dd0191d5SShuanglin Wang 	}
995dd0191d5SShuanglin Wang 
996*7d32c003SAriel Otilibili 	pthread_mutex_init(&bp->ulp_ctx->cfg_data->flow_db_lock, NULL);
997dd0191d5SShuanglin Wang 
998dd0191d5SShuanglin Wang 	rc = ulp_tfc_dparms_init(bp, bp->ulp_ctx, ulp_dev_id);
999dd0191d5SShuanglin Wang 	if (rc) {
1000dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to initialize the dparms\n");
1001dd0191d5SShuanglin Wang 		goto jump_to_error;
1002dd0191d5SShuanglin Wang 	}
1003dd0191d5SShuanglin Wang 
1004dd0191d5SShuanglin Wang 	/* create the port database */
1005dd0191d5SShuanglin Wang 	rc = ulp_port_db_init(bp->ulp_ctx, bp->port_cnt);
1006dd0191d5SShuanglin Wang 	if (rc) {
1007dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to create the port database\n");
1008dd0191d5SShuanglin Wang 		goto jump_to_error;
1009dd0191d5SShuanglin Wang 	}
1010dd0191d5SShuanglin Wang 
1011dd0191d5SShuanglin Wang 	/* BAUCOM TODO: Mark database assumes LFID/GFID Parms, need to look at
1012dd0191d5SShuanglin Wang 	 * alternatives.
1013dd0191d5SShuanglin Wang 	 */
1014dd0191d5SShuanglin Wang 	/* Create the Mark database. */
1015dd0191d5SShuanglin Wang 	rc = ulp_mark_db_init(bp->ulp_ctx);
1016dd0191d5SShuanglin Wang 	if (rc) {
1017dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to create the mark database\n");
1018dd0191d5SShuanglin Wang 		goto jump_to_error;
1019dd0191d5SShuanglin Wang 	}
1020dd0191d5SShuanglin Wang 
1021dd0191d5SShuanglin Wang 	/* Create the flow database. */
1022dd0191d5SShuanglin Wang 	rc = ulp_flow_db_init(bp->ulp_ctx);
1023dd0191d5SShuanglin Wang 	if (rc) {
1024dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to create the flow database\n");
1025dd0191d5SShuanglin Wang 		goto jump_to_error;
1026dd0191d5SShuanglin Wang 	}
1027dd0191d5SShuanglin Wang 
1028dd0191d5SShuanglin Wang 	rc = ulp_matcher_init(bp->ulp_ctx);
1029dd0191d5SShuanglin Wang 	if (rc) {
1030dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to initialize ulp matcher\n");
1031dd0191d5SShuanglin Wang 		goto jump_to_error;
1032dd0191d5SShuanglin Wang 	}
1033dd0191d5SShuanglin Wang 
1034dd0191d5SShuanglin Wang 	rc = ulp_mapper_init(bp->ulp_ctx);
1035dd0191d5SShuanglin Wang 	if (rc) {
1036dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to initialize ulp mapper\n");
1037dd0191d5SShuanglin Wang 		goto jump_to_error;
1038dd0191d5SShuanglin Wang 	}
1039dd0191d5SShuanglin Wang 
1040dd0191d5SShuanglin Wang 	/* BAUCOM TODO: need to make FC Mgr not start the thread. */
1041dd0191d5SShuanglin Wang 	rc = ulp_fc_mgr_init(bp->ulp_ctx);
1042dd0191d5SShuanglin Wang 	if (rc) {
1043dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to initialize ulp flow counter mgr\n");
1044dd0191d5SShuanglin Wang 		goto jump_to_error;
1045dd0191d5SShuanglin Wang 	}
1046dd0191d5SShuanglin Wang 
10470513f0afSPeter Spreadborough 	rc = ulp_sc_mgr_init(bp->ulp_ctx);
10480513f0afSPeter Spreadborough 	if (rc) {
10490513f0afSPeter Spreadborough 		BNXT_DRV_DBG(ERR, "Failed to initialize ulp stats cache mgr\n");
10500513f0afSPeter Spreadborough 		goto jump_to_error;
10510513f0afSPeter Spreadborough 	}
10520513f0afSPeter Spreadborough 
105380d760e1SJay Ding 	rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
105480d760e1SJay Ding 	if (rc) {
105580d760e1SJay Ding 		BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n");
105680d760e1SJay Ding 		return rc;
105780d760e1SJay Ding 	}
105880d760e1SJay Ding 
105980d760e1SJay Ding 	if (ulp_dev_id == BNXT_ULP_DEVICE_ID_THOR2) {
106080d760e1SJay Ding 		rc = bnxt_flow_mtr_init(bp);
106180d760e1SJay Ding 		if (rc) {
106280d760e1SJay Ding 			BNXT_DRV_DBG(ERR, "Failed to config meter\n");
106380d760e1SJay Ding 			goto jump_to_error;
106480d760e1SJay Ding 		}
106580d760e1SJay Ding 	}
106680d760e1SJay Ding 
1067ffbc3529SShuanglin Wang #ifdef TF_FLOW_SCALE_QUERY
1068ffbc3529SShuanglin Wang 	/* Query resource statstics from firmware */
1069ffbc3529SShuanglin Wang 	tfc_resc_usage_query_all(bp);
1070ffbc3529SShuanglin Wang #endif /* TF_FLOW_SCALE_QUERY */
1071ffbc3529SShuanglin Wang 
1072dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "ulp ctx has been initialized\n");
1073dd0191d5SShuanglin Wang 	return rc;
1074dd0191d5SShuanglin Wang 
1075dd0191d5SShuanglin Wang jump_to_error:
1076dd0191d5SShuanglin Wang 	bp->ulp_ctx->ops->ulp_deinit(bp, session);
1077dd0191d5SShuanglin Wang 	return rc;
1078dd0191d5SShuanglin Wang }
1079dd0191d5SShuanglin Wang 
108080d760e1SJay Ding /**
108180d760e1SJay Ding  * Get meter capabilities.
108280d760e1SJay Ding  */
108380d760e1SJay Ding #define MAX_FLOW_PER_METER 1024
108480d760e1SJay Ding #define MAX_NUM_METER 1024
108580d760e1SJay Ding #define MAX_METER_RATE_200GBPS ((1ULL << 31) * 100 / 8)
108680d760e1SJay Ding static int
108780d760e1SJay Ding ulp_tfc_mtr_cap_get(struct bnxt *bp __rte_unused,
108880d760e1SJay Ding 		    struct rte_mtr_capabilities *cap)
108980d760e1SJay Ding {
109080d760e1SJay Ding #if (RTE_VERSION_NUM(21, 05, 0, 0) <= RTE_VERSION)
109180d760e1SJay Ding 	cap->srtcm_rfc2697_byte_mode_supported = 1;
109280d760e1SJay Ding #endif
109380d760e1SJay Ding 	cap->n_max = MAX_NUM_METER;
109480d760e1SJay Ding 	cap->n_shared_max = cap->n_max;
109580d760e1SJay Ding 	/* No meter is identical */
109680d760e1SJay Ding 	cap->identical = 1;
109780d760e1SJay Ding 	cap->shared_identical = 1;
109880d760e1SJay Ding 	cap->shared_n_flows_per_mtr_max = MAX_FLOW_PER_METER;
109980d760e1SJay Ding 	cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */
110080d760e1SJay Ding 	cap->meter_srtcm_rfc2697_n_max = cap->n_max;
110180d760e1SJay Ding 	cap->meter_rate_max = MAX_METER_RATE_200GBPS;
110280d760e1SJay Ding 	/* No stats supported now */
110380d760e1SJay Ding 	cap->stats_mask = 0;
110480d760e1SJay Ding 
110580d760e1SJay Ding 	return 0;
110680d760e1SJay Ding }
110780d760e1SJay Ding 
1108dd0191d5SShuanglin Wang const struct bnxt_ulp_core_ops bnxt_ulp_tfc_core_ops = {
1109dd0191d5SShuanglin Wang 	.ulp_ctx_attach = ulp_tfc_ctx_attach,
1110dd0191d5SShuanglin Wang 	.ulp_ctx_detach = ulp_tfc_ctx_detach,
1111dd0191d5SShuanglin Wang 	.ulp_deinit =  ulp_tfc_deinit,
1112dd0191d5SShuanglin Wang 	.ulp_init =  ulp_tfc_init,
1113be4732e8SMike Baucom 	.ulp_vfr_session_fid_add = ulp_tfc_vfr_session_fid_add,
111480d760e1SJay Ding 	.ulp_vfr_session_fid_rem = ulp_tfc_vfr_session_fid_rem,
111580d760e1SJay Ding 	.ulp_mtr_cap_get = ulp_tfc_mtr_cap_get
1116dd0191d5SShuanglin Wang };
1117