net/bnxt: fix port stop process and cleanup resources
[dpdk.git] / drivers / net / bnxt / tf_ulp / bnxt_ulp.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2020 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
26 /* Linked list of all TF sessions. */
27 STAILQ_HEAD(, bnxt_ulp_session_state) bnxt_ulp_session_list =
28                         STAILQ_HEAD_INITIALIZER(bnxt_ulp_session_list);
29
30 /* Mutex to synchronize bnxt_ulp_session_list operations. */
31 static pthread_mutex_t bnxt_ulp_global_mutex = PTHREAD_MUTEX_INITIALIZER;
32
33 /*
34  * Allow the deletion of context only for the bnxt device that
35  * created the session.
36  */
37 bool
38 ulp_ctx_deinit_allowed(void *ptr)
39 {
40         struct bnxt *bp = (struct bnxt *)ptr;
41
42         if (!bp || !bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
43                 return false;
44
45         if (!bp->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 /*
54  * Initialize an ULP session.
55  * An ULP session will contain all the resources needed to support rte flow
56  * offloads. A session is initialized as part of rte_eth_device start.
57  * A single vswitch instance can have multiple uplinks which means
58  * rte_eth_device start will be called for each of these devices.
59  * ULP session manager will make sure that a single ULP session is only
60  * initialized once. Apart from this, it also initializes MARK database,
61  * EEM table & flow database. ULP session manager also manages a list of
62  * all opened ULP sessions.
63  */
64 static int32_t
65 ulp_ctx_session_open(struct bnxt *bp,
66                      struct bnxt_ulp_session_state *session)
67 {
68         struct rte_eth_dev              *ethdev = bp->eth_dev;
69         int32_t                         rc = 0;
70         struct tf_open_session_parms    params;
71         struct tf_session_resources     *resources;
72
73         memset(&params, 0, sizeof(params));
74
75         rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
76                                           params.ctrl_chan_name);
77         if (rc) {
78                 BNXT_TF_DBG(ERR, "Invalid port %d, rc = %d\n",
79                             ethdev->data->port_id, rc);
80                 return rc;
81         }
82
83         params.shadow_copy = true;
84         params.device_type = TF_DEVICE_TYPE_WH;
85         resources = &params.resources;
86         /** RX **/
87         /* Identifiers */
88         resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_L2_CTXT_HIGH] = 422;
89         resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_L2_CTXT_LOW] = 6;
90         resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_WC_PROF] = 8;
91         resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_PROF_FUNC] = 8;
92         resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_EM_PROF] = 8;
93
94         /* Table Types */
95         resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_FULL_ACT_RECORD] = 8192;
96         resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_ACT_STATS_64] = 8192;
97         resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_ACT_MODIFY_IPV4] = 1023;
98
99         /* ENCAP */
100         resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_ACT_ENCAP_8B] = 16;
101         resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_ACT_ENCAP_16B] = 63;
102
103         /* TCAMs */
104         resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_HIGH] =
105                 422;
106         resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_LOW] =
107                 6;
108         resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_PROF_TCAM] = 8;
109         resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] = 88;
110
111         /* EM */
112         resources->em_cnt[TF_DIR_RX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 13176;
113
114         /* EEM */
115         resources->em_cnt[TF_DIR_RX].cnt[TF_EM_TBL_TYPE_TBL_SCOPE] = 1;
116
117         /** TX **/
118         /* Identifiers */
119         resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_L2_CTXT_HIGH] = 292;
120         resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_L2_CTXT_LOW] = 144;
121         resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_WC_PROF] = 8;
122         resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_PROF_FUNC] = 8;
123         resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_EM_PROF] = 8;
124
125         /* Table Types */
126         resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_FULL_ACT_RECORD] = 8192;
127         resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_ACT_STATS_64] = 8192;
128         resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_ACT_MODIFY_IPV4] = 1023;
129
130         /* ENCAP */
131         resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_ACT_ENCAP_64B] = 511;
132         resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_ACT_ENCAP_16B] = 200;
133
134         /* TCAMs */
135         resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_HIGH] =
136                 292;
137         resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_LOW] =
138                 144;
139         resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_PROF_TCAM] = 8;
140         resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] = 8;
141
142         /* EM */
143         resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 15232;
144
145         /* EEM */
146         resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_TBL_SCOPE] = 1;
147
148         /* SP */
149         resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_ACT_SP_SMAC_IPV4] = 488;
150
151         rc = tf_open_session(&bp->tfp, &params);
152         if (rc) {
153                 BNXT_TF_DBG(ERR, "Failed to open TF session - %s, rc = %d\n",
154                             params.ctrl_chan_name, rc);
155                 return -EINVAL;
156         }
157         if (!session->session_opened) {
158                 session->session_opened = 1;
159                 session->g_tfp = &bp->tfp;
160         }
161         return rc;
162 }
163
164 /*
165  * Close the ULP session.
166  * It takes the ulp context pointer.
167  */
168 static void
169 ulp_ctx_session_close(struct bnxt *bp,
170                       struct bnxt_ulp_session_state *session)
171 {
172         /* close the session in the hardware */
173         if (session->session_opened)
174                 tf_close_session(&bp->tfp);
175         session->session_opened = 0;
176         session->g_tfp = NULL;
177 }
178
179 static void
180 bnxt_init_tbl_scope_parms(struct bnxt *bp,
181                           struct tf_alloc_tbl_scope_parms *params)
182 {
183         struct bnxt_ulp_device_params   *dparms;
184         uint32_t dev_id;
185         int rc;
186
187         rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id);
188         if (rc)
189                 /* TBD: For now, just use default. */
190                 dparms = 0;
191         else
192                 dparms = bnxt_ulp_device_params_get(dev_id);
193
194         /*
195          * Set the flush timer for EEM entries. The value is in 100ms intervals,
196          * so 100 is 10s.
197          */
198         params->hw_flow_cache_flush_timer = 100;
199
200         if (!dparms) {
201                 params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
202                 params->rx_max_action_entry_sz_in_bits =
203                         BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
204                 params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
205                 params->rx_num_flows_in_k = BNXT_ULP_RX_NUM_FLOWS;
206                 params->rx_tbl_if_id = BNXT_ULP_RX_TBL_IF_ID;
207
208                 params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
209                 params->tx_max_action_entry_sz_in_bits =
210                         BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
211                 params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
212                 params->tx_num_flows_in_k = BNXT_ULP_TX_NUM_FLOWS;
213                 params->tx_tbl_if_id = BNXT_ULP_TX_TBL_IF_ID;
214         } else {
215                 params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
216                 params->rx_max_action_entry_sz_in_bits =
217                         BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
218                 params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
219                 params->rx_num_flows_in_k = dparms->flow_db_num_entries / 1024;
220                 params->rx_tbl_if_id = BNXT_ULP_RX_TBL_IF_ID;
221
222                 params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
223                 params->tx_max_action_entry_sz_in_bits =
224                         BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
225                 params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
226                 params->tx_num_flows_in_k = dparms->flow_db_num_entries / 1024;
227                 params->tx_tbl_if_id = BNXT_ULP_TX_TBL_IF_ID;
228         }
229 }
230
231 /* Initialize Extended Exact Match host memory. */
232 static int32_t
233 ulp_eem_tbl_scope_init(struct bnxt *bp)
234 {
235         struct tf_alloc_tbl_scope_parms params = {0};
236         uint32_t dev_id;
237         struct bnxt_ulp_device_params *dparms;
238         int rc;
239
240         /* Get the dev specific number of flows that needed to be supported. */
241         if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
242                 BNXT_TF_DBG(ERR, "Invalid device id\n");
243                 return -EINVAL;
244         }
245
246         dparms = bnxt_ulp_device_params_get(dev_id);
247         if (!dparms) {
248                 BNXT_TF_DBG(ERR, "could not fetch the device params\n");
249                 return -ENODEV;
250         }
251
252         if (dparms->flow_mem_type != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
253                 BNXT_TF_DBG(INFO, "Table Scope alloc is not required\n");
254                 return 0;
255         }
256
257         bnxt_init_tbl_scope_parms(bp, &params);
258
259         rc = tf_alloc_tbl_scope(&bp->tfp, &params);
260         if (rc) {
261                 BNXT_TF_DBG(ERR, "Unable to allocate eem table scope rc = %d\n",
262                             rc);
263                 return rc;
264         }
265
266         rc = bnxt_ulp_cntxt_tbl_scope_id_set(bp->ulp_ctx, params.tbl_scope_id);
267         if (rc) {
268                 BNXT_TF_DBG(ERR, "Unable to set table scope id\n");
269                 return rc;
270         }
271
272         return 0;
273 }
274
275 /* Free Extended Exact Match host memory */
276 static int32_t
277 ulp_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)
278 {
279         struct tf_free_tbl_scope_parms  params = {0};
280         struct tf                       *tfp;
281         int32_t                         rc = 0;
282         struct bnxt_ulp_device_params *dparms;
283         uint32_t dev_id;
284
285         if (!ulp_ctx || !ulp_ctx->cfg_data)
286                 return -EINVAL;
287
288         tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
289         if (!tfp) {
290                 BNXT_TF_DBG(ERR, "Failed to get the truflow pointer\n");
291                 return -EINVAL;
292         }
293
294         /* Get the dev specific number of flows that needed to be supported. */
295         if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) {
296                 BNXT_TF_DBG(ERR, "Invalid device id\n");
297                 return -EINVAL;
298         }
299
300         dparms = bnxt_ulp_device_params_get(dev_id);
301         if (!dparms) {
302                 BNXT_TF_DBG(ERR, "could not fetch the device params\n");
303                 return -ENODEV;
304         }
305
306         if (dparms->flow_mem_type != BNXT_ULP_FLOW_MEM_TYPE_EXT) {
307                 BNXT_TF_DBG(INFO, "Table Scope free is not required\n");
308                 return 0;
309         }
310
311         rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp_ctx, &params.tbl_scope_id);
312         if (rc) {
313                 BNXT_TF_DBG(ERR, "Failed to get the table scope id\n");
314                 return -EINVAL;
315         }
316
317         rc = tf_free_tbl_scope(tfp, &params);
318         if (rc) {
319                 BNXT_TF_DBG(ERR, "Unable to free table scope\n");
320                 return -EINVAL;
321         }
322         return rc;
323 }
324
325 /* The function to free and deinit the ulp context data. */
326 static int32_t
327 ulp_ctx_deinit(struct bnxt *bp,
328                struct bnxt_ulp_session_state *session)
329 {
330         /* close the tf session */
331         ulp_ctx_session_close(bp, session);
332
333         /* Free the contents */
334         if (session->cfg_data) {
335                 rte_free(session->cfg_data);
336                 bp->ulp_ctx->cfg_data = NULL;
337                 session->cfg_data = NULL;
338         }
339         return 0;
340 }
341
342 /* The function to allocate and initialize the ulp context data. */
343 static int32_t
344 ulp_ctx_init(struct bnxt *bp,
345              struct bnxt_ulp_session_state *session)
346 {
347         struct bnxt_ulp_data    *ulp_data;
348         int32_t                 rc = 0;
349
350         /* Allocate memory to hold ulp context data. */
351         ulp_data = rte_zmalloc("bnxt_ulp_data",
352                                sizeof(struct bnxt_ulp_data), 0);
353         if (!ulp_data) {
354                 BNXT_TF_DBG(ERR, "Failed to allocate memory for ulp data\n");
355                 return -ENOMEM;
356         }
357
358         /* Increment the ulp context data reference count usage. */
359         bp->ulp_ctx->cfg_data = ulp_data;
360         session->cfg_data = ulp_data;
361         ulp_data->ref_cnt++;
362         ulp_data->ulp_flags |= BNXT_ULP_VF_REP_ENABLED;
363
364         /* Open the ulp session. */
365         rc = ulp_ctx_session_open(bp, session);
366         if (rc) {
367                 session->session_opened = 1;
368                 (void)ulp_ctx_deinit(bp, session);
369                 return rc;
370         }
371
372         bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, &bp->tfp);
373         return rc;
374 }
375
376 /* The function to initialize ulp dparms with devargs */
377 static int32_t
378 ulp_dparms_init(struct bnxt *bp,
379                 struct bnxt_ulp_context *ulp_ctx)
380 {
381         struct bnxt_ulp_device_params *dparms;
382         uint32_t dev_id;
383
384         if (!bp->max_num_kflows)
385                 return 0;
386
387         if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) {
388                 BNXT_TF_DBG(DEBUG, "Failed to get device id\n");
389                 return -EINVAL;
390         }
391
392         dparms = bnxt_ulp_device_params_get(dev_id);
393         if (!dparms) {
394                 BNXT_TF_DBG(DEBUG, "Failed to get device parms\n");
395                 return -EINVAL;
396         }
397
398         /* num_flows = max_num_kflows * 1024 */
399         dparms->flow_db_num_entries = bp->max_num_kflows * 1024;
400         /* GFID =  2 * num_flows */
401         dparms->mark_db_gfid_entries = dparms->flow_db_num_entries * 2;
402         BNXT_TF_DBG(DEBUG, "Set the number of flows = %"PRIu64"\n",
403                     dparms->flow_db_num_entries);
404
405         return 0;
406 }
407
408 /* The function to initialize bp flags with truflow features */
409 static int32_t
410 ulp_dparms_dev_port_intf_update(struct bnxt *bp,
411                                 struct bnxt_ulp_context *ulp_ctx)
412 {
413         struct bnxt_ulp_device_params *dparms;
414         uint32_t dev_id;
415
416         if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) {
417                 BNXT_TF_DBG(DEBUG, "Failed to get device id\n");
418                 return -EINVAL;
419         }
420
421         dparms = bnxt_ulp_device_params_get(dev_id);
422         if (!dparms) {
423                 BNXT_TF_DBG(DEBUG, "Failed to get device parms\n");
424                 return -EINVAL;
425         }
426
427         /* Update the bp flag with gfid flag */
428         if (dparms->flow_mem_type == BNXT_ULP_FLOW_MEM_TYPE_EXT)
429                 bp->flags |= BNXT_FLAG_GFID_ENABLE;
430
431         return 0;
432 }
433
434 static int32_t
435 ulp_ctx_attach(struct bnxt *bp,
436                struct bnxt_ulp_session_state *session)
437 {
438         int32_t rc = 0;
439
440         /* Increment the ulp context data reference count usage. */
441         bp->ulp_ctx->cfg_data = session->cfg_data;
442         bp->ulp_ctx->cfg_data->ref_cnt++;
443
444         /* update the session details in bnxt tfp */
445         bp->tfp.session = session->g_tfp->session;
446
447         /* Create a TF Client */
448         rc = ulp_ctx_session_open(bp, session);
449         if (rc) {
450                 PMD_DRV_LOG(ERR, "Failed to open ctxt session, rc:%d\n", rc);
451                 bp->tfp.session = NULL;
452                 return rc;
453         }
454
455         bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, &bp->tfp);
456         return rc;
457 }
458
459 static void
460 ulp_ctx_detach(struct bnxt *bp)
461 {
462         if (bp->tfp.session) {
463                 tf_close_session(&bp->tfp);
464                 bp->tfp.session = NULL;
465         }
466 }
467
468 /*
469  * Initialize the state of an ULP session.
470  * If the state of an ULP session is not initialized, set it's state to
471  * initialized. If the state is already initialized, do nothing.
472  */
473 static void
474 ulp_context_initialized(struct bnxt_ulp_session_state *session, bool *init)
475 {
476         pthread_mutex_lock(&session->bnxt_ulp_mutex);
477
478         if (!session->bnxt_ulp_init) {
479                 session->bnxt_ulp_init = true;
480                 *init = false;
481         } else {
482                 *init = true;
483         }
484
485         pthread_mutex_unlock(&session->bnxt_ulp_mutex);
486 }
487
488 /*
489  * Check if an ULP session is already allocated for a specific PCI
490  * domain & bus. If it is already allocated simply return the session
491  * pointer, otherwise allocate a new session.
492  */
493 static struct bnxt_ulp_session_state *
494 ulp_get_session(struct rte_pci_addr *pci_addr)
495 {
496         struct bnxt_ulp_session_state *session;
497
498         STAILQ_FOREACH(session, &bnxt_ulp_session_list, next) {
499                 if (session->pci_info.domain == pci_addr->domain &&
500                     session->pci_info.bus == pci_addr->bus) {
501                         return session;
502                 }
503         }
504         return NULL;
505 }
506
507 /*
508  * Allocate and Initialize an ULP session and set it's state to INITIALIZED.
509  * If it's already initialized simply return the already existing session.
510  */
511 static struct bnxt_ulp_session_state *
512 ulp_session_init(struct bnxt *bp,
513                  bool *init)
514 {
515         struct rte_pci_device           *pci_dev;
516         struct rte_pci_addr             *pci_addr;
517         struct bnxt_ulp_session_state   *session;
518         int rc = 0;
519
520         if (!bp)
521                 return NULL;
522
523         pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
524         pci_addr = &pci_dev->addr;
525
526         pthread_mutex_lock(&bnxt_ulp_global_mutex);
527
528         session = ulp_get_session(pci_addr);
529         if (!session) {
530                 /* Not Found the session  Allocate a new one */
531                 session = rte_zmalloc("bnxt_ulp_session",
532                                       sizeof(struct bnxt_ulp_session_state),
533                                       0);
534                 if (!session) {
535                         BNXT_TF_DBG(ERR,
536                                     "Allocation failed for bnxt_ulp_session\n");
537                         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
538                         return NULL;
539
540                 } else {
541                         /* Add it to the queue */
542                         session->pci_info.domain = pci_addr->domain;
543                         session->pci_info.bus = pci_addr->bus;
544                         rc = pthread_mutex_init(&session->bnxt_ulp_mutex, NULL);
545                         if (rc) {
546                                 BNXT_TF_DBG(ERR, "mutex create failed\n");
547                                 pthread_mutex_unlock(&bnxt_ulp_global_mutex);
548                                 return NULL;
549                         }
550                         STAILQ_INSERT_TAIL(&bnxt_ulp_session_list,
551                                            session, next);
552                 }
553         }
554         ulp_context_initialized(session, init);
555         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
556         return session;
557 }
558
559 /*
560  * When a device is closed, remove it's associated session from the global
561  * session list.
562  */
563 static void
564 ulp_session_deinit(struct bnxt_ulp_session_state *session)
565 {
566         if (!session)
567                 return;
568
569         if (!session->cfg_data) {
570                 pthread_mutex_lock(&bnxt_ulp_global_mutex);
571                 STAILQ_REMOVE(&bnxt_ulp_session_list, session,
572                               bnxt_ulp_session_state, next);
573                 pthread_mutex_destroy(&session->bnxt_ulp_mutex);
574                 rte_free(session);
575                 pthread_mutex_unlock(&bnxt_ulp_global_mutex);
576         }
577 }
578
579 /*
580  * Internal api to enable NAT feature.
581  * Set set_flag to 1 to set the value or zero to reset the value.
582  * returns 0 on success.
583  */
584 static int32_t
585 bnxt_ulp_global_cfg_update(struct bnxt *bp,
586                            enum tf_dir dir,
587                            enum tf_global_config_type type,
588                            uint32_t offset,
589                            uint32_t value,
590                            uint32_t set_flag)
591 {
592         uint32_t global_cfg = 0;
593         int rc;
594         struct tf_global_cfg_parms parms;
595
596         /* Initialize the params */
597         parms.dir = dir,
598         parms.type = type,
599         parms.offset = offset,
600         parms.config = (uint8_t *)&global_cfg,
601         parms.config_sz_in_bytes = sizeof(global_cfg);
602
603         rc = tf_get_global_cfg(&bp->tfp, &parms);
604         if (rc) {
605                 BNXT_TF_DBG(ERR, "Failed to get global cfg 0x%x rc:%d\n",
606                             type, rc);
607                 return rc;
608         }
609
610         if (set_flag)
611                 global_cfg |= value;
612         else
613                 global_cfg &= ~value;
614
615         /* SET the register RE_CFA_REG_ACT_TECT */
616         rc = tf_set_global_cfg(&bp->tfp, &parms);
617         if (rc) {
618                 BNXT_TF_DBG(ERR, "Failed to set global cfg 0x%x rc:%d\n",
619                             type, rc);
620                 return rc;
621         }
622         return rc;
623 }
624
625 /* Internal function to delete all the flows belonging to the given port */
626 static void
627 bnxt_ulp_flush_port_flows(struct bnxt *bp)
628 {
629         uint16_t func_id;
630
631         func_id = bnxt_get_fw_func_id(bp->eth_dev->data->port_id,
632                                       BNXT_ULP_INTF_TYPE_INVALID);
633         ulp_flow_db_function_flow_flush(bp->ulp_ctx, func_id);
634 }
635
636 /* Internal function to delete the VFR default flows */
637 static void
638 bnxt_ulp_destroy_vfr_default_rules(struct bnxt *bp, bool global)
639 {
640         struct bnxt_ulp_vfr_rule_info *info;
641         uint8_t port_id;
642         struct rte_eth_dev *vfr_eth_dev;
643         struct bnxt_vf_representor *vfr_bp;
644
645         if (!BNXT_TRUFLOW_EN(bp) || BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev))
646                 return;
647
648         if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
649                 return;
650
651         /* Delete default rules for all ports */
652         for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
653                 info = &bp->ulp_ctx->cfg_data->vfr_rule_info[port_id];
654                 if (!info->valid)
655                         continue;
656
657                 if (!global && info->parent_port_id !=
658                     bp->eth_dev->data->port_id)
659                         continue;
660
661                 /* Destroy the flows */
662                 ulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);
663                 ulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);
664                 /* Clean up the tx action pointer */
665                 vfr_eth_dev = &rte_eth_devices[port_id];
666                 if (vfr_eth_dev) {
667                         vfr_bp = vfr_eth_dev->data->dev_private;
668                         vfr_bp->vfr_tx_cfa_action = 0;
669                 }
670                 memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));
671         }
672 }
673
674 /*
675  * When a port is deinit'ed by dpdk. This function is called
676  * and this function clears the ULP context and rest of the
677  * infrastructure associated with it.
678  */
679 static void
680 bnxt_ulp_deinit(struct bnxt *bp,
681                 struct bnxt_ulp_session_state *session)
682 {
683         if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
684                 return;
685
686         /* clean up default flows */
687         bnxt_ulp_destroy_df_rules(bp, true);
688
689         /* clean up default VFR flows */
690         bnxt_ulp_destroy_vfr_default_rules(bp, true);
691
692         /* clean up regular flows */
693         ulp_flow_db_flush_flows(bp->ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE);
694
695         /* cleanup the eem table scope */
696         ulp_eem_tbl_scope_deinit(bp, bp->ulp_ctx);
697
698         /* cleanup the flow database */
699         ulp_flow_db_deinit(bp->ulp_ctx);
700
701         /* Delete the Mark database */
702         ulp_mark_db_deinit(bp->ulp_ctx);
703
704         /* cleanup the ulp mapper */
705         ulp_mapper_deinit(bp->ulp_ctx);
706
707         /* Delete the Flow Counter Manager */
708         ulp_fc_mgr_deinit(bp->ulp_ctx);
709
710         /* Delete the Port database */
711         ulp_port_db_deinit(bp->ulp_ctx);
712
713         /* Disable NAT feature */
714         (void)bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
715                                          TF_TUNNEL_ENCAP_NAT,
716                                          (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |
717                                           BNXT_ULP_NAT_INNER_L2_HEADER_DMAC),
718                                          0);
719
720         (void)bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
721                                          TF_TUNNEL_ENCAP_NAT,
722                                          (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |
723                                           BNXT_ULP_NAT_INNER_L2_HEADER_DMAC),
724                                          0);
725
726         /* Delete the ulp context and tf session and free the ulp context */
727         ulp_ctx_deinit(bp, session);
728         BNXT_TF_DBG(DEBUG, "ulp ctx has been deinitialized\n");
729 }
730
731 /*
732  * When a port is initialized by dpdk. This functions is called
733  * and this function initializes the ULP context and rest of the
734  * infrastructure associated with it.
735  */
736 static int32_t
737 bnxt_ulp_init(struct bnxt *bp,
738               struct bnxt_ulp_session_state *session)
739 {
740         int rc;
741
742         /* Allocate and Initialize the ulp context. */
743         rc = ulp_ctx_init(bp, session);
744         if (rc) {
745                 BNXT_TF_DBG(ERR, "Failed to create the ulp context\n");
746                 goto jump_to_error;
747         }
748
749         /* Initialize ulp dparms with values devargs passed */
750         rc = ulp_dparms_init(bp, bp->ulp_ctx);
751         if (rc) {
752                 BNXT_TF_DBG(ERR, "Failed to initialize the dparms\n");
753                 goto jump_to_error;
754         }
755
756         /* create the port database */
757         rc = ulp_port_db_init(bp->ulp_ctx, bp->port_cnt);
758         if (rc) {
759                 BNXT_TF_DBG(ERR, "Failed to create the port database\n");
760                 goto jump_to_error;
761         }
762
763         /* Create the Mark database. */
764         rc = ulp_mark_db_init(bp->ulp_ctx);
765         if (rc) {
766                 BNXT_TF_DBG(ERR, "Failed to create the mark database\n");
767                 goto jump_to_error;
768         }
769
770         /* Create the flow database. */
771         rc = ulp_flow_db_init(bp->ulp_ctx);
772         if (rc) {
773                 BNXT_TF_DBG(ERR, "Failed to create the flow database\n");
774                 goto jump_to_error;
775         }
776
777         /* Create the eem table scope. */
778         rc = ulp_eem_tbl_scope_init(bp);
779         if (rc) {
780                 BNXT_TF_DBG(ERR, "Failed to create the eem scope table\n");
781                 goto jump_to_error;
782         }
783
784         rc = ulp_mapper_init(bp->ulp_ctx);
785         if (rc) {
786                 BNXT_TF_DBG(ERR, "Failed to initialize ulp mapper\n");
787                 goto jump_to_error;
788         }
789
790         rc = ulp_fc_mgr_init(bp->ulp_ctx);
791         if (rc) {
792                 BNXT_TF_DBG(ERR, "Failed to initialize ulp flow counter mgr\n");
793                 goto jump_to_error;
794         }
795
796         /*
797          * Enable NAT feature. Set the global configuration register
798          * Tunnel encap to enable NAT with the reuse of existing inner
799          * L2 header smac and dmac
800          */
801         rc = bnxt_ulp_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP,
802                                         TF_TUNNEL_ENCAP_NAT,
803                                         (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |
804                                         BNXT_ULP_NAT_INNER_L2_HEADER_DMAC), 1);
805         if (rc) {
806                 BNXT_TF_DBG(ERR, "Failed to set rx global configuration\n");
807                 goto jump_to_error;
808         }
809
810         rc = bnxt_ulp_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP,
811                                         TF_TUNNEL_ENCAP_NAT,
812                                         (BNXT_ULP_NAT_INNER_L2_HEADER_SMAC |
813                                         BNXT_ULP_NAT_INNER_L2_HEADER_DMAC), 1);
814         if (rc) {
815                 BNXT_TF_DBG(ERR, "Failed to set tx global configuration\n");
816                 goto jump_to_error;
817         }
818         BNXT_TF_DBG(DEBUG, "ulp ctx has been initialized\n");
819         return rc;
820
821 jump_to_error:
822         bnxt_ulp_deinit(bp, session);
823         return rc;
824 }
825
826 /*
827  * When a port is initialized by dpdk. This functions sets up
828  * the port specific details.
829  */
830 int32_t
831 bnxt_ulp_port_init(struct bnxt *bp)
832 {
833         struct bnxt_ulp_session_state *session;
834         bool initialized;
835         int32_t rc = 0;
836
837         if (!bp || !BNXT_TRUFLOW_EN(bp))
838                 return rc;
839
840         if (!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {
841                 BNXT_TF_DBG(ERR,
842                             "Skip ulp init for port: %d, not a TVF or PF\n",
843                         bp->eth_dev->data->port_id);
844                 return rc;
845         }
846
847         if (bp->ulp_ctx) {
848                 BNXT_TF_DBG(DEBUG, "ulp ctx already allocated\n");
849                 return rc;
850         }
851
852         bp->ulp_ctx = rte_zmalloc("bnxt_ulp_ctx",
853                                   sizeof(struct bnxt_ulp_context), 0);
854         if (!bp->ulp_ctx) {
855                 BNXT_TF_DBG(ERR, "Failed to allocate ulp ctx\n");
856                 return -ENOMEM;
857         }
858
859         /*
860          * Multiple uplink ports can be associated with a single vswitch.
861          * Make sure only the port that is started first will initialize
862          * the TF session.
863          */
864         session = ulp_session_init(bp, &initialized);
865         if (!session) {
866                 BNXT_TF_DBG(ERR, "Failed to initialize the tf session\n");
867                 rc = -EIO;
868                 goto jump_to_error;
869         }
870
871         if (initialized) {
872                 /*
873                  * If ULP is already initialized for a specific domain then
874                  * simply assign the ulp context to this rte_eth_dev.
875                  */
876                 rc = ulp_ctx_attach(bp, session);
877                 if (rc) {
878                         BNXT_TF_DBG(ERR, "Failed to attach the ulp context\n");
879                         goto jump_to_error;
880                 }
881         } else {
882                 rc = bnxt_ulp_init(bp, session);
883                 if (rc) {
884                         BNXT_TF_DBG(ERR, "Failed to initialize the ulp init\n");
885                         goto jump_to_error;
886                 }
887         }
888
889         /* Update bnxt driver flags */
890         rc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx);
891         if (rc) {
892                 BNXT_TF_DBG(ERR, "Failed to update driver flags\n");
893                 goto jump_to_error;
894         }
895
896         /* update the port database for the given interface */
897         rc = ulp_port_db_dev_port_intf_update(bp->ulp_ctx, bp->eth_dev);
898         if (rc) {
899                 BNXT_TF_DBG(ERR, "Failed to update port database\n");
900                 goto jump_to_error;
901         }
902         /* create the default rules */
903         bnxt_ulp_create_df_rules(bp);
904         BNXT_TF_DBG(DEBUG, "ULP Port:%d created and initialized\n",
905                     bp->eth_dev->data->port_id);
906         return rc;
907
908 jump_to_error:
909         bnxt_ulp_port_deinit(bp);
910         return rc;
911 }
912
913 /*
914  * When a port is de-initialized by dpdk. This functions clears up
915  * the port specific details.
916  */
917 void
918 bnxt_ulp_port_deinit(struct bnxt *bp)
919 {
920         struct bnxt_ulp_session_state *session;
921         struct rte_pci_device *pci_dev;
922         struct rte_pci_addr *pci_addr;
923
924         if (!BNXT_TRUFLOW_EN(bp))
925                 return;
926
927         if (!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp)) {
928                 BNXT_TF_DBG(ERR,
929                             "Skip ULP deinit port:%d, not a TVF or PF\n",
930                             bp->eth_dev->data->port_id);
931                 return;
932         }
933
934         if (!bp->ulp_ctx) {
935                 BNXT_TF_DBG(DEBUG, "ulp ctx already de-allocated\n");
936                 return;
937         }
938
939         BNXT_TF_DBG(DEBUG, "ULP Port:%d destroyed\n",
940                     bp->eth_dev->data->port_id);
941
942         /* Get the session details  */
943         pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
944         pci_addr = &pci_dev->addr;
945         pthread_mutex_lock(&bnxt_ulp_global_mutex);
946         session = ulp_get_session(pci_addr);
947         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
948
949         /* session not found then just exit */
950         if (!session) {
951                 /* Free the ulp context */
952                 rte_free(bp->ulp_ctx);
953                 bp->ulp_ctx = NULL;
954                 return;
955         }
956
957         /* Check the reference count to deinit or deattach*/
958         if (bp->ulp_ctx->cfg_data && bp->ulp_ctx->cfg_data->ref_cnt) {
959                 bp->ulp_ctx->cfg_data->ref_cnt--;
960                 if (bp->ulp_ctx->cfg_data->ref_cnt) {
961                         /* free the port details */
962                         /* Free the default flow rule associated to this port */
963                         bnxt_ulp_destroy_df_rules(bp, false);
964                         bnxt_ulp_destroy_vfr_default_rules(bp, false);
965
966                         /* free flows associated with this port */
967                         bnxt_ulp_flush_port_flows(bp);
968
969                         /* close the session associated with this port */
970                         ulp_ctx_detach(bp);
971                 } else {
972                         /* Perform ulp ctx deinit */
973                         bnxt_ulp_deinit(bp, session);
974                 }
975         }
976
977         /* clean up the session */
978         ulp_session_deinit(session);
979
980         /* Free the ulp context */
981         rte_free(bp->ulp_ctx);
982         bp->ulp_ctx = NULL;
983 }
984
985 /* Below are the access functions to access internal data of ulp context. */
986 /* Function to set the Mark DB into the context */
987 int32_t
988 bnxt_ulp_cntxt_ptr2_mark_db_set(struct bnxt_ulp_context *ulp_ctx,
989                                 struct bnxt_ulp_mark_tbl *mark_tbl)
990 {
991         if (!ulp_ctx || !ulp_ctx->cfg_data) {
992                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
993                 return -EINVAL;
994         }
995
996         ulp_ctx->cfg_data->mark_tbl = mark_tbl;
997
998         return 0;
999 }
1000
1001 /* Function to retrieve the Mark DB from the context. */
1002 struct bnxt_ulp_mark_tbl *
1003 bnxt_ulp_cntxt_ptr2_mark_db_get(struct bnxt_ulp_context *ulp_ctx)
1004 {
1005         if (!ulp_ctx || !ulp_ctx->cfg_data)
1006                 return NULL;
1007
1008         return ulp_ctx->cfg_data->mark_tbl;
1009 }
1010
1011 /* Function to set the device id of the hardware. */
1012 int32_t
1013 bnxt_ulp_cntxt_dev_id_set(struct bnxt_ulp_context *ulp_ctx,
1014                           uint32_t dev_id)
1015 {
1016         if (ulp_ctx && ulp_ctx->cfg_data) {
1017                 ulp_ctx->cfg_data->dev_id = dev_id;
1018                 return 0;
1019         }
1020
1021         return -EINVAL;
1022 }
1023
1024 /* Function to get the device id of the hardware. */
1025 int32_t
1026 bnxt_ulp_cntxt_dev_id_get(struct bnxt_ulp_context *ulp_ctx,
1027                           uint32_t *dev_id)
1028 {
1029         if (ulp_ctx && ulp_ctx->cfg_data) {
1030                 *dev_id = ulp_ctx->cfg_data->dev_id;
1031                 return 0;
1032         }
1033
1034         return -EINVAL;
1035 }
1036
1037 /* Function to get the table scope id of the EEM table. */
1038 int32_t
1039 bnxt_ulp_cntxt_tbl_scope_id_get(struct bnxt_ulp_context *ulp_ctx,
1040                                 uint32_t *tbl_scope_id)
1041 {
1042         if (ulp_ctx && ulp_ctx->cfg_data) {
1043                 *tbl_scope_id = ulp_ctx->cfg_data->tbl_scope_id;
1044                 return 0;
1045         }
1046
1047         return -EINVAL;
1048 }
1049
1050 /* Function to set the table scope id of the EEM table. */
1051 int32_t
1052 bnxt_ulp_cntxt_tbl_scope_id_set(struct bnxt_ulp_context *ulp_ctx,
1053                                 uint32_t tbl_scope_id)
1054 {
1055         if (ulp_ctx && ulp_ctx->cfg_data) {
1056                 ulp_ctx->cfg_data->tbl_scope_id = tbl_scope_id;
1057                 return 0;
1058         }
1059
1060         return -EINVAL;
1061 }
1062
1063 /* Function to set the tfp session details from the ulp context. */
1064 int32_t
1065 bnxt_ulp_cntxt_tfp_set(struct bnxt_ulp_context *ulp, struct tf *tfp)
1066 {
1067         if (!ulp) {
1068                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
1069                 return -EINVAL;
1070         }
1071
1072         ulp->g_tfp = tfp;
1073         return 0;
1074 }
1075
1076 /* Function to get the tfp session details from the ulp context. */
1077 struct tf *
1078 bnxt_ulp_cntxt_tfp_get(struct bnxt_ulp_context *ulp)
1079 {
1080         if (!ulp) {
1081                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
1082                 return NULL;
1083         }
1084         return ulp->g_tfp;
1085 }
1086
1087 /*
1088  * Get the device table entry based on the device id.
1089  *
1090  * dev_id [in] The device id of the hardware
1091  *
1092  * Returns the pointer to the device parameters.
1093  */
1094 struct bnxt_ulp_device_params *
1095 bnxt_ulp_device_params_get(uint32_t dev_id)
1096 {
1097         if (dev_id < BNXT_ULP_MAX_NUM_DEVICES)
1098                 return &ulp_device_params[dev_id];
1099         return NULL;
1100 }
1101
1102 /* Function to set the flow database to the ulp context. */
1103 int32_t
1104 bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx,
1105                                 struct bnxt_ulp_flow_db *flow_db)
1106 {
1107         if (!ulp_ctx || !ulp_ctx->cfg_data)
1108                 return -EINVAL;
1109
1110         ulp_ctx->cfg_data->flow_db = flow_db;
1111         return 0;
1112 }
1113
1114 /* Function to get the flow database from the ulp context. */
1115 struct bnxt_ulp_flow_db *
1116 bnxt_ulp_cntxt_ptr2_flow_db_get(struct bnxt_ulp_context *ulp_ctx)
1117 {
1118         if (!ulp_ctx || !ulp_ctx->cfg_data)
1119                 return NULL;
1120
1121         return ulp_ctx->cfg_data->flow_db;
1122 }
1123
1124 /* Function to get the ulp context from eth device. */
1125 struct bnxt_ulp_context *
1126 bnxt_ulp_eth_dev_ptr2_cntxt_get(struct rte_eth_dev      *dev)
1127 {
1128         struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
1129
1130         if (BNXT_ETH_DEV_IS_REPRESENTOR(dev)) {
1131                 struct bnxt_vf_representor *vfr = dev->data->dev_private;
1132
1133                 bp = vfr->parent_dev->data->dev_private;
1134         }
1135
1136         if (!bp) {
1137                 BNXT_TF_DBG(ERR, "Bnxt private data is not initialized\n");
1138                 return NULL;
1139         }
1140         return bp->ulp_ctx;
1141 }
1142
1143 int32_t
1144 bnxt_ulp_cntxt_ptr2_mapper_data_set(struct bnxt_ulp_context *ulp_ctx,
1145                                     void *mapper_data)
1146 {
1147         if (!ulp_ctx || !ulp_ctx->cfg_data) {
1148                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
1149                 return -EINVAL;
1150         }
1151
1152         ulp_ctx->cfg_data->mapper_data = mapper_data;
1153         return 0;
1154 }
1155
1156 void *
1157 bnxt_ulp_cntxt_ptr2_mapper_data_get(struct bnxt_ulp_context *ulp_ctx)
1158 {
1159         if (!ulp_ctx || !ulp_ctx->cfg_data) {
1160                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
1161                 return NULL;
1162         }
1163
1164         return ulp_ctx->cfg_data->mapper_data;
1165 }
1166
1167 /* Function to set the port database to the ulp context. */
1168 int32_t
1169 bnxt_ulp_cntxt_ptr2_port_db_set(struct bnxt_ulp_context *ulp_ctx,
1170                                 struct bnxt_ulp_port_db *port_db)
1171 {
1172         if (!ulp_ctx || !ulp_ctx->cfg_data)
1173                 return -EINVAL;
1174
1175         ulp_ctx->cfg_data->port_db = port_db;
1176         return 0;
1177 }
1178
1179 /* Function to get the port database from the ulp context. */
1180 struct bnxt_ulp_port_db *
1181 bnxt_ulp_cntxt_ptr2_port_db_get(struct bnxt_ulp_context *ulp_ctx)
1182 {
1183         if (!ulp_ctx || !ulp_ctx->cfg_data)
1184                 return NULL;
1185
1186         return ulp_ctx->cfg_data->port_db;
1187 }
1188
1189 /* Function to set the flow counter info into the context */
1190 int32_t
1191 bnxt_ulp_cntxt_ptr2_fc_info_set(struct bnxt_ulp_context *ulp_ctx,
1192                                 struct bnxt_ulp_fc_info *ulp_fc_info)
1193 {
1194         if (!ulp_ctx || !ulp_ctx->cfg_data) {
1195                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
1196                 return -EINVAL;
1197         }
1198
1199         ulp_ctx->cfg_data->fc_info = ulp_fc_info;
1200
1201         return 0;
1202 }
1203
1204 /* Function to retrieve the flow counter info from the context. */
1205 struct bnxt_ulp_fc_info *
1206 bnxt_ulp_cntxt_ptr2_fc_info_get(struct bnxt_ulp_context *ulp_ctx)
1207 {
1208         if (!ulp_ctx || !ulp_ctx->cfg_data)
1209                 return NULL;
1210
1211         return ulp_ctx->cfg_data->fc_info;
1212 }
1213
1214 /* Function to get the ulp flags from the ulp context. */
1215 int32_t
1216 bnxt_ulp_cntxt_ptr2_ulp_flags_get(struct bnxt_ulp_context *ulp_ctx,
1217                                   uint32_t *flags)
1218 {
1219         if (!ulp_ctx || !ulp_ctx->cfg_data)
1220                 return -1;
1221
1222         *flags =  ulp_ctx->cfg_data->ulp_flags;
1223         return 0;
1224 }
1225
1226 /* Function to get the ulp vfr info from the ulp context. */
1227 struct bnxt_ulp_vfr_rule_info*
1228 bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(struct bnxt_ulp_context *ulp_ctx,
1229                                      uint32_t port_id)
1230 {
1231         if (!ulp_ctx || !ulp_ctx->cfg_data || port_id >= RTE_MAX_ETHPORTS)
1232                 return NULL;
1233
1234         return &ulp_ctx->cfg_data->vfr_rule_info[port_id];
1235 }