xref: /dpdk/drivers/net/bnxt/tf_ulp/bnxt_ulp_tf.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_tf.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"
29dd0191d5SShuanglin Wang #include "ulp_flow_db.h"
30dd0191d5SShuanglin Wang #include "ulp_mapper.h"
31dd0191d5SShuanglin Wang #include "ulp_matcher.h"
32dd0191d5SShuanglin Wang #include "ulp_port_db.h"
33dd0191d5SShuanglin Wang #include "ulp_tun.h"
34dd0191d5SShuanglin Wang #include "ulp_ha_mgr.h"
35dd0191d5SShuanglin Wang #include "bnxt_tf_pmd_shim.h"
36dd0191d5SShuanglin Wang #include "ulp_template_db_tbl.h"
37dd0191d5SShuanglin Wang 
38dd0191d5SShuanglin Wang /* Function to set the tfp session details from the ulp context. */
39dd0191d5SShuanglin Wang int32_t
40dd0191d5SShuanglin Wang bnxt_ulp_cntxt_tfp_set(struct bnxt_ulp_context *ulp,
41dd0191d5SShuanglin Wang 		       enum bnxt_ulp_session_type s_type,
42dd0191d5SShuanglin Wang 		       struct tf *tfp)
43dd0191d5SShuanglin Wang {
44dd0191d5SShuanglin Wang 	uint32_t idx = 0;
45dd0191d5SShuanglin Wang 	enum bnxt_ulp_tfo_type tfo_type = BNXT_ULP_TFO_TYPE_TF;
46dd0191d5SShuanglin Wang 
47dd0191d5SShuanglin Wang 	if (ulp == NULL)
48dd0191d5SShuanglin Wang 		return -EINVAL;
49dd0191d5SShuanglin Wang 
50dd0191d5SShuanglin Wang 	if (ULP_MULTI_SHARED_IS_SUPPORTED(ulp)) {
51dd0191d5SShuanglin Wang 		if (s_type & BNXT_ULP_SESSION_TYPE_SHARED)
52dd0191d5SShuanglin Wang 			idx = 1;
53dd0191d5SShuanglin Wang 		else if (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC)
54dd0191d5SShuanglin Wang 			idx = 2;
55dd0191d5SShuanglin Wang 
56dd0191d5SShuanglin Wang 	} else {
57dd0191d5SShuanglin Wang 		if ((s_type & BNXT_ULP_SESSION_TYPE_SHARED) ||
58dd0191d5SShuanglin Wang 		    (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC))
59dd0191d5SShuanglin Wang 			idx = 1;
60dd0191d5SShuanglin Wang 	}
61dd0191d5SShuanglin Wang 
62dd0191d5SShuanglin Wang 	ulp->g_tfp[idx] = tfp;
63dd0191d5SShuanglin Wang 
64dd0191d5SShuanglin Wang 	if (tfp == NULL) {
65dd0191d5SShuanglin Wang 		uint32_t i = 0;
66dd0191d5SShuanglin Wang 		while (i < BNXT_ULP_SESSION_MAX && ulp->g_tfp[i] == NULL)
67dd0191d5SShuanglin Wang 			i++;
68dd0191d5SShuanglin Wang 		if (i == BNXT_ULP_SESSION_MAX)
69dd0191d5SShuanglin Wang 			ulp->tfo_type = BNXT_ULP_TFO_TYPE_INVALID;
70dd0191d5SShuanglin Wang 	} else {
71dd0191d5SShuanglin Wang 		ulp->tfo_type = tfo_type;
72dd0191d5SShuanglin Wang 	}
73dd0191d5SShuanglin Wang 	return 0;
74dd0191d5SShuanglin Wang }
75dd0191d5SShuanglin Wang 
76dd0191d5SShuanglin Wang /* Function to get the tfp session details from the ulp context. */
77dd0191d5SShuanglin Wang struct tf *
78dd0191d5SShuanglin Wang bnxt_ulp_cntxt_tfp_get(struct bnxt_ulp_context *ulp,
79dd0191d5SShuanglin Wang 		       enum bnxt_ulp_session_type s_type)
80dd0191d5SShuanglin Wang {
81dd0191d5SShuanglin Wang 	uint32_t idx = 0;
82dd0191d5SShuanglin Wang 
83dd0191d5SShuanglin Wang 	if (ulp == NULL)
84dd0191d5SShuanglin Wang 		return NULL;
85dd0191d5SShuanglin Wang 
86dd0191d5SShuanglin Wang 	if (ulp->tfo_type != BNXT_ULP_TFO_TYPE_TF) {
87dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Wrong tf type %d != %d\n",
88dd0191d5SShuanglin Wang 			     ulp->tfo_type, BNXT_ULP_TFO_TYPE_TF);
89dd0191d5SShuanglin Wang 		return NULL;
90dd0191d5SShuanglin Wang 	}
91dd0191d5SShuanglin Wang 
92dd0191d5SShuanglin Wang 	if (ULP_MULTI_SHARED_IS_SUPPORTED(ulp)) {
93dd0191d5SShuanglin Wang 		if (s_type & BNXT_ULP_SESSION_TYPE_SHARED)
94dd0191d5SShuanglin Wang 			idx = 1;
95dd0191d5SShuanglin Wang 		else if (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC)
96dd0191d5SShuanglin Wang 			idx = 2;
97dd0191d5SShuanglin Wang 	} else {
98dd0191d5SShuanglin Wang 		if ((s_type & BNXT_ULP_SESSION_TYPE_SHARED) ||
99dd0191d5SShuanglin Wang 		    (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC))
100dd0191d5SShuanglin Wang 			idx = 1;
101dd0191d5SShuanglin Wang 	}
102dd0191d5SShuanglin Wang 	return (struct tf *)ulp->g_tfp[idx];
103dd0191d5SShuanglin Wang }
104dd0191d5SShuanglin Wang 
105dd0191d5SShuanglin Wang struct tf *bnxt_get_tfp_session(struct bnxt *bp, enum bnxt_session_type type)
106dd0191d5SShuanglin Wang {
107dd0191d5SShuanglin Wang 	return (type >= BNXT_SESSION_TYPE_LAST) ?
108dd0191d5SShuanglin Wang 		&bp->tfp[BNXT_SESSION_TYPE_REGULAR] : &bp->tfp[type];
109dd0191d5SShuanglin Wang }
110dd0191d5SShuanglin Wang 
111dd0191d5SShuanglin Wang struct tf *
112dd0191d5SShuanglin Wang bnxt_ulp_bp_tfp_get(struct bnxt *bp, enum bnxt_ulp_session_type type)
113dd0191d5SShuanglin Wang {
114dd0191d5SShuanglin Wang 	enum bnxt_session_type btype;
115dd0191d5SShuanglin Wang 
116dd0191d5SShuanglin Wang 	if (type & BNXT_ULP_SESSION_TYPE_SHARED)
117dd0191d5SShuanglin Wang 		btype = BNXT_SESSION_TYPE_SHARED_COMMON;
118dd0191d5SShuanglin Wang 	else if (type & BNXT_ULP_SESSION_TYPE_SHARED_WC)
119dd0191d5SShuanglin Wang 		btype = BNXT_SESSION_TYPE_SHARED_WC;
120dd0191d5SShuanglin Wang 	else
121dd0191d5SShuanglin Wang 		btype = BNXT_SESSION_TYPE_REGULAR;
122dd0191d5SShuanglin Wang 
123dd0191d5SShuanglin Wang 	return bnxt_get_tfp_session(bp, btype);
124dd0191d5SShuanglin Wang }
125dd0191d5SShuanglin Wang 
126dd0191d5SShuanglin Wang static int32_t
127dd0191d5SShuanglin Wang ulp_tf_named_resources_calc(struct bnxt_ulp_context *ulp_ctx,
128dd0191d5SShuanglin Wang 			    struct bnxt_ulp_glb_resource_info *info,
129dd0191d5SShuanglin Wang 			    uint32_t num,
130dd0191d5SShuanglin Wang 			    enum bnxt_ulp_session_type stype,
131dd0191d5SShuanglin Wang 			    struct tf_session_resources *res)
132dd0191d5SShuanglin Wang {
133dd0191d5SShuanglin Wang 	uint32_t dev_id = BNXT_ULP_DEVICE_ID_LAST, res_type, i;
134dd0191d5SShuanglin Wang 	enum tf_dir dir;
135dd0191d5SShuanglin Wang 	uint8_t app_id;
136dd0191d5SShuanglin Wang 	int32_t rc = 0;
137dd0191d5SShuanglin Wang 
138dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || info == NULL || res == NULL || num == 0) {
139dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid parms to named resources calc.\n");
140dd0191d5SShuanglin Wang 		return -EINVAL;
141dd0191d5SShuanglin Wang 	}
142dd0191d5SShuanglin Wang 
143dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id);
144dd0191d5SShuanglin Wang 	if (rc) {
145dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the app id from ulp.\n");
146dd0191d5SShuanglin Wang 		return -EINVAL;
147dd0191d5SShuanglin Wang 	}
148dd0191d5SShuanglin Wang 
149dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id);
150dd0191d5SShuanglin Wang 	if (rc) {
151dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the dev id from ulp.\n");
152dd0191d5SShuanglin Wang 		return -EINVAL;
153dd0191d5SShuanglin Wang 	}
154dd0191d5SShuanglin Wang 
155dd0191d5SShuanglin Wang 	for (i = 0; i < num; i++) {
156dd0191d5SShuanglin Wang 		if (dev_id != info[i].device_id || app_id != info[i].app_id)
157dd0191d5SShuanglin Wang 			continue;
158dd0191d5SShuanglin Wang 		/* check to see if the session type matches only then include */
159dd0191d5SShuanglin Wang 		if ((stype || info[i].session_type) &&
160dd0191d5SShuanglin Wang 		    !(info[i].session_type & stype))
161dd0191d5SShuanglin Wang 			continue;
162dd0191d5SShuanglin Wang 
163dd0191d5SShuanglin Wang 		dir = info[i].direction;
164dd0191d5SShuanglin Wang 		res_type = info[i].resource_type;
165dd0191d5SShuanglin Wang 
166dd0191d5SShuanglin Wang 		switch (info[i].resource_func) {
167dd0191d5SShuanglin Wang 		case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
168dd0191d5SShuanglin Wang 			res->ident_cnt[dir].cnt[res_type]++;
169dd0191d5SShuanglin Wang 			break;
170dd0191d5SShuanglin Wang 		case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
171dd0191d5SShuanglin Wang 			res->tbl_cnt[dir].cnt[res_type]++;
172dd0191d5SShuanglin Wang 			break;
173dd0191d5SShuanglin Wang 		case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE:
174dd0191d5SShuanglin Wang 			res->tcam_cnt[dir].cnt[res_type]++;
175dd0191d5SShuanglin Wang 			break;
176dd0191d5SShuanglin Wang 		case BNXT_ULP_RESOURCE_FUNC_EM_TABLE:
177dd0191d5SShuanglin Wang 			res->em_cnt[dir].cnt[res_type]++;
178dd0191d5SShuanglin Wang 			break;
179dd0191d5SShuanglin Wang 		default:
180dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR, "Unknown resource func (0x%x)\n,",
181dd0191d5SShuanglin Wang 				     info[i].resource_func);
182dd0191d5SShuanglin Wang 			continue;
183dd0191d5SShuanglin Wang 		}
184dd0191d5SShuanglin Wang 	}
185dd0191d5SShuanglin Wang 
186dd0191d5SShuanglin Wang 	return 0;
187dd0191d5SShuanglin Wang }
188dd0191d5SShuanglin Wang 
189dd0191d5SShuanglin Wang static int32_t
190dd0191d5SShuanglin Wang ulp_tf_unnamed_resources_calc(struct bnxt_ulp_context *ulp_ctx,
191dd0191d5SShuanglin Wang 			      struct bnxt_ulp_resource_resv_info *info,
192dd0191d5SShuanglin Wang 			      uint32_t num,
193dd0191d5SShuanglin Wang 			      enum bnxt_ulp_session_type stype,
194dd0191d5SShuanglin Wang 			      struct tf_session_resources *res)
195dd0191d5SShuanglin Wang {
196dd0191d5SShuanglin Wang 	uint32_t dev_id, res_type, i;
197dd0191d5SShuanglin Wang 	enum tf_dir dir;
198dd0191d5SShuanglin Wang 	uint8_t app_id;
199dd0191d5SShuanglin Wang 	int32_t rc = 0;
200dd0191d5SShuanglin Wang 
201dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || res == NULL || info == NULL || num == 0) {
202dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid arguments to get resources.\n");
203dd0191d5SShuanglin Wang 		return -EINVAL;
204dd0191d5SShuanglin Wang 	}
205dd0191d5SShuanglin Wang 
206dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id);
207dd0191d5SShuanglin Wang 	if (rc) {
208dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the app id from ulp.\n");
209dd0191d5SShuanglin Wang 		return -EINVAL;
210dd0191d5SShuanglin Wang 	}
211dd0191d5SShuanglin Wang 
212dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id);
213dd0191d5SShuanglin Wang 	if (rc) {
214dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the dev id from ulp.\n");
215dd0191d5SShuanglin Wang 		return -EINVAL;
216dd0191d5SShuanglin Wang 	}
217dd0191d5SShuanglin Wang 
218dd0191d5SShuanglin Wang 	for (i = 0; i < num; i++) {
219dd0191d5SShuanglin Wang 		if (app_id != info[i].app_id || dev_id != info[i].device_id)
220dd0191d5SShuanglin Wang 			continue;
221dd0191d5SShuanglin Wang 
222dd0191d5SShuanglin Wang 		/* check to see if the session type matches only then include */
223dd0191d5SShuanglin Wang 		if ((stype || info[i].session_type) &&
224dd0191d5SShuanglin Wang 		    !(info[i].session_type & stype))
225dd0191d5SShuanglin Wang 			continue;
226dd0191d5SShuanglin Wang 
227dd0191d5SShuanglin Wang 		dir = info[i].direction;
228dd0191d5SShuanglin Wang 		res_type = info[i].resource_type;
229dd0191d5SShuanglin Wang 
230dd0191d5SShuanglin Wang 		switch (info[i].resource_func) {
231dd0191d5SShuanglin Wang 		case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
232dd0191d5SShuanglin Wang 			res->ident_cnt[dir].cnt[res_type] = info[i].count;
233dd0191d5SShuanglin Wang 			break;
234dd0191d5SShuanglin Wang 		case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
235dd0191d5SShuanglin Wang 			res->tbl_cnt[dir].cnt[res_type] = info[i].count;
236dd0191d5SShuanglin Wang 			break;
237dd0191d5SShuanglin Wang 		case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE:
238dd0191d5SShuanglin Wang 			res->tcam_cnt[dir].cnt[res_type] = info[i].count;
239dd0191d5SShuanglin Wang 			break;
240dd0191d5SShuanglin Wang 		case BNXT_ULP_RESOURCE_FUNC_EM_TABLE:
241dd0191d5SShuanglin Wang 			res->em_cnt[dir].cnt[res_type] = info[i].count;
242dd0191d5SShuanglin Wang 			break;
243dd0191d5SShuanglin Wang 		default:
244dd0191d5SShuanglin Wang 			break;
245dd0191d5SShuanglin Wang 		}
246dd0191d5SShuanglin Wang 	}
247dd0191d5SShuanglin Wang 	return 0;
248dd0191d5SShuanglin Wang }
249dd0191d5SShuanglin Wang 
250dd0191d5SShuanglin Wang static int32_t
251dd0191d5SShuanglin Wang ulp_tf_resources_get(struct bnxt_ulp_context *ulp_ctx,
252dd0191d5SShuanglin Wang 		     enum bnxt_ulp_session_type stype,
253dd0191d5SShuanglin Wang 		     struct tf_session_resources *res)
254dd0191d5SShuanglin Wang {
255dd0191d5SShuanglin Wang 	struct bnxt_ulp_resource_resv_info *unnamed = NULL;
256dd0191d5SShuanglin Wang 	uint32_t unum;
257dd0191d5SShuanglin Wang 	int32_t rc = 0;
258dd0191d5SShuanglin Wang 
259dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || res == NULL) {
260dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid arguments to get resources.\n");
261dd0191d5SShuanglin Wang 		return -EINVAL;
262dd0191d5SShuanglin Wang 	}
263dd0191d5SShuanglin Wang 
26461a7ca1fSKishore Padmanabha 	/* use DEFAULT_NON_HA instead of DEFAULT resources if HA is disabled */
26561a7ca1fSKishore Padmanabha 	if (ULP_APP_HA_IS_DYNAMIC(ulp_ctx))
26661a7ca1fSKishore Padmanabha 		stype = ulp_ctx->cfg_data->def_session_type;
26761a7ca1fSKishore Padmanabha 
268dd0191d5SShuanglin Wang 	unnamed = bnxt_ulp_resource_resv_list_get(&unum);
269dd0191d5SShuanglin Wang 	if (unnamed == NULL) {
270dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get resource resv list.\n");
271dd0191d5SShuanglin Wang 		return -EINVAL;
272dd0191d5SShuanglin Wang 	}
273dd0191d5SShuanglin Wang 
274dd0191d5SShuanglin Wang 	rc = ulp_tf_unnamed_resources_calc(ulp_ctx, unnamed, unum, stype, res);
275dd0191d5SShuanglin Wang 	if (rc)
276dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to calc resources for session.\n");
277dd0191d5SShuanglin Wang 
278dd0191d5SShuanglin Wang 	return rc;
279dd0191d5SShuanglin Wang }
280dd0191d5SShuanglin Wang 
281dd0191d5SShuanglin Wang static int32_t
282dd0191d5SShuanglin Wang ulp_tf_shared_session_resources_get(struct bnxt_ulp_context *ulp_ctx,
283dd0191d5SShuanglin Wang 				    enum bnxt_ulp_session_type stype,
284dd0191d5SShuanglin Wang 				    struct tf_session_resources *res)
285dd0191d5SShuanglin Wang {
286dd0191d5SShuanglin Wang 	struct bnxt_ulp_resource_resv_info *unnamed;
287dd0191d5SShuanglin Wang 	struct bnxt_ulp_glb_resource_info *named;
288dd0191d5SShuanglin Wang 	uint32_t unum = 0, nnum = 0;
289dd0191d5SShuanglin Wang 	int32_t rc;
290dd0191d5SShuanglin Wang 
291dd0191d5SShuanglin Wang 	if (ulp_ctx == NULL || res == NULL) {
292dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid arguments to get resources.\n");
293dd0191d5SShuanglin Wang 		return -EINVAL;
294dd0191d5SShuanglin Wang 	}
295dd0191d5SShuanglin Wang 
296dd0191d5SShuanglin Wang 	/* Make sure the resources are zero before accumulating. */
297dd0191d5SShuanglin Wang 	memset(res, 0, sizeof(struct tf_session_resources));
298dd0191d5SShuanglin Wang 
299dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_ha_enabled(ulp_ctx) &&
300dd0191d5SShuanglin Wang 	    stype == BNXT_ULP_SESSION_TYPE_SHARED)
301dd0191d5SShuanglin Wang 		stype = ulp_ctx->cfg_data->hu_session_type;
302dd0191d5SShuanglin Wang 
303dd0191d5SShuanglin Wang 	/*
304dd0191d5SShuanglin Wang 	 * Shared resources are comprised of both named and unnamed resources.
305dd0191d5SShuanglin Wang 	 * First get the unnamed counts, and then add the named to the result.
306dd0191d5SShuanglin Wang 	 */
307dd0191d5SShuanglin Wang 	/* Get the baseline counts */
308dd0191d5SShuanglin Wang 	unnamed = bnxt_ulp_app_resource_resv_list_get(&unum);
309dd0191d5SShuanglin Wang 	if (unum) {
310dd0191d5SShuanglin Wang 		rc = ulp_tf_unnamed_resources_calc(ulp_ctx, unnamed,
311dd0191d5SShuanglin Wang 						   unum, stype, res);
312dd0191d5SShuanglin Wang 		if (rc) {
313dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR,
314dd0191d5SShuanglin Wang 				     "Unable to calc resources for shared session.\n");
315dd0191d5SShuanglin Wang 			return -EINVAL;
316dd0191d5SShuanglin Wang 		}
317dd0191d5SShuanglin Wang 	}
318dd0191d5SShuanglin Wang 
319dd0191d5SShuanglin Wang 	/* Get the named list and add the totals */
320dd0191d5SShuanglin Wang 	named = bnxt_ulp_app_glb_resource_info_list_get(&nnum);
321dd0191d5SShuanglin Wang 	/* No need to calc resources, none to calculate */
322dd0191d5SShuanglin Wang 	if (!nnum)
323dd0191d5SShuanglin Wang 		return 0;
324dd0191d5SShuanglin Wang 
325dd0191d5SShuanglin Wang 	rc = ulp_tf_named_resources_calc(ulp_ctx, named, nnum, stype, res);
326dd0191d5SShuanglin Wang 	if (rc)
327dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to calc named resources\n");
328dd0191d5SShuanglin Wang 
329dd0191d5SShuanglin Wang 	return rc;
330dd0191d5SShuanglin Wang }
331dd0191d5SShuanglin Wang 
332dd0191d5SShuanglin Wang /* Function to set the hot upgrade support into the context */
333dd0191d5SShuanglin Wang static int
334dd0191d5SShuanglin Wang ulp_tf_multi_shared_session_support_set(struct bnxt *bp,
335dd0191d5SShuanglin Wang 					enum bnxt_ulp_device_id devid,
336dd0191d5SShuanglin Wang 					uint32_t fw_hu_update)
337dd0191d5SShuanglin Wang {
338dd0191d5SShuanglin Wang 	struct bnxt_ulp_context *ulp_ctx = bp->ulp_ctx;
339dd0191d5SShuanglin Wang 	struct tf_get_version_parms v_params = { 0 };
340dd0191d5SShuanglin Wang 	struct tf *tfp;
341dd0191d5SShuanglin Wang 	int32_t rc = 0;
342dd0191d5SShuanglin Wang 	int32_t new_fw = 0;
343dd0191d5SShuanglin Wang 
344dd0191d5SShuanglin Wang 	v_params.device_type = bnxt_ulp_cntxt_convert_dev_id(devid);
345dd0191d5SShuanglin Wang 	v_params.bp = bp;
346dd0191d5SShuanglin Wang 
347dd0191d5SShuanglin Wang 	tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
348dd0191d5SShuanglin Wang 	rc = tf_get_version(tfp, &v_params);
349dd0191d5SShuanglin Wang 	if (rc) {
350dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get tf version.\n");
351dd0191d5SShuanglin Wang 		return rc;
352dd0191d5SShuanglin Wang 	}
353dd0191d5SShuanglin Wang 
354dd0191d5SShuanglin Wang 	if (v_params.major == 1 && v_params.minor == 0 &&
355dd0191d5SShuanglin Wang 	    v_params.update == 1) {
356dd0191d5SShuanglin Wang 		new_fw = 1;
357dd0191d5SShuanglin Wang 	}
358dd0191d5SShuanglin Wang 	/* if the version update is greater than 0 then set support for
359dd0191d5SShuanglin Wang 	 * multiple version
360dd0191d5SShuanglin Wang 	 */
361dd0191d5SShuanglin Wang 	if (new_fw) {
362dd0191d5SShuanglin Wang 		ulp_ctx->cfg_data->ulp_flags |= BNXT_ULP_MULTI_SHARED_SUPPORT;
363dd0191d5SShuanglin Wang 		ulp_ctx->cfg_data->hu_session_type =
364dd0191d5SShuanglin Wang 			BNXT_ULP_SESSION_TYPE_SHARED;
365dd0191d5SShuanglin Wang 	}
366dd0191d5SShuanglin Wang 	if (!new_fw && fw_hu_update) {
367dd0191d5SShuanglin Wang 		ulp_ctx->cfg_data->ulp_flags &= ~BNXT_ULP_HIGH_AVAIL_ENABLED;
368dd0191d5SShuanglin Wang 		ulp_ctx->cfg_data->hu_session_type =
369dd0191d5SShuanglin Wang 			BNXT_ULP_SESSION_TYPE_SHARED |
370dd0191d5SShuanglin Wang 			BNXT_ULP_SESSION_TYPE_SHARED_OWC;
371dd0191d5SShuanglin Wang 	}
372dd0191d5SShuanglin Wang 
373dd0191d5SShuanglin Wang 	if (!new_fw && !fw_hu_update) {
374dd0191d5SShuanglin Wang 		ulp_ctx->cfg_data->hu_session_type =
375dd0191d5SShuanglin Wang 			BNXT_ULP_SESSION_TYPE_SHARED |
376dd0191d5SShuanglin Wang 			BNXT_ULP_SESSION_TYPE_SHARED_OWC;
377dd0191d5SShuanglin Wang 	}
378dd0191d5SShuanglin Wang 
379dd0191d5SShuanglin Wang 	return rc;
380dd0191d5SShuanglin Wang }
381dd0191d5SShuanglin Wang 
382dd0191d5SShuanglin Wang static int32_t
383dd0191d5SShuanglin Wang ulp_tf_cntxt_app_caps_init(struct bnxt *bp,
384dd0191d5SShuanglin Wang 			   uint8_t app_id, uint32_t dev_id)
385dd0191d5SShuanglin Wang {
386dd0191d5SShuanglin Wang 	struct bnxt_ulp_app_capabilities_info *info;
387dd0191d5SShuanglin Wang 	uint32_t num = 0, fw = 0;
388dd0191d5SShuanglin Wang 	uint16_t i;
389dd0191d5SShuanglin Wang 	bool found = false;
390dd0191d5SShuanglin Wang 	struct bnxt_ulp_context *ulp_ctx = bp->ulp_ctx;
391dd0191d5SShuanglin Wang 
392dd0191d5SShuanglin Wang 	if (ULP_APP_DEV_UNSUPPORTED_ENABLED(ulp_ctx->cfg_data->ulp_flags)) {
393dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
394dd0191d5SShuanglin Wang 			     app_id, dev_id);
395dd0191d5SShuanglin Wang 		return -EINVAL;
396dd0191d5SShuanglin Wang 	}
397dd0191d5SShuanglin Wang 
398dd0191d5SShuanglin Wang 	info = bnxt_ulp_app_cap_list_get(&num);
399dd0191d5SShuanglin Wang 	if (!info || !num) {
400dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to get app capabilities.\n");
401dd0191d5SShuanglin Wang 		return -EINVAL;
402dd0191d5SShuanglin Wang 	}
403dd0191d5SShuanglin Wang 
404dd0191d5SShuanglin Wang 	for (i = 0; i < num; i++) {
405dd0191d5SShuanglin Wang 		if (info[i].app_id != app_id || info[i].device_id != dev_id)
406dd0191d5SShuanglin Wang 			continue;
407dd0191d5SShuanglin Wang 		found = true;
408dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_SHARED_EN)
409dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
410dd0191d5SShuanglin Wang 				BNXT_ULP_SHARED_SESSION_ENABLED;
411dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_HOT_UPGRADE_EN)
412dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
413dd0191d5SShuanglin Wang 				BNXT_ULP_HIGH_AVAIL_ENABLED;
414dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_UNICAST_ONLY)
415dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
416dd0191d5SShuanglin Wang 				BNXT_ULP_APP_UNICAST_ONLY;
417dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_IP_TOS_PROTO_SUPPORT)
418dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
419dd0191d5SShuanglin Wang 				BNXT_ULP_APP_TOS_PROTO_SUPPORT;
420dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_BC_MC_SUPPORT)
421dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
422dd0191d5SShuanglin Wang 				BNXT_ULP_APP_BC_MC_SUPPORT;
423dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_SOCKET_DIRECT) {
424dd0191d5SShuanglin Wang 			/* Enable socket direction only if MR is enabled in fw*/
425dd0191d5SShuanglin Wang 			if (BNXT_MULTIROOT_EN(bp)) {
426dd0191d5SShuanglin Wang 				ulp_ctx->cfg_data->ulp_flags |=
427dd0191d5SShuanglin Wang 					BNXT_ULP_APP_SOCKET_DIRECT;
428dd0191d5SShuanglin Wang 				BNXT_DRV_DBG(INFO,
429dd0191d5SShuanglin Wang 					     "Socket Direct feature is enabled\n");
430dd0191d5SShuanglin Wang 			}
431dd0191d5SShuanglin Wang 		}
432dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_HA_DYNAMIC) {
433dd0191d5SShuanglin Wang 			/* Read the environment variable to determine hot up */
434dd0191d5SShuanglin Wang 			if (!bnxt_pmd_get_hot_up_config()) {
435dd0191d5SShuanglin Wang 				ulp_ctx->cfg_data->ulp_flags |=
436dd0191d5SShuanglin Wang 					BNXT_ULP_APP_HA_DYNAMIC;
437dd0191d5SShuanglin Wang 				/* reset Hot upgrade, dynamically disabled */
438dd0191d5SShuanglin Wang 				ulp_ctx->cfg_data->ulp_flags &=
439dd0191d5SShuanglin Wang 					~BNXT_ULP_HIGH_AVAIL_ENABLED;
440dd0191d5SShuanglin Wang 				ulp_ctx->cfg_data->def_session_type =
441dd0191d5SShuanglin Wang 					BNXT_ULP_SESSION_TYPE_DEFAULT_NON_HA;
442dd0191d5SShuanglin Wang 				BNXT_DRV_DBG(INFO, "Hot upgrade disabled.\n");
443dd0191d5SShuanglin Wang 			}
444dd0191d5SShuanglin Wang 		}
445dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_SRV6)
446dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
447dd0191d5SShuanglin Wang 				BNXT_ULP_APP_SRV6;
448dd0191d5SShuanglin Wang 
449dd0191d5SShuanglin Wang 		if (info[i].flags & BNXT_ULP_APP_CAP_L2_ETYPE)
450dd0191d5SShuanglin Wang 			ulp_ctx->cfg_data->ulp_flags |=
451dd0191d5SShuanglin Wang 				BNXT_ULP_APP_L2_ETYPE;
452dd0191d5SShuanglin Wang 
453dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_vxlan_ip_port_set(ulp_ctx, info[i].vxlan_ip_port);
454dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_vxlan_port_set(ulp_ctx, info[i].vxlan_port);
455dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_ecpri_udp_port_set(ulp_ctx, info[i].ecpri_udp_port);
456dd0191d5SShuanglin Wang 		bnxt_ulp_vxlan_gpe_next_proto_set(ulp_ctx, info[i].tunnel_next_proto);
457dd0191d5SShuanglin Wang 		bnxt_ulp_num_key_recipes_set(ulp_ctx,
458dd0191d5SShuanglin Wang 					     info[i].num_key_recipes_per_dir);
459dd0191d5SShuanglin Wang 
460dd0191d5SShuanglin Wang 		/* set the shared session support from firmware */
461dd0191d5SShuanglin Wang 		fw = info[i].upgrade_fw_update;
462dd0191d5SShuanglin Wang 		if (ULP_HIGH_AVAIL_IS_ENABLED(ulp_ctx->cfg_data->ulp_flags) &&
463dd0191d5SShuanglin Wang 		    ulp_tf_multi_shared_session_support_set(bp, dev_id, fw)) {
464dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR,
465dd0191d5SShuanglin Wang 				     "Unable to get shared session support\n");
466dd0191d5SShuanglin Wang 			return -EINVAL;
467dd0191d5SShuanglin Wang 		}
468dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_ha_reg_set(ulp_ctx, info[i].ha_reg_state,
469dd0191d5SShuanglin Wang 				    info[i].ha_reg_cnt);
470dd0191d5SShuanglin Wang 		ulp_ctx->cfg_data->ha_pool_id = info[i].ha_pool_id;
47122b65613SKishore Padmanabha 		bnxt_ulp_default_app_priority_set(ulp_ctx,
47222b65613SKishore Padmanabha 						  info[i].default_priority);
47322b65613SKishore Padmanabha 		bnxt_ulp_max_def_priority_set(ulp_ctx,
47422b65613SKishore Padmanabha 					      info[i].max_def_priority);
47522b65613SKishore Padmanabha 		bnxt_ulp_min_flow_priority_set(ulp_ctx,
47622b65613SKishore Padmanabha 					       info[i].min_flow_priority);
47722b65613SKishore Padmanabha 		bnxt_ulp_max_flow_priority_set(ulp_ctx,
47822b65613SKishore Padmanabha 					       info[i].max_flow_priority);
479b413ab0aSKishore Padmanabha 		/* Update the capability feature bits*/
480b413ab0aSKishore Padmanabha 		if (bnxt_ulp_cap_feat_process(info[i].feature_bits,
481b413ab0aSKishore Padmanabha 					      &ulp_ctx->cfg_data->feature_bits))
482b413ab0aSKishore Padmanabha 			return -EINVAL;
483b413ab0aSKishore Padmanabha 
4842aa70990SKishore Padmanabha 		bnxt_ulp_cntxt_ptr2_default_class_bits_set(ulp_ctx,
4852aa70990SKishore Padmanabha 							   info[i].default_class_bits);
4862aa70990SKishore Padmanabha 		bnxt_ulp_cntxt_ptr2_default_act_bits_set(ulp_ctx,
4872aa70990SKishore Padmanabha 							 info[i].default_act_bits);
488dd0191d5SShuanglin Wang 	}
489dd0191d5SShuanglin Wang 	if (!found) {
490dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
491dd0191d5SShuanglin Wang 			     app_id, dev_id);
492dd0191d5SShuanglin Wang 		ulp_ctx->cfg_data->ulp_flags |= BNXT_ULP_APP_DEV_UNSUPPORTED;
493dd0191d5SShuanglin Wang 		return -EINVAL;
494dd0191d5SShuanglin Wang 	}
495dd0191d5SShuanglin Wang 
496dd0191d5SShuanglin Wang 	return 0;
497dd0191d5SShuanglin Wang }
498dd0191d5SShuanglin Wang 
499dd0191d5SShuanglin Wang static inline uint32_t
500dd0191d5SShuanglin Wang ulp_tf_session_idx_get(enum bnxt_ulp_session_type session_type) {
501dd0191d5SShuanglin Wang 	if (session_type & BNXT_ULP_SESSION_TYPE_SHARED)
502dd0191d5SShuanglin Wang 		return 1;
503dd0191d5SShuanglin Wang 	else if (session_type & BNXT_ULP_SESSION_TYPE_SHARED_WC)
504dd0191d5SShuanglin Wang 		return 2;
505dd0191d5SShuanglin Wang 	return 0;
506dd0191d5SShuanglin Wang }
507dd0191d5SShuanglin Wang 
508dd0191d5SShuanglin Wang /* Function to set the tfp session details in session */
509dd0191d5SShuanglin Wang static int32_t
510dd0191d5SShuanglin Wang ulp_tf_session_tfp_set(struct bnxt_ulp_session_state *session,
511dd0191d5SShuanglin Wang 		       enum bnxt_ulp_session_type session_type,
512dd0191d5SShuanglin Wang 		       struct tf *tfp)
513dd0191d5SShuanglin Wang {
514dd0191d5SShuanglin Wang 	uint32_t idx = ulp_tf_session_idx_get(session_type);
515dd0191d5SShuanglin Wang 	struct tf *local_tfp;
516dd0191d5SShuanglin Wang 	int32_t rc = 0;
517dd0191d5SShuanglin Wang 
518dd0191d5SShuanglin Wang 	if (!session->session_opened[idx]) {
519dd0191d5SShuanglin Wang 		local_tfp = rte_zmalloc("bnxt_ulp_session_tfp",
520dd0191d5SShuanglin Wang 					sizeof(struct tf), 0);
521dd0191d5SShuanglin Wang 
522dd0191d5SShuanglin Wang 		if (local_tfp == NULL) {
523dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(DEBUG, "Failed to alloc session tfp\n");
524dd0191d5SShuanglin Wang 			return -ENOMEM;
525dd0191d5SShuanglin Wang 		}
526dd0191d5SShuanglin Wang 		local_tfp->session = tfp->session;
527dd0191d5SShuanglin Wang 		session->g_tfp[idx] = local_tfp;
528dd0191d5SShuanglin Wang 		session->session_opened[idx] = 1;
529dd0191d5SShuanglin Wang 	}
530dd0191d5SShuanglin Wang 	return rc;
531dd0191d5SShuanglin Wang }
532dd0191d5SShuanglin Wang 
533dd0191d5SShuanglin Wang /* Function to get the tfp session details in session */
534dd0191d5SShuanglin Wang static struct tf_session_info *
535dd0191d5SShuanglin Wang ulp_tf_session_tfp_get(struct bnxt_ulp_session_state *session,
536dd0191d5SShuanglin Wang 		       enum bnxt_ulp_session_type session_type)
537dd0191d5SShuanglin Wang {
538dd0191d5SShuanglin Wang 	uint32_t idx = ulp_tf_session_idx_get(session_type);
539dd0191d5SShuanglin Wang 	struct tf *local_tfp = session->g_tfp[idx];
540dd0191d5SShuanglin Wang 
541dd0191d5SShuanglin Wang 	if (session->session_opened[idx])
542dd0191d5SShuanglin Wang 		return local_tfp->session;
543dd0191d5SShuanglin Wang 	return NULL;
544dd0191d5SShuanglin Wang }
545dd0191d5SShuanglin Wang 
546dd0191d5SShuanglin Wang static uint32_t
547dd0191d5SShuanglin Wang ulp_tf_session_is_open(struct bnxt_ulp_session_state *session,
548dd0191d5SShuanglin Wang 		       enum bnxt_ulp_session_type session_type)
549dd0191d5SShuanglin Wang {
550dd0191d5SShuanglin Wang 	uint32_t idx = ulp_tf_session_idx_get(session_type);
551dd0191d5SShuanglin Wang 
552dd0191d5SShuanglin Wang 	return session->session_opened[idx];
553dd0191d5SShuanglin Wang }
554dd0191d5SShuanglin Wang 
555dd0191d5SShuanglin Wang /* Function to reset the tfp session details in session */
556dd0191d5SShuanglin Wang static void
557dd0191d5SShuanglin Wang ulp_tf_session_tfp_reset(struct bnxt_ulp_session_state *session,
558dd0191d5SShuanglin Wang 			 enum bnxt_ulp_session_type session_type)
559dd0191d5SShuanglin Wang {
560dd0191d5SShuanglin Wang 	uint32_t idx = ulp_tf_session_idx_get(session_type);
561dd0191d5SShuanglin Wang 
562dd0191d5SShuanglin Wang 	if (session->session_opened[idx]) {
563dd0191d5SShuanglin Wang 		session->session_opened[idx] = 0;
564dd0191d5SShuanglin Wang 		rte_free(session->g_tfp[idx]);
565dd0191d5SShuanglin Wang 		session->g_tfp[idx] = NULL;
566dd0191d5SShuanglin Wang 	}
567dd0191d5SShuanglin Wang }
568dd0191d5SShuanglin Wang 
569dd0191d5SShuanglin Wang static void
570dd0191d5SShuanglin Wang ulp_tf_ctx_shared_session_close(struct bnxt *bp,
571dd0191d5SShuanglin Wang 				enum bnxt_ulp_session_type session_type,
572dd0191d5SShuanglin Wang 				struct bnxt_ulp_session_state *session)
573dd0191d5SShuanglin Wang {
574dd0191d5SShuanglin Wang 	struct tf *tfp;
575dd0191d5SShuanglin Wang 	int32_t rc;
576dd0191d5SShuanglin Wang 
577dd0191d5SShuanglin Wang 	tfp = bnxt_ulp_cntxt_tfp_get(bp->ulp_ctx, session_type);
578dd0191d5SShuanglin Wang 	if (!tfp) {
579dd0191d5SShuanglin Wang 		/*
580dd0191d5SShuanglin Wang 		 * Log it under debug since this is likely a case of the
581dd0191d5SShuanglin Wang 		 * shared session not being created.  For example, a failed
582dd0191d5SShuanglin Wang 		 * initialization.
583dd0191d5SShuanglin Wang 		 */
584dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Failed to get shared tfp on close.\n");
585dd0191d5SShuanglin Wang 		return;
586dd0191d5SShuanglin Wang 	}
587dd0191d5SShuanglin Wang 	rc = tf_close_session(tfp);
588dd0191d5SShuanglin Wang 	if (rc)
589dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to close the shared session rc=%d.\n",
590dd0191d5SShuanglin Wang 			     rc);
591dd0191d5SShuanglin Wang 	(void)bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session_type, NULL);
592dd0191d5SShuanglin Wang 	ulp_tf_session_tfp_reset(session, session_type);
593dd0191d5SShuanglin Wang }
594dd0191d5SShuanglin Wang 
595dd0191d5SShuanglin Wang static int32_t
596dd0191d5SShuanglin Wang ulp_tf_ctx_shared_session_open(struct bnxt *bp,
597dd0191d5SShuanglin Wang 			       enum bnxt_ulp_session_type session_type,
598dd0191d5SShuanglin Wang 			       struct bnxt_ulp_session_state *session)
599dd0191d5SShuanglin Wang {
600dd0191d5SShuanglin Wang 	struct rte_eth_dev *ethdev = bp->eth_dev;
601dd0191d5SShuanglin Wang 	struct tf_session_resources *resources;
602dd0191d5SShuanglin Wang 	struct tf_open_session_parms parms;
603dd0191d5SShuanglin Wang 	size_t nb;
604dd0191d5SShuanglin Wang 	uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
605dd0191d5SShuanglin Wang 	int32_t	rc = 0;
606dd0191d5SShuanglin Wang 	uint8_t app_id;
607dd0191d5SShuanglin Wang 	struct tf *tfp;
608dd0191d5SShuanglin Wang 	uint8_t pool_id;
609dd0191d5SShuanglin Wang 
610dd0191d5SShuanglin Wang 	memset(&parms, 0, sizeof(parms));
611dd0191d5SShuanglin Wang 	rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
612dd0191d5SShuanglin Wang 					  parms.ctrl_chan_name);
613dd0191d5SShuanglin Wang 	if (rc) {
614dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid port %d, rc = %d\n",
615dd0191d5SShuanglin Wang 			     ethdev->data->port_id, rc);
616dd0191d5SShuanglin Wang 		return rc;
617dd0191d5SShuanglin Wang 	}
618dd0191d5SShuanglin Wang 
619dd0191d5SShuanglin Wang 	/* On multi-host system, adjust ctrl_chan_name to avoid confliction */
620dd0191d5SShuanglin Wang 	if (BNXT_MH(bp)) {
621dd0191d5SShuanglin Wang 		rc = ulp_ctx_mh_get_session_name(bp, &parms);
622dd0191d5SShuanglin Wang 		if (rc)
623dd0191d5SShuanglin Wang 			return rc;
624dd0191d5SShuanglin Wang 	}
625dd0191d5SShuanglin Wang 
626dd0191d5SShuanglin Wang 	resources = &parms.resources;
627dd0191d5SShuanglin Wang 
628dd0191d5SShuanglin Wang 	/*
629dd0191d5SShuanglin Wang 	 * Need to account for size of ctrl_chan_name and 1 extra for Null
630dd0191d5SShuanglin Wang 	 * terminator
631dd0191d5SShuanglin Wang 	 */
632dd0191d5SShuanglin Wang 	nb = sizeof(parms.ctrl_chan_name) - strlen(parms.ctrl_chan_name) - 1;
633dd0191d5SShuanglin Wang 
634dd0191d5SShuanglin Wang 	/*
635dd0191d5SShuanglin Wang 	 * Build the ctrl_chan_name with shared token.
636dd0191d5SShuanglin Wang 	 * When HA is enabled, the WC TCAM needs extra management by the core,
637dd0191d5SShuanglin Wang 	 * so add the wc_tcam string to the control channel.
638dd0191d5SShuanglin Wang 	 */
639dd0191d5SShuanglin Wang 	pool_id = bp->ulp_ctx->cfg_data->ha_pool_id;
640dd0191d5SShuanglin Wang 	if (!bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
641dd0191d5SShuanglin Wang 		if (bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx))
642dd0191d5SShuanglin Wang 			strncat(parms.ctrl_chan_name, "-tf_shared-wc_tcam", nb);
643dd0191d5SShuanglin Wang 		else
644dd0191d5SShuanglin Wang 			strncat(parms.ctrl_chan_name, "-tf_shared", nb);
645dd0191d5SShuanglin Wang 	} else if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
646dd0191d5SShuanglin Wang 		if (session_type == BNXT_ULP_SESSION_TYPE_SHARED) {
647dd0191d5SShuanglin Wang 			strncat(parms.ctrl_chan_name, "-tf_shared", nb);
648dd0191d5SShuanglin Wang 		} else if (session_type == BNXT_ULP_SESSION_TYPE_SHARED_WC) {
649dd0191d5SShuanglin Wang 			char session_pool_name[64];
650dd0191d5SShuanglin Wang 
651dd0191d5SShuanglin Wang 			sprintf(session_pool_name, "-tf_shared-pool%d",
652dd0191d5SShuanglin Wang 				pool_id);
653dd0191d5SShuanglin Wang 
654dd0191d5SShuanglin Wang 			if (nb >= strlen(session_pool_name)) {
655dd0191d5SShuanglin Wang 				strncat(parms.ctrl_chan_name, session_pool_name, nb);
656dd0191d5SShuanglin Wang 			} else {
657dd0191d5SShuanglin Wang 				BNXT_DRV_DBG(ERR, "No space left for session_name\n");
658dd0191d5SShuanglin Wang 				return -EINVAL;
659dd0191d5SShuanglin Wang 			}
660dd0191d5SShuanglin Wang 		}
661dd0191d5SShuanglin Wang 	}
662dd0191d5SShuanglin Wang 
663dd0191d5SShuanglin Wang 	rc = ulp_tf_shared_session_resources_get(bp->ulp_ctx, session_type,
664dd0191d5SShuanglin Wang 						 resources);
665dd0191d5SShuanglin Wang 	if (rc)
666dd0191d5SShuanglin Wang 		return rc;
667dd0191d5SShuanglin Wang 
668dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id);
669dd0191d5SShuanglin Wang 	if (rc) {
670dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the app id from ulp.\n");
671dd0191d5SShuanglin Wang 		return -EINVAL;
672dd0191d5SShuanglin Wang 	}
673dd0191d5SShuanglin Wang 
674dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
675dd0191d5SShuanglin Wang 	if (rc) {
676dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n");
677dd0191d5SShuanglin Wang 		return rc;
678dd0191d5SShuanglin Wang 	}
679dd0191d5SShuanglin Wang 
680dd0191d5SShuanglin Wang 	tfp = bnxt_ulp_bp_tfp_get(bp, session_type);
681dd0191d5SShuanglin Wang 	parms.device_type = bnxt_ulp_cntxt_convert_dev_id(ulp_dev_id);
682dd0191d5SShuanglin Wang 	parms.bp = bp;
683dd0191d5SShuanglin Wang 
684dd0191d5SShuanglin Wang 	/*
685dd0191d5SShuanglin Wang 	 * Open the session here, but the collect the resources during the
686dd0191d5SShuanglin Wang 	 * mapper initialization.
687dd0191d5SShuanglin Wang 	 */
688dd0191d5SShuanglin Wang 	rc = tf_open_session(tfp, &parms);
689dd0191d5SShuanglin Wang 	if (rc)
690dd0191d5SShuanglin Wang 		return rc;
691dd0191d5SShuanglin Wang 
692dd0191d5SShuanglin Wang 	if (parms.shared_session_creator)
693dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Shared session creator.\n");
694dd0191d5SShuanglin Wang 	else
695dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Shared session attached.\n");
696dd0191d5SShuanglin Wang 
697dd0191d5SShuanglin Wang 	/* Save the shared session in global data */
698dd0191d5SShuanglin Wang 	rc = ulp_tf_session_tfp_set(session, session_type, tfp);
699dd0191d5SShuanglin Wang 	if (rc) {
700dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to add shared tfp to session\n");
701dd0191d5SShuanglin Wang 		return rc;
702dd0191d5SShuanglin Wang 	}
703dd0191d5SShuanglin Wang 
704dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session_type, tfp);
705dd0191d5SShuanglin Wang 	if (rc) {
706dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to add shared tfp to ulp (%d)\n", rc);
707dd0191d5SShuanglin Wang 		return rc;
708dd0191d5SShuanglin Wang 	}
709dd0191d5SShuanglin Wang 
710dd0191d5SShuanglin Wang 	return rc;
711dd0191d5SShuanglin Wang }
712dd0191d5SShuanglin Wang 
713dd0191d5SShuanglin Wang static int32_t
714dd0191d5SShuanglin Wang ulp_tf_ctx_shared_session_attach(struct bnxt *bp,
715dd0191d5SShuanglin Wang 				 struct bnxt_ulp_session_state *ses)
716dd0191d5SShuanglin Wang {
717dd0191d5SShuanglin Wang 	enum bnxt_ulp_session_type type;
718dd0191d5SShuanglin Wang 	struct tf *tfp;
719dd0191d5SShuanglin Wang 	int32_t rc = 0;
720dd0191d5SShuanglin Wang 
721dd0191d5SShuanglin Wang 	/* Simply return success if shared session not enabled */
722dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) {
723dd0191d5SShuanglin Wang 		type = BNXT_ULP_SESSION_TYPE_SHARED;
724dd0191d5SShuanglin Wang 		tfp = bnxt_ulp_bp_tfp_get(bp, type);
725dd0191d5SShuanglin Wang 		tfp->session = ulp_tf_session_tfp_get(ses, type);
726dd0191d5SShuanglin Wang 		rc = ulp_tf_ctx_shared_session_open(bp, type, ses);
727dd0191d5SShuanglin Wang 	}
728dd0191d5SShuanglin Wang 
729dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
730dd0191d5SShuanglin Wang 		type = BNXT_ULP_SESSION_TYPE_SHARED_WC;
731dd0191d5SShuanglin Wang 		tfp = bnxt_ulp_bp_tfp_get(bp, type);
732dd0191d5SShuanglin Wang 		tfp->session = ulp_tf_session_tfp_get(ses, type);
733dd0191d5SShuanglin Wang 		rc = ulp_tf_ctx_shared_session_open(bp, type, ses);
734dd0191d5SShuanglin Wang 	}
735dd0191d5SShuanglin Wang 
736dd0191d5SShuanglin Wang 	if (!rc)
737dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, true);
738dd0191d5SShuanglin Wang 
739dd0191d5SShuanglin Wang 	return rc;
740dd0191d5SShuanglin Wang }
741dd0191d5SShuanglin Wang 
742dd0191d5SShuanglin Wang static void
743dd0191d5SShuanglin Wang ulp_tf_ctx_shared_session_detach(struct bnxt *bp)
744dd0191d5SShuanglin Wang {
745dd0191d5SShuanglin Wang 	struct tf *tfp;
746dd0191d5SShuanglin Wang 
747dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) {
748dd0191d5SShuanglin Wang 		tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_SHARED);
749dd0191d5SShuanglin Wang 		if (tfp->session) {
750dd0191d5SShuanglin Wang 			tf_close_session(tfp);
751dd0191d5SShuanglin Wang 			tfp->session = NULL;
752dd0191d5SShuanglin Wang 		}
753dd0191d5SShuanglin Wang 	}
754dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
755dd0191d5SShuanglin Wang 		tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_SHARED_WC);
756dd0191d5SShuanglin Wang 		if (tfp->session) {
757dd0191d5SShuanglin Wang 			tf_close_session(tfp);
758dd0191d5SShuanglin Wang 			tfp->session = NULL;
759dd0191d5SShuanglin Wang 		}
760dd0191d5SShuanglin Wang 	}
761dd0191d5SShuanglin Wang 	bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, false);
762dd0191d5SShuanglin Wang }
763dd0191d5SShuanglin Wang 
764dd0191d5SShuanglin Wang /*
765dd0191d5SShuanglin Wang  * Initialize an ULP session.
766dd0191d5SShuanglin Wang  * An ULP session will contain all the resources needed to support rte flow
767dd0191d5SShuanglin Wang  * offloads. A session is initialized as part of rte_eth_device start.
768dd0191d5SShuanglin Wang  * A single vswitch instance can have multiple uplinks which means
769dd0191d5SShuanglin Wang  * rte_eth_device start will be called for each of these devices.
770dd0191d5SShuanglin Wang  * ULP session manager will make sure that a single ULP session is only
771dd0191d5SShuanglin Wang  * initialized once. Apart from this, it also initializes MARK database,
772dd0191d5SShuanglin Wang  * EEM table & flow database. ULP session manager also manages a list of
773dd0191d5SShuanglin Wang  * all opened ULP sessions.
774dd0191d5SShuanglin Wang  */
775dd0191d5SShuanglin Wang static int32_t
776dd0191d5SShuanglin Wang ulp_tf_ctx_session_open(struct bnxt *bp,
777dd0191d5SShuanglin Wang 			struct bnxt_ulp_session_state *session)
778dd0191d5SShuanglin Wang {
779dd0191d5SShuanglin Wang 	struct rte_eth_dev		*ethdev = bp->eth_dev;
780dd0191d5SShuanglin Wang 	int32_t				rc = 0;
781dd0191d5SShuanglin Wang 	struct tf_open_session_parms	params;
782dd0191d5SShuanglin Wang 	struct tf_session_resources	*resources;
783dd0191d5SShuanglin Wang 	uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
784dd0191d5SShuanglin Wang 	uint8_t app_id;
785dd0191d5SShuanglin Wang 	struct tf *tfp;
786dd0191d5SShuanglin Wang 
787dd0191d5SShuanglin Wang 	memset(&params, 0, sizeof(params));
788dd0191d5SShuanglin Wang 
789dd0191d5SShuanglin Wang 	rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
790dd0191d5SShuanglin Wang 					  params.ctrl_chan_name);
791dd0191d5SShuanglin Wang 	if (rc) {
792dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid port %d, rc = %d\n",
793dd0191d5SShuanglin Wang 			     ethdev->data->port_id, rc);
794dd0191d5SShuanglin Wang 		return rc;
795dd0191d5SShuanglin Wang 	}
796dd0191d5SShuanglin Wang 
797dd0191d5SShuanglin Wang 	/* On multi-host system, adjust ctrl_chan_name to avoid confliction */
798dd0191d5SShuanglin Wang 	if (BNXT_MH(bp)) {
799dd0191d5SShuanglin Wang 		rc = ulp_ctx_mh_get_session_name(bp, &params);
800dd0191d5SShuanglin Wang 		if (rc)
801dd0191d5SShuanglin Wang 			return rc;
802dd0191d5SShuanglin Wang 	}
803dd0191d5SShuanglin Wang 
804dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id);
805dd0191d5SShuanglin Wang 	if (rc) {
806dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the app id from ulp.\n");
807dd0191d5SShuanglin Wang 		return -EINVAL;
808dd0191d5SShuanglin Wang 	}
809dd0191d5SShuanglin Wang 
810dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
811dd0191d5SShuanglin Wang 	if (rc) {
812dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n");
813dd0191d5SShuanglin Wang 		return rc;
814dd0191d5SShuanglin Wang 	}
815dd0191d5SShuanglin Wang 
816dd0191d5SShuanglin Wang 	params.device_type = bnxt_ulp_cntxt_convert_dev_id(ulp_dev_id);
817dd0191d5SShuanglin Wang 	resources = &params.resources;
818dd0191d5SShuanglin Wang 	rc = ulp_tf_resources_get(bp->ulp_ctx,
819dd0191d5SShuanglin Wang 				  BNXT_ULP_SESSION_TYPE_DEFAULT,
820dd0191d5SShuanglin Wang 				  resources);
821dd0191d5SShuanglin Wang 	if (rc)
822dd0191d5SShuanglin Wang 		return rc;
823dd0191d5SShuanglin Wang 
824dd0191d5SShuanglin Wang 	params.bp = bp;
825dd0191d5SShuanglin Wang 
826dd0191d5SShuanglin Wang 	tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
827dd0191d5SShuanglin Wang 	rc = tf_open_session(tfp, &params);
828dd0191d5SShuanglin Wang 	if (rc) {
829dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to open TF session - %s, rc = %d\n",
830dd0191d5SShuanglin Wang 			     params.ctrl_chan_name, rc);
831dd0191d5SShuanglin Wang 		return -EINVAL;
832dd0191d5SShuanglin Wang 	}
833dd0191d5SShuanglin Wang 	rc = ulp_tf_session_tfp_set(session, BNXT_ULP_SESSION_TYPE_DEFAULT, tfp);
834dd0191d5SShuanglin Wang 	if (rc) {
835dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to set TF session - %s, rc = %d\n",
836dd0191d5SShuanglin Wang 			     params.ctrl_chan_name, rc);
837dd0191d5SShuanglin Wang 		return -EINVAL;
838dd0191d5SShuanglin Wang 	}
839dd0191d5SShuanglin Wang 	return rc;
840dd0191d5SShuanglin Wang }
841dd0191d5SShuanglin Wang 
842dd0191d5SShuanglin Wang /*
843dd0191d5SShuanglin Wang  * Close the ULP session.
844dd0191d5SShuanglin Wang  * It takes the ulp context pointer.
845dd0191d5SShuanglin Wang  */
846dd0191d5SShuanglin Wang static void
847dd0191d5SShuanglin Wang ulp_tf_ctx_session_close(struct bnxt *bp,
848dd0191d5SShuanglin Wang 			 struct bnxt_ulp_session_state *session)
849dd0191d5SShuanglin Wang {
850dd0191d5SShuanglin Wang 	struct tf *tfp;
851dd0191d5SShuanglin Wang 
852dd0191d5SShuanglin Wang 	/* close the session in the hardware */
853dd0191d5SShuanglin Wang 	if (ulp_tf_session_is_open(session, BNXT_ULP_SESSION_TYPE_DEFAULT)) {
854dd0191d5SShuanglin Wang 		tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
855dd0191d5SShuanglin Wang 		tf_close_session(tfp);
856dd0191d5SShuanglin Wang 	}
857dd0191d5SShuanglin Wang 	ulp_tf_session_tfp_reset(session, BNXT_ULP_SESSION_TYPE_DEFAULT);
858dd0191d5SShuanglin Wang }
859dd0191d5SShuanglin Wang 
860dd0191d5SShuanglin Wang static void
861dd0191d5SShuanglin Wang ulp_tf_init_tbl_scope_parms(struct bnxt *bp,
862dd0191d5SShuanglin Wang 			    struct tf_alloc_tbl_scope_parms *params)
863dd0191d5SShuanglin Wang {
864dd0191d5SShuanglin Wang 	struct bnxt_ulp_device_params	*dparms;
865dd0191d5SShuanglin Wang 	uint32_t dev_id;
866dd0191d5SShuanglin Wang 	int rc;
867dd0191d5SShuanglin Wang 
868dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id);
869dd0191d5SShuanglin Wang 	if (rc)
870dd0191d5SShuanglin Wang 		/* TBD: For now, just use default. */
871dd0191d5SShuanglin Wang 		dparms = 0;
872dd0191d5SShuanglin Wang 	else
873dd0191d5SShuanglin Wang 		dparms = bnxt_ulp_device_params_get(dev_id);
874dd0191d5SShuanglin Wang 
875dd0191d5SShuanglin Wang 	/*
876dd0191d5SShuanglin Wang 	 * Set the flush timer for EEM entries. The value is in 100ms intervals,
877dd0191d5SShuanglin Wang 	 * so 100 is 10s.
878dd0191d5SShuanglin Wang 	 */
879dd0191d5SShuanglin Wang 	params->hw_flow_cache_flush_timer = 100;
880dd0191d5SShuanglin Wang 
881dd0191d5SShuanglin Wang 	if (!dparms) {
882dd0191d5SShuanglin Wang 		params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
883dd0191d5SShuanglin Wang 		params->rx_max_action_entry_sz_in_bits =
884dd0191d5SShuanglin Wang 			BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
885dd0191d5SShuanglin Wang 		params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
886dd0191d5SShuanglin Wang 		params->rx_num_flows_in_k = BNXT_ULP_RX_NUM_FLOWS;
887dd0191d5SShuanglin Wang 
888dd0191d5SShuanglin Wang 		params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
889dd0191d5SShuanglin Wang 		params->tx_max_action_entry_sz_in_bits =
890dd0191d5SShuanglin Wang 			BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
891dd0191d5SShuanglin Wang 		params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
892dd0191d5SShuanglin Wang 		params->tx_num_flows_in_k = BNXT_ULP_TX_NUM_FLOWS;
893dd0191d5SShuanglin Wang 	} else {
894dd0191d5SShuanglin Wang 		params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
895dd0191d5SShuanglin Wang 		params->rx_max_action_entry_sz_in_bits =
896dd0191d5SShuanglin Wang 			BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
897dd0191d5SShuanglin Wang 		params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
898dd0191d5SShuanglin Wang 		params->rx_num_flows_in_k =
899dd0191d5SShuanglin Wang 			dparms->ext_flow_db_num_entries / 1024;
900dd0191d5SShuanglin Wang 
901dd0191d5SShuanglin Wang 		params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
902dd0191d5SShuanglin Wang 		params->tx_max_action_entry_sz_in_bits =
903dd0191d5SShuanglin Wang 			BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
904dd0191d5SShuanglin Wang 		params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
905dd0191d5SShuanglin Wang 		params->tx_num_flows_in_k =
906dd0191d5SShuanglin Wang 			dparms->ext_flow_db_num_entries / 1024;
907dd0191d5SShuanglin Wang 	}
908dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(INFO, "Table Scope initialized with %uK flows.\n",
909dd0191d5SShuanglin Wang 		     params->rx_num_flows_in_k);
910dd0191d5SShuanglin Wang }
911dd0191d5SShuanglin Wang 
912dd0191d5SShuanglin Wang /* Initialize Extended Exact Match host memory. */
913dd0191d5SShuanglin Wang static int32_t
914dd0191d5SShuanglin Wang ulp_tf_eem_tbl_scope_init(struct bnxt *bp)
915dd0191d5SShuanglin Wang {
916dd0191d5SShuanglin Wang 	struct tf_alloc_tbl_scope_parms params = {0};
917dd0191d5SShuanglin Wang 	struct bnxt_ulp_device_params *dparms;
918dd0191d5SShuanglin Wang 	enum bnxt_ulp_flow_mem_type mtype;
919dd0191d5SShuanglin Wang 	uint32_t dev_id;
920dd0191d5SShuanglin Wang 	struct tf *tfp;
921dd0191d5SShuanglin Wang 	int rc;
922dd0191d5SShuanglin Wang 
923dd0191d5SShuanglin Wang 	/* Get the dev specific number of flows that needed to be supported. */
924dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
925dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid device id\n");
926dd0191d5SShuanglin Wang 		return -EINVAL;
927dd0191d5SShuanglin Wang 	}
928dd0191d5SShuanglin Wang 
929dd0191d5SShuanglin Wang 	dparms = bnxt_ulp_device_params_get(dev_id);
930dd0191d5SShuanglin Wang 	if (!dparms) {
931dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "could not fetch the device params\n");
932dd0191d5SShuanglin Wang 		return -ENODEV;
933dd0191d5SShuanglin Wang 	}
934dd0191d5SShuanglin Wang 
935dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_mem_type_get(bp->ulp_ctx, &mtype))
936dd0191d5SShuanglin Wang 		return -EINVAL;
937dd0191d5SShuanglin Wang 	if (mtype != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
938dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO, "Table Scope alloc is not required\n");
939dd0191d5SShuanglin Wang 		return 0;
940dd0191d5SShuanglin Wang 	}
941dd0191d5SShuanglin Wang 
942dd0191d5SShuanglin Wang 	ulp_tf_init_tbl_scope_parms(bp, &params);
943dd0191d5SShuanglin Wang 	tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
944dd0191d5SShuanglin Wang 	rc = tf_alloc_tbl_scope(tfp, &params);
945dd0191d5SShuanglin Wang 	if (rc) {
946dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR,
947dd0191d5SShuanglin Wang 			     "Unable to allocate eem table scope rc = %d\n",
948dd0191d5SShuanglin Wang 			     rc);
949dd0191d5SShuanglin Wang 		return rc;
950dd0191d5SShuanglin Wang 	}
951dd0191d5SShuanglin Wang 
952dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
953dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "TableScope=0x%0x %d\n",
954dd0191d5SShuanglin Wang 		     params.tbl_scope_id,
955dd0191d5SShuanglin Wang 		     params.tbl_scope_id);
956dd0191d5SShuanglin Wang #endif
957dd0191d5SShuanglin Wang 
958dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_tbl_scope_id_set(bp->ulp_ctx, params.tbl_scope_id);
959dd0191d5SShuanglin Wang 	if (rc) {
960dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to set table scope id\n");
961dd0191d5SShuanglin Wang 		return rc;
962dd0191d5SShuanglin Wang 	}
963dd0191d5SShuanglin Wang 
964dd0191d5SShuanglin Wang 	return 0;
965dd0191d5SShuanglin Wang }
966dd0191d5SShuanglin Wang 
967dd0191d5SShuanglin Wang /* Free Extended Exact Match host memory */
968dd0191d5SShuanglin Wang static int32_t
969dd0191d5SShuanglin Wang ulp_tf_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)
970dd0191d5SShuanglin Wang {
971dd0191d5SShuanglin Wang 	struct tf_free_tbl_scope_parms	params = {0};
972dd0191d5SShuanglin Wang 	struct tf			*tfp;
973dd0191d5SShuanglin Wang 	int32_t				rc = 0;
974dd0191d5SShuanglin Wang 	struct bnxt_ulp_device_params *dparms;
975dd0191d5SShuanglin Wang 	enum bnxt_ulp_flow_mem_type mtype;
976dd0191d5SShuanglin Wang 	uint32_t dev_id;
977dd0191d5SShuanglin Wang 
978dd0191d5SShuanglin Wang 	if (!ulp_ctx || !ulp_ctx->cfg_data)
979dd0191d5SShuanglin Wang 		return -EINVAL;
980dd0191d5SShuanglin Wang 
981dd0191d5SShuanglin Wang 	tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT);
982dd0191d5SShuanglin Wang 	if (!tfp) {
983dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to get the truflow pointer\n");
984dd0191d5SShuanglin Wang 		return -EINVAL;
985dd0191d5SShuanglin Wang 	}
986dd0191d5SShuanglin Wang 
987dd0191d5SShuanglin Wang 	/* Get the dev specific number of flows that needed to be supported. */
988dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
989dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Invalid device id\n");
990dd0191d5SShuanglin Wang 		return -EINVAL;
991dd0191d5SShuanglin Wang 	}
992dd0191d5SShuanglin Wang 
993dd0191d5SShuanglin Wang 	dparms = bnxt_ulp_device_params_get(dev_id);
994dd0191d5SShuanglin Wang 	if (!dparms) {
995dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "could not fetch the device params\n");
996dd0191d5SShuanglin Wang 		return -ENODEV;
997dd0191d5SShuanglin Wang 	}
998dd0191d5SShuanglin Wang 
999dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_mem_type_get(ulp_ctx, &mtype))
1000dd0191d5SShuanglin Wang 		return -EINVAL;
1001dd0191d5SShuanglin Wang 	if (mtype != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
1002dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO, "Table Scope free is not required\n");
1003dd0191d5SShuanglin Wang 		return 0;
1004dd0191d5SShuanglin Wang 	}
1005dd0191d5SShuanglin Wang 
1006dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp_ctx, &params.tbl_scope_id);
1007dd0191d5SShuanglin Wang 	if (rc) {
1008dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to get the table scope id\n");
1009dd0191d5SShuanglin Wang 		return -EINVAL;
1010dd0191d5SShuanglin Wang 	}
1011dd0191d5SShuanglin Wang 
1012dd0191d5SShuanglin Wang 	rc = tf_free_tbl_scope(tfp, &params);
1013dd0191d5SShuanglin Wang 	if (rc) {
1014dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to free table scope\n");
1015dd0191d5SShuanglin Wang 		return -EINVAL;
1016dd0191d5SShuanglin Wang 	}
1017dd0191d5SShuanglin Wang 	return rc;
1018dd0191d5SShuanglin Wang }
1019dd0191d5SShuanglin Wang 
1020dd0191d5SShuanglin Wang /* The function to free and deinit the ulp context data. */
1021dd0191d5SShuanglin Wang static int32_t
1022dd0191d5SShuanglin Wang ulp_tf_ctx_deinit(struct bnxt *bp,
1023dd0191d5SShuanglin Wang 		  struct bnxt_ulp_session_state *session)
1024dd0191d5SShuanglin Wang {
1025dd0191d5SShuanglin Wang 	/* close the tf session */
1026dd0191d5SShuanglin Wang 	ulp_tf_ctx_session_close(bp, session);
1027dd0191d5SShuanglin Wang 
1028dd0191d5SShuanglin Wang 	/* The shared session must be closed last. */
1029dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx))
1030dd0191d5SShuanglin Wang 		ulp_tf_ctx_shared_session_close(bp, BNXT_ULP_SESSION_TYPE_SHARED,
1031dd0191d5SShuanglin Wang 						session);
1032dd0191d5SShuanglin Wang 
1033dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx))
1034dd0191d5SShuanglin Wang 		ulp_tf_ctx_shared_session_close(bp,
1035dd0191d5SShuanglin Wang 						BNXT_ULP_SESSION_TYPE_SHARED_WC,
1036dd0191d5SShuanglin Wang 						session);
1037dd0191d5SShuanglin Wang 
1038dd0191d5SShuanglin Wang 	bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, false);
1039dd0191d5SShuanglin Wang 
1040dd0191d5SShuanglin Wang 	/* Free the contents */
1041dd0191d5SShuanglin Wang 	if (session->cfg_data) {
1042dd0191d5SShuanglin Wang 		rte_free(session->cfg_data);
1043dd0191d5SShuanglin Wang 		bp->ulp_ctx->cfg_data = NULL;
1044dd0191d5SShuanglin Wang 		session->cfg_data = NULL;
1045dd0191d5SShuanglin Wang 	}
1046dd0191d5SShuanglin Wang 	return 0;
1047dd0191d5SShuanglin Wang }
1048dd0191d5SShuanglin Wang 
1049dd0191d5SShuanglin Wang /* The function to allocate and initialize the ulp context data. */
1050dd0191d5SShuanglin Wang static int32_t
1051dd0191d5SShuanglin Wang ulp_tf_ctx_init(struct bnxt *bp,
1052dd0191d5SShuanglin Wang 		struct bnxt_ulp_session_state *session)
1053dd0191d5SShuanglin Wang {
1054dd0191d5SShuanglin Wang 	struct bnxt_ulp_data	*ulp_data;
1055dd0191d5SShuanglin Wang 	int32_t			rc = 0;
1056dd0191d5SShuanglin Wang 	enum bnxt_ulp_device_id devid;
1057dd0191d5SShuanglin Wang 	enum bnxt_ulp_session_type stype;
1058dd0191d5SShuanglin Wang 	struct tf *tfp;
1059dd0191d5SShuanglin Wang 
1060dd0191d5SShuanglin Wang 	/* Initialize the context entries list */
1061dd0191d5SShuanglin Wang 	bnxt_ulp_cntxt_list_init();
1062dd0191d5SShuanglin Wang 
1063dd0191d5SShuanglin Wang 	/* Allocate memory to hold ulp context data. */
1064dd0191d5SShuanglin Wang 	ulp_data = rte_zmalloc("bnxt_ulp_data",
1065dd0191d5SShuanglin Wang 			       sizeof(struct bnxt_ulp_data), 0);
1066dd0191d5SShuanglin Wang 	if (!ulp_data) {
1067dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to allocate memory for ulp data\n");
1068dd0191d5SShuanglin Wang 		return -ENOMEM;
1069dd0191d5SShuanglin Wang 	}
1070dd0191d5SShuanglin Wang 
1071dd0191d5SShuanglin Wang 	/* Increment the ulp context data reference count usage. */
1072dd0191d5SShuanglin Wang 	bp->ulp_ctx->cfg_data = ulp_data;
1073dd0191d5SShuanglin Wang 	session->cfg_data = ulp_data;
1074dd0191d5SShuanglin Wang 	ulp_data->ref_cnt++;
1075dd0191d5SShuanglin Wang 	ulp_data->ulp_flags |= BNXT_ULP_VF_REP_ENABLED;
1076dd0191d5SShuanglin Wang 
107794dbd6cfSKishore Padmanabha 	/* Add the context to the context entries list */
107894dbd6cfSKishore Padmanabha 	rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx);
107994dbd6cfSKishore Padmanabha 	if (rc) {
108094dbd6cfSKishore Padmanabha 		BNXT_DRV_DBG(ERR, "Failed to add the context list entry\n");
108194dbd6cfSKishore Padmanabha 		goto error_deinit;
108294dbd6cfSKishore Padmanabha 	}
108394dbd6cfSKishore Padmanabha 
1084dd0191d5SShuanglin Wang 	rc = bnxt_ulp_devid_get(bp, &devid);
1085dd0191d5SShuanglin Wang 	if (rc) {
1086dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to determine device for ULP init.\n");
1087dd0191d5SShuanglin Wang 		goto error_deinit;
1088dd0191d5SShuanglin Wang 	}
1089dd0191d5SShuanglin Wang 
1090dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_dev_id_set(bp->ulp_ctx, devid);
1091dd0191d5SShuanglin Wang 	if (rc) {
1092dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to set device for ULP init.\n");
1093dd0191d5SShuanglin Wang 		goto error_deinit;
1094dd0191d5SShuanglin Wang 	}
1095dd0191d5SShuanglin Wang 
1096dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_app_id_set(bp->ulp_ctx, bp->app_id);
1097dd0191d5SShuanglin Wang 	if (rc) {
1098dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to set app_id for ULP init.\n");
1099dd0191d5SShuanglin Wang 		goto error_deinit;
1100dd0191d5SShuanglin Wang 	}
1101dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "Ulp initialized with app id %d\n", bp->app_id);
1102dd0191d5SShuanglin Wang 
1103dd0191d5SShuanglin Wang 	rc = ulp_tf_cntxt_app_caps_init(bp, bp->app_id, devid);
1104dd0191d5SShuanglin Wang 	if (rc) {
1105dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to set caps for app(%x)/dev(%x)\n",
1106dd0191d5SShuanglin Wang 			     bp->app_id, devid);
1107dd0191d5SShuanglin Wang 		goto error_deinit;
1108dd0191d5SShuanglin Wang 	}
1109dd0191d5SShuanglin Wang 
1110dd0191d5SShuanglin Wang 	if (BNXT_TESTPMD_EN(bp)) {
1111dd0191d5SShuanglin Wang 		ulp_data->ulp_flags &= ~BNXT_ULP_VF_REP_ENABLED;
1112dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Enabled Testpmd forward mode\n");
1113dd0191d5SShuanglin Wang 	}
1114dd0191d5SShuanglin Wang 
1115dd0191d5SShuanglin Wang 	/*
1116dd0191d5SShuanglin Wang 	 * Shared session must be created before first regular session but after
1117dd0191d5SShuanglin Wang 	 * the ulp_ctx is valid.
1118dd0191d5SShuanglin Wang 	 */
1119dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) {
1120dd0191d5SShuanglin Wang 		rc = ulp_tf_ctx_shared_session_open(bp,
1121dd0191d5SShuanglin Wang 						    BNXT_ULP_SESSION_TYPE_SHARED,
1122dd0191d5SShuanglin Wang 						    session);
1123dd0191d5SShuanglin Wang 		if (rc) {
1124dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR, "Unable to open shared session (%d)\n",
1125dd0191d5SShuanglin Wang 				     rc);
1126dd0191d5SShuanglin Wang 			goto error_deinit;
1127dd0191d5SShuanglin Wang 		}
1128dd0191d5SShuanglin Wang 	}
1129dd0191d5SShuanglin Wang 
1130dd0191d5SShuanglin Wang 	/* Multiple session support */
1131dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
1132dd0191d5SShuanglin Wang 		stype = BNXT_ULP_SESSION_TYPE_SHARED_WC;
1133dd0191d5SShuanglin Wang 		rc = ulp_tf_ctx_shared_session_open(bp, stype, session);
1134dd0191d5SShuanglin Wang 		if (rc) {
1135dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR,
1136dd0191d5SShuanglin Wang 				     "Unable to open shared wc session (%d)\n",
1137dd0191d5SShuanglin Wang 				     rc);
1138dd0191d5SShuanglin Wang 			goto error_deinit;
1139dd0191d5SShuanglin Wang 		}
1140dd0191d5SShuanglin Wang 	}
1141dd0191d5SShuanglin Wang 	bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, true);
1142dd0191d5SShuanglin Wang 
1143dd0191d5SShuanglin Wang 	/* Open the ulp session. */
1144dd0191d5SShuanglin Wang 	rc = ulp_tf_ctx_session_open(bp, session);
1145dd0191d5SShuanglin Wang 	if (rc)
1146dd0191d5SShuanglin Wang 		goto error_deinit;
1147dd0191d5SShuanglin Wang 
1148dd0191d5SShuanglin Wang 	tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1149dd0191d5SShuanglin Wang 	bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT, tfp);
1150dd0191d5SShuanglin Wang 	return rc;
1151dd0191d5SShuanglin Wang 
1152dd0191d5SShuanglin Wang error_deinit:
1153dd0191d5SShuanglin Wang 	session->session_opened[BNXT_ULP_SESSION_TYPE_DEFAULT] = 1;
1154dd0191d5SShuanglin Wang 	(void)ulp_tf_ctx_deinit(bp, session);
1155dd0191d5SShuanglin Wang 	return rc;
1156dd0191d5SShuanglin Wang }
1157dd0191d5SShuanglin Wang 
1158dd0191d5SShuanglin Wang /* The function to initialize ulp dparms with devargs */
1159dd0191d5SShuanglin Wang static int32_t
1160dd0191d5SShuanglin Wang ulp_tf_dparms_init(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)
1161dd0191d5SShuanglin Wang {
1162dd0191d5SShuanglin Wang 	struct bnxt_ulp_device_params *dparms;
1163dd0191d5SShuanglin Wang 	uint32_t dev_id = BNXT_ULP_DEVICE_ID_LAST;
1164dd0191d5SShuanglin Wang 
1165dd0191d5SShuanglin Wang 	if (!bp->max_num_kflows) {
1166dd0191d5SShuanglin Wang 		/* Defaults to Internal */
1167dd0191d5SShuanglin Wang 		bnxt_ulp_cntxt_mem_type_set(ulp_ctx,
1168dd0191d5SShuanglin Wang 					    BNXT_ULP_FLOW_MEM_TYPE_INT);
1169dd0191d5SShuanglin Wang 		return 0;
1170dd0191d5SShuanglin Wang 	}
1171dd0191d5SShuanglin Wang 
1172dd0191d5SShuanglin Wang 	/* The max_num_kflows were set, so move to external */
1173dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_mem_type_set(ulp_ctx, BNXT_ULP_FLOW_MEM_TYPE_EXT))
1174dd0191d5SShuanglin Wang 		return -EINVAL;
1175dd0191d5SShuanglin Wang 
1176dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) {
1177dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Failed to get device id\n");
1178dd0191d5SShuanglin Wang 		return -EINVAL;
1179dd0191d5SShuanglin Wang 	}
1180dd0191d5SShuanglin Wang 
1181dd0191d5SShuanglin Wang 	dparms = bnxt_ulp_device_params_get(dev_id);
1182dd0191d5SShuanglin Wang 	if (!dparms) {
1183dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Failed to get device parms\n");
1184dd0191d5SShuanglin Wang 		return -EINVAL;
1185dd0191d5SShuanglin Wang 	}
1186dd0191d5SShuanglin Wang 
1187dd0191d5SShuanglin Wang 	/* num_flows = max_num_kflows * 1024 */
1188dd0191d5SShuanglin Wang 	dparms->ext_flow_db_num_entries = bp->max_num_kflows * 1024;
1189dd0191d5SShuanglin Wang 	/* GFID =  2 * num_flows */
1190dd0191d5SShuanglin Wang 	dparms->mark_db_gfid_entries = dparms->ext_flow_db_num_entries * 2;
1191dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "Set the number of flows = %" PRIu64 "\n",
1192dd0191d5SShuanglin Wang 		     dparms->ext_flow_db_num_entries);
1193dd0191d5SShuanglin Wang 
1194dd0191d5SShuanglin Wang 	return 0;
1195dd0191d5SShuanglin Wang }
1196dd0191d5SShuanglin Wang 
1197dd0191d5SShuanglin Wang static int32_t
1198dd0191d5SShuanglin Wang ulp_tf_ctx_attach(struct bnxt *bp,
1199dd0191d5SShuanglin Wang 	       struct bnxt_ulp_session_state *session)
1200dd0191d5SShuanglin Wang {
1201dd0191d5SShuanglin Wang 	int32_t rc = 0;
1202dd0191d5SShuanglin Wang 	uint32_t flags, dev_id = BNXT_ULP_DEVICE_ID_LAST;
1203dd0191d5SShuanglin Wang 	struct tf *tfp;
1204dd0191d5SShuanglin Wang 	uint8_t app_id;
1205dd0191d5SShuanglin Wang 
1206dd0191d5SShuanglin Wang 	/* Increment the ulp context data reference count usage. */
1207dd0191d5SShuanglin Wang 	bp->ulp_ctx->cfg_data = session->cfg_data;
1208dd0191d5SShuanglin Wang 	bp->ulp_ctx->cfg_data->ref_cnt++;
1209dd0191d5SShuanglin Wang 
1210dd0191d5SShuanglin Wang 	/* update the session details in bnxt tfp */
1211dd0191d5SShuanglin Wang 	tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1212dd0191d5SShuanglin Wang 	tfp->session = ulp_tf_session_tfp_get(session,
1213dd0191d5SShuanglin Wang 					      BNXT_ULP_SESSION_TYPE_DEFAULT);
1214dd0191d5SShuanglin Wang 
1215dd0191d5SShuanglin Wang 	/* Add the context to the context entries list */
1216dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx);
1217dd0191d5SShuanglin Wang 	if (rc) {
1218dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to add the context list entry\n");
1219dd0191d5SShuanglin Wang 		return -EINVAL;
1220dd0191d5SShuanglin Wang 	}
1221dd0191d5SShuanglin Wang 
1222dd0191d5SShuanglin Wang 	/*
1223dd0191d5SShuanglin Wang 	 * The supported flag will be set during the init. Use it now to
1224dd0191d5SShuanglin Wang 	 * know if we should go through the attach.
1225dd0191d5SShuanglin Wang 	 */
1226dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id);
1227dd0191d5SShuanglin Wang 	if (rc) {
1228dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get the app id from ulp.\n");
1229dd0191d5SShuanglin Wang 		return -EINVAL;
1230dd0191d5SShuanglin Wang 	}
1231dd0191d5SShuanglin Wang 
1232dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id);
1233dd0191d5SShuanglin Wang 	if (rc) {
1234dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable do get the dev_id.\n");
1235dd0191d5SShuanglin Wang 		return -EINVAL;
1236dd0191d5SShuanglin Wang 	}
1237dd0191d5SShuanglin Wang 
1238dd0191d5SShuanglin Wang 	flags = bp->ulp_ctx->cfg_data->ulp_flags;
1239dd0191d5SShuanglin Wang 	if (ULP_APP_DEV_UNSUPPORTED_ENABLED(flags)) {
1240dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
1241dd0191d5SShuanglin Wang 			     app_id, dev_id);
1242dd0191d5SShuanglin Wang 		return -EINVAL;
1243dd0191d5SShuanglin Wang 	}
1244dd0191d5SShuanglin Wang 
1245dd0191d5SShuanglin Wang 	/* Create a TF Client */
1246dd0191d5SShuanglin Wang 	rc = ulp_tf_ctx_session_open(bp, session);
1247dd0191d5SShuanglin Wang 	if (rc) {
1248dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to open ctxt session, rc:%d\n", rc);
1249dd0191d5SShuanglin Wang 		tfp->session = NULL;
1250dd0191d5SShuanglin Wang 		return rc;
1251dd0191d5SShuanglin Wang 	}
1252dd0191d5SShuanglin Wang 	tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1253dd0191d5SShuanglin Wang 	bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT, tfp);
1254dd0191d5SShuanglin Wang 
1255dd0191d5SShuanglin Wang 	/*
1256dd0191d5SShuanglin Wang 	 * Attach to the shared session, must be called after the
1257dd0191d5SShuanglin Wang 	 * ulp_ctx_attach in order to ensure that ulp data is available
1258dd0191d5SShuanglin Wang 	 * for attaching.
1259dd0191d5SShuanglin Wang 	 */
1260dd0191d5SShuanglin Wang 	rc = ulp_tf_ctx_shared_session_attach(bp, session);
1261dd0191d5SShuanglin Wang 	if (rc)
1262dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed attach to shared session (%d)", rc);
1263dd0191d5SShuanglin Wang 
1264dd0191d5SShuanglin Wang 	return rc;
1265dd0191d5SShuanglin Wang }
1266dd0191d5SShuanglin Wang 
1267dd0191d5SShuanglin Wang static void
1268dd0191d5SShuanglin Wang ulp_tf_ctx_detach(struct bnxt *bp,
1269dd0191d5SShuanglin Wang 		  struct bnxt_ulp_session_state *session __rte_unused)
1270dd0191d5SShuanglin Wang {
1271dd0191d5SShuanglin Wang 	struct tf *tfp;
1272dd0191d5SShuanglin Wang 
1273dd0191d5SShuanglin Wang 	tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1274dd0191d5SShuanglin Wang 	if (tfp->session) {
1275dd0191d5SShuanglin Wang 		tf_close_session(tfp);
1276dd0191d5SShuanglin Wang 		tfp->session = NULL;
1277dd0191d5SShuanglin Wang 	}
1278dd0191d5SShuanglin Wang 
1279dd0191d5SShuanglin Wang 	/* always detach/close shared after the session. */
1280dd0191d5SShuanglin Wang 	ulp_tf_ctx_shared_session_detach(bp);
1281dd0191d5SShuanglin Wang }
1282dd0191d5SShuanglin Wang 
1283dd0191d5SShuanglin Wang /*
1284dd0191d5SShuanglin Wang  * Internal api to enable NAT feature.
1285dd0191d5SShuanglin Wang  * Set set_flag to 1 to set the value or zero to reset the value.
1286dd0191d5SShuanglin Wang  * returns 0 on success.
1287dd0191d5SShuanglin Wang  */
1288dd0191d5SShuanglin Wang static int32_t
1289dd0191d5SShuanglin Wang ulp_tf_global_cfg_update(struct bnxt *bp,
1290dd0191d5SShuanglin Wang 			 enum tf_dir dir,
1291dd0191d5SShuanglin Wang 			 enum tf_global_config_type type,
1292dd0191d5SShuanglin Wang 			 uint32_t offset,
1293dd0191d5SShuanglin Wang 			 uint32_t value,
1294dd0191d5SShuanglin Wang 			 uint32_t set_flag)
1295dd0191d5SShuanglin Wang {
1296dd0191d5SShuanglin Wang 	uint32_t global_cfg = 0;
1297dd0191d5SShuanglin Wang 	int rc;
1298dd0191d5SShuanglin Wang 	struct tf_global_cfg_parms parms = { 0 };
1299dd0191d5SShuanglin Wang 	struct tf *tfp;
1300dd0191d5SShuanglin Wang 
1301dd0191d5SShuanglin Wang 	/* Initialize the params */
1302dd0191d5SShuanglin Wang 	parms.dir = dir,
1303dd0191d5SShuanglin Wang 	parms.type = type,
1304dd0191d5SShuanglin Wang 	parms.offset = offset,
1305dd0191d5SShuanglin Wang 	parms.config = (uint8_t *)&global_cfg,
1306dd0191d5SShuanglin Wang 	parms.config_sz_in_bytes = sizeof(global_cfg);
1307dd0191d5SShuanglin Wang 
1308dd0191d5SShuanglin Wang 	tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1309dd0191d5SShuanglin Wang 	rc = tf_get_global_cfg(tfp, &parms);
1310dd0191d5SShuanglin Wang 	if (rc) {
1311dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to get global cfg 0x%x rc:%d\n",
1312dd0191d5SShuanglin Wang 			     type, rc);
1313dd0191d5SShuanglin Wang 		return rc;
1314dd0191d5SShuanglin Wang 	}
1315dd0191d5SShuanglin Wang 
1316dd0191d5SShuanglin Wang 	if (set_flag)
1317dd0191d5SShuanglin Wang 		global_cfg |= value;
1318dd0191d5SShuanglin Wang 	else
1319dd0191d5SShuanglin Wang 		global_cfg &= ~value;
1320dd0191d5SShuanglin Wang 
1321dd0191d5SShuanglin Wang 	/* SET the register RE_CFA_REG_ACT_TECT */
1322dd0191d5SShuanglin Wang 	rc = tf_set_global_cfg(tfp, &parms);
1323dd0191d5SShuanglin Wang 	if (rc) {
1324dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to set global cfg 0x%x rc:%d\n",
1325dd0191d5SShuanglin Wang 			     type, rc);
1326dd0191d5SShuanglin Wang 		return rc;
1327dd0191d5SShuanglin Wang 	}
1328dd0191d5SShuanglin Wang 	return rc;
1329dd0191d5SShuanglin Wang }
1330dd0191d5SShuanglin Wang 
133180d760e1SJay Ding /**
133280d760e1SJay Ding  * When a port is initialized by dpdk. This functions is called
133380d760e1SJay Ding  * to enable the meter and initializes the meter global configurations.
133480d760e1SJay Ding  */
133580d760e1SJay Ding #define BNXT_THOR_FMTCR_NUM_MET_MET_1K (0x7UL << 20)
133680d760e1SJay Ding #define BNXT_THOR_FMTCR_CNTRS_ENABLE (0x1UL << 25)
133780d760e1SJay Ding #define BNXT_THOR_FMTCR_INTERVAL_1K (1024)
133880d760e1SJay Ding static int32_t
133980d760e1SJay Ding ulp_tf_flow_mtr_init(struct bnxt *bp)
134080d760e1SJay Ding {
134180d760e1SJay Ding 	int rc = 0;
134280d760e1SJay Ding 
134380d760e1SJay Ding 	/*
134480d760e1SJay Ding 	 * Enable metering. Set the meter global configuration register.
134580d760e1SJay Ding 	 * Set number of meter to 1K. Disable the drop counter for now.
134680d760e1SJay Ding 	 */
134780d760e1SJay Ding 	rc = ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_METER_CFG,
134880d760e1SJay Ding 				      0,
134980d760e1SJay Ding 				      BNXT_THOR_FMTCR_NUM_MET_MET_1K,
135080d760e1SJay Ding 				      1);
135180d760e1SJay Ding 	if (rc) {
135280d760e1SJay Ding 		BNXT_DRV_DBG(ERR, "Failed to set rx meter configuration\n");
135380d760e1SJay Ding 		goto jump_to_error;
135480d760e1SJay Ding 	}
135580d760e1SJay Ding 
135680d760e1SJay Ding 	rc = ulp_tf_global_cfg_update(bp, TF_DIR_TX, TF_METER_CFG,
135780d760e1SJay Ding 				      0,
135880d760e1SJay Ding 				      BNXT_THOR_FMTCR_NUM_MET_MET_1K,
135980d760e1SJay Ding 				      1);
136080d760e1SJay Ding 	if (rc) {
136180d760e1SJay Ding 		BNXT_DRV_DBG(ERR, "Failed to set tx meter configuration\n");
136280d760e1SJay Ding 		goto jump_to_error;
136380d760e1SJay Ding 	}
136480d760e1SJay Ding 
136580d760e1SJay Ding 	/*
136680d760e1SJay Ding 	 * Set meter refresh rate to 1024 clock cycle. This value works for
136780d760e1SJay Ding 	 * most bit rates especially for high rates.
136880d760e1SJay Ding 	 */
136980d760e1SJay Ding 	rc = ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_METER_INTERVAL_CFG,
137080d760e1SJay Ding 				      0,
137180d760e1SJay Ding 				      BNXT_THOR_FMTCR_INTERVAL_1K,
137280d760e1SJay Ding 				      1);
137380d760e1SJay Ding 	if (rc) {
137480d760e1SJay Ding 		BNXT_DRV_DBG(ERR, "Failed to set rx meter interval\n");
137580d760e1SJay Ding 		goto jump_to_error;
137680d760e1SJay Ding 	}
137780d760e1SJay Ding 
137880d760e1SJay Ding 	rc = bnxt_flow_mtr_init(bp);
137980d760e1SJay Ding 	if (rc) {
138080d760e1SJay Ding 		BNXT_DRV_DBG(ERR, "Failed to config meter\n");
138180d760e1SJay Ding 		goto jump_to_error;
138280d760e1SJay Ding 	}
138380d760e1SJay Ding 
138480d760e1SJay Ding 	return rc;
138580d760e1SJay Ding 
138680d760e1SJay Ding jump_to_error:
138780d760e1SJay Ding 	return rc;
138880d760e1SJay Ding }
138980d760e1SJay Ding 
1390dd0191d5SShuanglin Wang /*
1391dd0191d5SShuanglin Wang  * When a port is deinit'ed by dpdk. This function is called
1392dd0191d5SShuanglin Wang  * and this function clears the ULP context and rest of the
1393dd0191d5SShuanglin Wang  * infrastructure associated with it.
1394dd0191d5SShuanglin Wang  */
1395dd0191d5SShuanglin Wang static void
1396dd0191d5SShuanglin Wang ulp_tf_deinit(struct bnxt *bp,
1397dd0191d5SShuanglin Wang 	      struct bnxt_ulp_session_state *session)
1398dd0191d5SShuanglin Wang {
1399dd0191d5SShuanglin Wang 	bool ha_enabled;
1400dd0191d5SShuanglin Wang 
1401dd0191d5SShuanglin Wang 	if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
1402dd0191d5SShuanglin Wang 		return;
1403dd0191d5SShuanglin Wang 
1404dd0191d5SShuanglin Wang 	ha_enabled = bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx);
1405dd0191d5SShuanglin Wang 	if (ha_enabled &&
1406dd0191d5SShuanglin Wang 	    ulp_tf_session_is_open(session, BNXT_ULP_SESSION_TYPE_DEFAULT)) {
1407dd0191d5SShuanglin Wang 		int32_t rc = ulp_ha_mgr_close(bp->ulp_ctx);
1408dd0191d5SShuanglin Wang 		if (rc)
1409dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR, "Failed to close HA (%d)\n", rc);
1410dd0191d5SShuanglin Wang 	}
1411dd0191d5SShuanglin Wang 
1412dd0191d5SShuanglin Wang 	/* cleanup the eem table scope */
1413dd0191d5SShuanglin Wang 	ulp_tf_eem_tbl_scope_deinit(bp, bp->ulp_ctx);
1414dd0191d5SShuanglin Wang 
1415dd0191d5SShuanglin Wang 	/* cleanup the flow database */
1416dd0191d5SShuanglin Wang 	ulp_flow_db_deinit(bp->ulp_ctx);
1417dd0191d5SShuanglin Wang 
1418dd0191d5SShuanglin Wang 	/* Delete the Mark database */
1419dd0191d5SShuanglin Wang 	ulp_mark_db_deinit(bp->ulp_ctx);
1420dd0191d5SShuanglin Wang 
1421dd0191d5SShuanglin Wang 	/* cleanup the ulp mapper */
1422dd0191d5SShuanglin Wang 	ulp_mapper_deinit(bp->ulp_ctx);
1423dd0191d5SShuanglin Wang 
1424dd0191d5SShuanglin Wang 	/* cleanup the ulp matcher */
1425dd0191d5SShuanglin Wang 	ulp_matcher_deinit(bp->ulp_ctx);
1426dd0191d5SShuanglin Wang 
1427dd0191d5SShuanglin Wang 	/* Delete the Flow Counter Manager */
1428dd0191d5SShuanglin Wang 	ulp_fc_mgr_deinit(bp->ulp_ctx);
1429dd0191d5SShuanglin Wang 
1430dd0191d5SShuanglin Wang 	/* Delete the Port database */
1431dd0191d5SShuanglin Wang 	ulp_port_db_deinit(bp->ulp_ctx);
1432dd0191d5SShuanglin Wang 
1433dd0191d5SShuanglin Wang 	/* Disable NAT feature */
1434dd0191d5SShuanglin Wang 	(void)ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
1435dd0191d5SShuanglin Wang 				       TF_TUNNEL_ENCAP_NAT,
1436dd0191d5SShuanglin Wang 				       BNXT_ULP_NAT_OUTER_MOST_FLAGS, 0);
1437dd0191d5SShuanglin Wang 
1438dd0191d5SShuanglin Wang 	(void)ulp_tf_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
1439dd0191d5SShuanglin Wang 				       TF_TUNNEL_ENCAP_NAT,
1440dd0191d5SShuanglin Wang 				       BNXT_ULP_NAT_OUTER_MOST_FLAGS, 0);
1441dd0191d5SShuanglin Wang 
1442dd0191d5SShuanglin Wang 	/* free the flow db lock */
1443dd0191d5SShuanglin Wang 	pthread_mutex_destroy(&bp->ulp_ctx->cfg_data->flow_db_lock);
1444dd0191d5SShuanglin Wang 
1445dd0191d5SShuanglin Wang 	if (ha_enabled)
1446dd0191d5SShuanglin Wang 		ulp_ha_mgr_deinit(bp->ulp_ctx);
1447dd0191d5SShuanglin Wang 
1448dd0191d5SShuanglin Wang 	/* Delete the ulp context and tf session and free the ulp context */
1449dd0191d5SShuanglin Wang 	ulp_tf_ctx_deinit(bp, session);
1450dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "ulp ctx has been deinitialized\n");
1451dd0191d5SShuanglin Wang }
1452dd0191d5SShuanglin Wang 
1453dd0191d5SShuanglin Wang /*
1454dd0191d5SShuanglin Wang  * When a port is initialized by dpdk. This functions is called
1455dd0191d5SShuanglin Wang  * and this function initializes the ULP context and rest of the
1456dd0191d5SShuanglin Wang  * infrastructure associated with it.
1457dd0191d5SShuanglin Wang  */
1458dd0191d5SShuanglin Wang static int32_t
1459dd0191d5SShuanglin Wang ulp_tf_init(struct bnxt *bp,
1460dd0191d5SShuanglin Wang 	    struct bnxt_ulp_session_state *session)
1461dd0191d5SShuanglin Wang {
1462dd0191d5SShuanglin Wang 	int rc;
1463dd0191d5SShuanglin Wang 	uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
1464dd0191d5SShuanglin Wang 
1465b14da654SPeter Spreadborough 	/* Select 64bit SSE4.2 intrinsic if available */
1466b14da654SPeter Spreadborough 	rte_hash_crc_set_alg(CRC32_SSE42_x64);
1467b14da654SPeter Spreadborough 
1468dd0191d5SShuanglin Wang 	/* Allocate and Initialize the ulp context. */
1469dd0191d5SShuanglin Wang 	rc = ulp_tf_ctx_init(bp, session);
1470dd0191d5SShuanglin Wang 	if (rc) {
1471dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to create the ulp context\n");
1472dd0191d5SShuanglin Wang 		goto jump_to_error;
1473dd0191d5SShuanglin Wang 	}
1474dd0191d5SShuanglin Wang 
1475*7d32c003SAriel Otilibili 	pthread_mutex_init(&bp->ulp_ctx->cfg_data->flow_db_lock, NULL);
1476dd0191d5SShuanglin Wang 
1477dd0191d5SShuanglin Wang 	/* Initialize ulp dparms with values devargs passed */
1478dd0191d5SShuanglin Wang 	rc = ulp_tf_dparms_init(bp, bp->ulp_ctx);
1479dd0191d5SShuanglin Wang 	if (rc) {
1480dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to initialize the dparms\n");
1481dd0191d5SShuanglin Wang 		goto jump_to_error;
1482dd0191d5SShuanglin Wang 	}
1483dd0191d5SShuanglin Wang 
1484dd0191d5SShuanglin Wang 	/* create the port database */
1485dd0191d5SShuanglin Wang 	rc = ulp_port_db_init(bp->ulp_ctx, bp->port_cnt);
1486dd0191d5SShuanglin Wang 	if (rc) {
1487dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to create the port database\n");
1488dd0191d5SShuanglin Wang 		goto jump_to_error;
1489dd0191d5SShuanglin Wang 	}
1490dd0191d5SShuanglin Wang 
1491dd0191d5SShuanglin Wang 	/* Create the Mark database. */
1492dd0191d5SShuanglin Wang 	rc = ulp_mark_db_init(bp->ulp_ctx);
1493dd0191d5SShuanglin Wang 	if (rc) {
1494dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to create the mark database\n");
1495dd0191d5SShuanglin Wang 		goto jump_to_error;
1496dd0191d5SShuanglin Wang 	}
1497dd0191d5SShuanglin Wang 
1498dd0191d5SShuanglin Wang 	/* Create the flow database. */
1499dd0191d5SShuanglin Wang 	rc = ulp_flow_db_init(bp->ulp_ctx);
1500dd0191d5SShuanglin Wang 	if (rc) {
1501dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to create the flow database\n");
1502dd0191d5SShuanglin Wang 		goto jump_to_error;
1503dd0191d5SShuanglin Wang 	}
1504dd0191d5SShuanglin Wang 
1505dd0191d5SShuanglin Wang 	/* Create the eem table scope. */
1506dd0191d5SShuanglin Wang 	rc = ulp_tf_eem_tbl_scope_init(bp);
1507dd0191d5SShuanglin Wang 	if (rc) {
1508dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to create the eem scope table\n");
1509dd0191d5SShuanglin Wang 		goto jump_to_error;
1510dd0191d5SShuanglin Wang 	}
1511dd0191d5SShuanglin Wang 
1512dd0191d5SShuanglin Wang 	rc = ulp_matcher_init(bp->ulp_ctx);
1513dd0191d5SShuanglin Wang 	if (rc) {
1514dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to initialize ulp matcher\n");
1515dd0191d5SShuanglin Wang 		goto jump_to_error;
1516dd0191d5SShuanglin Wang 	}
1517dd0191d5SShuanglin Wang 
1518dd0191d5SShuanglin Wang 	rc = ulp_mapper_init(bp->ulp_ctx);
1519dd0191d5SShuanglin Wang 	if (rc) {
1520dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to initialize ulp mapper\n");
1521dd0191d5SShuanglin Wang 		goto jump_to_error;
1522dd0191d5SShuanglin Wang 	}
1523dd0191d5SShuanglin Wang 
1524dd0191d5SShuanglin Wang 	rc = ulp_fc_mgr_init(bp->ulp_ctx);
1525dd0191d5SShuanglin Wang 	if (rc) {
1526dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to initialize ulp flow counter mgr\n");
1527dd0191d5SShuanglin Wang 		goto jump_to_error;
1528dd0191d5SShuanglin Wang 	}
1529dd0191d5SShuanglin Wang 
1530dd0191d5SShuanglin Wang 	/*
1531dd0191d5SShuanglin Wang 	 * Enable NAT feature. Set the global configuration register
1532dd0191d5SShuanglin Wang 	 * Tunnel encap to enable NAT with the reuse of existing inner
1533dd0191d5SShuanglin Wang 	 * L2 header smac and dmac
1534dd0191d5SShuanglin Wang 	 */
1535dd0191d5SShuanglin Wang 	rc = ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
1536dd0191d5SShuanglin Wang 				      TF_TUNNEL_ENCAP_NAT,
1537dd0191d5SShuanglin Wang 				      BNXT_ULP_NAT_OUTER_MOST_FLAGS, 1);
1538dd0191d5SShuanglin Wang 	if (rc) {
1539dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to set rx global configuration\n");
1540dd0191d5SShuanglin Wang 		goto jump_to_error;
1541dd0191d5SShuanglin Wang 	}
1542dd0191d5SShuanglin Wang 
1543dd0191d5SShuanglin Wang 	rc = ulp_tf_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
1544dd0191d5SShuanglin Wang 				      TF_TUNNEL_ENCAP_NAT,
1545dd0191d5SShuanglin Wang 				      BNXT_ULP_NAT_OUTER_MOST_FLAGS, 1);
1546dd0191d5SShuanglin Wang 	if (rc) {
1547dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to set tx global configuration\n");
1548dd0191d5SShuanglin Wang 		goto jump_to_error;
1549dd0191d5SShuanglin Wang 	}
1550dd0191d5SShuanglin Wang 
1551dd0191d5SShuanglin Wang 	if (bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx)) {
1552dd0191d5SShuanglin Wang 		rc = ulp_ha_mgr_init(bp->ulp_ctx);
1553dd0191d5SShuanglin Wang 		if (rc) {
1554dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR, "Failed to initialize HA %d\n", rc);
1555dd0191d5SShuanglin Wang 			goto jump_to_error;
1556dd0191d5SShuanglin Wang 		}
1557dd0191d5SShuanglin Wang 		rc = ulp_ha_mgr_open(bp->ulp_ctx);
1558dd0191d5SShuanglin Wang 		if (rc) {
1559dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR, "Failed to Process HA Open %d\n", rc);
1560dd0191d5SShuanglin Wang 			goto jump_to_error;
1561dd0191d5SShuanglin Wang 		}
1562dd0191d5SShuanglin Wang 	}
1563dd0191d5SShuanglin Wang 
1564dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
1565dd0191d5SShuanglin Wang 	if (rc) {
1566dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n");
1567dd0191d5SShuanglin Wang 		return rc;
1568dd0191d5SShuanglin Wang 	}
1569dd0191d5SShuanglin Wang 
1570dd0191d5SShuanglin Wang 	if (ulp_dev_id == BNXT_ULP_DEVICE_ID_THOR) {
157180d760e1SJay Ding 		rc = ulp_tf_flow_mtr_init(bp);
1572dd0191d5SShuanglin Wang 		if (rc) {
1573dd0191d5SShuanglin Wang 			BNXT_DRV_DBG(ERR, "Failed to config meter\n");
1574dd0191d5SShuanglin Wang 			goto jump_to_error;
1575dd0191d5SShuanglin Wang 		}
1576dd0191d5SShuanglin Wang 	}
1577dd0191d5SShuanglin Wang 
1578dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "ulp ctx has been initialized\n");
1579dd0191d5SShuanglin Wang 	return rc;
1580dd0191d5SShuanglin Wang 
1581dd0191d5SShuanglin Wang jump_to_error:
1582dd0191d5SShuanglin Wang 	bp->ulp_ctx->ops->ulp_deinit(bp, session);
1583dd0191d5SShuanglin Wang 	return rc;
1584dd0191d5SShuanglin Wang }
1585dd0191d5SShuanglin Wang 
158680d760e1SJay Ding /**
158780d760e1SJay Ding  * Get meter capabilities.
158880d760e1SJay Ding  */
158980d760e1SJay Ding #define MAX_FLOW_PER_METER 1024
159080d760e1SJay Ding #define MAX_METER_RATE_100GBPS ((1ULL << 30) * 100 / 8)
159180d760e1SJay Ding static int
159280d760e1SJay Ding ulp_tf_mtr_cap_get(struct bnxt *bp,
159380d760e1SJay Ding 		   struct rte_mtr_capabilities *cap)
159480d760e1SJay Ding {
159580d760e1SJay Ding 	struct tf_get_session_info_parms iparms;
159680d760e1SJay Ding 	struct tf *tfp;
159780d760e1SJay Ding 	int32_t rc = 0;
159880d760e1SJay Ding 
159980d760e1SJay Ding 	/* Get number of meter reserved for this session */
160080d760e1SJay Ding 	memset(&iparms, 0, sizeof(iparms));
160180d760e1SJay Ding 	tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
160280d760e1SJay Ding 	rc = tf_get_session_info(tfp, &iparms);
160380d760e1SJay Ding 	if (rc != 0) {
160480d760e1SJay Ding 		BNXT_DRV_DBG(ERR, "Failed to get session resource info\n");
160580d760e1SJay Ding 		return rc;
160680d760e1SJay Ding 	}
160780d760e1SJay Ding 
160880d760e1SJay Ding 	memset(cap, 0, sizeof(struct rte_mtr_capabilities));
160980d760e1SJay Ding 
161080d760e1SJay Ding 	cap->n_max = iparms.session_info.tbl[TF_DIR_RX].info[TF_TBL_TYPE_METER_INST].stride;
161180d760e1SJay Ding 	if (!cap->n_max) {
161280d760e1SJay Ding 		BNXT_DRV_DBG(ERR, "Meter is not supported\n");
161380d760e1SJay Ding 		return -EINVAL;
161480d760e1SJay Ding 	}
161580d760e1SJay Ding 
161680d760e1SJay Ding #if (RTE_VERSION_NUM(21, 05, 0, 0) <= RTE_VERSION)
161780d760e1SJay Ding 	cap->srtcm_rfc2697_byte_mode_supported = 1;
161880d760e1SJay Ding #endif
161980d760e1SJay Ding 	cap->n_shared_max = cap->n_max;
162080d760e1SJay Ding 	/* No meter is identical */
162180d760e1SJay Ding 	cap->identical = 1;
162280d760e1SJay Ding 	cap->shared_identical = 1;
162380d760e1SJay Ding 	cap->shared_n_flows_per_mtr_max = MAX_FLOW_PER_METER;
162480d760e1SJay Ding 	cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */
162580d760e1SJay Ding 	cap->meter_srtcm_rfc2697_n_max = cap->n_max;
162680d760e1SJay Ding 	cap->meter_rate_max = MAX_METER_RATE_100GBPS;
162780d760e1SJay Ding 	/* No stats supported now */
162880d760e1SJay Ding 	cap->stats_mask = 0;
162980d760e1SJay Ding 
163080d760e1SJay Ding 	return 0;
163180d760e1SJay Ding }
163280d760e1SJay Ding 
1633dd0191d5SShuanglin Wang const struct bnxt_ulp_core_ops bnxt_ulp_tf_core_ops = {
1634dd0191d5SShuanglin Wang 	.ulp_ctx_attach = ulp_tf_ctx_attach,
1635dd0191d5SShuanglin Wang 	.ulp_ctx_detach = ulp_tf_ctx_detach,
1636dd0191d5SShuanglin Wang 	.ulp_deinit =  ulp_tf_deinit,
1637dd0191d5SShuanglin Wang 	.ulp_init =  ulp_tf_init,
1638be4732e8SMike Baucom 	.ulp_vfr_session_fid_add = NULL,
163980d760e1SJay Ding 	.ulp_vfr_session_fid_rem = NULL,
164080d760e1SJay Ding 	.ulp_mtr_cap_get = ulp_tf_mtr_cap_get
1641dd0191d5SShuanglin Wang };
1642