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