3795c6db60ffe680bf5ecc0c4f22a262ef151be5
[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_ulp.h"
13 #include "bnxt_tf_common.h"
14 #include "bnxt.h"
15 #include "tf_core.h"
16 #include "tf_ext_flow_handle.h"
17
18 #include "ulp_template_db.h"
19 #include "ulp_template_struct.h"
20 #include "ulp_mark_mgr.h"
21 #include "ulp_flow_db.h"
22
23 /* Linked list of all TF sessions. */
24 STAILQ_HEAD(, bnxt_ulp_session_state) bnxt_ulp_session_list =
25                         STAILQ_HEAD_INITIALIZER(bnxt_ulp_session_list);
26
27 /* Mutex to synchronize bnxt_ulp_session_list operations. */
28 static pthread_mutex_t bnxt_ulp_global_mutex = PTHREAD_MUTEX_INITIALIZER;
29
30 /*
31  * Allow the deletion of context only for the bnxt device that
32  * created the session
33  * TBD - The implementation of the function should change to
34  * using the reference count once tf_session_attach functionality
35  * is fixed.
36  */
37 bool
38 ulp_ctx_deinit_allowed(void *ptr)
39 {
40         struct bnxt *bp = (struct bnxt *)ptr;
41
42         if (!bp)
43                 return 0;
44
45         if (&bp->tfp == bp->ulp_ctx.g_tfp)
46                 return 1;
47
48         return 0;
49 }
50
51 /*
52  * Initialize an ULP session.
53  * An ULP session will contain all the resources needed to support rte flow
54  * offloads. A session is initialized as part of rte_eth_device start.
55  * A single vswitch instance can have multiple uplinks which means
56  * rte_eth_device start will be called for each of these devices.
57  * ULP session manager will make sure that a single ULP session is only
58  * initialized once. Apart from this, it also initializes MARK database,
59  * EEM table & flow database. ULP session manager also manages a list of
60  * all opened ULP sessions.
61  */
62 static int32_t
63 ulp_ctx_session_open(struct bnxt *bp,
64                      struct bnxt_ulp_session_state *session)
65 {
66         struct rte_eth_dev              *ethdev = bp->eth_dev;
67         int32_t                         rc = 0;
68         struct tf_open_session_parms    params;
69
70         memset(&params, 0, sizeof(params));
71
72         rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id,
73                                           params.ctrl_chan_name);
74         if (rc) {
75                 BNXT_TF_DBG(ERR, "Invalid port %d, rc = %d\n",
76                             ethdev->data->port_id, rc);
77                 return rc;
78         }
79
80         rc = tf_open_session(&bp->tfp, &params);
81         if (rc) {
82                 BNXT_TF_DBG(ERR, "Failed to open TF session - %s, rc = %d\n",
83                             params.ctrl_chan_name, rc);
84                 return -EINVAL;
85         }
86         session->session_opened = 1;
87         session->g_tfp = &bp->tfp;
88         return rc;
89 }
90
91 /*
92  * Close the ULP session.
93  * It takes the ulp context pointer.
94  */
95 static void
96 ulp_ctx_session_close(struct bnxt *bp,
97                       struct bnxt_ulp_session_state *session)
98 {
99         /* close the session in the hardware */
100         if (session->session_opened)
101                 tf_close_session(&bp->tfp);
102         session->session_opened = 0;
103         session->g_tfp = NULL;
104         bp->ulp_ctx.g_tfp = NULL;
105 }
106
107 static void
108 bnxt_init_tbl_scope_parms(struct bnxt *bp,
109                           struct tf_alloc_tbl_scope_parms *params)
110 {
111         struct bnxt_ulp_device_params   *dparms;
112         uint32_t dev_id;
113         int rc;
114
115         rc = bnxt_ulp_cntxt_dev_id_get(&bp->ulp_ctx, &dev_id);
116         if (rc)
117                 /* TBD: For now, just use default. */
118                 dparms = 0;
119         else
120                 dparms = bnxt_ulp_device_params_get(dev_id);
121
122         if (!dparms) {
123                 params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
124                 params->rx_max_action_entry_sz_in_bits =
125                         BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
126                 params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
127                 params->rx_num_flows_in_k = BNXT_ULP_RX_NUM_FLOWS;
128                 params->rx_tbl_if_id = BNXT_ULP_RX_TBL_IF_ID;
129
130                 params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
131                 params->tx_max_action_entry_sz_in_bits =
132                         BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
133                 params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
134                 params->tx_num_flows_in_k = BNXT_ULP_TX_NUM_FLOWS;
135                 params->tx_tbl_if_id = BNXT_ULP_TX_TBL_IF_ID;
136         } else {
137                 params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
138                 params->rx_max_action_entry_sz_in_bits =
139                         BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
140                 params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
141                 params->rx_num_flows_in_k = dparms->num_flows / (1024);
142                 params->rx_tbl_if_id = BNXT_ULP_RX_TBL_IF_ID;
143
144                 params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
145                 params->tx_max_action_entry_sz_in_bits =
146                         BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
147                 params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
148                 params->tx_num_flows_in_k = dparms->num_flows / (1024);
149                 params->tx_tbl_if_id = BNXT_ULP_TX_TBL_IF_ID;
150         }
151 }
152
153 /* Initialize Extended Exact Match host memory. */
154 static int32_t
155 ulp_eem_tbl_scope_init(struct bnxt *bp)
156 {
157         struct tf_alloc_tbl_scope_parms params = {0};
158         int rc;
159
160         bnxt_init_tbl_scope_parms(bp, &params);
161
162         rc = tf_alloc_tbl_scope(&bp->tfp, &params);
163         if (rc) {
164                 BNXT_TF_DBG(ERR, "Unable to allocate eem table scope rc = %d\n",
165                             rc);
166                 return rc;
167         }
168
169         rc = bnxt_ulp_cntxt_tbl_scope_id_set(&bp->ulp_ctx, params.tbl_scope_id);
170         if (rc) {
171                 BNXT_TF_DBG(ERR, "Unable to set table scope id\n");
172                 return rc;
173         }
174
175         return 0;
176 }
177
178 /* Free Extended Exact Match host memory */
179 static int32_t
180 ulp_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)
181 {
182         struct tf_free_tbl_scope_parms  params = {0};
183         struct tf                       *tfp;
184         int32_t                         rc = 0;
185
186         if (!ulp_ctx || !ulp_ctx->cfg_data)
187                 return -EINVAL;
188
189         /* Free the resources for the last device */
190         if (!ulp_ctx_deinit_allowed(bp))
191                 return rc;
192
193         tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
194         if (!tfp) {
195                 BNXT_TF_DBG(ERR, "Failed to get the truflow pointer\n");
196                 return -EINVAL;
197         }
198
199         rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp_ctx, &params.tbl_scope_id);
200         if (rc) {
201                 BNXT_TF_DBG(ERR, "Failed to get the table scope id\n");
202                 return -EINVAL;
203         }
204
205         rc = tf_free_tbl_scope(tfp, &params);
206         if (rc) {
207                 BNXT_TF_DBG(ERR, "Unable to free table scope\n");
208                 return -EINVAL;
209         }
210         return rc;
211 }
212
213 /* The function to free and deinit the ulp context data. */
214 static int32_t
215 ulp_ctx_deinit(struct bnxt *bp,
216                struct bnxt_ulp_session_state *session)
217 {
218         if (!session || !bp) {
219                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
220                 return -EINVAL;
221         }
222
223         /* close the tf session */
224         ulp_ctx_session_close(bp, session);
225
226         /* Free the contents */
227         if (session->cfg_data) {
228                 rte_free(session->cfg_data);
229                 bp->ulp_ctx.cfg_data = NULL;
230                 session->cfg_data = NULL;
231         }
232         return 0;
233 }
234
235 /* The function to allocate and initialize the ulp context data. */
236 static int32_t
237 ulp_ctx_init(struct bnxt *bp,
238              struct bnxt_ulp_session_state *session)
239 {
240         struct bnxt_ulp_data    *ulp_data;
241         int32_t                 rc = 0;
242
243         if (!session || !bp) {
244                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
245                 return -EINVAL;
246         }
247
248         /* Allocate memory to hold ulp context data. */
249         ulp_data = rte_zmalloc("bnxt_ulp_data",
250                                sizeof(struct bnxt_ulp_data), 0);
251         if (!ulp_data) {
252                 BNXT_TF_DBG(ERR, "Failed to allocate memory for ulp data\n");
253                 return -ENOMEM;
254         }
255
256         /* Increment the ulp context data reference count usage. */
257         bp->ulp_ctx.cfg_data = ulp_data;
258         session->cfg_data = ulp_data;
259         ulp_data->ref_cnt++;
260
261         /* Open the ulp session. */
262         rc = ulp_ctx_session_open(bp, session);
263         if (rc) {
264                 (void)ulp_ctx_deinit(bp, session);
265                 return rc;
266         }
267         bnxt_ulp_cntxt_tfp_set(&bp->ulp_ctx, session->g_tfp);
268         return rc;
269 }
270
271 static int32_t
272 ulp_ctx_attach(struct bnxt_ulp_context *ulp_ctx,
273                struct bnxt_ulp_session_state *session)
274 {
275         if (!ulp_ctx || !session) {
276                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
277                 return -EINVAL;
278         }
279
280         /* Increment the ulp context data reference count usage. */
281         ulp_ctx->cfg_data = session->cfg_data;
282         ulp_ctx->cfg_data->ref_cnt++;
283
284         /* TBD call TF_session_attach. */
285         ulp_ctx->g_tfp = session->g_tfp;
286         return 0;
287 }
288
289 static int32_t
290 ulp_ctx_detach(struct bnxt *bp,
291                struct bnxt_ulp_session_state *session)
292 {
293         struct bnxt_ulp_context *ulp_ctx;
294
295         if (!bp || !session) {
296                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
297                 return -EINVAL;
298         }
299         ulp_ctx = &bp->ulp_ctx;
300
301         if (!ulp_ctx->cfg_data)
302                 return 0;
303
304         /* TBD call TF_session_detach */
305
306         /* Increment the ulp context data reference count usage. */
307         if (ulp_ctx->cfg_data->ref_cnt >= 1) {
308                 ulp_ctx->cfg_data->ref_cnt--;
309                 if (ulp_ctx_deinit_allowed(bp))
310                         ulp_ctx_deinit(bp, session);
311                 ulp_ctx->cfg_data = NULL;
312                 ulp_ctx->g_tfp = NULL;
313                 return 0;
314         }
315         BNXT_TF_DBG(ERR, "context deatach on invalid data\n");
316         return 0;
317 }
318
319 /*
320  * Initialize the state of an ULP session.
321  * If the state of an ULP session is not initialized, set it's state to
322  * initialized. If the state is already initialized, do nothing.
323  */
324 static void
325 ulp_context_initialized(struct bnxt_ulp_session_state *session, bool *init)
326 {
327         pthread_mutex_lock(&session->bnxt_ulp_mutex);
328
329         if (!session->bnxt_ulp_init) {
330                 session->bnxt_ulp_init = true;
331                 *init = false;
332         } else {
333                 *init = true;
334         }
335
336         pthread_mutex_unlock(&session->bnxt_ulp_mutex);
337 }
338
339 /*
340  * Check if an ULP session is already allocated for a specific PCI
341  * domain & bus. If it is already allocated simply return the session
342  * pointer, otherwise allocate a new session.
343  */
344 static struct bnxt_ulp_session_state *
345 ulp_get_session(struct rte_pci_addr *pci_addr)
346 {
347         struct bnxt_ulp_session_state *session;
348
349         STAILQ_FOREACH(session, &bnxt_ulp_session_list, next) {
350                 if (session->pci_info.domain == pci_addr->domain &&
351                     session->pci_info.bus == pci_addr->bus) {
352                         return session;
353                 }
354         }
355         return NULL;
356 }
357
358 /*
359  * Allocate and Initialize an ULP session and set it's state to INITIALIZED.
360  * If it's already initialized simply return the already existing session.
361  */
362 static struct bnxt_ulp_session_state *
363 ulp_session_init(struct bnxt *bp,
364                  bool *init)
365 {
366         struct rte_pci_device           *pci_dev;
367         struct rte_pci_addr             *pci_addr;
368         struct bnxt_ulp_session_state   *session;
369
370         if (!bp)
371                 return NULL;
372
373         pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
374         pci_addr = &pci_dev->addr;
375
376         pthread_mutex_lock(&bnxt_ulp_global_mutex);
377
378         session = ulp_get_session(pci_addr);
379         if (!session) {
380                 /* Not Found the session  Allocate a new one */
381                 session = rte_zmalloc("bnxt_ulp_session",
382                                       sizeof(struct bnxt_ulp_session_state),
383                                       0);
384                 if (!session) {
385                         BNXT_TF_DBG(ERR,
386                                     "Allocation failed for bnxt_ulp_session\n");
387                         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
388                         return NULL;
389
390                 } else {
391                         /* Add it to the queue */
392                         session->pci_info.domain = pci_addr->domain;
393                         session->pci_info.bus = pci_addr->bus;
394                         pthread_mutex_init(&session->bnxt_ulp_mutex, NULL);
395                         STAILQ_INSERT_TAIL(&bnxt_ulp_session_list,
396                                            session, next);
397                 }
398         }
399         ulp_context_initialized(session, init);
400         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
401         return session;
402 }
403
404 /*
405  * When a device is closed, remove it's associated session from the global
406  * session list.
407  */
408 static void
409 ulp_session_deinit(struct bnxt_ulp_session_state *session)
410 {
411         if (!session)
412                 return;
413
414         if (!session->cfg_data) {
415                 pthread_mutex_lock(&bnxt_ulp_global_mutex);
416                 STAILQ_REMOVE(&bnxt_ulp_session_list, session,
417                               bnxt_ulp_session_state, next);
418                 pthread_mutex_destroy(&session->bnxt_ulp_mutex);
419                 rte_free(session);
420                 pthread_mutex_unlock(&bnxt_ulp_global_mutex);
421         }
422 }
423
424 /*
425  * When a port is initialized by dpdk. This functions is called
426  * and this function initializes the ULP context and rest of the
427  * infrastructure associated with it.
428  */
429 int32_t
430 bnxt_ulp_init(struct bnxt *bp)
431 {
432         struct bnxt_ulp_session_state *session;
433         bool init;
434         int rc;
435
436         /*
437          * Multiple uplink ports can be associated with a single vswitch.
438          * Make sure only the port that is started first will initialize
439          * the TF session.
440          */
441         session = ulp_session_init(bp, &init);
442         if (!session) {
443                 BNXT_TF_DBG(ERR, "Failed to initialize the tf session\n");
444                 return -EINVAL;
445         }
446
447         /*
448          * If ULP is already initialized for a specific domain then simply
449          * assign the ulp context to this rte_eth_dev.
450          */
451         if (init) {
452                 rc = ulp_ctx_attach(&bp->ulp_ctx, session);
453                 if (rc) {
454                         BNXT_TF_DBG(ERR,
455                                     "Failed to attach the ulp context\n");
456                 }
457                 return rc;
458         }
459
460         /* Allocate and Initialize the ulp context. */
461         rc = ulp_ctx_init(bp, session);
462         if (rc) {
463                 BNXT_TF_DBG(ERR, "Failed to create the ulp context\n");
464                 goto jump_to_error;
465         }
466
467         /* Create the Mark database. */
468         rc = ulp_mark_db_init(&bp->ulp_ctx);
469         if (rc) {
470                 BNXT_TF_DBG(ERR, "Failed to create the mark database\n");
471                 goto jump_to_error;
472         }
473
474         /* Create the flow database. */
475         rc = ulp_flow_db_init(&bp->ulp_ctx);
476         if (rc) {
477                 BNXT_TF_DBG(ERR, "Failed to create the flow database\n");
478                 goto jump_to_error;
479         }
480
481         /* Create the eem table scope. */
482         rc = ulp_eem_tbl_scope_init(bp);
483         if (rc) {
484                 BNXT_TF_DBG(ERR, "Failed to create the eem scope table\n");
485                 goto jump_to_error;
486         }
487
488         return rc;
489
490 jump_to_error:
491         bnxt_ulp_deinit(bp);
492         return -ENOMEM;
493 }
494
495 /* Below are the access functions to access internal data of ulp context. */
496
497 /*
498  * When a port is deinit'ed by dpdk. This function is called
499  * and this function clears the ULP context and rest of the
500  * infrastructure associated with it.
501  */
502 void
503 bnxt_ulp_deinit(struct bnxt *bp)
504 {
505         struct bnxt_ulp_session_state   *session;
506         struct rte_pci_device           *pci_dev;
507         struct rte_pci_addr             *pci_addr;
508
509         /* Get the session first */
510         pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
511         pci_addr = &pci_dev->addr;
512         pthread_mutex_lock(&bnxt_ulp_global_mutex);
513         session = ulp_get_session(pci_addr);
514         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
515
516         /* session not found then just exit */
517         if (!session)
518                 return;
519
520         /* cleanup the eem table scope */
521         ulp_eem_tbl_scope_deinit(bp, &bp->ulp_ctx);
522
523         /* cleanup the flow database */
524         ulp_flow_db_deinit(&bp->ulp_ctx);
525
526         /* Delete the Mark database */
527         ulp_mark_db_deinit(&bp->ulp_ctx);
528
529         /* Delete the ulp context and tf session */
530         ulp_ctx_detach(bp, session);
531
532         /* Finally delete the bnxt session*/
533         ulp_session_deinit(session);
534 }
535
536 /* Function to set the Mark DB into the context */
537 int32_t
538 bnxt_ulp_cntxt_ptr2_mark_db_set(struct bnxt_ulp_context *ulp_ctx,
539                                 struct bnxt_ulp_mark_tbl *mark_tbl)
540 {
541         if (!ulp_ctx || !ulp_ctx->cfg_data) {
542                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
543                 return -EINVAL;
544         }
545
546         ulp_ctx->cfg_data->mark_tbl = mark_tbl;
547
548         return 0;
549 }
550
551 /* Function to retrieve the Mark DB from the context. */
552 struct bnxt_ulp_mark_tbl *
553 bnxt_ulp_cntxt_ptr2_mark_db_get(struct bnxt_ulp_context *ulp_ctx)
554 {
555         if (!ulp_ctx || !ulp_ctx->cfg_data)
556                 return NULL;
557
558         return ulp_ctx->cfg_data->mark_tbl;
559 }
560
561 /* Function to set the device id of the hardware. */
562 int32_t
563 bnxt_ulp_cntxt_dev_id_set(struct bnxt_ulp_context *ulp_ctx,
564                           uint32_t dev_id)
565 {
566         if (ulp_ctx && ulp_ctx->cfg_data) {
567                 ulp_ctx->cfg_data->dev_id = dev_id;
568                 return 0;
569         }
570
571         return -EINVAL;
572 }
573
574 /* Function to get the device id of the hardware. */
575 int32_t
576 bnxt_ulp_cntxt_dev_id_get(struct bnxt_ulp_context *ulp_ctx,
577                           uint32_t *dev_id)
578 {
579         if (ulp_ctx && ulp_ctx->cfg_data) {
580                 *dev_id = ulp_ctx->cfg_data->dev_id;
581                 return 0;
582         }
583
584         return -EINVAL;
585 }
586
587 /* Function to get the table scope id of the EEM table. */
588 int32_t
589 bnxt_ulp_cntxt_tbl_scope_id_get(struct bnxt_ulp_context *ulp_ctx,
590                                 uint32_t *tbl_scope_id)
591 {
592         if (ulp_ctx && ulp_ctx->cfg_data) {
593                 *tbl_scope_id = ulp_ctx->cfg_data->tbl_scope_id;
594                 return 0;
595         }
596
597         return -EINVAL;
598 }
599
600 /* Function to set the table scope id of the EEM table. */
601 int32_t
602 bnxt_ulp_cntxt_tbl_scope_id_set(struct bnxt_ulp_context *ulp_ctx,
603                                 uint32_t tbl_scope_id)
604 {
605         if (ulp_ctx && ulp_ctx->cfg_data) {
606                 ulp_ctx->cfg_data->tbl_scope_id = tbl_scope_id;
607                 return 0;
608         }
609
610         return -EINVAL;
611 }
612
613 /* Function to set the tfp session details from the ulp context. */
614 int32_t
615 bnxt_ulp_cntxt_tfp_set(struct bnxt_ulp_context *ulp, struct tf *tfp)
616 {
617         if (!ulp) {
618                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
619                 return -EINVAL;
620         }
621
622         /* TBD The tfp should be removed once tf_attach is implemented. */
623         ulp->g_tfp = tfp;
624         return 0;
625 }
626
627 /* Function to get the tfp session details from the ulp context. */
628 struct tf *
629 bnxt_ulp_cntxt_tfp_get(struct bnxt_ulp_context *ulp)
630 {
631         if (!ulp) {
632                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
633                 return NULL;
634         }
635         /* TBD The tfp should be removed once tf_attach is implemented. */
636         return ulp->g_tfp;
637 }
638
639 /*
640  * Get the device table entry based on the device id.
641  *
642  * dev_id [in] The device id of the hardware
643  *
644  * Returns the pointer to the device parameters.
645  */
646 struct bnxt_ulp_device_params *
647 bnxt_ulp_device_params_get(uint32_t dev_id)
648 {
649         if (dev_id < BNXT_ULP_MAX_NUM_DEVICES)
650                 return &ulp_device_params[dev_id];
651         return NULL;
652 }
653
654 /* Function to set the flow database to the ulp context. */
655 int32_t
656 bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx,
657                                 struct bnxt_ulp_flow_db *flow_db)
658 {
659         if (!ulp_ctx || !ulp_ctx->cfg_data) {
660                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
661                 return -EINVAL;
662         }
663
664         ulp_ctx->cfg_data->flow_db = flow_db;
665         return 0;
666 }
667
668 /* Function to get the flow database from the ulp context. */
669 struct bnxt_ulp_flow_db *
670 bnxt_ulp_cntxt_ptr2_flow_db_get(struct bnxt_ulp_context *ulp_ctx)
671 {
672         if (!ulp_ctx || !ulp_ctx->cfg_data) {
673                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
674                 return NULL;
675         }
676
677         return ulp_ctx->cfg_data->flow_db;
678 }
679
680 /* Function to get the ulp context from eth device. */
681 struct bnxt_ulp_context *
682 bnxt_ulp_eth_dev_ptr2_cntxt_get(struct rte_eth_dev      *dev)
683 {
684         struct bnxt     *bp;
685
686         bp = (struct bnxt *)dev->data->dev_private;
687         if (!bp) {
688                 BNXT_TF_DBG(ERR, "Bnxt private data is not initialized\n");
689                 return NULL;
690         }
691         return &bp->ulp_ctx;
692 }