1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019-2023 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <assert.h> 7 #include <inttypes.h> 8 #include <stdbool.h> 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include "tf_em_common.h" 13 #include "tf_msg_common.h" 14 #include "tf_device.h" 15 #include "tf_msg.h" 16 #include "tf_util.h" 17 #include "tf_common.h" 18 #include "tf_session.h" 19 #include "tfp.h" 20 #include "tf_em.h" 21 22 /* Specific msg size defines as we cannot use defines in tf.yaml. This 23 * means we have to manually sync hwrm with these defines if the 24 * tf.yaml changes. 25 */ 26 #define TF_MSG_SET_GLOBAL_CFG_DATA_SIZE 16 27 #define TF_MSG_EM_INSERT_KEY_SIZE 64 28 #define TF_MSG_EM_INSERT_RECORD_SIZE 96 29 #define TF_MSG_TBL_TYPE_SET_DATA_SIZE 88 30 31 /* Compile check - Catch any msg changes that we depend on, like the 32 * defines listed above for array size checking. 33 * 34 * Checking array size is dangerous in that the type could change and 35 * we wouldn't be able to catch it. Thus we check if the complete msg 36 * changed instead. Best we can do. 37 * 38 * If failure is observed then both msg size (defines below) and the 39 * array size (define above) should be checked and compared. 40 */ 41 #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56 42 static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) == 43 TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET, 44 "HWRM message size changed: hwrm_tf_global_cfg_set_input"); 45 46 #define TF_MSG_SIZE_HWRM_TF_EM_INSERT 104 47 static_assert(sizeof(struct hwrm_tf_em_insert_input) == 48 TF_MSG_SIZE_HWRM_TF_EM_INSERT, 49 "HWRM message size changed: hwrm_tf_em_insert_input"); 50 #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET 128 51 static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) == 52 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET, 53 "HWRM message size changed: hwrm_tf_tbl_type_set_input"); 54 55 /** 56 * This is the MAX data we can transport across regular HWRM 57 */ 58 #define TF_PCI_BUF_SIZE_MAX 88 59 60 /** 61 * This is the length of shared session name "tf_share" 62 */ 63 #define TF_SHARED_SESSION_NAME_LEN 9 64 65 /** 66 * This is the length of tcam shared session name "tf_shared-wc_tcam" 67 */ 68 #define TF_TCAM_SHARED_SESSION_NAME_LEN 17 69 70 /** 71 * This is the length of tcam shared session name "tf_shared-poolx" 72 */ 73 #define TF_POOL_SHARED_SESSION_NAME_LEN 16 74 75 /** 76 * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method 77 */ 78 struct tf_msg_dma_buf { 79 void *va_addr; 80 uint64_t pa_addr; 81 }; 82 83 /** 84 * Allocates a DMA buffer that can be used for message transfer. 85 * 86 * [in] buf 87 * Pointer to DMA buffer structure 88 * 89 * [in] size 90 * Requested size of the buffer in bytes 91 * 92 * Returns: 93 * 0 - Success 94 * -ENOMEM - Unable to allocate buffer, no memory 95 */ 96 static int 97 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size) 98 { 99 struct tfp_calloc_parms alloc_parms; 100 int rc; 101 102 /* Allocate session */ 103 alloc_parms.nitems = 1; 104 alloc_parms.size = size; 105 alloc_parms.alignment = 4096; 106 rc = tfp_calloc(&alloc_parms); 107 if (rc) 108 return -ENOMEM; 109 110 buf->pa_addr = (uintptr_t)alloc_parms.mem_pa; 111 buf->va_addr = alloc_parms.mem_va; 112 113 return 0; 114 } 115 116 /** 117 * Free's a previous allocated DMA buffer. 118 * 119 * [in] buf 120 * Pointer to DMA buffer structure 121 */ 122 static void 123 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf) 124 { 125 tfp_free(buf->va_addr); 126 } 127 128 /* HWRM Direct messages */ 129 130 int 131 tf_msg_session_open(struct bnxt *bp, 132 char *ctrl_chan_name, 133 uint8_t *fw_session_id, 134 uint8_t *fw_session_client_id, 135 struct tf_dev_info *dev, 136 bool *shared_session_creator) 137 { 138 int rc; 139 struct hwrm_tf_session_open_input req = { 0 }; 140 struct hwrm_tf_session_open_output resp = { 0 }; 141 struct tfp_send_msg_parms parms = { 0 }; 142 char *session_name; 143 char *tcam_session_name; 144 char *pool_session_name; 145 146 /* 147 * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0. 148 * "tf_shared-pool" is defined for version 1.0.1. 149 * "tf_shared" is used by both verions. 150 */ 151 tcam_session_name = strstr(ctrl_chan_name, "tf_shared-wc_tcam"); 152 pool_session_name = strstr(ctrl_chan_name, "tf_shared-pool"); 153 session_name = strstr(ctrl_chan_name, "tf_shared"); 154 if (tcam_session_name) 155 tfp_memcpy(&req.session_name, 156 tcam_session_name, 157 TF_TCAM_SHARED_SESSION_NAME_LEN); 158 else if (pool_session_name) 159 tfp_memcpy(&req.session_name, 160 pool_session_name, 161 TF_POOL_SHARED_SESSION_NAME_LEN); 162 else if (session_name) 163 tfp_memcpy(&req.session_name, 164 session_name, 165 TF_SHARED_SESSION_NAME_LEN); 166 else 167 tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX); 168 169 parms.tf_type = HWRM_TF_SESSION_OPEN; 170 parms.req_data = (uint32_t *)&req; 171 parms.req_size = sizeof(req); 172 parms.resp_data = (uint32_t *)&resp; 173 parms.resp_size = sizeof(resp); 174 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 175 176 rc = tfp_send_msg_direct(bp, 177 &parms); 178 if (rc) 179 return rc; 180 181 *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id); 182 *fw_session_client_id = 183 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id); 184 *shared_session_creator = (bool)tfp_le_to_cpu_32(resp.flags 185 & HWRM_TF_SESSION_OPEN_OUTPUT_FLAGS_SHARED_SESSION_CREATOR); 186 187 return rc; 188 } 189 190 int 191 tf_msg_session_attach(struct tf *tfp __rte_unused, 192 char *ctrl_chan_name __rte_unused, 193 uint8_t tf_fw_session_id __rte_unused) 194 { 195 return -1; 196 } 197 198 int 199 tf_msg_session_client_register(struct tf *tfp, 200 struct tf_session *tfs, 201 char *ctrl_channel_name, 202 uint8_t *fw_session_client_id) 203 { 204 int rc; 205 struct hwrm_tf_session_register_input req = { 0 }; 206 struct hwrm_tf_session_register_output resp = { 0 }; 207 struct tfp_send_msg_parms parms = { 0 }; 208 uint8_t fw_session_id; 209 struct tf_dev_info *dev; 210 char *session_name; 211 char *tcam_session_name; 212 char *pool_session_name; 213 214 /* Retrieve the device information */ 215 rc = tf_session_get_device(tfs, &dev); 216 if (rc) { 217 TFP_DRV_LOG(ERR, 218 "Failed to lookup device, rc:%s\n", 219 strerror(-rc)); 220 return rc; 221 } 222 223 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 224 if (rc) { 225 TFP_DRV_LOG(ERR, 226 "Unable to lookup FW id, rc:%s\n", 227 strerror(-rc)); 228 return rc; 229 } 230 231 /* Populate the request */ 232 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 233 234 /* 235 * "tf_shared-wc_tcam" is defined for tf_fw version 1.0.0. 236 * "tf_shared-pool" is defined for version 1.0.1. 237 * "tf_shared" is used by both verions. 238 */ 239 tcam_session_name = strstr(ctrl_channel_name, "tf_shared-wc_tcam"); 240 pool_session_name = strstr(ctrl_channel_name, "tf_shared-pool"); 241 session_name = strstr(ctrl_channel_name, "tf_shared"); 242 if (tcam_session_name) 243 tfp_memcpy(&req.session_client_name, 244 tcam_session_name, 245 TF_TCAM_SHARED_SESSION_NAME_LEN); 246 else if (pool_session_name) 247 tfp_memcpy(&req.session_client_name, 248 pool_session_name, 249 TF_POOL_SHARED_SESSION_NAME_LEN); 250 else if (session_name) 251 tfp_memcpy(&req.session_client_name, 252 session_name, 253 TF_SHARED_SESSION_NAME_LEN); 254 else 255 tfp_memcpy(&req.session_client_name, 256 ctrl_channel_name, 257 TF_SESSION_NAME_MAX); 258 259 parms.tf_type = HWRM_TF_SESSION_REGISTER; 260 parms.req_data = (uint32_t *)&req; 261 parms.req_size = sizeof(req); 262 parms.resp_data = (uint32_t *)&resp; 263 parms.resp_size = sizeof(resp); 264 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 265 266 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 267 &parms); 268 if (rc) 269 return rc; 270 271 *fw_session_client_id = 272 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id); 273 274 return rc; 275 } 276 277 int 278 tf_msg_session_client_unregister(struct tf *tfp, 279 struct tf_session *tfs, 280 uint8_t fw_session_client_id) 281 { 282 int rc; 283 struct hwrm_tf_session_unregister_input req = { 0 }; 284 struct hwrm_tf_session_unregister_output resp = { 0 }; 285 struct tfp_send_msg_parms parms = { 0 }; 286 uint8_t fw_session_id; 287 struct tf_dev_info *dev; 288 289 /* Retrieve the device information */ 290 rc = tf_session_get_device(tfs, &dev); 291 if (rc) { 292 TFP_DRV_LOG(ERR, 293 "Failed to lookup device, rc:%s\n", 294 strerror(-rc)); 295 return rc; 296 } 297 298 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 299 if (rc) { 300 TFP_DRV_LOG(ERR, 301 "Unable to lookup FW id, rc:%s\n", 302 strerror(-rc)); 303 return rc; 304 } 305 306 /* Populate the request */ 307 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 308 req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id); 309 310 parms.tf_type = HWRM_TF_SESSION_UNREGISTER; 311 parms.req_data = (uint32_t *)&req; 312 parms.req_size = sizeof(req); 313 parms.resp_data = (uint32_t *)&resp; 314 parms.resp_size = sizeof(resp); 315 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 316 317 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 318 &parms); 319 320 return rc; 321 } 322 323 int 324 tf_msg_session_close(struct tf *tfp, 325 uint8_t fw_session_id, 326 int mailbox) 327 { 328 int rc; 329 struct hwrm_tf_session_close_input req = { 0 }; 330 struct hwrm_tf_session_close_output resp = { 0 }; 331 struct tfp_send_msg_parms parms = { 0 }; 332 333 /* Populate the request */ 334 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 335 336 parms.tf_type = HWRM_TF_SESSION_CLOSE; 337 parms.req_data = (uint32_t *)&req; 338 parms.req_size = sizeof(req); 339 parms.resp_data = (uint32_t *)&resp; 340 parms.resp_size = sizeof(resp); 341 parms.mailbox = mailbox; 342 343 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 344 &parms); 345 return rc; 346 } 347 348 int 349 tf_msg_session_qcfg(struct tf *tfp) 350 { 351 int rc; 352 struct hwrm_tf_session_qcfg_input req = { 0 }; 353 struct hwrm_tf_session_qcfg_output resp = { 0 }; 354 struct tfp_send_msg_parms parms = { 0 }; 355 uint8_t fw_session_id; 356 struct tf_dev_info *dev; 357 struct tf_session *tfs; 358 359 /* Retrieve the session information */ 360 rc = tf_session_get_session_internal(tfp, &tfs); 361 if (rc) { 362 TFP_DRV_LOG(ERR, 363 "Failed to lookup session, rc:%s\n", 364 strerror(-rc)); 365 return rc; 366 } 367 368 /* Retrieve the device information */ 369 rc = tf_session_get_device(tfs, &dev); 370 if (rc) { 371 TFP_DRV_LOG(ERR, 372 "Failed to lookup device, rc:%s\n", 373 strerror(-rc)); 374 return rc; 375 } 376 377 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 378 if (rc) { 379 TFP_DRV_LOG(ERR, 380 "Unable to lookup FW id, rc:%s\n", 381 strerror(-rc)); 382 return rc; 383 } 384 385 /* Populate the request */ 386 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 387 388 parms.tf_type = HWRM_TF_SESSION_QCFG, 389 parms.req_data = (uint32_t *)&req; 390 parms.req_size = sizeof(req); 391 parms.resp_data = (uint32_t *)&resp; 392 parms.resp_size = sizeof(resp); 393 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 394 395 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 396 &parms); 397 return rc; 398 } 399 400 int 401 tf_msg_session_resc_qcaps(struct tf *tfp, 402 struct tf_dev_info *dev, 403 enum tf_dir dir, 404 uint16_t size, 405 struct tf_rm_resc_req_entry *query, 406 enum tf_rm_resc_resv_strategy *resv_strategy, 407 uint8_t *sram_profile) 408 { 409 int rc; 410 int i; 411 struct tfp_send_msg_parms parms = { 0 }; 412 struct hwrm_tf_session_resc_qcaps_input req = { 0 }; 413 struct hwrm_tf_session_resc_qcaps_output resp = { 0 }; 414 struct tf_msg_dma_buf qcaps_buf = { 0 }; 415 struct tf_rm_resc_req_entry *data; 416 int dma_size; 417 418 TF_CHECK_PARMS3(tfp, query, resv_strategy); 419 420 /* Prepare DMA buffer */ 421 dma_size = size * sizeof(struct tf_rm_resc_req_entry); 422 rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size); 423 if (rc) 424 return rc; 425 426 /* Populate the request */ 427 req.fw_session_id = 0; 428 req.flags = tfp_cpu_to_le_16(dir); 429 req.qcaps_size = size; 430 req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr); 431 432 parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS; 433 parms.req_data = (uint32_t *)&req; 434 parms.req_size = sizeof(req); 435 parms.resp_data = (uint32_t *)&resp; 436 parms.resp_size = sizeof(resp); 437 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 438 439 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 440 if (rc) 441 goto cleanup; 442 443 /* Process the response 444 * Should always get expected number of entries 445 */ 446 if (tfp_le_to_cpu_32(resp.size) != size) { 447 TFP_DRV_LOG(WARNING, 448 "%s: QCAPS message size error, rc:%s, request %d vs response %d\n", 449 tf_dir_2_str(dir), 450 strerror(EINVAL), 451 size, 452 resp.size); 453 } 454 455 /* Post process the response */ 456 data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr; 457 for (i = 0; i < resp.size; i++) { 458 query[i].type = tfp_le_to_cpu_32(data[i].type); 459 query[i].min = tfp_le_to_cpu_16(data[i].min); 460 query[i].max = tfp_le_to_cpu_16(data[i].max); 461 } 462 463 *resv_strategy = resp.flags & 464 HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK; 465 466 if (sram_profile != NULL) 467 *sram_profile = resp.sram_profile; 468 469 cleanup: 470 tf_msg_free_dma_buf(&qcaps_buf); 471 472 return rc; 473 } 474 475 int 476 tf_msg_session_resc_alloc(struct tf *tfp, 477 struct tf_dev_info *dev, 478 enum tf_dir dir, 479 uint16_t size, 480 struct tf_rm_resc_req_entry *request, 481 struct tf_rm_resc_entry *resv) 482 { 483 int rc; 484 int i; 485 struct tfp_send_msg_parms parms = { 0 }; 486 struct hwrm_tf_session_resc_alloc_input req = { 0 }; 487 struct hwrm_tf_session_resc_alloc_output resp = { 0 }; 488 uint8_t fw_session_id; 489 struct tf_msg_dma_buf req_buf = { 0 }; 490 struct tf_msg_dma_buf resv_buf = { 0 }; 491 struct tf_rm_resc_req_entry *req_data; 492 struct tf_rm_resc_entry *resv_data; 493 int dma_size; 494 struct tf_session *tfs; 495 496 /* Retrieve the session information */ 497 rc = tf_session_get_session_internal(tfp, &tfs); 498 if (rc) { 499 TFP_DRV_LOG(ERR, 500 "Failed to lookup session, rc:%s\n", 501 strerror(-rc)); 502 return rc; 503 } 504 505 TF_CHECK_PARMS3(tfp, request, resv); 506 507 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 508 if (rc) { 509 TFP_DRV_LOG(ERR, 510 "%s: Unable to lookup FW id, rc:%s\n", 511 tf_dir_2_str(dir), 512 strerror(-rc)); 513 return rc; 514 } 515 516 /* Prepare DMA buffers */ 517 dma_size = size * sizeof(struct tf_rm_resc_req_entry); 518 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size); 519 if (rc) 520 return rc; 521 522 dma_size = size * sizeof(struct tf_rm_resc_entry); 523 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size); 524 if (rc) { 525 tf_msg_free_dma_buf(&req_buf); 526 return rc; 527 } 528 529 /* Populate the request */ 530 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 531 req.flags = tfp_cpu_to_le_16(dir); 532 req.req_size = size; 533 534 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr; 535 for (i = 0; i < size; i++) { 536 req_data[i].type = tfp_cpu_to_le_32(request[i].type); 537 req_data[i].min = tfp_cpu_to_le_16(request[i].min); 538 req_data[i].max = tfp_cpu_to_le_16(request[i].max); 539 } 540 541 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr); 542 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr); 543 544 parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC; 545 parms.req_data = (uint32_t *)&req; 546 parms.req_size = sizeof(req); 547 parms.resp_data = (uint32_t *)&resp; 548 parms.resp_size = sizeof(resp); 549 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 550 551 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 552 if (rc) 553 goto cleanup; 554 555 /* Process the response 556 * Should always get expected number of entries 557 */ 558 if (tfp_le_to_cpu_32(resp.size) != size) { 559 TFP_DRV_LOG(ERR, 560 "%s: Alloc message size error, rc:%s\n", 561 tf_dir_2_str(dir), 562 strerror(EINVAL)); 563 rc = -EINVAL; 564 goto cleanup; 565 } 566 567 /* Post process the response */ 568 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr; 569 for (i = 0; i < size; i++) { 570 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type); 571 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start); 572 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride); 573 } 574 575 cleanup: 576 tf_msg_free_dma_buf(&req_buf); 577 tf_msg_free_dma_buf(&resv_buf); 578 579 return rc; 580 } 581 582 int 583 tf_msg_session_resc_info(struct tf *tfp, 584 struct tf_dev_info *dev, 585 enum tf_dir dir, 586 uint16_t size, 587 struct tf_rm_resc_req_entry *request, 588 struct tf_rm_resc_entry *resv) 589 { 590 int rc; 591 int i; 592 struct tfp_send_msg_parms parms = { 0 }; 593 struct hwrm_tf_session_resc_info_input req = { 0 }; 594 struct hwrm_tf_session_resc_info_output resp = { 0 }; 595 uint8_t fw_session_id; 596 struct tf_msg_dma_buf req_buf = { 0 }; 597 struct tf_msg_dma_buf resv_buf = { 0 }; 598 struct tf_rm_resc_req_entry *req_data; 599 struct tf_rm_resc_entry *resv_data; 600 int dma_size; 601 struct tf_session *tfs; 602 603 /* Retrieve the session information */ 604 rc = tf_session_get_session_internal(tfp, &tfs); 605 if (rc) { 606 TFP_DRV_LOG(ERR, 607 "Failed to lookup session, rc:%s\n", 608 strerror(-rc)); 609 return rc; 610 } 611 612 TF_CHECK_PARMS3(tfp, request, resv); 613 614 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 615 if (rc) { 616 TFP_DRV_LOG(ERR, 617 "%s: Unable to lookup FW id, rc:%s\n", 618 tf_dir_2_str(dir), 619 strerror(-rc)); 620 return rc; 621 } 622 623 /* Prepare DMA buffers */ 624 dma_size = size * sizeof(struct tf_rm_resc_req_entry); 625 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size); 626 if (rc) 627 return rc; 628 629 dma_size = size * sizeof(struct tf_rm_resc_entry); 630 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size); 631 if (rc) { 632 tf_msg_free_dma_buf(&req_buf); 633 return rc; 634 } 635 636 /* Populate the request */ 637 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 638 req.flags = tfp_cpu_to_le_16(dir); 639 req.req_size = size; 640 641 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr; 642 for (i = 0; i < size; i++) { 643 req_data[i].type = tfp_cpu_to_le_32(request[i].type); 644 req_data[i].min = tfp_cpu_to_le_16(request[i].min); 645 req_data[i].max = tfp_cpu_to_le_16(request[i].max); 646 } 647 648 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr); 649 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr); 650 651 parms.tf_type = HWRM_TF_SESSION_RESC_INFO; 652 parms.req_data = (uint32_t *)&req; 653 parms.req_size = sizeof(req); 654 parms.resp_data = (uint32_t *)&resp; 655 parms.resp_size = sizeof(resp); 656 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 657 658 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 659 if (rc) 660 goto cleanup; 661 662 /* Process the response 663 * Should always get expected number of entries 664 */ 665 if (tfp_le_to_cpu_32(resp.size) != size) { 666 TFP_DRV_LOG(ERR, 667 "%s: Alloc message size error, rc:%s\n", 668 tf_dir_2_str(dir), 669 strerror(EINVAL)); 670 rc = -EINVAL; 671 goto cleanup; 672 } 673 674 /* Post process the response */ 675 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr; 676 for (i = 0; i < size; i++) { 677 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type); 678 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start); 679 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride); 680 } 681 682 cleanup: 683 tf_msg_free_dma_buf(&req_buf); 684 tf_msg_free_dma_buf(&resv_buf); 685 686 return rc; 687 } 688 689 int 690 tf_msg_session_resc_flush(struct tf *tfp, 691 enum tf_dir dir, 692 uint16_t size, 693 struct tf_rm_resc_entry *resv) 694 { 695 int rc; 696 int i; 697 struct tfp_send_msg_parms parms = { 0 }; 698 struct hwrm_tf_session_resc_flush_input req = { 0 }; 699 struct hwrm_tf_session_resc_flush_output resp = { 0 }; 700 uint8_t fw_session_id; 701 struct tf_msg_dma_buf resv_buf = { 0 }; 702 struct tf_rm_resc_entry *resv_data; 703 int dma_size; 704 struct tf_dev_info *dev; 705 struct tf_session *tfs; 706 707 TF_CHECK_PARMS2(tfp, resv); 708 709 /* Retrieve the session information */ 710 rc = tf_session_get_session_internal(tfp, &tfs); 711 if (rc) { 712 TFP_DRV_LOG(ERR, 713 "%s: Failed to lookup session, rc:%s\n", 714 tf_dir_2_str(dir), 715 strerror(-rc)); 716 return rc; 717 } 718 719 /* Retrieve the device information */ 720 rc = tf_session_get_device(tfs, &dev); 721 if (rc) { 722 TFP_DRV_LOG(ERR, 723 "%s: Failed to lookup device, rc:%s\n", 724 tf_dir_2_str(dir), 725 strerror(-rc)); 726 return rc; 727 } 728 729 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 730 if (rc) { 731 TFP_DRV_LOG(ERR, 732 "%s: Unable to lookup FW id, rc:%s\n", 733 tf_dir_2_str(dir), 734 strerror(-rc)); 735 return rc; 736 } 737 738 /* Prepare DMA buffers */ 739 dma_size = size * sizeof(struct tf_rm_resc_entry); 740 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size); 741 if (rc) 742 return rc; 743 744 /* Populate the request */ 745 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 746 req.flags = tfp_cpu_to_le_16(dir); 747 req.flush_size = size; 748 749 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr; 750 for (i = 0; i < size; i++) { 751 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type); 752 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start); 753 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride); 754 } 755 756 req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr); 757 758 parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH; 759 parms.req_data = (uint32_t *)&req; 760 parms.req_size = sizeof(req); 761 parms.resp_data = (uint32_t *)&resp; 762 parms.resp_size = sizeof(resp); 763 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 764 765 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 766 767 tf_msg_free_dma_buf(&resv_buf); 768 769 return rc; 770 } 771 772 int 773 tf_msg_insert_em_internal_entry(struct tf *tfp, 774 struct tf_insert_em_entry_parms *em_parms, 775 uint16_t *rptr_index, 776 uint8_t *rptr_entry, 777 uint8_t *num_of_entries) 778 { 779 int rc; 780 struct tfp_send_msg_parms parms = { 0 }; 781 struct hwrm_tf_em_insert_input req = { 0 }; 782 struct hwrm_tf_em_insert_output resp = { 0 }; 783 struct tf_em_64b_entry *em_result = 784 (struct tf_em_64b_entry *)em_parms->em_record; 785 uint16_t flags; 786 uint8_t fw_session_id; 787 uint8_t msg_key_size; 788 struct tf_dev_info *dev; 789 struct tf_session *tfs; 790 791 RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_em_insert_input) != 792 TF_MSG_SIZE_HWRM_TF_EM_INSERT); 793 794 /* Retrieve the session information */ 795 rc = tf_session_get_session_internal(tfp, &tfs); 796 if (rc) { 797 TFP_DRV_LOG(ERR, 798 "%s: Failed to lookup session, rc:%s\n", 799 tf_dir_2_str(em_parms->dir), 800 strerror(-rc)); 801 return rc; 802 } 803 804 /* Retrieve the device information */ 805 rc = tf_session_get_device(tfs, &dev); 806 if (rc) { 807 TFP_DRV_LOG(ERR, 808 "%s: Failed to lookup device, rc:%s\n", 809 tf_dir_2_str(em_parms->dir), 810 strerror(-rc)); 811 return rc; 812 } 813 814 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 815 if (rc) { 816 TFP_DRV_LOG(ERR, 817 "%s: Unable to lookup FW id, rc:%s\n", 818 tf_dir_2_str(em_parms->dir), 819 strerror(-rc)); 820 return rc; 821 } 822 823 /* Populate the request */ 824 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 825 826 /* Check for key size conformity */ 827 msg_key_size = (em_parms->key_sz_in_bits + 7) / 8; 828 if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) { 829 rc = -EINVAL; 830 TFP_DRV_LOG(ERR, 831 "%s: Invalid parameters for msg type, rc:%s\n", 832 tf_dir_2_str(em_parms->dir), 833 strerror(-rc)); 834 return rc; 835 } 836 837 tfp_memcpy(req.em_key, 838 em_parms->key, 839 msg_key_size); 840 841 flags = (em_parms->dir == TF_DIR_TX ? 842 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX : 843 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX); 844 req.flags = tfp_cpu_to_le_16(flags); 845 req.strength = (em_result->hdr.word1 & 846 CFA_P4_EEM_ENTRY_STRENGTH_MASK) >> 847 CFA_P4_EEM_ENTRY_STRENGTH_SHIFT; 848 req.em_key_bitlen = em_parms->key_sz_in_bits; 849 req.action_ptr = em_result->hdr.pointer; 850 req.em_record_idx = *rptr_index; 851 852 parms.tf_type = HWRM_TF_EM_INSERT; 853 parms.req_data = (uint32_t *)&req; 854 parms.req_size = sizeof(req); 855 parms.resp_data = (uint32_t *)&resp; 856 parms.resp_size = sizeof(resp); 857 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 858 859 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 860 &parms); 861 if (rc) 862 return rc; 863 864 *rptr_entry = resp.rptr_entry; 865 *rptr_index = resp.rptr_index; 866 *num_of_entries = resp.num_of_entries; 867 868 return 0; 869 } 870 871 int 872 tf_msg_hash_insert_em_internal_entry(struct tf *tfp, 873 struct tf_insert_em_entry_parms *em_parms, 874 uint32_t key0_hash, 875 uint32_t key1_hash, 876 uint16_t *rptr_index, 877 uint8_t *rptr_entry, 878 uint8_t *num_of_entries) 879 { 880 int rc; 881 struct tfp_send_msg_parms parms = { 0 }; 882 struct hwrm_tf_em_hash_insert_input req = { 0 }; 883 struct hwrm_tf_em_hash_insert_output resp = { 0 }; 884 uint16_t flags; 885 uint8_t fw_session_id; 886 uint8_t msg_record_size; 887 struct tf_dev_info *dev; 888 struct tf_session *tfs; 889 890 /* Retrieve the session information */ 891 rc = tf_session_get_session_internal(tfp, &tfs); 892 if (rc) { 893 TFP_DRV_LOG(ERR, 894 "%s: Failed to lookup session, rc:%s\n", 895 tf_dir_2_str(em_parms->dir), 896 strerror(-rc)); 897 return rc; 898 } 899 900 /* Retrieve the device information */ 901 rc = tf_session_get_device(tfs, &dev); 902 if (rc) { 903 TFP_DRV_LOG(ERR, 904 "%s: Failed to lookup device, rc:%s\n", 905 tf_dir_2_str(em_parms->dir), 906 strerror(-rc)); 907 return rc; 908 } 909 910 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 911 if (rc) { 912 TFP_DRV_LOG(ERR, 913 "%s: Unable to lookup FW id, rc:%s\n", 914 tf_dir_2_str(em_parms->dir), 915 strerror(-rc)); 916 return rc; 917 } 918 919 /* Populate the request */ 920 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 921 922 /* Check for key size conformity */ 923 msg_record_size = (em_parms->em_record_sz_in_bits + 7) / 8; 924 925 if (msg_record_size > TF_MSG_EM_INSERT_RECORD_SIZE) { 926 rc = -EINVAL; 927 TFP_DRV_LOG(ERR, 928 "%s: Record size too large, rc:%s\n", 929 tf_dir_2_str(em_parms->dir), 930 strerror(-rc)); 931 return rc; 932 } 933 934 tfp_memcpy((char *)req.em_record, 935 em_parms->em_record, 936 msg_record_size); 937 938 flags = (em_parms->dir == TF_DIR_TX ? 939 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX : 940 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX); 941 req.flags = tfp_cpu_to_le_16(flags); 942 req.em_record_size_bits = em_parms->em_record_sz_in_bits; 943 req.em_record_idx = *rptr_index; 944 req.key0_hash = key0_hash; 945 req.key1_hash = key1_hash; 946 947 parms.tf_type = HWRM_TF_EM_HASH_INSERT; 948 parms.req_data = (uint32_t *)&req; 949 parms.req_size = sizeof(req); 950 parms.resp_data = (uint32_t *)&resp; 951 parms.resp_size = sizeof(resp); 952 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 953 954 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 955 &parms); 956 if (rc) 957 return rc; 958 959 *rptr_entry = resp.rptr_entry; 960 *rptr_index = resp.rptr_index; 961 *num_of_entries = resp.num_of_entries; 962 963 return 0; 964 } 965 966 int 967 tf_msg_delete_em_entry(struct tf *tfp, 968 struct tf_delete_em_entry_parms *em_parms) 969 { 970 int rc; 971 struct tfp_send_msg_parms parms = { 0 }; 972 struct hwrm_tf_em_delete_input req = { 0 }; 973 struct hwrm_tf_em_delete_output resp = { 0 }; 974 uint16_t flags; 975 uint8_t fw_session_id; 976 struct tf_dev_info *dev; 977 struct tf_session *tfs; 978 979 /* Retrieve the session information */ 980 rc = tf_session_get_session_internal(tfp, &tfs); 981 if (rc) { 982 TFP_DRV_LOG(ERR, 983 "%s: Failed to lookup session, rc:%s\n", 984 tf_dir_2_str(em_parms->dir), 985 strerror(-rc)); 986 return rc; 987 } 988 989 /* Retrieve the device information */ 990 rc = tf_session_get_device(tfs, &dev); 991 if (rc) { 992 TFP_DRV_LOG(ERR, 993 "%s: Failed to lookup device, rc:%s\n", 994 tf_dir_2_str(em_parms->dir), 995 strerror(-rc)); 996 return rc; 997 } 998 999 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1000 if (rc) { 1001 TFP_DRV_LOG(ERR, 1002 "%s: Unable to lookup FW id, rc:%s\n", 1003 tf_dir_2_str(em_parms->dir), 1004 strerror(-rc)); 1005 return rc; 1006 } 1007 1008 /* Populate the request */ 1009 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1010 1011 flags = (em_parms->dir == TF_DIR_TX ? 1012 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX : 1013 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX); 1014 req.flags = tfp_cpu_to_le_16(flags); 1015 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle); 1016 1017 parms.tf_type = HWRM_TF_EM_DELETE; 1018 parms.req_data = (uint32_t *)&req; 1019 parms.req_size = sizeof(req); 1020 parms.resp_data = (uint32_t *)&resp; 1021 parms.resp_size = sizeof(resp); 1022 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1023 1024 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1025 &parms); 1026 if (rc) 1027 return rc; 1028 1029 em_parms->index = tfp_le_to_cpu_16(resp.em_index); 1030 1031 return 0; 1032 } 1033 1034 int 1035 tf_msg_move_em_entry(struct tf *tfp, 1036 struct tf_move_em_entry_parms *em_parms) 1037 { 1038 int rc; 1039 struct tfp_send_msg_parms parms = { 0 }; 1040 struct hwrm_tf_em_move_input req = { 0 }; 1041 struct hwrm_tf_em_move_output resp = { 0 }; 1042 uint16_t flags; 1043 uint8_t fw_session_id; 1044 struct tf_dev_info *dev; 1045 struct tf_session *tfs; 1046 1047 /* Retrieve the session information */ 1048 rc = tf_session_get_session_internal(tfp, &tfs); 1049 if (rc) { 1050 TFP_DRV_LOG(ERR, 1051 "%s: Failed to lookup session, rc:%s\n", 1052 tf_dir_2_str(em_parms->dir), 1053 strerror(-rc)); 1054 return rc; 1055 } 1056 1057 /* Retrieve the device information */ 1058 rc = tf_session_get_device(tfs, &dev); 1059 if (rc) { 1060 TFP_DRV_LOG(ERR, 1061 "%s: Failed to lookup device, rc:%s\n", 1062 tf_dir_2_str(em_parms->dir), 1063 strerror(-rc)); 1064 return rc; 1065 } 1066 1067 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1068 if (rc) { 1069 TFP_DRV_LOG(ERR, 1070 "%s: Unable to lookup FW id, rc:%s\n", 1071 tf_dir_2_str(em_parms->dir), 1072 strerror(-rc)); 1073 return rc; 1074 } 1075 1076 /* Populate the request */ 1077 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1078 1079 flags = (em_parms->dir == TF_DIR_TX ? 1080 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX : 1081 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX); 1082 req.flags = tfp_cpu_to_le_16(flags); 1083 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle); 1084 req.new_index = tfp_cpu_to_le_32(em_parms->new_index); 1085 1086 parms.tf_type = HWRM_TF_EM_MOVE; 1087 parms.req_data = (uint32_t *)&req; 1088 parms.req_size = sizeof(req); 1089 parms.resp_data = (uint32_t *)&resp; 1090 parms.resp_size = sizeof(resp); 1091 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1092 1093 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1094 &parms); 1095 if (rc) 1096 return rc; 1097 1098 em_parms->index = tfp_le_to_cpu_16(resp.em_index); 1099 1100 return 0; 1101 } 1102 1103 int 1104 tf_msg_tcam_entry_set(struct tf *tfp, 1105 struct tf_dev_info *dev, 1106 struct tf_tcam_set_parms *parms) 1107 { 1108 int rc; 1109 struct tfp_send_msg_parms mparms = { 0 }; 1110 struct hwrm_tf_tcam_set_input req = { 0 }; 1111 struct hwrm_tf_tcam_set_output resp = { 0 }; 1112 struct tf_msg_dma_buf buf = { 0 }; 1113 uint8_t *data = NULL; 1114 int data_size = 0; 1115 uint8_t fw_session_id; 1116 struct tf_session *tfs; 1117 1118 /* Retrieve the session information */ 1119 rc = tf_session_get_session_internal(tfp, &tfs); 1120 if (rc) { 1121 TFP_DRV_LOG(ERR, 1122 "Failed to lookup session, rc:%s\n", 1123 strerror(-rc)); 1124 return rc; 1125 } 1126 1127 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1128 if (rc) { 1129 TFP_DRV_LOG(ERR, 1130 "%s: Unable to lookup FW id, rc:%s\n", 1131 tf_dir_2_str(parms->dir), 1132 strerror(-rc)); 1133 return rc; 1134 } 1135 1136 /* Populate the request */ 1137 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1138 req.type = parms->hcapi_type; 1139 req.idx = tfp_cpu_to_le_16(parms->idx); 1140 if (parms->dir == TF_DIR_TX) 1141 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX; 1142 1143 req.key_size = parms->key_size; 1144 req.mask_offset = parms->key_size; 1145 /* Result follows after key and mask, thus multiply by 2 */ 1146 req.result_offset = 2 * parms->key_size; 1147 req.result_size = parms->result_size; 1148 data_size = 2 * req.key_size + req.result_size; 1149 1150 /* 1151 * Always use dma buffer, as the delete multi slice 1152 * tcam entries not support with HWRM request buffer 1153 * only DMA'ed buffer can update the mode bits for 1154 * the delete to work 1155 */ 1156 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA; 1157 rc = tf_msg_alloc_dma_buf(&buf, data_size); 1158 if (rc) 1159 goto cleanup; 1160 data = buf.va_addr; 1161 tfp_memcpy(&req.dev_data[0], 1162 &buf.pa_addr, 1163 sizeof(buf.pa_addr)); 1164 1165 tfp_memcpy(&data[0], parms->key, parms->key_size); 1166 tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size); 1167 tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size); 1168 1169 mparms.tf_type = HWRM_TF_TCAM_SET; 1170 mparms.req_data = (uint32_t *)&req; 1171 mparms.req_size = sizeof(req); 1172 mparms.resp_data = (uint32_t *)&resp; 1173 mparms.resp_size = sizeof(resp); 1174 mparms.mailbox = dev->ops->tf_dev_get_mailbox(); 1175 1176 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1177 &mparms); 1178 1179 cleanup: 1180 tf_msg_free_dma_buf(&buf); 1181 1182 return rc; 1183 } 1184 1185 int 1186 tf_msg_tcam_entry_get(struct tf *tfp, 1187 struct tf_dev_info *dev, 1188 struct tf_tcam_get_parms *parms) 1189 { 1190 int rc; 1191 struct tfp_send_msg_parms mparms = { 0 }; 1192 struct hwrm_tf_tcam_get_input req = { 0 }; 1193 struct hwrm_tf_tcam_get_output resp = { 0 }; 1194 uint8_t fw_session_id; 1195 struct tf_session *tfs; 1196 1197 /* Retrieve the session information */ 1198 rc = tf_session_get_session_internal(tfp, &tfs); 1199 if (rc) { 1200 TFP_DRV_LOG(ERR, 1201 "Failed to lookup session, rc:%s\n", 1202 strerror(-rc)); 1203 return rc; 1204 } 1205 1206 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1207 if (rc) { 1208 TFP_DRV_LOG(ERR, 1209 "%s: Unable to lookup FW id, rc:%s\n", 1210 tf_dir_2_str(parms->dir), 1211 strerror(-rc)); 1212 return rc; 1213 } 1214 1215 /* Populate the request */ 1216 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1217 req.type = parms->hcapi_type; 1218 req.idx = tfp_cpu_to_le_16(parms->idx); 1219 if (parms->dir == TF_DIR_TX) 1220 req.flags |= HWRM_TF_TCAM_GET_INPUT_FLAGS_DIR_TX; 1221 1222 mparms.tf_type = HWRM_TF_TCAM_GET; 1223 mparms.req_data = (uint32_t *)&req; 1224 mparms.req_size = sizeof(req); 1225 mparms.resp_data = (uint32_t *)&resp; 1226 mparms.resp_size = sizeof(resp); 1227 mparms.mailbox = dev->ops->tf_dev_get_mailbox(); 1228 1229 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1230 &mparms); 1231 1232 if (rc != 0) 1233 return rc; 1234 1235 if (parms->key_size < resp.key_size || 1236 parms->result_size < resp.result_size) { 1237 rc = -EINVAL; 1238 TFP_DRV_LOG(ERR, 1239 "%s: Key buffer(%d) is smaller than the key(%d), rc:%s\n", 1240 tf_dir_2_str(parms->dir), 1241 parms->key_size, 1242 resp.key_size, 1243 strerror(-rc)); 1244 return rc; 1245 } 1246 parms->key_size = resp.key_size; 1247 parms->result_size = resp.result_size; 1248 tfp_memcpy(parms->key, resp.dev_data, resp.key_size); 1249 tfp_memcpy(parms->mask, &resp.dev_data[resp.key_size], resp.key_size); 1250 tfp_memcpy(parms->result, &resp.dev_data[resp.result_offset], resp.result_size); 1251 1252 return 0; 1253 } 1254 1255 int 1256 tf_msg_tcam_entry_free(struct tf *tfp, 1257 struct tf_dev_info *dev, 1258 struct tf_tcam_free_parms *in_parms) 1259 { 1260 int rc; 1261 struct hwrm_tf_tcam_free_input req = { 0 }; 1262 struct hwrm_tf_tcam_free_output resp = { 0 }; 1263 struct tfp_send_msg_parms parms = { 0 }; 1264 uint8_t fw_session_id; 1265 struct tf_session *tfs; 1266 1267 /* Retrieve the session information */ 1268 rc = tf_session_get_session_internal(tfp, &tfs); 1269 if (rc) { 1270 TFP_DRV_LOG(ERR, 1271 "Failed to lookup session, rc:%s\n", 1272 strerror(-rc)); 1273 return rc; 1274 } 1275 1276 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1277 if (rc) { 1278 TFP_DRV_LOG(ERR, 1279 "%s: Unable to lookup FW id, rc:%s\n", 1280 tf_dir_2_str(in_parms->dir), 1281 strerror(-rc)); 1282 return rc; 1283 } 1284 1285 /* Populate the request */ 1286 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1287 req.type = in_parms->hcapi_type; 1288 req.count = 1; 1289 req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx); 1290 if (in_parms->dir == TF_DIR_TX) 1291 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX; 1292 1293 parms.tf_type = HWRM_TF_TCAM_FREE; 1294 parms.req_data = (uint32_t *)&req; 1295 parms.req_size = sizeof(req); 1296 parms.resp_data = (uint32_t *)&resp; 1297 parms.resp_size = sizeof(resp); 1298 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1299 1300 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1301 &parms); 1302 return rc; 1303 } 1304 1305 int 1306 tf_msg_set_tbl_entry(struct tf *tfp, 1307 enum tf_dir dir, 1308 uint16_t hcapi_type, 1309 uint16_t size, 1310 uint8_t *data, 1311 uint32_t index) 1312 { 1313 int rc; 1314 struct hwrm_tf_tbl_type_set_input req = { 0 }; 1315 struct hwrm_tf_tbl_type_set_output resp = { 0 }; 1316 struct tfp_send_msg_parms parms = { 0 }; 1317 struct tf_msg_dma_buf buf = { 0 }; 1318 uint8_t fw_session_id; 1319 struct tf_dev_info *dev; 1320 struct tf_session *tfs; 1321 1322 RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_tbl_type_set_input) != 1323 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET); 1324 1325 /* Retrieve the session information */ 1326 rc = tf_session_get_session_internal(tfp, &tfs); 1327 if (rc) { 1328 TFP_DRV_LOG(ERR, 1329 "%s: Failed to lookup session, rc:%s\n", 1330 tf_dir_2_str(dir), 1331 strerror(-rc)); 1332 return rc; 1333 } 1334 1335 /* Retrieve the device information */ 1336 rc = tf_session_get_device(tfs, &dev); 1337 if (rc) { 1338 TFP_DRV_LOG(ERR, 1339 "%s: Failed to lookup device, rc:%s\n", 1340 tf_dir_2_str(dir), 1341 strerror(-rc)); 1342 return rc; 1343 } 1344 1345 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1346 if (rc) { 1347 TFP_DRV_LOG(ERR, 1348 "%s: Unable to lookup FW id, rc:%s\n", 1349 tf_dir_2_str(dir), 1350 strerror(-rc)); 1351 return rc; 1352 } 1353 1354 /* Populate the request */ 1355 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1356 req.flags = tfp_cpu_to_le_16(dir); 1357 req.type = tfp_cpu_to_le_32(hcapi_type); 1358 req.size = tfp_cpu_to_le_16(size); 1359 req.index = tfp_cpu_to_le_32(index); 1360 1361 /* Check for data size conformity */ 1362 if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) { 1363 /* use dma buffer */ 1364 req.flags |= HWRM_TF_TBL_TYPE_SET_INPUT_FLAGS_DMA; 1365 rc = tf_msg_alloc_dma_buf(&buf, size); 1366 if (rc) 1367 goto cleanup; 1368 tfp_memcpy(buf.va_addr, data, size); 1369 tfp_memcpy(&req.data[0], 1370 &buf.pa_addr, 1371 sizeof(buf.pa_addr)); 1372 } else { 1373 tfp_memcpy(&req.data, data, size); 1374 } 1375 1376 parms.tf_type = HWRM_TF_TBL_TYPE_SET; 1377 parms.req_data = (uint32_t *)&req; 1378 parms.req_size = sizeof(req); 1379 parms.resp_data = (uint32_t *)&resp; 1380 parms.resp_size = sizeof(resp); 1381 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1382 1383 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1384 &parms); 1385 cleanup: 1386 tf_msg_free_dma_buf(&buf); 1387 1388 return rc; 1389 } 1390 1391 int 1392 tf_msg_get_tbl_entry(struct tf *tfp, 1393 enum tf_dir dir, 1394 uint16_t hcapi_type, 1395 uint16_t size, 1396 uint8_t *data, 1397 uint32_t index, 1398 bool clear_on_read) 1399 { 1400 int rc; 1401 struct hwrm_tf_tbl_type_get_input req = { 0 }; 1402 struct hwrm_tf_tbl_type_get_output resp = { 0 }; 1403 struct tfp_send_msg_parms parms = { 0 }; 1404 uint8_t fw_session_id; 1405 struct tf_dev_info *dev; 1406 struct tf_session *tfs; 1407 uint32_t flags = 0; 1408 1409 /* Retrieve the session information */ 1410 rc = tf_session_get_session_internal(tfp, &tfs); 1411 if (rc) { 1412 TFP_DRV_LOG(ERR, 1413 "%s: Failed to lookup session, rc:%s\n", 1414 tf_dir_2_str(dir), 1415 strerror(-rc)); 1416 return rc; 1417 } 1418 1419 /* Retrieve the device information */ 1420 rc = tf_session_get_device(tfs, &dev); 1421 if (rc) { 1422 TFP_DRV_LOG(ERR, 1423 "%s: Failed to lookup device, rc:%s\n", 1424 tf_dir_2_str(dir), 1425 strerror(-rc)); 1426 return rc; 1427 } 1428 1429 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1430 if (rc) { 1431 TFP_DRV_LOG(ERR, 1432 "%s: Unable to lookup FW id, rc:%s\n", 1433 tf_dir_2_str(dir), 1434 strerror(-rc)); 1435 return rc; 1436 } 1437 flags = (dir == TF_DIR_TX ? 1438 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_TX : 1439 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_RX); 1440 1441 if (clear_on_read) 1442 flags |= HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_CLEAR_ON_READ; 1443 1444 /* Populate the request */ 1445 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1446 req.flags = tfp_cpu_to_le_16(flags); 1447 req.type = tfp_cpu_to_le_32(hcapi_type); 1448 req.index = tfp_cpu_to_le_32(index); 1449 1450 parms.tf_type = HWRM_TF_TBL_TYPE_GET; 1451 parms.req_data = (uint32_t *)&req; 1452 parms.req_size = sizeof(req); 1453 parms.resp_data = (uint32_t *)&resp; 1454 parms.resp_size = sizeof(resp); 1455 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1456 1457 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1458 &parms); 1459 if (rc) 1460 return rc; 1461 1462 /* 1463 * The response will be 64 bytes long, the response size will 1464 * be in words (16). All we can test for is that the response 1465 * size is < to the requested size. 1466 */ 1467 if ((tfp_le_to_cpu_32(resp.size) * 4) < size) 1468 return -EINVAL; 1469 1470 /* 1471 * Copy the requested number of bytes 1472 */ 1473 tfp_memcpy(data, 1474 &resp.data, 1475 size); 1476 1477 return 0; 1478 } 1479 1480 /* HWRM Tunneled messages */ 1481 1482 int 1483 tf_msg_get_global_cfg(struct tf *tfp, 1484 struct tf_global_cfg_parms *params) 1485 { 1486 int rc = 0; 1487 struct tfp_send_msg_parms parms = { 0 }; 1488 struct hwrm_tf_global_cfg_get_input req = { 0 }; 1489 struct hwrm_tf_global_cfg_get_output resp = { 0 }; 1490 uint32_t flags = 0; 1491 uint8_t fw_session_id; 1492 uint16_t resp_size = 0; 1493 struct tf_dev_info *dev; 1494 struct tf_session *tfs; 1495 1496 /* Retrieve the session information */ 1497 rc = tf_session_get_session_internal(tfp, &tfs); 1498 if (rc) { 1499 TFP_DRV_LOG(ERR, 1500 "%s: Failed to lookup session, rc:%s\n", 1501 tf_dir_2_str(params->dir), 1502 strerror(-rc)); 1503 return rc; 1504 } 1505 1506 /* Retrieve the device information */ 1507 rc = tf_session_get_device(tfs, &dev); 1508 if (rc) { 1509 TFP_DRV_LOG(ERR, 1510 "%s: Failed to lookup device, rc:%s\n", 1511 tf_dir_2_str(params->dir), 1512 strerror(-rc)); 1513 return rc; 1514 } 1515 1516 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1517 if (rc) { 1518 TFP_DRV_LOG(ERR, 1519 "%s: Unable to lookup FW id, rc:%s\n", 1520 tf_dir_2_str(params->dir), 1521 strerror(-rc)); 1522 return rc; 1523 } 1524 1525 flags = (params->dir == TF_DIR_TX ? 1526 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX : 1527 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX); 1528 1529 /* Populate the request */ 1530 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1531 req.flags = tfp_cpu_to_le_32(flags); 1532 req.type = tfp_cpu_to_le_32(params->type); 1533 req.offset = tfp_cpu_to_le_32(params->offset); 1534 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes); 1535 1536 parms.tf_type = HWRM_TF_GLOBAL_CFG_GET; 1537 parms.req_data = (uint32_t *)&req; 1538 parms.req_size = sizeof(req); 1539 parms.resp_data = (uint32_t *)&resp; 1540 parms.resp_size = sizeof(resp); 1541 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1542 1543 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 1544 if (rc != 0) 1545 return rc; 1546 1547 /* Verify that we got enough buffer to return the requested data */ 1548 resp_size = tfp_le_to_cpu_16(resp.size); 1549 if (resp_size < params->config_sz_in_bytes) 1550 return -EINVAL; 1551 1552 if (params->config) 1553 tfp_memcpy(params->config, 1554 resp.data, 1555 resp_size); 1556 else 1557 return -EFAULT; 1558 1559 return 0; 1560 } 1561 1562 int 1563 tf_msg_set_global_cfg(struct tf *tfp, 1564 struct tf_global_cfg_parms *params) 1565 { 1566 int rc = 0; 1567 struct tfp_send_msg_parms parms = { 0 }; 1568 struct hwrm_tf_global_cfg_set_input req = { 0 }; 1569 struct hwrm_tf_global_cfg_set_output resp = { 0 }; 1570 uint32_t flags = 0; 1571 uint8_t fw_session_id; 1572 struct tf_dev_info *dev; 1573 struct tf_session *tfs; 1574 1575 /* Retrieve the session information */ 1576 rc = tf_session_get_session_internal(tfp, &tfs); 1577 if (rc) { 1578 TFP_DRV_LOG(ERR, 1579 "%s: Failed to lookup session, rc:%s\n", 1580 tf_dir_2_str(params->dir), 1581 strerror(-rc)); 1582 return rc; 1583 } 1584 1585 /* Retrieve the device information */ 1586 rc = tf_session_get_device(tfs, &dev); 1587 if (rc) { 1588 TFP_DRV_LOG(ERR, 1589 "%s: Failed to lookup device, rc:%s\n", 1590 tf_dir_2_str(params->dir), 1591 strerror(-rc)); 1592 return rc; 1593 } 1594 1595 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1596 if (rc) { 1597 TFP_DRV_LOG(ERR, 1598 "%s: Unable to lookup FW id, rc:%s\n", 1599 tf_dir_2_str(params->dir), 1600 strerror(-rc)); 1601 return rc; 1602 } 1603 1604 flags = (params->dir == TF_DIR_TX ? 1605 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX : 1606 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX); 1607 1608 /* Populate the request */ 1609 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1610 req.flags = tfp_cpu_to_le_32(flags); 1611 req.type = tfp_cpu_to_le_32(params->type); 1612 req.offset = tfp_cpu_to_le_32(params->offset); 1613 1614 /* Check for data size conformity */ 1615 if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) { 1616 rc = -EINVAL; 1617 TFP_DRV_LOG(ERR, 1618 "%s: Invalid parameters for msg type, rc:%s\n", 1619 tf_dir_2_str(params->dir), 1620 strerror(-rc)); 1621 return rc; 1622 } 1623 1624 tfp_memcpy(req.data, params->config, 1625 params->config_sz_in_bytes); 1626 1627 /* Only set mask if pointer is provided 1628 */ 1629 if (params->config_mask) { 1630 tfp_memcpy(req.mask, 1631 params->config_mask, 1632 params->config_sz_in_bytes); 1633 } 1634 1635 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes); 1636 1637 parms.tf_type = HWRM_TF_GLOBAL_CFG_SET; 1638 parms.req_data = (uint32_t *)&req; 1639 parms.req_size = sizeof(req); 1640 parms.resp_data = (uint32_t *)&resp; 1641 parms.resp_size = sizeof(resp); 1642 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1643 1644 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 1645 1646 if (rc != 0) 1647 return rc; 1648 1649 return 0; 1650 } 1651 1652 int 1653 tf_msg_bulk_get_tbl_entry(struct tf *tfp, 1654 enum tf_dir dir, 1655 uint16_t hcapi_type, 1656 uint32_t starting_idx, 1657 uint16_t num_entries, 1658 uint16_t entry_sz_in_bytes, 1659 uint64_t physical_mem_addr, 1660 bool clear_on_read) 1661 { 1662 int rc; 1663 struct tfp_send_msg_parms parms = { 0 }; 1664 struct hwrm_tf_tbl_type_bulk_get_input req = { 0 }; 1665 struct hwrm_tf_tbl_type_bulk_get_output resp = { 0 }; 1666 int data_size = 0; 1667 uint8_t fw_session_id; 1668 struct tf_dev_info *dev; 1669 struct tf_session *tfs; 1670 uint32_t flags = 0; 1671 1672 /* Retrieve the session information */ 1673 rc = tf_session_get_session(tfp, &tfs); 1674 if (rc) { 1675 TFP_DRV_LOG(ERR, 1676 "%s: Failed to lookup session, rc:%s\n", 1677 tf_dir_2_str(dir), 1678 strerror(-rc)); 1679 return rc; 1680 } 1681 1682 /* Retrieve the device information */ 1683 rc = tf_session_get_device(tfs, &dev); 1684 if (rc) { 1685 TFP_DRV_LOG(ERR, 1686 "%s: Failed to lookup device, rc:%s\n", 1687 tf_dir_2_str(dir), 1688 strerror(-rc)); 1689 return rc; 1690 } 1691 1692 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1693 if (rc) { 1694 TFP_DRV_LOG(ERR, 1695 "%s: Unable to lookup FW id, rc:%s\n", 1696 tf_dir_2_str(dir), 1697 strerror(-rc)); 1698 return rc; 1699 } 1700 flags = (dir == TF_DIR_TX ? 1701 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_TX : 1702 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_RX); 1703 1704 if (clear_on_read) 1705 flags |= HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_CLEAR_ON_READ; 1706 1707 /* Populate the request */ 1708 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1709 req.flags = tfp_cpu_to_le_16(flags); 1710 req.type = tfp_cpu_to_le_32(hcapi_type); 1711 req.start_index = tfp_cpu_to_le_32(starting_idx); 1712 req.num_entries = tfp_cpu_to_le_32(num_entries); 1713 1714 data_size = num_entries * entry_sz_in_bytes; 1715 1716 req.host_addr = tfp_cpu_to_le_64(physical_mem_addr); 1717 1718 parms.tf_type = HWRM_TF_TBL_TYPE_BULK_GET; 1719 parms.req_data = (uint32_t *)&req; 1720 parms.req_size = sizeof(req); 1721 parms.resp_data = (uint32_t *)&resp; 1722 parms.resp_size = sizeof(resp); 1723 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1724 1725 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1726 &parms); 1727 if (rc) 1728 return rc; 1729 1730 /* Verify that we got enough buffer to return the requested data */ 1731 if (tfp_le_to_cpu_32(resp.size) != data_size) 1732 return -EINVAL; 1733 1734 return 0; 1735 } 1736 1737 int 1738 tf_msg_get_if_tbl_entry(struct tf *tfp, 1739 struct tf_if_tbl_get_parms *params) 1740 { 1741 int rc = 0; 1742 struct tfp_send_msg_parms parms = { 0 }; 1743 struct hwrm_tf_if_tbl_get_input req = { 0 }; 1744 struct hwrm_tf_if_tbl_get_output resp = { 0 }; 1745 uint32_t flags = 0; 1746 struct tf_dev_info *dev; 1747 struct tf_session *tfs; 1748 1749 /* Retrieve the session information */ 1750 rc = tf_session_get_session(tfp, &tfs); 1751 if (rc) { 1752 TFP_DRV_LOG(ERR, 1753 "%s: Failed to lookup session, rc:%s\n", 1754 tf_dir_2_str(params->dir), 1755 strerror(-rc)); 1756 return rc; 1757 } 1758 1759 /* Retrieve the device information */ 1760 rc = tf_session_get_device(tfs, &dev); 1761 if (rc) { 1762 TFP_DRV_LOG(ERR, 1763 "%s: Failed to lookup device, rc:%s\n", 1764 tf_dir_2_str(params->dir), 1765 strerror(-rc)); 1766 return rc; 1767 } 1768 1769 flags = (params->dir == TF_DIR_TX ? 1770 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX : 1771 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX); 1772 1773 /* Populate the request */ 1774 req.fw_session_id = 1775 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); 1776 req.flags = flags; 1777 req.type = params->hcapi_type; 1778 req.index = tfp_cpu_to_le_16(params->idx); 1779 req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes); 1780 1781 parms.tf_type = HWRM_TF_IF_TBL_GET; 1782 parms.req_data = (uint32_t *)&req; 1783 parms.req_size = sizeof(req); 1784 parms.resp_data = (uint32_t *)&resp; 1785 parms.resp_size = sizeof(resp); 1786 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1787 1788 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 1789 1790 if (rc != 0) 1791 return rc; 1792 1793 tfp_memcpy(¶ms->data[0], resp.data, req.size); 1794 1795 return 0; 1796 } 1797 1798 int 1799 tf_msg_set_if_tbl_entry(struct tf *tfp, 1800 struct tf_if_tbl_set_parms *params) 1801 { 1802 int rc = 0; 1803 struct tfp_send_msg_parms parms = { 0 }; 1804 struct hwrm_tf_if_tbl_set_input req = { 0 }; 1805 struct hwrm_tf_if_tbl_get_output resp = { 0 }; 1806 uint32_t flags = 0; 1807 struct tf_dev_info *dev; 1808 struct tf_session *tfs; 1809 1810 /* Retrieve the session information */ 1811 rc = tf_session_get_session(tfp, &tfs); 1812 if (rc) { 1813 TFP_DRV_LOG(ERR, 1814 "%s: Failed to lookup session, rc:%s\n", 1815 tf_dir_2_str(params->dir), 1816 strerror(-rc)); 1817 return rc; 1818 } 1819 1820 /* Retrieve the device information */ 1821 rc = tf_session_get_device(tfs, &dev); 1822 if (rc) 1823 return rc; 1824 1825 flags = (params->dir == TF_DIR_TX ? 1826 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX : 1827 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX); 1828 1829 /* Populate the request */ 1830 req.fw_session_id = 1831 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); 1832 req.flags = flags; 1833 req.type = params->hcapi_type; 1834 req.index = tfp_cpu_to_le_32(params->idx); 1835 req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes); 1836 tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes); 1837 1838 parms.tf_type = HWRM_TF_IF_TBL_SET; 1839 parms.req_data = (uint32_t *)&req; 1840 parms.req_size = sizeof(req); 1841 parms.resp_data = (uint32_t *)&resp; 1842 parms.resp_size = sizeof(resp); 1843 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1844 1845 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 1846 1847 if (rc != 0) 1848 return rc; 1849 1850 return 0; 1851 } 1852 1853 int 1854 tf_msg_get_version(struct bnxt *bp, 1855 struct tf_dev_info *dev, 1856 struct tf_get_version_parms *params) 1857 1858 { 1859 int rc; 1860 struct hwrm_tf_version_get_input req = { 0 }; 1861 struct hwrm_tf_version_get_output resp = { 0 }; 1862 struct tfp_send_msg_parms parms = { 0 }; 1863 1864 /* Populate the request */ 1865 parms.tf_type = HWRM_TF_VERSION_GET, 1866 parms.req_data = (uint32_t *)&req; 1867 parms.req_size = sizeof(req); 1868 parms.resp_data = (uint32_t *)&resp; 1869 parms.resp_size = sizeof(resp); 1870 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1871 1872 rc = tfp_send_msg_direct(bp, 1873 &parms); 1874 1875 params->major = resp.major; 1876 params->minor = resp.minor; 1877 params->update = resp.update; 1878 1879 dev->ops->tf_dev_map_hcapi_caps(resp.dev_caps_cfg, 1880 ¶ms->dev_ident_caps, 1881 ¶ms->dev_tcam_caps, 1882 ¶ms->dev_tbl_caps, 1883 ¶ms->dev_em_caps); 1884 1885 return rc; 1886 } 1887 1888 int 1889 tf_msg_session_set_hotup_state(struct tf *tfp, uint16_t state) 1890 { 1891 int rc; 1892 struct hwrm_tf_session_hotup_state_set_input req = { 0 }; 1893 struct hwrm_tf_session_hotup_state_set_output resp = { 0 }; 1894 struct tfp_send_msg_parms parms = { 0 }; 1895 uint8_t fw_session_id; 1896 struct tf_dev_info *dev; 1897 struct tf_session *tfs; 1898 1899 /* Retrieve the session information */ 1900 rc = tf_session_get_session_internal(tfp, &tfs); 1901 if (rc) { 1902 TFP_DRV_LOG(ERR, 1903 "Failed to lookup session, rc:%s\n", 1904 strerror(-rc)); 1905 return rc; 1906 } 1907 1908 /* Retrieve the device information */ 1909 rc = tf_session_get_device(tfs, &dev); 1910 if (rc) { 1911 TFP_DRV_LOG(ERR, 1912 "Failed to lookup device, rc:%s\n", 1913 strerror(-rc)); 1914 return rc; 1915 } 1916 1917 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1918 if (rc) { 1919 TFP_DRV_LOG(ERR, 1920 "Unable to lookup FW id, rc:%s\n", 1921 strerror(-rc)); 1922 return rc; 1923 } 1924 1925 /* Populate the request */ 1926 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1927 req.state = tfp_cpu_to_le_16(state); 1928 1929 parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_SET; 1930 parms.req_data = (uint32_t *)&req; 1931 parms.req_size = sizeof(req); 1932 parms.resp_data = (uint32_t *)&resp; 1933 parms.resp_size = sizeof(resp); 1934 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1935 1936 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1937 &parms); 1938 return rc; 1939 } 1940 1941 int 1942 tf_msg_session_get_hotup_state(struct tf *tfp, 1943 uint16_t *state, 1944 uint16_t *ref_cnt) 1945 { 1946 int rc; 1947 struct hwrm_tf_session_hotup_state_get_input req = { 0 }; 1948 struct hwrm_tf_session_hotup_state_get_output resp = { 0 }; 1949 struct tfp_send_msg_parms parms = { 0 }; 1950 uint8_t fw_session_id; 1951 struct tf_dev_info *dev; 1952 struct tf_session *tfs; 1953 1954 /* Retrieve the session information */ 1955 rc = tf_session_get_session_internal(tfp, &tfs); 1956 if (rc) { 1957 TFP_DRV_LOG(ERR, 1958 "Failed to lookup session, rc:%s\n", 1959 strerror(-rc)); 1960 return rc; 1961 } 1962 1963 /* Retrieve the device information */ 1964 rc = tf_session_get_device(tfs, &dev); 1965 if (rc) { 1966 TFP_DRV_LOG(ERR, 1967 "Failed to lookup device, rc:%s\n", 1968 strerror(-rc)); 1969 return rc; 1970 } 1971 1972 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1973 if (rc) { 1974 TFP_DRV_LOG(ERR, 1975 "Unable to lookup FW id, rc:%s\n", 1976 strerror(-rc)); 1977 return rc; 1978 } 1979 1980 /* Populate the request */ 1981 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1982 1983 parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_GET; 1984 parms.req_data = (uint32_t *)&req; 1985 parms.req_size = sizeof(req); 1986 parms.resp_data = (uint32_t *)&resp; 1987 parms.resp_size = sizeof(resp); 1988 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1989 1990 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1991 &parms); 1992 1993 *state = tfp_le_to_cpu_16(resp.state); 1994 *ref_cnt = tfp_le_to_cpu_16(resp.ref_cnt); 1995 1996 return rc; 1997 } 1998 1999 #ifdef TF_FLOW_SCALE_QUERY 2000 /* Send set resource usage request to the firmware. */ 2001 int 2002 tf_msg_set_resc_usage(struct tf *tfp, 2003 enum tf_dir dir, 2004 uint32_t resc_types, 2005 uint32_t size, 2006 uint8_t *data) 2007 { 2008 int rc; 2009 struct hwrm_tf_resc_usage_set_input req = { 0 }; 2010 struct hwrm_tf_resc_usage_set_output resp = { 0 }; 2011 struct tfp_send_msg_parms parms = { 0 }; 2012 struct tf_msg_dma_buf buf = { 0 }; 2013 uint8_t fw_session_id; 2014 struct tf_dev_info *dev; 2015 struct tf_session *tfs; 2016 2017 /* Retrieve the session information */ 2018 rc = tf_session_get_session_internal(tfp, &tfs); 2019 if (rc) { 2020 TFP_DRV_LOG(ERR, 2021 "%s: Failed to lookup session, rc:%s\n", 2022 tf_dir_2_str(dir), 2023 strerror(-rc)); 2024 return rc; 2025 } 2026 2027 /* Retrieve the device information */ 2028 rc = tf_session_get_device(tfs, &dev); 2029 if (rc) { 2030 TFP_DRV_LOG(ERR, 2031 "%s: Failed to lookup device, rc:%s\n", 2032 tf_dir_2_str(dir), 2033 strerror(-rc)); 2034 return rc; 2035 } 2036 2037 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 2038 if (rc) { 2039 TFP_DRV_LOG(ERR, 2040 "%s: Unable to lookup FW id, rc:%s\n", 2041 tf_dir_2_str(dir), 2042 strerror(-rc)); 2043 return rc; 2044 } 2045 2046 /* Populate the request */ 2047 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 2048 req.flags = tfp_cpu_to_le_16(dir); 2049 req.types = tfp_cpu_to_le_32(resc_types); 2050 req.size = tfp_cpu_to_le_16(size); 2051 #if (TF_RM_MSG_DEBUG == 1) 2052 /* Dump data */ 2053 dump_tf_resc_usage(dir, data, size); 2054 #endif /* (TF_RM_MSG_DEBUG == 1) */ 2055 /* Check for data size conformity */ 2056 if (size > sizeof(req.data)) { 2057 /* use dma buffer */ 2058 req.flags |= HWRM_TF_RESC_USAGE_SET_INPUT_FLAGS_DMA; 2059 rc = tf_msg_alloc_dma_buf(&buf, size); 2060 if (rc) 2061 goto exit; 2062 tfp_memcpy(buf.va_addr, data, size); 2063 tfp_memcpy(&req.data[0], 2064 &buf.pa_addr, 2065 sizeof(buf.pa_addr)); 2066 } else { 2067 tfp_memcpy(&req.data, data, size); 2068 } 2069 2070 parms.tf_type = HWRM_TF_RESC_USAGE_SET; 2071 parms.req_data = (uint32_t *)&req; 2072 parms.req_size = sizeof(req); 2073 parms.resp_data = (uint32_t *)&resp; 2074 parms.resp_size = sizeof(resp); 2075 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2076 2077 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 2078 &parms); 2079 2080 /* Free dma buffer */ 2081 if (size > sizeof(req.data)) 2082 tf_msg_free_dma_buf(&buf); 2083 exit: 2084 return rc; 2085 } 2086 2087 /* Send query resource usage request to the firmware. */ 2088 int tf_msg_query_resc_usage(struct tf *tfp, 2089 enum tf_dir dir, 2090 uint32_t resc_types, 2091 uint32_t *size, 2092 uint8_t *data) 2093 { 2094 int rc; 2095 struct hwrm_tf_resc_usage_query_input req = { 0 }; 2096 struct hwrm_tf_resc_usage_query_output resp = { 0 }; 2097 struct tfp_send_msg_parms parms = { 0 }; 2098 uint8_t fw_session_id; 2099 struct tf_dev_info *dev; 2100 struct tf_session *tfs; 2101 uint32_t flags = 0; 2102 2103 /* Retrieve the session information */ 2104 rc = tf_session_get_session_internal(tfp, &tfs); 2105 if (rc) { 2106 TFP_DRV_LOG(ERR, 2107 "%s: Failed to lookup session, rc:%s\n", 2108 tf_dir_2_str(dir), 2109 strerror(-rc)); 2110 return rc; 2111 } 2112 2113 /* Retrieve the device information */ 2114 rc = tf_session_get_device(tfs, &dev); 2115 if (rc) { 2116 TFP_DRV_LOG(ERR, 2117 "%s: Failed to lookup device, rc:%s\n", 2118 tf_dir_2_str(dir), 2119 strerror(-rc)); 2120 return rc; 2121 } 2122 2123 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 2124 if (rc) { 2125 TFP_DRV_LOG(ERR, 2126 "%s: Unable to lookup FW id, rc:%s\n", 2127 tf_dir_2_str(dir), 2128 strerror(-rc)); 2129 return rc; 2130 } 2131 flags = (dir == TF_DIR_TX ? 2132 HWRM_TF_RESC_USAGE_QUERY_INPUT_FLAGS_DIR_TX : 2133 HWRM_TF_RESC_USAGE_QUERY_INPUT_FLAGS_DIR_RX); 2134 2135 /* Populate the request */ 2136 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 2137 req.flags = tfp_cpu_to_le_16(flags); 2138 req.types = tfp_cpu_to_le_32(resc_types); 2139 2140 parms.tf_type = HWRM_TF_RESC_USAGE_QUERY; 2141 parms.req_data = (uint32_t *)&req; 2142 parms.req_size = sizeof(req); 2143 parms.resp_data = (uint32_t *)&resp; 2144 parms.resp_size = sizeof(resp); 2145 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2146 2147 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 2148 &parms); 2149 if (rc) 2150 return rc; 2151 2152 /* The response size should be less than or equal to (<=) the input buffer size. */ 2153 if (resp.size > *size) 2154 return -EINVAL; 2155 2156 *size = resp.size; 2157 2158 /* 2159 * Copy the requested number of bytes 2160 */ 2161 tfp_memcpy(data, 2162 &resp.data, 2163 resp.size); 2164 2165 #if (TF_RM_MSG_DEBUG == 1) 2166 /* dump data */ 2167 dump_tf_resc_usage(dir, data, resp.size); 2168 #endif /* (TF_RM_MSG_DEBUG == 1) */ 2169 2170 return 0; 2171 } 2172 #endif /* TF_FLOW_SCALE_QUERY */ 2173