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