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