net/bnxt: support WC TCAM shared session
[dpdk.git] / drivers / net / bnxt / tf_core / tf_session.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5
6 #include <string.h>
7
8 #include <rte_common.h>
9
10 #include "tf_session.h"
11 #include "tf_common.h"
12 #include "tf_msg.h"
13 #include "tfp.h"
14 #include "bnxt.h"
15
16 struct tf_session_client_create_parms {
17         /**
18          * [in] Pointer to the control channel name string
19          */
20         char *ctrl_chan_name;
21
22         /**
23          * [out] Firmware Session Client ID
24          */
25         union tf_session_client_id *session_client_id;
26 };
27
28 struct tf_session_client_destroy_parms {
29         /**
30          * FW Session Client Identifier
31          */
32         union tf_session_client_id session_client_id;
33 };
34
35 /**
36  * Creates a Session and the associated client.
37  *
38  * [in] tfp
39  *   Pointer to TF handle
40  *
41  * [in] parms
42  *   Pointer to session client create parameters
43  *
44  * Returns
45  *   - (0) if successful.
46  *   - (-EINVAL) on failure.
47  *   - (-ENOMEM) if max session clients has been reached.
48  */
49 static int
50 tf_session_create(struct tf *tfp,
51                   struct tf_session_open_session_parms *parms)
52 {
53         int rc;
54         struct tf_session *session = NULL;
55         struct tf_session_client *client;
56         struct tfp_calloc_parms cparms;
57         uint8_t fw_session_id;
58         uint8_t fw_session_client_id;
59         union tf_session_id *session_id;
60         struct tf_dev_info dev;
61         bool shared_session_creator;
62         int name_len;
63         char *name;
64
65         TF_CHECK_PARMS2(tfp, parms);
66
67         tf_dev_bind_ops(parms->open_cfg->device_type,
68                         &dev);
69
70         /* Open FW session and get a new session_id */
71         rc = tf_msg_session_open(parms->open_cfg->bp,
72                                  parms->open_cfg->ctrl_chan_name,
73                                  &fw_session_id,
74                                  &fw_session_client_id,
75                                  &dev,
76                                  &shared_session_creator);
77         if (rc) {
78                 /* Log error */
79                 if (rc == -EEXIST)
80                         TFP_DRV_LOG(ERR,
81                                     "Session is already open, rc:%s\n",
82                                     strerror(-rc));
83                 else
84                         TFP_DRV_LOG(ERR,
85                                     "Open message send failed, rc:%s\n",
86                                     strerror(-rc));
87
88                 parms->open_cfg->session_id.id = TF_FW_SESSION_ID_INVALID;
89                 return rc;
90         }
91
92         /* Allocate session */
93         cparms.nitems = 1;
94         cparms.size = sizeof(struct tf_session_info);
95         cparms.alignment = 0;
96         rc = tfp_calloc(&cparms);
97         if (rc) {
98                 /* Log error */
99                 TFP_DRV_LOG(ERR,
100                             "Failed to allocate session info, rc:%s\n",
101                             strerror(-rc));
102                 goto cleanup;
103         }
104         tfp->session = (struct tf_session_info *)cparms.mem_va;
105
106         /* Allocate core data for the session */
107         cparms.nitems = 1;
108         cparms.size = sizeof(struct tf_session);
109         cparms.alignment = 0;
110         rc = tfp_calloc(&cparms);
111         if (rc) {
112                 /* Log error */
113                 TFP_DRV_LOG(ERR,
114                             "Failed to allocate session data, rc:%s\n",
115                             strerror(-rc));
116                 goto cleanup;
117         }
118         tfp->session->core_data = cparms.mem_va;
119         session_id = &parms->open_cfg->session_id;
120
121         /* Update Session Info, which is what is visible to the caller */
122         tfp->session->ver.major = 0;
123         tfp->session->ver.minor = 0;
124         tfp->session->ver.update = 0;
125
126         tfp->session->session_id.internal.domain = session_id->internal.domain;
127         tfp->session->session_id.internal.bus = session_id->internal.bus;
128         tfp->session->session_id.internal.device = session_id->internal.device;
129         tfp->session->session_id.internal.fw_session_id = fw_session_id;
130
131         /* Initialize Session and Device, which is private */
132         session = (struct tf_session *)tfp->session->core_data;
133         session->ver.major = 0;
134         session->ver.minor = 0;
135         session->ver.update = 0;
136
137         session->session_id.internal.domain = session_id->internal.domain;
138         session->session_id.internal.bus = session_id->internal.bus;
139         session->session_id.internal.device = session_id->internal.device;
140         session->session_id.internal.fw_session_id = fw_session_id;
141         /* Return the allocated session id */
142         session_id->id = session->session_id.id;
143
144         session->shadow_copy = parms->open_cfg->shadow_copy;
145
146         /* Init session client list */
147         ll_init(&session->client_ll);
148
149         /* Create the local session client, initialize and attach to
150          * the session
151          */
152         cparms.nitems = 1;
153         cparms.size = sizeof(struct tf_session_client);
154         cparms.alignment = 0;
155         rc = tfp_calloc(&cparms);
156         if (rc) {
157                 /* Log error */
158                 TFP_DRV_LOG(ERR,
159                             "Failed to allocate session client, rc:%s\n",
160                             strerror(-rc));
161                 goto cleanup;
162         }
163         client = cparms.mem_va;
164
165         /* Register FID with the client */
166         rc = tfp_get_fid(tfp, &client->fw_fid);
167         if (rc)
168                 return rc;
169
170         client->session_client_id.internal.fw_session_id = fw_session_id;
171         client->session_client_id.internal.fw_session_client_id =
172                 fw_session_client_id;
173
174         tfp_memcpy(client->ctrl_chan_name,
175                    parms->open_cfg->ctrl_chan_name,
176                    TF_SESSION_NAME_MAX);
177
178         ll_insert(&session->client_ll, &client->ll_entry);
179         session->ref_count++;
180
181         /* Init session em_ext_db */
182         session->em_ext_db_handle = NULL;
183
184         /* Populate the request */
185         name_len = strnlen(parms->open_cfg->ctrl_chan_name,
186                            TF_SESSION_NAME_MAX);
187         name = &parms->open_cfg->ctrl_chan_name[name_len - strlen("tf_shared")];
188         if (!strncmp(name, "tf_shared", strlen("tf_shared")))
189                 session->shared_session = true;
190
191         name = &parms->open_cfg->ctrl_chan_name[name_len -
192                 strlen("tf_shared-wc_tcam")];
193         if (!strncmp(name, "tf_shared-wc_tcam", strlen("tf_shared-wc_tcam")))
194                 session->shared_session = true;
195
196         if (session->shared_session && shared_session_creator) {
197                 session->shared_session_creator = true;
198                 parms->open_cfg->shared_session_creator = true;
199         }
200
201         rc = tf_dev_bind(tfp,
202                          parms->open_cfg->device_type,
203                          session->shadow_copy,
204                          &parms->open_cfg->resources,
205                          &session->dev);
206
207         /* Logging handled by dev_bind */
208         if (rc)
209                 goto cleanup;
210
211         if (session->dev.ops->tf_dev_get_mailbox == NULL) {
212                 /* Log error */
213                 TFP_DRV_LOG(ERR,
214                             "No tf_dev_get_mailbox() defined for device\n");
215                 goto cleanup;
216         }
217
218         session->dev_init = true;
219
220         return 0;
221
222  cleanup:
223         rc = tf_msg_session_close(tfp,
224                         fw_session_id,
225                         dev.ops->tf_dev_get_mailbox());
226         if (rc) {
227                 /* Log error */
228                 TFP_DRV_LOG(ERR,
229                             "FW Session close failed, rc:%s\n",
230                             strerror(-rc));
231         }
232
233         tfp_free(tfp->session->core_data);
234         tfp_free(tfp->session);
235         tfp->session = NULL;
236         return rc;
237 }
238
239 /**
240  * Creates a Session Client on an existing Session.
241  *
242  * [in] tfp
243  *   Pointer to TF handle
244  *
245  * [in] parms
246  *   Pointer to session client create parameters
247  *
248  * Returns
249  *   - (0) if successful.
250  *   - (-EINVAL) on failure.
251  *   - (-ENOMEM) if max session clients has been reached.
252  */
253 static int
254 tf_session_client_create(struct tf *tfp,
255                          struct tf_session_client_create_parms *parms)
256 {
257         int rc;
258         struct tf_session *session = NULL;
259         struct tf_session_client *client;
260         struct tfp_calloc_parms cparms;
261         union tf_session_client_id session_client_id;
262
263         TF_CHECK_PARMS2(tfp, parms);
264
265         /* Using internal version as session client may not exist yet */
266         rc = tf_session_get_session_internal(tfp, &session);
267         if (rc) {
268                 TFP_DRV_LOG(ERR,
269                             "Failed to lookup session, rc:%s\n",
270                             strerror(-rc));
271                 return rc;
272         }
273
274         client = tf_session_find_session_client_by_name(session,
275                                                         parms->ctrl_chan_name);
276         if (client) {
277                 TFP_DRV_LOG(ERR,
278                             "Client %s, already registered with this session\n",
279                             parms->ctrl_chan_name);
280                 return -EOPNOTSUPP;
281         }
282
283         rc = tf_msg_session_client_register
284                     (tfp,
285                      session,
286                      parms->ctrl_chan_name,
287                      &session_client_id.internal.fw_session_client_id);
288         if (rc) {
289                 TFP_DRV_LOG(ERR,
290                             "Failed to create client on session, rc:%s\n",
291                             strerror(-rc));
292                 return rc;
293         }
294
295         /* Create the local session client, initialize and attach to
296          * the session
297          */
298         cparms.nitems = 1;
299         cparms.size = sizeof(struct tf_session_client);
300         cparms.alignment = 0;
301         rc = tfp_calloc(&cparms);
302         if (rc) {
303                 TFP_DRV_LOG(ERR,
304                             "Failed to allocate session client, rc:%s\n",
305                             strerror(-rc));
306                 goto cleanup;
307         }
308         client = cparms.mem_va;
309
310         /* Register FID with the client */
311         rc = tfp_get_fid(tfp, &client->fw_fid);
312         if (rc)
313                 return rc;
314
315         /* Build the Session Client ID by adding the fw_session_id */
316         rc = tf_session_get_fw_session_id
317                         (tfp,
318                         &session_client_id.internal.fw_session_id);
319         if (rc) {
320                 TFP_DRV_LOG(ERR,
321                             "Session Firmware id lookup failed, rc:%s\n",
322                             strerror(-rc));
323                 return rc;
324         }
325
326         tfp_memcpy(client->ctrl_chan_name,
327                    parms->ctrl_chan_name,
328                    TF_SESSION_NAME_MAX);
329
330         client->session_client_id.id = session_client_id.id;
331
332         ll_insert(&session->client_ll, &client->ll_entry);
333
334         session->ref_count++;
335
336         /* Build the return value */
337         parms->session_client_id->id = session_client_id.id;
338
339  cleanup:
340         /* TBD - Add code to unregister newly create client from fw */
341
342         return rc;
343 }
344
345
346 /**
347  * Destroys a Session Client on an existing Session.
348  *
349  * [in] tfp
350  *   Pointer to TF handle
351  *
352  * [in] parms
353  *   Pointer to the session client destroy parameters
354  *
355  * Returns
356  *   - (0) if successful.
357  *   - (-EINVAL) on failure.
358  *   - (-ENOTFOUND) error, client not owned by the session.
359  *   - (-ENOTSUPP) error, unable to destroy client as its the last
360  *                 client. Please use the tf_session_close().
361  */
362 static int
363 tf_session_client_destroy(struct tf *tfp,
364                           struct tf_session_client_destroy_parms *parms)
365 {
366         int rc;
367         struct tf_session *tfs;
368         struct tf_session_client *client;
369
370         TF_CHECK_PARMS2(tfp, parms);
371
372         rc = tf_session_get_session(tfp, &tfs);
373         if (rc) {
374                 TFP_DRV_LOG(ERR,
375                             "Failed to lookup session, rc:%s\n",
376                             strerror(-rc));
377                 return rc;
378         }
379
380         /* Check session owns this client and that we're not the last client */
381         client = tf_session_get_session_client(tfs,
382                                                parms->session_client_id);
383         if (client == NULL) {
384                 TFP_DRV_LOG(ERR,
385                             "Client %d, not found within this session\n",
386                             parms->session_client_id.id);
387                 return -EINVAL;
388         }
389
390         /* If last client the request is rejected and cleanup should
391          * be done by session close.
392          */
393         if (tfs->ref_count == 1)
394                 return -EOPNOTSUPP;
395
396         rc = tf_msg_session_client_unregister
397                         (tfp,
398                         tfs,
399                         parms->session_client_id.internal.fw_session_client_id);
400
401         /* Log error, but continue. If FW fails we do not really have
402          * a way to fix this but the client would no longer be valid
403          * thus we remove from the session.
404          */
405         if (rc) {
406                 TFP_DRV_LOG(ERR,
407                             "Client destroy on FW Failed, rc:%s\n",
408                             strerror(-rc));
409         }
410
411         ll_delete(&tfs->client_ll, &client->ll_entry);
412
413         /* Decrement the session ref_count */
414         tfs->ref_count--;
415
416         tfp_free(client);
417
418         return rc;
419 }
420
421 int
422 tf_session_open_session(struct tf *tfp,
423                         struct tf_session_open_session_parms *parms)
424 {
425         int rc;
426         struct tf_session_client_create_parms scparms;
427
428         TF_CHECK_PARMS3(tfp, parms, parms->open_cfg->bp);
429
430         tfp->bp = parms->open_cfg->bp;
431         /* Decide if we're creating a new session or session client */
432         if (tfp->session == NULL) {
433                 rc = tf_session_create(tfp, parms);
434                 if (rc) {
435                         TFP_DRV_LOG(ERR,
436                                     "Failed to create session, ctrl_chan_name:%s, rc:%s\n",
437                                     parms->open_cfg->ctrl_chan_name,
438                                     strerror(-rc));
439                         return rc;
440                 }
441
442                 TFP_DRV_LOG(INFO,
443                        "Session created, session_client_id:%d,"
444                        "session_id:0x%08x, fw_session_id:%d\n",
445                        parms->open_cfg->session_client_id.id,
446                        parms->open_cfg->session_id.id,
447                        parms->open_cfg->session_id.internal.fw_session_id);
448         } else {
449                 scparms.ctrl_chan_name = parms->open_cfg->ctrl_chan_name;
450                 scparms.session_client_id = &parms->open_cfg->session_client_id;
451
452                 /* Create the new client and get it associated with
453                  * the session.
454                  */
455                 rc = tf_session_client_create(tfp, &scparms);
456                 if (rc) {
457                         TFP_DRV_LOG(ERR,
458                               "Failed to create client on session 0x%x, rc:%s\n",
459                               parms->open_cfg->session_id.id,
460                               strerror(-rc));
461                         return rc;
462                 }
463
464                 TFP_DRV_LOG(INFO,
465                         "Session Client:%d registered on session:0x%8x\n",
466                         scparms.session_client_id->internal.fw_session_client_id,
467                         tfp->session->session_id.id);
468         }
469
470         return 0;
471 }
472
473 int
474 tf_session_attach_session(struct tf *tfp __rte_unused,
475                           struct tf_session_attach_session_parms *parms __rte_unused)
476 {
477         int rc = -EOPNOTSUPP;
478
479         TF_CHECK_PARMS2(tfp, parms);
480
481         TFP_DRV_LOG(ERR,
482                     "Attach not yet supported, rc:%s\n",
483                     strerror(-rc));
484         return rc;
485 }
486
487 int
488 tf_session_close_session(struct tf *tfp,
489                          struct tf_session_close_session_parms *parms)
490 {
491         int rc;
492         struct tf_session *tfs = NULL;
493         struct tf_session_client *client;
494         struct tf_dev_info *tfd = NULL;
495         struct tf_session_client_destroy_parms scdparms;
496         uint16_t fid;
497         uint8_t fw_session_id = 1;
498         int mailbox = 0;
499
500         TF_CHECK_PARMS2(tfp, parms);
501
502         rc = tf_session_get_session(tfp, &tfs);
503         if (rc) {
504                 TFP_DRV_LOG(ERR,
505                             "Session lookup failed, rc:%s\n",
506                             strerror(-rc));
507                 return rc;
508         }
509
510         if (tfs->session_id.id == TF_SESSION_ID_INVALID) {
511                 rc = -EINVAL;
512                 TFP_DRV_LOG(ERR,
513                             "Invalid session id, unable to close, rc:%s\n",
514                             strerror(-rc));
515                 return rc;
516         }
517
518         /* Get the client, we need it independently of the closure
519          * type (client or session closure).
520          *
521          * We find the client by way of the fid. Thus one cannot close
522          * a client on behalf of someone else.
523          */
524         rc = tfp_get_fid(tfp, &fid);
525         if (rc)
526                 return rc;
527
528         client = tf_session_find_session_client_by_fid(tfs,
529                                                        fid);
530         if (!client) {
531                 rc = -EINVAL;
532                 TFP_DRV_LOG(ERR,
533                             "Client not part of the session, unable to close, rc:%s\n",
534                             strerror(-rc));
535                 return rc;
536         }
537
538         /* In case multiple clients we chose to close those first */
539         if (tfs->ref_count > 1) {
540                 /* Linaro gcc can't static init this structure */
541                 memset(&scdparms,
542                        0,
543                        sizeof(struct tf_session_client_destroy_parms));
544
545                 scdparms.session_client_id = client->session_client_id;
546                 /* Destroy requested client so its no longer
547                  * registered with this session.
548                  */
549                 rc = tf_session_client_destroy(tfp, &scdparms);
550                 if (rc) {
551                         TFP_DRV_LOG(ERR,
552                                     "Failed to unregister Client %d, rc:%s\n",
553                                     client->session_client_id.id,
554                                     strerror(-rc));
555                         return rc;
556                 }
557
558                 TFP_DRV_LOG(INFO,
559                             "Closed session client, session_client_id:%d\n",
560                             client->session_client_id.id);
561
562                 TFP_DRV_LOG(INFO,
563                             "session_id:0x%08x, ref_count:%d\n",
564                             tfs->session_id.id,
565                             tfs->ref_count);
566
567                 return 0;
568         }
569
570         /* Record the session we're closing so the caller knows the
571          * details.
572          */
573         *parms->session_id = tfs->session_id;
574
575         rc = tf_session_get_device(tfs, &tfd);
576         if (rc) {
577                 TFP_DRV_LOG(ERR,
578                             "Device lookup failed, rc:%s\n",
579                             strerror(-rc));
580                 return rc;
581         }
582
583         mailbox = tfd->ops->tf_dev_get_mailbox();
584
585         rc = tf_session_get_fw_session_id(tfp, &fw_session_id);
586         if (rc) {
587                 TFP_DRV_LOG(ERR,
588                             "Unable to lookup FW id, rc:%s\n",
589                             strerror(-rc));
590                 return rc;
591         }
592
593         /* Unbind the device */
594         rc = tf_dev_unbind(tfp, tfd);
595         if (rc) {
596                 /* Log error */
597                 TFP_DRV_LOG(ERR,
598                             "Device unbind failed, rc:%s\n",
599                             strerror(-rc));
600         }
601
602         rc = tf_msg_session_close(tfp, fw_session_id, mailbox);
603         if (rc) {
604                 /* Log error */
605                 TFP_DRV_LOG(ERR,
606                             "FW Session close failed, rc:%s\n",
607                             strerror(-rc));
608         }
609
610         /* Final cleanup as we're last user of the session thus we
611          * also delete the last client.
612          */
613         ll_delete(&tfs->client_ll, &client->ll_entry);
614         tfp_free(client);
615
616         tfs->ref_count--;
617
618         TFP_DRV_LOG(INFO,
619                     "Closed session, session_id:0x%08x, ref_count:%d\n",
620                     tfs->session_id.id,
621                     tfs->ref_count);
622
623         tfs->dev_init = false;
624
625         tfp_free(tfp->session->core_data);
626         tfp_free(tfp->session);
627         tfp->session = NULL;
628
629         return 0;
630 }
631
632 bool
633 tf_session_is_fid_supported(struct tf_session *tfs,
634                             uint16_t fid)
635 {
636         struct ll_entry *c_entry;
637         struct tf_session_client *client;
638
639         for (c_entry = tfs->client_ll.head;
640              c_entry != NULL;
641              c_entry = c_entry->next) {
642                 client = (struct tf_session_client *)c_entry;
643                 if (client->fw_fid == fid)
644                         return true;
645         }
646
647         return false;
648 }
649
650 int
651 tf_session_get_session_internal(struct tf *tfp,
652                                 struct tf_session **tfs)
653 {
654         int rc = 0;
655
656         /* Skip using the check macro as we want to control the error msg */
657         if (tfp->session == NULL || tfp->session->core_data == NULL) {
658                 rc = -EINVAL;
659                 TFP_DRV_LOG(ERR,
660                             "Session not created, rc:%s\n",
661                             strerror(-rc));
662                 return rc;
663         }
664
665         *tfs = (struct tf_session *)(tfp->session->core_data);
666
667         return rc;
668 }
669
670 int
671 tf_session_get_session(struct tf *tfp,
672                        struct tf_session **tfs)
673 {
674         int rc;
675         uint16_t fw_fid;
676         bool supported = false;
677
678         rc = tf_session_get_session_internal(tfp,
679                                              tfs);
680         /* Logging done by tf_session_get_session_internal */
681         if (rc)
682                 return rc;
683
684         /* As session sharing among functions aka 'individual clients'
685          * is supported we have to assure that the client is indeed
686          * registered before we get deep in the TruFlow api stack.
687          */
688         rc = tfp_get_fid(tfp, &fw_fid);
689         if (rc) {
690                 TFP_DRV_LOG(ERR,
691                             "Internal FID lookup\n, rc:%s\n",
692                             strerror(-rc));
693                 return rc;
694         }
695
696         supported = tf_session_is_fid_supported(*tfs, fw_fid);
697         if (!supported) {
698                 TFP_DRV_LOG
699                         (ERR,
700                         "Ctrl channel not registered with session\n, rc:%s\n",
701                         strerror(-rc));
702                 return -EINVAL;
703         }
704
705         return rc;
706 }
707
708 struct tf_session_client *
709 tf_session_get_session_client(struct tf_session *tfs,
710                               union tf_session_client_id session_client_id)
711 {
712         struct ll_entry *c_entry;
713         struct tf_session_client *client;
714
715         /* Skip using the check macro as we just want to return */
716         if (tfs == NULL)
717                 return NULL;
718
719         for (c_entry = tfs->client_ll.head;
720              c_entry != NULL;
721              c_entry = c_entry->next) {
722                 client = (struct tf_session_client *)c_entry;
723                 if (client->session_client_id.id == session_client_id.id)
724                         return client;
725         }
726
727         return NULL;
728 }
729
730 struct tf_session_client *
731 tf_session_find_session_client_by_name(struct tf_session *tfs,
732                                        const char *ctrl_chan_name)
733 {
734         struct ll_entry *c_entry;
735         struct tf_session_client *client;
736
737         /* Skip using the check macro as we just want to return */
738         if (tfs == NULL || ctrl_chan_name == NULL)
739                 return NULL;
740
741         for (c_entry = tfs->client_ll.head;
742              c_entry != NULL;
743              c_entry = c_entry->next) {
744                 client = (struct tf_session_client *)c_entry;
745                 if (strncmp(client->ctrl_chan_name,
746                             ctrl_chan_name,
747                             TF_SESSION_NAME_MAX) == 0)
748                         return client;
749         }
750
751         return NULL;
752 }
753
754 struct tf_session_client *
755 tf_session_find_session_client_by_fid(struct tf_session *tfs,
756                                       uint16_t fid)
757 {
758         struct ll_entry *c_entry;
759         struct tf_session_client *client;
760
761         /* Skip using the check macro as we just want to return */
762         if (tfs == NULL)
763                 return NULL;
764
765         for (c_entry = tfs->client_ll.head;
766              c_entry != NULL;
767              c_entry = c_entry->next) {
768                 client = (struct tf_session_client *)c_entry;
769                 if (client->fw_fid == fid)
770                         return client;
771         }
772
773         return NULL;
774 }
775
776 int
777 tf_session_get_device(struct tf_session *tfs,
778                       struct tf_dev_info **tfd)
779 {
780         *tfd = &tfs->dev;
781
782         return 0;
783 }
784
785 int
786 tf_session_get_fw_session_id(struct tf *tfp,
787                              uint8_t *fw_session_id)
788 {
789         int rc;
790         struct tf_session *tfs = NULL;
791
792         /* Skip using the check macro as we want to control the error msg */
793         if (tfp->session == NULL) {
794                 rc = -EINVAL;
795                 TFP_DRV_LOG(ERR,
796                             "Session not created, rc:%s\n",
797                             strerror(-rc));
798                 return rc;
799         }
800
801         if (fw_session_id == NULL) {
802                 rc = -EINVAL;
803                 TFP_DRV_LOG(ERR,
804                             "Invalid Argument(s), rc:%s\n",
805                             strerror(-rc));
806                 return rc;
807         }
808
809         rc = tf_session_get_session_internal(tfp, &tfs);
810         if (rc)
811                 return rc;
812
813         *fw_session_id = tfs->session_id.internal.fw_session_id;
814
815         return 0;
816 }
817
818 int
819 tf_session_get_session_id(struct tf *tfp,
820                           union tf_session_id *session_id)
821 {
822         int rc;
823         struct tf_session *tfs = NULL;
824
825         if (tfp->session == NULL) {
826                 rc = -EINVAL;
827                 TFP_DRV_LOG(ERR,
828                             "Session not created, rc:%s\n",
829                             strerror(-rc));
830                 return rc;
831         }
832
833         if (session_id == NULL) {
834                 rc = -EINVAL;
835                 TFP_DRV_LOG(ERR,
836                             "Invalid Argument(s), rc:%s\n",
837                             strerror(-rc));
838                 return rc;
839         }
840
841         /* Using internal version as session client may not exist yet */
842         rc = tf_session_get_session_internal(tfp, &tfs);
843         if (rc)
844                 return rc;
845
846         *session_id = tfs->session_id;
847
848         return 0;
849 }
850
851 int
852 tf_session_get_em_ext_db(struct tf *tfp,
853                          void **em_ext_db_handle)
854 {
855         struct tf_session *tfs = NULL;
856         int rc = 0;
857
858         *em_ext_db_handle = NULL;
859
860         if (tfp == NULL)
861                 return (-EINVAL);
862
863         rc = tf_session_get_session_internal(tfp, &tfs);
864         if (rc)
865                 return rc;
866
867         *em_ext_db_handle = tfs->em_ext_db_handle;
868         return rc;
869 }
870
871 int
872 tf_session_set_em_ext_db(struct tf *tfp,
873                          void *em_ext_db_handle)
874 {
875         struct tf_session *tfs = NULL;
876         int rc = 0;
877
878         if (tfp == NULL)
879                 return (-EINVAL);
880
881         rc = tf_session_get_session_internal(tfp, &tfs);
882         if (rc)
883                 return rc;
884
885         tfs->em_ext_db_handle = em_ext_db_handle;
886         return rc;
887 }
888
889 int
890 tf_session_get_db(struct tf *tfp,
891                   enum tf_module_type type,
892                   void **db_handle)
893 {
894         struct tf_session *tfs = NULL;
895         int rc = 0;
896
897         *db_handle = NULL;
898
899         if (tfp == NULL)
900                 return (-EINVAL);
901
902         rc = tf_session_get_session_internal(tfp, &tfs);
903         if (rc)
904                 return rc;
905
906         switch (type) {
907         case TF_MODULE_TYPE_IDENTIFIER:
908                 if (tfs->id_db_handle)
909                         *db_handle = tfs->id_db_handle;
910                 else
911                         rc = -ENOMEM;
912                 break;
913         case TF_MODULE_TYPE_TABLE:
914                 if (tfs->tbl_db_handle)
915                         *db_handle = tfs->tbl_db_handle;
916                 else
917                         rc = -ENOMEM;
918
919                 break;
920         case TF_MODULE_TYPE_TCAM:
921                 if (tfs->tcam_db_handle)
922                         *db_handle = tfs->tcam_db_handle;
923                 else
924                         rc = -ENOMEM;
925                 break;
926         case TF_MODULE_TYPE_EM:
927                 if (tfs->em_db_handle)
928                         *db_handle = tfs->em_db_handle;
929                 else
930                         rc = -ENOMEM;
931                 break;
932         default:
933                 rc = -EINVAL;
934                 break;
935         }
936
937         return rc;
938 }
939
940 int
941 tf_session_set_db(struct tf *tfp,
942                   enum tf_module_type type,
943                   void *db_handle)
944 {
945         struct tf_session *tfs = NULL;
946         int rc = 0;
947
948         if (tfp == NULL)
949                 return (-EINVAL);
950
951         rc = tf_session_get_session_internal(tfp, &tfs);
952         if (rc)
953                 return rc;
954
955         switch (type) {
956         case TF_MODULE_TYPE_IDENTIFIER:
957                 tfs->id_db_handle = db_handle;
958                 break;
959         case TF_MODULE_TYPE_TABLE:
960                 tfs->tbl_db_handle = db_handle;
961                 break;
962         case TF_MODULE_TYPE_TCAM:
963                 tfs->tcam_db_handle = db_handle;
964                 break;
965         case TF_MODULE_TYPE_EM:
966                 tfs->em_db_handle = db_handle;
967                 break;
968         default:
969                 rc = -EINVAL;
970                 break;
971         }
972
973         return rc;
974 }
975
976 #ifdef TF_TCAM_SHARED
977
978 int
979 tf_session_get_tcam_shared_db(struct tf *tfp,
980                               void **tcam_shared_db_handle)
981 {
982         struct tf_session *tfs = NULL;
983         int rc = 0;
984
985         *tcam_shared_db_handle = NULL;
986
987         if (tfp == NULL)
988                 return (-EINVAL);
989
990         rc = tf_session_get_session_internal(tfp, &tfs);
991         if (rc)
992                 return rc;
993
994         *tcam_shared_db_handle = tfs->tcam_shared_db_handle;
995         return rc;
996 }
997
998 int
999 tf_session_set_tcam_shared_db(struct tf *tfp,
1000                          void *tcam_shared_db_handle)
1001 {
1002         struct tf_session *tfs = NULL;
1003         int rc = 0;
1004
1005         if (tfp == NULL)
1006                 return (-EINVAL);
1007
1008         rc = tf_session_get_session_internal(tfp, &tfs);
1009         if (rc)
1010                 return rc;
1011
1012         tfs->tcam_shared_db_handle = tcam_shared_db_handle;
1013         return rc;
1014 }
1015 #endif /* TF_TCAM_SHARED */