net/bnxt: cleanup logs in session handling paths
[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         if (session->shared_session && shared_session_creator) {
192                 session->shared_session_creator = true;
193                 parms->open_cfg->shared_session_creator = true;
194         }
195
196         rc = tf_dev_bind(tfp,
197                          parms->open_cfg->device_type,
198                          session->shadow_copy,
199                          &parms->open_cfg->resources,
200                          &session->dev);
201
202         /* Logging handled by dev_bind */
203         if (rc)
204                 goto cleanup;
205
206         if (session->dev.ops->tf_dev_get_mailbox == NULL) {
207                 /* Log error */
208                 TFP_DRV_LOG(ERR,
209                             "No tf_dev_get_mailbox() defined for device\n");
210                 goto cleanup;
211         }
212
213         session->dev_init = true;
214
215         return 0;
216
217  cleanup:
218         tfp_free(tfp->session->core_data);
219         tfp_free(tfp->session);
220         tfp->session = NULL;
221         return rc;
222 }
223
224 /**
225  * Creates a Session Client on an existing Session.
226  *
227  * [in] tfp
228  *   Pointer to TF handle
229  *
230  * [in] parms
231  *   Pointer to session client create parameters
232  *
233  * Returns
234  *   - (0) if successful.
235  *   - (-EINVAL) on failure.
236  *   - (-ENOMEM) if max session clients has been reached.
237  */
238 static int
239 tf_session_client_create(struct tf *tfp,
240                          struct tf_session_client_create_parms *parms)
241 {
242         int rc;
243         struct tf_session *session = NULL;
244         struct tf_session_client *client;
245         struct tfp_calloc_parms cparms;
246         union tf_session_client_id session_client_id;
247
248         TF_CHECK_PARMS2(tfp, parms);
249
250         /* Using internal version as session client may not exist yet */
251         rc = tf_session_get_session_internal(tfp, &session);
252         if (rc) {
253                 TFP_DRV_LOG(ERR,
254                             "Failed to lookup session, rc:%s\n",
255                             strerror(-rc));
256                 return rc;
257         }
258
259         client = tf_session_find_session_client_by_name(session,
260                                                         parms->ctrl_chan_name);
261         if (client) {
262                 TFP_DRV_LOG(ERR,
263                             "Client %s, already registered with this session\n",
264                             parms->ctrl_chan_name);
265                 return -EOPNOTSUPP;
266         }
267
268         rc = tf_msg_session_client_register
269                     (tfp,
270                      session,
271                      parms->ctrl_chan_name,
272                      &session_client_id.internal.fw_session_client_id);
273         if (rc) {
274                 TFP_DRV_LOG(ERR,
275                             "Failed to create client on session, rc:%s\n",
276                             strerror(-rc));
277                 return rc;
278         }
279
280         /* Create the local session client, initialize and attach to
281          * the session
282          */
283         cparms.nitems = 1;
284         cparms.size = sizeof(struct tf_session_client);
285         cparms.alignment = 0;
286         rc = tfp_calloc(&cparms);
287         if (rc) {
288                 TFP_DRV_LOG(ERR,
289                             "Failed to allocate session client, rc:%s\n",
290                             strerror(-rc));
291                 goto cleanup;
292         }
293         client = cparms.mem_va;
294
295         /* Register FID with the client */
296         rc = tfp_get_fid(tfp, &client->fw_fid);
297         if (rc)
298                 return rc;
299
300         /* Build the Session Client ID by adding the fw_session_id */
301         rc = tf_session_get_fw_session_id
302                         (tfp,
303                         &session_client_id.internal.fw_session_id);
304         if (rc) {
305                 TFP_DRV_LOG(ERR,
306                             "Session Firmware id lookup failed, rc:%s\n",
307                             strerror(-rc));
308                 return rc;
309         }
310
311         tfp_memcpy(client->ctrl_chan_name,
312                    parms->ctrl_chan_name,
313                    TF_SESSION_NAME_MAX);
314
315         client->session_client_id.id = session_client_id.id;
316
317         ll_insert(&session->client_ll, &client->ll_entry);
318
319         session->ref_count++;
320
321         /* Build the return value */
322         parms->session_client_id->id = session_client_id.id;
323
324  cleanup:
325         /* TBD - Add code to unregister newly create client from fw */
326
327         return rc;
328 }
329
330
331 /**
332  * Destroys a Session Client on an existing Session.
333  *
334  * [in] tfp
335  *   Pointer to TF handle
336  *
337  * [in] parms
338  *   Pointer to the session client destroy parameters
339  *
340  * Returns
341  *   - (0) if successful.
342  *   - (-EINVAL) on failure.
343  *   - (-ENOTFOUND) error, client not owned by the session.
344  *   - (-ENOTSUPP) error, unable to destroy client as its the last
345  *                 client. Please use the tf_session_close().
346  */
347 static int
348 tf_session_client_destroy(struct tf *tfp,
349                           struct tf_session_client_destroy_parms *parms)
350 {
351         int rc;
352         struct tf_session *tfs;
353         struct tf_session_client *client;
354
355         TF_CHECK_PARMS2(tfp, parms);
356
357         rc = tf_session_get_session(tfp, &tfs);
358         if (rc) {
359                 TFP_DRV_LOG(ERR,
360                             "Failed to lookup session, rc:%s\n",
361                             strerror(-rc));
362                 return rc;
363         }
364
365         /* Check session owns this client and that we're not the last client */
366         client = tf_session_get_session_client(tfs,
367                                                parms->session_client_id);
368         if (client == NULL) {
369                 TFP_DRV_LOG(ERR,
370                             "Client %d, not found within this session\n",
371                             parms->session_client_id.id);
372                 return -EINVAL;
373         }
374
375         /* If last client the request is rejected and cleanup should
376          * be done by session close.
377          */
378         if (tfs->ref_count == 1)
379                 return -EOPNOTSUPP;
380
381         rc = tf_msg_session_client_unregister
382                         (tfp,
383                         tfs,
384                         parms->session_client_id.internal.fw_session_client_id);
385
386         /* Log error, but continue. If FW fails we do not really have
387          * a way to fix this but the client would no longer be valid
388          * thus we remove from the session.
389          */
390         if (rc) {
391                 TFP_DRV_LOG(ERR,
392                             "Client destroy on FW Failed, rc:%s\n",
393                             strerror(-rc));
394         }
395
396         ll_delete(&tfs->client_ll, &client->ll_entry);
397
398         /* Decrement the session ref_count */
399         tfs->ref_count--;
400
401         tfp_free(client);
402
403         return rc;
404 }
405
406 int
407 tf_session_open_session(struct tf *tfp,
408                         struct tf_session_open_session_parms *parms)
409 {
410         int rc;
411         struct tf_session_client_create_parms scparms;
412
413         TF_CHECK_PARMS3(tfp, parms, parms->open_cfg->bp);
414
415         tfp->bp = parms->open_cfg->bp;
416         /* Decide if we're creating a new session or session client */
417         if (tfp->session == NULL) {
418                 rc = tf_session_create(tfp, parms);
419                 if (rc) {
420                         TFP_DRV_LOG(ERR,
421                                     "Failed to create session, ctrl_chan_name:%s, rc:%s\n",
422                                     parms->open_cfg->ctrl_chan_name,
423                                     strerror(-rc));
424                         return rc;
425                 }
426
427                 TFP_DRV_LOG(INFO,
428                        "Session created, session_client_id:%d,"
429                        "session_id:0x%08x, fw_session_id:%d\n",
430                        parms->open_cfg->session_client_id.id,
431                        parms->open_cfg->session_id.id,
432                        parms->open_cfg->session_id.internal.fw_session_id);
433         } else {
434                 scparms.ctrl_chan_name = parms->open_cfg->ctrl_chan_name;
435                 scparms.session_client_id = &parms->open_cfg->session_client_id;
436
437                 /* Create the new client and get it associated with
438                  * the session.
439                  */
440                 rc = tf_session_client_create(tfp, &scparms);
441                 if (rc) {
442                         TFP_DRV_LOG(ERR,
443                               "Failed to create client on session 0x%x, rc:%s\n",
444                               parms->open_cfg->session_id.id,
445                               strerror(-rc));
446                         return rc;
447                 }
448
449                 TFP_DRV_LOG(INFO,
450                         "Session Client:%d registered on session:0x%8x\n",
451                         scparms.session_client_id->internal.fw_session_client_id,
452                         tfp->session->session_id.id);
453         }
454
455         return 0;
456 }
457
458 int
459 tf_session_attach_session(struct tf *tfp __rte_unused,
460                           struct tf_session_attach_session_parms *parms __rte_unused)
461 {
462         int rc = -EOPNOTSUPP;
463
464         TF_CHECK_PARMS2(tfp, parms);
465
466         TFP_DRV_LOG(ERR,
467                     "Attach not yet supported, rc:%s\n",
468                     strerror(-rc));
469         return rc;
470 }
471
472 int
473 tf_session_close_session(struct tf *tfp,
474                          struct tf_session_close_session_parms *parms)
475 {
476         int rc;
477         struct tf_session *tfs = NULL;
478         struct tf_session_client *client;
479         struct tf_dev_info *tfd = NULL;
480         struct tf_session_client_destroy_parms scdparms;
481         uint16_t fid;
482
483         TF_CHECK_PARMS2(tfp, parms);
484
485         rc = tf_session_get_session(tfp, &tfs);
486         if (rc) {
487                 TFP_DRV_LOG(ERR,
488                             "Session lookup failed, rc:%s\n",
489                             strerror(-rc));
490                 return rc;
491         }
492
493         if (tfs->session_id.id == TF_SESSION_ID_INVALID) {
494                 rc = -EINVAL;
495                 TFP_DRV_LOG(ERR,
496                             "Invalid session id, unable to close, rc:%s\n",
497                             strerror(-rc));
498                 return rc;
499         }
500
501         /* Get the client, we need it independently of the closure
502          * type (client or session closure).
503          *
504          * We find the client by way of the fid. Thus one cannot close
505          * a client on behalf of someone else.
506          */
507         rc = tfp_get_fid(tfp, &fid);
508         if (rc)
509                 return rc;
510
511         client = tf_session_find_session_client_by_fid(tfs,
512                                                        fid);
513         if (!client) {
514                 rc = -EINVAL;
515                 TFP_DRV_LOG(ERR,
516                             "Client not part of the session, unable to close, rc:%s\n",
517                             strerror(-rc));
518                 return rc;
519         }
520
521         /* In case multiple clients we chose to close those first */
522         if (tfs->ref_count > 1) {
523                 /* Linaro gcc can't static init this structure */
524                 memset(&scdparms,
525                        0,
526                        sizeof(struct tf_session_client_destroy_parms));
527
528                 scdparms.session_client_id = client->session_client_id;
529                 /* Destroy requested client so its no longer
530                  * registered with this session.
531                  */
532                 rc = tf_session_client_destroy(tfp, &scdparms);
533                 if (rc) {
534                         TFP_DRV_LOG(ERR,
535                                     "Failed to unregister Client %d, rc:%s\n",
536                                     client->session_client_id.id,
537                                     strerror(-rc));
538                         return rc;
539                 }
540
541                 TFP_DRV_LOG(INFO,
542                             "Closed session client, session_client_id:%d\n",
543                             client->session_client_id.id);
544
545                 TFP_DRV_LOG(INFO,
546                             "session_id:0x%08x, ref_count:%d\n",
547                             tfs->session_id.id,
548                             tfs->ref_count);
549
550                 return 0;
551         }
552
553         /* Record the session we're closing so the caller knows the
554          * details.
555          */
556         *parms->session_id = tfs->session_id;
557
558         rc = tf_session_get_device(tfs, &tfd);
559         if (rc) {
560                 TFP_DRV_LOG(ERR,
561                             "Device lookup failed, rc:%s\n",
562                             strerror(-rc));
563                 return rc;
564         }
565
566         /* Unbind the device */
567         rc = tf_dev_unbind(tfp, tfd);
568         if (rc) {
569                 /* Log error */
570                 TFP_DRV_LOG(ERR,
571                             "Device unbind failed, rc:%s\n",
572                             strerror(-rc));
573         }
574
575         rc = tf_msg_session_close(tfp, tfs);
576         if (rc) {
577                 /* Log error */
578                 TFP_DRV_LOG(ERR,
579                             "FW Session close failed, rc:%s\n",
580                             strerror(-rc));
581         }
582
583         /* Final cleanup as we're last user of the session thus we
584          * also delete the last client.
585          */
586         ll_delete(&tfs->client_ll, &client->ll_entry);
587         tfp_free(client);
588
589         tfs->ref_count--;
590
591         TFP_DRV_LOG(INFO,
592                     "Closed session, session_id:0x%08x, ref_count:%d\n",
593                     tfs->session_id.id,
594                     tfs->ref_count);
595
596         tfs->dev_init = false;
597
598         tfp_free(tfp->session->core_data);
599         tfp_free(tfp->session);
600         tfp->session = NULL;
601
602         return 0;
603 }
604
605 bool
606 tf_session_is_fid_supported(struct tf_session *tfs,
607                             uint16_t fid)
608 {
609         struct ll_entry *c_entry;
610         struct tf_session_client *client;
611
612         for (c_entry = tfs->client_ll.head;
613              c_entry != NULL;
614              c_entry = c_entry->next) {
615                 client = (struct tf_session_client *)c_entry;
616                 if (client->fw_fid == fid)
617                         return true;
618         }
619
620         return false;
621 }
622
623 int
624 tf_session_get_session_internal(struct tf *tfp,
625                                 struct tf_session **tfs)
626 {
627         int rc = 0;
628
629         /* Skip using the check macro as we want to control the error msg */
630         if (tfp->session == NULL || tfp->session->core_data == NULL) {
631                 rc = -EINVAL;
632                 TFP_DRV_LOG(ERR,
633                             "Session not created, rc:%s\n",
634                             strerror(-rc));
635                 return rc;
636         }
637
638         *tfs = (struct tf_session *)(tfp->session->core_data);
639
640         return rc;
641 }
642
643 int
644 tf_session_get_session(struct tf *tfp,
645                        struct tf_session **tfs)
646 {
647         int rc;
648         uint16_t fw_fid;
649         bool supported = false;
650
651         rc = tf_session_get_session_internal(tfp,
652                                              tfs);
653         /* Logging done by tf_session_get_session_internal */
654         if (rc)
655                 return rc;
656
657         /* As session sharing among functions aka 'individual clients'
658          * is supported we have to assure that the client is indeed
659          * registered before we get deep in the TruFlow api stack.
660          */
661         rc = tfp_get_fid(tfp, &fw_fid);
662         if (rc) {
663                 TFP_DRV_LOG(ERR,
664                             "Internal FID lookup\n, rc:%s\n",
665                             strerror(-rc));
666                 return rc;
667         }
668
669         supported = tf_session_is_fid_supported(*tfs, fw_fid);
670         if (!supported) {
671                 TFP_DRV_LOG
672                         (ERR,
673                         "Ctrl channel not registered with session\n, rc:%s\n",
674                         strerror(-rc));
675                 return -EINVAL;
676         }
677
678         return rc;
679 }
680
681 struct tf_session_client *
682 tf_session_get_session_client(struct tf_session *tfs,
683                               union tf_session_client_id session_client_id)
684 {
685         struct ll_entry *c_entry;
686         struct tf_session_client *client;
687
688         /* Skip using the check macro as we just want to return */
689         if (tfs == NULL)
690                 return NULL;
691
692         for (c_entry = tfs->client_ll.head;
693              c_entry != NULL;
694              c_entry = c_entry->next) {
695                 client = (struct tf_session_client *)c_entry;
696                 if (client->session_client_id.id == session_client_id.id)
697                         return client;
698         }
699
700         return NULL;
701 }
702
703 struct tf_session_client *
704 tf_session_find_session_client_by_name(struct tf_session *tfs,
705                                        const char *ctrl_chan_name)
706 {
707         struct ll_entry *c_entry;
708         struct tf_session_client *client;
709
710         /* Skip using the check macro as we just want to return */
711         if (tfs == NULL || ctrl_chan_name == NULL)
712                 return NULL;
713
714         for (c_entry = tfs->client_ll.head;
715              c_entry != NULL;
716              c_entry = c_entry->next) {
717                 client = (struct tf_session_client *)c_entry;
718                 if (strncmp(client->ctrl_chan_name,
719                             ctrl_chan_name,
720                             TF_SESSION_NAME_MAX) == 0)
721                         return client;
722         }
723
724         return NULL;
725 }
726
727 struct tf_session_client *
728 tf_session_find_session_client_by_fid(struct tf_session *tfs,
729                                       uint16_t fid)
730 {
731         struct ll_entry *c_entry;
732         struct tf_session_client *client;
733
734         /* Skip using the check macro as we just want to return */
735         if (tfs == NULL)
736                 return NULL;
737
738         for (c_entry = tfs->client_ll.head;
739              c_entry != NULL;
740              c_entry = c_entry->next) {
741                 client = (struct tf_session_client *)c_entry;
742                 if (client->fw_fid == fid)
743                         return client;
744         }
745
746         return NULL;
747 }
748
749 int
750 tf_session_get_device(struct tf_session *tfs,
751                       struct tf_dev_info **tfd)
752 {
753         *tfd = &tfs->dev;
754
755         return 0;
756 }
757
758 int
759 tf_session_get_fw_session_id(struct tf *tfp,
760                              uint8_t *fw_session_id)
761 {
762         int rc;
763         struct tf_session *tfs = NULL;
764
765         /* Skip using the check macro as we want to control the error msg */
766         if (tfp->session == NULL) {
767                 rc = -EINVAL;
768                 TFP_DRV_LOG(ERR,
769                             "Session not created, rc:%s\n",
770                             strerror(-rc));
771                 return rc;
772         }
773
774         if (fw_session_id == NULL) {
775                 rc = -EINVAL;
776                 TFP_DRV_LOG(ERR,
777                             "Invalid Argument(s), rc:%s\n",
778                             strerror(-rc));
779                 return rc;
780         }
781
782         rc = tf_session_get_session_internal(tfp, &tfs);
783         if (rc)
784                 return rc;
785
786         *fw_session_id = tfs->session_id.internal.fw_session_id;
787
788         return 0;
789 }
790
791 int
792 tf_session_get_session_id(struct tf *tfp,
793                           union tf_session_id *session_id)
794 {
795         int rc;
796         struct tf_session *tfs = NULL;
797
798         if (tfp->session == NULL) {
799                 rc = -EINVAL;
800                 TFP_DRV_LOG(ERR,
801                             "Session not created, rc:%s\n",
802                             strerror(-rc));
803                 return rc;
804         }
805
806         if (session_id == NULL) {
807                 rc = -EINVAL;
808                 TFP_DRV_LOG(ERR,
809                             "Invalid Argument(s), rc:%s\n",
810                             strerror(-rc));
811                 return rc;
812         }
813
814         /* Using internal version as session client may not exist yet */
815         rc = tf_session_get_session_internal(tfp, &tfs);
816         if (rc)
817                 return rc;
818
819         *session_id = tfs->session_id;
820
821         return 0;
822 }
823
824 int
825 tf_session_get_em_ext_db(struct tf *tfp,
826                          void **em_ext_db_handle)
827 {
828         struct tf_session *tfs = NULL;
829         int rc = 0;
830
831         *em_ext_db_handle = NULL;
832
833         if (tfp == NULL)
834                 return (-EINVAL);
835
836         rc = tf_session_get_session_internal(tfp, &tfs);
837         if (rc)
838                 return rc;
839
840         *em_ext_db_handle = tfs->em_ext_db_handle;
841         return rc;
842 }
843
844 int
845 tf_session_set_em_ext_db(struct tf *tfp,
846                          void *em_ext_db_handle)
847 {
848         struct tf_session *tfs = NULL;
849         int rc = 0;
850
851         if (tfp == NULL)
852                 return (-EINVAL);
853
854         rc = tf_session_get_session_internal(tfp, &tfs);
855         if (rc)
856                 return rc;
857
858         tfs->em_ext_db_handle = em_ext_db_handle;
859         return rc;
860 }
861
862 int
863 tf_session_get_db(struct tf *tfp,
864                   enum tf_module_type type,
865                   void **db_handle)
866 {
867         struct tf_session *tfs = NULL;
868         int rc = 0;
869
870         *db_handle = NULL;
871
872         if (tfp == NULL)
873                 return (-EINVAL);
874
875         rc = tf_session_get_session_internal(tfp, &tfs);
876         if (rc)
877                 return rc;
878
879         switch (type) {
880         case TF_MODULE_TYPE_IDENTIFIER:
881                 if (tfs->id_db_handle)
882                         *db_handle = tfs->id_db_handle;
883                 else
884                         rc = -EINVAL;
885                 break;
886         case TF_MODULE_TYPE_TABLE:
887                 if (tfs->tbl_db_handle)
888                         *db_handle = tfs->tbl_db_handle;
889                 else
890                         rc = -EINVAL;
891
892                 break;
893         case TF_MODULE_TYPE_TCAM:
894                 if (tfs->tcam_db_handle)
895                         *db_handle = tfs->tcam_db_handle;
896                 else
897                         rc = -EINVAL;
898                 break;
899         case TF_MODULE_TYPE_EM:
900                 if (tfs->em_db_handle)
901                         *db_handle = tfs->em_db_handle;
902                 else
903                         rc = -EINVAL;
904                 break;
905         default:
906                 rc = -EINVAL;
907                 break;
908         }
909
910         return rc;
911 }
912
913 int
914 tf_session_set_db(struct tf *tfp,
915                   enum tf_module_type type,
916                   void *db_handle)
917 {
918         struct tf_session *tfs = NULL;
919         int rc = 0;
920
921         if (tfp == NULL)
922                 return (-EINVAL);
923
924         rc = tf_session_get_session_internal(tfp, &tfs);
925         if (rc)
926                 return rc;
927
928         switch (type) {
929         case TF_MODULE_TYPE_IDENTIFIER:
930                 tfs->id_db_handle = db_handle;
931                 break;
932         case TF_MODULE_TYPE_TABLE:
933                 tfs->tbl_db_handle = db_handle;
934                 break;
935         case TF_MODULE_TYPE_TCAM:
936                 tfs->tcam_db_handle = db_handle;
937                 break;
938         case TF_MODULE_TYPE_EM:
939                 tfs->em_db_handle = db_handle;
940                 break;
941         default:
942                 rc = -EINVAL;
943                 break;
944         }
945
946         return rc;
947 }