xref: /dpdk/drivers/net/bnxt/tf_core/tf_session.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
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 */
1072