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