c67da6d762173eead8d10f825cf6b52f0fc410f3
[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         /* clean up regular flows */
521         ulp_flow_db_flush_flows(&bp->ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE);
522
523         /* cleanup the eem table scope */
524         ulp_eem_tbl_scope_deinit(bp, &bp->ulp_ctx);
525
526         /* cleanup the flow database */
527         ulp_flow_db_deinit(&bp->ulp_ctx);
528
529         /* Delete the Mark database */
530         ulp_mark_db_deinit(&bp->ulp_ctx);
531
532         /* Delete the ulp context and tf session */
533         ulp_ctx_detach(bp, session);
534
535         /* Finally delete the bnxt session*/
536         ulp_session_deinit(session);
537 }
538
539 /* Function to set the Mark DB into the context */
540 int32_t
541 bnxt_ulp_cntxt_ptr2_mark_db_set(struct bnxt_ulp_context *ulp_ctx,
542                                 struct bnxt_ulp_mark_tbl *mark_tbl)
543 {
544         if (!ulp_ctx || !ulp_ctx->cfg_data) {
545                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
546                 return -EINVAL;
547         }
548
549         ulp_ctx->cfg_data->mark_tbl = mark_tbl;
550
551         return 0;
552 }
553
554 /* Function to retrieve the Mark DB from the context. */
555 struct bnxt_ulp_mark_tbl *
556 bnxt_ulp_cntxt_ptr2_mark_db_get(struct bnxt_ulp_context *ulp_ctx)
557 {
558         if (!ulp_ctx || !ulp_ctx->cfg_data)
559                 return NULL;
560
561         return ulp_ctx->cfg_data->mark_tbl;
562 }
563
564 /* Function to set the device id of the hardware. */
565 int32_t
566 bnxt_ulp_cntxt_dev_id_set(struct bnxt_ulp_context *ulp_ctx,
567                           uint32_t dev_id)
568 {
569         if (ulp_ctx && ulp_ctx->cfg_data) {
570                 ulp_ctx->cfg_data->dev_id = dev_id;
571                 return 0;
572         }
573
574         return -EINVAL;
575 }
576
577 /* Function to get the device id of the hardware. */
578 int32_t
579 bnxt_ulp_cntxt_dev_id_get(struct bnxt_ulp_context *ulp_ctx,
580                           uint32_t *dev_id)
581 {
582         if (ulp_ctx && ulp_ctx->cfg_data) {
583                 *dev_id = ulp_ctx->cfg_data->dev_id;
584                 return 0;
585         }
586
587         return -EINVAL;
588 }
589
590 /* Function to get the table scope id of the EEM table. */
591 int32_t
592 bnxt_ulp_cntxt_tbl_scope_id_get(struct bnxt_ulp_context *ulp_ctx,
593                                 uint32_t *tbl_scope_id)
594 {
595         if (ulp_ctx && ulp_ctx->cfg_data) {
596                 *tbl_scope_id = ulp_ctx->cfg_data->tbl_scope_id;
597                 return 0;
598         }
599
600         return -EINVAL;
601 }
602
603 /* Function to set the table scope id of the EEM table. */
604 int32_t
605 bnxt_ulp_cntxt_tbl_scope_id_set(struct bnxt_ulp_context *ulp_ctx,
606                                 uint32_t tbl_scope_id)
607 {
608         if (ulp_ctx && ulp_ctx->cfg_data) {
609                 ulp_ctx->cfg_data->tbl_scope_id = tbl_scope_id;
610                 return 0;
611         }
612
613         return -EINVAL;
614 }
615
616 /* Function to set the tfp session details from the ulp context. */
617 int32_t
618 bnxt_ulp_cntxt_tfp_set(struct bnxt_ulp_context *ulp, struct tf *tfp)
619 {
620         if (!ulp) {
621                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
622                 return -EINVAL;
623         }
624
625         /* TBD The tfp should be removed once tf_attach is implemented. */
626         ulp->g_tfp = tfp;
627         return 0;
628 }
629
630 /* Function to get the tfp session details from the ulp context. */
631 struct tf *
632 bnxt_ulp_cntxt_tfp_get(struct bnxt_ulp_context *ulp)
633 {
634         if (!ulp) {
635                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
636                 return NULL;
637         }
638         /* TBD The tfp should be removed once tf_attach is implemented. */
639         return ulp->g_tfp;
640 }
641
642 /*
643  * Get the device table entry based on the device id.
644  *
645  * dev_id [in] The device id of the hardware
646  *
647  * Returns the pointer to the device parameters.
648  */
649 struct bnxt_ulp_device_params *
650 bnxt_ulp_device_params_get(uint32_t dev_id)
651 {
652         if (dev_id < BNXT_ULP_MAX_NUM_DEVICES)
653                 return &ulp_device_params[dev_id];
654         return NULL;
655 }
656
657 /* Function to set the flow database to the ulp context. */
658 int32_t
659 bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx,
660                                 struct bnxt_ulp_flow_db *flow_db)
661 {
662         if (!ulp_ctx || !ulp_ctx->cfg_data)
663                 return -EINVAL;
664
665         ulp_ctx->cfg_data->flow_db = flow_db;
666         return 0;
667 }
668
669 /* Function to get the flow database from the ulp context. */
670 struct bnxt_ulp_flow_db *
671 bnxt_ulp_cntxt_ptr2_flow_db_get(struct bnxt_ulp_context *ulp_ctx)
672 {
673         if (!ulp_ctx || !ulp_ctx->cfg_data)
674                 return NULL;
675
676         return ulp_ctx->cfg_data->flow_db;
677 }
678
679 /* Function to get the ulp context from eth device. */
680 struct bnxt_ulp_context *
681 bnxt_ulp_eth_dev_ptr2_cntxt_get(struct rte_eth_dev      *dev)
682 {
683         struct bnxt     *bp;
684
685         bp = (struct bnxt *)dev->data->dev_private;
686         if (!bp) {
687                 BNXT_TF_DBG(ERR, "Bnxt private data is not initialized\n");
688                 return NULL;
689         }
690         return &bp->ulp_ctx;
691 }