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