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