Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2019-2023 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 : :
13 : : #include "bnxt.h"
14 : : #include "bnxt_ulp.h"
15 : : #include "bnxt_tf_common.h"
16 : : #include "hsi_struct_def_dpdk.h"
17 : : #include "tf_core.h"
18 : : #include "tf_ext_flow_handle.h"
19 : :
20 : : #include "ulp_template_db_enum.h"
21 : : #include "ulp_template_struct.h"
22 : : #include "ulp_mark_mgr.h"
23 : : #include "ulp_fc_mgr.h"
24 : : #include "ulp_flow_db.h"
25 : : #include "ulp_mapper.h"
26 : : #include "ulp_port_db.h"
27 : : #include "ulp_tun.h"
28 : : #include "ulp_ha_mgr.h"
29 : : #include "bnxt_tf_pmd_shim.h"
30 : : #include "ulp_template_db_tbl.h"
31 : :
32 : : /* Linked list of all TF sessions. */
33 : : STAILQ_HEAD(, bnxt_ulp_session_state) bnxt_ulp_session_list =
34 : : STAILQ_HEAD_INITIALIZER(bnxt_ulp_session_list);
35 : :
36 : : /* Mutex to synchronize bnxt_ulp_session_list operations. */
37 : : static pthread_mutex_t bnxt_ulp_global_mutex = PTHREAD_MUTEX_INITIALIZER;
38 : :
39 : : /* Spin lock to protect context global list */
40 : : uint32_t bnxt_ulp_ctxt_lock_created;
41 : : rte_spinlock_t bnxt_ulp_ctxt_lock;
42 : : TAILQ_HEAD(cntx_list_entry_list, ulp_context_list_entry);
43 : : static struct cntx_list_entry_list ulp_cntx_list =
44 : : TAILQ_HEAD_INITIALIZER(ulp_cntx_list);
45 : :
46 : : /* Static function declarations */
47 : : static int32_t bnxt_ulp_cntxt_list_init(void);
48 : : static int32_t bnxt_ulp_cntxt_list_add(struct bnxt_ulp_context *ulp_ctx);
49 : : static void bnxt_ulp_cntxt_list_del(struct bnxt_ulp_context *ulp_ctx);
50 : :
51 : : /*
52 : : * Allow the deletion of context only for the bnxt device that
53 : : * created the session.
54 : : */
55 : : bool
56 : 0 : ulp_ctx_deinit_allowed(struct bnxt_ulp_context *ulp_ctx)
57 : : {
58 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
59 : : return false;
60 : :
61 [ # # ]: 0 : if (!ulp_ctx->cfg_data->ref_cnt) {
62 : 0 : BNXT_TF_DBG(DEBUG, "ulp ctx shall initiate deinit\n");
63 : 0 : return true;
64 : : }
65 : :
66 : : return false;
67 : : }
68 : :
69 : : static int32_t
70 : : bnxt_ulp_devid_get(struct bnxt *bp,
71 : : enum bnxt_ulp_device_id *ulp_dev_id)
72 : : {
73 : 0 : if (BNXT_CHIP_P5(bp)) {
74 : : *ulp_dev_id = BNXT_ULP_DEVICE_ID_THOR;
75 : : return 0;
76 : : }
77 : :
78 [ # # ]: 0 : if (BNXT_STINGRAY(bp))
79 : : *ulp_dev_id = BNXT_ULP_DEVICE_ID_STINGRAY;
80 : : else
81 : : /* Assuming P4 */
82 : : *ulp_dev_id = BNXT_ULP_DEVICE_ID_WH_PLUS;
83 : :
84 : : return 0;
85 : : }
86 : :
87 : : struct bnxt_ulp_app_capabilities_info *
88 : 0 : bnxt_ulp_app_cap_list_get(uint32_t *num_entries)
89 : : {
90 [ # # ]: 0 : if (!num_entries)
91 : : return NULL;
92 : 0 : *num_entries = BNXT_ULP_APP_CAP_TBL_MAX_SZ;
93 : 0 : return ulp_app_cap_info_list;
94 : : }
95 : :
96 : : struct bnxt_ulp_shared_act_info *
97 : 0 : bnxt_ulp_shared_act_info_get(uint32_t *num_entries)
98 : : {
99 [ # # ]: 0 : if (!num_entries)
100 : : return NULL;
101 : :
102 : 0 : *num_entries = BNXT_ULP_GEN_TBL_MAX_SZ;
103 : :
104 : 0 : return ulp_shared_act_info;
105 : : }
106 : :
107 : : static struct bnxt_ulp_resource_resv_info *
108 : : bnxt_ulp_app_resource_resv_list_get(uint32_t *num_entries)
109 : : {
110 : : if (num_entries == NULL)
111 : : return NULL;
112 : : *num_entries = BNXT_ULP_APP_RESOURCE_RESV_LIST_MAX_SZ;
113 : : return ulp_app_resource_resv_list;
114 : : }
115 : :
116 : : struct bnxt_ulp_resource_resv_info *
117 : 0 : bnxt_ulp_resource_resv_list_get(uint32_t *num_entries)
118 : : {
119 [ # # ]: 0 : if (!num_entries)
120 : : return NULL;
121 : 0 : *num_entries = BNXT_ULP_RESOURCE_RESV_LIST_MAX_SZ;
122 : 0 : return ulp_resource_resv_list;
123 : : }
124 : :
125 : : struct bnxt_ulp_glb_resource_info *
126 : 0 : bnxt_ulp_app_glb_resource_info_list_get(uint32_t *num_entries)
127 : : {
128 [ # # ]: 0 : if (!num_entries)
129 : : return NULL;
130 : 0 : *num_entries = BNXT_ULP_APP_GLB_RESOURCE_TBL_MAX_SZ;
131 : 0 : return ulp_app_glb_resource_tbl;
132 : : }
133 : :
134 : : static int32_t
135 : 0 : bnxt_ulp_named_resources_calc(struct bnxt_ulp_context *ulp_ctx,
136 : : struct bnxt_ulp_glb_resource_info *info,
137 : : uint32_t num,
138 : : enum bnxt_ulp_session_type stype,
139 : : struct tf_session_resources *res)
140 : : {
141 : 0 : uint32_t dev_id = BNXT_ULP_DEVICE_ID_LAST, res_type, i;
142 : : enum tf_dir dir;
143 : : uint8_t app_id;
144 : : int32_t rc = 0;
145 : :
146 [ # # # # ]: 0 : if (ulp_ctx == NULL || info == NULL || res == NULL || num == 0) {
147 : 0 : BNXT_TF_DBG(ERR, "Invalid parms to named resources calc.\n");
148 : 0 : return -EINVAL;
149 : : }
150 : :
151 : 0 : rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id);
152 [ # # ]: 0 : if (rc) {
153 : 0 : BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n");
154 : 0 : return -EINVAL;
155 : : }
156 : :
157 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id);
158 [ # # ]: 0 : if (rc) {
159 : 0 : BNXT_TF_DBG(ERR, "Unable to get the dev id from ulp.\n");
160 : 0 : return -EINVAL;
161 : : }
162 : :
163 [ # # ]: 0 : for (i = 0; i < num; i++) {
164 [ # # # # ]: 0 : if (dev_id != info[i].device_id || app_id != info[i].app_id)
165 : 0 : continue;
166 : : /* check to see if the session type matches only then include */
167 [ # # # # ]: 0 : if ((stype || info[i].session_type) &&
168 [ # # ]: 0 : !(info[i].session_type & stype))
169 : 0 : continue;
170 : :
171 : 0 : dir = info[i].direction;
172 : 0 : res_type = info[i].resource_type;
173 : :
174 [ # # # # : 0 : switch (info[i].resource_func) {
# ]
175 : 0 : case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
176 : 0 : res->ident_cnt[dir].cnt[res_type]++;
177 : 0 : break;
178 : 0 : case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
179 : 0 : res->tbl_cnt[dir].cnt[res_type]++;
180 : 0 : break;
181 : 0 : case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE:
182 : 0 : res->tcam_cnt[dir].cnt[res_type]++;
183 : 0 : break;
184 : 0 : case BNXT_ULP_RESOURCE_FUNC_EM_TABLE:
185 : 0 : res->em_cnt[dir].cnt[res_type]++;
186 : 0 : break;
187 : 0 : default:
188 : 0 : BNXT_TF_DBG(ERR, "Unknown resource func (0x%x)\n,",
189 : : info[i].resource_func);
190 : 0 : continue;
191 : : }
192 : : }
193 : :
194 : : return 0;
195 : : }
196 : :
197 : : static int32_t
198 : 0 : bnxt_ulp_unnamed_resources_calc(struct bnxt_ulp_context *ulp_ctx,
199 : : struct bnxt_ulp_resource_resv_info *info,
200 : : uint32_t num,
201 : : enum bnxt_ulp_session_type stype,
202 : : struct tf_session_resources *res)
203 : : {
204 : : uint32_t dev_id, res_type, i;
205 : : enum tf_dir dir;
206 : : uint8_t app_id;
207 : : int32_t rc = 0;
208 : :
209 [ # # # # ]: 0 : if (ulp_ctx == NULL || res == NULL || info == NULL || num == 0) {
210 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments to get resources.\n");
211 : 0 : return -EINVAL;
212 : : }
213 : :
214 : 0 : rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id);
215 [ # # ]: 0 : if (rc) {
216 : 0 : BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n");
217 : 0 : return -EINVAL;
218 : : }
219 : :
220 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id);
221 [ # # ]: 0 : if (rc) {
222 : 0 : BNXT_TF_DBG(ERR, "Unable to get the dev id from ulp.\n");
223 : 0 : return -EINVAL;
224 : : }
225 : :
226 [ # # ]: 0 : for (i = 0; i < num; i++) {
227 [ # # # # ]: 0 : if (app_id != info[i].app_id || dev_id != info[i].device_id)
228 : 0 : continue;
229 : :
230 : : /* check to see if the session type matches only then include */
231 [ # # # # ]: 0 : if ((stype || info[i].session_type) &&
232 [ # # ]: 0 : !(info[i].session_type & stype))
233 : 0 : continue;
234 : :
235 : 0 : dir = info[i].direction;
236 : 0 : res_type = info[i].resource_type;
237 : :
238 [ # # # # : 0 : switch (info[i].resource_func) {
# ]
239 : 0 : case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
240 : 0 : res->ident_cnt[dir].cnt[res_type] = info[i].count;
241 : 0 : break;
242 : 0 : case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
243 : 0 : res->tbl_cnt[dir].cnt[res_type] = info[i].count;
244 : 0 : break;
245 : 0 : case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE:
246 : 0 : res->tcam_cnt[dir].cnt[res_type] = info[i].count;
247 : 0 : break;
248 : 0 : case BNXT_ULP_RESOURCE_FUNC_EM_TABLE:
249 : 0 : res->em_cnt[dir].cnt[res_type] = info[i].count;
250 : 0 : break;
251 : : default:
252 : : break;
253 : : }
254 : : }
255 : : return 0;
256 : : }
257 : :
258 : : static int32_t
259 : 0 : bnxt_ulp_tf_resources_get(struct bnxt_ulp_context *ulp_ctx,
260 : : enum bnxt_ulp_session_type stype,
261 : : struct tf_session_resources *res)
262 : : {
263 : : struct bnxt_ulp_resource_resv_info *unnamed = NULL;
264 : : uint32_t unum;
265 : : int32_t rc = 0;
266 : :
267 [ # # ]: 0 : if (ulp_ctx == NULL || res == NULL) {
268 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments to get resources.\n");
269 : 0 : return -EINVAL;
270 : : }
271 : :
272 : : /* use DEFAULT_NON_HA instead of DEFAULT resources if HA is disabled */
273 [ # # ]: 0 : if (ULP_APP_HA_IS_DYNAMIC(ulp_ctx))
274 : 0 : stype = ulp_ctx->cfg_data->def_session_type;
275 : :
276 : 0 : unnamed = bnxt_ulp_resource_resv_list_get(&unum);
277 [ # # ]: 0 : if (unnamed == NULL) {
278 : 0 : BNXT_TF_DBG(ERR, "Unable to get resource resv list.\n");
279 : 0 : return -EINVAL;
280 : : }
281 : :
282 : 0 : rc = bnxt_ulp_unnamed_resources_calc(ulp_ctx, unnamed, unum, stype,
283 : : res);
284 [ # # ]: 0 : if (rc)
285 : 0 : BNXT_TF_DBG(ERR, "Unable to calc resources for session.\n");
286 : :
287 : : return rc;
288 : : }
289 : :
290 : : static int32_t
291 : 0 : bnxt_ulp_tf_shared_session_resources_get(struct bnxt_ulp_context *ulp_ctx,
292 : : enum bnxt_ulp_session_type stype,
293 : : struct tf_session_resources *res)
294 : : {
295 : : struct bnxt_ulp_resource_resv_info *unnamed;
296 : : struct bnxt_ulp_glb_resource_info *named;
297 : : uint32_t unum, nnum;
298 : : int32_t rc;
299 : :
300 [ # # ]: 0 : if (ulp_ctx == NULL || res == NULL) {
301 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments to get resources.\n");
302 : 0 : return -EINVAL;
303 : : }
304 : :
305 : : /* Make sure the resources are zero before accumulating. */
306 : : memset(res, 0, sizeof(struct tf_session_resources));
307 : :
308 [ # # # # ]: 0 : if (bnxt_ulp_cntxt_ha_enabled(ulp_ctx) &&
309 : : stype == BNXT_ULP_SESSION_TYPE_SHARED)
310 : 0 : stype = ulp_ctx->cfg_data->hu_session_type;
311 : :
312 : : /*
313 : : * Shared resources are comprised of both named and unnamed resources.
314 : : * First get the unnamed counts, and then add the named to the result.
315 : : */
316 : : /* Get the baseline counts */
317 : : unnamed = bnxt_ulp_app_resource_resv_list_get(&unum);
318 : : if (unnamed == NULL) {
319 : : BNXT_TF_DBG(ERR, "Unable to get shared resource resv list.\n");
320 : : return -EINVAL;
321 : : }
322 : 0 : rc = bnxt_ulp_unnamed_resources_calc(ulp_ctx, unnamed, unum, stype,
323 : : res);
324 [ # # ]: 0 : if (rc) {
325 : 0 : BNXT_TF_DBG(ERR,
326 : : "Unable to calc resources for shared session.\n");
327 : 0 : return -EINVAL;
328 : : }
329 : :
330 : : /* Get the named list and add the totals */
331 : 0 : named = bnxt_ulp_app_glb_resource_info_list_get(&nnum);
332 [ # # ]: 0 : if (named == NULL) {
333 : 0 : BNXT_TF_DBG(ERR, "Unable to get app global resource list\n");
334 : 0 : return -EINVAL;
335 : : }
336 : 0 : rc = bnxt_ulp_named_resources_calc(ulp_ctx, named, nnum, stype, res);
337 [ # # ]: 0 : if (rc)
338 : 0 : BNXT_TF_DBG(ERR, "Unable to calc named resources\n");
339 : :
340 : : return rc;
341 : : }
342 : :
343 : : /* Function to set the hot upgrade support into the context */
344 : : static int
345 : 0 : bnxt_ulp_multi_shared_session_support_set(struct bnxt *bp,
346 : : enum bnxt_ulp_device_id devid,
347 : : uint32_t fw_hu_update)
348 : : {
349 : 0 : struct bnxt_ulp_context *ulp_ctx = bp->ulp_ctx;
350 : 0 : struct tf_get_version_parms v_params = { 0 };
351 : : struct tf *tfp;
352 : : int32_t rc = 0;
353 : : int32_t new_fw = 0;
354 : :
355 : 0 : v_params.device_type = bnxt_ulp_cntxt_convert_dev_id(devid);
356 : 0 : v_params.bp = bp;
357 : :
358 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
359 : 0 : rc = tf_get_version(tfp, &v_params);
360 [ # # ]: 0 : if (rc) {
361 : 0 : BNXT_TF_DBG(ERR, "Unable to get tf version.\n");
362 : 0 : return rc;
363 : : }
364 : :
365 [ # # ]: 0 : if (v_params.major == 1 && v_params.minor == 0 &&
366 : : v_params.update == 1) {
367 : : new_fw = 1;
368 : : }
369 : : /* if the version update is greater than 0 then set support for
370 : : * multiple version
371 : : */
372 : : if (new_fw) {
373 : 0 : ulp_ctx->cfg_data->ulp_flags |= BNXT_ULP_MULTI_SHARED_SUPPORT;
374 : 0 : ulp_ctx->cfg_data->hu_session_type =
375 : : BNXT_ULP_SESSION_TYPE_SHARED;
376 : : }
377 [ # # ]: 0 : if (!new_fw && fw_hu_update) {
378 : 0 : ulp_ctx->cfg_data->ulp_flags &= ~BNXT_ULP_HIGH_AVAIL_ENABLED;
379 : 0 : ulp_ctx->cfg_data->hu_session_type =
380 : : BNXT_ULP_SESSION_TYPE_SHARED |
381 : : BNXT_ULP_SESSION_TYPE_SHARED_OWC;
382 : : }
383 : :
384 [ # # ]: 0 : if (!new_fw && !fw_hu_update) {
385 : 0 : ulp_ctx->cfg_data->hu_session_type =
386 : : BNXT_ULP_SESSION_TYPE_SHARED |
387 : : BNXT_ULP_SESSION_TYPE_SHARED_OWC;
388 : : }
389 : :
390 : : return rc;
391 : : }
392 : :
393 : : int32_t
394 : 0 : bnxt_ulp_cntxt_app_caps_init(struct bnxt *bp,
395 : : uint8_t app_id, uint32_t dev_id)
396 : : {
397 : : struct bnxt_ulp_app_capabilities_info *info;
398 : 0 : uint32_t num = 0, fw = 0;
399 : : uint16_t i;
400 : : bool found = false;
401 : 0 : struct bnxt_ulp_context *ulp_ctx = bp->ulp_ctx;
402 : :
403 [ # # ]: 0 : if (ULP_APP_DEV_UNSUPPORTED_ENABLED(ulp_ctx->cfg_data->ulp_flags)) {
404 : 0 : BNXT_TF_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
405 : : app_id, dev_id);
406 : 0 : return -EINVAL;
407 : : }
408 : :
409 : 0 : info = bnxt_ulp_app_cap_list_get(&num);
410 [ # # # # ]: 0 : if (!info || !num) {
411 : 0 : BNXT_TF_DBG(ERR, "Failed to get app capabilities.\n");
412 : 0 : return -EINVAL;
413 : : }
414 : :
415 [ # # ]: 0 : for (i = 0; i < num; i++) {
416 [ # # # # ]: 0 : if (info[i].app_id != app_id || info[i].device_id != dev_id)
417 : 0 : continue;
418 : : found = true;
419 [ # # ]: 0 : if (info[i].flags & BNXT_ULP_APP_CAP_SHARED_EN)
420 : 0 : ulp_ctx->cfg_data->ulp_flags |=
421 : : BNXT_ULP_SHARED_SESSION_ENABLED;
422 [ # # ]: 0 : if (info[i].flags & BNXT_ULP_APP_CAP_HOT_UPGRADE_EN)
423 : 0 : ulp_ctx->cfg_data->ulp_flags |=
424 : : BNXT_ULP_HIGH_AVAIL_ENABLED;
425 [ # # ]: 0 : if (info[i].flags & BNXT_ULP_APP_CAP_UNICAST_ONLY)
426 : 0 : ulp_ctx->cfg_data->ulp_flags |=
427 : : BNXT_ULP_APP_UNICAST_ONLY;
428 [ # # ]: 0 : if (info[i].flags & BNXT_ULP_APP_CAP_IP_TOS_PROTO_SUPPORT)
429 : 0 : ulp_ctx->cfg_data->ulp_flags |=
430 : : BNXT_ULP_APP_TOS_PROTO_SUPPORT;
431 [ # # ]: 0 : if (info[i].flags & BNXT_ULP_APP_CAP_BC_MC_SUPPORT)
432 : 0 : ulp_ctx->cfg_data->ulp_flags |=
433 : : BNXT_ULP_APP_BC_MC_SUPPORT;
434 [ # # ]: 0 : if (info[i].flags & BNXT_ULP_APP_CAP_SOCKET_DIRECT) {
435 : : /* Enable socket direction only if MR is enabled in fw*/
436 [ # # ]: 0 : if (BNXT_MULTIROOT_EN(bp)) {
437 : 0 : ulp_ctx->cfg_data->ulp_flags |=
438 : : BNXT_ULP_APP_SOCKET_DIRECT;
439 : 0 : BNXT_TF_DBG(INFO,
440 : : "Socket Direct feature is enabled\n");
441 : : }
442 : : }
443 [ # # ]: 0 : if (info[i].flags & BNXT_ULP_APP_CAP_HA_DYNAMIC) {
444 : : /* Read the environment variable to determine hot up */
445 [ # # ]: 0 : if (!bnxt_pmd_get_hot_upgrade_env()) {
446 : 0 : ulp_ctx->cfg_data->ulp_flags |=
447 : : BNXT_ULP_APP_HA_DYNAMIC;
448 : : /* reset Hot upgrade, dynamically disabled */
449 : 0 : ulp_ctx->cfg_data->ulp_flags &=
450 : : ~BNXT_ULP_HIGH_AVAIL_ENABLED;
451 : 0 : ulp_ctx->cfg_data->def_session_type =
452 : : BNXT_ULP_SESSION_TYPE_DEFAULT_NON_HA;
453 : 0 : BNXT_TF_DBG(INFO, "Hot upgrade disabled.\n");
454 : : }
455 : : }
456 : :
457 : 0 : bnxt_ulp_vxlan_ip_port_set(ulp_ctx, info[i].vxlan_ip_port);
458 : 0 : bnxt_ulp_vxlan_port_set(ulp_ctx, info[i].vxlan_port);
459 : 0 : bnxt_ulp_ecpri_udp_port_set(ulp_ctx, info[i].ecpri_udp_port);
460 : :
461 : : /* set the shared session support from firmware */
462 : 0 : fw = info[i].upgrade_fw_update;
463 [ # # # # ]: 0 : if (ULP_HIGH_AVAIL_IS_ENABLED(ulp_ctx->cfg_data->ulp_flags) &&
464 : 0 : bnxt_ulp_multi_shared_session_support_set(bp, dev_id, fw)) {
465 : 0 : BNXT_TF_DBG(ERR,
466 : : "Unable to get shared session support\n");
467 : 0 : return -EINVAL;
468 : : }
469 : 0 : bnxt_ulp_ha_reg_set(ulp_ctx, info[i].ha_reg_state,
470 : 0 : info[i].ha_reg_cnt);
471 : 0 : ulp_ctx->cfg_data->ha_pool_id = info[i].ha_pool_id;
472 : : }
473 [ # # ]: 0 : if (!found) {
474 : 0 : BNXT_TF_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
475 : : app_id, dev_id);
476 : 0 : ulp_ctx->cfg_data->ulp_flags |= BNXT_ULP_APP_DEV_UNSUPPORTED;
477 : 0 : return -EINVAL;
478 : : }
479 : :
480 : : return 0;
481 : : }
482 : :
483 : : /* Function to retrieve the vxlan_ip (ecpri) port from the context. */
484 : : int
485 : 0 : bnxt_ulp_ecpri_udp_port_set(struct bnxt_ulp_context *ulp_ctx,
486 : : uint32_t ecpri_udp_port)
487 : : {
488 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
489 : : return -EINVAL;
490 : :
491 : 0 : ulp_ctx->cfg_data->ecpri_udp_port = ecpri_udp_port;
492 : :
493 : 0 : return 0;
494 : : }
495 : :
496 : : /* Function to retrieve the vxlan_ip (ecpri) port from the context. */
497 : : unsigned int
498 : 0 : bnxt_ulp_ecpri_udp_port_get(struct bnxt_ulp_context *ulp_ctx)
499 : : {
500 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
501 : : return 0;
502 : :
503 : 0 : return (unsigned int)ulp_ctx->cfg_data->ecpri_udp_port;
504 : : }
505 : :
506 : : /* Function to set the number for vxlan_ip (custom vxlan) port into the context */
507 : : int
508 : 0 : bnxt_ulp_vxlan_ip_port_set(struct bnxt_ulp_context *ulp_ctx,
509 : : uint32_t vxlan_ip_port)
510 : : {
511 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
512 : : return -EINVAL;
513 : :
514 : 0 : ulp_ctx->cfg_data->vxlan_ip_port = vxlan_ip_port;
515 : :
516 : 0 : return 0;
517 : : }
518 : :
519 : : /* Function to retrieve the vxlan_ip (custom vxlan) port from the context. */
520 : : unsigned int
521 : 0 : bnxt_ulp_vxlan_ip_port_get(struct bnxt_ulp_context *ulp_ctx)
522 : : {
523 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
524 : : return 0;
525 : :
526 : 0 : return (unsigned int)ulp_ctx->cfg_data->vxlan_ip_port;
527 : : }
528 : :
529 : : /* Function to set the number for vxlan port into the context */
530 : : int
531 : 0 : bnxt_ulp_vxlan_port_set(struct bnxt_ulp_context *ulp_ctx,
532 : : uint32_t vxlan_port)
533 : : {
534 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
535 : : return -EINVAL;
536 : :
537 : 0 : ulp_ctx->cfg_data->vxlan_port = vxlan_port;
538 : :
539 : 0 : return 0;
540 : : }
541 : :
542 : : /* Function to retrieve the vxlan port from the context. */
543 : : unsigned int
544 : 0 : bnxt_ulp_vxlan_port_get(struct bnxt_ulp_context *ulp_ctx)
545 : : {
546 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
547 : : return 0;
548 : :
549 : 0 : return (unsigned int)ulp_ctx->cfg_data->vxlan_port;
550 : : }
551 : :
552 : : static inline uint32_t
553 : : bnxt_ulp_session_idx_get(enum bnxt_ulp_session_type session_type) {
554 : 0 : if (session_type & BNXT_ULP_SESSION_TYPE_SHARED)
555 : : return 1;
556 [ # # # # ]: 0 : else if (session_type & BNXT_ULP_SESSION_TYPE_SHARED_WC)
557 : 0 : return 2;
558 : : return 0;
559 : : }
560 : :
561 : : /* Function to set the tfp session details in session */
562 : : static int32_t
563 [ # # ]: 0 : bnxt_ulp_session_tfp_set(struct bnxt_ulp_session_state *session,
564 : : enum bnxt_ulp_session_type session_type,
565 : : struct tf *tfp)
566 : : {
567 : : uint32_t idx = bnxt_ulp_session_idx_get(session_type);
568 : : int32_t rc = 0;
569 : :
570 [ # # ]: 0 : if (!session->session_opened[idx]) {
571 : 0 : session->g_tfp[idx] = rte_zmalloc("bnxt_ulp_session_tfp",
572 : : sizeof(struct tf), 0);
573 [ # # ]: 0 : if (!session->g_tfp[idx]) {
574 : 0 : BNXT_TF_DBG(DEBUG, "Failed to alloc session tfp\n");
575 : 0 : return -ENOMEM;
576 : : }
577 : 0 : session->g_tfp[idx]->session = tfp->session;
578 : 0 : session->session_opened[idx] = 1;
579 : : }
580 : : return rc;
581 : : }
582 : :
583 : : /* Function to get the tfp session details in session */
584 : : static struct tf_session_info *
585 : : bnxt_ulp_session_tfp_get(struct bnxt_ulp_session_state *session,
586 : : enum bnxt_ulp_session_type session_type)
587 : : {
588 : : uint32_t idx = bnxt_ulp_session_idx_get(session_type);
589 : :
590 [ # # # # : 0 : if (session->session_opened[idx])
# # ]
591 : 0 : return session->g_tfp[idx]->session;
592 : : return NULL;
593 : : }
594 : :
595 : : static uint32_t
596 : : bnxt_ulp_session_is_open(struct bnxt_ulp_session_state *session,
597 : : enum bnxt_ulp_session_type session_type)
598 : : {
599 : : uint32_t idx = bnxt_ulp_session_idx_get(session_type);
600 : :
601 : 0 : return session->session_opened[idx];
602 : : }
603 : :
604 : : /* Function to reset the tfp session details in session */
605 : : static void
606 [ # # ]: 0 : bnxt_ulp_session_tfp_reset(struct bnxt_ulp_session_state *session,
607 : : enum bnxt_ulp_session_type session_type)
608 : : {
609 : : uint32_t idx = bnxt_ulp_session_idx_get(session_type);
610 : :
611 [ # # # # ]: 0 : if (session->session_opened[idx]) {
612 : 0 : session->session_opened[idx] = 0;
613 : 0 : rte_free(session->g_tfp[idx]);
614 : 0 : session->g_tfp[idx] = NULL;
615 : : }
616 : 0 : }
617 : :
618 : : static void
619 : 0 : ulp_ctx_shared_session_close(struct bnxt *bp,
620 : : enum bnxt_ulp_session_type session_type,
621 : : struct bnxt_ulp_session_state *session)
622 : : {
623 : : struct tf *tfp;
624 : : int32_t rc;
625 : :
626 : 0 : tfp = bnxt_ulp_cntxt_tfp_get(bp->ulp_ctx, session_type);
627 [ # # ]: 0 : if (!tfp) {
628 : : /*
629 : : * Log it under debug since this is likely a case of the
630 : : * shared session not being created. For example, a failed
631 : : * initialization.
632 : : */
633 : 0 : BNXT_TF_DBG(DEBUG, "Failed to get shared tfp on close.\n");
634 : 0 : return;
635 : : }
636 : 0 : rc = tf_close_session(tfp);
637 [ # # ]: 0 : if (rc)
638 : 0 : BNXT_TF_DBG(ERR, "Failed to close the shared session rc=%d.\n",
639 : : rc);
640 : 0 : (void)bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session_type, NULL);
641 : 0 : bnxt_ulp_session_tfp_reset(session, session_type);
642 : : }
643 : :
644 : : static int32_t
645 : 0 : ulp_ctx_mh_get_session_name(struct bnxt *bp,
646 : : struct tf_open_session_parms *parms)
647 : : {
648 : : int32_t rc = 0;
649 : 0 : unsigned int domain = 0, bus = 0, slot = 0, device = 0;
650 : 0 : rc = sscanf(parms->ctrl_chan_name,
651 : : "%x:%x:%x.%u",
652 : : &domain,
653 : : &bus,
654 : : &slot,
655 : : &device);
656 [ # # ]: 0 : if (rc != 4) {
657 : : /* PCI Domain not provided (optional in DPDK), thus we
658 : : * force domain to 0 and recheck.
659 : : */
660 : 0 : domain = 0;
661 : : /* Check parsing of bus/slot/device */
662 : 0 : rc = sscanf(parms->ctrl_chan_name,
663 : : "%x:%x.%u",
664 : : &bus,
665 : : &slot,
666 : : &device);
667 [ # # ]: 0 : if (rc != 3) {
668 : 0 : BNXT_TF_DBG(DEBUG,
669 : : "Failed to scan device ctrl_chan_name\n");
670 : 0 : return -EINVAL;
671 : : }
672 : : }
673 : :
674 : : /* change domain name for multi-host system */
675 : 0 : domain = domain + (0xf & bp->multi_host_pf_pci_id);
676 : 0 : sprintf(parms->ctrl_chan_name,
677 : : "%x:%x:%x.%u",
678 : : domain,
679 : : bus,
680 : : slot,
681 : : device);
682 : 0 : BNXT_TF_DBG(DEBUG,
683 : : "Session name for Multi-Host: ctrl_chan_name:%s\n", parms->ctrl_chan_name);
684 : 0 : return 0;
685 : : }
686 : :
687 : : static int32_t
688 : 0 : ulp_ctx_shared_session_open(struct bnxt *bp,
689 : : enum bnxt_ulp_session_type session_type,
690 : : struct bnxt_ulp_session_state *session)
691 : : {
692 : 0 : struct rte_eth_dev *ethdev = bp->eth_dev;
693 : : struct tf_session_resources *resources;
694 : : struct tf_open_session_parms parms;
695 : : size_t nb;
696 : 0 : uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
697 : : int32_t rc = 0;
698 : : uint8_t app_id;
699 : : struct tf *tfp;
700 : : uint8_t pool_id;
701 : :
702 : : memset(&parms, 0, sizeof(parms));
703 : 0 : rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
704 : : parms.ctrl_chan_name);
705 [ # # ]: 0 : if (rc) {
706 : 0 : BNXT_TF_DBG(ERR, "Invalid port %d, rc = %d\n",
707 : : ethdev->data->port_id, rc);
708 : 0 : return rc;
709 : : }
710 : :
711 : : /* On multi-host system, adjust ctrl_chan_name to avoid confliction */
712 [ # # ]: 0 : if (BNXT_MH(bp)) {
713 : 0 : rc = ulp_ctx_mh_get_session_name(bp, &parms);
714 [ # # ]: 0 : if (rc)
715 : : return rc;
716 : : }
717 : :
718 : : resources = &parms.resources;
719 : :
720 : : /*
721 : : * Need to account for size of ctrl_chan_name and 1 extra for Null
722 : : * terminator
723 : : */
724 : 0 : nb = sizeof(parms.ctrl_chan_name) - strlen(parms.ctrl_chan_name) - 1;
725 : :
726 : : /*
727 : : * Build the ctrl_chan_name with shared token.
728 : : * When HA is enabled, the WC TCAM needs extra management by the core,
729 : : * so add the wc_tcam string to the control channel.
730 : : */
731 : 0 : pool_id = bp->ulp_ctx->cfg_data->ha_pool_id;
732 [ # # ]: 0 : if (!bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
733 [ # # ]: 0 : if (bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx))
734 : : strncat(parms.ctrl_chan_name, "-tf_shared-wc_tcam", nb);
735 : : else
736 : : strncat(parms.ctrl_chan_name, "-tf_shared", nb);
737 [ # # ]: 0 : } else if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
738 [ # # ]: 0 : if (session_type == BNXT_ULP_SESSION_TYPE_SHARED) {
739 : : strncat(parms.ctrl_chan_name, "-tf_shared", nb);
740 [ # # ]: 0 : } else if (session_type == BNXT_ULP_SESSION_TYPE_SHARED_WC) {
741 : : char session_pool_name[64];
742 : :
743 [ # # ]: 0 : sprintf(session_pool_name, "-tf_shared-pool%d",
744 : : pool_id);
745 : :
746 [ # # ]: 0 : if (nb >= strlen(session_pool_name)) {
747 : : strncat(parms.ctrl_chan_name, session_pool_name, nb);
748 : : } else {
749 : 0 : BNXT_TF_DBG(ERR, "No space left for session_name\n");
750 : 0 : return -EINVAL;
751 : : }
752 : : }
753 : : }
754 : :
755 : 0 : rc = bnxt_ulp_tf_shared_session_resources_get(bp->ulp_ctx, session_type,
756 : : resources);
757 [ # # ]: 0 : if (rc)
758 : : return rc;
759 : :
760 : 0 : rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id);
761 [ # # ]: 0 : if (rc) {
762 : 0 : BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n");
763 : 0 : return -EINVAL;
764 : : }
765 : :
766 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
767 [ # # ]: 0 : if (rc) {
768 : 0 : BNXT_TF_DBG(ERR, "Unable to get device id from ulp.\n");
769 : 0 : return rc;
770 : : }
771 : :
772 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, session_type);
773 : 0 : parms.device_type = bnxt_ulp_cntxt_convert_dev_id(ulp_dev_id);
774 : 0 : parms.bp = bp;
775 : :
776 : : /*
777 : : * Open the session here, but the collect the resources during the
778 : : * mapper initialization.
779 : : */
780 : 0 : rc = tf_open_session(tfp, &parms);
781 [ # # ]: 0 : if (rc)
782 : : return rc;
783 : :
784 [ # # ]: 0 : if (parms.shared_session_creator)
785 : 0 : BNXT_TF_DBG(DEBUG, "Shared session creator.\n");
786 : : else
787 : 0 : BNXT_TF_DBG(DEBUG, "Shared session attached.\n");
788 : :
789 : : /* Save the shared session in global data */
790 : 0 : rc = bnxt_ulp_session_tfp_set(session, session_type, tfp);
791 [ # # ]: 0 : if (rc) {
792 : 0 : BNXT_TF_DBG(ERR, "Failed to add shared tfp to session\n");
793 : 0 : return rc;
794 : : }
795 : :
796 : 0 : rc = bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session_type, tfp);
797 [ # # ]: 0 : if (rc) {
798 : 0 : BNXT_TF_DBG(ERR, "Failed to add shared tfp to ulp (%d)\n", rc);
799 : 0 : return rc;
800 : : }
801 : :
802 : : return rc;
803 : : }
804 : :
805 : : static int32_t
806 : 0 : ulp_ctx_shared_session_attach(struct bnxt *bp,
807 : : struct bnxt_ulp_session_state *ses)
808 : : {
809 : : enum bnxt_ulp_session_type type;
810 : : struct tf *tfp;
811 : : int32_t rc = 0;
812 : :
813 : : /* Simply return success if shared session not enabled */
814 [ # # ]: 0 : if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) {
815 : : type = BNXT_ULP_SESSION_TYPE_SHARED;
816 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, type);
817 : 0 : tfp->session = bnxt_ulp_session_tfp_get(ses, type);
818 : 0 : rc = ulp_ctx_shared_session_open(bp, type, ses);
819 : : }
820 : :
821 [ # # ]: 0 : if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
822 : : type = BNXT_ULP_SESSION_TYPE_SHARED_WC;
823 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, type);
824 : 0 : tfp->session = bnxt_ulp_session_tfp_get(ses, type);
825 : 0 : rc = ulp_ctx_shared_session_open(bp, type, ses);
826 : : }
827 : :
828 [ # # ]: 0 : if (!rc)
829 : 0 : bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, true);
830 : :
831 : 0 : return rc;
832 : : }
833 : :
834 : : static void
835 : 0 : ulp_ctx_shared_session_detach(struct bnxt *bp)
836 : : {
837 : : struct tf *tfp;
838 : :
839 [ # # ]: 0 : if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) {
840 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_SHARED);
841 [ # # ]: 0 : if (tfp->session) {
842 : 0 : tf_close_session(tfp);
843 : 0 : tfp->session = NULL;
844 : : }
845 : : }
846 [ # # ]: 0 : if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
847 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_SHARED_WC);
848 [ # # ]: 0 : if (tfp->session) {
849 : 0 : tf_close_session(tfp);
850 : 0 : tfp->session = NULL;
851 : : }
852 : : }
853 : 0 : bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, false);
854 : 0 : }
855 : :
856 : : /*
857 : : * Initialize an ULP session.
858 : : * An ULP session will contain all the resources needed to support rte flow
859 : : * offloads. A session is initialized as part of rte_eth_device start.
860 : : * A single vswitch instance can have multiple uplinks which means
861 : : * rte_eth_device start will be called for each of these devices.
862 : : * ULP session manager will make sure that a single ULP session is only
863 : : * initialized once. Apart from this, it also initializes MARK database,
864 : : * EEM table & flow database. ULP session manager also manages a list of
865 : : * all opened ULP sessions.
866 : : */
867 : : static int32_t
868 : 0 : ulp_ctx_session_open(struct bnxt *bp,
869 : : struct bnxt_ulp_session_state *session)
870 : : {
871 : 0 : struct rte_eth_dev *ethdev = bp->eth_dev;
872 : : int32_t rc = 0;
873 : : struct tf_open_session_parms params;
874 : : struct tf_session_resources *resources;
875 : 0 : uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
876 : : uint8_t app_id;
877 : : struct tf *tfp;
878 : :
879 : : memset(¶ms, 0, sizeof(params));
880 : :
881 : 0 : rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
882 : : params.ctrl_chan_name);
883 [ # # ]: 0 : if (rc) {
884 : 0 : BNXT_TF_DBG(ERR, "Invalid port %d, rc = %d\n",
885 : : ethdev->data->port_id, rc);
886 : 0 : return rc;
887 : : }
888 : :
889 : : /* On multi-host system, adjust ctrl_chan_name to avoid confliction */
890 [ # # ]: 0 : if (BNXT_MH(bp)) {
891 : 0 : rc = ulp_ctx_mh_get_session_name(bp, ¶ms);
892 [ # # ]: 0 : if (rc)
893 : : return rc;
894 : : }
895 : :
896 : 0 : rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id);
897 [ # # ]: 0 : if (rc) {
898 : 0 : BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n");
899 : 0 : return -EINVAL;
900 : : }
901 : :
902 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
903 [ # # ]: 0 : if (rc) {
904 : 0 : BNXT_TF_DBG(ERR, "Unable to get device id from ulp.\n");
905 : 0 : return rc;
906 : : }
907 : :
908 : 0 : params.device_type = bnxt_ulp_cntxt_convert_dev_id(ulp_dev_id);
909 : : resources = ¶ms.resources;
910 : 0 : rc = bnxt_ulp_tf_resources_get(bp->ulp_ctx,
911 : : BNXT_ULP_SESSION_TYPE_DEFAULT,
912 : : resources);
913 [ # # ]: 0 : if (rc)
914 : : return rc;
915 : :
916 : 0 : params.bp = bp;
917 : :
918 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
919 : 0 : rc = tf_open_session(tfp, ¶ms);
920 [ # # ]: 0 : if (rc) {
921 : 0 : BNXT_TF_DBG(ERR, "Failed to open TF session - %s, rc = %d\n",
922 : : params.ctrl_chan_name, rc);
923 : 0 : return -EINVAL;
924 : : }
925 : 0 : rc = bnxt_ulp_session_tfp_set(session,
926 : : BNXT_ULP_SESSION_TYPE_DEFAULT, tfp);
927 [ # # ]: 0 : if (rc) {
928 : 0 : BNXT_TF_DBG(ERR, "Failed to set TF session - %s, rc = %d\n",
929 : : params.ctrl_chan_name, rc);
930 : 0 : return -EINVAL;
931 : : }
932 : : return rc;
933 : : }
934 : :
935 : : /*
936 : : * Close the ULP session.
937 : : * It takes the ulp context pointer.
938 : : */
939 : : static void
940 : 0 : ulp_ctx_session_close(struct bnxt *bp,
941 : : struct bnxt_ulp_session_state *session)
942 : : {
943 : : struct tf *tfp;
944 : :
945 : : /* close the session in the hardware */
946 [ # # ]: 0 : if (bnxt_ulp_session_is_open(session, BNXT_ULP_SESSION_TYPE_DEFAULT)) {
947 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
948 : 0 : tf_close_session(tfp);
949 : : }
950 : : bnxt_ulp_session_tfp_reset(session, BNXT_ULP_SESSION_TYPE_DEFAULT);
951 : 0 : }
952 : :
953 : : static void
954 : 0 : bnxt_init_tbl_scope_parms(struct bnxt *bp,
955 : : struct tf_alloc_tbl_scope_parms *params)
956 : : {
957 : : struct bnxt_ulp_device_params *dparms;
958 : : uint32_t dev_id;
959 : : int rc;
960 : :
961 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id);
962 [ # # ]: 0 : if (rc)
963 : : /* TBD: For now, just use default. */
964 : : dparms = 0;
965 : : else
966 : 0 : dparms = bnxt_ulp_device_params_get(dev_id);
967 : :
968 : : /*
969 : : * Set the flush timer for EEM entries. The value is in 100ms intervals,
970 : : * so 100 is 10s.
971 : : */
972 : 0 : params->hw_flow_cache_flush_timer = 100;
973 : :
974 [ # # ]: 0 : if (!dparms) {
975 : 0 : params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
976 : 0 : params->rx_max_action_entry_sz_in_bits =
977 : : BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
978 : 0 : params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
979 : 0 : params->rx_num_flows_in_k = BNXT_ULP_RX_NUM_FLOWS;
980 : :
981 : 0 : params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
982 : 0 : params->tx_max_action_entry_sz_in_bits =
983 : : BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
984 : 0 : params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
985 : 0 : params->tx_num_flows_in_k = BNXT_ULP_TX_NUM_FLOWS;
986 : : } else {
987 : 0 : params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
988 : 0 : params->rx_max_action_entry_sz_in_bits =
989 : : BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
990 : 0 : params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
991 : 0 : params->rx_num_flows_in_k =
992 : 0 : dparms->ext_flow_db_num_entries / 1024;
993 : :
994 : 0 : params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
995 : 0 : params->tx_max_action_entry_sz_in_bits =
996 : : BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
997 : 0 : params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
998 : 0 : params->tx_num_flows_in_k =
999 : : dparms->ext_flow_db_num_entries / 1024;
1000 : : }
1001 : 0 : BNXT_TF_DBG(INFO, "Table Scope initialized with %uK flows.\n",
1002 : : params->rx_num_flows_in_k);
1003 : 0 : }
1004 : :
1005 : : /* Initialize Extended Exact Match host memory. */
1006 : : static int32_t
1007 : 0 : ulp_eem_tbl_scope_init(struct bnxt *bp)
1008 : : {
1009 : 0 : struct tf_alloc_tbl_scope_parms params = {0};
1010 : : struct bnxt_ulp_device_params *dparms;
1011 : : enum bnxt_ulp_flow_mem_type mtype;
1012 : : uint32_t dev_id;
1013 : : struct tf *tfp;
1014 : : int rc;
1015 : :
1016 : : /* Get the dev specific number of flows that needed to be supported. */
1017 [ # # ]: 0 : if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
1018 : 0 : BNXT_TF_DBG(ERR, "Invalid device id\n");
1019 : 0 : return -EINVAL;
1020 : : }
1021 : :
1022 : 0 : dparms = bnxt_ulp_device_params_get(dev_id);
1023 [ # # ]: 0 : if (!dparms) {
1024 : 0 : BNXT_TF_DBG(ERR, "could not fetch the device params\n");
1025 : 0 : return -ENODEV;
1026 : : }
1027 : :
1028 [ # # ]: 0 : if (bnxt_ulp_cntxt_mem_type_get(bp->ulp_ctx, &mtype))
1029 : : return -EINVAL;
1030 [ # # ]: 0 : if (mtype != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
1031 : 0 : BNXT_TF_DBG(INFO, "Table Scope alloc is not required\n");
1032 : 0 : return 0;
1033 : : }
1034 : :
1035 : 0 : bnxt_init_tbl_scope_parms(bp, ¶ms);
1036 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1037 : 0 : rc = tf_alloc_tbl_scope(tfp, ¶ms);
1038 [ # # ]: 0 : if (rc) {
1039 : 0 : BNXT_TF_DBG(ERR, "Unable to allocate eem table scope rc = %d\n",
1040 : : rc);
1041 : 0 : return rc;
1042 : : }
1043 : :
1044 : 0 : rc = bnxt_ulp_cntxt_tbl_scope_id_set(bp->ulp_ctx, params.tbl_scope_id);
1045 [ # # ]: 0 : if (rc) {
1046 : 0 : BNXT_TF_DBG(ERR, "Unable to set table scope id\n");
1047 : 0 : return rc;
1048 : : }
1049 : :
1050 : : return 0;
1051 : : }
1052 : :
1053 : : /* Free Extended Exact Match host memory */
1054 : : static int32_t
1055 : 0 : ulp_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)
1056 : : {
1057 : 0 : struct tf_free_tbl_scope_parms params = {0};
1058 : : struct tf *tfp;
1059 : : int32_t rc = 0;
1060 : : struct bnxt_ulp_device_params *dparms;
1061 : : enum bnxt_ulp_flow_mem_type mtype;
1062 : : uint32_t dev_id;
1063 : :
1064 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
1065 : : return -EINVAL;
1066 : :
1067 : 0 : tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT);
1068 [ # # ]: 0 : if (!tfp) {
1069 : 0 : BNXT_TF_DBG(ERR, "Failed to get the truflow pointer\n");
1070 : 0 : return -EINVAL;
1071 : : }
1072 : :
1073 : : /* Get the dev specific number of flows that needed to be supported. */
1074 [ # # ]: 0 : if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
1075 : 0 : BNXT_TF_DBG(ERR, "Invalid device id\n");
1076 : 0 : return -EINVAL;
1077 : : }
1078 : :
1079 : 0 : dparms = bnxt_ulp_device_params_get(dev_id);
1080 [ # # ]: 0 : if (!dparms) {
1081 : 0 : BNXT_TF_DBG(ERR, "could not fetch the device params\n");
1082 : 0 : return -ENODEV;
1083 : : }
1084 : :
1085 [ # # ]: 0 : if (bnxt_ulp_cntxt_mem_type_get(ulp_ctx, &mtype))
1086 : : return -EINVAL;
1087 [ # # ]: 0 : if (mtype != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
1088 : 0 : BNXT_TF_DBG(INFO, "Table Scope free is not required\n");
1089 : 0 : return 0;
1090 : : }
1091 : :
1092 : 0 : rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp_ctx, ¶ms.tbl_scope_id);
1093 [ # # ]: 0 : if (rc) {
1094 : 0 : BNXT_TF_DBG(ERR, "Failed to get the table scope id\n");
1095 : 0 : return -EINVAL;
1096 : : }
1097 : :
1098 : 0 : rc = tf_free_tbl_scope(tfp, ¶ms);
1099 [ # # ]: 0 : if (rc) {
1100 : 0 : BNXT_TF_DBG(ERR, "Unable to free table scope\n");
1101 : 0 : return -EINVAL;
1102 : : }
1103 : : return rc;
1104 : : }
1105 : :
1106 : : /* The function to free and deinit the ulp context data. */
1107 : : static int32_t
1108 : 0 : ulp_ctx_deinit(struct bnxt *bp,
1109 : : struct bnxt_ulp_session_state *session)
1110 : : {
1111 : : /* close the tf session */
1112 : 0 : ulp_ctx_session_close(bp, session);
1113 : :
1114 : : /* The shared session must be closed last. */
1115 [ # # ]: 0 : if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx))
1116 : 0 : ulp_ctx_shared_session_close(bp, BNXT_ULP_SESSION_TYPE_SHARED,
1117 : : session);
1118 : :
1119 [ # # ]: 0 : if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx))
1120 : 0 : ulp_ctx_shared_session_close(bp,
1121 : : BNXT_ULP_SESSION_TYPE_SHARED_WC,
1122 : : session);
1123 : :
1124 : 0 : bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, false);
1125 : :
1126 : : /* Free the contents */
1127 [ # # ]: 0 : if (session->cfg_data) {
1128 : 0 : rte_free(session->cfg_data);
1129 : 0 : bp->ulp_ctx->cfg_data = NULL;
1130 : 0 : session->cfg_data = NULL;
1131 : : }
1132 : 0 : return 0;
1133 : : }
1134 : :
1135 : : /* The function to allocate and initialize the ulp context data. */
1136 : : static int32_t
1137 : 0 : ulp_ctx_init(struct bnxt *bp,
1138 : : struct bnxt_ulp_session_state *session)
1139 : : {
1140 : : struct bnxt_ulp_data *ulp_data;
1141 : : int32_t rc = 0;
1142 : : enum bnxt_ulp_device_id devid;
1143 : : enum bnxt_ulp_session_type stype;
1144 : : struct tf *tfp;
1145 : :
1146 : : /* Initialize the context entries list */
1147 : : bnxt_ulp_cntxt_list_init();
1148 : :
1149 : : /* Add the context to the context entries list */
1150 : 0 : rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx);
1151 [ # # ]: 0 : if (rc) {
1152 : 0 : BNXT_TF_DBG(ERR, "Failed to add the context list entry\n");
1153 : 0 : return -ENOMEM;
1154 : : }
1155 : :
1156 : : /* Allocate memory to hold ulp context data. */
1157 : 0 : ulp_data = rte_zmalloc("bnxt_ulp_data",
1158 : : sizeof(struct bnxt_ulp_data), 0);
1159 [ # # ]: 0 : if (!ulp_data) {
1160 : 0 : BNXT_TF_DBG(ERR, "Failed to allocate memory for ulp data\n");
1161 : 0 : return -ENOMEM;
1162 : : }
1163 : :
1164 : : /* Increment the ulp context data reference count usage. */
1165 : 0 : bp->ulp_ctx->cfg_data = ulp_data;
1166 : 0 : session->cfg_data = ulp_data;
1167 : 0 : ulp_data->ref_cnt++;
1168 [ # # ]: 0 : ulp_data->ulp_flags |= BNXT_ULP_VF_REP_ENABLED;
1169 : :
1170 : : rc = bnxt_ulp_devid_get(bp, &devid);
1171 : : if (rc) {
1172 : : BNXT_TF_DBG(ERR, "Unable to determine device for ULP init.\n");
1173 : : goto error_deinit;
1174 : : }
1175 : :
1176 : 0 : rc = bnxt_ulp_cntxt_dev_id_set(bp->ulp_ctx, devid);
1177 [ # # ]: 0 : if (rc) {
1178 : 0 : BNXT_TF_DBG(ERR, "Unable to set device for ULP init.\n");
1179 : 0 : goto error_deinit;
1180 : : }
1181 : :
1182 : 0 : rc = bnxt_ulp_cntxt_app_id_set(bp->ulp_ctx, bp->app_id);
1183 [ # # ]: 0 : if (rc) {
1184 : 0 : BNXT_TF_DBG(ERR, "Unable to set app_id for ULP init.\n");
1185 : 0 : goto error_deinit;
1186 : : }
1187 : 0 : BNXT_TF_DBG(DEBUG, "Ulp initialized with app id %d\n", bp->app_id);
1188 : :
1189 : 0 : rc = bnxt_ulp_cntxt_app_caps_init(bp, bp->app_id, devid);
1190 [ # # ]: 0 : if (rc) {
1191 : 0 : BNXT_TF_DBG(ERR, "Unable to set caps for app(%x)/dev(%x)\n",
1192 : : bp->app_id, devid);
1193 : 0 : goto error_deinit;
1194 : : }
1195 : :
1196 [ # # ]: 0 : if (BNXT_TESTPMD_EN(bp)) {
1197 : 0 : ulp_data->ulp_flags &= ~BNXT_ULP_VF_REP_ENABLED;
1198 : 0 : BNXT_TF_DBG(ERR, "Enabled Testpmd forward mode\n");
1199 : : }
1200 : :
1201 : : /*
1202 : : * Shared session must be created before first regular session but after
1203 : : * the ulp_ctx is valid.
1204 : : */
1205 [ # # ]: 0 : if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) {
1206 : 0 : rc = ulp_ctx_shared_session_open(bp,
1207 : : BNXT_ULP_SESSION_TYPE_SHARED,
1208 : : session);
1209 [ # # ]: 0 : if (rc) {
1210 : 0 : BNXT_TF_DBG(ERR, "Unable to open shared session (%d)\n",
1211 : : rc);
1212 : 0 : goto error_deinit;
1213 : : }
1214 : : }
1215 : :
1216 : : /* Multiple session support */
1217 [ # # ]: 0 : if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
1218 : : stype = BNXT_ULP_SESSION_TYPE_SHARED_WC;
1219 : 0 : rc = ulp_ctx_shared_session_open(bp, stype, session);
1220 [ # # ]: 0 : if (rc) {
1221 : 0 : BNXT_TF_DBG(ERR,
1222 : : "Unable to open shared wc session (%d)\n",
1223 : : rc);
1224 : 0 : goto error_deinit;
1225 : : }
1226 : : }
1227 : 0 : bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, true);
1228 : :
1229 : : /* Open the ulp session. */
1230 : 0 : rc = ulp_ctx_session_open(bp, session);
1231 [ # # ]: 0 : if (rc)
1232 : 0 : goto error_deinit;
1233 : :
1234 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1235 : 0 : bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT, tfp);
1236 : 0 : return rc;
1237 : :
1238 : 0 : error_deinit:
1239 : 0 : session->session_opened[BNXT_ULP_SESSION_TYPE_DEFAULT] = 1;
1240 : 0 : (void)ulp_ctx_deinit(bp, session);
1241 : 0 : return rc;
1242 : : }
1243 : :
1244 : : /* The function to initialize ulp dparms with devargs */
1245 : : static int32_t
1246 : 0 : ulp_dparms_init(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)
1247 : : {
1248 : : struct bnxt_ulp_device_params *dparms;
1249 : 0 : uint32_t dev_id = BNXT_ULP_DEVICE_ID_LAST;
1250 : :
1251 [ # # ]: 0 : if (!bp->max_num_kflows) {
1252 : : /* Defaults to Internal */
1253 : 0 : bnxt_ulp_cntxt_mem_type_set(ulp_ctx,
1254 : : BNXT_ULP_FLOW_MEM_TYPE_INT);
1255 : 0 : return 0;
1256 : : }
1257 : :
1258 : : /* The max_num_kflows were set, so move to external */
1259 [ # # ]: 0 : if (bnxt_ulp_cntxt_mem_type_set(ulp_ctx, BNXT_ULP_FLOW_MEM_TYPE_EXT))
1260 : : return -EINVAL;
1261 : :
1262 [ # # ]: 0 : if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) {
1263 : 0 : BNXT_TF_DBG(DEBUG, "Failed to get device id\n");
1264 : 0 : return -EINVAL;
1265 : : }
1266 : :
1267 : 0 : dparms = bnxt_ulp_device_params_get(dev_id);
1268 [ # # ]: 0 : if (!dparms) {
1269 : 0 : BNXT_TF_DBG(DEBUG, "Failed to get device parms\n");
1270 : 0 : return -EINVAL;
1271 : : }
1272 : :
1273 : : /* num_flows = max_num_kflows * 1024 */
1274 : 0 : dparms->ext_flow_db_num_entries = bp->max_num_kflows * 1024;
1275 : : /* GFID = 2 * num_flows */
1276 : 0 : dparms->mark_db_gfid_entries = dparms->ext_flow_db_num_entries * 2;
1277 : 0 : BNXT_TF_DBG(DEBUG, "Set the number of flows = %" PRIu64 "\n",
1278 : : dparms->ext_flow_db_num_entries);
1279 : :
1280 : 0 : return 0;
1281 : : }
1282 : :
1283 : : /* The function to initialize bp flags with truflow features */
1284 : : static int32_t
1285 : : ulp_dparms_dev_port_intf_update(struct bnxt *bp,
1286 : : struct bnxt_ulp_context *ulp_ctx)
1287 : : {
1288 : : enum bnxt_ulp_flow_mem_type mtype;
1289 : :
1290 [ # # ]: 0 : if (bnxt_ulp_cntxt_mem_type_get(ulp_ctx, &mtype))
1291 : : return -EINVAL;
1292 : : /* Update the bp flag with gfid flag */
1293 [ # # ]: 0 : if (mtype == BNXT_ULP_FLOW_MEM_TYPE_EXT)
1294 : 0 : bp->flags |= BNXT_FLAG_GFID_ENABLE;
1295 : :
1296 : : return 0;
1297 : : }
1298 : :
1299 : : static int32_t
1300 : 0 : ulp_ctx_attach(struct bnxt *bp,
1301 : : struct bnxt_ulp_session_state *session)
1302 : : {
1303 : : int32_t rc = 0;
1304 : 0 : uint32_t flags, dev_id = BNXT_ULP_DEVICE_ID_LAST;
1305 : : struct tf *tfp;
1306 : : uint8_t app_id;
1307 : :
1308 : : /* Increment the ulp context data reference count usage. */
1309 : 0 : bp->ulp_ctx->cfg_data = session->cfg_data;
1310 : 0 : bp->ulp_ctx->cfg_data->ref_cnt++;
1311 : :
1312 : : /* update the session details in bnxt tfp */
1313 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1314 : 0 : tfp->session = bnxt_ulp_session_tfp_get(session,
1315 : : BNXT_ULP_SESSION_TYPE_DEFAULT);
1316 : :
1317 : : /* Add the context to the context entries list */
1318 : 0 : rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx);
1319 [ # # ]: 0 : if (rc) {
1320 : 0 : BNXT_TF_DBG(ERR, "Failed to add the context list entry\n");
1321 : 0 : return -EINVAL;
1322 : : }
1323 : :
1324 : : /*
1325 : : * The supported flag will be set during the init. Use it now to
1326 : : * know if we should go through the attach.
1327 : : */
1328 : 0 : rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id);
1329 [ # # ]: 0 : if (rc) {
1330 : 0 : BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n");
1331 : 0 : return -EINVAL;
1332 : : }
1333 : :
1334 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id);
1335 [ # # ]: 0 : if (rc) {
1336 : 0 : BNXT_TF_DBG(ERR, "Unable do get the dev_id.\n");
1337 : 0 : return -EINVAL;
1338 : : }
1339 : :
1340 : 0 : flags = bp->ulp_ctx->cfg_data->ulp_flags;
1341 [ # # ]: 0 : if (ULP_APP_DEV_UNSUPPORTED_ENABLED(flags)) {
1342 : 0 : BNXT_TF_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
1343 : : app_id, dev_id);
1344 : 0 : return -EINVAL;
1345 : : }
1346 : :
1347 : : /* Create a TF Client */
1348 : 0 : rc = ulp_ctx_session_open(bp, session);
1349 [ # # ]: 0 : if (rc) {
1350 : 0 : PMD_DRV_LOG(ERR, "Failed to open ctxt session, rc:%d\n", rc);
1351 : 0 : tfp->session = NULL;
1352 : 0 : return rc;
1353 : : }
1354 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1355 : 0 : bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT, tfp);
1356 : 0 : return rc;
1357 : : }
1358 : :
1359 : : static void
1360 : 0 : ulp_ctx_detach(struct bnxt *bp)
1361 : : {
1362 : : struct tf *tfp;
1363 : :
1364 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1365 [ # # ]: 0 : if (tfp->session) {
1366 : 0 : tf_close_session(tfp);
1367 : 0 : tfp->session = NULL;
1368 : : }
1369 : 0 : }
1370 : :
1371 : : /*
1372 : : * Initialize the state of an ULP session.
1373 : : * If the state of an ULP session is not initialized, set it's state to
1374 : : * initialized. If the state is already initialized, do nothing.
1375 : : */
1376 : : static void
1377 : 0 : ulp_context_initialized(struct bnxt_ulp_session_state *session, bool *init)
1378 : : {
1379 : 0 : pthread_mutex_lock(&session->bnxt_ulp_mutex);
1380 : :
1381 [ # # ]: 0 : if (!session->bnxt_ulp_init) {
1382 : 0 : session->bnxt_ulp_init = true;
1383 : 0 : *init = false;
1384 : : } else {
1385 : 0 : *init = true;
1386 : : }
1387 : :
1388 : 0 : pthread_mutex_unlock(&session->bnxt_ulp_mutex);
1389 : 0 : }
1390 : :
1391 : : /*
1392 : : * Check if an ULP session is already allocated for a specific PCI
1393 : : * domain & bus. If it is already allocated simply return the session
1394 : : * pointer, otherwise allocate a new session.
1395 : : */
1396 : : static struct bnxt_ulp_session_state *
1397 : 0 : ulp_get_session(struct bnxt *bp, struct rte_pci_addr *pci_addr)
1398 : : {
1399 : : struct bnxt_ulp_session_state *session;
1400 : :
1401 : : /* if multi root capability is enabled, then ignore the pci bus id */
1402 [ # # ]: 0 : STAILQ_FOREACH(session, &bnxt_ulp_session_list, next) {
1403 [ # # ]: 0 : if (BNXT_MULTIROOT_EN(bp)) {
1404 [ # # ]: 0 : if (!memcmp(bp->dsn, session->dsn,
1405 : : sizeof(session->dsn))) {
1406 : 0 : return session;
1407 : : }
1408 [ # # ]: 0 : } else if (session->pci_info.domain == pci_addr->domain &&
1409 [ # # ]: 0 : session->pci_info.bus == pci_addr->bus) {
1410 : 0 : return session;
1411 : : }
1412 : : }
1413 : : return NULL;
1414 : : }
1415 : :
1416 : : /*
1417 : : * Allocate and Initialize an ULP session and set it's state to INITIALIZED.
1418 : : * If it's already initialized simply return the already existing session.
1419 : : */
1420 : : static struct bnxt_ulp_session_state *
1421 : 0 : ulp_session_init(struct bnxt *bp,
1422 : : bool *init)
1423 : : {
1424 : : struct rte_pci_device *pci_dev;
1425 : : struct rte_pci_addr *pci_addr;
1426 : : struct bnxt_ulp_session_state *session;
1427 : : int rc = 0;
1428 : :
1429 [ # # ]: 0 : if (!bp)
1430 : : return NULL;
1431 : :
1432 : 0 : pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
1433 : 0 : pci_addr = &pci_dev->addr;
1434 : :
1435 : 0 : pthread_mutex_lock(&bnxt_ulp_global_mutex);
1436 : :
1437 : 0 : session = ulp_get_session(bp, pci_addr);
1438 [ # # ]: 0 : if (!session) {
1439 : : /* Not Found the session Allocate a new one */
1440 : 0 : session = rte_zmalloc("bnxt_ulp_session",
1441 : : sizeof(struct bnxt_ulp_session_state),
1442 : : 0);
1443 [ # # ]: 0 : if (!session) {
1444 : 0 : BNXT_TF_DBG(ERR,
1445 : : "Allocation failed for bnxt_ulp_session\n");
1446 : 0 : pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1447 : 0 : return NULL;
1448 : :
1449 : : } else {
1450 : : /* Add it to the queue */
1451 : 0 : session->pci_info.domain = pci_addr->domain;
1452 : 0 : session->pci_info.bus = pci_addr->bus;
1453 : 0 : memcpy(session->dsn, bp->dsn, sizeof(session->dsn));
1454 : 0 : rc = pthread_mutex_init(&session->bnxt_ulp_mutex, NULL);
1455 [ # # ]: 0 : if (rc) {
1456 : 0 : BNXT_TF_DBG(ERR, "mutex create failed\n");
1457 : 0 : pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1458 : 0 : return NULL;
1459 : : }
1460 : 0 : STAILQ_INSERT_TAIL(&bnxt_ulp_session_list,
1461 : : session, next);
1462 : : }
1463 : : }
1464 : 0 : ulp_context_initialized(session, init);
1465 : 0 : pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1466 : 0 : return session;
1467 : : }
1468 : :
1469 : : /*
1470 : : * When a device is closed, remove it's associated session from the global
1471 : : * session list.
1472 : : */
1473 : : static void
1474 : 0 : ulp_session_deinit(struct bnxt_ulp_session_state *session)
1475 : : {
1476 [ # # ]: 0 : if (!session)
1477 : : return;
1478 : :
1479 [ # # ]: 0 : if (!session->cfg_data) {
1480 : 0 : pthread_mutex_lock(&bnxt_ulp_global_mutex);
1481 [ # # # # : 0 : STAILQ_REMOVE(&bnxt_ulp_session_list, session,
# # # # ]
1482 : : bnxt_ulp_session_state, next);
1483 : 0 : pthread_mutex_destroy(&session->bnxt_ulp_mutex);
1484 : 0 : rte_free(session);
1485 : 0 : pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1486 : : }
1487 : : }
1488 : :
1489 : : /*
1490 : : * Internal api to enable NAT feature.
1491 : : * Set set_flag to 1 to set the value or zero to reset the value.
1492 : : * returns 0 on success.
1493 : : */
1494 : : static int32_t
1495 : 0 : bnxt_ulp_global_cfg_update(struct bnxt *bp,
1496 : : enum tf_dir dir,
1497 : : enum tf_global_config_type type,
1498 : : uint32_t offset,
1499 : : uint32_t value,
1500 : : uint32_t set_flag)
1501 : : {
1502 : 0 : uint32_t global_cfg = 0;
1503 : : int rc;
1504 : 0 : struct tf_global_cfg_parms parms = { 0 };
1505 : : struct tf *tfp;
1506 : :
1507 : : /* Initialize the params */
1508 : 0 : parms.dir = dir,
1509 : 0 : parms.type = type,
1510 : 0 : parms.offset = offset,
1511 : 0 : parms.config = (uint8_t *)&global_cfg,
1512 : 0 : parms.config_sz_in_bytes = sizeof(global_cfg);
1513 : :
1514 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1515 : 0 : rc = tf_get_global_cfg(tfp, &parms);
1516 [ # # ]: 0 : if (rc) {
1517 : 0 : BNXT_TF_DBG(ERR, "Failed to get global cfg 0x%x rc:%d\n",
1518 : : type, rc);
1519 : 0 : return rc;
1520 : : }
1521 : :
1522 [ # # ]: 0 : if (set_flag)
1523 : 0 : global_cfg |= value;
1524 : : else
1525 : 0 : global_cfg &= ~value;
1526 : :
1527 : : /* SET the register RE_CFA_REG_ACT_TECT */
1528 : 0 : rc = tf_set_global_cfg(tfp, &parms);
1529 [ # # ]: 0 : if (rc) {
1530 : 0 : BNXT_TF_DBG(ERR, "Failed to set global cfg 0x%x rc:%d\n",
1531 : : type, rc);
1532 : 0 : return rc;
1533 : : }
1534 : : return rc;
1535 : : }
1536 : :
1537 : : /* Internal function to delete all the flows belonging to the given port */
1538 : : static void
1539 : 0 : bnxt_ulp_flush_port_flows(struct bnxt *bp)
1540 : : {
1541 : : uint16_t func_id;
1542 : :
1543 : : /* it is assumed that port is either TVF or PF */
1544 [ # # ]: 0 : if (ulp_port_db_port_func_id_get(bp->ulp_ctx,
1545 : 0 : bp->eth_dev->data->port_id,
1546 : : &func_id)) {
1547 : 0 : BNXT_TF_DBG(ERR, "Invalid argument\n");
1548 : 0 : return;
1549 : : }
1550 : 0 : (void)ulp_flow_db_function_flow_flush(bp->ulp_ctx, func_id);
1551 : : }
1552 : :
1553 : : /* Internal function to delete the VFR default flows */
1554 : : static void
1555 : 0 : bnxt_ulp_destroy_vfr_default_rules(struct bnxt *bp, bool global)
1556 : : {
1557 : : struct bnxt_ulp_vfr_rule_info *info;
1558 : : uint16_t port_id;
1559 : : struct rte_eth_dev *vfr_eth_dev;
1560 : : struct bnxt_representor *vfr_bp;
1561 : :
1562 [ # # # # : 0 : if (!BNXT_TRUFLOW_EN(bp) || rte_eth_dev_is_repr(bp->eth_dev))
# # ]
1563 : : return;
1564 : :
1565 [ # # # # ]: 0 : if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
1566 : : return;
1567 : :
1568 : : /* Delete default rules for all ports */
1569 [ # # ]: 0 : for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
1570 : 0 : info = &bp->ulp_ctx->cfg_data->vfr_rule_info[port_id];
1571 [ # # ]: 0 : if (!info->valid)
1572 : 0 : continue;
1573 : :
1574 [ # # ]: 0 : if (!global && info->parent_port_id !=
1575 [ # # ]: 0 : bp->eth_dev->data->port_id)
1576 : 0 : continue;
1577 : :
1578 : : /* Destroy the flows */
1579 : 0 : ulp_default_flow_destroy(bp->eth_dev, info->vfr_flow_id);
1580 : : /* Clean up the tx action pointer */
1581 : : vfr_eth_dev = &rte_eth_devices[port_id];
1582 : : if (vfr_eth_dev) {
1583 : 0 : vfr_bp = vfr_eth_dev->data->dev_private;
1584 : 0 : vfr_bp->vfr_tx_cfa_action = 0;
1585 : : }
1586 : : memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));
1587 : : }
1588 : : }
1589 : :
1590 : : /*
1591 : : * When a port is deinit'ed by dpdk. This function is called
1592 : : * and this function clears the ULP context and rest of the
1593 : : * infrastructure associated with it.
1594 : : */
1595 : : static void
1596 : 0 : bnxt_ulp_deinit(struct bnxt *bp,
1597 : : struct bnxt_ulp_session_state *session)
1598 : : {
1599 : : bool ha_enabled;
1600 : :
1601 [ # # # # ]: 0 : if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
1602 : : return;
1603 : :
1604 : 0 : ha_enabled = bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx);
1605 [ # # # # ]: 0 : if (ha_enabled &&
1606 : : bnxt_ulp_session_is_open(session, BNXT_ULP_SESSION_TYPE_DEFAULT)) {
1607 : 0 : int32_t rc = ulp_ha_mgr_close(bp->ulp_ctx);
1608 [ # # ]: 0 : if (rc)
1609 : 0 : BNXT_TF_DBG(ERR, "Failed to close HA (%d)\n", rc);
1610 : : }
1611 : :
1612 : : /* clean up default flows */
1613 : 0 : bnxt_ulp_destroy_df_rules(bp, true);
1614 : :
1615 : : /* clean up default VFR flows */
1616 : 0 : bnxt_ulp_destroy_vfr_default_rules(bp, true);
1617 : :
1618 : : /* clean up regular flows */
1619 : 0 : ulp_flow_db_flush_flows(bp->ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR);
1620 : :
1621 : : /* cleanup the eem table scope */
1622 : 0 : ulp_eem_tbl_scope_deinit(bp, bp->ulp_ctx);
1623 : :
1624 : : /* cleanup the flow database */
1625 : 0 : ulp_flow_db_deinit(bp->ulp_ctx);
1626 : :
1627 : : /* Delete the Mark database */
1628 : 0 : ulp_mark_db_deinit(bp->ulp_ctx);
1629 : :
1630 : : /* cleanup the ulp mapper */
1631 : 0 : ulp_mapper_deinit(bp->ulp_ctx);
1632 : :
1633 : : /* Delete the Flow Counter Manager */
1634 : 0 : ulp_fc_mgr_deinit(bp->ulp_ctx);
1635 : :
1636 : : /* Delete the Port database */
1637 : 0 : ulp_port_db_deinit(bp->ulp_ctx);
1638 : :
1639 : : /* Disable NAT feature */
1640 : 0 : (void)bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
1641 : : TF_TUNNEL_ENCAP_NAT,
1642 : : BNXT_ULP_NAT_OUTER_MOST_FLAGS, 0);
1643 : :
1644 : 0 : (void)bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
1645 : : TF_TUNNEL_ENCAP_NAT,
1646 : : BNXT_ULP_NAT_OUTER_MOST_FLAGS, 0);
1647 : :
1648 : : /* free the flow db lock */
1649 : 0 : pthread_mutex_destroy(&bp->ulp_ctx->cfg_data->flow_db_lock);
1650 : :
1651 [ # # ]: 0 : if (ha_enabled)
1652 : 0 : ulp_ha_mgr_deinit(bp->ulp_ctx);
1653 : :
1654 : : /* Delete the ulp context and tf session and free the ulp context */
1655 : 0 : ulp_ctx_deinit(bp, session);
1656 : 0 : BNXT_TF_DBG(DEBUG, "ulp ctx has been deinitialized\n");
1657 : : }
1658 : :
1659 : : /*
1660 : : * When a port is initialized by dpdk. This functions is called
1661 : : * and this function initializes the ULP context and rest of the
1662 : : * infrastructure associated with it.
1663 : : */
1664 : : static int32_t
1665 : 0 : bnxt_ulp_init(struct bnxt *bp,
1666 : : struct bnxt_ulp_session_state *session)
1667 : : {
1668 : : int rc;
1669 : 0 : uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
1670 : :
1671 : : /* Allocate and Initialize the ulp context. */
1672 : 0 : rc = ulp_ctx_init(bp, session);
1673 [ # # ]: 0 : if (rc) {
1674 : 0 : BNXT_TF_DBG(ERR, "Failed to create the ulp context\n");
1675 : 0 : goto jump_to_error;
1676 : : }
1677 : :
1678 : 0 : rc = pthread_mutex_init(&bp->ulp_ctx->cfg_data->flow_db_lock, NULL);
1679 [ # # ]: 0 : if (rc) {
1680 : 0 : BNXT_TF_DBG(ERR, "Unable to initialize flow db lock\n");
1681 : 0 : goto jump_to_error;
1682 : : }
1683 : :
1684 : : /* Initialize ulp dparms with values devargs passed */
1685 : 0 : rc = ulp_dparms_init(bp, bp->ulp_ctx);
1686 [ # # ]: 0 : if (rc) {
1687 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize the dparms\n");
1688 : 0 : goto jump_to_error;
1689 : : }
1690 : :
1691 : : /* create the port database */
1692 : 0 : rc = ulp_port_db_init(bp->ulp_ctx, bp->port_cnt);
1693 [ # # ]: 0 : if (rc) {
1694 : 0 : BNXT_TF_DBG(ERR, "Failed to create the port database\n");
1695 : 0 : goto jump_to_error;
1696 : : }
1697 : :
1698 : : /* Create the Mark database. */
1699 : 0 : rc = ulp_mark_db_init(bp->ulp_ctx);
1700 [ # # ]: 0 : if (rc) {
1701 : 0 : BNXT_TF_DBG(ERR, "Failed to create the mark database\n");
1702 : 0 : goto jump_to_error;
1703 : : }
1704 : :
1705 : : /* Create the flow database. */
1706 : 0 : rc = ulp_flow_db_init(bp->ulp_ctx);
1707 [ # # ]: 0 : if (rc) {
1708 : 0 : BNXT_TF_DBG(ERR, "Failed to create the flow database\n");
1709 : 0 : goto jump_to_error;
1710 : : }
1711 : :
1712 : : /* Create the eem table scope. */
1713 : 0 : rc = ulp_eem_tbl_scope_init(bp);
1714 [ # # ]: 0 : if (rc) {
1715 : 0 : BNXT_TF_DBG(ERR, "Failed to create the eem scope table\n");
1716 : 0 : goto jump_to_error;
1717 : : }
1718 : :
1719 : 0 : rc = ulp_mapper_init(bp->ulp_ctx);
1720 [ # # ]: 0 : if (rc) {
1721 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize ulp mapper\n");
1722 : 0 : goto jump_to_error;
1723 : : }
1724 : :
1725 : 0 : rc = ulp_fc_mgr_init(bp->ulp_ctx);
1726 [ # # ]: 0 : if (rc) {
1727 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize ulp flow counter mgr\n");
1728 : 0 : goto jump_to_error;
1729 : : }
1730 : :
1731 : : /*
1732 : : * Enable NAT feature. Set the global configuration register
1733 : : * Tunnel encap to enable NAT with the reuse of existing inner
1734 : : * L2 header smac and dmac
1735 : : */
1736 : 0 : rc = bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
1737 : : TF_TUNNEL_ENCAP_NAT,
1738 : : BNXT_ULP_NAT_OUTER_MOST_FLAGS, 1);
1739 [ # # ]: 0 : if (rc) {
1740 : 0 : BNXT_TF_DBG(ERR, "Failed to set rx global configuration\n");
1741 : 0 : goto jump_to_error;
1742 : : }
1743 : :
1744 : 0 : rc = bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
1745 : : TF_TUNNEL_ENCAP_NAT,
1746 : : BNXT_ULP_NAT_OUTER_MOST_FLAGS, 1);
1747 [ # # ]: 0 : if (rc) {
1748 : 0 : BNXT_TF_DBG(ERR, "Failed to set tx global configuration\n");
1749 : 0 : goto jump_to_error;
1750 : : }
1751 : :
1752 [ # # ]: 0 : if (bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx)) {
1753 : 0 : rc = ulp_ha_mgr_init(bp->ulp_ctx);
1754 [ # # ]: 0 : if (rc) {
1755 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize HA %d\n", rc);
1756 : 0 : goto jump_to_error;
1757 : : }
1758 : 0 : rc = ulp_ha_mgr_open(bp->ulp_ctx);
1759 [ # # ]: 0 : if (rc) {
1760 : 0 : BNXT_TF_DBG(ERR, "Failed to Process HA Open %d\n", rc);
1761 : 0 : goto jump_to_error;
1762 : : }
1763 : : }
1764 : :
1765 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
1766 [ # # ]: 0 : if (rc) {
1767 : 0 : BNXT_TF_DBG(ERR, "Unable to get device id from ulp.\n");
1768 : 0 : return rc;
1769 : : }
1770 : :
1771 [ # # ]: 0 : if (ulp_dev_id == BNXT_ULP_DEVICE_ID_THOR) {
1772 : 0 : rc = bnxt_flow_meter_init(bp);
1773 [ # # ]: 0 : if (rc) {
1774 : 0 : BNXT_TF_DBG(ERR, "Failed to config meter\n");
1775 : 0 : goto jump_to_error;
1776 : : }
1777 : : }
1778 : :
1779 : 0 : BNXT_TF_DBG(DEBUG, "ulp ctx has been initialized\n");
1780 : 0 : return rc;
1781 : :
1782 : 0 : jump_to_error:
1783 : 0 : bnxt_ulp_deinit(bp, session);
1784 : 0 : return rc;
1785 : : }
1786 : :
1787 : : static int
1788 : 0 : ulp_cust_vxlan_alloc(struct bnxt *bp)
1789 : : {
1790 : : int rc = 0;
1791 : :
1792 [ # # ]: 0 : if (ULP_APP_CUST_VXLAN_SUPPORT(bp->ulp_ctx)) {
1793 : 0 : rc = bnxt_tunnel_dst_port_alloc(bp,
1794 : : bp->ulp_ctx->cfg_data->vxlan_port,
1795 : : HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN);
1796 [ # # ]: 0 : if (rc)
1797 : 0 : BNXT_TF_DBG(ERR, "Failed to set global vxlan port\n");
1798 : : }
1799 : :
1800 [ # # ]: 0 : if (ULP_APP_CUST_VXLAN_IP_SUPPORT(bp->ulp_ctx)) {
1801 : 0 : rc = bnxt_tunnel_dst_port_alloc(bp,
1802 : : bp->ulp_ctx->cfg_data->vxlan_ip_port,
1803 : : HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4);
1804 [ # # ]: 0 : if (rc)
1805 : 0 : BNXT_TF_DBG(ERR, "Failed to set global custom vxlan_ip port\n");
1806 : : }
1807 : :
1808 : 0 : return rc;
1809 : : }
1810 : :
1811 : : /*
1812 : : * When a port is initialized by dpdk. This functions sets up
1813 : : * the port specific details.
1814 : : */
1815 : : int32_t
1816 : 0 : bnxt_ulp_port_init(struct bnxt *bp)
1817 : : {
1818 : : struct bnxt_ulp_session_state *session;
1819 : : bool initialized;
1820 : : enum bnxt_ulp_device_id devid = BNXT_ULP_DEVICE_ID_LAST;
1821 : : uint32_t ulp_flags;
1822 : : int32_t rc = 0;
1823 : :
1824 [ # # # # ]: 0 : if (!BNXT_TRUFLOW_EN(bp)) {
1825 : 0 : BNXT_TF_DBG(DEBUG,
1826 : : "Skip ulp init for port: %d, TF is not enabled\n",
1827 : : bp->eth_dev->data->port_id);
1828 : 0 : return rc;
1829 : : }
1830 : :
1831 [ # # ]: 0 : if (!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {
1832 : 0 : BNXT_TF_DBG(DEBUG,
1833 : : "Skip ulp init for port: %d, not a TVF or PF\n",
1834 : : bp->eth_dev->data->port_id);
1835 : 0 : return rc;
1836 : : }
1837 : :
1838 [ # # ]: 0 : if (bp->ulp_ctx) {
1839 : 0 : BNXT_TF_DBG(DEBUG, "ulp ctx already allocated\n");
1840 : 0 : return rc;
1841 : : }
1842 : :
1843 : 0 : bp->ulp_ctx = rte_zmalloc("bnxt_ulp_ctx",
1844 : : sizeof(struct bnxt_ulp_context), 0);
1845 [ # # ]: 0 : if (!bp->ulp_ctx) {
1846 : 0 : BNXT_TF_DBG(ERR, "Failed to allocate ulp ctx\n");
1847 : 0 : return -ENOMEM;
1848 : : }
1849 : :
1850 : : /*
1851 : : * Multiple uplink ports can be associated with a single vswitch.
1852 : : * Make sure only the port that is started first will initialize
1853 : : * the TF session.
1854 : : */
1855 : 0 : session = ulp_session_init(bp, &initialized);
1856 [ # # ]: 0 : if (!session) {
1857 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize the tf session\n");
1858 : : rc = -EIO;
1859 : 0 : goto jump_to_error;
1860 : : }
1861 : :
1862 [ # # ]: 0 : if (initialized) {
1863 : : /*
1864 : : * If ULP is already initialized for a specific domain then
1865 : : * simply assign the ulp context to this rte_eth_dev.
1866 : : */
1867 : 0 : rc = ulp_ctx_attach(bp, session);
1868 [ # # ]: 0 : if (rc) {
1869 : 0 : BNXT_TF_DBG(ERR, "Failed to attach the ulp context\n");
1870 : 0 : goto jump_to_error;
1871 : : }
1872 : :
1873 : : /*
1874 : : * Attach to the shared session, must be called after the
1875 : : * ulp_ctx_attach in order to ensure that ulp data is available
1876 : : * for attaching.
1877 : : */
1878 : 0 : rc = ulp_ctx_shared_session_attach(bp, session);
1879 [ # # ]: 0 : if (rc) {
1880 : 0 : BNXT_TF_DBG(ERR,
1881 : : "Failed attach to shared session (%d)", rc);
1882 : 0 : goto jump_to_error;
1883 : : }
1884 : : } else {
1885 : 0 : rc = bnxt_ulp_init(bp, session);
1886 [ # # ]: 0 : if (rc) {
1887 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize the ulp init\n");
1888 : 0 : goto jump_to_error;
1889 : : }
1890 : : }
1891 : :
1892 : : /* Update bnxt driver flags */
1893 : 0 : rc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx);
1894 : : if (rc) {
1895 : 0 : BNXT_TF_DBG(ERR, "Failed to update driver flags\n");
1896 : 0 : goto jump_to_error;
1897 : : }
1898 : :
1899 : : /* update the port database for the given interface */
1900 : 0 : rc = ulp_port_db_port_update(bp->ulp_ctx, bp->eth_dev);
1901 [ # # ]: 0 : if (rc) {
1902 : 0 : BNXT_TF_DBG(ERR, "Failed to update port database\n");
1903 : 0 : goto jump_to_error;
1904 : : }
1905 : :
1906 : : /* create the default rules */
1907 : 0 : rc = bnxt_ulp_create_df_rules(bp);
1908 [ # # ]: 0 : if (rc) {
1909 : 0 : BNXT_TF_DBG(ERR, "Failed to create default flow\n");
1910 : 0 : goto jump_to_error;
1911 : : }
1912 : :
1913 : : rc = bnxt_ulp_devid_get(bp, &devid);
1914 : : if (rc) {
1915 : : BNXT_TF_DBG(ERR, "Unable to determine device for ULP port init.\n");
1916 : : goto jump_to_error;
1917 : : }
1918 : :
1919 : : /* set the unicast mode */
1920 [ # # ]: 0 : if (bnxt_ulp_cntxt_ptr2_ulp_flags_get(bp->ulp_ctx, &ulp_flags)) {
1921 : 0 : BNXT_TF_DBG(ERR, "Error in getting ULP context flags\n");
1922 : 0 : goto jump_to_error;
1923 : : }
1924 [ # # ]: 0 : if (ulp_flags & BNXT_ULP_APP_UNICAST_ONLY) {
1925 [ # # ]: 0 : if (bnxt_pmd_set_unicast_rxmask(bp->eth_dev)) {
1926 : 0 : BNXT_TF_DBG(ERR, "Error in setting unicast rxmode\n");
1927 : 0 : goto jump_to_error;
1928 : : }
1929 : : }
1930 : :
1931 : 0 : rc = ulp_cust_vxlan_alloc(bp);
1932 [ # # ]: 0 : if (rc)
1933 : 0 : goto jump_to_error;
1934 : :
1935 : : return rc;
1936 : :
1937 : 0 : jump_to_error:
1938 : 0 : bnxt_ulp_port_deinit(bp);
1939 : 0 : return rc;
1940 : : }
1941 : :
1942 : : static void
1943 : 0 : ulp_cust_vxlan_free(struct bnxt *bp)
1944 : : {
1945 : : int rc;
1946 : :
1947 [ # # ]: 0 : if (ULP_APP_CUST_VXLAN_SUPPORT(bp->ulp_ctx)) {
1948 : 0 : rc = bnxt_tunnel_dst_port_free(bp,
1949 : : bp->ulp_ctx->cfg_data->vxlan_port,
1950 : : HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN);
1951 [ # # ]: 0 : if (rc)
1952 : 0 : BNXT_TF_DBG(ERR, "Failed to clear global vxlan port\n");
1953 : : }
1954 : :
1955 [ # # ]: 0 : if (ULP_APP_CUST_VXLAN_IP_SUPPORT(bp->ulp_ctx)) {
1956 : 0 : rc = bnxt_tunnel_dst_port_free(bp,
1957 : : bp->ulp_ctx->cfg_data->vxlan_ip_port,
1958 : : HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4);
1959 [ # # ]: 0 : if (rc)
1960 : 0 : BNXT_TF_DBG(ERR, "Failed to clear global custom vxlan port\n");
1961 : : }
1962 : 0 : }
1963 : :
1964 : : /*
1965 : : * When a port is de-initialized by dpdk. This functions clears up
1966 : : * the port specific details.
1967 : : */
1968 : : void
1969 : 0 : bnxt_ulp_port_deinit(struct bnxt *bp)
1970 : : {
1971 : : struct bnxt_ulp_session_state *session;
1972 : : struct rte_pci_device *pci_dev;
1973 : : struct rte_pci_addr *pci_addr;
1974 : :
1975 [ # # # # ]: 0 : if (!BNXT_TRUFLOW_EN(bp)) {
1976 : 0 : BNXT_TF_DBG(DEBUG,
1977 : : "Skip ULP deinit for port:%d, TF is not enabled\n",
1978 : : bp->eth_dev->data->port_id);
1979 : 0 : return;
1980 : : }
1981 : :
1982 [ # # ]: 0 : if (!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {
1983 : 0 : BNXT_TF_DBG(DEBUG,
1984 : : "Skip ULP deinit port:%d, not a TVF or PF\n",
1985 : : bp->eth_dev->data->port_id);
1986 : 0 : return;
1987 : : }
1988 : :
1989 [ # # ]: 0 : if (!bp->ulp_ctx) {
1990 : 0 : BNXT_TF_DBG(DEBUG, "ulp ctx already de-allocated\n");
1991 : 0 : return;
1992 : : }
1993 : :
1994 : 0 : BNXT_TF_DBG(DEBUG, "BNXT Port:%d ULP port deinit\n",
1995 : : bp->eth_dev->data->port_id);
1996 : :
1997 : : /* Get the session details */
1998 : 0 : pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
1999 : 0 : pci_addr = &pci_dev->addr;
2000 : 0 : pthread_mutex_lock(&bnxt_ulp_global_mutex);
2001 : 0 : session = ulp_get_session(bp, pci_addr);
2002 : 0 : pthread_mutex_unlock(&bnxt_ulp_global_mutex);
2003 : :
2004 : : /* session not found then just exit */
2005 [ # # ]: 0 : if (!session) {
2006 : : /* Free the ulp context */
2007 : 0 : rte_free(bp->ulp_ctx);
2008 : 0 : bp->ulp_ctx = NULL;
2009 : 0 : return;
2010 : : }
2011 : :
2012 : : /* Check the reference count to deinit or deattach*/
2013 [ # # # # ]: 0 : if (bp->ulp_ctx->cfg_data && bp->ulp_ctx->cfg_data->ref_cnt) {
2014 : 0 : bp->ulp_ctx->cfg_data->ref_cnt--;
2015 [ # # ]: 0 : if (bp->ulp_ctx->cfg_data->ref_cnt) {
2016 : : /* Free tunnel configurations */
2017 : 0 : ulp_cust_vxlan_free(bp);
2018 : :
2019 : : /* free the port details */
2020 : : /* Free the default flow rule associated to this port */
2021 : 0 : bnxt_ulp_destroy_df_rules(bp, false);
2022 : 0 : bnxt_ulp_destroy_vfr_default_rules(bp, false);
2023 : :
2024 : : /* free flows associated with this port */
2025 : 0 : bnxt_ulp_flush_port_flows(bp);
2026 : :
2027 : : /* close the session associated with this port */
2028 : 0 : ulp_ctx_detach(bp);
2029 : :
2030 : : /* always detach/close shared after the session. */
2031 : 0 : ulp_ctx_shared_session_detach(bp);
2032 : : } else {
2033 : : /* Perform ulp ctx deinit */
2034 : 0 : bnxt_ulp_deinit(bp, session);
2035 : : }
2036 : : }
2037 : :
2038 : : /* Free the ulp context in the context entry list */
2039 : 0 : bnxt_ulp_cntxt_list_del(bp->ulp_ctx);
2040 : :
2041 : : /* clean up the session */
2042 : 0 : ulp_session_deinit(session);
2043 : :
2044 : : /* Free the ulp context */
2045 : 0 : rte_free(bp->ulp_ctx);
2046 : 0 : bp->ulp_ctx = NULL;
2047 : : }
2048 : :
2049 : : /* Below are the access functions to access internal data of ulp context. */
2050 : : /* Function to set the Mark DB into the context */
2051 : : int32_t
2052 : 0 : bnxt_ulp_cntxt_ptr2_mark_db_set(struct bnxt_ulp_context *ulp_ctx,
2053 : : struct bnxt_ulp_mark_tbl *mark_tbl)
2054 : : {
2055 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data) {
2056 : 0 : BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
2057 : 0 : return -EINVAL;
2058 : : }
2059 : :
2060 : 0 : ulp_ctx->cfg_data->mark_tbl = mark_tbl;
2061 : :
2062 : 0 : return 0;
2063 : : }
2064 : :
2065 : : /* Function to retrieve the Mark DB from the context. */
2066 : : struct bnxt_ulp_mark_tbl *
2067 : 0 : bnxt_ulp_cntxt_ptr2_mark_db_get(struct bnxt_ulp_context *ulp_ctx)
2068 : : {
2069 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2070 : : return NULL;
2071 : :
2072 : 0 : return ulp_ctx->cfg_data->mark_tbl;
2073 : : }
2074 : :
2075 : : bool
2076 : 0 : bnxt_ulp_cntxt_shared_session_enabled(struct bnxt_ulp_context *ulp_ctx)
2077 : : {
2078 : 0 : return ULP_SHARED_SESSION_IS_ENABLED(ulp_ctx->cfg_data->ulp_flags);
2079 : : }
2080 : :
2081 : : bool
2082 : 0 : bnxt_ulp_cntxt_multi_shared_session_enabled(struct bnxt_ulp_context *ulp_ctx)
2083 : : {
2084 : 0 : return ULP_MULTI_SHARED_IS_SUPPORTED(ulp_ctx);
2085 : : }
2086 : :
2087 : : int32_t
2088 : 0 : bnxt_ulp_cntxt_app_id_set(struct bnxt_ulp_context *ulp_ctx, uint8_t app_id)
2089 : : {
2090 [ # # ]: 0 : if (!ulp_ctx)
2091 : : return -EINVAL;
2092 : 0 : ulp_ctx->cfg_data->app_id = app_id;
2093 : 0 : return 0;
2094 : : }
2095 : :
2096 : : int32_t
2097 : 0 : bnxt_ulp_cntxt_app_id_get(struct bnxt_ulp_context *ulp_ctx, uint8_t *app_id)
2098 : : {
2099 : : /* Default APP id is zero */
2100 [ # # ]: 0 : if (!ulp_ctx || !app_id)
2101 : : return -EINVAL;
2102 : 0 : *app_id = ulp_ctx->cfg_data->app_id;
2103 : 0 : return 0;
2104 : : }
2105 : :
2106 : : /* Function to set the device id of the hardware. */
2107 : : int32_t
2108 : 0 : bnxt_ulp_cntxt_dev_id_set(struct bnxt_ulp_context *ulp_ctx,
2109 : : uint32_t dev_id)
2110 : : {
2111 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2112 : 0 : ulp_ctx->cfg_data->dev_id = dev_id;
2113 : 0 : return 0;
2114 : : }
2115 : :
2116 : : return -EINVAL;
2117 : : }
2118 : :
2119 : : /* Function to get the device id of the hardware. */
2120 : : int32_t
2121 : 0 : bnxt_ulp_cntxt_dev_id_get(struct bnxt_ulp_context *ulp_ctx,
2122 : : uint32_t *dev_id)
2123 : : {
2124 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2125 : 0 : *dev_id = ulp_ctx->cfg_data->dev_id;
2126 : 0 : return 0;
2127 : : }
2128 : 0 : *dev_id = BNXT_ULP_DEVICE_ID_LAST;
2129 : 0 : BNXT_TF_DBG(ERR, "Failed to read dev_id from ulp ctxt\n");
2130 : 0 : return -EINVAL;
2131 : : }
2132 : :
2133 : : int32_t
2134 : 0 : bnxt_ulp_cntxt_mem_type_set(struct bnxt_ulp_context *ulp_ctx,
2135 : : enum bnxt_ulp_flow_mem_type mem_type)
2136 : : {
2137 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2138 : 0 : ulp_ctx->cfg_data->mem_type = mem_type;
2139 : 0 : return 0;
2140 : : }
2141 : 0 : BNXT_TF_DBG(ERR, "Failed to write mem_type in ulp ctxt\n");
2142 : 0 : return -EINVAL;
2143 : : }
2144 : :
2145 : : int32_t
2146 : 0 : bnxt_ulp_cntxt_mem_type_get(struct bnxt_ulp_context *ulp_ctx,
2147 : : enum bnxt_ulp_flow_mem_type *mem_type)
2148 : : {
2149 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2150 : 0 : *mem_type = ulp_ctx->cfg_data->mem_type;
2151 : 0 : return 0;
2152 : : }
2153 : 0 : *mem_type = BNXT_ULP_FLOW_MEM_TYPE_LAST;
2154 : 0 : BNXT_TF_DBG(ERR, "Failed to read mem_type in ulp ctxt\n");
2155 : 0 : return -EINVAL;
2156 : : }
2157 : :
2158 : : /* Function to get the table scope id of the EEM table. */
2159 : : int32_t
2160 : 0 : bnxt_ulp_cntxt_tbl_scope_id_get(struct bnxt_ulp_context *ulp_ctx,
2161 : : uint32_t *tbl_scope_id)
2162 : : {
2163 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2164 : 0 : *tbl_scope_id = ulp_ctx->cfg_data->tbl_scope_id;
2165 : 0 : return 0;
2166 : : }
2167 : :
2168 : : return -EINVAL;
2169 : : }
2170 : :
2171 : : /* Function to set the table scope id of the EEM table. */
2172 : : int32_t
2173 : 0 : bnxt_ulp_cntxt_tbl_scope_id_set(struct bnxt_ulp_context *ulp_ctx,
2174 : : uint32_t tbl_scope_id)
2175 : : {
2176 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2177 : 0 : ulp_ctx->cfg_data->tbl_scope_id = tbl_scope_id;
2178 : 0 : return 0;
2179 : : }
2180 : :
2181 : : return -EINVAL;
2182 : : }
2183 : :
2184 : : /* Function to get the number of shared clients attached */
2185 : : uint8_t
2186 : 0 : bnxt_ulp_cntxt_num_shared_clients_get(struct bnxt_ulp_context *ulp)
2187 : : {
2188 [ # # # # ]: 0 : if (ulp == NULL || ulp->cfg_data == NULL) {
2189 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments\n");
2190 : 0 : return 0;
2191 : : }
2192 : 0 : return ulp->cfg_data->num_shared_clients;
2193 : : }
2194 : :
2195 : : /* Function to set the number of shared clients */
2196 : : int
2197 : 0 : bnxt_ulp_cntxt_num_shared_clients_set(struct bnxt_ulp_context *ulp, bool incr)
2198 : : {
2199 [ # # # # ]: 0 : if (ulp == NULL || ulp->cfg_data == NULL) {
2200 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments\n");
2201 : 0 : return 0;
2202 : : }
2203 [ # # ]: 0 : if (incr)
2204 : 0 : ulp->cfg_data->num_shared_clients++;
2205 [ # # ]: 0 : else if (ulp->cfg_data->num_shared_clients)
2206 : 0 : ulp->cfg_data->num_shared_clients--;
2207 : :
2208 : 0 : BNXT_TF_DBG(DEBUG, "%d:clients(%d)\n", incr,
2209 : : ulp->cfg_data->num_shared_clients);
2210 : :
2211 : 0 : return 0;
2212 : : }
2213 : :
2214 : : /* Function to set the tfp session details from the ulp context. */
2215 : : int32_t
2216 : 0 : bnxt_ulp_cntxt_tfp_set(struct bnxt_ulp_context *ulp,
2217 : : enum bnxt_ulp_session_type s_type,
2218 : : struct tf *tfp)
2219 : : {
2220 : : uint32_t idx = 0;
2221 : :
2222 [ # # ]: 0 : if (!ulp) {
2223 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments\n");
2224 : 0 : return -EINVAL;
2225 : : }
2226 [ # # ]: 0 : if (ULP_MULTI_SHARED_IS_SUPPORTED(ulp)) {
2227 [ # # ]: 0 : if (s_type & BNXT_ULP_SESSION_TYPE_SHARED)
2228 : : idx = 1;
2229 [ # # ]: 0 : else if (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC)
2230 : : idx = 2;
2231 : :
2232 : : } else {
2233 [ # # ]: 0 : if ((s_type & BNXT_ULP_SESSION_TYPE_SHARED) ||
2234 : : (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC))
2235 : : idx = 1;
2236 : : }
2237 : :
2238 : 0 : ulp->g_tfp[idx] = tfp;
2239 : 0 : return 0;
2240 : : }
2241 : :
2242 : : /* Function to get the tfp session details from the ulp context. */
2243 : : struct tf *
2244 : 0 : bnxt_ulp_cntxt_tfp_get(struct bnxt_ulp_context *ulp,
2245 : : enum bnxt_ulp_session_type s_type)
2246 : : {
2247 : : uint32_t idx = 0;
2248 : :
2249 [ # # ]: 0 : if (!ulp) {
2250 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments\n");
2251 : 0 : return NULL;
2252 : : }
2253 [ # # ]: 0 : if (ULP_MULTI_SHARED_IS_SUPPORTED(ulp)) {
2254 [ # # ]: 0 : if (s_type & BNXT_ULP_SESSION_TYPE_SHARED)
2255 : : idx = 1;
2256 [ # # ]: 0 : else if (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC)
2257 : : idx = 2;
2258 : : } else {
2259 [ # # ]: 0 : if ((s_type & BNXT_ULP_SESSION_TYPE_SHARED) ||
2260 : : (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC))
2261 : : idx = 1;
2262 : : }
2263 : 0 : return ulp->g_tfp[idx];
2264 : : }
2265 : :
2266 : : /*
2267 : : * Get the device table entry based on the device id.
2268 : : *
2269 : : * dev_id [in] The device id of the hardware
2270 : : *
2271 : : * Returns the pointer to the device parameters.
2272 : : */
2273 : : struct bnxt_ulp_device_params *
2274 : 0 : bnxt_ulp_device_params_get(uint32_t dev_id)
2275 : : {
2276 [ # # ]: 0 : if (dev_id < BNXT_ULP_MAX_NUM_DEVICES)
2277 : 0 : return &ulp_device_params[dev_id];
2278 : : return NULL;
2279 : : }
2280 : :
2281 : : /* Function to set the flow database to the ulp context. */
2282 : : int32_t
2283 : 0 : bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx,
2284 : : struct bnxt_ulp_flow_db *flow_db)
2285 : : {
2286 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2287 : : return -EINVAL;
2288 : :
2289 : 0 : ulp_ctx->cfg_data->flow_db = flow_db;
2290 : 0 : return 0;
2291 : : }
2292 : :
2293 : : /* Function to get the flow database from the ulp context. */
2294 : : struct bnxt_ulp_flow_db *
2295 : 0 : bnxt_ulp_cntxt_ptr2_flow_db_get(struct bnxt_ulp_context *ulp_ctx)
2296 : : {
2297 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2298 : : return NULL;
2299 : :
2300 : 0 : return ulp_ctx->cfg_data->flow_db;
2301 : : }
2302 : :
2303 : : /* Function to get the tunnel cache table info from the ulp context. */
2304 : : struct bnxt_tun_cache_entry *
2305 : 0 : bnxt_ulp_cntxt_ptr2_tun_tbl_get(struct bnxt_ulp_context *ulp_ctx)
2306 : : {
2307 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2308 : : return NULL;
2309 : :
2310 : 0 : return ulp_ctx->cfg_data->tun_tbl;
2311 : : }
2312 : :
2313 : : /* Function to get the ulp context from eth device. */
2314 : : struct bnxt_ulp_context *
2315 : 0 : bnxt_ulp_eth_dev_ptr2_cntxt_get(struct rte_eth_dev *dev)
2316 : : {
2317 [ # # ]: 0 : struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
2318 : :
2319 [ # # ]: 0 : if (rte_eth_dev_is_repr(dev)) {
2320 : : struct bnxt_representor *vfr = dev->data->dev_private;
2321 : :
2322 : 0 : bp = vfr->parent_dev->data->dev_private;
2323 : : }
2324 : :
2325 [ # # ]: 0 : if (!bp) {
2326 : 0 : BNXT_TF_DBG(ERR, "Bnxt private data is not initialized\n");
2327 : 0 : return NULL;
2328 : : }
2329 : 0 : return bp->ulp_ctx;
2330 : : }
2331 : :
2332 : : int32_t
2333 : 0 : bnxt_ulp_cntxt_ptr2_mapper_data_set(struct bnxt_ulp_context *ulp_ctx,
2334 : : void *mapper_data)
2335 : : {
2336 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data) {
2337 : 0 : BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
2338 : 0 : return -EINVAL;
2339 : : }
2340 : :
2341 : 0 : ulp_ctx->cfg_data->mapper_data = mapper_data;
2342 : 0 : return 0;
2343 : : }
2344 : :
2345 : : void *
2346 : 0 : bnxt_ulp_cntxt_ptr2_mapper_data_get(struct bnxt_ulp_context *ulp_ctx)
2347 : : {
2348 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data) {
2349 : 0 : BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
2350 : 0 : return NULL;
2351 : : }
2352 : :
2353 : 0 : return ulp_ctx->cfg_data->mapper_data;
2354 : : }
2355 : :
2356 : : /* Function to set the port database to the ulp context. */
2357 : : int32_t
2358 : 0 : bnxt_ulp_cntxt_ptr2_port_db_set(struct bnxt_ulp_context *ulp_ctx,
2359 : : struct bnxt_ulp_port_db *port_db)
2360 : : {
2361 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2362 : : return -EINVAL;
2363 : :
2364 : 0 : ulp_ctx->cfg_data->port_db = port_db;
2365 : 0 : return 0;
2366 : : }
2367 : :
2368 : : /* Function to get the port database from the ulp context. */
2369 : : struct bnxt_ulp_port_db *
2370 : 0 : bnxt_ulp_cntxt_ptr2_port_db_get(struct bnxt_ulp_context *ulp_ctx)
2371 : : {
2372 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2373 : : return NULL;
2374 : :
2375 : 0 : return ulp_ctx->cfg_data->port_db;
2376 : : }
2377 : :
2378 : : /* Function to set the flow counter info into the context */
2379 : : int32_t
2380 : 0 : bnxt_ulp_cntxt_ptr2_fc_info_set(struct bnxt_ulp_context *ulp_ctx,
2381 : : struct bnxt_ulp_fc_info *ulp_fc_info)
2382 : : {
2383 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data) {
2384 : 0 : BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
2385 : 0 : return -EINVAL;
2386 : : }
2387 : :
2388 : 0 : ulp_ctx->cfg_data->fc_info = ulp_fc_info;
2389 : :
2390 : 0 : return 0;
2391 : : }
2392 : :
2393 : : /* Function to retrieve the flow counter info from the context. */
2394 : : struct bnxt_ulp_fc_info *
2395 : 0 : bnxt_ulp_cntxt_ptr2_fc_info_get(struct bnxt_ulp_context *ulp_ctx)
2396 : : {
2397 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2398 : : return NULL;
2399 : :
2400 : 0 : return ulp_ctx->cfg_data->fc_info;
2401 : : }
2402 : :
2403 : : /* Function to get the ulp flags from the ulp context. */
2404 : : int32_t
2405 : 0 : bnxt_ulp_cntxt_ptr2_ulp_flags_get(struct bnxt_ulp_context *ulp_ctx,
2406 : : uint32_t *flags)
2407 : : {
2408 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2409 : : return -1;
2410 : :
2411 : 0 : *flags = ulp_ctx->cfg_data->ulp_flags;
2412 : 0 : return 0;
2413 : : }
2414 : :
2415 : : /* Function to get the ulp vfr info from the ulp context. */
2416 : : struct bnxt_ulp_vfr_rule_info*
2417 : 0 : bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(struct bnxt_ulp_context *ulp_ctx,
2418 : : uint32_t port_id)
2419 : : {
2420 [ # # # # : 0 : if (!ulp_ctx || !ulp_ctx->cfg_data || port_id >= RTE_MAX_ETHPORTS)
# # ]
2421 : : return NULL;
2422 : :
2423 : 0 : return &ulp_ctx->cfg_data->vfr_rule_info[port_id];
2424 : : }
2425 : :
2426 : : /* Function to acquire the flow database lock from the ulp context. */
2427 : : int32_t
2428 : 0 : bnxt_ulp_cntxt_acquire_fdb_lock(struct bnxt_ulp_context *ulp_ctx)
2429 : : {
2430 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2431 : : return -1;
2432 : :
2433 [ # # ]: 0 : if (pthread_mutex_lock(&ulp_ctx->cfg_data->flow_db_lock)) {
2434 : 0 : BNXT_TF_DBG(ERR, "unable to acquire fdb lock\n");
2435 : 0 : return -1;
2436 : : }
2437 : : return 0;
2438 : : }
2439 : :
2440 : : /* Function to release the flow database lock from the ulp context. */
2441 : : void
2442 : 0 : bnxt_ulp_cntxt_release_fdb_lock(struct bnxt_ulp_context *ulp_ctx)
2443 : : {
2444 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2445 : : return;
2446 : :
2447 : 0 : pthread_mutex_unlock(&ulp_ctx->cfg_data->flow_db_lock);
2448 : : }
2449 : :
2450 : : /* Function to extract the action type from the shared action handle. */
2451 : : int32_t
2452 : 0 : bnxt_get_action_handle_type(const struct rte_flow_action_handle *handle,
2453 : : uint32_t *action_handle_type)
2454 : : {
2455 [ # # ]: 0 : if (!action_handle_type)
2456 : : return -EINVAL;
2457 : :
2458 : 0 : *action_handle_type = (uint32_t)(((uint64_t)handle >> 32) & 0xffffffff);
2459 [ # # ]: 0 : if (*action_handle_type >= BNXT_ULP_GEN_TBL_MAX_SZ)
2460 : 0 : return -EINVAL;
2461 : :
2462 : : return 0;
2463 : : }
2464 : :
2465 : : /* Function to extract the direction from the shared action handle. */
2466 : : int32_t
2467 : 0 : bnxt_get_action_handle_direction(const struct rte_flow_action_handle *handle,
2468 : : uint32_t *dir)
2469 : : {
2470 : : uint32_t shared_type;
2471 : : int32_t ret = 0;
2472 : :
2473 : 0 : ret = bnxt_get_action_handle_type(handle, &shared_type);
2474 [ # # ]: 0 : if (ret)
2475 : : return ret;
2476 : :
2477 [ # # ]: 0 : *dir = shared_type & 0x1 ? BNXT_ULP_DIR_EGRESS : BNXT_ULP_DIR_INGRESS;
2478 : :
2479 : 0 : return ret;
2480 : : }
2481 : :
2482 : : /* Function to extract the action index from the shared action handle. */
2483 : : uint32_t
2484 : 0 : bnxt_get_action_handle_index(const struct rte_flow_action_handle *handle)
2485 : : {
2486 : 0 : return (uint32_t)((uint64_t)handle & 0xffffffff);
2487 : : }
2488 : :
2489 : : /* Function to set the ha info into the context */
2490 : : int32_t
2491 : 0 : bnxt_ulp_cntxt_ptr2_ha_info_set(struct bnxt_ulp_context *ulp_ctx,
2492 : : struct bnxt_ulp_ha_mgr_info *ulp_ha_info)
2493 : : {
2494 [ # # # # ]: 0 : if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL) {
2495 : 0 : BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
2496 : 0 : return -EINVAL;
2497 : : }
2498 : 0 : ulp_ctx->cfg_data->ha_info = ulp_ha_info;
2499 : 0 : return 0;
2500 : : }
2501 : :
2502 : : /* Function to retrieve the ha info from the context. */
2503 : : struct bnxt_ulp_ha_mgr_info *
2504 : 0 : bnxt_ulp_cntxt_ptr2_ha_info_get(struct bnxt_ulp_context *ulp_ctx)
2505 : : {
2506 [ # # # # ]: 0 : if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
2507 : : return NULL;
2508 : 0 : return ulp_ctx->cfg_data->ha_info;
2509 : : }
2510 : :
2511 : : bool
2512 : 0 : bnxt_ulp_cntxt_ha_enabled(struct bnxt_ulp_context *ulp_ctx)
2513 : : {
2514 [ # # # # ]: 0 : if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
2515 : : return false;
2516 : 0 : return !!ULP_HIGH_AVAIL_IS_ENABLED(ulp_ctx->cfg_data->ulp_flags);
2517 : : }
2518 : :
2519 : : static int32_t
2520 : : bnxt_ulp_cntxt_list_init(void)
2521 : : {
2522 : : /* Create the cntxt spin lock only once*/
2523 [ # # ]: 0 : if (!bnxt_ulp_ctxt_lock_created)
2524 : : rte_spinlock_init(&bnxt_ulp_ctxt_lock);
2525 : 0 : bnxt_ulp_ctxt_lock_created = 1;
2526 : : return 0;
2527 : : }
2528 : :
2529 : : static int32_t
2530 : 0 : bnxt_ulp_cntxt_list_add(struct bnxt_ulp_context *ulp_ctx)
2531 : : {
2532 : : struct ulp_context_list_entry *entry;
2533 : :
2534 : 0 : entry = rte_zmalloc(NULL, sizeof(struct ulp_context_list_entry), 0);
2535 [ # # ]: 0 : if (entry == NULL) {
2536 : 0 : BNXT_TF_DBG(ERR, "unable to allocate memory\n");
2537 : 0 : return -ENOMEM;
2538 : : }
2539 : :
2540 : : rte_spinlock_lock(&bnxt_ulp_ctxt_lock);
2541 : 0 : entry->ulp_ctx = ulp_ctx;
2542 : 0 : TAILQ_INSERT_TAIL(&ulp_cntx_list, entry, next);
2543 : : rte_spinlock_unlock(&bnxt_ulp_ctxt_lock);
2544 : 0 : return 0;
2545 : : }
2546 : :
2547 : : static void
2548 : 0 : bnxt_ulp_cntxt_list_del(struct bnxt_ulp_context *ulp_ctx)
2549 : : {
2550 : : struct ulp_context_list_entry *entry, *temp;
2551 : :
2552 : : rte_spinlock_lock(&bnxt_ulp_ctxt_lock);
2553 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(entry, &ulp_cntx_list, next, temp) {
2554 [ # # ]: 0 : if (entry->ulp_ctx == ulp_ctx) {
2555 [ # # ]: 0 : TAILQ_REMOVE(&ulp_cntx_list, entry, next);
2556 : 0 : rte_free(entry);
2557 : 0 : break;
2558 : : }
2559 : : }
2560 : : rte_spinlock_unlock(&bnxt_ulp_ctxt_lock);
2561 : 0 : }
2562 : :
2563 : : struct bnxt_ulp_context *
2564 : 0 : bnxt_ulp_cntxt_entry_acquire(void *arg)
2565 : : {
2566 : : struct ulp_context_list_entry *entry;
2567 : :
2568 : : /* take a lock and get the first ulp context available */
2569 [ # # ]: 0 : if (rte_spinlock_trylock(&bnxt_ulp_ctxt_lock)) {
2570 [ # # ]: 0 : TAILQ_FOREACH(entry, &ulp_cntx_list, next)
2571 [ # # ]: 0 : if (entry->ulp_ctx->cfg_data == arg)
2572 : 0 : return entry->ulp_ctx;
2573 : : rte_spinlock_unlock(&bnxt_ulp_ctxt_lock);
2574 : : }
2575 : : return NULL;
2576 : : }
2577 : :
2578 : : void
2579 : 0 : bnxt_ulp_cntxt_entry_release(void)
2580 : : {
2581 : : rte_spinlock_unlock(&bnxt_ulp_ctxt_lock);
2582 : 0 : }
2583 : :
2584 : : /* Function to get the app tunnel details from the ulp context. */
2585 : : struct bnxt_flow_app_tun_ent *
2586 : 0 : bnxt_ulp_cntxt_ptr2_app_tun_list_get(struct bnxt_ulp_context *ulp)
2587 : : {
2588 [ # # # # ]: 0 : if (!ulp || !ulp->cfg_data)
2589 : : return NULL;
2590 : :
2591 : 0 : return ulp->cfg_data->app_tun;
2592 : : }
2593 : :
2594 : : /* Function to get the truflow app id. This defined in the build file */
2595 : : uint32_t
2596 : 0 : bnxt_ulp_default_app_id_get(void)
2597 : : {
2598 : 0 : return BNXT_TF_APP_ID;
2599 : : }
2600 : :
2601 : : /* Function to convert ulp dev id to regular dev id. */
2602 : : uint32_t
2603 [ # # ]: 0 : bnxt_ulp_cntxt_convert_dev_id(uint32_t ulp_dev_id)
2604 : : {
2605 : : enum tf_device_type type = 0;
2606 : :
2607 : : switch (ulp_dev_id) {
2608 : : case BNXT_ULP_DEVICE_ID_WH_PLUS:
2609 : : type = TF_DEVICE_TYPE_P4;
2610 : : break;
2611 : : case BNXT_ULP_DEVICE_ID_STINGRAY:
2612 : : type = TF_DEVICE_TYPE_SR;
2613 : : break;
2614 : : case BNXT_ULP_DEVICE_ID_THOR:
2615 : : type = TF_DEVICE_TYPE_P5;
2616 : : break;
2617 : 0 : default:
2618 : 0 : BNXT_TF_DBG(ERR, "Invalid device id\n");
2619 : 0 : break;
2620 : : }
2621 : 0 : return type;
2622 : : }
2623 : :
2624 : : /* This function sets the IF table index for the
2625 : : * Application to poll to get the hot upgrade state and count details from
2626 : : * the firmware.
2627 : : */
2628 : : int32_t
2629 : 0 : bnxt_ulp_ha_reg_set(struct bnxt_ulp_context *ulp_ctx,
2630 : : uint8_t state, uint8_t cnt)
2631 : : {
2632 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2633 : : return -EINVAL;
2634 : :
2635 [ # # ]: 0 : if (ULP_MULTI_SHARED_IS_SUPPORTED(ulp_ctx)) {
2636 : 0 : ulp_ctx->cfg_data->hu_reg_state = state;
2637 : 0 : ulp_ctx->cfg_data->hu_reg_cnt = cnt;
2638 : : } else {
2639 : 0 : ulp_ctx->cfg_data->hu_reg_state = ULP_HA_IF_TBL_IDX;
2640 : 0 : ulp_ctx->cfg_data->hu_reg_cnt = ULP_HA_CLIENT_CNT_IF_TBL_IDX;
2641 : : }
2642 : : return 0;
2643 : : }
2644 : :
2645 : : /* This function gets the IF table index for the
2646 : : * application to poll to get the application hot upgrade state from
2647 : : * the firmware.
2648 : : */
2649 : : uint32_t
2650 : 0 : bnxt_ulp_ha_reg_state_get(struct bnxt_ulp_context *ulp_ctx)
2651 : : {
2652 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2653 : : return 0;
2654 : :
2655 : 0 : return (uint32_t)ulp_ctx->cfg_data->hu_reg_state;
2656 : : }
2657 : :
2658 : : /* This function gets the IF table index for the
2659 : : * Application to poll to get the application count from
2660 : : * the firmware.
2661 : : */
2662 : : uint32_t
2663 : 0 : bnxt_ulp_ha_reg_cnt_get(struct bnxt_ulp_context *ulp_ctx)
2664 : : {
2665 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2666 : : return 0;
2667 : :
2668 : 0 : return (uint32_t)ulp_ctx->cfg_data->hu_reg_cnt;
2669 : : }
2670 : :
2671 : : struct tf*
2672 : 0 : bnxt_ulp_bp_tfp_get(struct bnxt *bp, enum bnxt_ulp_session_type type)
2673 : : {
2674 : : enum bnxt_session_type btype;
2675 : :
2676 [ # # ]: 0 : if (type & BNXT_ULP_SESSION_TYPE_SHARED)
2677 : : btype = BNXT_SESSION_TYPE_SHARED_COMMON;
2678 [ # # ]: 0 : else if (type & BNXT_ULP_SESSION_TYPE_SHARED_WC)
2679 : : btype = BNXT_SESSION_TYPE_SHARED_WC;
2680 : : else
2681 : : btype = BNXT_SESSION_TYPE_REGULAR;
2682 : :
2683 : 0 : return bnxt_get_tfp_session(bp, btype);
2684 : : }
|