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 1073 int 1074 tf_session_get_global_db(struct tf *tfp, 1075 void **global_handle) 1076 { 1077 struct tf_session *tfs = NULL; 1078 int rc = 0; 1079 1080 *global_handle = NULL; 1081 1082 if (tfp == NULL) 1083 return (-EINVAL); 1084 1085 rc = tf_session_get_session_internal(tfp, &tfs); 1086 if (rc) 1087 return rc; 1088 1089 *global_handle = tfs->global_db_handle; 1090 return rc; 1091 } 1092 1093 int 1094 tf_session_set_global_db(struct tf *tfp, 1095 void *global_handle) 1096 { 1097 struct tf_session *tfs = NULL; 1098 int rc = 0; 1099 1100 if (tfp == NULL) 1101 return (-EINVAL); 1102 1103 rc = tf_session_get_session_internal(tfp, &tfs); 1104 if (rc) 1105 return rc; 1106 1107 tfs->global_db_handle = global_handle; 1108 return rc; 1109 } 1110 1111 int 1112 tf_session_get_if_tbl_db(struct tf *tfp, 1113 void **if_tbl_handle) 1114 { 1115 struct tf_session *tfs = NULL; 1116 int rc = 0; 1117 1118 *if_tbl_handle = NULL; 1119 1120 if (tfp == NULL) 1121 return (-EINVAL); 1122 1123 rc = tf_session_get_session_internal(tfp, &tfs); 1124 if (rc) 1125 return rc; 1126 1127 *if_tbl_handle = tfs->if_tbl_db_handle; 1128 return rc; 1129 } 1130 1131 int 1132 tf_session_set_if_tbl_db(struct tf *tfp, 1133 void *if_tbl_handle) 1134 { 1135 struct tf_session *tfs = NULL; 1136 int rc = 0; 1137 1138 if (tfp == NULL) 1139 return (-EINVAL); 1140 1141 rc = tf_session_get_session_internal(tfp, &tfs); 1142 if (rc) 1143 return rc; 1144 1145 tfs->if_tbl_db_handle = if_tbl_handle; 1146 return rc; 1147 } 1148