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_shared_session_open(struct bnxt *bp,
646 : : enum bnxt_ulp_session_type session_type,
647 : : struct bnxt_ulp_session_state *session)
648 : : {
649 : 0 : struct rte_eth_dev *ethdev = bp->eth_dev;
650 : : struct tf_session_resources *resources;
651 : : struct tf_open_session_parms parms;
652 : : size_t nb;
653 : 0 : uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
654 : : int32_t rc = 0;
655 : : uint8_t app_id;
656 : : struct tf *tfp;
657 : : uint8_t pool_id;
658 : :
659 : : memset(&parms, 0, sizeof(parms));
660 : 0 : rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
661 : : parms.ctrl_chan_name);
662 [ # # ]: 0 : if (rc) {
663 : 0 : BNXT_TF_DBG(ERR, "Invalid port %d, rc = %d\n",
664 : : ethdev->data->port_id, rc);
665 : 0 : return rc;
666 : : }
667 : : resources = &parms.resources;
668 : :
669 : : /*
670 : : * Need to account for size of ctrl_chan_name and 1 extra for Null
671 : : * terminator
672 : : */
673 : 0 : nb = sizeof(parms.ctrl_chan_name) - strlen(parms.ctrl_chan_name) - 1;
674 : :
675 : : /*
676 : : * Build the ctrl_chan_name with shared token.
677 : : * When HA is enabled, the WC TCAM needs extra management by the core,
678 : : * so add the wc_tcam string to the control channel.
679 : : */
680 : 0 : pool_id = bp->ulp_ctx->cfg_data->ha_pool_id;
681 [ # # ]: 0 : if (!bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
682 [ # # ]: 0 : if (bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx))
683 : : strncat(parms.ctrl_chan_name, "-tf_shared-wc_tcam", nb);
684 : : else
685 : : strncat(parms.ctrl_chan_name, "-tf_shared", nb);
686 [ # # ]: 0 : } else if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
687 [ # # ]: 0 : if (session_type == BNXT_ULP_SESSION_TYPE_SHARED) {
688 : : strncat(parms.ctrl_chan_name, "-tf_shared", nb);
689 [ # # ]: 0 : } else if (session_type == BNXT_ULP_SESSION_TYPE_SHARED_WC) {
690 : : char session_pool_name[64];
691 : :
692 [ # # ]: 0 : sprintf(session_pool_name, "-tf_shared-pool%d",
693 : : pool_id);
694 : :
695 [ # # ]: 0 : if (nb >= strlen(session_pool_name)) {
696 : : strncat(parms.ctrl_chan_name, session_pool_name, nb);
697 : : } else {
698 : 0 : BNXT_TF_DBG(ERR, "No space left for session_name\n");
699 : 0 : return -EINVAL;
700 : : }
701 : : }
702 : : }
703 : :
704 : 0 : rc = bnxt_ulp_tf_shared_session_resources_get(bp->ulp_ctx, session_type,
705 : : resources);
706 [ # # ]: 0 : if (rc)
707 : : return rc;
708 : :
709 : 0 : rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id);
710 [ # # ]: 0 : if (rc) {
711 : 0 : BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n");
712 : 0 : return -EINVAL;
713 : : }
714 : :
715 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
716 [ # # ]: 0 : if (rc) {
717 : 0 : BNXT_TF_DBG(ERR, "Unable to get device id from ulp.\n");
718 : 0 : return rc;
719 : : }
720 : :
721 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, session_type);
722 : 0 : parms.device_type = bnxt_ulp_cntxt_convert_dev_id(ulp_dev_id);
723 : 0 : parms.bp = bp;
724 : :
725 : : /*
726 : : * Open the session here, but the collect the resources during the
727 : : * mapper initialization.
728 : : */
729 : 0 : rc = tf_open_session(tfp, &parms);
730 [ # # ]: 0 : if (rc)
731 : : return rc;
732 : :
733 [ # # ]: 0 : if (parms.shared_session_creator)
734 : 0 : BNXT_TF_DBG(DEBUG, "Shared session creator.\n");
735 : : else
736 : 0 : BNXT_TF_DBG(DEBUG, "Shared session attached.\n");
737 : :
738 : : /* Save the shared session in global data */
739 : 0 : rc = bnxt_ulp_session_tfp_set(session, session_type, tfp);
740 [ # # ]: 0 : if (rc) {
741 : 0 : BNXT_TF_DBG(ERR, "Failed to add shared tfp to session\n");
742 : 0 : return rc;
743 : : }
744 : :
745 : 0 : rc = bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session_type, tfp);
746 [ # # ]: 0 : if (rc) {
747 : 0 : BNXT_TF_DBG(ERR, "Failed to add shared tfp to ulp (%d)\n", rc);
748 : 0 : return rc;
749 : : }
750 : :
751 : : return rc;
752 : : }
753 : :
754 : : static int32_t
755 : 0 : ulp_ctx_shared_session_attach(struct bnxt *bp,
756 : : struct bnxt_ulp_session_state *ses)
757 : : {
758 : : enum bnxt_ulp_session_type type;
759 : : struct tf *tfp;
760 : : int32_t rc = 0;
761 : :
762 : : /* Simply return success if shared session not enabled */
763 [ # # ]: 0 : if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) {
764 : : type = BNXT_ULP_SESSION_TYPE_SHARED;
765 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, type);
766 : 0 : tfp->session = bnxt_ulp_session_tfp_get(ses, type);
767 : 0 : rc = ulp_ctx_shared_session_open(bp, type, ses);
768 : : }
769 : :
770 [ # # ]: 0 : if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
771 : : type = BNXT_ULP_SESSION_TYPE_SHARED_WC;
772 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, type);
773 : 0 : tfp->session = bnxt_ulp_session_tfp_get(ses, type);
774 : 0 : rc = ulp_ctx_shared_session_open(bp, type, ses);
775 : : }
776 : :
777 [ # # ]: 0 : if (!rc)
778 : 0 : bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, true);
779 : :
780 : 0 : return rc;
781 : : }
782 : :
783 : : static void
784 : 0 : ulp_ctx_shared_session_detach(struct bnxt *bp)
785 : : {
786 : : struct tf *tfp;
787 : :
788 [ # # ]: 0 : if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) {
789 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_SHARED);
790 [ # # ]: 0 : if (tfp->session) {
791 : 0 : tf_close_session(tfp);
792 : 0 : tfp->session = NULL;
793 : : }
794 : : }
795 [ # # ]: 0 : if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
796 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_SHARED_WC);
797 [ # # ]: 0 : if (tfp->session) {
798 : 0 : tf_close_session(tfp);
799 : 0 : tfp->session = NULL;
800 : : }
801 : : }
802 : 0 : bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, false);
803 : 0 : }
804 : :
805 : : /*
806 : : * Initialize an ULP session.
807 : : * An ULP session will contain all the resources needed to support rte flow
808 : : * offloads. A session is initialized as part of rte_eth_device start.
809 : : * A single vswitch instance can have multiple uplinks which means
810 : : * rte_eth_device start will be called for each of these devices.
811 : : * ULP session manager will make sure that a single ULP session is only
812 : : * initialized once. Apart from this, it also initializes MARK database,
813 : : * EEM table & flow database. ULP session manager also manages a list of
814 : : * all opened ULP sessions.
815 : : */
816 : : static int32_t
817 : 0 : ulp_ctx_session_open(struct bnxt *bp,
818 : : struct bnxt_ulp_session_state *session)
819 : : {
820 : 0 : struct rte_eth_dev *ethdev = bp->eth_dev;
821 : : int32_t rc = 0;
822 : : struct tf_open_session_parms params;
823 : : struct tf_session_resources *resources;
824 : 0 : uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
825 : : uint8_t app_id;
826 : : struct tf *tfp;
827 : :
828 : : memset(¶ms, 0, sizeof(params));
829 : :
830 : 0 : rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
831 : : params.ctrl_chan_name);
832 [ # # ]: 0 : if (rc) {
833 : 0 : BNXT_TF_DBG(ERR, "Invalid port %d, rc = %d\n",
834 : : ethdev->data->port_id, rc);
835 : 0 : return rc;
836 : : }
837 : :
838 : 0 : rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id);
839 [ # # ]: 0 : if (rc) {
840 : 0 : BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n");
841 : 0 : return -EINVAL;
842 : : }
843 : :
844 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
845 [ # # ]: 0 : if (rc) {
846 : 0 : BNXT_TF_DBG(ERR, "Unable to get device id from ulp.\n");
847 : 0 : return rc;
848 : : }
849 : :
850 : 0 : params.device_type = bnxt_ulp_cntxt_convert_dev_id(ulp_dev_id);
851 : : resources = ¶ms.resources;
852 : 0 : rc = bnxt_ulp_tf_resources_get(bp->ulp_ctx,
853 : : BNXT_ULP_SESSION_TYPE_DEFAULT,
854 : : resources);
855 [ # # ]: 0 : if (rc)
856 : : return rc;
857 : :
858 : 0 : params.bp = bp;
859 : :
860 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
861 : 0 : rc = tf_open_session(tfp, ¶ms);
862 [ # # ]: 0 : if (rc) {
863 : 0 : BNXT_TF_DBG(ERR, "Failed to open TF session - %s, rc = %d\n",
864 : : params.ctrl_chan_name, rc);
865 : 0 : return -EINVAL;
866 : : }
867 : 0 : rc = bnxt_ulp_session_tfp_set(session,
868 : : BNXT_ULP_SESSION_TYPE_DEFAULT, tfp);
869 [ # # ]: 0 : if (rc) {
870 : 0 : BNXT_TF_DBG(ERR, "Failed to set TF session - %s, rc = %d\n",
871 : : params.ctrl_chan_name, rc);
872 : 0 : return -EINVAL;
873 : : }
874 : : return rc;
875 : : }
876 : :
877 : : /*
878 : : * Close the ULP session.
879 : : * It takes the ulp context pointer.
880 : : */
881 : : static void
882 : 0 : ulp_ctx_session_close(struct bnxt *bp,
883 : : struct bnxt_ulp_session_state *session)
884 : : {
885 : : struct tf *tfp;
886 : :
887 : : /* close the session in the hardware */
888 [ # # ]: 0 : if (bnxt_ulp_session_is_open(session, BNXT_ULP_SESSION_TYPE_DEFAULT)) {
889 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
890 : 0 : tf_close_session(tfp);
891 : : }
892 : : bnxt_ulp_session_tfp_reset(session, BNXT_ULP_SESSION_TYPE_DEFAULT);
893 : 0 : }
894 : :
895 : : static void
896 : 0 : bnxt_init_tbl_scope_parms(struct bnxt *bp,
897 : : struct tf_alloc_tbl_scope_parms *params)
898 : : {
899 : : struct bnxt_ulp_device_params *dparms;
900 : : uint32_t dev_id;
901 : : int rc;
902 : :
903 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id);
904 [ # # ]: 0 : if (rc)
905 : : /* TBD: For now, just use default. */
906 : : dparms = 0;
907 : : else
908 : 0 : dparms = bnxt_ulp_device_params_get(dev_id);
909 : :
910 : : /*
911 : : * Set the flush timer for EEM entries. The value is in 100ms intervals,
912 : : * so 100 is 10s.
913 : : */
914 : 0 : params->hw_flow_cache_flush_timer = 100;
915 : :
916 [ # # ]: 0 : if (!dparms) {
917 : 0 : params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
918 : 0 : params->rx_max_action_entry_sz_in_bits =
919 : : BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
920 : 0 : params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
921 : 0 : params->rx_num_flows_in_k = BNXT_ULP_RX_NUM_FLOWS;
922 : :
923 : 0 : params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
924 : 0 : params->tx_max_action_entry_sz_in_bits =
925 : : BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
926 : 0 : params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
927 : 0 : params->tx_num_flows_in_k = BNXT_ULP_TX_NUM_FLOWS;
928 : : } else {
929 : 0 : params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
930 : 0 : params->rx_max_action_entry_sz_in_bits =
931 : : BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
932 : 0 : params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
933 : 0 : params->rx_num_flows_in_k =
934 : 0 : dparms->ext_flow_db_num_entries / 1024;
935 : :
936 : 0 : params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
937 : 0 : params->tx_max_action_entry_sz_in_bits =
938 : : BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
939 : 0 : params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
940 : 0 : params->tx_num_flows_in_k =
941 : : dparms->ext_flow_db_num_entries / 1024;
942 : : }
943 : 0 : BNXT_TF_DBG(INFO, "Table Scope initialized with %uK flows.\n",
944 : : params->rx_num_flows_in_k);
945 : 0 : }
946 : :
947 : : /* Initialize Extended Exact Match host memory. */
948 : : static int32_t
949 : 0 : ulp_eem_tbl_scope_init(struct bnxt *bp)
950 : : {
951 : 0 : struct tf_alloc_tbl_scope_parms params = {0};
952 : : struct bnxt_ulp_device_params *dparms;
953 : : enum bnxt_ulp_flow_mem_type mtype;
954 : : uint32_t dev_id;
955 : : struct tf *tfp;
956 : : int rc;
957 : :
958 : : /* Get the dev specific number of flows that needed to be supported. */
959 [ # # ]: 0 : if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
960 : 0 : BNXT_TF_DBG(ERR, "Invalid device id\n");
961 : 0 : return -EINVAL;
962 : : }
963 : :
964 : 0 : dparms = bnxt_ulp_device_params_get(dev_id);
965 [ # # ]: 0 : if (!dparms) {
966 : 0 : BNXT_TF_DBG(ERR, "could not fetch the device params\n");
967 : 0 : return -ENODEV;
968 : : }
969 : :
970 [ # # ]: 0 : if (bnxt_ulp_cntxt_mem_type_get(bp->ulp_ctx, &mtype))
971 : : return -EINVAL;
972 [ # # ]: 0 : if (mtype != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
973 : 0 : BNXT_TF_DBG(INFO, "Table Scope alloc is not required\n");
974 : 0 : return 0;
975 : : }
976 : :
977 : 0 : bnxt_init_tbl_scope_parms(bp, ¶ms);
978 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
979 : 0 : rc = tf_alloc_tbl_scope(tfp, ¶ms);
980 [ # # ]: 0 : if (rc) {
981 : 0 : BNXT_TF_DBG(ERR, "Unable to allocate eem table scope rc = %d\n",
982 : : rc);
983 : 0 : return rc;
984 : : }
985 : :
986 : 0 : rc = bnxt_ulp_cntxt_tbl_scope_id_set(bp->ulp_ctx, params.tbl_scope_id);
987 [ # # ]: 0 : if (rc) {
988 : 0 : BNXT_TF_DBG(ERR, "Unable to set table scope id\n");
989 : 0 : return rc;
990 : : }
991 : :
992 : : return 0;
993 : : }
994 : :
995 : : /* Free Extended Exact Match host memory */
996 : : static int32_t
997 : 0 : ulp_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)
998 : : {
999 : 0 : struct tf_free_tbl_scope_parms params = {0};
1000 : : struct tf *tfp;
1001 : : int32_t rc = 0;
1002 : : struct bnxt_ulp_device_params *dparms;
1003 : : enum bnxt_ulp_flow_mem_type mtype;
1004 : : uint32_t dev_id;
1005 : :
1006 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
1007 : : return -EINVAL;
1008 : :
1009 : 0 : tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT);
1010 [ # # ]: 0 : if (!tfp) {
1011 : 0 : BNXT_TF_DBG(ERR, "Failed to get the truflow pointer\n");
1012 : 0 : return -EINVAL;
1013 : : }
1014 : :
1015 : : /* Get the dev specific number of flows that needed to be supported. */
1016 [ # # ]: 0 : if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
1017 : 0 : BNXT_TF_DBG(ERR, "Invalid device id\n");
1018 : 0 : return -EINVAL;
1019 : : }
1020 : :
1021 : 0 : dparms = bnxt_ulp_device_params_get(dev_id);
1022 [ # # ]: 0 : if (!dparms) {
1023 : 0 : BNXT_TF_DBG(ERR, "could not fetch the device params\n");
1024 : 0 : return -ENODEV;
1025 : : }
1026 : :
1027 [ # # ]: 0 : if (bnxt_ulp_cntxt_mem_type_get(ulp_ctx, &mtype))
1028 : : return -EINVAL;
1029 [ # # ]: 0 : if (mtype != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
1030 : 0 : BNXT_TF_DBG(INFO, "Table Scope free is not required\n");
1031 : 0 : return 0;
1032 : : }
1033 : :
1034 : 0 : rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp_ctx, ¶ms.tbl_scope_id);
1035 [ # # ]: 0 : if (rc) {
1036 : 0 : BNXT_TF_DBG(ERR, "Failed to get the table scope id\n");
1037 : 0 : return -EINVAL;
1038 : : }
1039 : :
1040 : 0 : rc = tf_free_tbl_scope(tfp, ¶ms);
1041 [ # # ]: 0 : if (rc) {
1042 : 0 : BNXT_TF_DBG(ERR, "Unable to free table scope\n");
1043 : 0 : return -EINVAL;
1044 : : }
1045 : : return rc;
1046 : : }
1047 : :
1048 : : /* The function to free and deinit the ulp context data. */
1049 : : static int32_t
1050 : 0 : ulp_ctx_deinit(struct bnxt *bp,
1051 : : struct bnxt_ulp_session_state *session)
1052 : : {
1053 : : /* close the tf session */
1054 : 0 : ulp_ctx_session_close(bp, session);
1055 : :
1056 : : /* The shared session must be closed last. */
1057 [ # # ]: 0 : if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx))
1058 : 0 : ulp_ctx_shared_session_close(bp, BNXT_ULP_SESSION_TYPE_SHARED,
1059 : : session);
1060 : :
1061 [ # # ]: 0 : if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx))
1062 : 0 : ulp_ctx_shared_session_close(bp,
1063 : : BNXT_ULP_SESSION_TYPE_SHARED_WC,
1064 : : session);
1065 : :
1066 : 0 : bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, false);
1067 : :
1068 : : /* Free the contents */
1069 [ # # ]: 0 : if (session->cfg_data) {
1070 : 0 : rte_free(session->cfg_data);
1071 : 0 : bp->ulp_ctx->cfg_data = NULL;
1072 : 0 : session->cfg_data = NULL;
1073 : : }
1074 : 0 : return 0;
1075 : : }
1076 : :
1077 : : /* The function to allocate and initialize the ulp context data. */
1078 : : static int32_t
1079 : 0 : ulp_ctx_init(struct bnxt *bp,
1080 : : struct bnxt_ulp_session_state *session)
1081 : : {
1082 : : struct bnxt_ulp_data *ulp_data;
1083 : : int32_t rc = 0;
1084 : : enum bnxt_ulp_device_id devid;
1085 : : enum bnxt_ulp_session_type stype;
1086 : : struct tf *tfp;
1087 : :
1088 : : /* Initialize the context entries list */
1089 : : bnxt_ulp_cntxt_list_init();
1090 : :
1091 : : /* Add the context to the context entries list */
1092 : 0 : rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx);
1093 [ # # ]: 0 : if (rc) {
1094 : 0 : BNXT_TF_DBG(ERR, "Failed to add the context list entry\n");
1095 : 0 : return -ENOMEM;
1096 : : }
1097 : :
1098 : : /* Allocate memory to hold ulp context data. */
1099 : 0 : ulp_data = rte_zmalloc("bnxt_ulp_data",
1100 : : sizeof(struct bnxt_ulp_data), 0);
1101 [ # # ]: 0 : if (!ulp_data) {
1102 : 0 : BNXT_TF_DBG(ERR, "Failed to allocate memory for ulp data\n");
1103 : 0 : return -ENOMEM;
1104 : : }
1105 : :
1106 : : /* Increment the ulp context data reference count usage. */
1107 : 0 : bp->ulp_ctx->cfg_data = ulp_data;
1108 : 0 : session->cfg_data = ulp_data;
1109 : 0 : ulp_data->ref_cnt++;
1110 [ # # ]: 0 : ulp_data->ulp_flags |= BNXT_ULP_VF_REP_ENABLED;
1111 : :
1112 : : rc = bnxt_ulp_devid_get(bp, &devid);
1113 : : if (rc) {
1114 : : BNXT_TF_DBG(ERR, "Unable to determine device for ULP init.\n");
1115 : : goto error_deinit;
1116 : : }
1117 : :
1118 : 0 : rc = bnxt_ulp_cntxt_dev_id_set(bp->ulp_ctx, devid);
1119 [ # # ]: 0 : if (rc) {
1120 : 0 : BNXT_TF_DBG(ERR, "Unable to set device for ULP init.\n");
1121 : 0 : goto error_deinit;
1122 : : }
1123 : :
1124 : 0 : rc = bnxt_ulp_cntxt_app_id_set(bp->ulp_ctx, bp->app_id);
1125 [ # # ]: 0 : if (rc) {
1126 : 0 : BNXT_TF_DBG(ERR, "Unable to set app_id for ULP init.\n");
1127 : 0 : goto error_deinit;
1128 : : }
1129 : 0 : BNXT_TF_DBG(DEBUG, "Ulp initialized with app id %d\n", bp->app_id);
1130 : :
1131 : 0 : rc = bnxt_ulp_cntxt_app_caps_init(bp, bp->app_id, devid);
1132 [ # # ]: 0 : if (rc) {
1133 : 0 : BNXT_TF_DBG(ERR, "Unable to set caps for app(%x)/dev(%x)\n",
1134 : : bp->app_id, devid);
1135 : 0 : goto error_deinit;
1136 : : }
1137 : :
1138 [ # # ]: 0 : if (BNXT_TESTPMD_EN(bp)) {
1139 : 0 : ulp_data->ulp_flags &= ~BNXT_ULP_VF_REP_ENABLED;
1140 : 0 : BNXT_TF_DBG(ERR, "Enabled Testpmd forward mode\n");
1141 : : }
1142 : :
1143 : : /*
1144 : : * Shared session must be created before first regular session but after
1145 : : * the ulp_ctx is valid.
1146 : : */
1147 [ # # ]: 0 : if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) {
1148 : 0 : rc = ulp_ctx_shared_session_open(bp,
1149 : : BNXT_ULP_SESSION_TYPE_SHARED,
1150 : : session);
1151 [ # # ]: 0 : if (rc) {
1152 : 0 : BNXT_TF_DBG(ERR, "Unable to open shared session (%d)\n",
1153 : : rc);
1154 : 0 : goto error_deinit;
1155 : : }
1156 : : }
1157 : :
1158 : : /* Multiple session support */
1159 [ # # ]: 0 : if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) {
1160 : : stype = BNXT_ULP_SESSION_TYPE_SHARED_WC;
1161 : 0 : rc = ulp_ctx_shared_session_open(bp, stype, session);
1162 [ # # ]: 0 : if (rc) {
1163 : 0 : BNXT_TF_DBG(ERR,
1164 : : "Unable to open shared wc session (%d)\n",
1165 : : rc);
1166 : 0 : goto error_deinit;
1167 : : }
1168 : : }
1169 : 0 : bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, true);
1170 : :
1171 : : /* Open the ulp session. */
1172 : 0 : rc = ulp_ctx_session_open(bp, session);
1173 [ # # ]: 0 : if (rc)
1174 : 0 : goto error_deinit;
1175 : :
1176 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1177 : 0 : bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT, tfp);
1178 : 0 : return rc;
1179 : :
1180 : 0 : error_deinit:
1181 : 0 : session->session_opened[BNXT_ULP_SESSION_TYPE_DEFAULT] = 1;
1182 : 0 : (void)ulp_ctx_deinit(bp, session);
1183 : 0 : return rc;
1184 : : }
1185 : :
1186 : : /* The function to initialize ulp dparms with devargs */
1187 : : static int32_t
1188 : 0 : ulp_dparms_init(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)
1189 : : {
1190 : : struct bnxt_ulp_device_params *dparms;
1191 : 0 : uint32_t dev_id = BNXT_ULP_DEVICE_ID_LAST;
1192 : :
1193 [ # # ]: 0 : if (!bp->max_num_kflows) {
1194 : : /* Defaults to Internal */
1195 : 0 : bnxt_ulp_cntxt_mem_type_set(ulp_ctx,
1196 : : BNXT_ULP_FLOW_MEM_TYPE_INT);
1197 : 0 : return 0;
1198 : : }
1199 : :
1200 : : /* The max_num_kflows were set, so move to external */
1201 [ # # ]: 0 : if (bnxt_ulp_cntxt_mem_type_set(ulp_ctx, BNXT_ULP_FLOW_MEM_TYPE_EXT))
1202 : : return -EINVAL;
1203 : :
1204 [ # # ]: 0 : if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) {
1205 : 0 : BNXT_TF_DBG(DEBUG, "Failed to get device id\n");
1206 : 0 : return -EINVAL;
1207 : : }
1208 : :
1209 : 0 : dparms = bnxt_ulp_device_params_get(dev_id);
1210 [ # # ]: 0 : if (!dparms) {
1211 : 0 : BNXT_TF_DBG(DEBUG, "Failed to get device parms\n");
1212 : 0 : return -EINVAL;
1213 : : }
1214 : :
1215 : : /* num_flows = max_num_kflows * 1024 */
1216 : 0 : dparms->ext_flow_db_num_entries = bp->max_num_kflows * 1024;
1217 : : /* GFID = 2 * num_flows */
1218 : 0 : dparms->mark_db_gfid_entries = dparms->ext_flow_db_num_entries * 2;
1219 : 0 : BNXT_TF_DBG(DEBUG, "Set the number of flows = %" PRIu64 "\n",
1220 : : dparms->ext_flow_db_num_entries);
1221 : :
1222 : 0 : return 0;
1223 : : }
1224 : :
1225 : : /* The function to initialize bp flags with truflow features */
1226 : : static int32_t
1227 : : ulp_dparms_dev_port_intf_update(struct bnxt *bp,
1228 : : struct bnxt_ulp_context *ulp_ctx)
1229 : : {
1230 : : enum bnxt_ulp_flow_mem_type mtype;
1231 : :
1232 [ # # ]: 0 : if (bnxt_ulp_cntxt_mem_type_get(ulp_ctx, &mtype))
1233 : : return -EINVAL;
1234 : : /* Update the bp flag with gfid flag */
1235 [ # # ]: 0 : if (mtype == BNXT_ULP_FLOW_MEM_TYPE_EXT)
1236 : 0 : bp->flags |= BNXT_FLAG_GFID_ENABLE;
1237 : :
1238 : : return 0;
1239 : : }
1240 : :
1241 : : static int32_t
1242 : 0 : ulp_ctx_attach(struct bnxt *bp,
1243 : : struct bnxt_ulp_session_state *session)
1244 : : {
1245 : : int32_t rc = 0;
1246 : 0 : uint32_t flags, dev_id = BNXT_ULP_DEVICE_ID_LAST;
1247 : : struct tf *tfp;
1248 : : uint8_t app_id;
1249 : :
1250 : : /* Increment the ulp context data reference count usage. */
1251 : 0 : bp->ulp_ctx->cfg_data = session->cfg_data;
1252 : 0 : bp->ulp_ctx->cfg_data->ref_cnt++;
1253 : :
1254 : : /* update the session details in bnxt tfp */
1255 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1256 : 0 : tfp->session = bnxt_ulp_session_tfp_get(session,
1257 : : BNXT_ULP_SESSION_TYPE_DEFAULT);
1258 : :
1259 : : /* Add the context to the context entries list */
1260 : 0 : rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx);
1261 [ # # ]: 0 : if (rc) {
1262 : 0 : BNXT_TF_DBG(ERR, "Failed to add the context list entry\n");
1263 : 0 : return -EINVAL;
1264 : : }
1265 : :
1266 : : /*
1267 : : * The supported flag will be set during the init. Use it now to
1268 : : * know if we should go through the attach.
1269 : : */
1270 : 0 : rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id);
1271 [ # # ]: 0 : if (rc) {
1272 : 0 : BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n");
1273 : 0 : return -EINVAL;
1274 : : }
1275 : :
1276 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id);
1277 [ # # ]: 0 : if (rc) {
1278 : 0 : BNXT_TF_DBG(ERR, "Unable do get the dev_id.\n");
1279 : 0 : return -EINVAL;
1280 : : }
1281 : :
1282 : 0 : flags = bp->ulp_ctx->cfg_data->ulp_flags;
1283 [ # # ]: 0 : if (ULP_APP_DEV_UNSUPPORTED_ENABLED(flags)) {
1284 : 0 : BNXT_TF_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
1285 : : app_id, dev_id);
1286 : 0 : return -EINVAL;
1287 : : }
1288 : :
1289 : : /* Create a TF Client */
1290 : 0 : rc = ulp_ctx_session_open(bp, session);
1291 [ # # ]: 0 : if (rc) {
1292 : 0 : PMD_DRV_LOG(ERR, "Failed to open ctxt session, rc:%d\n", rc);
1293 : 0 : tfp->session = NULL;
1294 : 0 : return rc;
1295 : : }
1296 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1297 : 0 : bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT, tfp);
1298 : 0 : return rc;
1299 : : }
1300 : :
1301 : : static void
1302 : 0 : ulp_ctx_detach(struct bnxt *bp)
1303 : : {
1304 : : struct tf *tfp;
1305 : :
1306 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1307 [ # # ]: 0 : if (tfp->session) {
1308 : 0 : tf_close_session(tfp);
1309 : 0 : tfp->session = NULL;
1310 : : }
1311 : 0 : }
1312 : :
1313 : : /*
1314 : : * Initialize the state of an ULP session.
1315 : : * If the state of an ULP session is not initialized, set it's state to
1316 : : * initialized. If the state is already initialized, do nothing.
1317 : : */
1318 : : static void
1319 : 0 : ulp_context_initialized(struct bnxt_ulp_session_state *session, bool *init)
1320 : : {
1321 : 0 : pthread_mutex_lock(&session->bnxt_ulp_mutex);
1322 : :
1323 [ # # ]: 0 : if (!session->bnxt_ulp_init) {
1324 : 0 : session->bnxt_ulp_init = true;
1325 : 0 : *init = false;
1326 : : } else {
1327 : 0 : *init = true;
1328 : : }
1329 : :
1330 : 0 : pthread_mutex_unlock(&session->bnxt_ulp_mutex);
1331 : 0 : }
1332 : :
1333 : : /*
1334 : : * Check if an ULP session is already allocated for a specific PCI
1335 : : * domain & bus. If it is already allocated simply return the session
1336 : : * pointer, otherwise allocate a new session.
1337 : : */
1338 : : static struct bnxt_ulp_session_state *
1339 : 0 : ulp_get_session(struct bnxt *bp, struct rte_pci_addr *pci_addr)
1340 : : {
1341 : : struct bnxt_ulp_session_state *session;
1342 : :
1343 : : /* if multi root capability is enabled, then ignore the pci bus id */
1344 [ # # ]: 0 : STAILQ_FOREACH(session, &bnxt_ulp_session_list, next) {
1345 [ # # ]: 0 : if (BNXT_MULTIROOT_EN(bp)) {
1346 [ # # ]: 0 : if (!memcmp(bp->dsn, session->dsn,
1347 : : sizeof(session->dsn))) {
1348 : 0 : return session;
1349 : : }
1350 [ # # ]: 0 : } else if (session->pci_info.domain == pci_addr->domain &&
1351 [ # # ]: 0 : session->pci_info.bus == pci_addr->bus) {
1352 : 0 : return session;
1353 : : }
1354 : : }
1355 : : return NULL;
1356 : : }
1357 : :
1358 : : /*
1359 : : * Allocate and Initialize an ULP session and set it's state to INITIALIZED.
1360 : : * If it's already initialized simply return the already existing session.
1361 : : */
1362 : : static struct bnxt_ulp_session_state *
1363 : 0 : ulp_session_init(struct bnxt *bp,
1364 : : bool *init)
1365 : : {
1366 : : struct rte_pci_device *pci_dev;
1367 : : struct rte_pci_addr *pci_addr;
1368 : : struct bnxt_ulp_session_state *session;
1369 : : int rc = 0;
1370 : :
1371 [ # # ]: 0 : if (!bp)
1372 : : return NULL;
1373 : :
1374 : 0 : pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
1375 : 0 : pci_addr = &pci_dev->addr;
1376 : :
1377 : 0 : pthread_mutex_lock(&bnxt_ulp_global_mutex);
1378 : :
1379 : 0 : session = ulp_get_session(bp, pci_addr);
1380 [ # # ]: 0 : if (!session) {
1381 : : /* Not Found the session Allocate a new one */
1382 : 0 : session = rte_zmalloc("bnxt_ulp_session",
1383 : : sizeof(struct bnxt_ulp_session_state),
1384 : : 0);
1385 [ # # ]: 0 : if (!session) {
1386 : 0 : BNXT_TF_DBG(ERR,
1387 : : "Allocation failed for bnxt_ulp_session\n");
1388 : 0 : pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1389 : 0 : return NULL;
1390 : :
1391 : : } else {
1392 : : /* Add it to the queue */
1393 : 0 : session->pci_info.domain = pci_addr->domain;
1394 : 0 : session->pci_info.bus = pci_addr->bus;
1395 : 0 : memcpy(session->dsn, bp->dsn, sizeof(session->dsn));
1396 : 0 : rc = pthread_mutex_init(&session->bnxt_ulp_mutex, NULL);
1397 [ # # ]: 0 : if (rc) {
1398 : 0 : BNXT_TF_DBG(ERR, "mutex create failed\n");
1399 : 0 : pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1400 : 0 : return NULL;
1401 : : }
1402 : 0 : STAILQ_INSERT_TAIL(&bnxt_ulp_session_list,
1403 : : session, next);
1404 : : }
1405 : : }
1406 : 0 : ulp_context_initialized(session, init);
1407 : 0 : pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1408 : 0 : return session;
1409 : : }
1410 : :
1411 : : /*
1412 : : * When a device is closed, remove it's associated session from the global
1413 : : * session list.
1414 : : */
1415 : : static void
1416 : 0 : ulp_session_deinit(struct bnxt_ulp_session_state *session)
1417 : : {
1418 [ # # ]: 0 : if (!session)
1419 : : return;
1420 : :
1421 [ # # ]: 0 : if (!session->cfg_data) {
1422 : 0 : pthread_mutex_lock(&bnxt_ulp_global_mutex);
1423 [ # # # # : 0 : STAILQ_REMOVE(&bnxt_ulp_session_list, session,
# # # # ]
1424 : : bnxt_ulp_session_state, next);
1425 : 0 : pthread_mutex_destroy(&session->bnxt_ulp_mutex);
1426 : 0 : rte_free(session);
1427 : 0 : pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1428 : : }
1429 : : }
1430 : :
1431 : : /*
1432 : : * Internal api to enable NAT feature.
1433 : : * Set set_flag to 1 to set the value or zero to reset the value.
1434 : : * returns 0 on success.
1435 : : */
1436 : : static int32_t
1437 : 0 : bnxt_ulp_global_cfg_update(struct bnxt *bp,
1438 : : enum tf_dir dir,
1439 : : enum tf_global_config_type type,
1440 : : uint32_t offset,
1441 : : uint32_t value,
1442 : : uint32_t set_flag)
1443 : : {
1444 : 0 : uint32_t global_cfg = 0;
1445 : : int rc;
1446 : 0 : struct tf_global_cfg_parms parms = { 0 };
1447 : : struct tf *tfp;
1448 : :
1449 : : /* Initialize the params */
1450 : 0 : parms.dir = dir,
1451 : 0 : parms.type = type,
1452 : 0 : parms.offset = offset,
1453 : 0 : parms.config = (uint8_t *)&global_cfg,
1454 : 0 : parms.config_sz_in_bytes = sizeof(global_cfg);
1455 : :
1456 : 0 : tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
1457 : 0 : rc = tf_get_global_cfg(tfp, &parms);
1458 [ # # ]: 0 : if (rc) {
1459 : 0 : BNXT_TF_DBG(ERR, "Failed to get global cfg 0x%x rc:%d\n",
1460 : : type, rc);
1461 : 0 : return rc;
1462 : : }
1463 : :
1464 [ # # ]: 0 : if (set_flag)
1465 : 0 : global_cfg |= value;
1466 : : else
1467 : 0 : global_cfg &= ~value;
1468 : :
1469 : : /* SET the register RE_CFA_REG_ACT_TECT */
1470 : 0 : rc = tf_set_global_cfg(tfp, &parms);
1471 [ # # ]: 0 : if (rc) {
1472 : 0 : BNXT_TF_DBG(ERR, "Failed to set global cfg 0x%x rc:%d\n",
1473 : : type, rc);
1474 : 0 : return rc;
1475 : : }
1476 : : return rc;
1477 : : }
1478 : :
1479 : : /* Internal function to delete all the flows belonging to the given port */
1480 : : static void
1481 : 0 : bnxt_ulp_flush_port_flows(struct bnxt *bp)
1482 : : {
1483 : : uint16_t func_id;
1484 : :
1485 : : /* it is assumed that port is either TVF or PF */
1486 [ # # ]: 0 : if (ulp_port_db_port_func_id_get(bp->ulp_ctx,
1487 : 0 : bp->eth_dev->data->port_id,
1488 : : &func_id)) {
1489 : 0 : BNXT_TF_DBG(ERR, "Invalid argument\n");
1490 : 0 : return;
1491 : : }
1492 : 0 : (void)ulp_flow_db_function_flow_flush(bp->ulp_ctx, func_id);
1493 : : }
1494 : :
1495 : : /* Internal function to delete the VFR default flows */
1496 : : static void
1497 : 0 : bnxt_ulp_destroy_vfr_default_rules(struct bnxt *bp, bool global)
1498 : : {
1499 : : struct bnxt_ulp_vfr_rule_info *info;
1500 : : uint16_t port_id;
1501 : : struct rte_eth_dev *vfr_eth_dev;
1502 : : struct bnxt_representor *vfr_bp;
1503 : :
1504 [ # # # # : 0 : if (!BNXT_TRUFLOW_EN(bp) || BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev))
# # ]
1505 : : return;
1506 : :
1507 [ # # # # ]: 0 : if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
1508 : : return;
1509 : :
1510 : : /* Delete default rules for all ports */
1511 [ # # ]: 0 : for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
1512 : 0 : info = &bp->ulp_ctx->cfg_data->vfr_rule_info[port_id];
1513 [ # # ]: 0 : if (!info->valid)
1514 : 0 : continue;
1515 : :
1516 [ # # ]: 0 : if (!global && info->parent_port_id !=
1517 [ # # ]: 0 : bp->eth_dev->data->port_id)
1518 : 0 : continue;
1519 : :
1520 : : /* Destroy the flows */
1521 : 0 : ulp_default_flow_destroy(bp->eth_dev, info->vfr_flow_id);
1522 : : /* Clean up the tx action pointer */
1523 : : vfr_eth_dev = &rte_eth_devices[port_id];
1524 : : if (vfr_eth_dev) {
1525 : 0 : vfr_bp = vfr_eth_dev->data->dev_private;
1526 : 0 : vfr_bp->vfr_tx_cfa_action = 0;
1527 : : }
1528 : : memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));
1529 : : }
1530 : : }
1531 : :
1532 : : /*
1533 : : * When a port is deinit'ed by dpdk. This function is called
1534 : : * and this function clears the ULP context and rest of the
1535 : : * infrastructure associated with it.
1536 : : */
1537 : : static void
1538 : 0 : bnxt_ulp_deinit(struct bnxt *bp,
1539 : : struct bnxt_ulp_session_state *session)
1540 : : {
1541 : : bool ha_enabled;
1542 : :
1543 [ # # # # ]: 0 : if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
1544 : : return;
1545 : :
1546 : 0 : ha_enabled = bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx);
1547 [ # # # # ]: 0 : if (ha_enabled &&
1548 : : bnxt_ulp_session_is_open(session, BNXT_ULP_SESSION_TYPE_DEFAULT)) {
1549 : 0 : int32_t rc = ulp_ha_mgr_close(bp->ulp_ctx);
1550 [ # # ]: 0 : if (rc)
1551 : 0 : BNXT_TF_DBG(ERR, "Failed to close HA (%d)\n", rc);
1552 : : }
1553 : :
1554 : : /* clean up default flows */
1555 : 0 : bnxt_ulp_destroy_df_rules(bp, true);
1556 : :
1557 : : /* clean up default VFR flows */
1558 : 0 : bnxt_ulp_destroy_vfr_default_rules(bp, true);
1559 : :
1560 : : /* clean up regular flows */
1561 : 0 : ulp_flow_db_flush_flows(bp->ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR);
1562 : :
1563 : : /* cleanup the eem table scope */
1564 : 0 : ulp_eem_tbl_scope_deinit(bp, bp->ulp_ctx);
1565 : :
1566 : : /* cleanup the flow database */
1567 : 0 : ulp_flow_db_deinit(bp->ulp_ctx);
1568 : :
1569 : : /* Delete the Mark database */
1570 : 0 : ulp_mark_db_deinit(bp->ulp_ctx);
1571 : :
1572 : : /* cleanup the ulp mapper */
1573 : 0 : ulp_mapper_deinit(bp->ulp_ctx);
1574 : :
1575 : : /* Delete the Flow Counter Manager */
1576 : 0 : ulp_fc_mgr_deinit(bp->ulp_ctx);
1577 : :
1578 : : /* Delete the Port database */
1579 : 0 : ulp_port_db_deinit(bp->ulp_ctx);
1580 : :
1581 : : /* Disable NAT feature */
1582 : 0 : (void)bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
1583 : : TF_TUNNEL_ENCAP_NAT,
1584 : : BNXT_ULP_NAT_OUTER_MOST_FLAGS, 0);
1585 : :
1586 : 0 : (void)bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
1587 : : TF_TUNNEL_ENCAP_NAT,
1588 : : BNXT_ULP_NAT_OUTER_MOST_FLAGS, 0);
1589 : :
1590 : : /* free the flow db lock */
1591 : 0 : pthread_mutex_destroy(&bp->ulp_ctx->cfg_data->flow_db_lock);
1592 : :
1593 [ # # ]: 0 : if (ha_enabled)
1594 : 0 : ulp_ha_mgr_deinit(bp->ulp_ctx);
1595 : :
1596 : : /* Delete the ulp context and tf session and free the ulp context */
1597 : 0 : ulp_ctx_deinit(bp, session);
1598 : 0 : BNXT_TF_DBG(DEBUG, "ulp ctx has been deinitialized\n");
1599 : : }
1600 : :
1601 : : /*
1602 : : * When a port is initialized by dpdk. This functions is called
1603 : : * and this function initializes the ULP context and rest of the
1604 : : * infrastructure associated with it.
1605 : : */
1606 : : static int32_t
1607 : 0 : bnxt_ulp_init(struct bnxt *bp,
1608 : : struct bnxt_ulp_session_state *session)
1609 : : {
1610 : : int rc;
1611 : 0 : uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
1612 : :
1613 : : /* Allocate and Initialize the ulp context. */
1614 : 0 : rc = ulp_ctx_init(bp, session);
1615 [ # # ]: 0 : if (rc) {
1616 : 0 : BNXT_TF_DBG(ERR, "Failed to create the ulp context\n");
1617 : 0 : goto jump_to_error;
1618 : : }
1619 : :
1620 : 0 : rc = pthread_mutex_init(&bp->ulp_ctx->cfg_data->flow_db_lock, NULL);
1621 [ # # ]: 0 : if (rc) {
1622 : 0 : BNXT_TF_DBG(ERR, "Unable to initialize flow db lock\n");
1623 : 0 : goto jump_to_error;
1624 : : }
1625 : :
1626 : : /* Initialize ulp dparms with values devargs passed */
1627 : 0 : rc = ulp_dparms_init(bp, bp->ulp_ctx);
1628 [ # # ]: 0 : if (rc) {
1629 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize the dparms\n");
1630 : 0 : goto jump_to_error;
1631 : : }
1632 : :
1633 : : /* create the port database */
1634 : 0 : rc = ulp_port_db_init(bp->ulp_ctx, bp->port_cnt);
1635 [ # # ]: 0 : if (rc) {
1636 : 0 : BNXT_TF_DBG(ERR, "Failed to create the port database\n");
1637 : 0 : goto jump_to_error;
1638 : : }
1639 : :
1640 : : /* Create the Mark database. */
1641 : 0 : rc = ulp_mark_db_init(bp->ulp_ctx);
1642 [ # # ]: 0 : if (rc) {
1643 : 0 : BNXT_TF_DBG(ERR, "Failed to create the mark database\n");
1644 : 0 : goto jump_to_error;
1645 : : }
1646 : :
1647 : : /* Create the flow database. */
1648 : 0 : rc = ulp_flow_db_init(bp->ulp_ctx);
1649 [ # # ]: 0 : if (rc) {
1650 : 0 : BNXT_TF_DBG(ERR, "Failed to create the flow database\n");
1651 : 0 : goto jump_to_error;
1652 : : }
1653 : :
1654 : : /* Create the eem table scope. */
1655 : 0 : rc = ulp_eem_tbl_scope_init(bp);
1656 [ # # ]: 0 : if (rc) {
1657 : 0 : BNXT_TF_DBG(ERR, "Failed to create the eem scope table\n");
1658 : 0 : goto jump_to_error;
1659 : : }
1660 : :
1661 : 0 : rc = ulp_mapper_init(bp->ulp_ctx);
1662 [ # # ]: 0 : if (rc) {
1663 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize ulp mapper\n");
1664 : 0 : goto jump_to_error;
1665 : : }
1666 : :
1667 : 0 : rc = ulp_fc_mgr_init(bp->ulp_ctx);
1668 [ # # ]: 0 : if (rc) {
1669 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize ulp flow counter mgr\n");
1670 : 0 : goto jump_to_error;
1671 : : }
1672 : :
1673 : : /*
1674 : : * Enable NAT feature. Set the global configuration register
1675 : : * Tunnel encap to enable NAT with the reuse of existing inner
1676 : : * L2 header smac and dmac
1677 : : */
1678 : 0 : rc = bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
1679 : : TF_TUNNEL_ENCAP_NAT,
1680 : : BNXT_ULP_NAT_OUTER_MOST_FLAGS, 1);
1681 [ # # ]: 0 : if (rc) {
1682 : 0 : BNXT_TF_DBG(ERR, "Failed to set rx global configuration\n");
1683 : 0 : goto jump_to_error;
1684 : : }
1685 : :
1686 : 0 : rc = bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
1687 : : TF_TUNNEL_ENCAP_NAT,
1688 : : BNXT_ULP_NAT_OUTER_MOST_FLAGS, 1);
1689 [ # # ]: 0 : if (rc) {
1690 : 0 : BNXT_TF_DBG(ERR, "Failed to set tx global configuration\n");
1691 : 0 : goto jump_to_error;
1692 : : }
1693 : :
1694 [ # # ]: 0 : if (bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx)) {
1695 : 0 : rc = ulp_ha_mgr_init(bp->ulp_ctx);
1696 [ # # ]: 0 : if (rc) {
1697 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize HA %d\n", rc);
1698 : 0 : goto jump_to_error;
1699 : : }
1700 : 0 : rc = ulp_ha_mgr_open(bp->ulp_ctx);
1701 [ # # ]: 0 : if (rc) {
1702 : 0 : BNXT_TF_DBG(ERR, "Failed to Process HA Open %d\n", rc);
1703 : 0 : goto jump_to_error;
1704 : : }
1705 : : }
1706 : :
1707 : 0 : rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
1708 [ # # ]: 0 : if (rc) {
1709 : 0 : BNXT_TF_DBG(ERR, "Unable to get device id from ulp.\n");
1710 : 0 : return rc;
1711 : : }
1712 : :
1713 [ # # ]: 0 : if (ulp_dev_id == BNXT_ULP_DEVICE_ID_THOR) {
1714 : 0 : rc = bnxt_flow_meter_init(bp);
1715 [ # # ]: 0 : if (rc) {
1716 : 0 : BNXT_TF_DBG(ERR, "Failed to config meter\n");
1717 : 0 : goto jump_to_error;
1718 : : }
1719 : : }
1720 : :
1721 : 0 : BNXT_TF_DBG(DEBUG, "ulp ctx has been initialized\n");
1722 : 0 : return rc;
1723 : :
1724 : 0 : jump_to_error:
1725 : 0 : bnxt_ulp_deinit(bp, session);
1726 : 0 : return rc;
1727 : : }
1728 : :
1729 : : static int
1730 : 0 : ulp_cust_vxlan_alloc(struct bnxt *bp)
1731 : : {
1732 : : int rc = 0;
1733 : :
1734 [ # # ]: 0 : if (ULP_APP_CUST_VXLAN_SUPPORT(bp->ulp_ctx)) {
1735 : 0 : rc = bnxt_tunnel_dst_port_alloc(bp,
1736 : : bp->ulp_ctx->cfg_data->vxlan_port,
1737 : : HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN);
1738 [ # # ]: 0 : if (rc)
1739 : 0 : BNXT_TF_DBG(ERR, "Failed to set global vxlan port\n");
1740 : : }
1741 : :
1742 [ # # ]: 0 : if (ULP_APP_CUST_VXLAN_IP_SUPPORT(bp->ulp_ctx)) {
1743 : 0 : rc = bnxt_tunnel_dst_port_alloc(bp,
1744 : : bp->ulp_ctx->cfg_data->vxlan_ip_port,
1745 : : HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4);
1746 [ # # ]: 0 : if (rc)
1747 : 0 : BNXT_TF_DBG(ERR, "Failed to set global custom vxlan_ip port\n");
1748 : : }
1749 : :
1750 : 0 : return rc;
1751 : : }
1752 : :
1753 : : /*
1754 : : * When a port is initialized by dpdk. This functions sets up
1755 : : * the port specific details.
1756 : : */
1757 : : int32_t
1758 : 0 : bnxt_ulp_port_init(struct bnxt *bp)
1759 : : {
1760 : : struct bnxt_ulp_session_state *session;
1761 : : bool initialized;
1762 : : enum bnxt_ulp_device_id devid = BNXT_ULP_DEVICE_ID_LAST;
1763 : : uint32_t ulp_flags;
1764 : : int32_t rc = 0;
1765 : :
1766 [ # # # # ]: 0 : if (!BNXT_TRUFLOW_EN(bp)) {
1767 : 0 : BNXT_TF_DBG(DEBUG,
1768 : : "Skip ulp init for port: %d, TF is not enabled\n",
1769 : : bp->eth_dev->data->port_id);
1770 : 0 : return rc;
1771 : : }
1772 : :
1773 [ # # ]: 0 : if (!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {
1774 : 0 : BNXT_TF_DBG(DEBUG,
1775 : : "Skip ulp init for port: %d, not a TVF or PF\n",
1776 : : bp->eth_dev->data->port_id);
1777 : 0 : return rc;
1778 : : }
1779 : :
1780 [ # # ]: 0 : if (bp->ulp_ctx) {
1781 : 0 : BNXT_TF_DBG(DEBUG, "ulp ctx already allocated\n");
1782 : 0 : return rc;
1783 : : }
1784 : :
1785 : 0 : bp->ulp_ctx = rte_zmalloc("bnxt_ulp_ctx",
1786 : : sizeof(struct bnxt_ulp_context), 0);
1787 [ # # ]: 0 : if (!bp->ulp_ctx) {
1788 : 0 : BNXT_TF_DBG(ERR, "Failed to allocate ulp ctx\n");
1789 : 0 : return -ENOMEM;
1790 : : }
1791 : :
1792 : : /*
1793 : : * Multiple uplink ports can be associated with a single vswitch.
1794 : : * Make sure only the port that is started first will initialize
1795 : : * the TF session.
1796 : : */
1797 : 0 : session = ulp_session_init(bp, &initialized);
1798 [ # # ]: 0 : if (!session) {
1799 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize the tf session\n");
1800 : : rc = -EIO;
1801 : 0 : goto jump_to_error;
1802 : : }
1803 : :
1804 [ # # ]: 0 : if (initialized) {
1805 : : /*
1806 : : * If ULP is already initialized for a specific domain then
1807 : : * simply assign the ulp context to this rte_eth_dev.
1808 : : */
1809 : 0 : rc = ulp_ctx_attach(bp, session);
1810 [ # # ]: 0 : if (rc) {
1811 : 0 : BNXT_TF_DBG(ERR, "Failed to attach the ulp context\n");
1812 : 0 : goto jump_to_error;
1813 : : }
1814 : :
1815 : : /*
1816 : : * Attach to the shared session, must be called after the
1817 : : * ulp_ctx_attach in order to ensure that ulp data is available
1818 : : * for attaching.
1819 : : */
1820 : 0 : rc = ulp_ctx_shared_session_attach(bp, session);
1821 [ # # ]: 0 : if (rc) {
1822 : 0 : BNXT_TF_DBG(ERR,
1823 : : "Failed attach to shared session (%d)", rc);
1824 : 0 : goto jump_to_error;
1825 : : }
1826 : : } else {
1827 : 0 : rc = bnxt_ulp_init(bp, session);
1828 [ # # ]: 0 : if (rc) {
1829 : 0 : BNXT_TF_DBG(ERR, "Failed to initialize the ulp init\n");
1830 : 0 : goto jump_to_error;
1831 : : }
1832 : : }
1833 : :
1834 : : /* Update bnxt driver flags */
1835 : 0 : rc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx);
1836 : : if (rc) {
1837 : 0 : BNXT_TF_DBG(ERR, "Failed to update driver flags\n");
1838 : 0 : goto jump_to_error;
1839 : : }
1840 : :
1841 : : /* update the port database for the given interface */
1842 : 0 : rc = ulp_port_db_port_update(bp->ulp_ctx, bp->eth_dev);
1843 [ # # ]: 0 : if (rc) {
1844 : 0 : BNXT_TF_DBG(ERR, "Failed to update port database\n");
1845 : 0 : goto jump_to_error;
1846 : : }
1847 : :
1848 : : /* create the default rules */
1849 : 0 : rc = bnxt_ulp_create_df_rules(bp);
1850 [ # # ]: 0 : if (rc) {
1851 : 0 : BNXT_TF_DBG(ERR, "Failed to create default flow\n");
1852 : 0 : goto jump_to_error;
1853 : : }
1854 : :
1855 : : rc = bnxt_ulp_devid_get(bp, &devid);
1856 : : if (rc) {
1857 : : BNXT_TF_DBG(ERR, "Unable to determine device for ULP port init.\n");
1858 : : goto jump_to_error;
1859 : : }
1860 : :
1861 : : /* set the unicast mode */
1862 [ # # ]: 0 : if (bnxt_ulp_cntxt_ptr2_ulp_flags_get(bp->ulp_ctx, &ulp_flags)) {
1863 : 0 : BNXT_TF_DBG(ERR, "Error in getting ULP context flags\n");
1864 : 0 : goto jump_to_error;
1865 : : }
1866 [ # # ]: 0 : if (ulp_flags & BNXT_ULP_APP_UNICAST_ONLY) {
1867 [ # # ]: 0 : if (bnxt_pmd_set_unicast_rxmask(bp->eth_dev)) {
1868 : 0 : BNXT_TF_DBG(ERR, "Error in setting unicast rxmode\n");
1869 : 0 : goto jump_to_error;
1870 : : }
1871 : : }
1872 : :
1873 : 0 : rc = ulp_cust_vxlan_alloc(bp);
1874 [ # # ]: 0 : if (rc)
1875 : 0 : goto jump_to_error;
1876 : :
1877 : : return rc;
1878 : :
1879 : 0 : jump_to_error:
1880 : 0 : bnxt_ulp_port_deinit(bp);
1881 : 0 : return rc;
1882 : : }
1883 : :
1884 : : static void
1885 : 0 : ulp_cust_vxlan_free(struct bnxt *bp)
1886 : : {
1887 : : int rc;
1888 : :
1889 [ # # ]: 0 : if (ULP_APP_CUST_VXLAN_SUPPORT(bp->ulp_ctx)) {
1890 : 0 : rc = bnxt_tunnel_dst_port_free(bp,
1891 : : bp->ulp_ctx->cfg_data->vxlan_port,
1892 : : HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN);
1893 [ # # ]: 0 : if (rc)
1894 : 0 : BNXT_TF_DBG(ERR, "Failed to clear global vxlan port\n");
1895 : : }
1896 : :
1897 [ # # ]: 0 : if (ULP_APP_CUST_VXLAN_IP_SUPPORT(bp->ulp_ctx)) {
1898 : 0 : rc = bnxt_tunnel_dst_port_free(bp,
1899 : : bp->ulp_ctx->cfg_data->vxlan_ip_port,
1900 : : HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN_V4);
1901 [ # # ]: 0 : if (rc)
1902 : 0 : BNXT_TF_DBG(ERR, "Failed to clear global custom vxlan port\n");
1903 : : }
1904 : 0 : }
1905 : :
1906 : : /*
1907 : : * When a port is de-initialized by dpdk. This functions clears up
1908 : : * the port specific details.
1909 : : */
1910 : : void
1911 : 0 : bnxt_ulp_port_deinit(struct bnxt *bp)
1912 : : {
1913 : : struct bnxt_ulp_session_state *session;
1914 : : struct rte_pci_device *pci_dev;
1915 : : struct rte_pci_addr *pci_addr;
1916 : :
1917 [ # # # # ]: 0 : if (!BNXT_TRUFLOW_EN(bp)) {
1918 : 0 : BNXT_TF_DBG(DEBUG,
1919 : : "Skip ULP deinit for port:%d, TF is not enabled\n",
1920 : : bp->eth_dev->data->port_id);
1921 : 0 : return;
1922 : : }
1923 : :
1924 [ # # ]: 0 : if (!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {
1925 : 0 : BNXT_TF_DBG(DEBUG,
1926 : : "Skip ULP deinit port:%d, not a TVF or PF\n",
1927 : : bp->eth_dev->data->port_id);
1928 : 0 : return;
1929 : : }
1930 : :
1931 [ # # ]: 0 : if (!bp->ulp_ctx) {
1932 : 0 : BNXT_TF_DBG(DEBUG, "ulp ctx already de-allocated\n");
1933 : 0 : return;
1934 : : }
1935 : :
1936 : 0 : BNXT_TF_DBG(DEBUG, "BNXT Port:%d ULP port deinit\n",
1937 : : bp->eth_dev->data->port_id);
1938 : :
1939 : : /* Get the session details */
1940 : 0 : pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
1941 : 0 : pci_addr = &pci_dev->addr;
1942 : 0 : pthread_mutex_lock(&bnxt_ulp_global_mutex);
1943 : 0 : session = ulp_get_session(bp, pci_addr);
1944 : 0 : pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1945 : :
1946 : : /* session not found then just exit */
1947 [ # # ]: 0 : if (!session) {
1948 : : /* Free the ulp context */
1949 : 0 : rte_free(bp->ulp_ctx);
1950 : 0 : bp->ulp_ctx = NULL;
1951 : 0 : return;
1952 : : }
1953 : :
1954 : : /* Check the reference count to deinit or deattach*/
1955 [ # # # # ]: 0 : if (bp->ulp_ctx->cfg_data && bp->ulp_ctx->cfg_data->ref_cnt) {
1956 : 0 : bp->ulp_ctx->cfg_data->ref_cnt--;
1957 [ # # ]: 0 : if (bp->ulp_ctx->cfg_data->ref_cnt) {
1958 : : /* Free tunnel configurations */
1959 : 0 : ulp_cust_vxlan_free(bp);
1960 : :
1961 : : /* free the port details */
1962 : : /* Free the default flow rule associated to this port */
1963 : 0 : bnxt_ulp_destroy_df_rules(bp, false);
1964 : 0 : bnxt_ulp_destroy_vfr_default_rules(bp, false);
1965 : :
1966 : : /* free flows associated with this port */
1967 : 0 : bnxt_ulp_flush_port_flows(bp);
1968 : :
1969 : : /* close the session associated with this port */
1970 : 0 : ulp_ctx_detach(bp);
1971 : :
1972 : : /* always detach/close shared after the session. */
1973 : 0 : ulp_ctx_shared_session_detach(bp);
1974 : : } else {
1975 : : /* Perform ulp ctx deinit */
1976 : 0 : bnxt_ulp_deinit(bp, session);
1977 : : }
1978 : : }
1979 : :
1980 : : /* Free the ulp context in the context entry list */
1981 : 0 : bnxt_ulp_cntxt_list_del(bp->ulp_ctx);
1982 : :
1983 : : /* clean up the session */
1984 : 0 : ulp_session_deinit(session);
1985 : :
1986 : : /* Free the ulp context */
1987 : 0 : rte_free(bp->ulp_ctx);
1988 : 0 : bp->ulp_ctx = NULL;
1989 : : }
1990 : :
1991 : : /* Below are the access functions to access internal data of ulp context. */
1992 : : /* Function to set the Mark DB into the context */
1993 : : int32_t
1994 : 0 : bnxt_ulp_cntxt_ptr2_mark_db_set(struct bnxt_ulp_context *ulp_ctx,
1995 : : struct bnxt_ulp_mark_tbl *mark_tbl)
1996 : : {
1997 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data) {
1998 : 0 : BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
1999 : 0 : return -EINVAL;
2000 : : }
2001 : :
2002 : 0 : ulp_ctx->cfg_data->mark_tbl = mark_tbl;
2003 : :
2004 : 0 : return 0;
2005 : : }
2006 : :
2007 : : /* Function to retrieve the Mark DB from the context. */
2008 : : struct bnxt_ulp_mark_tbl *
2009 : 0 : bnxt_ulp_cntxt_ptr2_mark_db_get(struct bnxt_ulp_context *ulp_ctx)
2010 : : {
2011 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2012 : : return NULL;
2013 : :
2014 : 0 : return ulp_ctx->cfg_data->mark_tbl;
2015 : : }
2016 : :
2017 : : bool
2018 : 0 : bnxt_ulp_cntxt_shared_session_enabled(struct bnxt_ulp_context *ulp_ctx)
2019 : : {
2020 : 0 : return ULP_SHARED_SESSION_IS_ENABLED(ulp_ctx->cfg_data->ulp_flags);
2021 : : }
2022 : :
2023 : : bool
2024 : 0 : bnxt_ulp_cntxt_multi_shared_session_enabled(struct bnxt_ulp_context *ulp_ctx)
2025 : : {
2026 : 0 : return ULP_MULTI_SHARED_IS_SUPPORTED(ulp_ctx);
2027 : : }
2028 : :
2029 : : int32_t
2030 : 0 : bnxt_ulp_cntxt_app_id_set(struct bnxt_ulp_context *ulp_ctx, uint8_t app_id)
2031 : : {
2032 [ # # ]: 0 : if (!ulp_ctx)
2033 : : return -EINVAL;
2034 : 0 : ulp_ctx->cfg_data->app_id = app_id;
2035 : 0 : return 0;
2036 : : }
2037 : :
2038 : : int32_t
2039 : 0 : bnxt_ulp_cntxt_app_id_get(struct bnxt_ulp_context *ulp_ctx, uint8_t *app_id)
2040 : : {
2041 : : /* Default APP id is zero */
2042 [ # # ]: 0 : if (!ulp_ctx || !app_id)
2043 : : return -EINVAL;
2044 : 0 : *app_id = ulp_ctx->cfg_data->app_id;
2045 : 0 : return 0;
2046 : : }
2047 : :
2048 : : /* Function to set the device id of the hardware. */
2049 : : int32_t
2050 : 0 : bnxt_ulp_cntxt_dev_id_set(struct bnxt_ulp_context *ulp_ctx,
2051 : : uint32_t dev_id)
2052 : : {
2053 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2054 : 0 : ulp_ctx->cfg_data->dev_id = dev_id;
2055 : 0 : return 0;
2056 : : }
2057 : :
2058 : : return -EINVAL;
2059 : : }
2060 : :
2061 : : /* Function to get the device id of the hardware. */
2062 : : int32_t
2063 : 0 : bnxt_ulp_cntxt_dev_id_get(struct bnxt_ulp_context *ulp_ctx,
2064 : : uint32_t *dev_id)
2065 : : {
2066 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2067 : 0 : *dev_id = ulp_ctx->cfg_data->dev_id;
2068 : 0 : return 0;
2069 : : }
2070 : 0 : *dev_id = BNXT_ULP_DEVICE_ID_LAST;
2071 : 0 : BNXT_TF_DBG(ERR, "Failed to read dev_id from ulp ctxt\n");
2072 : 0 : return -EINVAL;
2073 : : }
2074 : :
2075 : : int32_t
2076 : 0 : bnxt_ulp_cntxt_mem_type_set(struct bnxt_ulp_context *ulp_ctx,
2077 : : enum bnxt_ulp_flow_mem_type mem_type)
2078 : : {
2079 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2080 : 0 : ulp_ctx->cfg_data->mem_type = mem_type;
2081 : 0 : return 0;
2082 : : }
2083 : 0 : BNXT_TF_DBG(ERR, "Failed to write mem_type in ulp ctxt\n");
2084 : 0 : return -EINVAL;
2085 : : }
2086 : :
2087 : : int32_t
2088 : 0 : bnxt_ulp_cntxt_mem_type_get(struct bnxt_ulp_context *ulp_ctx,
2089 : : enum bnxt_ulp_flow_mem_type *mem_type)
2090 : : {
2091 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2092 : 0 : *mem_type = ulp_ctx->cfg_data->mem_type;
2093 : 0 : return 0;
2094 : : }
2095 : 0 : *mem_type = BNXT_ULP_FLOW_MEM_TYPE_LAST;
2096 : 0 : BNXT_TF_DBG(ERR, "Failed to read mem_type in ulp ctxt\n");
2097 : 0 : return -EINVAL;
2098 : : }
2099 : :
2100 : : /* Function to get the table scope id of the EEM table. */
2101 : : int32_t
2102 : 0 : bnxt_ulp_cntxt_tbl_scope_id_get(struct bnxt_ulp_context *ulp_ctx,
2103 : : uint32_t *tbl_scope_id)
2104 : : {
2105 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2106 : 0 : *tbl_scope_id = ulp_ctx->cfg_data->tbl_scope_id;
2107 : 0 : return 0;
2108 : : }
2109 : :
2110 : : return -EINVAL;
2111 : : }
2112 : :
2113 : : /* Function to set the table scope id of the EEM table. */
2114 : : int32_t
2115 : 0 : bnxt_ulp_cntxt_tbl_scope_id_set(struct bnxt_ulp_context *ulp_ctx,
2116 : : uint32_t tbl_scope_id)
2117 : : {
2118 [ # # # # ]: 0 : if (ulp_ctx && ulp_ctx->cfg_data) {
2119 : 0 : ulp_ctx->cfg_data->tbl_scope_id = tbl_scope_id;
2120 : 0 : return 0;
2121 : : }
2122 : :
2123 : : return -EINVAL;
2124 : : }
2125 : :
2126 : : /* Function to get the number of shared clients attached */
2127 : : uint8_t
2128 : 0 : bnxt_ulp_cntxt_num_shared_clients_get(struct bnxt_ulp_context *ulp)
2129 : : {
2130 [ # # # # ]: 0 : if (ulp == NULL || ulp->cfg_data == NULL) {
2131 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments\n");
2132 : 0 : return 0;
2133 : : }
2134 : 0 : return ulp->cfg_data->num_shared_clients;
2135 : : }
2136 : :
2137 : : /* Function to set the number of shared clients */
2138 : : int
2139 : 0 : bnxt_ulp_cntxt_num_shared_clients_set(struct bnxt_ulp_context *ulp, bool incr)
2140 : : {
2141 [ # # # # ]: 0 : if (ulp == NULL || ulp->cfg_data == NULL) {
2142 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments\n");
2143 : 0 : return 0;
2144 : : }
2145 [ # # ]: 0 : if (incr)
2146 : 0 : ulp->cfg_data->num_shared_clients++;
2147 [ # # ]: 0 : else if (ulp->cfg_data->num_shared_clients)
2148 : 0 : ulp->cfg_data->num_shared_clients--;
2149 : :
2150 : 0 : BNXT_TF_DBG(DEBUG, "%d:clients(%d)\n", incr,
2151 : : ulp->cfg_data->num_shared_clients);
2152 : :
2153 : 0 : return 0;
2154 : : }
2155 : :
2156 : : /* Function to set the tfp session details from the ulp context. */
2157 : : int32_t
2158 : 0 : bnxt_ulp_cntxt_tfp_set(struct bnxt_ulp_context *ulp,
2159 : : enum bnxt_ulp_session_type s_type,
2160 : : struct tf *tfp)
2161 : : {
2162 : : uint32_t idx = 0;
2163 : :
2164 [ # # ]: 0 : if (!ulp) {
2165 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments\n");
2166 : 0 : return -EINVAL;
2167 : : }
2168 [ # # ]: 0 : if (ULP_MULTI_SHARED_IS_SUPPORTED(ulp)) {
2169 [ # # ]: 0 : if (s_type & BNXT_ULP_SESSION_TYPE_SHARED)
2170 : : idx = 1;
2171 [ # # ]: 0 : else if (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC)
2172 : : idx = 2;
2173 : :
2174 : : } else {
2175 [ # # ]: 0 : if ((s_type & BNXT_ULP_SESSION_TYPE_SHARED) ||
2176 : : (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC))
2177 : : idx = 1;
2178 : : }
2179 : :
2180 : 0 : ulp->g_tfp[idx] = tfp;
2181 : 0 : return 0;
2182 : : }
2183 : :
2184 : : /* Function to get the tfp session details from the ulp context. */
2185 : : struct tf *
2186 : 0 : bnxt_ulp_cntxt_tfp_get(struct bnxt_ulp_context *ulp,
2187 : : enum bnxt_ulp_session_type s_type)
2188 : : {
2189 : : uint32_t idx = 0;
2190 : :
2191 [ # # ]: 0 : if (!ulp) {
2192 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments\n");
2193 : 0 : return NULL;
2194 : : }
2195 [ # # ]: 0 : if (ULP_MULTI_SHARED_IS_SUPPORTED(ulp)) {
2196 [ # # ]: 0 : if (s_type & BNXT_ULP_SESSION_TYPE_SHARED)
2197 : : idx = 1;
2198 [ # # ]: 0 : else if (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC)
2199 : : idx = 2;
2200 : : } else {
2201 [ # # ]: 0 : if ((s_type & BNXT_ULP_SESSION_TYPE_SHARED) ||
2202 : : (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC))
2203 : : idx = 1;
2204 : : }
2205 : 0 : return ulp->g_tfp[idx];
2206 : : }
2207 : :
2208 : : /*
2209 : : * Get the device table entry based on the device id.
2210 : : *
2211 : : * dev_id [in] The device id of the hardware
2212 : : *
2213 : : * Returns the pointer to the device parameters.
2214 : : */
2215 : : struct bnxt_ulp_device_params *
2216 : 0 : bnxt_ulp_device_params_get(uint32_t dev_id)
2217 : : {
2218 [ # # ]: 0 : if (dev_id < BNXT_ULP_MAX_NUM_DEVICES)
2219 : 0 : return &ulp_device_params[dev_id];
2220 : : return NULL;
2221 : : }
2222 : :
2223 : : /* Function to set the flow database to the ulp context. */
2224 : : int32_t
2225 : 0 : bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx,
2226 : : struct bnxt_ulp_flow_db *flow_db)
2227 : : {
2228 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2229 : : return -EINVAL;
2230 : :
2231 : 0 : ulp_ctx->cfg_data->flow_db = flow_db;
2232 : 0 : return 0;
2233 : : }
2234 : :
2235 : : /* Function to get the flow database from the ulp context. */
2236 : : struct bnxt_ulp_flow_db *
2237 : 0 : bnxt_ulp_cntxt_ptr2_flow_db_get(struct bnxt_ulp_context *ulp_ctx)
2238 : : {
2239 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2240 : : return NULL;
2241 : :
2242 : 0 : return ulp_ctx->cfg_data->flow_db;
2243 : : }
2244 : :
2245 : : /* Function to get the tunnel cache table info from the ulp context. */
2246 : : struct bnxt_tun_cache_entry *
2247 : 0 : bnxt_ulp_cntxt_ptr2_tun_tbl_get(struct bnxt_ulp_context *ulp_ctx)
2248 : : {
2249 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2250 : : return NULL;
2251 : :
2252 : 0 : return ulp_ctx->cfg_data->tun_tbl;
2253 : : }
2254 : :
2255 : : /* Function to get the ulp context from eth device. */
2256 : : struct bnxt_ulp_context *
2257 : 0 : bnxt_ulp_eth_dev_ptr2_cntxt_get(struct rte_eth_dev *dev)
2258 : : {
2259 : 0 : struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
2260 : :
2261 [ # # ]: 0 : if (BNXT_ETH_DEV_IS_REPRESENTOR(dev)) {
2262 : : struct bnxt_representor *vfr = dev->data->dev_private;
2263 : :
2264 : 0 : bp = vfr->parent_dev->data->dev_private;
2265 : : }
2266 : :
2267 [ # # ]: 0 : if (!bp) {
2268 : 0 : BNXT_TF_DBG(ERR, "Bnxt private data is not initialized\n");
2269 : 0 : return NULL;
2270 : : }
2271 : 0 : return bp->ulp_ctx;
2272 : : }
2273 : :
2274 : : int32_t
2275 : 0 : bnxt_ulp_cntxt_ptr2_mapper_data_set(struct bnxt_ulp_context *ulp_ctx,
2276 : : void *mapper_data)
2277 : : {
2278 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data) {
2279 : 0 : BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
2280 : 0 : return -EINVAL;
2281 : : }
2282 : :
2283 : 0 : ulp_ctx->cfg_data->mapper_data = mapper_data;
2284 : 0 : return 0;
2285 : : }
2286 : :
2287 : : void *
2288 : 0 : bnxt_ulp_cntxt_ptr2_mapper_data_get(struct bnxt_ulp_context *ulp_ctx)
2289 : : {
2290 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data) {
2291 : 0 : BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
2292 : 0 : return NULL;
2293 : : }
2294 : :
2295 : 0 : return ulp_ctx->cfg_data->mapper_data;
2296 : : }
2297 : :
2298 : : /* Function to set the port database to the ulp context. */
2299 : : int32_t
2300 : 0 : bnxt_ulp_cntxt_ptr2_port_db_set(struct bnxt_ulp_context *ulp_ctx,
2301 : : struct bnxt_ulp_port_db *port_db)
2302 : : {
2303 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2304 : : return -EINVAL;
2305 : :
2306 : 0 : ulp_ctx->cfg_data->port_db = port_db;
2307 : 0 : return 0;
2308 : : }
2309 : :
2310 : : /* Function to get the port database from the ulp context. */
2311 : : struct bnxt_ulp_port_db *
2312 : 0 : bnxt_ulp_cntxt_ptr2_port_db_get(struct bnxt_ulp_context *ulp_ctx)
2313 : : {
2314 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2315 : : return NULL;
2316 : :
2317 : 0 : return ulp_ctx->cfg_data->port_db;
2318 : : }
2319 : :
2320 : : /* Function to set the flow counter info into the context */
2321 : : int32_t
2322 : 0 : bnxt_ulp_cntxt_ptr2_fc_info_set(struct bnxt_ulp_context *ulp_ctx,
2323 : : struct bnxt_ulp_fc_info *ulp_fc_info)
2324 : : {
2325 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data) {
2326 : 0 : BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
2327 : 0 : return -EINVAL;
2328 : : }
2329 : :
2330 : 0 : ulp_ctx->cfg_data->fc_info = ulp_fc_info;
2331 : :
2332 : 0 : return 0;
2333 : : }
2334 : :
2335 : : /* Function to retrieve the flow counter info from the context. */
2336 : : struct bnxt_ulp_fc_info *
2337 : 0 : bnxt_ulp_cntxt_ptr2_fc_info_get(struct bnxt_ulp_context *ulp_ctx)
2338 : : {
2339 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2340 : : return NULL;
2341 : :
2342 : 0 : return ulp_ctx->cfg_data->fc_info;
2343 : : }
2344 : :
2345 : : /* Function to get the ulp flags from the ulp context. */
2346 : : int32_t
2347 : 0 : bnxt_ulp_cntxt_ptr2_ulp_flags_get(struct bnxt_ulp_context *ulp_ctx,
2348 : : uint32_t *flags)
2349 : : {
2350 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2351 : : return -1;
2352 : :
2353 : 0 : *flags = ulp_ctx->cfg_data->ulp_flags;
2354 : 0 : return 0;
2355 : : }
2356 : :
2357 : : /* Function to get the ulp vfr info from the ulp context. */
2358 : : struct bnxt_ulp_vfr_rule_info*
2359 : 0 : bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(struct bnxt_ulp_context *ulp_ctx,
2360 : : uint32_t port_id)
2361 : : {
2362 [ # # # # : 0 : if (!ulp_ctx || !ulp_ctx->cfg_data || port_id >= RTE_MAX_ETHPORTS)
# # ]
2363 : : return NULL;
2364 : :
2365 : 0 : return &ulp_ctx->cfg_data->vfr_rule_info[port_id];
2366 : : }
2367 : :
2368 : : /* Function to acquire the flow database lock from the ulp context. */
2369 : : int32_t
2370 : 0 : bnxt_ulp_cntxt_acquire_fdb_lock(struct bnxt_ulp_context *ulp_ctx)
2371 : : {
2372 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2373 : : return -1;
2374 : :
2375 [ # # ]: 0 : if (pthread_mutex_lock(&ulp_ctx->cfg_data->flow_db_lock)) {
2376 : 0 : BNXT_TF_DBG(ERR, "unable to acquire fdb lock\n");
2377 : 0 : return -1;
2378 : : }
2379 : : return 0;
2380 : : }
2381 : :
2382 : : /* Function to release the flow database lock from the ulp context. */
2383 : : void
2384 : 0 : bnxt_ulp_cntxt_release_fdb_lock(struct bnxt_ulp_context *ulp_ctx)
2385 : : {
2386 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2387 : : return;
2388 : :
2389 : 0 : pthread_mutex_unlock(&ulp_ctx->cfg_data->flow_db_lock);
2390 : : }
2391 : :
2392 : : /* Function to extract the action type from the shared action handle. */
2393 : : int32_t
2394 : 0 : bnxt_get_action_handle_type(const struct rte_flow_action_handle *handle,
2395 : : uint32_t *action_handle_type)
2396 : : {
2397 [ # # ]: 0 : if (!action_handle_type)
2398 : : return -EINVAL;
2399 : :
2400 : 0 : *action_handle_type = (uint32_t)(((uint64_t)handle >> 32) & 0xffffffff);
2401 [ # # ]: 0 : if (*action_handle_type >= BNXT_ULP_GEN_TBL_MAX_SZ)
2402 : 0 : return -EINVAL;
2403 : :
2404 : : return 0;
2405 : : }
2406 : :
2407 : : /* Function to extract the direction from the shared action handle. */
2408 : : int32_t
2409 : 0 : bnxt_get_action_handle_direction(const struct rte_flow_action_handle *handle,
2410 : : uint32_t *dir)
2411 : : {
2412 : : uint32_t shared_type;
2413 : : int32_t ret = 0;
2414 : :
2415 : 0 : ret = bnxt_get_action_handle_type(handle, &shared_type);
2416 [ # # ]: 0 : if (ret)
2417 : : return ret;
2418 : :
2419 [ # # ]: 0 : *dir = shared_type & 0x1 ? BNXT_ULP_DIR_EGRESS : BNXT_ULP_DIR_INGRESS;
2420 : :
2421 : 0 : return ret;
2422 : : }
2423 : :
2424 : : /* Function to extract the action index from the shared action handle. */
2425 : : uint32_t
2426 : 0 : bnxt_get_action_handle_index(const struct rte_flow_action_handle *handle)
2427 : : {
2428 : 0 : return (uint32_t)((uint64_t)handle & 0xffffffff);
2429 : : }
2430 : :
2431 : : /* Function to set the ha info into the context */
2432 : : int32_t
2433 : 0 : bnxt_ulp_cntxt_ptr2_ha_info_set(struct bnxt_ulp_context *ulp_ctx,
2434 : : struct bnxt_ulp_ha_mgr_info *ulp_ha_info)
2435 : : {
2436 [ # # # # ]: 0 : if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL) {
2437 : 0 : BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
2438 : 0 : return -EINVAL;
2439 : : }
2440 : 0 : ulp_ctx->cfg_data->ha_info = ulp_ha_info;
2441 : 0 : return 0;
2442 : : }
2443 : :
2444 : : /* Function to retrieve the ha info from the context. */
2445 : : struct bnxt_ulp_ha_mgr_info *
2446 : 0 : bnxt_ulp_cntxt_ptr2_ha_info_get(struct bnxt_ulp_context *ulp_ctx)
2447 : : {
2448 [ # # # # ]: 0 : if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
2449 : : return NULL;
2450 : 0 : return ulp_ctx->cfg_data->ha_info;
2451 : : }
2452 : :
2453 : : bool
2454 : 0 : bnxt_ulp_cntxt_ha_enabled(struct bnxt_ulp_context *ulp_ctx)
2455 : : {
2456 [ # # # # ]: 0 : if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
2457 : : return false;
2458 : 0 : return !!ULP_HIGH_AVAIL_IS_ENABLED(ulp_ctx->cfg_data->ulp_flags);
2459 : : }
2460 : :
2461 : : static int32_t
2462 : : bnxt_ulp_cntxt_list_init(void)
2463 : : {
2464 : : /* Create the cntxt spin lock only once*/
2465 [ # # ]: 0 : if (!bnxt_ulp_ctxt_lock_created)
2466 : : rte_spinlock_init(&bnxt_ulp_ctxt_lock);
2467 : 0 : bnxt_ulp_ctxt_lock_created = 1;
2468 : : return 0;
2469 : : }
2470 : :
2471 : : static int32_t
2472 : 0 : bnxt_ulp_cntxt_list_add(struct bnxt_ulp_context *ulp_ctx)
2473 : : {
2474 : : struct ulp_context_list_entry *entry;
2475 : :
2476 : 0 : entry = rte_zmalloc(NULL, sizeof(struct ulp_context_list_entry), 0);
2477 [ # # ]: 0 : if (entry == NULL) {
2478 : 0 : BNXT_TF_DBG(ERR, "unable to allocate memory\n");
2479 : 0 : return -ENOMEM;
2480 : : }
2481 : :
2482 : : rte_spinlock_lock(&bnxt_ulp_ctxt_lock);
2483 : 0 : entry->ulp_ctx = ulp_ctx;
2484 : 0 : TAILQ_INSERT_TAIL(&ulp_cntx_list, entry, next);
2485 : : rte_spinlock_unlock(&bnxt_ulp_ctxt_lock);
2486 : 0 : return 0;
2487 : : }
2488 : :
2489 : : static void
2490 : 0 : bnxt_ulp_cntxt_list_del(struct bnxt_ulp_context *ulp_ctx)
2491 : : {
2492 : : struct ulp_context_list_entry *entry, *temp;
2493 : :
2494 : : rte_spinlock_lock(&bnxt_ulp_ctxt_lock);
2495 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(entry, &ulp_cntx_list, next, temp) {
2496 [ # # ]: 0 : if (entry->ulp_ctx == ulp_ctx) {
2497 [ # # ]: 0 : TAILQ_REMOVE(&ulp_cntx_list, entry, next);
2498 : 0 : rte_free(entry);
2499 : 0 : break;
2500 : : }
2501 : : }
2502 : : rte_spinlock_unlock(&bnxt_ulp_ctxt_lock);
2503 : 0 : }
2504 : :
2505 : : struct bnxt_ulp_context *
2506 : 0 : bnxt_ulp_cntxt_entry_acquire(void *arg)
2507 : : {
2508 : : struct ulp_context_list_entry *entry;
2509 : :
2510 : : /* take a lock and get the first ulp context available */
2511 [ # # ]: 0 : if (rte_spinlock_trylock(&bnxt_ulp_ctxt_lock)) {
2512 [ # # ]: 0 : TAILQ_FOREACH(entry, &ulp_cntx_list, next)
2513 [ # # ]: 0 : if (entry->ulp_ctx->cfg_data == arg)
2514 : 0 : return entry->ulp_ctx;
2515 : : rte_spinlock_unlock(&bnxt_ulp_ctxt_lock);
2516 : : }
2517 : : return NULL;
2518 : : }
2519 : :
2520 : : void
2521 : 0 : bnxt_ulp_cntxt_entry_release(void)
2522 : : {
2523 : : rte_spinlock_unlock(&bnxt_ulp_ctxt_lock);
2524 : 0 : }
2525 : :
2526 : : /* Function to get the app tunnel details from the ulp context. */
2527 : : struct bnxt_flow_app_tun_ent *
2528 : 0 : bnxt_ulp_cntxt_ptr2_app_tun_list_get(struct bnxt_ulp_context *ulp)
2529 : : {
2530 [ # # # # ]: 0 : if (!ulp || !ulp->cfg_data)
2531 : : return NULL;
2532 : :
2533 : 0 : return ulp->cfg_data->app_tun;
2534 : : }
2535 : :
2536 : : /* Function to get the truflow app id. This defined in the build file */
2537 : : uint32_t
2538 : 0 : bnxt_ulp_default_app_id_get(void)
2539 : : {
2540 : 0 : return BNXT_TF_APP_ID;
2541 : : }
2542 : :
2543 : : /* Function to convert ulp dev id to regular dev id. */
2544 : : uint32_t
2545 [ # # ]: 0 : bnxt_ulp_cntxt_convert_dev_id(uint32_t ulp_dev_id)
2546 : : {
2547 : : enum tf_device_type type = 0;
2548 : :
2549 : : switch (ulp_dev_id) {
2550 : : case BNXT_ULP_DEVICE_ID_WH_PLUS:
2551 : : type = TF_DEVICE_TYPE_P4;
2552 : : break;
2553 : : case BNXT_ULP_DEVICE_ID_STINGRAY:
2554 : : type = TF_DEVICE_TYPE_SR;
2555 : : break;
2556 : : case BNXT_ULP_DEVICE_ID_THOR:
2557 : : type = TF_DEVICE_TYPE_P5;
2558 : : break;
2559 : 0 : default:
2560 : 0 : BNXT_TF_DBG(ERR, "Invalid device id\n");
2561 : 0 : break;
2562 : : }
2563 : 0 : return type;
2564 : : }
2565 : :
2566 : : /* This function sets the IF table index for the
2567 : : * Application to poll to get the hot upgrade state and count details from
2568 : : * the firmware.
2569 : : */
2570 : : int32_t
2571 : 0 : bnxt_ulp_ha_reg_set(struct bnxt_ulp_context *ulp_ctx,
2572 : : uint8_t state, uint8_t cnt)
2573 : : {
2574 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2575 : : return -EINVAL;
2576 : :
2577 [ # # ]: 0 : if (ULP_MULTI_SHARED_IS_SUPPORTED(ulp_ctx)) {
2578 : 0 : ulp_ctx->cfg_data->hu_reg_state = state;
2579 : 0 : ulp_ctx->cfg_data->hu_reg_cnt = cnt;
2580 : : } else {
2581 : 0 : ulp_ctx->cfg_data->hu_reg_state = ULP_HA_IF_TBL_IDX;
2582 : 0 : ulp_ctx->cfg_data->hu_reg_cnt = ULP_HA_CLIENT_CNT_IF_TBL_IDX;
2583 : : }
2584 : : return 0;
2585 : : }
2586 : :
2587 : : /* This function gets the IF table index for the
2588 : : * application to poll to get the application hot upgrade state from
2589 : : * the firmware.
2590 : : */
2591 : : uint32_t
2592 : 0 : bnxt_ulp_ha_reg_state_get(struct bnxt_ulp_context *ulp_ctx)
2593 : : {
2594 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2595 : : return 0;
2596 : :
2597 : 0 : return (uint32_t)ulp_ctx->cfg_data->hu_reg_state;
2598 : : }
2599 : :
2600 : : /* This function gets the IF table index for the
2601 : : * Application to poll to get the application count from
2602 : : * the firmware.
2603 : : */
2604 : : uint32_t
2605 : 0 : bnxt_ulp_ha_reg_cnt_get(struct bnxt_ulp_context *ulp_ctx)
2606 : : {
2607 [ # # # # ]: 0 : if (!ulp_ctx || !ulp_ctx->cfg_data)
2608 : : return 0;
2609 : :
2610 : 0 : return (uint32_t)ulp_ctx->cfg_data->hu_reg_cnt;
2611 : : }
2612 : :
2613 : : struct tf*
2614 : 0 : bnxt_ulp_bp_tfp_get(struct bnxt *bp, enum bnxt_ulp_session_type type)
2615 : : {
2616 : : enum bnxt_session_type btype;
2617 : :
2618 [ # # ]: 0 : if (type & BNXT_ULP_SESSION_TYPE_SHARED)
2619 : : btype = BNXT_SESSION_TYPE_SHARED_COMMON;
2620 [ # # ]: 0 : else if (type & BNXT_ULP_SESSION_TYPE_SHARED_WC)
2621 : : btype = BNXT_SESSION_TYPE_SHARED_WC;
2622 : : else
2623 : : btype = BNXT_SESSION_TYPE_REGULAR;
2624 : :
2625 : 0 : return bnxt_get_tfp_session(bp, btype);
2626 : : }
|