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