net/bnxt: add HA support in ULP
[dpdk.git] / drivers / net / bnxt / tf_ulp / bnxt_ulp.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5
6 #include <rte_log.h>
7 #include <rte_malloc.h>
8 #include <rte_flow.h>
9 #include <rte_flow_driver.h>
10 #include <rte_tailq.h>
11
12 #include "bnxt.h"
13 #include "bnxt_ulp.h"
14 #include "bnxt_tf_common.h"
15 #include "tf_core.h"
16 #include "tf_ext_flow_handle.h"
17
18 #include "ulp_template_db_enum.h"
19 #include "ulp_template_struct.h"
20 #include "ulp_mark_mgr.h"
21 #include "ulp_fc_mgr.h"
22 #include "ulp_flow_db.h"
23 #include "ulp_mapper.h"
24 #include "ulp_port_db.h"
25 #include "ulp_tun.h"
26 #include "ulp_ha_mgr.h"
27
28 /* Linked list of all TF sessions. */
29 STAILQ_HEAD(, bnxt_ulp_session_state) bnxt_ulp_session_list =
30                         STAILQ_HEAD_INITIALIZER(bnxt_ulp_session_list);
31
32 /* Mutex to synchronize bnxt_ulp_session_list operations. */
33 static pthread_mutex_t bnxt_ulp_global_mutex = PTHREAD_MUTEX_INITIALIZER;
34
35 /*
36  * Allow the deletion of context only for the bnxt device that
37  * created the session.
38  */
39 bool
40 ulp_ctx_deinit_allowed(struct bnxt_ulp_context *ulp_ctx)
41 {
42         if (!ulp_ctx || !ulp_ctx->cfg_data)
43                 return false;
44
45         if (!ulp_ctx->cfg_data->ref_cnt) {
46                 BNXT_TF_DBG(DEBUG, "ulp ctx shall initiate deinit\n");
47                 return true;
48         }
49
50         return false;
51 }
52
53 static int32_t
54 bnxt_ulp_devid_get(struct bnxt *bp,
55                    enum bnxt_ulp_device_id  *ulp_dev_id)
56 {
57         if (BNXT_CHIP_P5(bp)) {
58                 /* TBD: needs to accommodate even SR2 */
59                 *ulp_dev_id = BNXT_ULP_DEVICE_ID_THOR;
60                 return 0;
61         }
62
63         if (BNXT_STINGRAY(bp))
64                 *ulp_dev_id = BNXT_ULP_DEVICE_ID_STINGRAY;
65         else
66                 /* Assuming Whitney */
67                 *ulp_dev_id = BNXT_ULP_DEVICE_ID_WH_PLUS;
68
69         return 0;
70 }
71
72 struct bnxt_ulp_app_capabilities_info *
73 bnxt_ulp_app_cap_list_get(uint32_t *num_entries)
74 {
75         if (!num_entries)
76                 return NULL;
77         *num_entries = BNXT_ULP_APP_CAP_TBL_MAX_SZ;
78         return ulp_app_cap_info_list;
79 }
80
81 static struct bnxt_ulp_resource_resv_info *
82 bnxt_ulp_app_resource_resv_list_get(uint32_t *num_entries)
83 {
84         if (num_entries == NULL)
85                 return NULL;
86         *num_entries = BNXT_ULP_APP_RESOURCE_RESV_LIST_MAX_SZ;
87         return ulp_app_resource_resv_list;
88 }
89
90 struct bnxt_ulp_resource_resv_info *
91 bnxt_ulp_resource_resv_list_get(uint32_t *num_entries)
92 {
93         if (!num_entries)
94                 return NULL;
95         *num_entries = BNXT_ULP_RESOURCE_RESV_LIST_MAX_SZ;
96         return ulp_resource_resv_list;
97 }
98
99 struct bnxt_ulp_glb_resource_info *
100 bnxt_ulp_app_glb_resource_info_list_get(uint32_t *num_entries)
101 {
102         if (!num_entries)
103                 return NULL;
104         *num_entries = BNXT_ULP_APP_GLB_RESOURCE_TBL_MAX_SZ;
105         return ulp_app_glb_resource_tbl;
106 }
107
108 static int32_t
109 bnxt_ulp_named_resources_calc(struct bnxt_ulp_context *ulp_ctx,
110                               struct bnxt_ulp_glb_resource_info *info,
111                               uint32_t num,
112                               struct tf_session_resources *res)
113 {
114         uint32_t dev_id, res_type, i;
115         enum tf_dir dir;
116         uint8_t app_id;
117         int32_t rc = 0;
118
119         if (ulp_ctx == NULL || info == NULL || res == NULL || num == 0) {
120                 BNXT_TF_DBG(ERR, "Invalid parms to named resources calc.\n");
121                 return -EINVAL;
122         }
123
124         rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id);
125         if (rc) {
126                 BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n");
127                 return -EINVAL;
128         }
129
130         rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id);
131         if (rc) {
132                 BNXT_TF_DBG(ERR, "Unable to get the dev id from ulp.\n");
133                 return -EINVAL;
134         }
135
136         for (i = 0; i < num; i++) {
137                 if (dev_id != info[i].device_id || app_id != info[i].app_id)
138                         continue;
139                 dir = info[i].direction;
140                 res_type = info[i].resource_type;
141
142                 switch (info[i].resource_func) {
143                 case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
144                         res->ident_cnt[dir].cnt[res_type]++;
145                         break;
146                 case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
147                         res->tbl_cnt[dir].cnt[res_type]++;
148                         break;
149                 case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE:
150                         res->tcam_cnt[dir].cnt[res_type]++;
151                         break;
152                 case BNXT_ULP_RESOURCE_FUNC_EM_TABLE:
153                         res->em_cnt[dir].cnt[res_type]++;
154                         break;
155                 default:
156                         BNXT_TF_DBG(ERR, "Unknown resource func (0x%x)\n,",
157                                     info[i].resource_func);
158                         continue;
159                 }
160         }
161
162         return 0;
163 }
164
165 static int32_t
166 bnxt_ulp_unnamed_resources_calc(struct bnxt_ulp_context *ulp_ctx,
167                                 struct bnxt_ulp_resource_resv_info *info,
168                                 uint32_t num,
169                                 struct tf_session_resources *res)
170 {
171         uint32_t dev_id, res_type, i;
172         enum tf_dir dir;
173         uint8_t app_id;
174         int32_t rc = 0;
175
176         if (ulp_ctx == NULL || res == NULL || info == NULL || num == 0) {
177                 BNXT_TF_DBG(ERR, "Invalid arguments to get resources.\n");
178                 return -EINVAL;
179         }
180
181         rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id);
182         if (rc) {
183                 BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n");
184                 return -EINVAL;
185         }
186
187         rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id);
188         if (rc) {
189                 BNXT_TF_DBG(ERR, "Unable to get the dev id from ulp.\n");
190                 return -EINVAL;
191         }
192
193         for (i = 0; i < num; i++) {
194                 if (app_id != info[i].app_id || dev_id != info[i].device_id)
195                         continue;
196                 dir = info[i].direction;
197                 res_type = info[i].resource_type;
198
199                 switch (info[i].resource_func) {
200                 case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER:
201                         res->ident_cnt[dir].cnt[res_type] = info[i].count;
202                         break;
203                 case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE:
204                         res->tbl_cnt[dir].cnt[res_type] = info[i].count;
205                         break;
206                 case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE:
207                         res->tcam_cnt[dir].cnt[res_type] = info[i].count;
208                         break;
209                 case BNXT_ULP_RESOURCE_FUNC_EM_TABLE:
210                         res->em_cnt[dir].cnt[res_type] = info[i].count;
211                         break;
212                 default:
213                         break;
214                 }
215         }
216         return 0;
217 }
218
219 static int32_t
220 bnxt_ulp_tf_resources_get(struct bnxt_ulp_context *ulp_ctx,
221                           struct tf_session_resources *res)
222 {
223         struct bnxt_ulp_resource_resv_info *unnamed = NULL;
224         uint32_t unum;
225         int32_t rc = 0;
226
227         if (ulp_ctx == NULL || res == NULL) {
228                 BNXT_TF_DBG(ERR, "Invalid arguments to get resources.\n");
229                 return -EINVAL;
230         }
231
232         unnamed = bnxt_ulp_resource_resv_list_get(&unum);
233         if (unnamed == NULL) {
234                 BNXT_TF_DBG(ERR, "Unable to get resource resv list.\n");
235                 return -EINVAL;
236         }
237
238         rc = bnxt_ulp_unnamed_resources_calc(ulp_ctx, unnamed, unum, res);
239         if (rc)
240                 BNXT_TF_DBG(ERR, "Unable to calc resources for session.\n");
241
242         return rc;
243 }
244
245 static int32_t
246 bnxt_ulp_tf_shared_session_resources_get(struct bnxt_ulp_context *ulp_ctx,
247                                          struct tf_session_resources *res)
248 {
249         struct bnxt_ulp_resource_resv_info *unnamed;
250         struct bnxt_ulp_glb_resource_info *named;
251         uint32_t unum, nnum;
252         int32_t rc;
253
254         if (ulp_ctx == NULL || res == NULL) {
255                 BNXT_TF_DBG(ERR, "Invalid arguments to get resources.\n");
256                 return -EINVAL;
257         }
258
259         /* Make sure the resources are zero before accumulating. */
260         memset(res, 0, sizeof(struct tf_session_resources));
261
262         /*
263          * Shared resources are comprised of both named and unnamed resources.
264          * First get the unnamed counts, and then add the named to the result.
265          */
266         /* Get the baseline counts */
267         unnamed = bnxt_ulp_app_resource_resv_list_get(&unum);
268         if (unnamed == NULL) {
269                 BNXT_TF_DBG(ERR, "Unable to get shared resource resv list.\n");
270                 return -EINVAL;
271         }
272         rc = bnxt_ulp_unnamed_resources_calc(ulp_ctx, unnamed, unum, res);
273         if (rc) {
274                 BNXT_TF_DBG(ERR, "Unable to calc resources for shared session.\n");
275                 return -EINVAL;
276         }
277
278         /* Get the named list and add the totals */
279         named = bnxt_ulp_app_glb_resource_info_list_get(&nnum);
280         if (named == NULL) {
281                 BNXT_TF_DBG(ERR, "Unable to get app global resource list\n");
282                 return -EINVAL;
283         }
284         rc = bnxt_ulp_named_resources_calc(ulp_ctx, named, nnum, res);
285         if (rc)
286                 BNXT_TF_DBG(ERR, "Unable to calc named resources\n");
287
288         return rc;
289 }
290
291 int32_t
292 bnxt_ulp_cntxt_app_caps_init(struct bnxt_ulp_context *ulp_ctx,
293                              uint8_t app_id, uint32_t dev_id)
294 {
295         struct bnxt_ulp_app_capabilities_info *info;
296         uint32_t num = 0;
297         uint16_t i;
298         bool found = false;
299
300         if (ULP_APP_DEV_UNSUPPORTED_ENABLED(ulp_ctx->cfg_data->ulp_flags)) {
301                 BNXT_TF_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
302                             app_id, dev_id);
303                 return -EINVAL;
304         }
305
306         info = bnxt_ulp_app_cap_list_get(&num);
307         if (!info || !num) {
308                 BNXT_TF_DBG(ERR, "Failed to get app capabilities.\n");
309                 return -EINVAL;
310         }
311
312         for (i = 0; i < num; i++) {
313                 if (info[i].app_id != app_id || info[i].device_id != dev_id)
314                         continue;
315                 found = true;
316                 if (info[i].flags & BNXT_ULP_APP_CAP_SHARED_EN)
317                         ulp_ctx->cfg_data->ulp_flags |=
318                                 BNXT_ULP_SHARED_SESSION_ENABLED;
319                 if (info[i].flags & BNXT_ULP_APP_CAP_HOT_UPGRADE_EN)
320                         ulp_ctx->cfg_data->ulp_flags |=
321                                 BNXT_ULP_HIGH_AVAIL_ENABLED;
322         }
323         if (!found) {
324                 BNXT_TF_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
325                             app_id, dev_id);
326                 ulp_ctx->cfg_data->ulp_flags |= BNXT_ULP_APP_DEV_UNSUPPORTED;
327                 return -EINVAL;
328         }
329
330         return 0;
331 }
332
333 static void
334 ulp_ctx_shared_session_close(struct bnxt *bp,
335                              struct bnxt_ulp_session_state *session)
336 {
337         struct tf *tfp;
338         int32_t rc;
339
340         if (!bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx))
341                 return;
342
343         tfp = bnxt_ulp_cntxt_shared_tfp_get(bp->ulp_ctx);
344         if (!tfp) {
345                 /*
346                  * Log it under debug since this is likely a case of the
347                  * shared session not being created.  For example, a failed
348                  * initialization.
349                  */
350                 BNXT_TF_DBG(DEBUG, "Failed to get shared tfp on close.\n");
351                 return;
352         }
353         rc = tf_close_session(tfp);
354         if (rc)
355                 BNXT_TF_DBG(ERR, "Failed to close the shared session rc=%d.\n",
356                             rc);
357         (void)bnxt_ulp_cntxt_shared_tfp_set(bp->ulp_ctx, NULL);
358
359         session->g_shared_tfp.session = NULL;
360 }
361
362 static int32_t
363 ulp_ctx_shared_session_open(struct bnxt *bp,
364                             struct bnxt_ulp_session_state *session)
365 {
366         struct rte_eth_dev *ethdev = bp->eth_dev;
367         struct tf_session_resources *resources;
368         struct tf_open_session_parms parms;
369         size_t copy_num_bytes;
370         uint32_t ulp_dev_id;
371         int32_t rc = 0;
372
373         /* only perform this if shared session is enabled. */
374         if (!bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx))
375                 return 0;
376
377         memset(&parms, 0, sizeof(parms));
378
379         rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
380                                           parms.ctrl_chan_name);
381         if (rc) {
382                 BNXT_TF_DBG(ERR, "Invalid port %d, rc = %d\n",
383                             ethdev->data->port_id, rc);
384                 return rc;
385         }
386         resources = &parms.resources;
387
388         /*
389          * Need to account for size of ctrl_chan_name and 1 extra for Null
390          * terminator
391          */
392         copy_num_bytes = sizeof(parms.ctrl_chan_name) -
393                 strlen(parms.ctrl_chan_name) - 1;
394
395         /* Build the ctrl_chan_name with shared token */
396         strncat(parms.ctrl_chan_name, "-tf_shared", copy_num_bytes);
397
398         rc = bnxt_ulp_tf_shared_session_resources_get(bp->ulp_ctx, resources);
399         if (rc)
400                 return rc;
401
402         rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
403         if (rc) {
404                 BNXT_TF_DBG(ERR, "Unable to get device id from ulp.\n");
405                 return rc;
406         }
407
408         switch (ulp_dev_id) {
409         case BNXT_ULP_DEVICE_ID_WH_PLUS:
410                 parms.device_type = TF_DEVICE_TYPE_WH;
411                 break;
412         case BNXT_ULP_DEVICE_ID_STINGRAY:
413                 parms.device_type = TF_DEVICE_TYPE_SR;
414                 break;
415         case BNXT_ULP_DEVICE_ID_THOR:
416                 parms.device_type = TF_DEVICE_TYPE_THOR;
417                 break;
418         default:
419                 BNXT_TF_DBG(ERR, "Unable to determine dev for opening session.\n");
420                 return rc;
421         }
422
423         parms.shadow_copy = true;
424         parms.bp = bp;
425
426         /*
427          * Open the session here, but the collect the resources during the
428          * mapper initialization.
429          */
430         rc = tf_open_session(&bp->tfp_shared, &parms);
431         if (rc)
432                 return rc;
433
434         if (parms.shared_session_creator)
435                 BNXT_TF_DBG(DEBUG, "Shared session creator.\n");
436         else
437                 BNXT_TF_DBG(DEBUG, "Shared session attached.\n");
438
439         /* Save the shared session in global data */
440         if (!session->g_shared_tfp.session)
441                 session->g_shared_tfp.session = bp->tfp_shared.session;
442
443         rc = bnxt_ulp_cntxt_shared_tfp_set(bp->ulp_ctx, &bp->tfp_shared);
444         if (rc)
445                 BNXT_TF_DBG(ERR, "Failed to add shared tfp to ulp (%d)\n", rc);
446
447         return rc;
448 }
449
450 static int32_t
451 ulp_ctx_shared_session_attach(struct bnxt *bp,
452                               struct bnxt_ulp_session_state *session)
453 {
454         int32_t rc = 0;
455
456         /* Simply return success if shared session not enabled */
457         if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) {
458                 bp->tfp_shared.session = session->g_shared_tfp.session;
459                 rc = ulp_ctx_shared_session_open(bp, session);
460         }
461
462         return rc;
463 }
464
465 static void
466 ulp_ctx_shared_session_detach(struct bnxt *bp)
467 {
468         if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) {
469                 if (bp->tfp_shared.session) {
470                         tf_close_session(&bp->tfp_shared);
471                         bp->tfp_shared.session = NULL;
472                 }
473         }
474 }
475
476 /*
477  * Initialize an ULP session.
478  * An ULP session will contain all the resources needed to support rte flow
479  * offloads. A session is initialized as part of rte_eth_device start.
480  * A single vswitch instance can have multiple uplinks which means
481  * rte_eth_device start will be called for each of these devices.
482  * ULP session manager will make sure that a single ULP session is only
483  * initialized once. Apart from this, it also initializes MARK database,
484  * EEM table & flow database. ULP session manager also manages a list of
485  * all opened ULP sessions.
486  */
487 static int32_t
488 ulp_ctx_session_open(struct bnxt *bp,
489                      struct bnxt_ulp_session_state *session)
490 {
491         struct rte_eth_dev              *ethdev = bp->eth_dev;
492         int32_t                         rc = 0;
493         struct tf_open_session_parms    params;
494         struct tf_session_resources     *resources;
495         uint32_t                        ulp_dev_id;
496
497         memset(&params, 0, sizeof(params));
498
499         rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
500                                           params.ctrl_chan_name);
501         if (rc) {
502                 BNXT_TF_DBG(ERR, "Invalid port %d, rc = %d\n",
503                             ethdev->data->port_id, rc);
504                 return rc;
505         }
506
507         params.shadow_copy = true;
508
509         rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
510         if (rc) {
511                 BNXT_TF_DBG(ERR, "Unable to get device id from ulp.\n");
512                 return rc;
513         }
514
515         switch (ulp_dev_id) {
516         case BNXT_ULP_DEVICE_ID_WH_PLUS:
517                 params.device_type = TF_DEVICE_TYPE_WH;
518                 break;
519         case BNXT_ULP_DEVICE_ID_STINGRAY:
520                 params.device_type = TF_DEVICE_TYPE_SR;
521                 break;
522         case BNXT_ULP_DEVICE_ID_THOR:
523                 params.device_type = TF_DEVICE_TYPE_THOR;
524                 break;
525         default:
526                 BNXT_TF_DBG(ERR, "Unable to determine device for opening session.\n");
527                 return rc;
528         }
529
530         resources = &params.resources;
531         rc = bnxt_ulp_tf_resources_get(bp->ulp_ctx, resources);
532         if (rc)
533                 return rc;
534
535         params.bp = bp;
536         rc = tf_open_session(&bp->tfp, &params);
537         if (rc) {
538                 BNXT_TF_DBG(ERR, "Failed to open TF session - %s, rc = %d\n",
539                             params.ctrl_chan_name, rc);
540                 return -EINVAL;
541         }
542         if (!session->session_opened) {
543                 session->session_opened = 1;
544                 session->g_tfp = rte_zmalloc("bnxt_ulp_session_tfp",
545                                              sizeof(struct tf), 0);
546                 session->g_tfp->session = bp->tfp.session;
547         }
548         return rc;
549 }
550
551 /*
552  * Close the ULP session.
553  * It takes the ulp context pointer.
554  */
555 static void
556 ulp_ctx_session_close(struct bnxt *bp,
557                       struct bnxt_ulp_session_state *session)
558 {
559         /* close the session in the hardware */
560         if (session->session_opened)
561                 tf_close_session(&bp->tfp);
562         session->session_opened = 0;
563         rte_free(session->g_tfp);
564         session->g_tfp = NULL;
565 }
566
567 static void
568 bnxt_init_tbl_scope_parms(struct bnxt *bp,
569                           struct tf_alloc_tbl_scope_parms *params)
570 {
571         struct bnxt_ulp_device_params   *dparms;
572         uint32_t dev_id;
573         int rc;
574
575         rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id);
576         if (rc)
577                 /* TBD: For now, just use default. */
578                 dparms = 0;
579         else
580                 dparms = bnxt_ulp_device_params_get(dev_id);
581
582         /*
583          * Set the flush timer for EEM entries. The value is in 100ms intervals,
584          * so 100 is 10s.
585          */
586         params->hw_flow_cache_flush_timer = 100;
587
588         if (!dparms) {
589                 params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
590                 params->rx_max_action_entry_sz_in_bits =
591                         BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
592                 params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
593                 params->rx_num_flows_in_k = BNXT_ULP_RX_NUM_FLOWS;
594
595                 params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
596                 params->tx_max_action_entry_sz_in_bits =
597                         BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
598                 params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
599                 params->tx_num_flows_in_k = BNXT_ULP_TX_NUM_FLOWS;
600         } else {
601                 params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
602                 params->rx_max_action_entry_sz_in_bits =
603                         BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
604                 params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
605                 params->rx_num_flows_in_k =
606                         dparms->ext_flow_db_num_entries / 1024;
607
608                 params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
609                 params->tx_max_action_entry_sz_in_bits =
610                         BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
611                 params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
612                 params->tx_num_flows_in_k =
613                         dparms->ext_flow_db_num_entries / 1024;
614         }
615         BNXT_TF_DBG(INFO, "Table Scope initialized with %uK flows.\n",
616                     params->rx_num_flows_in_k);
617 }
618
619 /* Initialize Extended Exact Match host memory. */
620 static int32_t
621 ulp_eem_tbl_scope_init(struct bnxt *bp)
622 {
623         struct tf_alloc_tbl_scope_parms params = {0};
624         struct bnxt_ulp_device_params *dparms;
625         enum bnxt_ulp_flow_mem_type mtype;
626         uint32_t dev_id;
627         int rc;
628
629         /* Get the dev specific number of flows that needed to be supported. */
630         if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
631                 BNXT_TF_DBG(ERR, "Invalid device id\n");
632                 return -EINVAL;
633         }
634
635         dparms = bnxt_ulp_device_params_get(dev_id);
636         if (!dparms) {
637                 BNXT_TF_DBG(ERR, "could not fetch the device params\n");
638                 return -ENODEV;
639         }
640
641         if (bnxt_ulp_cntxt_mem_type_get(bp->ulp_ctx, &mtype))
642                 return -EINVAL;
643         if (mtype != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
644                 BNXT_TF_DBG(INFO, "Table Scope alloc is not required\n");
645                 return 0;
646         }
647
648         bnxt_init_tbl_scope_parms(bp, &params);
649         rc = tf_alloc_tbl_scope(&bp->tfp, &params);
650         if (rc) {
651                 BNXT_TF_DBG(ERR, "Unable to allocate eem table scope rc = %d\n",
652                             rc);
653                 return rc;
654         }
655         rc = bnxt_ulp_cntxt_tbl_scope_id_set(bp->ulp_ctx, params.tbl_scope_id);
656         if (rc) {
657                 BNXT_TF_DBG(ERR, "Unable to set table scope id\n");
658                 return rc;
659         }
660
661         return 0;
662 }
663
664 /* Free Extended Exact Match host memory */
665 static int32_t
666 ulp_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)
667 {
668         struct tf_free_tbl_scope_parms  params = {0};
669         struct tf                       *tfp;
670         int32_t                         rc = 0;
671         struct bnxt_ulp_device_params *dparms;
672         enum bnxt_ulp_flow_mem_type mtype;
673         uint32_t dev_id;
674
675         if (!ulp_ctx || !ulp_ctx->cfg_data)
676                 return -EINVAL;
677
678         tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SHARED_SESSION_NO);
679         if (!tfp) {
680                 BNXT_TF_DBG(ERR, "Failed to get the truflow pointer\n");
681                 return -EINVAL;
682         }
683
684         /* Get the dev specific number of flows that needed to be supported. */
685         if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
686                 BNXT_TF_DBG(ERR, "Invalid device id\n");
687                 return -EINVAL;
688         }
689
690         dparms = bnxt_ulp_device_params_get(dev_id);
691         if (!dparms) {
692                 BNXT_TF_DBG(ERR, "could not fetch the device params\n");
693                 return -ENODEV;
694         }
695
696         if (bnxt_ulp_cntxt_mem_type_get(ulp_ctx, &mtype))
697                 return -EINVAL;
698         if (mtype != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
699                 BNXT_TF_DBG(INFO, "Table Scope free is not required\n");
700                 return 0;
701         }
702
703         rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp_ctx, &params.tbl_scope_id);
704         if (rc) {
705                 BNXT_TF_DBG(ERR, "Failed to get the table scope id\n");
706                 return -EINVAL;
707         }
708
709         rc = tf_free_tbl_scope(tfp, &params);
710         if (rc) {
711                 BNXT_TF_DBG(ERR, "Unable to free table scope\n");
712                 return -EINVAL;
713         }
714         return rc;
715 }
716
717 /* The function to free and deinit the ulp context data. */
718 static int32_t
719 ulp_ctx_deinit(struct bnxt *bp,
720                struct bnxt_ulp_session_state *session)
721 {
722         /* close the tf session */
723         ulp_ctx_session_close(bp, session);
724
725         /* The shared session must be closed last. */
726         ulp_ctx_shared_session_close(bp, session);
727
728         /* Free the contents */
729         if (session->cfg_data) {
730                 rte_free(session->cfg_data);
731                 bp->ulp_ctx->cfg_data = NULL;
732                 session->cfg_data = NULL;
733         }
734         return 0;
735 }
736
737 /* The function to allocate and initialize the ulp context data. */
738 static int32_t
739 ulp_ctx_init(struct bnxt *bp,
740              struct bnxt_ulp_session_state *session)
741 {
742         struct bnxt_ulp_data    *ulp_data;
743         int32_t                 rc = 0;
744         enum bnxt_ulp_device_id devid;
745
746         /* Allocate memory to hold ulp context data. */
747         ulp_data = rte_zmalloc("bnxt_ulp_data",
748                                sizeof(struct bnxt_ulp_data), 0);
749         if (!ulp_data) {
750                 BNXT_TF_DBG(ERR, "Failed to allocate memory for ulp data\n");
751                 return -ENOMEM;
752         }
753
754         /* Increment the ulp context data reference count usage. */
755         bp->ulp_ctx->cfg_data = ulp_data;
756         session->cfg_data = ulp_data;
757         ulp_data->ref_cnt++;
758         ulp_data->ulp_flags |= BNXT_ULP_VF_REP_ENABLED;
759
760         rc = bnxt_ulp_devid_get(bp, &devid);
761         if (rc) {
762                 BNXT_TF_DBG(ERR, "Unable to determine device for ULP init.\n");
763                 goto error_deinit;
764         }
765
766         rc = bnxt_ulp_cntxt_dev_id_set(bp->ulp_ctx, devid);
767         if (rc) {
768                 BNXT_TF_DBG(ERR, "Unable to set device for ULP init.\n");
769                 goto error_deinit;
770         }
771
772         rc = bnxt_ulp_cntxt_app_id_set(bp->ulp_ctx, bp->app_id);
773         if (rc) {
774                 BNXT_TF_DBG(ERR, "Unable to set app_id for ULP init.\n");
775                 goto error_deinit;
776         }
777
778         rc = bnxt_ulp_cntxt_app_caps_init(bp->ulp_ctx, bp->app_id, devid);
779         if (rc) {
780                 BNXT_TF_DBG(ERR, "Unable to set caps for app(%x)/dev(%x)\n",
781                             bp->app_id, devid);
782                 goto error_deinit;
783         }
784
785         /*
786          * Shared session must be created before first regular session but after
787          * the ulp_ctx is valid.
788          */
789         rc = ulp_ctx_shared_session_open(bp, session);
790         if (rc) {
791                 BNXT_TF_DBG(ERR, "Unable to open shared session (%d)\n", rc);
792                 goto error_deinit;
793         }
794
795         /* Open the ulp session. */
796         rc = ulp_ctx_session_open(bp, session);
797         if (rc)
798                 goto error_deinit;
799
800         ulp_tun_tbl_init(ulp_data->tun_tbl);
801
802         bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, &bp->tfp);
803         return rc;
804
805 error_deinit:
806         session->session_opened = 1;
807         (void)ulp_ctx_deinit(bp, session);
808         return rc;
809 }
810
811 /* The function to initialize ulp dparms with devargs */
812 static int32_t
813 ulp_dparms_init(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)
814 {
815         struct bnxt_ulp_device_params *dparms;
816         uint32_t dev_id;
817
818         if (!bp->max_num_kflows) {
819                 /* Defaults to Internal */
820                 bnxt_ulp_cntxt_mem_type_set(ulp_ctx,
821                                             BNXT_ULP_FLOW_MEM_TYPE_INT);
822                 return 0;
823         }
824
825         /* The max_num_kflows were set, so move to external */
826         if (bnxt_ulp_cntxt_mem_type_set(ulp_ctx, BNXT_ULP_FLOW_MEM_TYPE_EXT))
827                 return -EINVAL;
828
829         if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) {
830                 BNXT_TF_DBG(DEBUG, "Failed to get device id\n");
831                 return -EINVAL;
832         }
833
834         dparms = bnxt_ulp_device_params_get(dev_id);
835         if (!dparms) {
836                 BNXT_TF_DBG(DEBUG, "Failed to get device parms\n");
837                 return -EINVAL;
838         }
839
840         /* num_flows = max_num_kflows * 1024 */
841         dparms->ext_flow_db_num_entries = bp->max_num_kflows * 1024;
842         /* GFID =  2 * num_flows */
843         dparms->mark_db_gfid_entries = dparms->ext_flow_db_num_entries * 2;
844         BNXT_TF_DBG(DEBUG, "Set the number of flows = %"PRIu64"\n",
845                     dparms->ext_flow_db_num_entries);
846
847         return 0;
848 }
849
850 /* The function to initialize bp flags with truflow features */
851 static int32_t
852 ulp_dparms_dev_port_intf_update(struct bnxt *bp,
853                                 struct bnxt_ulp_context *ulp_ctx)
854 {
855         enum bnxt_ulp_flow_mem_type mtype;
856
857         if (bnxt_ulp_cntxt_mem_type_get(ulp_ctx, &mtype))
858                 return -EINVAL;
859         /* Update the bp flag with gfid flag */
860         if (mtype == BNXT_ULP_FLOW_MEM_TYPE_EXT)
861                 bp->flags |= BNXT_FLAG_GFID_ENABLE;
862
863         return 0;
864 }
865
866 static int32_t
867 ulp_ctx_attach(struct bnxt *bp,
868                struct bnxt_ulp_session_state *session)
869 {
870         int32_t rc = 0;
871         uint32_t flags, dev_id;
872         uint8_t app_id;
873
874         /* Increment the ulp context data reference count usage. */
875         bp->ulp_ctx->cfg_data = session->cfg_data;
876         bp->ulp_ctx->cfg_data->ref_cnt++;
877
878         /* update the session details in bnxt tfp */
879         bp->tfp.session = session->g_tfp->session;
880
881         /*
882          * The supported flag will be set during the init. Use it now to
883          * know if we should go through the attach.
884          */
885         rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id);
886         if (rc) {
887                 BNXT_TF_DBG(ERR, "Unable to get the app id from ulp.\n");
888                 return -EINVAL;
889         }
890
891         rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id);
892         if (rc) {
893                 BNXT_TF_DBG(ERR, "Unable do get the dev_id.\n");
894                 return -EINVAL;
895         }
896
897         flags = bp->ulp_ctx->cfg_data->ulp_flags;
898         if (ULP_APP_DEV_UNSUPPORTED_ENABLED(flags)) {
899                 BNXT_TF_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n",
900                             app_id, dev_id);
901                 return -EINVAL;
902         }
903
904         /* Create a TF Client */
905         rc = ulp_ctx_session_open(bp, session);
906         if (rc) {
907                 PMD_DRV_LOG(ERR, "Failed to open ctxt session, rc:%d\n", rc);
908                 bp->tfp.session = NULL;
909                 return rc;
910         }
911
912         bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, &bp->tfp);
913         return rc;
914 }
915
916 static void
917 ulp_ctx_detach(struct bnxt *bp)
918 {
919         if (bp->tfp.session) {
920                 tf_close_session(&bp->tfp);
921                 bp->tfp.session = NULL;
922         }
923 }
924
925 /*
926  * Initialize the state of an ULP session.
927  * If the state of an ULP session is not initialized, set it's state to
928  * initialized. If the state is already initialized, do nothing.
929  */
930 static void
931 ulp_context_initialized(struct bnxt_ulp_session_state *session, bool *init)
932 {
933         pthread_mutex_lock(&session->bnxt_ulp_mutex);
934
935         if (!session->bnxt_ulp_init) {
936                 session->bnxt_ulp_init = true;
937                 *init = false;
938         } else {
939                 *init = true;
940         }
941
942         pthread_mutex_unlock(&session->bnxt_ulp_mutex);
943 }
944
945 /*
946  * Check if an ULP session is already allocated for a specific PCI
947  * domain & bus. If it is already allocated simply return the session
948  * pointer, otherwise allocate a new session.
949  */
950 static struct bnxt_ulp_session_state *
951 ulp_get_session(struct rte_pci_addr *pci_addr)
952 {
953         struct bnxt_ulp_session_state *session;
954
955         STAILQ_FOREACH(session, &bnxt_ulp_session_list, next) {
956                 if (session->pci_info.domain == pci_addr->domain &&
957                     session->pci_info.bus == pci_addr->bus) {
958                         return session;
959                 }
960         }
961         return NULL;
962 }
963
964 /*
965  * Allocate and Initialize an ULP session and set it's state to INITIALIZED.
966  * If it's already initialized simply return the already existing session.
967  */
968 static struct bnxt_ulp_session_state *
969 ulp_session_init(struct bnxt *bp,
970                  bool *init)
971 {
972         struct rte_pci_device           *pci_dev;
973         struct rte_pci_addr             *pci_addr;
974         struct bnxt_ulp_session_state   *session;
975         int rc = 0;
976
977         if (!bp)
978                 return NULL;
979
980         pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
981         pci_addr = &pci_dev->addr;
982
983         pthread_mutex_lock(&bnxt_ulp_global_mutex);
984
985         session = ulp_get_session(pci_addr);
986         if (!session) {
987                 /* Not Found the session  Allocate a new one */
988                 session = rte_zmalloc("bnxt_ulp_session",
989                                       sizeof(struct bnxt_ulp_session_state),
990                                       0);
991                 if (!session) {
992                         BNXT_TF_DBG(ERR,
993                                     "Allocation failed for bnxt_ulp_session\n");
994                         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
995                         return NULL;
996
997                 } else {
998                         /* Add it to the queue */
999                         session->pci_info.domain = pci_addr->domain;
1000                         session->pci_info.bus = pci_addr->bus;
1001                         rc = pthread_mutex_init(&session->bnxt_ulp_mutex, NULL);
1002                         if (rc) {
1003                                 BNXT_TF_DBG(ERR, "mutex create failed\n");
1004                                 pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1005                                 return NULL;
1006                         }
1007                         STAILQ_INSERT_TAIL(&bnxt_ulp_session_list,
1008                                            session, next);
1009                 }
1010         }
1011         ulp_context_initialized(session, init);
1012         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1013         return session;
1014 }
1015
1016 /*
1017  * When a device is closed, remove it's associated session from the global
1018  * session list.
1019  */
1020 static void
1021 ulp_session_deinit(struct bnxt_ulp_session_state *session)
1022 {
1023         if (!session)
1024                 return;
1025
1026         if (!session->cfg_data) {
1027                 pthread_mutex_lock(&bnxt_ulp_global_mutex);
1028                 STAILQ_REMOVE(&bnxt_ulp_session_list, session,
1029                               bnxt_ulp_session_state, next);
1030                 pthread_mutex_destroy(&session->bnxt_ulp_mutex);
1031                 rte_free(session);
1032                 pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1033         }
1034 }
1035
1036 /*
1037  * Internal api to enable NAT feature.
1038  * Set set_flag to 1 to set the value or zero to reset the value.
1039  * returns 0 on success.
1040  */
1041 static int32_t
1042 bnxt_ulp_global_cfg_update(struct bnxt *bp,
1043                            enum tf_dir dir,
1044                            enum tf_global_config_type type,
1045                            uint32_t offset,
1046                            uint32_t value,
1047                            uint32_t set_flag)
1048 {
1049         uint32_t global_cfg = 0;
1050         int rc;
1051         struct tf_global_cfg_parms parms = { 0 };
1052
1053         /* Initialize the params */
1054         parms.dir = dir,
1055         parms.type = type,
1056         parms.offset = offset,
1057         parms.config = (uint8_t *)&global_cfg,
1058         parms.config_sz_in_bytes = sizeof(global_cfg);
1059
1060         rc = tf_get_global_cfg(&bp->tfp, &parms);
1061         if (rc) {
1062                 BNXT_TF_DBG(ERR, "Failed to get global cfg 0x%x rc:%d\n",
1063                             type, rc);
1064                 return rc;
1065         }
1066
1067         if (set_flag)
1068                 global_cfg |= value;
1069         else
1070                 global_cfg &= ~value;
1071
1072         /* SET the register RE_CFA_REG_ACT_TECT */
1073         rc = tf_set_global_cfg(&bp->tfp, &parms);
1074         if (rc) {
1075                 BNXT_TF_DBG(ERR, "Failed to set global cfg 0x%x rc:%d\n",
1076                             type, rc);
1077                 return rc;
1078         }
1079         return rc;
1080 }
1081
1082 /* Internal function to delete all the flows belonging to the given port */
1083 static void
1084 bnxt_ulp_flush_port_flows(struct bnxt *bp)
1085 {
1086         uint16_t func_id;
1087
1088         /* it is assumed that port is either TVF or PF */
1089         if (ulp_port_db_port_func_id_get(bp->ulp_ctx,
1090                                          bp->eth_dev->data->port_id,
1091                                          &func_id)) {
1092                 BNXT_TF_DBG(ERR, "Invalid argument\n");
1093                 return;
1094         }
1095         (void)ulp_flow_db_function_flow_flush(bp->ulp_ctx, func_id);
1096 }
1097
1098 /* Internal function to delete the VFR default flows */
1099 static void
1100 bnxt_ulp_destroy_vfr_default_rules(struct bnxt *bp, bool global)
1101 {
1102         struct bnxt_ulp_vfr_rule_info *info;
1103         uint16_t port_id;
1104         struct rte_eth_dev *vfr_eth_dev;
1105         struct bnxt_representor *vfr_bp;
1106
1107         if (!BNXT_TRUFLOW_EN(bp) || BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev))
1108                 return;
1109
1110         if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
1111                 return;
1112
1113         /* Delete default rules for all ports */
1114         for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
1115                 info = &bp->ulp_ctx->cfg_data->vfr_rule_info[port_id];
1116                 if (!info->valid)
1117                         continue;
1118
1119                 if (!global && info->parent_port_id !=
1120                     bp->eth_dev->data->port_id)
1121                         continue;
1122
1123                 /* Destroy the flows */
1124                 ulp_default_flow_destroy(bp->eth_dev, info->vfr_flow_id);
1125                 /* Clean up the tx action pointer */
1126                 vfr_eth_dev = &rte_eth_devices[port_id];
1127                 if (vfr_eth_dev) {
1128                         vfr_bp = vfr_eth_dev->data->dev_private;
1129                         vfr_bp->vfr_tx_cfa_action = 0;
1130                 }
1131                 memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));
1132         }
1133 }
1134
1135 /*
1136  * When a port is deinit'ed by dpdk. This function is called
1137  * and this function clears the ULP context and rest of the
1138  * infrastructure associated with it.
1139  */
1140 static void
1141 bnxt_ulp_deinit(struct bnxt *bp,
1142                 struct bnxt_ulp_session_state *session)
1143 {
1144         bool ha_enabled;
1145
1146         if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
1147                 return;
1148
1149         ha_enabled = bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx);
1150         if (ha_enabled && session->session_opened) {
1151                 int32_t rc = ulp_ha_mgr_close(bp->ulp_ctx);
1152                 if (rc)
1153                         BNXT_TF_DBG(ERR, "Failed to close HA (%d)\n", rc);
1154         }
1155
1156         /* clean up default flows */
1157         bnxt_ulp_destroy_df_rules(bp, true);
1158
1159         /* clean up default VFR flows */
1160         bnxt_ulp_destroy_vfr_default_rules(bp, true);
1161
1162         /* clean up regular flows */
1163         ulp_flow_db_flush_flows(bp->ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR);
1164
1165         /* cleanup the eem table scope */
1166         ulp_eem_tbl_scope_deinit(bp, bp->ulp_ctx);
1167
1168         /* cleanup the flow database */
1169         ulp_flow_db_deinit(bp->ulp_ctx);
1170
1171         /* Delete the Mark database */
1172         ulp_mark_db_deinit(bp->ulp_ctx);
1173
1174         /* cleanup the ulp mapper */
1175         ulp_mapper_deinit(bp->ulp_ctx);
1176
1177         /* Delete the Flow Counter Manager */
1178         ulp_fc_mgr_deinit(bp->ulp_ctx);
1179
1180         /* Delete the Port database */
1181         ulp_port_db_deinit(bp->ulp_ctx);
1182
1183         /* Disable NAT feature */
1184         (void)bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
1185                                          TF_TUNNEL_ENCAP_NAT,
1186                                          BNXT_ULP_NAT_OUTER_MOST_FLAGS, 0);
1187
1188         (void)bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
1189                                          TF_TUNNEL_ENCAP_NAT,
1190                                          BNXT_ULP_NAT_OUTER_MOST_FLAGS, 0);
1191
1192         /* free the flow db lock */
1193         pthread_mutex_destroy(&bp->ulp_ctx->cfg_data->flow_db_lock);
1194
1195         if (ha_enabled)
1196                 ulp_ha_mgr_deinit(bp->ulp_ctx);
1197
1198         /* Delete the ulp context and tf session and free the ulp context */
1199         ulp_ctx_deinit(bp, session);
1200         BNXT_TF_DBG(DEBUG, "ulp ctx has been deinitialized\n");
1201 }
1202
1203 /*
1204  * When a port is initialized by dpdk. This functions is called
1205  * and this function initializes the ULP context and rest of the
1206  * infrastructure associated with it.
1207  */
1208 static int32_t
1209 bnxt_ulp_init(struct bnxt *bp,
1210               struct bnxt_ulp_session_state *session)
1211 {
1212         int rc;
1213
1214         /* Allocate and Initialize the ulp context. */
1215         rc = ulp_ctx_init(bp, session);
1216         if (rc) {
1217                 BNXT_TF_DBG(ERR, "Failed to create the ulp context\n");
1218                 goto jump_to_error;
1219         }
1220
1221         rc = pthread_mutex_init(&bp->ulp_ctx->cfg_data->flow_db_lock, NULL);
1222         if (rc) {
1223                 BNXT_TF_DBG(ERR, "Unable to initialize flow db lock\n");
1224                 goto jump_to_error;
1225         }
1226
1227         /* Initialize ulp dparms with values devargs passed */
1228         rc = ulp_dparms_init(bp, bp->ulp_ctx);
1229         if (rc) {
1230                 BNXT_TF_DBG(ERR, "Failed to initialize the dparms\n");
1231                 goto jump_to_error;
1232         }
1233
1234         /* create the port database */
1235         rc = ulp_port_db_init(bp->ulp_ctx, bp->port_cnt);
1236         if (rc) {
1237                 BNXT_TF_DBG(ERR, "Failed to create the port database\n");
1238                 goto jump_to_error;
1239         }
1240
1241         /* Create the Mark database. */
1242         rc = ulp_mark_db_init(bp->ulp_ctx);
1243         if (rc) {
1244                 BNXT_TF_DBG(ERR, "Failed to create the mark database\n");
1245                 goto jump_to_error;
1246         }
1247
1248         /* Create the flow database. */
1249         rc = ulp_flow_db_init(bp->ulp_ctx);
1250         if (rc) {
1251                 BNXT_TF_DBG(ERR, "Failed to create the flow database\n");
1252                 goto jump_to_error;
1253         }
1254
1255         /* Create the eem table scope. */
1256         rc = ulp_eem_tbl_scope_init(bp);
1257         if (rc) {
1258                 BNXT_TF_DBG(ERR, "Failed to create the eem scope table\n");
1259                 goto jump_to_error;
1260         }
1261
1262         rc = ulp_mapper_init(bp->ulp_ctx);
1263         if (rc) {
1264                 BNXT_TF_DBG(ERR, "Failed to initialize ulp mapper\n");
1265                 goto jump_to_error;
1266         }
1267
1268         rc = ulp_fc_mgr_init(bp->ulp_ctx);
1269         if (rc) {
1270                 BNXT_TF_DBG(ERR, "Failed to initialize ulp flow counter mgr\n");
1271                 goto jump_to_error;
1272         }
1273
1274         /*
1275          * Enable NAT feature. Set the global configuration register
1276          * Tunnel encap to enable NAT with the reuse of existing inner
1277          * L2 header smac and dmac
1278          */
1279         rc = bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
1280                                         TF_TUNNEL_ENCAP_NAT,
1281                                         BNXT_ULP_NAT_OUTER_MOST_FLAGS, 1);
1282         if (rc) {
1283                 BNXT_TF_DBG(ERR, "Failed to set rx global configuration\n");
1284                 goto jump_to_error;
1285         }
1286
1287         rc = bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
1288                                         TF_TUNNEL_ENCAP_NAT,
1289                                         BNXT_ULP_NAT_OUTER_MOST_FLAGS, 1);
1290         if (rc) {
1291                 BNXT_TF_DBG(ERR, "Failed to set tx global configuration\n");
1292                 goto jump_to_error;
1293         }
1294
1295         if (bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx)) {
1296                 rc = ulp_ha_mgr_init(bp->ulp_ctx);
1297                 if (rc) {
1298                         BNXT_TF_DBG(ERR, "Failed to initialize HA %d\n", rc);
1299                         goto jump_to_error;
1300                 }
1301                 rc = ulp_ha_mgr_open(bp->ulp_ctx);
1302                 if (rc) {
1303                         BNXT_TF_DBG(ERR, "Failed to Process HA Open %d\n", rc);
1304                         goto jump_to_error;
1305                 }
1306         }
1307         BNXT_TF_DBG(DEBUG, "ulp ctx has been initialized\n");
1308         return rc;
1309
1310 jump_to_error:
1311         bnxt_ulp_deinit(bp, session);
1312         return rc;
1313 }
1314
1315 /*
1316  * When a port is initialized by dpdk. This functions sets up
1317  * the port specific details.
1318  */
1319 int32_t
1320 bnxt_ulp_port_init(struct bnxt *bp)
1321 {
1322         struct bnxt_ulp_session_state *session;
1323         bool initialized;
1324         int32_t rc = 0;
1325
1326         if (!bp || !BNXT_TRUFLOW_EN(bp))
1327                 return rc;
1328
1329         if (!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {
1330                 BNXT_TF_DBG(ERR,
1331                             "Skip ulp init for port: %d, not a TVF or PF\n",
1332                         bp->eth_dev->data->port_id);
1333                 return rc;
1334         }
1335
1336         if (bp->ulp_ctx) {
1337                 BNXT_TF_DBG(DEBUG, "ulp ctx already allocated\n");
1338                 return rc;
1339         }
1340
1341         bp->ulp_ctx = rte_zmalloc("bnxt_ulp_ctx",
1342                                   sizeof(struct bnxt_ulp_context), 0);
1343         if (!bp->ulp_ctx) {
1344                 BNXT_TF_DBG(ERR, "Failed to allocate ulp ctx\n");
1345                 return -ENOMEM;
1346         }
1347
1348         /*
1349          * Multiple uplink ports can be associated with a single vswitch.
1350          * Make sure only the port that is started first will initialize
1351          * the TF session.
1352          */
1353         session = ulp_session_init(bp, &initialized);
1354         if (!session) {
1355                 BNXT_TF_DBG(ERR, "Failed to initialize the tf session\n");
1356                 rc = -EIO;
1357                 goto jump_to_error;
1358         }
1359
1360         if (initialized) {
1361                 /*
1362                  * If ULP is already initialized for a specific domain then
1363                  * simply assign the ulp context to this rte_eth_dev.
1364                  */
1365                 rc = ulp_ctx_attach(bp, session);
1366                 if (rc) {
1367                         BNXT_TF_DBG(ERR, "Failed to attach the ulp context\n");
1368                         goto jump_to_error;
1369                 }
1370
1371                 /*
1372                  * Attach to the shared session, must be called after the
1373                  * ulp_ctx_attach in order to ensure that ulp data is available
1374                  * for attaching.
1375                  */
1376                 rc = ulp_ctx_shared_session_attach(bp, session);
1377                 if (rc) {
1378                         BNXT_TF_DBG(ERR,
1379                                     "Failed attach to shared session (%d)", rc);
1380                         goto jump_to_error;
1381                 }
1382         } else {
1383                 rc = bnxt_ulp_init(bp, session);
1384                 if (rc) {
1385                         BNXT_TF_DBG(ERR, "Failed to initialize the ulp init\n");
1386                         goto jump_to_error;
1387                 }
1388         }
1389
1390         /* Update bnxt driver flags */
1391         rc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx);
1392         if (rc) {
1393                 BNXT_TF_DBG(ERR, "Failed to update driver flags\n");
1394                 goto jump_to_error;
1395         }
1396
1397         /* update the port database for the given interface */
1398         rc = ulp_port_db_dev_port_intf_update(bp->ulp_ctx, bp->eth_dev);
1399         if (rc) {
1400                 BNXT_TF_DBG(ERR, "Failed to update port database\n");
1401                 goto jump_to_error;
1402         }
1403         /* create the default rules */
1404         rc = bnxt_ulp_create_df_rules(bp);
1405         if (rc) {
1406                 BNXT_TF_DBG(ERR, "Failed to create default flow\n");
1407                 goto jump_to_error;
1408         }
1409
1410         if (BNXT_ACCUM_STATS_EN(bp))
1411                 bp->ulp_ctx->cfg_data->accum_stats = true;
1412
1413         BNXT_TF_DBG(DEBUG, "BNXT Port:%d ULP port init\n",
1414                     bp->eth_dev->data->port_id);
1415         return rc;
1416
1417 jump_to_error:
1418         bnxt_ulp_port_deinit(bp);
1419         return rc;
1420 }
1421
1422 /*
1423  * When a port is de-initialized by dpdk. This functions clears up
1424  * the port specific details.
1425  */
1426 void
1427 bnxt_ulp_port_deinit(struct bnxt *bp)
1428 {
1429         struct bnxt_ulp_session_state *session;
1430         struct rte_pci_device *pci_dev;
1431         struct rte_pci_addr *pci_addr;
1432
1433         if (!BNXT_TRUFLOW_EN(bp))
1434                 return;
1435
1436         if (!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {
1437                 BNXT_TF_DBG(ERR,
1438                             "Skip ULP deinit port:%d, not a TVF or PF\n",
1439                             bp->eth_dev->data->port_id);
1440                 return;
1441         }
1442
1443         if (!bp->ulp_ctx) {
1444                 BNXT_TF_DBG(DEBUG, "ulp ctx already de-allocated\n");
1445                 return;
1446         }
1447
1448         BNXT_TF_DBG(DEBUG, "BNXT Port:%d ULP port deinit\n",
1449                     bp->eth_dev->data->port_id);
1450
1451         /* Get the session details  */
1452         pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
1453         pci_addr = &pci_dev->addr;
1454         pthread_mutex_lock(&bnxt_ulp_global_mutex);
1455         session = ulp_get_session(pci_addr);
1456         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
1457
1458         /* session not found then just exit */
1459         if (!session) {
1460                 /* Free the ulp context */
1461                 rte_free(bp->ulp_ctx);
1462                 bp->ulp_ctx = NULL;
1463                 return;
1464         }
1465
1466         /* Check the reference count to deinit or deattach*/
1467         if (bp->ulp_ctx->cfg_data && bp->ulp_ctx->cfg_data->ref_cnt) {
1468                 bp->ulp_ctx->cfg_data->ref_cnt--;
1469                 if (bp->ulp_ctx->cfg_data->ref_cnt) {
1470                         /* free the port details */
1471                         /* Free the default flow rule associated to this port */
1472                         bnxt_ulp_destroy_df_rules(bp, false);
1473                         bnxt_ulp_destroy_vfr_default_rules(bp, false);
1474
1475                         /* free flows associated with this port */
1476                         bnxt_ulp_flush_port_flows(bp);
1477
1478                         /* close the session associated with this port */
1479                         ulp_ctx_detach(bp);
1480
1481                         /* always detach/close shared after the session. */
1482                         ulp_ctx_shared_session_detach(bp);
1483                 } else {
1484                         /* Perform ulp ctx deinit */
1485                         bnxt_ulp_deinit(bp, session);
1486                 }
1487         }
1488
1489         /* clean up the session */
1490         ulp_session_deinit(session);
1491
1492         /* Free the ulp context */
1493         rte_free(bp->ulp_ctx);
1494         bp->ulp_ctx = NULL;
1495 }
1496
1497 /* Below are the access functions to access internal data of ulp context. */
1498 /* Function to set the Mark DB into the context */
1499 int32_t
1500 bnxt_ulp_cntxt_ptr2_mark_db_set(struct bnxt_ulp_context *ulp_ctx,
1501                                 struct bnxt_ulp_mark_tbl *mark_tbl)
1502 {
1503         if (!ulp_ctx || !ulp_ctx->cfg_data) {
1504                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
1505                 return -EINVAL;
1506         }
1507
1508         ulp_ctx->cfg_data->mark_tbl = mark_tbl;
1509
1510         return 0;
1511 }
1512
1513 /* Function to retrieve the Mark DB from the context. */
1514 struct bnxt_ulp_mark_tbl *
1515 bnxt_ulp_cntxt_ptr2_mark_db_get(struct bnxt_ulp_context *ulp_ctx)
1516 {
1517         if (!ulp_ctx || !ulp_ctx->cfg_data)
1518                 return NULL;
1519
1520         return ulp_ctx->cfg_data->mark_tbl;
1521 }
1522
1523 bool
1524 bnxt_ulp_cntxt_shared_session_enabled(struct bnxt_ulp_context *ulp_ctx)
1525 {
1526         return ULP_SHARED_SESSION_IS_ENABLED(ulp_ctx->cfg_data->ulp_flags);
1527 }
1528
1529 int32_t
1530 bnxt_ulp_cntxt_app_id_set(struct bnxt_ulp_context *ulp_ctx, uint8_t app_id)
1531 {
1532         if (!ulp_ctx)
1533                 return -EINVAL;
1534         ulp_ctx->cfg_data->app_id = app_id;
1535         return 0;
1536 }
1537
1538 int32_t
1539 bnxt_ulp_cntxt_app_id_get(struct bnxt_ulp_context *ulp_ctx, uint8_t *app_id)
1540 {
1541         /* Default APP id is zero */
1542         if (!ulp_ctx || !app_id)
1543                 return -EINVAL;
1544         *app_id = ulp_ctx->cfg_data->app_id;
1545         return 0;
1546 }
1547
1548 /* Function to set the device id of the hardware. */
1549 int32_t
1550 bnxt_ulp_cntxt_dev_id_set(struct bnxt_ulp_context *ulp_ctx,
1551                           uint32_t dev_id)
1552 {
1553         if (ulp_ctx && ulp_ctx->cfg_data) {
1554                 ulp_ctx->cfg_data->dev_id = dev_id;
1555                 return 0;
1556         }
1557
1558         return -EINVAL;
1559 }
1560
1561 /* Function to get the device id of the hardware. */
1562 int32_t
1563 bnxt_ulp_cntxt_dev_id_get(struct bnxt_ulp_context *ulp_ctx,
1564                           uint32_t *dev_id)
1565 {
1566         if (ulp_ctx && ulp_ctx->cfg_data) {
1567                 *dev_id = ulp_ctx->cfg_data->dev_id;
1568                 return 0;
1569         }
1570
1571         BNXT_TF_DBG(ERR, "Failed to read dev_id from ulp ctxt\n");
1572         return -EINVAL;
1573 }
1574
1575 int32_t
1576 bnxt_ulp_cntxt_mem_type_set(struct bnxt_ulp_context *ulp_ctx,
1577                             enum bnxt_ulp_flow_mem_type mem_type)
1578 {
1579         if (ulp_ctx && ulp_ctx->cfg_data) {
1580                 ulp_ctx->cfg_data->mem_type = mem_type;
1581                 return 0;
1582         }
1583         BNXT_TF_DBG(ERR, "Failed to write mem_type in ulp ctxt\n");
1584         return -EINVAL;
1585 }
1586
1587 int32_t
1588 bnxt_ulp_cntxt_mem_type_get(struct bnxt_ulp_context *ulp_ctx,
1589                             enum bnxt_ulp_flow_mem_type *mem_type)
1590 {
1591         if (ulp_ctx && ulp_ctx->cfg_data) {
1592                 *mem_type = ulp_ctx->cfg_data->mem_type;
1593                 return 0;
1594         }
1595         BNXT_TF_DBG(ERR, "Failed to read mem_type in ulp ctxt\n");
1596         return -EINVAL;
1597 }
1598
1599 /* Function to get the table scope id of the EEM table. */
1600 int32_t
1601 bnxt_ulp_cntxt_tbl_scope_id_get(struct bnxt_ulp_context *ulp_ctx,
1602                                 uint32_t *tbl_scope_id)
1603 {
1604         if (ulp_ctx && ulp_ctx->cfg_data) {
1605                 *tbl_scope_id = ulp_ctx->cfg_data->tbl_scope_id;
1606                 return 0;
1607         }
1608
1609         return -EINVAL;
1610 }
1611
1612 /* Function to set the table scope id of the EEM table. */
1613 int32_t
1614 bnxt_ulp_cntxt_tbl_scope_id_set(struct bnxt_ulp_context *ulp_ctx,
1615                                 uint32_t tbl_scope_id)
1616 {
1617         if (ulp_ctx && ulp_ctx->cfg_data) {
1618                 ulp_ctx->cfg_data->tbl_scope_id = tbl_scope_id;
1619                 return 0;
1620         }
1621
1622         return -EINVAL;
1623 }
1624
1625 /* Function to set the shared tfp session details from the ulp context. */
1626 int32_t
1627 bnxt_ulp_cntxt_shared_tfp_set(struct bnxt_ulp_context *ulp, struct tf *tfp)
1628 {
1629         if (!ulp) {
1630                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
1631                 return -EINVAL;
1632         }
1633
1634         ulp->g_shared_tfp = tfp;
1635         return 0;
1636 }
1637
1638 /* Function to get the shared tfp session details from the ulp context. */
1639 struct tf *
1640 bnxt_ulp_cntxt_shared_tfp_get(struct bnxt_ulp_context *ulp)
1641 {
1642         if (!ulp) {
1643                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
1644                 return NULL;
1645         }
1646         return ulp->g_shared_tfp;
1647 }
1648
1649 /* Function to set the tfp session details from the ulp context. */
1650 int32_t
1651 bnxt_ulp_cntxt_tfp_set(struct bnxt_ulp_context *ulp, struct tf *tfp)
1652 {
1653         if (!ulp) {
1654                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
1655                 return -EINVAL;
1656         }
1657
1658         ulp->g_tfp = tfp;
1659         return 0;
1660 }
1661
1662 /* Function to get the tfp session details from the ulp context. */
1663 struct tf *
1664 bnxt_ulp_cntxt_tfp_get(struct bnxt_ulp_context *ulp,
1665                        enum bnxt_ulp_shared_session shared)
1666 {
1667         if (!ulp) {
1668                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
1669                 return NULL;
1670         }
1671         if (shared)
1672                 return ulp->g_shared_tfp;
1673         else
1674                 return ulp->g_tfp;
1675 }
1676
1677 /*
1678  * Get the device table entry based on the device id.
1679  *
1680  * dev_id [in] The device id of the hardware
1681  *
1682  * Returns the pointer to the device parameters.
1683  */
1684 struct bnxt_ulp_device_params *
1685 bnxt_ulp_device_params_get(uint32_t dev_id)
1686 {
1687         if (dev_id < BNXT_ULP_MAX_NUM_DEVICES)
1688                 return &ulp_device_params[dev_id];
1689         return NULL;
1690 }
1691
1692 /* Function to set the flow database to the ulp context. */
1693 int32_t
1694 bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx,
1695                                 struct bnxt_ulp_flow_db *flow_db)
1696 {
1697         if (!ulp_ctx || !ulp_ctx->cfg_data)
1698                 return -EINVAL;
1699
1700         ulp_ctx->cfg_data->flow_db = flow_db;
1701         return 0;
1702 }
1703
1704 /* Function to get the flow database from the ulp context. */
1705 struct bnxt_ulp_flow_db *
1706 bnxt_ulp_cntxt_ptr2_flow_db_get(struct bnxt_ulp_context *ulp_ctx)
1707 {
1708         if (!ulp_ctx || !ulp_ctx->cfg_data)
1709                 return NULL;
1710
1711         return ulp_ctx->cfg_data->flow_db;
1712 }
1713
1714 /* Function to get the tunnel cache table info from the ulp context. */
1715 struct bnxt_tun_cache_entry *
1716 bnxt_ulp_cntxt_ptr2_tun_tbl_get(struct bnxt_ulp_context *ulp_ctx)
1717 {
1718         if (!ulp_ctx || !ulp_ctx->cfg_data)
1719                 return NULL;
1720
1721         return ulp_ctx->cfg_data->tun_tbl;
1722 }
1723
1724 /* Function to get the ulp context from eth device. */
1725 struct bnxt_ulp_context *
1726 bnxt_ulp_eth_dev_ptr2_cntxt_get(struct rte_eth_dev      *dev)
1727 {
1728         struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
1729
1730         if (BNXT_ETH_DEV_IS_REPRESENTOR(dev)) {
1731                 struct bnxt_representor *vfr = dev->data->dev_private;
1732
1733                 bp = vfr->parent_dev->data->dev_private;
1734         }
1735
1736         if (!bp) {
1737                 BNXT_TF_DBG(ERR, "Bnxt private data is not initialized\n");
1738                 return NULL;
1739         }
1740         return bp->ulp_ctx;
1741 }
1742
1743 int32_t
1744 bnxt_ulp_cntxt_ptr2_mapper_data_set(struct bnxt_ulp_context *ulp_ctx,
1745                                     void *mapper_data)
1746 {
1747         if (!ulp_ctx || !ulp_ctx->cfg_data) {
1748                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
1749                 return -EINVAL;
1750         }
1751
1752         ulp_ctx->cfg_data->mapper_data = mapper_data;
1753         return 0;
1754 }
1755
1756 void *
1757 bnxt_ulp_cntxt_ptr2_mapper_data_get(struct bnxt_ulp_context *ulp_ctx)
1758 {
1759         if (!ulp_ctx || !ulp_ctx->cfg_data) {
1760                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
1761                 return NULL;
1762         }
1763
1764         return ulp_ctx->cfg_data->mapper_data;
1765 }
1766
1767 /* Function to set the port database to the ulp context. */
1768 int32_t
1769 bnxt_ulp_cntxt_ptr2_port_db_set(struct bnxt_ulp_context *ulp_ctx,
1770                                 struct bnxt_ulp_port_db *port_db)
1771 {
1772         if (!ulp_ctx || !ulp_ctx->cfg_data)
1773                 return -EINVAL;
1774
1775         ulp_ctx->cfg_data->port_db = port_db;
1776         return 0;
1777 }
1778
1779 /* Function to get the port database from the ulp context. */
1780 struct bnxt_ulp_port_db *
1781 bnxt_ulp_cntxt_ptr2_port_db_get(struct bnxt_ulp_context *ulp_ctx)
1782 {
1783         if (!ulp_ctx || !ulp_ctx->cfg_data)
1784                 return NULL;
1785
1786         return ulp_ctx->cfg_data->port_db;
1787 }
1788
1789 /* Function to set the flow counter info into the context */
1790 int32_t
1791 bnxt_ulp_cntxt_ptr2_fc_info_set(struct bnxt_ulp_context *ulp_ctx,
1792                                 struct bnxt_ulp_fc_info *ulp_fc_info)
1793 {
1794         if (!ulp_ctx || !ulp_ctx->cfg_data) {
1795                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
1796                 return -EINVAL;
1797         }
1798
1799         ulp_ctx->cfg_data->fc_info = ulp_fc_info;
1800
1801         return 0;
1802 }
1803
1804 /* Function to retrieve the flow counter info from the context. */
1805 struct bnxt_ulp_fc_info *
1806 bnxt_ulp_cntxt_ptr2_fc_info_get(struct bnxt_ulp_context *ulp_ctx)
1807 {
1808         if (!ulp_ctx || !ulp_ctx->cfg_data)
1809                 return NULL;
1810
1811         return ulp_ctx->cfg_data->fc_info;
1812 }
1813
1814 /* Function to get the ulp flags from the ulp context. */
1815 int32_t
1816 bnxt_ulp_cntxt_ptr2_ulp_flags_get(struct bnxt_ulp_context *ulp_ctx,
1817                                   uint32_t *flags)
1818 {
1819         if (!ulp_ctx || !ulp_ctx->cfg_data)
1820                 return -1;
1821
1822         *flags =  ulp_ctx->cfg_data->ulp_flags;
1823         return 0;
1824 }
1825
1826 /* Function to get the ulp vfr info from the ulp context. */
1827 struct bnxt_ulp_vfr_rule_info*
1828 bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(struct bnxt_ulp_context *ulp_ctx,
1829                                      uint32_t port_id)
1830 {
1831         if (!ulp_ctx || !ulp_ctx->cfg_data || port_id >= RTE_MAX_ETHPORTS)
1832                 return NULL;
1833
1834         return &ulp_ctx->cfg_data->vfr_rule_info[port_id];
1835 }
1836
1837 /* Function to acquire the flow database lock from the ulp context. */
1838 int32_t
1839 bnxt_ulp_cntxt_acquire_fdb_lock(struct bnxt_ulp_context *ulp_ctx)
1840 {
1841         if (!ulp_ctx || !ulp_ctx->cfg_data)
1842                 return -1;
1843
1844         if (pthread_mutex_lock(&ulp_ctx->cfg_data->flow_db_lock)) {
1845                 BNXT_TF_DBG(ERR, "unable to acquire fdb lock\n");
1846                 return -1;
1847         }
1848         return 0;
1849 }
1850
1851 /* Function to release the flow database lock from the ulp context. */
1852 void
1853 bnxt_ulp_cntxt_release_fdb_lock(struct bnxt_ulp_context *ulp_ctx)
1854 {
1855         if (!ulp_ctx || !ulp_ctx->cfg_data)
1856                 return;
1857
1858         pthread_mutex_unlock(&ulp_ctx->cfg_data->flow_db_lock);
1859 }
1860
1861 /* Function to set the ha info into the context */
1862 int32_t
1863 bnxt_ulp_cntxt_ptr2_ha_info_set(struct bnxt_ulp_context *ulp_ctx,
1864                                 struct bnxt_ulp_ha_mgr_info *ulp_ha_info)
1865 {
1866         if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL) {
1867                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
1868                 return -EINVAL;
1869         }
1870         ulp_ctx->cfg_data->ha_info = ulp_ha_info;
1871         return 0;
1872 }
1873
1874 /* Function to retrieve the ha info from the context. */
1875 struct bnxt_ulp_ha_mgr_info *
1876 bnxt_ulp_cntxt_ptr2_ha_info_get(struct bnxt_ulp_context *ulp_ctx)
1877 {
1878         if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
1879                 return NULL;
1880         return ulp_ctx->cfg_data->ha_info;
1881 }
1882
1883 bool
1884 bnxt_ulp_cntxt_ha_enabled(struct bnxt_ulp_context *ulp_ctx)
1885 {
1886         if (ulp_ctx == NULL || ulp_ctx->cfg_data == NULL)
1887                 return false;
1888         return !!ULP_HIGH_AVAIL_IS_ENABLED(ulp_ctx->cfg_data->ulp_flags);
1889 }