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 80 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 to 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 tf_msg_ext_em_ctxt_mem_alloc(struct tf *tfp, 1104 struct hcapi_cfa_em_table *tbl, 1105 uint64_t *dma_addr, 1106 uint32_t *page_lvl, 1107 uint32_t *page_size) 1108 { 1109 struct tfp_send_msg_parms parms = { 0 }; 1110 struct hwrm_tf_ctxt_mem_alloc_input req = {0}; 1111 struct hwrm_tf_ctxt_mem_alloc_output resp = {0}; 1112 uint32_t mem_size_k; 1113 int rc = 0; 1114 struct tf_dev_info *dev; 1115 struct tf_session *tfs; 1116 uint32_t fw_se_id; 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 /* Retrieve the device information */ 1128 rc = tf_session_get_device(tfs, &dev); 1129 if (rc) { 1130 TFP_DRV_LOG(ERR, 1131 "Failed to lookup device, rc:%s\n", 1132 strerror(-rc)); 1133 return rc; 1134 } 1135 /* Retrieve the session information */ 1136 fw_se_id = tfs->session_id.internal.fw_session_id; 1137 1138 if (tbl->num_entries && tbl->entry_size) { 1139 /* unit: kbytes */ 1140 mem_size_k = (tbl->num_entries / TF_KILOBYTE) * tbl->entry_size; 1141 req.mem_size = tfp_cpu_to_le_32(mem_size_k); 1142 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 1143 parms.tf_type = HWRM_TF_CTXT_MEM_ALLOC; 1144 parms.req_data = (uint32_t *)&req; 1145 parms.req_size = sizeof(req); 1146 parms.resp_data = (uint32_t *)&resp; 1147 parms.resp_size = sizeof(resp); 1148 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1149 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 1150 if (rc) { 1151 TFP_DRV_LOG(ERR, "Failed ext_em_alloc error rc:%s\n", 1152 strerror(-rc)); 1153 return rc; 1154 } 1155 1156 *dma_addr = tfp_le_to_cpu_64(resp.page_dir); 1157 *page_lvl = resp.page_level; 1158 *page_size = resp.page_size; 1159 } 1160 1161 return rc; 1162 } 1163 1164 int tf_msg_ext_em_ctxt_mem_free(struct tf *tfp, 1165 uint32_t mem_size_k, 1166 uint64_t dma_addr, 1167 uint8_t page_level, 1168 uint8_t page_size) 1169 { 1170 struct tfp_send_msg_parms parms = { 0 }; 1171 struct hwrm_tf_ctxt_mem_free_input req = {0}; 1172 struct hwrm_tf_ctxt_mem_free_output resp = {0}; 1173 int rc = 0; 1174 struct tf_dev_info *dev; 1175 struct tf_session *tfs; 1176 uint32_t fw_se_id; 1177 1178 /* Retrieve the session information */ 1179 rc = tf_session_get_session_internal(tfp, &tfs); 1180 if (rc) { 1181 TFP_DRV_LOG(ERR, 1182 "Failed to lookup session, rc:%s\n", 1183 strerror(-rc)); 1184 return rc; 1185 } 1186 1187 /* Retrieve the device information */ 1188 rc = tf_session_get_device(tfs, &dev); 1189 if (rc) { 1190 TFP_DRV_LOG(ERR, 1191 "Failed to lookup device, rc:%s\n", 1192 strerror(-rc)); 1193 return rc; 1194 } 1195 /* Retrieve the session information */ 1196 fw_se_id = tfs->session_id.internal.fw_session_id; 1197 1198 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 1199 req.mem_size = tfp_cpu_to_le_32(mem_size_k); 1200 req.page_dir = tfp_cpu_to_le_64(dma_addr); 1201 req.page_level = page_level; 1202 req.page_size = page_size; 1203 parms.tf_type = HWRM_TF_CTXT_MEM_FREE; 1204 parms.req_data = (uint32_t *)&req; 1205 parms.req_size = sizeof(req); 1206 parms.resp_data = (uint32_t *)&resp; 1207 parms.resp_size = sizeof(resp); 1208 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1209 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 1210 1211 return rc; 1212 } 1213 1214 int 1215 tf_msg_em_mem_rgtr(struct tf *tfp, 1216 int page_lvl, 1217 int page_size, 1218 uint64_t dma_addr, 1219 uint16_t *ctx_id) 1220 { 1221 int rc; 1222 struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 }; 1223 struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 }; 1224 struct tfp_send_msg_parms parms = { 0 }; 1225 struct tf_dev_info *dev; 1226 struct tf_session *tfs; 1227 uint32_t fw_se_id; 1228 1229 /* Retrieve the session information */ 1230 rc = tf_session_get_session_internal(tfp, &tfs); 1231 if (rc) { 1232 TFP_DRV_LOG(ERR, 1233 "Failed to lookup session, rc:%s\n", 1234 strerror(-rc)); 1235 return rc; 1236 } 1237 1238 /* Retrieve the device information */ 1239 rc = tf_session_get_device(tfs, &dev); 1240 if (rc) { 1241 TFP_DRV_LOG(ERR, 1242 "Failed to lookup device, rc:%s\n", 1243 strerror(-rc)); 1244 return rc; 1245 } 1246 fw_se_id = tfs->session_id.internal.fw_session_id; 1247 1248 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 1249 req.page_level = page_lvl; 1250 req.page_size = page_size; 1251 req.page_dir = tfp_cpu_to_le_64(dma_addr); 1252 1253 parms.tf_type = HWRM_TF_CTXT_MEM_RGTR; 1254 parms.req_data = (uint32_t *)&req; 1255 parms.req_size = sizeof(req); 1256 parms.resp_data = (uint32_t *)&resp; 1257 parms.resp_size = sizeof(resp); 1258 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1259 1260 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1261 &parms); 1262 if (rc) 1263 return rc; 1264 1265 *ctx_id = tfp_le_to_cpu_16(resp.ctx_id); 1266 1267 return rc; 1268 } 1269 1270 int 1271 tf_msg_em_mem_unrgtr(struct tf *tfp, 1272 uint16_t *ctx_id) 1273 { 1274 int rc; 1275 struct hwrm_tf_ctxt_mem_unrgtr_input req = {0}; 1276 struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0}; 1277 struct tfp_send_msg_parms parms = { 0 }; 1278 struct tf_dev_info *dev; 1279 struct tf_session *tfs; 1280 uint32_t fw_se_id; 1281 1282 /* Retrieve the session information */ 1283 rc = tf_session_get_session_internal(tfp, &tfs); 1284 if (rc) { 1285 TFP_DRV_LOG(ERR, 1286 "Failed to lookup session, rc:%s\n", 1287 strerror(-rc)); 1288 return rc; 1289 } 1290 1291 /* Retrieve the device information */ 1292 rc = tf_session_get_device(tfs, &dev); 1293 if (rc) { 1294 TFP_DRV_LOG(ERR, 1295 "Failed to lookup device, rc:%s\n", 1296 strerror(-rc)); 1297 return rc; 1298 } 1299 1300 fw_se_id = tfs->session_id.internal.fw_session_id; 1301 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 1302 1303 req.ctx_id = tfp_cpu_to_le_32(*ctx_id); 1304 1305 parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR; 1306 parms.req_data = (uint32_t *)&req; 1307 parms.req_size = sizeof(req); 1308 parms.resp_data = (uint32_t *)&resp; 1309 parms.resp_size = sizeof(resp); 1310 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1311 1312 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1313 &parms); 1314 return rc; 1315 } 1316 1317 int 1318 tf_msg_em_qcaps(struct tf *tfp, 1319 int dir, 1320 struct tf_em_caps *em_caps) 1321 { 1322 int rc; 1323 struct hwrm_tf_ext_em_qcaps_input req = {0}; 1324 struct hwrm_tf_ext_em_qcaps_output resp = { 0 }; 1325 uint32_t flags; 1326 struct tfp_send_msg_parms parms = { 0 }; 1327 struct tf_dev_info *dev; 1328 struct tf_session *tfs; 1329 uint32_t fw_se_id; 1330 1331 /* Retrieve the session information */ 1332 rc = tf_session_get_session_internal(tfp, &tfs); 1333 if (rc) { 1334 TFP_DRV_LOG(ERR, 1335 "%s: Failed to lookup session, rc:%s\n", 1336 tf_dir_2_str(dir), 1337 strerror(-rc)); 1338 return rc; 1339 } 1340 fw_se_id = tfs->session_id.internal.fw_session_id; 1341 1342 /* Retrieve the device information */ 1343 rc = tf_session_get_device(tfs, &dev); 1344 if (rc) { 1345 TFP_DRV_LOG(ERR, 1346 "%s: Failed to lookup device, rc:%s\n", 1347 tf_dir_2_str(dir), 1348 strerror(-rc)); 1349 return rc; 1350 } 1351 1352 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX : 1353 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX); 1354 req.flags = tfp_cpu_to_le_32(flags); 1355 1356 parms.tf_type = HWRM_TF_EXT_EM_QCAPS; 1357 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 1358 parms.req_data = (uint32_t *)&req; 1359 parms.req_size = sizeof(req); 1360 parms.resp_data = (uint32_t *)&resp; 1361 parms.resp_size = sizeof(resp); 1362 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1363 1364 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1365 &parms); 1366 if (rc) 1367 return rc; 1368 1369 em_caps->supported = tfp_le_to_cpu_32(resp.supported); 1370 em_caps->max_entries_supported = 1371 tfp_le_to_cpu_32(resp.max_entries_supported); 1372 em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size); 1373 em_caps->record_entry_size = 1374 tfp_le_to_cpu_16(resp.record_entry_size); 1375 em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size); 1376 1377 return rc; 1378 } 1379 1380 int 1381 tf_msg_em_cfg(struct tf *tfp, 1382 uint32_t num_entries, 1383 uint16_t key0_ctx_id, 1384 uint16_t key1_ctx_id, 1385 uint16_t record_ctx_id, 1386 uint16_t efc_ctx_id, 1387 uint8_t flush_interval, 1388 int dir) 1389 { 1390 int rc; 1391 struct hwrm_tf_ext_em_cfg_input req = {0}; 1392 struct hwrm_tf_ext_em_cfg_output resp = {0}; 1393 uint32_t flags; 1394 struct tfp_send_msg_parms parms = { 0 }; 1395 struct tf_dev_info *dev; 1396 struct tf_session *tfs; 1397 1398 /* Retrieve the session information */ 1399 rc = tf_session_get_session_internal(tfp, &tfs); 1400 if (rc) { 1401 TFP_DRV_LOG(ERR, 1402 "%s: Failed to lookup session, rc:%s\n", 1403 tf_dir_2_str(dir), 1404 strerror(-rc)); 1405 return rc; 1406 } 1407 1408 /* Retrieve the device information */ 1409 rc = tf_session_get_device(tfs, &dev); 1410 if (rc) { 1411 TFP_DRV_LOG(ERR, 1412 "%s: Failed to lookup device, rc:%s\n", 1413 tf_dir_2_str(dir), 1414 strerror(-rc)); 1415 return rc; 1416 } 1417 1418 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX : 1419 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX); 1420 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD; 1421 1422 req.flags = tfp_cpu_to_le_32(flags); 1423 req.num_entries = tfp_cpu_to_le_32(num_entries); 1424 1425 req.flush_interval = flush_interval; 1426 1427 req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id); 1428 req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id); 1429 req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id); 1430 req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id); 1431 1432 parms.tf_type = HWRM_TF_EXT_EM_CFG; 1433 parms.req_data = (uint32_t *)&req; 1434 parms.req_size = sizeof(req); 1435 parms.resp_data = (uint32_t *)&resp; 1436 parms.resp_size = sizeof(resp); 1437 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1438 1439 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1440 &parms); 1441 return rc; 1442 } 1443 1444 int 1445 tf_msg_ext_em_cfg(struct tf *tfp, 1446 struct tf_tbl_scope_cb *tbl_scope_cb, 1447 uint32_t st_buckets, 1448 uint8_t flush_interval, 1449 enum tf_dir dir) 1450 { 1451 struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir]; 1452 struct hcapi_cfa_em_table *lkup_tbl, *act_tbl; 1453 struct hwrm_tf_ext_em_cfg_input req = {0}; 1454 struct hwrm_tf_ext_em_cfg_output resp = {0}; 1455 struct tfp_send_msg_parms parms = { 0 }; 1456 uint32_t flags; 1457 struct tf_dev_info *dev; 1458 struct tf_session *tfs; 1459 uint32_t fw_se_id; 1460 int rc; 1461 1462 /* Retrieve the session information */ 1463 rc = tf_session_get_session_internal(tfp, &tfs); 1464 if (rc) { 1465 TFP_DRV_LOG(ERR, 1466 "%s: Failed to lookup session, rc:%s\n", 1467 tf_dir_2_str(dir), 1468 strerror(-rc)); 1469 return rc; 1470 } 1471 1472 /* Retrieve the device information */ 1473 rc = tf_session_get_device(tfs, &dev); 1474 if (rc) { 1475 TFP_DRV_LOG(ERR, 1476 "%s: Failed to lookup device, rc:%s\n", 1477 tf_dir_2_str(dir), 1478 strerror(-rc)); 1479 return rc; 1480 } 1481 fw_se_id = tfs->session_id.internal.fw_session_id; 1482 1483 lkup_tbl = &ctxp->em_tables[TF_EM_LKUP_TABLE]; 1484 act_tbl = &ctxp->em_tables[TF_ACTION_TABLE]; 1485 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX : 1486 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX); 1487 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD; 1488 1489 req.flags = tfp_cpu_to_le_32(flags); 1490 req.num_entries = tfp_cpu_to_le_32(act_tbl->num_entries); 1491 req.lkup_static_buckets = tfp_cpu_to_le_32(st_buckets); 1492 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 1493 req.flush_interval = flush_interval; 1494 req.action_ctx_id = tfp_cpu_to_le_16(act_tbl->ctx_id); 1495 req.action_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id); 1496 req.lkup_ctx_id = tfp_cpu_to_le_16(lkup_tbl->ctx_id); 1497 req.lkup_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id); 1498 1499 req.enables = (HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_CTX_ID | 1500 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_TBL_SCOPE | 1501 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_CTX_ID | 1502 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_TBL_SCOPE | 1503 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_STATIC_BUCKETS | 1504 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_NUM_ENTRIES); 1505 1506 parms.tf_type = HWRM_TF_EXT_EM_CFG; 1507 parms.req_data = (uint32_t *)&req; 1508 parms.req_size = sizeof(req); 1509 parms.resp_data = (uint32_t *)&resp; 1510 parms.resp_size = sizeof(resp); 1511 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1512 1513 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1514 &parms); 1515 return rc; 1516 } 1517 1518 int 1519 tf_msg_em_op(struct tf *tfp, 1520 int dir, 1521 uint16_t op) 1522 { 1523 int rc; 1524 struct hwrm_tf_ext_em_op_input req = {0}; 1525 struct hwrm_tf_ext_em_op_output resp = {0}; 1526 uint32_t flags; 1527 struct tfp_send_msg_parms parms = { 0 }; 1528 struct tf_dev_info *dev; 1529 struct tf_session *tfs; 1530 1531 /* Retrieve the session information */ 1532 rc = tf_session_get_session_internal(tfp, &tfs); 1533 if (rc) { 1534 TFP_DRV_LOG(ERR, 1535 "%s: Failed to lookup session, rc:%s\n", 1536 tf_dir_2_str(dir), 1537 strerror(-rc)); 1538 return rc; 1539 } 1540 1541 /* Retrieve the device information */ 1542 rc = tf_session_get_device(tfs, &dev); 1543 if (rc) { 1544 TFP_DRV_LOG(ERR, 1545 "%s: Failed to lookup device, rc:%s\n", 1546 tf_dir_2_str(dir), 1547 strerror(-rc)); 1548 return rc; 1549 } 1550 1551 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX : 1552 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX); 1553 req.flags = tfp_cpu_to_le_32(flags); 1554 req.op = tfp_cpu_to_le_16(op); 1555 1556 parms.tf_type = HWRM_TF_EXT_EM_OP; 1557 parms.req_data = (uint32_t *)&req; 1558 parms.req_size = sizeof(req); 1559 parms.resp_data = (uint32_t *)&resp; 1560 parms.resp_size = sizeof(resp); 1561 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1562 1563 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1564 &parms); 1565 return rc; 1566 } 1567 1568 int 1569 tf_msg_tcam_entry_set(struct tf *tfp, 1570 struct tf_dev_info *dev, 1571 struct tf_tcam_set_parms *parms) 1572 { 1573 int rc; 1574 struct tfp_send_msg_parms mparms = { 0 }; 1575 struct hwrm_tf_tcam_set_input req = { 0 }; 1576 struct hwrm_tf_tcam_set_output resp = { 0 }; 1577 struct tf_msg_dma_buf buf = { 0 }; 1578 uint8_t *data = NULL; 1579 int data_size = 0; 1580 uint8_t fw_session_id; 1581 struct tf_session *tfs; 1582 1583 /* Retrieve the session information */ 1584 rc = tf_session_get_session_internal(tfp, &tfs); 1585 if (rc) { 1586 TFP_DRV_LOG(ERR, 1587 "Failed to lookup session, rc:%s\n", 1588 strerror(-rc)); 1589 return rc; 1590 } 1591 1592 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1593 if (rc) { 1594 TFP_DRV_LOG(ERR, 1595 "%s: Unable to lookup FW id, rc:%s\n", 1596 tf_dir_2_str(parms->dir), 1597 strerror(-rc)); 1598 return rc; 1599 } 1600 1601 /* Populate the request */ 1602 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1603 req.type = parms->hcapi_type; 1604 req.idx = tfp_cpu_to_le_16(parms->idx); 1605 if (parms->dir == TF_DIR_TX) 1606 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX; 1607 1608 req.key_size = parms->key_size; 1609 req.mask_offset = parms->key_size; 1610 /* Result follows after key and mask, thus multiply by 2 */ 1611 req.result_offset = 2 * parms->key_size; 1612 req.result_size = parms->result_size; 1613 data_size = 2 * req.key_size + req.result_size; 1614 1615 if (data_size <= TF_PCI_BUF_SIZE_MAX) { 1616 /* use pci buffer */ 1617 data = &req.dev_data[0]; 1618 } else { 1619 /* use dma buffer */ 1620 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA; 1621 rc = tf_msg_alloc_dma_buf(&buf, data_size); 1622 if (rc) 1623 goto cleanup; 1624 data = buf.va_addr; 1625 tfp_memcpy(&req.dev_data[0], 1626 &buf.pa_addr, 1627 sizeof(buf.pa_addr)); 1628 } 1629 1630 tfp_memcpy(&data[0], parms->key, parms->key_size); 1631 tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size); 1632 tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size); 1633 1634 mparms.tf_type = HWRM_TF_TCAM_SET; 1635 mparms.req_data = (uint32_t *)&req; 1636 mparms.req_size = sizeof(req); 1637 mparms.resp_data = (uint32_t *)&resp; 1638 mparms.resp_size = sizeof(resp); 1639 mparms.mailbox = dev->ops->tf_dev_get_mailbox(); 1640 1641 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1642 &mparms); 1643 1644 cleanup: 1645 tf_msg_free_dma_buf(&buf); 1646 1647 return rc; 1648 } 1649 1650 int 1651 tf_msg_tcam_entry_get(struct tf *tfp, 1652 struct tf_dev_info *dev, 1653 struct tf_tcam_get_parms *parms) 1654 { 1655 int rc; 1656 struct tfp_send_msg_parms mparms = { 0 }; 1657 struct hwrm_tf_tcam_get_input req = { 0 }; 1658 struct hwrm_tf_tcam_get_output resp = { 0 }; 1659 uint8_t fw_session_id; 1660 struct tf_session *tfs; 1661 1662 /* Retrieve the session information */ 1663 rc = tf_session_get_session_internal(tfp, &tfs); 1664 if (rc) { 1665 TFP_DRV_LOG(ERR, 1666 "Failed to lookup session, rc:%s\n", 1667 strerror(-rc)); 1668 return rc; 1669 } 1670 1671 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1672 if (rc) { 1673 TFP_DRV_LOG(ERR, 1674 "%s: Unable to lookup FW id, rc:%s\n", 1675 tf_dir_2_str(parms->dir), 1676 strerror(-rc)); 1677 return rc; 1678 } 1679 1680 /* Populate the request */ 1681 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1682 req.type = parms->hcapi_type; 1683 req.idx = tfp_cpu_to_le_16(parms->idx); 1684 if (parms->dir == TF_DIR_TX) 1685 req.flags |= HWRM_TF_TCAM_GET_INPUT_FLAGS_DIR_TX; 1686 1687 mparms.tf_type = HWRM_TF_TCAM_GET; 1688 mparms.req_data = (uint32_t *)&req; 1689 mparms.req_size = sizeof(req); 1690 mparms.resp_data = (uint32_t *)&resp; 1691 mparms.resp_size = sizeof(resp); 1692 mparms.mailbox = dev->ops->tf_dev_get_mailbox(); 1693 1694 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1695 &mparms); 1696 1697 if (rc != 0) 1698 return rc; 1699 1700 if (parms->key_size < resp.key_size || 1701 parms->result_size < resp.result_size) { 1702 rc = -EINVAL; 1703 TFP_DRV_LOG(ERR, 1704 "%s: Key buffer(%d) is smaller than the key(%d), rc:%s\n", 1705 tf_dir_2_str(parms->dir), 1706 parms->key_size, 1707 resp.key_size, 1708 strerror(-rc)); 1709 return rc; 1710 } 1711 parms->key_size = resp.key_size; 1712 parms->result_size = resp.result_size; 1713 tfp_memcpy(parms->key, resp.dev_data, resp.key_size); 1714 tfp_memcpy(parms->mask, &resp.dev_data[resp.key_size], resp.key_size); 1715 tfp_memcpy(parms->result, &resp.dev_data[resp.result_offset], resp.result_size); 1716 1717 return 0; 1718 } 1719 1720 int 1721 tf_msg_tcam_entry_free(struct tf *tfp, 1722 struct tf_dev_info *dev, 1723 struct tf_tcam_free_parms *in_parms) 1724 { 1725 int rc; 1726 struct hwrm_tf_tcam_free_input req = { 0 }; 1727 struct hwrm_tf_tcam_free_output resp = { 0 }; 1728 struct tfp_send_msg_parms parms = { 0 }; 1729 uint8_t fw_session_id; 1730 struct tf_session *tfs; 1731 1732 /* Retrieve the session information */ 1733 rc = tf_session_get_session_internal(tfp, &tfs); 1734 if (rc) { 1735 TFP_DRV_LOG(ERR, 1736 "Failed to lookup session, rc:%s\n", 1737 strerror(-rc)); 1738 return rc; 1739 } 1740 1741 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1742 if (rc) { 1743 TFP_DRV_LOG(ERR, 1744 "%s: Unable to lookup FW id, rc:%s\n", 1745 tf_dir_2_str(in_parms->dir), 1746 strerror(-rc)); 1747 return rc; 1748 } 1749 1750 /* Populate the request */ 1751 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1752 req.type = in_parms->hcapi_type; 1753 req.count = 1; 1754 req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx); 1755 if (in_parms->dir == TF_DIR_TX) 1756 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX; 1757 1758 parms.tf_type = HWRM_TF_TCAM_FREE; 1759 parms.req_data = (uint32_t *)&req; 1760 parms.req_size = sizeof(req); 1761 parms.resp_data = (uint32_t *)&resp; 1762 parms.resp_size = sizeof(resp); 1763 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1764 1765 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1766 &parms); 1767 return rc; 1768 } 1769 1770 int 1771 tf_msg_set_tbl_entry(struct tf *tfp, 1772 enum tf_dir dir, 1773 uint16_t hcapi_type, 1774 uint16_t size, 1775 uint8_t *data, 1776 uint32_t index) 1777 { 1778 int rc; 1779 struct hwrm_tf_tbl_type_set_input req = { 0 }; 1780 struct hwrm_tf_tbl_type_set_output resp = { 0 }; 1781 struct tfp_send_msg_parms parms = { 0 }; 1782 struct tf_msg_dma_buf buf = { 0 }; 1783 uint8_t fw_session_id; 1784 struct tf_dev_info *dev; 1785 struct tf_session *tfs; 1786 1787 RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_tbl_type_set_input) != 1788 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET); 1789 1790 /* Retrieve the session information */ 1791 rc = tf_session_get_session_internal(tfp, &tfs); 1792 if (rc) { 1793 TFP_DRV_LOG(ERR, 1794 "%s: Failed to lookup session, rc:%s\n", 1795 tf_dir_2_str(dir), 1796 strerror(-rc)); 1797 return rc; 1798 } 1799 1800 /* Retrieve the device information */ 1801 rc = tf_session_get_device(tfs, &dev); 1802 if (rc) { 1803 TFP_DRV_LOG(ERR, 1804 "%s: Failed to lookup device, rc:%s\n", 1805 tf_dir_2_str(dir), 1806 strerror(-rc)); 1807 return rc; 1808 } 1809 1810 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1811 if (rc) { 1812 TFP_DRV_LOG(ERR, 1813 "%s: Unable to lookup FW id, rc:%s\n", 1814 tf_dir_2_str(dir), 1815 strerror(-rc)); 1816 return rc; 1817 } 1818 1819 /* Populate the request */ 1820 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1821 req.flags = tfp_cpu_to_le_16(dir); 1822 req.type = tfp_cpu_to_le_32(hcapi_type); 1823 req.size = tfp_cpu_to_le_16(size); 1824 req.index = tfp_cpu_to_le_32(index); 1825 1826 /* Check for data size conformity */ 1827 if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) { 1828 /* use dma buffer */ 1829 req.flags |= HWRM_TF_TBL_TYPE_SET_INPUT_FLAGS_DMA; 1830 rc = tf_msg_alloc_dma_buf(&buf, size); 1831 if (rc) 1832 goto cleanup; 1833 tfp_memcpy(buf.va_addr, data, size); 1834 tfp_memcpy(&req.data[0], 1835 &buf.pa_addr, 1836 sizeof(buf.pa_addr)); 1837 } else { 1838 tfp_memcpy(&req.data, data, size); 1839 } 1840 1841 parms.tf_type = HWRM_TF_TBL_TYPE_SET; 1842 parms.req_data = (uint32_t *)&req; 1843 parms.req_size = sizeof(req); 1844 parms.resp_data = (uint32_t *)&resp; 1845 parms.resp_size = sizeof(resp); 1846 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1847 1848 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1849 &parms); 1850 cleanup: 1851 tf_msg_free_dma_buf(&buf); 1852 1853 return rc; 1854 } 1855 1856 int 1857 tf_msg_get_tbl_entry(struct tf *tfp, 1858 enum tf_dir dir, 1859 uint16_t hcapi_type, 1860 uint16_t size, 1861 uint8_t *data, 1862 uint32_t index, 1863 bool clear_on_read) 1864 { 1865 int rc; 1866 struct hwrm_tf_tbl_type_get_input req = { 0 }; 1867 struct hwrm_tf_tbl_type_get_output resp = { 0 }; 1868 struct tfp_send_msg_parms parms = { 0 }; 1869 uint8_t fw_session_id; 1870 struct tf_dev_info *dev; 1871 struct tf_session *tfs; 1872 uint32_t flags = 0; 1873 1874 /* Retrieve the session information */ 1875 rc = tf_session_get_session_internal(tfp, &tfs); 1876 if (rc) { 1877 TFP_DRV_LOG(ERR, 1878 "%s: Failed to lookup session, rc:%s\n", 1879 tf_dir_2_str(dir), 1880 strerror(-rc)); 1881 return rc; 1882 } 1883 1884 /* Retrieve the device information */ 1885 rc = tf_session_get_device(tfs, &dev); 1886 if (rc) { 1887 TFP_DRV_LOG(ERR, 1888 "%s: Failed to lookup device, rc:%s\n", 1889 tf_dir_2_str(dir), 1890 strerror(-rc)); 1891 return rc; 1892 } 1893 1894 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1895 if (rc) { 1896 TFP_DRV_LOG(ERR, 1897 "%s: Unable to lookup FW id, rc:%s\n", 1898 tf_dir_2_str(dir), 1899 strerror(-rc)); 1900 return rc; 1901 } 1902 flags = (dir == TF_DIR_TX ? 1903 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_TX : 1904 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_RX); 1905 1906 if (clear_on_read) 1907 flags |= HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_CLEAR_ON_READ; 1908 1909 /* Populate the request */ 1910 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1911 req.flags = tfp_cpu_to_le_16(flags); 1912 req.type = tfp_cpu_to_le_32(hcapi_type); 1913 req.index = tfp_cpu_to_le_32(index); 1914 1915 parms.tf_type = HWRM_TF_TBL_TYPE_GET; 1916 parms.req_data = (uint32_t *)&req; 1917 parms.req_size = sizeof(req); 1918 parms.resp_data = (uint32_t *)&resp; 1919 parms.resp_size = sizeof(resp); 1920 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1921 1922 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1923 &parms); 1924 if (rc) 1925 return rc; 1926 1927 /* 1928 * The response will be 64 bytes long, the response size will 1929 * be in words (16). All we can test for is that the response 1930 * size is < to the requested size. 1931 */ 1932 if ((tfp_le_to_cpu_32(resp.size) * 4) < size) 1933 return -EINVAL; 1934 1935 /* 1936 * Copy the requested number of bytes 1937 */ 1938 tfp_memcpy(data, 1939 &resp.data, 1940 size); 1941 1942 return 0; 1943 } 1944 1945 /* HWRM Tunneled messages */ 1946 1947 int 1948 tf_msg_get_global_cfg(struct tf *tfp, 1949 struct tf_global_cfg_parms *params) 1950 { 1951 int rc = 0; 1952 struct tfp_send_msg_parms parms = { 0 }; 1953 struct hwrm_tf_global_cfg_get_input req = { 0 }; 1954 struct hwrm_tf_global_cfg_get_output resp = { 0 }; 1955 uint32_t flags = 0; 1956 uint8_t fw_session_id; 1957 uint16_t resp_size = 0; 1958 struct tf_dev_info *dev; 1959 struct tf_session *tfs; 1960 1961 /* Retrieve the session information */ 1962 rc = tf_session_get_session_internal(tfp, &tfs); 1963 if (rc) { 1964 TFP_DRV_LOG(ERR, 1965 "%s: Failed to lookup session, rc:%s\n", 1966 tf_dir_2_str(params->dir), 1967 strerror(-rc)); 1968 return rc; 1969 } 1970 1971 /* Retrieve the device information */ 1972 rc = tf_session_get_device(tfs, &dev); 1973 if (rc) { 1974 TFP_DRV_LOG(ERR, 1975 "%s: Failed to lookup device, rc:%s\n", 1976 tf_dir_2_str(params->dir), 1977 strerror(-rc)); 1978 return rc; 1979 } 1980 1981 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1982 if (rc) { 1983 TFP_DRV_LOG(ERR, 1984 "%s: Unable to lookup FW id, rc:%s\n", 1985 tf_dir_2_str(params->dir), 1986 strerror(-rc)); 1987 return rc; 1988 } 1989 1990 flags = (params->dir == TF_DIR_TX ? 1991 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX : 1992 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX); 1993 1994 /* Populate the request */ 1995 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1996 req.flags = tfp_cpu_to_le_32(flags); 1997 req.type = tfp_cpu_to_le_32(params->type); 1998 req.offset = tfp_cpu_to_le_32(params->offset); 1999 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes); 2000 2001 parms.tf_type = HWRM_TF_GLOBAL_CFG_GET; 2002 parms.req_data = (uint32_t *)&req; 2003 parms.req_size = sizeof(req); 2004 parms.resp_data = (uint32_t *)&resp; 2005 parms.resp_size = sizeof(resp); 2006 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2007 2008 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 2009 if (rc != 0) 2010 return rc; 2011 2012 /* Verify that we got enough buffer to return the requested data */ 2013 resp_size = tfp_le_to_cpu_16(resp.size); 2014 if (resp_size < params->config_sz_in_bytes) 2015 return -EINVAL; 2016 2017 if (params->config) 2018 tfp_memcpy(params->config, 2019 resp.data, 2020 resp_size); 2021 else 2022 return -EFAULT; 2023 2024 return 0; 2025 } 2026 2027 int 2028 tf_msg_set_global_cfg(struct tf *tfp, 2029 struct tf_global_cfg_parms *params) 2030 { 2031 int rc = 0; 2032 struct tfp_send_msg_parms parms = { 0 }; 2033 struct hwrm_tf_global_cfg_set_input req = { 0 }; 2034 struct hwrm_tf_global_cfg_set_output resp = { 0 }; 2035 uint32_t flags = 0; 2036 uint8_t fw_session_id; 2037 struct tf_dev_info *dev; 2038 struct tf_session *tfs; 2039 2040 /* Retrieve the session information */ 2041 rc = tf_session_get_session_internal(tfp, &tfs); 2042 if (rc) { 2043 TFP_DRV_LOG(ERR, 2044 "%s: Failed to lookup session, rc:%s\n", 2045 tf_dir_2_str(params->dir), 2046 strerror(-rc)); 2047 return rc; 2048 } 2049 2050 /* Retrieve the device information */ 2051 rc = tf_session_get_device(tfs, &dev); 2052 if (rc) { 2053 TFP_DRV_LOG(ERR, 2054 "%s: Failed to lookup device, rc:%s\n", 2055 tf_dir_2_str(params->dir), 2056 strerror(-rc)); 2057 return rc; 2058 } 2059 2060 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 2061 if (rc) { 2062 TFP_DRV_LOG(ERR, 2063 "%s: Unable to lookup FW id, rc:%s\n", 2064 tf_dir_2_str(params->dir), 2065 strerror(-rc)); 2066 return rc; 2067 } 2068 2069 flags = (params->dir == TF_DIR_TX ? 2070 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX : 2071 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX); 2072 2073 /* Populate the request */ 2074 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 2075 req.flags = tfp_cpu_to_le_32(flags); 2076 req.type = tfp_cpu_to_le_32(params->type); 2077 req.offset = tfp_cpu_to_le_32(params->offset); 2078 2079 /* Check for data size conformity */ 2080 if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) { 2081 rc = -EINVAL; 2082 TFP_DRV_LOG(ERR, 2083 "%s: Invalid parameters for msg type, rc:%s\n", 2084 tf_dir_2_str(params->dir), 2085 strerror(-rc)); 2086 return rc; 2087 } 2088 2089 tfp_memcpy(req.data, params->config, 2090 params->config_sz_in_bytes); 2091 2092 /* Only set mask if pointer is provided 2093 */ 2094 if (params->config_mask) { 2095 tfp_memcpy(req.mask, 2096 params->config_mask, 2097 params->config_sz_in_bytes); 2098 } 2099 2100 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes); 2101 2102 parms.tf_type = HWRM_TF_GLOBAL_CFG_SET; 2103 parms.req_data = (uint32_t *)&req; 2104 parms.req_size = sizeof(req); 2105 parms.resp_data = (uint32_t *)&resp; 2106 parms.resp_size = sizeof(resp); 2107 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2108 2109 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 2110 2111 if (rc != 0) 2112 return rc; 2113 2114 return 0; 2115 } 2116 2117 int 2118 tf_msg_bulk_get_tbl_entry(struct tf *tfp, 2119 enum tf_dir dir, 2120 uint16_t hcapi_type, 2121 uint32_t starting_idx, 2122 uint16_t num_entries, 2123 uint16_t entry_sz_in_bytes, 2124 uint64_t physical_mem_addr, 2125 bool clear_on_read) 2126 { 2127 int rc; 2128 struct tfp_send_msg_parms parms = { 0 }; 2129 struct hwrm_tf_tbl_type_bulk_get_input req = { 0 }; 2130 struct hwrm_tf_tbl_type_bulk_get_output resp = { 0 }; 2131 int data_size = 0; 2132 uint8_t fw_session_id; 2133 struct tf_dev_info *dev; 2134 struct tf_session *tfs; 2135 uint32_t flags = 0; 2136 2137 /* Retrieve the session information */ 2138 rc = tf_session_get_session(tfp, &tfs); 2139 if (rc) { 2140 TFP_DRV_LOG(ERR, 2141 "%s: Failed to lookup session, rc:%s\n", 2142 tf_dir_2_str(dir), 2143 strerror(-rc)); 2144 return rc; 2145 } 2146 2147 /* Retrieve the device information */ 2148 rc = tf_session_get_device(tfs, &dev); 2149 if (rc) { 2150 TFP_DRV_LOG(ERR, 2151 "%s: Failed to lookup device, rc:%s\n", 2152 tf_dir_2_str(dir), 2153 strerror(-rc)); 2154 return rc; 2155 } 2156 2157 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 2158 if (rc) { 2159 TFP_DRV_LOG(ERR, 2160 "%s: Unable to lookup FW id, rc:%s\n", 2161 tf_dir_2_str(dir), 2162 strerror(-rc)); 2163 return rc; 2164 } 2165 flags = (dir == TF_DIR_TX ? 2166 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_TX : 2167 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_RX); 2168 2169 if (clear_on_read) 2170 flags |= HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_CLEAR_ON_READ; 2171 2172 /* Populate the request */ 2173 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 2174 req.flags = tfp_cpu_to_le_16(flags); 2175 req.type = tfp_cpu_to_le_32(hcapi_type); 2176 req.start_index = tfp_cpu_to_le_32(starting_idx); 2177 req.num_entries = tfp_cpu_to_le_32(num_entries); 2178 2179 data_size = num_entries * entry_sz_in_bytes; 2180 2181 req.host_addr = tfp_cpu_to_le_64(physical_mem_addr); 2182 2183 parms.tf_type = HWRM_TF_TBL_TYPE_BULK_GET; 2184 parms.req_data = (uint32_t *)&req; 2185 parms.req_size = sizeof(req); 2186 parms.resp_data = (uint32_t *)&resp; 2187 parms.resp_size = sizeof(resp); 2188 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2189 2190 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 2191 &parms); 2192 if (rc) 2193 return rc; 2194 2195 /* Verify that we got enough buffer to return the requested data */ 2196 if (tfp_le_to_cpu_32(resp.size) != data_size) 2197 return -EINVAL; 2198 2199 return 0; 2200 } 2201 2202 int 2203 tf_msg_get_if_tbl_entry(struct tf *tfp, 2204 struct tf_if_tbl_get_parms *params) 2205 { 2206 int rc = 0; 2207 struct tfp_send_msg_parms parms = { 0 }; 2208 struct hwrm_tf_if_tbl_get_input req = { 0 }; 2209 struct hwrm_tf_if_tbl_get_output resp = { 0 }; 2210 uint32_t flags = 0; 2211 struct tf_dev_info *dev; 2212 struct tf_session *tfs; 2213 2214 /* Retrieve the session information */ 2215 rc = tf_session_get_session(tfp, &tfs); 2216 if (rc) { 2217 TFP_DRV_LOG(ERR, 2218 "%s: Failed to lookup session, rc:%s\n", 2219 tf_dir_2_str(params->dir), 2220 strerror(-rc)); 2221 return rc; 2222 } 2223 2224 /* Retrieve the device information */ 2225 rc = tf_session_get_device(tfs, &dev); 2226 if (rc) { 2227 TFP_DRV_LOG(ERR, 2228 "%s: Failed to lookup device, rc:%s\n", 2229 tf_dir_2_str(params->dir), 2230 strerror(-rc)); 2231 return rc; 2232 } 2233 2234 flags = (params->dir == TF_DIR_TX ? 2235 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX : 2236 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX); 2237 2238 /* Populate the request */ 2239 req.fw_session_id = 2240 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); 2241 req.flags = flags; 2242 req.type = params->hcapi_type; 2243 req.index = tfp_cpu_to_le_16(params->idx); 2244 req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes); 2245 2246 parms.tf_type = HWRM_TF_IF_TBL_GET; 2247 parms.req_data = (uint32_t *)&req; 2248 parms.req_size = sizeof(req); 2249 parms.resp_data = (uint32_t *)&resp; 2250 parms.resp_size = sizeof(resp); 2251 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2252 2253 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 2254 2255 if (rc != 0) 2256 return rc; 2257 2258 tfp_memcpy(¶ms->data[0], resp.data, req.size); 2259 2260 return 0; 2261 } 2262 2263 int 2264 tf_msg_set_if_tbl_entry(struct tf *tfp, 2265 struct tf_if_tbl_set_parms *params) 2266 { 2267 int rc = 0; 2268 struct tfp_send_msg_parms parms = { 0 }; 2269 struct hwrm_tf_if_tbl_set_input req = { 0 }; 2270 struct hwrm_tf_if_tbl_get_output resp = { 0 }; 2271 uint32_t flags = 0; 2272 struct tf_dev_info *dev; 2273 struct tf_session *tfs; 2274 2275 /* Retrieve the session information */ 2276 rc = tf_session_get_session(tfp, &tfs); 2277 if (rc) { 2278 TFP_DRV_LOG(ERR, 2279 "%s: Failed to lookup session, rc:%s\n", 2280 tf_dir_2_str(params->dir), 2281 strerror(-rc)); 2282 return rc; 2283 } 2284 2285 /* Retrieve the device information */ 2286 rc = tf_session_get_device(tfs, &dev); 2287 if (rc) 2288 return rc; 2289 2290 flags = (params->dir == TF_DIR_TX ? 2291 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX : 2292 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX); 2293 2294 /* Populate the request */ 2295 req.fw_session_id = 2296 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); 2297 req.flags = flags; 2298 req.type = params->hcapi_type; 2299 req.index = tfp_cpu_to_le_32(params->idx); 2300 req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes); 2301 tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes); 2302 2303 parms.tf_type = HWRM_TF_IF_TBL_SET; 2304 parms.req_data = (uint32_t *)&req; 2305 parms.req_size = sizeof(req); 2306 parms.resp_data = (uint32_t *)&resp; 2307 parms.resp_size = sizeof(resp); 2308 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2309 2310 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 2311 2312 if (rc != 0) 2313 return rc; 2314 2315 return 0; 2316 } 2317 2318 int 2319 tf_msg_get_version(struct bnxt *bp, 2320 struct tf_dev_info *dev, 2321 struct tf_get_version_parms *params) 2322 2323 { 2324 int rc; 2325 struct hwrm_tf_version_get_input req = { 0 }; 2326 struct hwrm_tf_version_get_output resp = { 0 }; 2327 struct tfp_send_msg_parms parms = { 0 }; 2328 2329 /* Populate the request */ 2330 parms.tf_type = HWRM_TF_VERSION_GET, 2331 parms.req_data = (uint32_t *)&req; 2332 parms.req_size = sizeof(req); 2333 parms.resp_data = (uint32_t *)&resp; 2334 parms.resp_size = sizeof(resp); 2335 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2336 2337 rc = tfp_send_msg_direct(bp, 2338 &parms); 2339 2340 params->major = resp.major; 2341 params->minor = resp.minor; 2342 params->update = resp.update; 2343 2344 dev->ops->tf_dev_map_hcapi_caps(resp.dev_caps_cfg, 2345 ¶ms->dev_ident_caps, 2346 ¶ms->dev_tcam_caps, 2347 ¶ms->dev_tbl_caps, 2348 ¶ms->dev_em_caps); 2349 2350 return rc; 2351 } 2352 2353 int 2354 tf_msg_session_set_hotup_state(struct tf *tfp, uint16_t state) 2355 { 2356 int rc; 2357 struct hwrm_tf_session_hotup_state_set_input req = { 0 }; 2358 struct hwrm_tf_session_hotup_state_set_output resp = { 0 }; 2359 struct tfp_send_msg_parms parms = { 0 }; 2360 uint8_t fw_session_id; 2361 struct tf_dev_info *dev; 2362 struct tf_session *tfs; 2363 2364 /* Retrieve the session information */ 2365 rc = tf_session_get_session_internal(tfp, &tfs); 2366 if (rc) { 2367 TFP_DRV_LOG(ERR, 2368 "Failed to lookup session, rc:%s\n", 2369 strerror(-rc)); 2370 return rc; 2371 } 2372 2373 /* Retrieve the device information */ 2374 rc = tf_session_get_device(tfs, &dev); 2375 if (rc) { 2376 TFP_DRV_LOG(ERR, 2377 "Failed to lookup device, rc:%s\n", 2378 strerror(-rc)); 2379 return rc; 2380 } 2381 2382 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 2383 if (rc) { 2384 TFP_DRV_LOG(ERR, 2385 "Unable to lookup FW id, rc:%s\n", 2386 strerror(-rc)); 2387 return rc; 2388 } 2389 2390 /* Populate the request */ 2391 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 2392 req.state = tfp_cpu_to_le_16(state); 2393 2394 parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_SET; 2395 parms.req_data = (uint32_t *)&req; 2396 parms.req_size = sizeof(req); 2397 parms.resp_data = (uint32_t *)&resp; 2398 parms.resp_size = sizeof(resp); 2399 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2400 2401 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 2402 &parms); 2403 return rc; 2404 } 2405 2406 int 2407 tf_msg_session_get_hotup_state(struct tf *tfp, 2408 uint16_t *state, 2409 uint16_t *ref_cnt) 2410 { 2411 int rc; 2412 struct hwrm_tf_session_hotup_state_get_input req = { 0 }; 2413 struct hwrm_tf_session_hotup_state_get_output resp = { 0 }; 2414 struct tfp_send_msg_parms parms = { 0 }; 2415 uint8_t fw_session_id; 2416 struct tf_dev_info *dev; 2417 struct tf_session *tfs; 2418 2419 /* Retrieve the session information */ 2420 rc = tf_session_get_session_internal(tfp, &tfs); 2421 if (rc) { 2422 TFP_DRV_LOG(ERR, 2423 "Failed to lookup session, rc:%s\n", 2424 strerror(-rc)); 2425 return rc; 2426 } 2427 2428 /* Retrieve the device information */ 2429 rc = tf_session_get_device(tfs, &dev); 2430 if (rc) { 2431 TFP_DRV_LOG(ERR, 2432 "Failed to lookup device, rc:%s\n", 2433 strerror(-rc)); 2434 return rc; 2435 } 2436 2437 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 2438 if (rc) { 2439 TFP_DRV_LOG(ERR, 2440 "Unable to lookup FW id, rc:%s\n", 2441 strerror(-rc)); 2442 return rc; 2443 } 2444 2445 /* Populate the request */ 2446 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 2447 2448 parms.tf_type = HWRM_TF_SESSION_HOTUP_STATE_GET; 2449 parms.req_data = (uint32_t *)&req; 2450 parms.req_size = sizeof(req); 2451 parms.resp_data = (uint32_t *)&resp; 2452 parms.resp_size = sizeof(resp); 2453 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2454 2455 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 2456 &parms); 2457 2458 *state = tfp_le_to_cpu_16(resp.state); 2459 *ref_cnt = tfp_le_to_cpu_16(resp.ref_cnt); 2460 2461 return rc; 2462 } 2463