xref: /dpdk/drivers/net/bnxt/tf_core/tf_session.c (revision 0d63f20a3c75cce117c96dda80e228dcfada1d4f)
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 	/* Init session client list */
145 	ll_init(&session->client_ll);
146 
147 	/* Create the local session client, initialize and attach to
148 	 * the session
149 	 */
150 	cparms.nitems = 1;
151 	cparms.size = sizeof(struct tf_session_client);
152 	cparms.alignment = 0;
153 	rc = tfp_calloc(&cparms);
154 	if (rc) {
155 		/* Log error */
156 		TFP_DRV_LOG(ERR,
157 			    "Failed to allocate session client, rc:%s\n",
158 			    strerror(-rc));
159 		goto cleanup;
160 	}
161 	client = cparms.mem_va;
162 
163 	/* Register FID with the client */
164 	rc = tfp_get_fid(tfp, &client->fw_fid);
165 	if (rc)
166 		return rc;
167 
168 	client->session_client_id.internal.fw_session_id = fw_session_id;
169 	client->session_client_id.internal.fw_session_client_id =
170 		fw_session_client_id;
171 
172 	tfp_memcpy(client->ctrl_chan_name,
173 		   parms->open_cfg->ctrl_chan_name,
174 		   TF_SESSION_NAME_MAX);
175 
176 	ll_insert(&session->client_ll, &client->ll_entry);
177 	session->ref_count++;
178 
179 	/* Init session em_ext_db */
180 	session->em_ext_db_handle = NULL;
181 
182 	/* Populate the request */
183 	name_len = strnlen(parms->open_cfg->ctrl_chan_name,
184 			   TF_SESSION_NAME_MAX);
185 	name = &parms->open_cfg->ctrl_chan_name[name_len - strlen("tf_shared")];
186 	if (!strncmp(name, "tf_shared", strlen("tf_shared")))
187 		session->shared_session = true;
188 
189 	name = &parms->open_cfg->ctrl_chan_name[name_len -
190 		strlen("tf_shared-wc_tcam")];
191 	if (!strncmp(name, "tf_shared-wc_tcam", strlen("tf_shared-wc_tcam")))
192 		session->shared_session = true;
193 
194 	if (session->shared_session && shared_session_creator) {
195 		session->shared_session_creator = true;
196 		parms->open_cfg->shared_session_creator = true;
197 	}
198 
199 	rc = tf_dev_bind(tfp,
200 			 parms->open_cfg->device_type,
201 			 &parms->open_cfg->resources,
202 			 parms->open_cfg->wc_num_slices,
203 			 &session->dev);
204 
205 	/* Logging handled by dev_bind */
206 	if (rc)
207 		goto cleanup;
208 
209 	if (session->dev.ops->tf_dev_get_mailbox == NULL) {
210 		/* Log error */
211 		TFP_DRV_LOG(ERR,
212 			    "No tf_dev_get_mailbox() defined for device\n");
213 		goto cleanup;
214 	}
215 
216 	session->dev_init = true;
217 
218 	return 0;
219 
220  cleanup:
221 	rc = tf_msg_session_close(tfp,
222 			fw_session_id,
223 			dev.ops->tf_dev_get_mailbox());
224 	if (rc) {
225 		/* Log error */
226 		TFP_DRV_LOG(ERR,
227 			    "FW Session close failed, rc:%s\n",
228 			    strerror(-rc));
229 	}
230 	if (tfp->session) {
231 		tfp_free(tfp->session->core_data);
232 		tfp_free(tfp->session);
233 		tfp->session = NULL;
234 	}
235 
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 int tf_session_get(struct tf *tfp,
709 		   struct tf_session **tfs,
710 		   struct tf_dev_info **tfd)
711 {
712 	int rc;
713 	rc = tf_session_get_session_internal(tfp, tfs);
714 
715 	/* Logging done by tf_session_get_session_internal */
716 	if (rc)
717 		return rc;
718 
719 	rc = tf_session_get_device(*tfs, tfd);
720 
721 	return rc;
722 }
723 
724 struct tf_session_client *
725 tf_session_get_session_client(struct tf_session *tfs,
726 			      union tf_session_client_id session_client_id)
727 {
728 	struct ll_entry *c_entry;
729 	struct tf_session_client *client;
730 
731 	/* Skip using the check macro as we just want to return */
732 	if (tfs == NULL)
733 		return NULL;
734 
735 	for (c_entry = tfs->client_ll.head;
736 	     c_entry != NULL;
737 	     c_entry = c_entry->next) {
738 		client = (struct tf_session_client *)c_entry;
739 		if (client->session_client_id.id == session_client_id.id)
740 			return client;
741 	}
742 
743 	return NULL;
744 }
745 
746 struct tf_session_client *
747 tf_session_find_session_client_by_name(struct tf_session *tfs,
748 				       const char *ctrl_chan_name)
749 {
750 	struct ll_entry *c_entry;
751 	struct tf_session_client *client;
752 
753 	/* Skip using the check macro as we just want to return */
754 	if (tfs == NULL || ctrl_chan_name == NULL)
755 		return NULL;
756 
757 	for (c_entry = tfs->client_ll.head;
758 	     c_entry != NULL;
759 	     c_entry = c_entry->next) {
760 		client = (struct tf_session_client *)c_entry;
761 		if (strncmp(client->ctrl_chan_name,
762 			    ctrl_chan_name,
763 			    TF_SESSION_NAME_MAX) == 0)
764 			return client;
765 	}
766 
767 	return NULL;
768 }
769 
770 struct tf_session_client *
771 tf_session_find_session_client_by_fid(struct tf_session *tfs,
772 				      uint16_t fid)
773 {
774 	struct ll_entry *c_entry;
775 	struct tf_session_client *client;
776 
777 	/* Skip using the check macro as we just want to return */
778 	if (tfs == NULL)
779 		return NULL;
780 
781 	for (c_entry = tfs->client_ll.head;
782 	     c_entry != NULL;
783 	     c_entry = c_entry->next) {
784 		client = (struct tf_session_client *)c_entry;
785 		if (client->fw_fid == fid)
786 			return client;
787 	}
788 
789 	return NULL;
790 }
791 
792 int
793 tf_session_get_device(struct tf_session *tfs,
794 		      struct tf_dev_info **tfd)
795 {
796 	*tfd = &tfs->dev;
797 
798 	return 0;
799 }
800 
801 int
802 tf_session_get_fw_session_id(struct tf *tfp,
803 			     uint8_t *fw_session_id)
804 {
805 	int rc;
806 	struct tf_session *tfs = NULL;
807 
808 	/* Skip using the check macro as we want to control the error msg */
809 	if (tfp->session == NULL) {
810 		rc = -EINVAL;
811 		TFP_DRV_LOG(ERR,
812 			    "Session not created, rc:%s\n",
813 			    strerror(-rc));
814 		return rc;
815 	}
816 
817 	if (fw_session_id == NULL) {
818 		rc = -EINVAL;
819 		TFP_DRV_LOG(ERR,
820 			    "Invalid Argument(s), rc:%s\n",
821 			    strerror(-rc));
822 		return rc;
823 	}
824 
825 	rc = tf_session_get_session_internal(tfp, &tfs);
826 	if (rc)
827 		return rc;
828 
829 	*fw_session_id = tfs->session_id.internal.fw_session_id;
830 
831 	return 0;
832 }
833 
834 int
835 tf_session_get_session_id(struct tf *tfp,
836 			  union tf_session_id *session_id)
837 {
838 	int rc;
839 	struct tf_session *tfs = NULL;
840 
841 	if (tfp->session == NULL) {
842 		rc = -EINVAL;
843 		TFP_DRV_LOG(ERR,
844 			    "Session not created, rc:%s\n",
845 			    strerror(-rc));
846 		return rc;
847 	}
848 
849 	if (session_id == NULL) {
850 		rc = -EINVAL;
851 		TFP_DRV_LOG(ERR,
852 			    "Invalid Argument(s), rc:%s\n",
853 			    strerror(-rc));
854 		return rc;
855 	}
856 
857 	/* Using internal version as session client may not exist yet */
858 	rc = tf_session_get_session_internal(tfp, &tfs);
859 	if (rc)
860 		return rc;
861 
862 	*session_id = tfs->session_id;
863 
864 	return 0;
865 }
866 
867 int
868 tf_session_get_em_ext_db(struct tf *tfp,
869 			 void **em_ext_db_handle)
870 {
871 	struct tf_session *tfs = NULL;
872 	int rc = 0;
873 
874 	*em_ext_db_handle = NULL;
875 
876 	if (tfp == NULL)
877 		return (-EINVAL);
878 
879 	rc = tf_session_get_session_internal(tfp, &tfs);
880 	if (rc)
881 		return rc;
882 
883 	*em_ext_db_handle = tfs->em_ext_db_handle;
884 	return rc;
885 }
886 
887 int
888 tf_session_set_em_ext_db(struct tf *tfp,
889 			 void *em_ext_db_handle)
890 {
891 	struct tf_session *tfs = NULL;
892 	int rc = 0;
893 
894 	if (tfp == NULL)
895 		return (-EINVAL);
896 
897 	rc = tf_session_get_session_internal(tfp, &tfs);
898 	if (rc)
899 		return rc;
900 
901 	tfs->em_ext_db_handle = em_ext_db_handle;
902 	return rc;
903 }
904 
905 int
906 tf_session_get_db(struct tf *tfp,
907 		  enum tf_module_type type,
908 		  void **db_handle)
909 {
910 	struct tf_session *tfs = NULL;
911 	int rc = 0;
912 
913 	*db_handle = NULL;
914 
915 	if (tfp == NULL)
916 		return (-EINVAL);
917 
918 	rc = tf_session_get_session_internal(tfp, &tfs);
919 	if (rc)
920 		return rc;
921 
922 	switch (type) {
923 	case TF_MODULE_TYPE_IDENTIFIER:
924 		if (tfs->id_db_handle)
925 			*db_handle = tfs->id_db_handle;
926 		else
927 			rc = -ENOMEM;
928 		break;
929 	case TF_MODULE_TYPE_TABLE:
930 		if (tfs->tbl_db_handle)
931 			*db_handle = tfs->tbl_db_handle;
932 		else
933 			rc = -ENOMEM;
934 
935 		break;
936 	case TF_MODULE_TYPE_TCAM:
937 		if (tfs->tcam_db_handle)
938 			*db_handle = tfs->tcam_db_handle;
939 		else
940 			rc = -ENOMEM;
941 		break;
942 	case TF_MODULE_TYPE_EM:
943 		if (tfs->em_db_handle)
944 			*db_handle = tfs->em_db_handle;
945 		else
946 			rc = -ENOMEM;
947 		break;
948 	default:
949 		rc = -EINVAL;
950 		break;
951 	}
952 
953 	return rc;
954 }
955 
956 int
957 tf_session_set_db(struct tf *tfp,
958 		  enum tf_module_type type,
959 		  void *db_handle)
960 {
961 	struct tf_session *tfs = NULL;
962 	int rc = 0;
963 
964 	if (tfp == NULL)
965 		return (-EINVAL);
966 
967 	rc = tf_session_get_session_internal(tfp, &tfs);
968 	if (rc)
969 		return rc;
970 
971 	switch (type) {
972 	case TF_MODULE_TYPE_IDENTIFIER:
973 		tfs->id_db_handle = db_handle;
974 		break;
975 	case TF_MODULE_TYPE_TABLE:
976 		tfs->tbl_db_handle = db_handle;
977 		break;
978 	case TF_MODULE_TYPE_TCAM:
979 		tfs->tcam_db_handle = db_handle;
980 		break;
981 	case TF_MODULE_TYPE_EM:
982 		tfs->em_db_handle = db_handle;
983 		break;
984 	default:
985 		rc = -EINVAL;
986 		break;
987 	}
988 
989 	return rc;
990 }
991 
992 int
993 tf_session_get_tcam_shared_db(struct tf *tfp,
994 			      void **tcam_shared_db_handle)
995 {
996 	struct tf_session *tfs = NULL;
997 	int rc = 0;
998 
999 	*tcam_shared_db_handle = NULL;
1000 
1001 	if (tfp == NULL)
1002 		return (-EINVAL);
1003 
1004 	rc = tf_session_get_session_internal(tfp, &tfs);
1005 	if (rc)
1006 		return rc;
1007 
1008 	*tcam_shared_db_handle = tfs->tcam_shared_db_handle;
1009 	return rc;
1010 }
1011 
1012 int
1013 tf_session_set_tcam_shared_db(struct tf *tfp,
1014 			 void *tcam_shared_db_handle)
1015 {
1016 	struct tf_session *tfs = NULL;
1017 	int rc = 0;
1018 
1019 	if (tfp == NULL)
1020 		return (-EINVAL);
1021 
1022 	rc = tf_session_get_session_internal(tfp, &tfs);
1023 	if (rc)
1024 		return rc;
1025 
1026 	tfs->tcam_shared_db_handle = tcam_shared_db_handle;
1027 	return rc;
1028 }
1029 
1030 int
1031 tf_session_get_sram_db(struct tf *tfp,
1032 		       void **sram_handle)
1033 {
1034 	struct tf_session *tfs = NULL;
1035 	int rc = 0;
1036 
1037 	*sram_handle = NULL;
1038 
1039 	if (tfp == NULL)
1040 		return (-EINVAL);
1041 
1042 	rc = tf_session_get_session_internal(tfp, &tfs);
1043 	if (rc)
1044 		return rc;
1045 
1046 	*sram_handle = tfs->sram_handle;
1047 	return rc;
1048 }
1049 
1050 int
1051 tf_session_set_sram_db(struct tf *tfp,
1052 		       void *sram_handle)
1053 {
1054 	struct tf_session *tfs = NULL;
1055 	int rc = 0;
1056 
1057 	if (tfp == NULL)
1058 		return (-EINVAL);
1059 
1060 	rc = tf_session_get_session_internal(tfp, &tfs);
1061 	if (rc)
1062 		return rc;
1063 
1064 	tfs->sram_handle = sram_handle;
1065 	return rc;
1066 }
1067 
1068 int
1069 tf_session_get_global_db(struct tf *tfp,
1070 			 void **global_handle)
1071 {
1072 	struct tf_session *tfs = NULL;
1073 	int rc = 0;
1074 
1075 	*global_handle = NULL;
1076 
1077 	if (tfp == NULL)
1078 		return (-EINVAL);
1079 
1080 	rc = tf_session_get_session_internal(tfp, &tfs);
1081 	if (rc)
1082 		return rc;
1083 
1084 	*global_handle = tfs->global_db_handle;
1085 	return rc;
1086 }
1087 
1088 int
1089 tf_session_set_global_db(struct tf *tfp,
1090 			 void *global_handle)
1091 {
1092 	struct tf_session *tfs = NULL;
1093 	int rc = 0;
1094 
1095 	if (tfp == NULL)
1096 		return (-EINVAL);
1097 
1098 	rc = tf_session_get_session_internal(tfp, &tfs);
1099 	if (rc)
1100 		return rc;
1101 
1102 	tfs->global_db_handle = global_handle;
1103 	return rc;
1104 }
1105 
1106 int
1107 tf_session_get_if_tbl_db(struct tf *tfp,
1108 			 void **if_tbl_handle)
1109 {
1110 	struct tf_session *tfs = NULL;
1111 	int rc = 0;
1112 
1113 	*if_tbl_handle = NULL;
1114 
1115 	if (tfp == NULL)
1116 		return (-EINVAL);
1117 
1118 	rc = tf_session_get_session_internal(tfp, &tfs);
1119 	if (rc)
1120 		return rc;
1121 
1122 	*if_tbl_handle = tfs->if_tbl_db_handle;
1123 	return rc;
1124 }
1125 
1126 int
1127 tf_session_set_if_tbl_db(struct tf *tfp,
1128 			 void *if_tbl_handle)
1129 {
1130 	struct tf_session *tfs = NULL;
1131 	int rc = 0;
1132 
1133 	if (tfp == NULL)
1134 		return (-EINVAL);
1135 
1136 	rc = tf_session_get_session_internal(tfp, &tfs);
1137 	if (rc)
1138 		return rc;
1139 
1140 	tfs->if_tbl_db_handle = if_tbl_handle;
1141 	return rc;
1142 }
1143