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