net/bnxt: integrate with the latest TF core changes
[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_enum.h"
19 #include "ulp_template_struct.h"
20 #include "ulp_mark_mgr.h"
21 #include "ulp_flow_db.h"
22 #include "ulp_mapper.h"
23 #include "ulp_port_db.h"
24
25 /* Linked list of all TF sessions. */
26 STAILQ_HEAD(, bnxt_ulp_session_state) bnxt_ulp_session_list =
27                         STAILQ_HEAD_INITIALIZER(bnxt_ulp_session_list);
28
29 /* Mutex to synchronize bnxt_ulp_session_list operations. */
30 static pthread_mutex_t bnxt_ulp_global_mutex = PTHREAD_MUTEX_INITIALIZER;
31
32 /*
33  * Allow the deletion of context only for the bnxt device that
34  * created the session
35  * TBD - The implementation of the function should change to
36  * using the reference count once tf_session_attach functionality
37  * is fixed.
38  */
39 bool
40 ulp_ctx_deinit_allowed(void *ptr)
41 {
42         struct bnxt *bp = (struct bnxt *)ptr;
43
44         if (!bp)
45                 return 0;
46
47         if (&bp->tfp == bp->ulp_ctx->g_tfp)
48                 return 1;
49
50         return 0;
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 = false;
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] = 16;
89         resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_WC_PROF] = 8;
90         resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_PROF_FUNC] = 8;
91         resources->ident_cnt[TF_DIR_RX].cnt[TF_IDENT_TYPE_EM_PROF] = 8;
92
93         /* Table Types */
94         resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_FULL_ACT_RECORD] = 720;
95         resources->tbl_cnt[TF_DIR_RX].cnt[TF_TBL_TYPE_ACT_STATS_64] = 720;
96
97         /* TCAMs */
98         resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM] = 16;
99         resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_PROF_TCAM] = 8;
100         resources->tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] = 416;
101
102         /* EM */
103         resources->em_cnt[TF_DIR_RX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 2048;
104
105         /** TX **/
106         /* Identifiers */
107         resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_L2_CTXT] = 8;
108         resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_WC_PROF] = 8;
109         resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_PROF_FUNC] = 8;
110         resources->ident_cnt[TF_DIR_TX].cnt[TF_IDENT_TYPE_EM_PROF] = 8;
111
112         /* Table Types */
113         resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_FULL_ACT_RECORD] = 16;
114         resources->tbl_cnt[TF_DIR_TX].cnt[TF_TBL_TYPE_ACT_STATS_64] = 16;
115
116         /* TCAMs */
117         resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_L2_CTXT_TCAM] = 8;
118         resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_PROF_TCAM] = 8;
119         resources->tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] = 8;
120
121         /* EM */
122         resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_EM_RECORD] = 8;
123
124         /* EEM */
125         resources->em_cnt[TF_DIR_RX].cnt[TF_EM_TBL_TYPE_TBL_SCOPE] = 1;
126         resources->em_cnt[TF_DIR_TX].cnt[TF_EM_TBL_TYPE_TBL_SCOPE] = 1;
127
128         rc = tf_open_session(&bp->tfp, &params);
129         if (rc) {
130                 BNXT_TF_DBG(ERR, "Failed to open TF session - %s, rc = %d\n",
131                             params.ctrl_chan_name, rc);
132                 return -EINVAL;
133         }
134         session->session_opened = 1;
135         session->g_tfp = &bp->tfp;
136         return rc;
137 }
138
139 /*
140  * Close the ULP session.
141  * It takes the ulp context pointer.
142  */
143 static void
144 ulp_ctx_session_close(struct bnxt *bp,
145                       struct bnxt_ulp_session_state *session)
146 {
147         /* close the session in the hardware */
148         if (session->session_opened)
149                 tf_close_session(&bp->tfp);
150         session->session_opened = 0;
151         session->g_tfp = NULL;
152         bp->ulp_ctx->g_tfp = NULL;
153 }
154
155 static void
156 bnxt_init_tbl_scope_parms(struct bnxt *bp,
157                           struct tf_alloc_tbl_scope_parms *params)
158 {
159         struct bnxt_ulp_device_params   *dparms;
160         uint32_t dev_id;
161         int rc;
162
163         rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id);
164         if (rc)
165                 /* TBD: For now, just use default. */
166                 dparms = 0;
167         else
168                 dparms = bnxt_ulp_device_params_get(dev_id);
169
170         /*
171          * Set the flush timer for EEM entries. The value is in 100ms intervals,
172          * so 100 is 10s.
173          */
174         params->hw_flow_cache_flush_timer = 100;
175
176         if (!dparms) {
177                 params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
178                 params->rx_max_action_entry_sz_in_bits =
179                         BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
180                 params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
181                 params->rx_num_flows_in_k = BNXT_ULP_RX_NUM_FLOWS;
182                 params->rx_tbl_if_id = BNXT_ULP_RX_TBL_IF_ID;
183
184                 params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
185                 params->tx_max_action_entry_sz_in_bits =
186                         BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
187                 params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
188                 params->tx_num_flows_in_k = BNXT_ULP_TX_NUM_FLOWS;
189                 params->tx_tbl_if_id = BNXT_ULP_TX_TBL_IF_ID;
190         } else {
191                 params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY;
192                 params->rx_max_action_entry_sz_in_bits =
193                         BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY;
194                 params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM;
195                 params->rx_num_flows_in_k = dparms->flow_db_num_entries / 1024;
196                 params->rx_tbl_if_id = BNXT_ULP_RX_TBL_IF_ID;
197
198                 params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY;
199                 params->tx_max_action_entry_sz_in_bits =
200                         BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY;
201                 params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM;
202                 params->tx_num_flows_in_k = dparms->flow_db_num_entries / 1024;
203                 params->tx_tbl_if_id = BNXT_ULP_TX_TBL_IF_ID;
204         }
205 }
206
207 /* Initialize Extended Exact Match host memory. */
208 static int32_t
209 ulp_eem_tbl_scope_init(struct bnxt *bp)
210 {
211         struct tf_alloc_tbl_scope_parms params = {0};
212         int rc;
213
214         bnxt_init_tbl_scope_parms(bp, &params);
215
216         rc = tf_alloc_tbl_scope(&bp->tfp, &params);
217         if (rc) {
218                 BNXT_TF_DBG(ERR, "Unable to allocate eem table scope rc = %d\n",
219                             rc);
220                 return rc;
221         }
222
223         rc = bnxt_ulp_cntxt_tbl_scope_id_set(bp->ulp_ctx, params.tbl_scope_id);
224         if (rc) {
225                 BNXT_TF_DBG(ERR, "Unable to set table scope id\n");
226                 return rc;
227         }
228
229         return 0;
230 }
231
232 /* Free Extended Exact Match host memory */
233 static int32_t
234 ulp_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx)
235 {
236         struct tf_free_tbl_scope_parms  params = {0};
237         struct tf                       *tfp;
238         int32_t                         rc = 0;
239
240         if (!ulp_ctx || !ulp_ctx->cfg_data)
241                 return -EINVAL;
242
243         /* Free the resources for the last device */
244         if (!ulp_ctx_deinit_allowed(bp))
245                 return rc;
246
247         tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
248         if (!tfp) {
249                 BNXT_TF_DBG(ERR, "Failed to get the truflow pointer\n");
250                 return -EINVAL;
251         }
252
253         rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp_ctx, &params.tbl_scope_id);
254         if (rc) {
255                 BNXT_TF_DBG(ERR, "Failed to get the table scope id\n");
256                 return -EINVAL;
257         }
258
259         rc = tf_free_tbl_scope(tfp, &params);
260         if (rc) {
261                 BNXT_TF_DBG(ERR, "Unable to free table scope\n");
262                 return -EINVAL;
263         }
264         return rc;
265 }
266
267 /* The function to free and deinit the ulp context data. */
268 static int32_t
269 ulp_ctx_deinit(struct bnxt *bp,
270                struct bnxt_ulp_session_state *session)
271 {
272         if (!session || !bp) {
273                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
274                 return -EINVAL;
275         }
276
277         /* close the tf session */
278         ulp_ctx_session_close(bp, session);
279
280         /* Free the contents */
281         if (session->cfg_data) {
282                 rte_free(session->cfg_data);
283                 bp->ulp_ctx->cfg_data = NULL;
284                 session->cfg_data = NULL;
285         }
286         return 0;
287 }
288
289 /* The function to allocate and initialize the ulp context data. */
290 static int32_t
291 ulp_ctx_init(struct bnxt *bp,
292              struct bnxt_ulp_session_state *session)
293 {
294         struct bnxt_ulp_data    *ulp_data;
295         int32_t                 rc = 0;
296
297         if (!session || !bp) {
298                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
299                 return -EINVAL;
300         }
301
302         /* Allocate memory to hold ulp context data. */
303         ulp_data = rte_zmalloc("bnxt_ulp_data",
304                                sizeof(struct bnxt_ulp_data), 0);
305         if (!ulp_data) {
306                 BNXT_TF_DBG(ERR, "Failed to allocate memory for ulp data\n");
307                 return -ENOMEM;
308         }
309
310         /* Increment the ulp context data reference count usage. */
311         bp->ulp_ctx->cfg_data = ulp_data;
312         session->cfg_data = ulp_data;
313         ulp_data->ref_cnt++;
314
315         /* Open the ulp session. */
316         rc = ulp_ctx_session_open(bp, session);
317         if (rc) {
318                 (void)ulp_ctx_deinit(bp, session);
319                 return rc;
320         }
321         bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session->g_tfp);
322         return rc;
323 }
324
325 /* The function to initialize ulp dparms with devargs */
326 static int32_t
327 ulp_dparms_init(struct bnxt *bp,
328                 struct bnxt_ulp_context *ulp_ctx)
329 {
330         struct bnxt_ulp_device_params *dparms;
331         uint32_t dev_id;
332
333         if (!bp->max_num_kflows)
334                 return -EINVAL;
335
336         if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) {
337                 BNXT_TF_DBG(DEBUG, "Failed to get device id\n");
338                 return -EINVAL;
339         }
340
341         dparms = bnxt_ulp_device_params_get(dev_id);
342         if (!dparms) {
343                 BNXT_TF_DBG(DEBUG, "Failed to get device parms\n");
344                 return -EINVAL;
345         }
346
347         /* num_flows = max_num_kflows * 1024 */
348         dparms->flow_db_num_entries = bp->max_num_kflows * 1024;
349         /* GFID =  2 * num_flows */
350         dparms->mark_db_gfid_entries = dparms->flow_db_num_entries * 2;
351         BNXT_TF_DBG(DEBUG, "Set the number of flows = %"PRIu64"\n",
352                     dparms->flow_db_num_entries);
353
354         return 0;
355 }
356
357 /* The function to initialize bp flags with truflow features */
358 static int32_t
359 ulp_dparms_dev_port_intf_update(struct bnxt *bp,
360                                 struct bnxt_ulp_context *ulp_ctx)
361 {
362         struct bnxt_ulp_device_params *dparms;
363         uint32_t dev_id;
364
365         if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) {
366                 BNXT_TF_DBG(DEBUG, "Failed to get device id\n");
367                 return -EINVAL;
368         }
369
370         dparms = bnxt_ulp_device_params_get(dev_id);
371         if (!dparms) {
372                 BNXT_TF_DBG(DEBUG, "Failed to get device parms\n");
373                 return -EINVAL;
374         }
375
376         /* Update the bp flag with gfid flag */
377         if (dparms->flow_mem_type == BNXT_ULP_FLOW_MEM_TYPE_EXT)
378                 bp->flags |= BNXT_FLAG_GFID_ENABLE;
379
380         return 0;
381 }
382
383 static int32_t
384 ulp_ctx_attach(struct bnxt_ulp_context *ulp_ctx,
385                struct bnxt_ulp_session_state *session)
386 {
387         if (!ulp_ctx || !session) {
388                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
389                 return -EINVAL;
390         }
391
392         /* Increment the ulp context data reference count usage. */
393         ulp_ctx->cfg_data = session->cfg_data;
394         ulp_ctx->cfg_data->ref_cnt++;
395
396         /* TBD call TF_session_attach. */
397         ulp_ctx->g_tfp = session->g_tfp;
398         return 0;
399 }
400
401 static int32_t
402 ulp_ctx_detach(struct bnxt *bp,
403                struct bnxt_ulp_session_state *session)
404 {
405         struct bnxt_ulp_context *ulp_ctx;
406
407         if (!bp || !session) {
408                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
409                 return -EINVAL;
410         }
411         ulp_ctx = bp->ulp_ctx;
412
413         if (!ulp_ctx->cfg_data)
414                 return 0;
415
416         /* TBD call TF_session_detach */
417
418         /* Increment the ulp context data reference count usage. */
419         if (ulp_ctx->cfg_data->ref_cnt >= 1) {
420                 ulp_ctx->cfg_data->ref_cnt--;
421                 if (ulp_ctx_deinit_allowed(bp))
422                         ulp_ctx_deinit(bp, session);
423                 ulp_ctx->cfg_data = NULL;
424                 ulp_ctx->g_tfp = NULL;
425                 return 0;
426         }
427         BNXT_TF_DBG(ERR, "context deatach on invalid data\n");
428         return 0;
429 }
430
431 /*
432  * Initialize the state of an ULP session.
433  * If the state of an ULP session is not initialized, set it's state to
434  * initialized. If the state is already initialized, do nothing.
435  */
436 static void
437 ulp_context_initialized(struct bnxt_ulp_session_state *session, bool *init)
438 {
439         pthread_mutex_lock(&session->bnxt_ulp_mutex);
440
441         if (!session->bnxt_ulp_init) {
442                 session->bnxt_ulp_init = true;
443                 *init = false;
444         } else {
445                 *init = true;
446         }
447
448         pthread_mutex_unlock(&session->bnxt_ulp_mutex);
449 }
450
451 /*
452  * Check if an ULP session is already allocated for a specific PCI
453  * domain & bus. If it is already allocated simply return the session
454  * pointer, otherwise allocate a new session.
455  */
456 static struct bnxt_ulp_session_state *
457 ulp_get_session(struct rte_pci_addr *pci_addr)
458 {
459         struct bnxt_ulp_session_state *session;
460
461         STAILQ_FOREACH(session, &bnxt_ulp_session_list, next) {
462                 if (session->pci_info.domain == pci_addr->domain &&
463                     session->pci_info.bus == pci_addr->bus) {
464                         return session;
465                 }
466         }
467         return NULL;
468 }
469
470 /*
471  * Allocate and Initialize an ULP session and set it's state to INITIALIZED.
472  * If it's already initialized simply return the already existing session.
473  */
474 static struct bnxt_ulp_session_state *
475 ulp_session_init(struct bnxt *bp,
476                  bool *init)
477 {
478         struct rte_pci_device           *pci_dev;
479         struct rte_pci_addr             *pci_addr;
480         struct bnxt_ulp_session_state   *session;
481
482         if (!bp)
483                 return NULL;
484
485         pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
486         pci_addr = &pci_dev->addr;
487
488         pthread_mutex_lock(&bnxt_ulp_global_mutex);
489
490         session = ulp_get_session(pci_addr);
491         if (!session) {
492                 /* Not Found the session  Allocate a new one */
493                 session = rte_zmalloc("bnxt_ulp_session",
494                                       sizeof(struct bnxt_ulp_session_state),
495                                       0);
496                 if (!session) {
497                         BNXT_TF_DBG(ERR,
498                                     "Allocation failed for bnxt_ulp_session\n");
499                         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
500                         return NULL;
501
502                 } else {
503                         /* Add it to the queue */
504                         session->pci_info.domain = pci_addr->domain;
505                         session->pci_info.bus = pci_addr->bus;
506                         pthread_mutex_init(&session->bnxt_ulp_mutex, NULL);
507                         STAILQ_INSERT_TAIL(&bnxt_ulp_session_list,
508                                            session, next);
509                 }
510         }
511         ulp_context_initialized(session, init);
512         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
513         return session;
514 }
515
516 /*
517  * When a device is closed, remove it's associated session from the global
518  * session list.
519  */
520 static void
521 ulp_session_deinit(struct bnxt_ulp_session_state *session)
522 {
523         if (!session)
524                 return;
525
526         if (!session->cfg_data) {
527                 pthread_mutex_lock(&bnxt_ulp_global_mutex);
528                 STAILQ_REMOVE(&bnxt_ulp_session_list, session,
529                               bnxt_ulp_session_state, next);
530                 pthread_mutex_destroy(&session->bnxt_ulp_mutex);
531                 rte_free(session);
532                 pthread_mutex_unlock(&bnxt_ulp_global_mutex);
533         }
534 }
535
536 /*
537  * When a port is initialized by dpdk. This functions is called
538  * and this function initializes the ULP context and rest of the
539  * infrastructure associated with it.
540  */
541 int32_t
542 bnxt_ulp_init(struct bnxt *bp)
543 {
544         struct bnxt_ulp_session_state *session;
545         bool init;
546         int rc;
547
548         if (bp->ulp_ctx) {
549                 BNXT_TF_DBG(ERR, "ulp ctx already allocated\n");
550                 return -EINVAL;
551         }
552
553         /*
554          * Multiple uplink ports can be associated with a single vswitch.
555          * Make sure only the port that is started first will initialize
556          * the TF session.
557          */
558         session = ulp_session_init(bp, &init);
559         if (!session) {
560                 BNXT_TF_DBG(ERR, "Failed to initialize the tf session\n");
561                 return -EINVAL;
562         }
563
564         bp->ulp_ctx = rte_zmalloc("bnxt_ulp_ctx",
565                                   sizeof(struct bnxt_ulp_context), 0);
566         if (!bp->ulp_ctx) {
567                 BNXT_TF_DBG(ERR, "Failed to allocate ulp ctx\n");
568                 ulp_session_deinit(session);
569                 return -ENOMEM;
570         }
571
572         /*
573          * If ULP is already initialized for a specific domain then simply
574          * assign the ulp context to this rte_eth_dev.
575          */
576         if (init) {
577                 rc = ulp_ctx_attach(bp->ulp_ctx, session);
578                 if (rc) {
579                         BNXT_TF_DBG(ERR,
580                                     "Failed to attach the ulp context\n");
581                         ulp_session_deinit(session);
582                         rte_free(bp->ulp_ctx);
583                         return rc;
584                 }
585
586                 /* Update bnxt driver flags */
587                 rc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx);
588                 if (rc) {
589                         BNXT_TF_DBG(ERR, "Failed to update driver flags\n");
590                         ulp_ctx_detach(bp, session);
591                         ulp_session_deinit(session);
592                         rte_free(bp->ulp_ctx);
593                         return rc;
594                 }
595
596                 /* update the port database */
597                 rc = ulp_port_db_dev_port_intf_update(bp->ulp_ctx, bp->eth_dev);
598                 if (rc) {
599                         BNXT_TF_DBG(ERR,
600                                     "Failed to update port database\n");
601                         ulp_ctx_detach(bp, session);
602                         ulp_session_deinit(session);
603                         rte_free(bp->ulp_ctx);
604                 }
605                 return rc;
606         }
607
608         /* Allocate and Initialize the ulp context. */
609         rc = ulp_ctx_init(bp, session);
610         if (rc) {
611                 BNXT_TF_DBG(ERR, "Failed to create the ulp context\n");
612                 goto jump_to_error;
613         }
614
615         /* Initialize ulp dparms with values devargs passed */
616         rc = ulp_dparms_init(bp, bp->ulp_ctx);
617
618         /* create the port database */
619         rc = ulp_port_db_init(bp->ulp_ctx);
620         if (rc) {
621                 BNXT_TF_DBG(ERR, "Failed to create the port database\n");
622                 goto jump_to_error;
623         }
624
625         /* Update bnxt driver flags */
626         rc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx);
627         if (rc) {
628                 BNXT_TF_DBG(ERR, "Failed to update driver flags\n");
629                 goto jump_to_error;
630         }
631
632         /* update the port database */
633         rc = ulp_port_db_dev_port_intf_update(bp->ulp_ctx, bp->eth_dev);
634         if (rc) {
635                 BNXT_TF_DBG(ERR, "Failed to update port database\n");
636                 goto jump_to_error;
637         }
638
639         /* Create the Mark database. */
640         rc = ulp_mark_db_init(bp->ulp_ctx);
641         if (rc) {
642                 BNXT_TF_DBG(ERR, "Failed to create the mark database\n");
643                 goto jump_to_error;
644         }
645
646         /* Create the flow database. */
647         rc = ulp_flow_db_init(bp->ulp_ctx);
648         if (rc) {
649                 BNXT_TF_DBG(ERR, "Failed to create the flow database\n");
650                 goto jump_to_error;
651         }
652
653         /* Create the eem table scope. */
654         rc = ulp_eem_tbl_scope_init(bp);
655         if (rc) {
656                 BNXT_TF_DBG(ERR, "Failed to create the eem scope table\n");
657                 goto jump_to_error;
658         }
659
660         rc = ulp_mapper_init(bp->ulp_ctx);
661         if (rc) {
662                 BNXT_TF_DBG(ERR, "Failed to initialize ulp mapper\n");
663                 goto jump_to_error;
664         }
665
666         return rc;
667
668 jump_to_error:
669         bnxt_ulp_deinit(bp);
670         return -ENOMEM;
671 }
672
673 /* Below are the access functions to access internal data of ulp context. */
674
675 /*
676  * When a port is deinit'ed by dpdk. This function is called
677  * and this function clears the ULP context and rest of the
678  * infrastructure associated with it.
679  */
680 void
681 bnxt_ulp_deinit(struct bnxt *bp)
682 {
683         struct bnxt_ulp_session_state   *session;
684         struct rte_pci_device           *pci_dev;
685         struct rte_pci_addr             *pci_addr;
686
687         /* Get the session first */
688         pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device);
689         pci_addr = &pci_dev->addr;
690         pthread_mutex_lock(&bnxt_ulp_global_mutex);
691         session = ulp_get_session(pci_addr);
692         pthread_mutex_unlock(&bnxt_ulp_global_mutex);
693
694         /* session not found then just exit */
695         if (!session)
696                 return;
697
698         /* clean up regular flows */
699         ulp_flow_db_flush_flows(bp->ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE);
700
701         /* cleanup the eem table scope */
702         ulp_eem_tbl_scope_deinit(bp, bp->ulp_ctx);
703
704         /* cleanup the flow database */
705         ulp_flow_db_deinit(bp->ulp_ctx);
706
707         /* Delete the Mark database */
708         ulp_mark_db_deinit(bp->ulp_ctx);
709
710         /* cleanup the ulp mapper */
711         ulp_mapper_deinit(bp->ulp_ctx);
712
713         /* Delete the Port database */
714         ulp_port_db_deinit(bp->ulp_ctx);
715
716         /* Delete the ulp context and tf session */
717         ulp_ctx_detach(bp, session);
718
719         /* Finally delete the bnxt session*/
720         ulp_session_deinit(session);
721
722         rte_free(bp->ulp_ctx);
723 }
724
725 /* Function to set the Mark DB into the context */
726 int32_t
727 bnxt_ulp_cntxt_ptr2_mark_db_set(struct bnxt_ulp_context *ulp_ctx,
728                                 struct bnxt_ulp_mark_tbl *mark_tbl)
729 {
730         if (!ulp_ctx || !ulp_ctx->cfg_data) {
731                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
732                 return -EINVAL;
733         }
734
735         ulp_ctx->cfg_data->mark_tbl = mark_tbl;
736
737         return 0;
738 }
739
740 /* Function to retrieve the Mark DB from the context. */
741 struct bnxt_ulp_mark_tbl *
742 bnxt_ulp_cntxt_ptr2_mark_db_get(struct bnxt_ulp_context *ulp_ctx)
743 {
744         if (!ulp_ctx || !ulp_ctx->cfg_data)
745                 return NULL;
746
747         return ulp_ctx->cfg_data->mark_tbl;
748 }
749
750 /* Function to set the device id of the hardware. */
751 int32_t
752 bnxt_ulp_cntxt_dev_id_set(struct bnxt_ulp_context *ulp_ctx,
753                           uint32_t dev_id)
754 {
755         if (ulp_ctx && ulp_ctx->cfg_data) {
756                 ulp_ctx->cfg_data->dev_id = dev_id;
757                 return 0;
758         }
759
760         return -EINVAL;
761 }
762
763 /* Function to get the device id of the hardware. */
764 int32_t
765 bnxt_ulp_cntxt_dev_id_get(struct bnxt_ulp_context *ulp_ctx,
766                           uint32_t *dev_id)
767 {
768         if (ulp_ctx && ulp_ctx->cfg_data) {
769                 *dev_id = ulp_ctx->cfg_data->dev_id;
770                 return 0;
771         }
772
773         return -EINVAL;
774 }
775
776 /* Function to get the table scope id of the EEM table. */
777 int32_t
778 bnxt_ulp_cntxt_tbl_scope_id_get(struct bnxt_ulp_context *ulp_ctx,
779                                 uint32_t *tbl_scope_id)
780 {
781         if (ulp_ctx && ulp_ctx->cfg_data) {
782                 *tbl_scope_id = ulp_ctx->cfg_data->tbl_scope_id;
783                 return 0;
784         }
785
786         return -EINVAL;
787 }
788
789 /* Function to set the table scope id of the EEM table. */
790 int32_t
791 bnxt_ulp_cntxt_tbl_scope_id_set(struct bnxt_ulp_context *ulp_ctx,
792                                 uint32_t tbl_scope_id)
793 {
794         if (ulp_ctx && ulp_ctx->cfg_data) {
795                 ulp_ctx->cfg_data->tbl_scope_id = tbl_scope_id;
796                 return 0;
797         }
798
799         return -EINVAL;
800 }
801
802 /* Function to set the tfp session details from the ulp context. */
803 int32_t
804 bnxt_ulp_cntxt_tfp_set(struct bnxt_ulp_context *ulp, struct tf *tfp)
805 {
806         if (!ulp) {
807                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
808                 return -EINVAL;
809         }
810
811         /* TBD The tfp should be removed once tf_attach is implemented. */
812         ulp->g_tfp = tfp;
813         return 0;
814 }
815
816 /* Function to get the tfp session details from the ulp context. */
817 struct tf *
818 bnxt_ulp_cntxt_tfp_get(struct bnxt_ulp_context *ulp)
819 {
820         if (!ulp) {
821                 BNXT_TF_DBG(ERR, "Invalid arguments\n");
822                 return NULL;
823         }
824         /* TBD The tfp should be removed once tf_attach is implemented. */
825         return ulp->g_tfp;
826 }
827
828 /*
829  * Get the device table entry based on the device id.
830  *
831  * dev_id [in] The device id of the hardware
832  *
833  * Returns the pointer to the device parameters.
834  */
835 struct bnxt_ulp_device_params *
836 bnxt_ulp_device_params_get(uint32_t dev_id)
837 {
838         if (dev_id < BNXT_ULP_MAX_NUM_DEVICES)
839                 return &ulp_device_params[dev_id];
840         return NULL;
841 }
842
843 /* Function to set the flow database to the ulp context. */
844 int32_t
845 bnxt_ulp_cntxt_ptr2_flow_db_set(struct bnxt_ulp_context *ulp_ctx,
846                                 struct bnxt_ulp_flow_db *flow_db)
847 {
848         if (!ulp_ctx || !ulp_ctx->cfg_data)
849                 return -EINVAL;
850
851         ulp_ctx->cfg_data->flow_db = flow_db;
852         return 0;
853 }
854
855 /* Function to get the flow database from the ulp context. */
856 struct bnxt_ulp_flow_db *
857 bnxt_ulp_cntxt_ptr2_flow_db_get(struct bnxt_ulp_context *ulp_ctx)
858 {
859         if (!ulp_ctx || !ulp_ctx->cfg_data)
860                 return NULL;
861
862         return ulp_ctx->cfg_data->flow_db;
863 }
864
865 /* Function to get the ulp context from eth device. */
866 struct bnxt_ulp_context *
867 bnxt_ulp_eth_dev_ptr2_cntxt_get(struct rte_eth_dev      *dev)
868 {
869         struct bnxt     *bp;
870
871         bp = (struct bnxt *)dev->data->dev_private;
872         if (!bp) {
873                 BNXT_TF_DBG(ERR, "Bnxt private data is not initialized\n");
874                 return NULL;
875         }
876         return bp->ulp_ctx;
877 }
878
879 int32_t
880 bnxt_ulp_cntxt_ptr2_mapper_data_set(struct bnxt_ulp_context *ulp_ctx,
881                                     void *mapper_data)
882 {
883         if (!ulp_ctx || !ulp_ctx->cfg_data) {
884                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
885                 return -EINVAL;
886         }
887
888         ulp_ctx->cfg_data->mapper_data = mapper_data;
889         return 0;
890 }
891
892 void *
893 bnxt_ulp_cntxt_ptr2_mapper_data_get(struct bnxt_ulp_context *ulp_ctx)
894 {
895         if (!ulp_ctx || !ulp_ctx->cfg_data) {
896                 BNXT_TF_DBG(ERR, "Invalid ulp context data\n");
897                 return NULL;
898         }
899
900         return ulp_ctx->cfg_data->mapper_data;
901 }
902
903 /* Function to set the port database to the ulp context. */
904 int32_t
905 bnxt_ulp_cntxt_ptr2_port_db_set(struct bnxt_ulp_context *ulp_ctx,
906                                 struct bnxt_ulp_port_db *port_db)
907 {
908         if (!ulp_ctx || !ulp_ctx->cfg_data)
909                 return -EINVAL;
910
911         ulp_ctx->cfg_data->port_db = port_db;
912         return 0;
913 }
914
915 /* Function to get the port database from the ulp context. */
916 struct bnxt_ulp_port_db *
917 bnxt_ulp_cntxt_ptr2_port_db_get(struct bnxt_ulp_context *ulp_ctx)
918 {
919         if (!ulp_ctx || !ulp_ctx->cfg_data)
920                 return NULL;
921
922         return ulp_ctx->cfg_data->port_db;
923 }