1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019-2020 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_msg_common.h" 13 #include "tf_device.h" 14 #include "tf_msg.h" 15 #include "tf_util.h" 16 #include "tf_common.h" 17 #include "tf_session.h" 18 #include "tfp.h" 19 #include "hwrm_tf.h" 20 #include "tf_em.h" 21 22 /* Logging defines */ 23 #define TF_RM_MSG_DEBUG 0 24 25 /* Specific msg size defines as we cannot use defines in tf.yaml. This 26 * means we have to manually sync hwrm with these defines if the 27 * tf.yaml changes. 28 */ 29 #define TF_MSG_SET_GLOBAL_CFG_DATA_SIZE 16 30 #define TF_MSG_EM_INSERT_KEY_SIZE 64 31 #define TF_MSG_TBL_TYPE_SET_DATA_SIZE 88 32 33 /* Compile check - Catch any msg changes that we depend on, like the 34 * defines listed above for array size checking. 35 * 36 * Checking array size is dangerous in that the type could change and 37 * we wouldn't be able to catch it. Thus we check if the complete msg 38 * changed instead. Best we can do. 39 * 40 * If failure is observed then both msg size (defines below) and the 41 * array size (define above) should be checked and compared. 42 */ 43 #define TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET 56 44 static_assert(sizeof(struct hwrm_tf_global_cfg_set_input) == 45 TF_MSG_SIZE_HWRM_TF_GLOBAL_CFG_SET, 46 "HWRM message size changed: hwrm_tf_global_cfg_set_input"); 47 48 #define TF_MSG_SIZE_HWRM_TF_EM_INSERT 104 49 static_assert(sizeof(struct hwrm_tf_em_insert_input) == 50 TF_MSG_SIZE_HWRM_TF_EM_INSERT, 51 "HWRM message size changed: hwrm_tf_em_insert_input"); 52 53 #define TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET 128 54 static_assert(sizeof(struct hwrm_tf_tbl_type_set_input) == 55 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET, 56 "HWRM message size changed: hwrm_tf_tbl_type_set_input"); 57 58 /** 59 * This is the MAX data we can transport across regular HWRM 60 */ 61 #define TF_PCI_BUF_SIZE_MAX 88 62 63 /** 64 * If data bigger than TF_PCI_BUF_SIZE_MAX then use DMA method 65 */ 66 struct tf_msg_dma_buf { 67 void *va_addr; 68 uint64_t pa_addr; 69 }; 70 71 /** 72 * Allocates a DMA buffer that can be used for message transfer. 73 * 74 * [in] buf 75 * Pointer to DMA buffer structure 76 * 77 * [in] size 78 * Requested size of the buffer in bytes 79 * 80 * Returns: 81 * 0 - Success 82 * -ENOMEM - Unable to allocate buffer, no memory 83 */ 84 static int 85 tf_msg_alloc_dma_buf(struct tf_msg_dma_buf *buf, int size) 86 { 87 struct tfp_calloc_parms alloc_parms; 88 int rc; 89 90 /* Allocate session */ 91 alloc_parms.nitems = 1; 92 alloc_parms.size = size; 93 alloc_parms.alignment = 4096; 94 rc = tfp_calloc(&alloc_parms); 95 if (rc) 96 return -ENOMEM; 97 98 buf->pa_addr = (uintptr_t)alloc_parms.mem_pa; 99 buf->va_addr = alloc_parms.mem_va; 100 101 return 0; 102 } 103 104 /** 105 * Free's a previous allocated DMA buffer. 106 * 107 * [in] buf 108 * Pointer to DMA buffer structure 109 */ 110 static void 111 tf_msg_free_dma_buf(struct tf_msg_dma_buf *buf) 112 { 113 tfp_free(buf->va_addr); 114 } 115 116 /* HWRM Direct messages */ 117 118 int 119 tf_msg_session_open(struct tf *tfp, 120 char *ctrl_chan_name, 121 uint8_t *fw_session_id, 122 uint8_t *fw_session_client_id) 123 { 124 int rc; 125 struct hwrm_tf_session_open_input req = { 0 }; 126 struct hwrm_tf_session_open_output resp = { 0 }; 127 struct tfp_send_msg_parms parms = { 0 }; 128 129 /* Populate the request */ 130 tfp_memcpy(&req.session_name, ctrl_chan_name, TF_SESSION_NAME_MAX); 131 132 parms.tf_type = HWRM_TF_SESSION_OPEN; 133 parms.req_data = (uint32_t *)&req; 134 parms.req_size = sizeof(req); 135 parms.resp_data = (uint32_t *)&resp; 136 parms.resp_size = sizeof(resp); 137 parms.mailbox = TF_KONG_MB; 138 139 rc = tfp_send_msg_direct(tfp, 140 &parms); 141 if (rc) 142 return rc; 143 144 *fw_session_id = (uint8_t)tfp_le_to_cpu_32(resp.fw_session_id); 145 *fw_session_client_id = 146 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id); 147 148 return rc; 149 } 150 151 int 152 tf_msg_session_attach(struct tf *tfp __rte_unused, 153 char *ctrl_chan_name __rte_unused, 154 uint8_t tf_fw_session_id __rte_unused) 155 { 156 return -1; 157 } 158 159 int 160 tf_msg_session_client_register(struct tf *tfp, 161 char *ctrl_channel_name, 162 uint8_t *fw_session_client_id) 163 { 164 int rc; 165 struct hwrm_tf_session_register_input req = { 0 }; 166 struct hwrm_tf_session_register_output resp = { 0 }; 167 struct tfp_send_msg_parms parms = { 0 }; 168 uint8_t fw_session_id; 169 170 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 171 if (rc) { 172 TFP_DRV_LOG(ERR, 173 "Unable to lookup FW id, rc:%s\n", 174 strerror(-rc)); 175 return rc; 176 } 177 178 /* Populate the request */ 179 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 180 tfp_memcpy(&req.session_client_name, 181 ctrl_channel_name, 182 TF_SESSION_NAME_MAX); 183 184 parms.tf_type = HWRM_TF_SESSION_REGISTER; 185 parms.req_data = (uint32_t *)&req; 186 parms.req_size = sizeof(req); 187 parms.resp_data = (uint32_t *)&resp; 188 parms.resp_size = sizeof(resp); 189 parms.mailbox = TF_KONG_MB; 190 191 rc = tfp_send_msg_direct(tfp, 192 &parms); 193 if (rc) 194 return rc; 195 196 *fw_session_client_id = 197 (uint8_t)tfp_le_to_cpu_32(resp.fw_session_client_id); 198 199 return rc; 200 } 201 202 int 203 tf_msg_session_client_unregister(struct tf *tfp, 204 uint8_t fw_session_client_id) 205 { 206 int rc; 207 struct hwrm_tf_session_unregister_input req = { 0 }; 208 struct hwrm_tf_session_unregister_output resp = { 0 }; 209 struct tfp_send_msg_parms parms = { 0 }; 210 uint8_t fw_session_id; 211 212 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 213 if (rc) { 214 TFP_DRV_LOG(ERR, 215 "Unable to lookup FW id, rc:%s\n", 216 strerror(-rc)); 217 return rc; 218 } 219 220 /* Populate the request */ 221 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 222 req.fw_session_client_id = tfp_cpu_to_le_32(fw_session_client_id); 223 224 parms.tf_type = HWRM_TF_SESSION_UNREGISTER; 225 parms.req_data = (uint32_t *)&req; 226 parms.req_size = sizeof(req); 227 parms.resp_data = (uint32_t *)&resp; 228 parms.resp_size = sizeof(resp); 229 parms.mailbox = TF_KONG_MB; 230 231 rc = tfp_send_msg_direct(tfp, 232 &parms); 233 234 return rc; 235 } 236 237 int 238 tf_msg_session_close(struct tf *tfp) 239 { 240 int rc; 241 struct hwrm_tf_session_close_input req = { 0 }; 242 struct hwrm_tf_session_close_output resp = { 0 }; 243 struct tfp_send_msg_parms parms = { 0 }; 244 uint8_t fw_session_id; 245 246 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 247 if (rc) { 248 TFP_DRV_LOG(ERR, 249 "Unable to lookup FW id, rc:%s\n", 250 strerror(-rc)); 251 return rc; 252 } 253 254 /* Populate the request */ 255 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 256 257 parms.tf_type = HWRM_TF_SESSION_CLOSE; 258 parms.req_data = (uint32_t *)&req; 259 parms.req_size = sizeof(req); 260 parms.resp_data = (uint32_t *)&resp; 261 parms.resp_size = sizeof(resp); 262 parms.mailbox = TF_KONG_MB; 263 264 rc = tfp_send_msg_direct(tfp, 265 &parms); 266 return rc; 267 } 268 269 int 270 tf_msg_session_qcfg(struct tf *tfp) 271 { 272 int rc; 273 struct hwrm_tf_session_qcfg_input req = { 0 }; 274 struct hwrm_tf_session_qcfg_output resp = { 0 }; 275 struct tfp_send_msg_parms parms = { 0 }; 276 uint8_t fw_session_id; 277 278 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 279 if (rc) { 280 TFP_DRV_LOG(ERR, 281 "Unable to lookup FW id, rc:%s\n", 282 strerror(-rc)); 283 return rc; 284 } 285 286 /* Populate the request */ 287 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 288 289 parms.tf_type = HWRM_TF_SESSION_QCFG, 290 parms.req_data = (uint32_t *)&req; 291 parms.req_size = sizeof(req); 292 parms.resp_data = (uint32_t *)&resp; 293 parms.resp_size = sizeof(resp); 294 parms.mailbox = TF_KONG_MB; 295 296 rc = tfp_send_msg_direct(tfp, 297 &parms); 298 return rc; 299 } 300 301 int 302 tf_msg_session_resc_qcaps(struct tf *tfp, 303 enum tf_dir dir, 304 uint16_t size, 305 struct tf_rm_resc_req_entry *query, 306 enum tf_rm_resc_resv_strategy *resv_strategy) 307 { 308 int rc; 309 int i; 310 struct tfp_send_msg_parms parms = { 0 }; 311 struct hwrm_tf_session_resc_qcaps_input req = { 0 }; 312 struct hwrm_tf_session_resc_qcaps_output resp = { 0 }; 313 uint8_t fw_session_id; 314 struct tf_msg_dma_buf qcaps_buf = { 0 }; 315 struct tf_rm_resc_req_entry *data; 316 int dma_size; 317 318 TF_CHECK_PARMS3(tfp, query, resv_strategy); 319 320 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 321 if (rc) { 322 TFP_DRV_LOG(ERR, 323 "%s: Unable to lookup FW id, rc:%s\n", 324 tf_dir_2_str(dir), 325 strerror(-rc)); 326 return rc; 327 } 328 329 /* Prepare DMA buffer */ 330 dma_size = size * sizeof(struct tf_rm_resc_req_entry); 331 rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size); 332 if (rc) 333 return rc; 334 335 /* Populate the request */ 336 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 337 req.flags = tfp_cpu_to_le_16(dir); 338 req.qcaps_size = size; 339 req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr); 340 341 parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS; 342 parms.req_data = (uint32_t *)&req; 343 parms.req_size = sizeof(req); 344 parms.resp_data = (uint32_t *)&resp; 345 parms.resp_size = sizeof(resp); 346 parms.mailbox = TF_KONG_MB; 347 348 rc = tfp_send_msg_direct(tfp, &parms); 349 if (rc) 350 goto cleanup; 351 352 /* Process the response 353 * Should always get expected number of entries 354 */ 355 if (tfp_le_to_cpu_32(resp.size) != size) { 356 TFP_DRV_LOG(ERR, 357 "%s: QCAPS message size error, rc:%s\n", 358 tf_dir_2_str(dir), 359 strerror(EINVAL)); 360 rc = -EINVAL; 361 goto cleanup; 362 } 363 364 #if (TF_RM_MSG_DEBUG == 1) 365 printf("size: %d\n", tfp_le_to_cpu_32(resp.size)); 366 #endif /* (TF_RM_MSG_DEBUG == 1) */ 367 368 /* Post process the response */ 369 data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr; 370 371 #if (TF_RM_MSG_DEBUG == 1) 372 printf("\nQCAPS\n"); 373 #endif /* (TF_RM_MSG_DEBUG == 1) */ 374 for (i = 0; i < size; i++) { 375 query[i].type = tfp_le_to_cpu_32(data[i].type); 376 query[i].min = tfp_le_to_cpu_16(data[i].min); 377 query[i].max = tfp_le_to_cpu_16(data[i].max); 378 379 #if (TF_RM_MSG_DEBUG == 1) 380 printf("type: %d(0x%x) %d %d\n", 381 query[i].type, 382 query[i].type, 383 query[i].min, 384 query[i].max); 385 #endif /* (TF_RM_MSG_DEBUG == 1) */ 386 387 } 388 389 *resv_strategy = resp.flags & 390 HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK; 391 392 cleanup: 393 tf_msg_free_dma_buf(&qcaps_buf); 394 395 return rc; 396 } 397 398 int 399 tf_msg_session_resc_alloc(struct tf *tfp, 400 enum tf_dir dir, 401 uint16_t size, 402 struct tf_rm_resc_req_entry *request, 403 struct tf_rm_resc_entry *resv) 404 { 405 int rc; 406 int i; 407 struct tfp_send_msg_parms parms = { 0 }; 408 struct hwrm_tf_session_resc_alloc_input req = { 0 }; 409 struct hwrm_tf_session_resc_alloc_output resp = { 0 }; 410 uint8_t fw_session_id; 411 struct tf_msg_dma_buf req_buf = { 0 }; 412 struct tf_msg_dma_buf resv_buf = { 0 }; 413 struct tf_rm_resc_req_entry *req_data; 414 struct tf_rm_resc_entry *resv_data; 415 int dma_size; 416 417 TF_CHECK_PARMS3(tfp, request, resv); 418 419 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 420 if (rc) { 421 TFP_DRV_LOG(ERR, 422 "%s: Unable to lookup FW id, rc:%s\n", 423 tf_dir_2_str(dir), 424 strerror(-rc)); 425 return rc; 426 } 427 428 /* Prepare DMA buffers */ 429 dma_size = size * sizeof(struct tf_rm_resc_req_entry); 430 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size); 431 if (rc) 432 return rc; 433 434 dma_size = size * sizeof(struct tf_rm_resc_entry); 435 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size); 436 if (rc) { 437 tf_msg_free_dma_buf(&req_buf); 438 return rc; 439 } 440 441 /* Populate the request */ 442 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 443 req.flags = tfp_cpu_to_le_16(dir); 444 req.req_size = size; 445 446 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr; 447 for (i = 0; i < size; i++) { 448 req_data[i].type = tfp_cpu_to_le_32(request[i].type); 449 req_data[i].min = tfp_cpu_to_le_16(request[i].min); 450 req_data[i].max = tfp_cpu_to_le_16(request[i].max); 451 } 452 453 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr); 454 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr); 455 456 parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC; 457 parms.req_data = (uint32_t *)&req; 458 parms.req_size = sizeof(req); 459 parms.resp_data = (uint32_t *)&resp; 460 parms.resp_size = sizeof(resp); 461 parms.mailbox = TF_KONG_MB; 462 463 rc = tfp_send_msg_direct(tfp, &parms); 464 if (rc) 465 goto cleanup; 466 467 /* Process the response 468 * Should always get expected number of entries 469 */ 470 if (tfp_le_to_cpu_32(resp.size) != size) { 471 TFP_DRV_LOG(ERR, 472 "%s: Alloc message size error, rc:%s\n", 473 tf_dir_2_str(dir), 474 strerror(EINVAL)); 475 rc = -EINVAL; 476 goto cleanup; 477 } 478 479 #if (TF_RM_MSG_DEBUG == 1) 480 printf("\nRESV\n"); 481 printf("size: %d\n", tfp_le_to_cpu_32(resp.size)); 482 #endif /* (TF_RM_MSG_DEBUG == 1) */ 483 484 /* Post process the response */ 485 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr; 486 for (i = 0; i < size; i++) { 487 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type); 488 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start); 489 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride); 490 491 #if (TF_RM_MSG_DEBUG == 1) 492 printf("%d type: %d(0x%x) %d %d\n", 493 i, 494 resv[i].type, 495 resv[i].type, 496 resv[i].start, 497 resv[i].stride); 498 #endif /* (TF_RM_MSG_DEBUG == 1) */ 499 } 500 501 cleanup: 502 tf_msg_free_dma_buf(&req_buf); 503 tf_msg_free_dma_buf(&resv_buf); 504 505 return rc; 506 } 507 508 int 509 tf_msg_session_resc_flush(struct tf *tfp, 510 enum tf_dir dir, 511 uint16_t size, 512 struct tf_rm_resc_entry *resv) 513 { 514 int rc; 515 int i; 516 struct tfp_send_msg_parms parms = { 0 }; 517 struct hwrm_tf_session_resc_flush_input req = { 0 }; 518 struct hwrm_tf_session_resc_flush_output resp = { 0 }; 519 uint8_t fw_session_id; 520 struct tf_msg_dma_buf resv_buf = { 0 }; 521 struct tf_rm_resc_entry *resv_data; 522 int dma_size; 523 524 TF_CHECK_PARMS2(tfp, resv); 525 526 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 527 if (rc) { 528 TFP_DRV_LOG(ERR, 529 "%s: Unable to lookup FW id, rc:%s\n", 530 tf_dir_2_str(dir), 531 strerror(-rc)); 532 return rc; 533 } 534 535 /* Prepare DMA buffers */ 536 dma_size = size * sizeof(struct tf_rm_resc_entry); 537 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size); 538 if (rc) 539 return rc; 540 541 /* Populate the request */ 542 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 543 req.flags = tfp_cpu_to_le_16(dir); 544 req.flush_size = size; 545 546 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr; 547 for (i = 0; i < size; i++) { 548 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type); 549 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start); 550 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride); 551 } 552 553 req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr); 554 555 parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH; 556 parms.req_data = (uint32_t *)&req; 557 parms.req_size = sizeof(req); 558 parms.resp_data = (uint32_t *)&resp; 559 parms.resp_size = sizeof(resp); 560 parms.mailbox = TF_KONG_MB; 561 562 rc = tfp_send_msg_direct(tfp, &parms); 563 564 tf_msg_free_dma_buf(&resv_buf); 565 566 return rc; 567 } 568 569 int 570 tf_msg_insert_em_internal_entry(struct tf *tfp, 571 struct tf_insert_em_entry_parms *em_parms, 572 uint16_t *rptr_index, 573 uint8_t *rptr_entry, 574 uint8_t *num_of_entries) 575 { 576 int rc; 577 struct tfp_send_msg_parms parms = { 0 }; 578 struct hwrm_tf_em_insert_input req = { 0 }; 579 struct hwrm_tf_em_insert_output resp = { 0 }; 580 struct tf_em_64b_entry *em_result = 581 (struct tf_em_64b_entry *)em_parms->em_record; 582 uint16_t flags; 583 uint8_t fw_session_id; 584 uint8_t msg_key_size; 585 586 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 587 if (rc) { 588 TFP_DRV_LOG(ERR, 589 "%s: Unable to lookup FW id, rc:%s\n", 590 tf_dir_2_str(em_parms->dir), 591 strerror(-rc)); 592 return rc; 593 } 594 595 /* Populate the request */ 596 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 597 598 /* Check for key size conformity */ 599 msg_key_size = (em_parms->key_sz_in_bits + 7) / 8; 600 if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) { 601 rc = -EINVAL; 602 TFP_DRV_LOG(ERR, 603 "%s: Invalid parameters for msg type, rc:%s\n", 604 tf_dir_2_str(em_parms->dir), 605 strerror(-rc)); 606 return rc; 607 } 608 609 tfp_memcpy(req.em_key, 610 em_parms->key, 611 msg_key_size); 612 613 flags = (em_parms->dir == TF_DIR_TX ? 614 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX : 615 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX); 616 req.flags = tfp_cpu_to_le_16(flags); 617 req.strength = (em_result->hdr.word1 & 618 CFA_P4_EEM_ENTRY_STRENGTH_MASK) >> 619 CFA_P4_EEM_ENTRY_STRENGTH_SHIFT; 620 req.em_key_bitlen = em_parms->key_sz_in_bits; 621 req.action_ptr = em_result->hdr.pointer; 622 req.em_record_idx = *rptr_index; 623 624 parms.tf_type = HWRM_TF_EM_INSERT; 625 parms.req_data = (uint32_t *)&req; 626 parms.req_size = sizeof(req); 627 parms.resp_data = (uint32_t *)&resp; 628 parms.resp_size = sizeof(resp); 629 parms.mailbox = TF_KONG_MB; 630 631 rc = tfp_send_msg_direct(tfp, 632 &parms); 633 if (rc) 634 return rc; 635 636 *rptr_entry = resp.rptr_entry; 637 *rptr_index = resp.rptr_index; 638 *num_of_entries = resp.num_of_entries; 639 640 return 0; 641 } 642 643 int 644 tf_msg_delete_em_entry(struct tf *tfp, 645 struct tf_delete_em_entry_parms *em_parms) 646 { 647 int rc; 648 struct tfp_send_msg_parms parms = { 0 }; 649 struct hwrm_tf_em_delete_input req = { 0 }; 650 struct hwrm_tf_em_delete_output resp = { 0 }; 651 uint16_t flags; 652 uint8_t fw_session_id; 653 654 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 655 if (rc) { 656 TFP_DRV_LOG(ERR, 657 "%s: Unable to lookup FW id, rc:%s\n", 658 tf_dir_2_str(em_parms->dir), 659 strerror(-rc)); 660 return rc; 661 } 662 663 /* Populate the request */ 664 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 665 666 flags = (em_parms->dir == TF_DIR_TX ? 667 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX : 668 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX); 669 req.flags = tfp_cpu_to_le_16(flags); 670 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle); 671 672 parms.tf_type = HWRM_TF_EM_DELETE; 673 parms.req_data = (uint32_t *)&req; 674 parms.req_size = sizeof(req); 675 parms.resp_data = (uint32_t *)&resp; 676 parms.resp_size = sizeof(resp); 677 parms.mailbox = TF_KONG_MB; 678 679 rc = tfp_send_msg_direct(tfp, 680 &parms); 681 if (rc) 682 return rc; 683 684 em_parms->index = tfp_le_to_cpu_16(resp.em_index); 685 686 return 0; 687 } 688 689 int 690 tf_msg_em_mem_rgtr(struct tf *tfp, 691 int page_lvl, 692 int page_size, 693 uint64_t dma_addr, 694 uint16_t *ctx_id) 695 { 696 int rc; 697 struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 }; 698 struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 }; 699 struct tfp_send_msg_parms parms = { 0 }; 700 701 req.page_level = page_lvl; 702 req.page_size = page_size; 703 req.page_dir = tfp_cpu_to_le_64(dma_addr); 704 705 parms.tf_type = HWRM_TF_CTXT_MEM_RGTR; 706 parms.req_data = (uint32_t *)&req; 707 parms.req_size = sizeof(req); 708 parms.resp_data = (uint32_t *)&resp; 709 parms.resp_size = sizeof(resp); 710 parms.mailbox = TF_KONG_MB; 711 712 rc = tfp_send_msg_direct(tfp, 713 &parms); 714 if (rc) 715 return rc; 716 717 *ctx_id = tfp_le_to_cpu_16(resp.ctx_id); 718 719 return rc; 720 } 721 722 int 723 tf_msg_em_mem_unrgtr(struct tf *tfp, 724 uint16_t *ctx_id) 725 { 726 int rc; 727 struct hwrm_tf_ctxt_mem_unrgtr_input req = {0}; 728 struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0}; 729 struct tfp_send_msg_parms parms = { 0 }; 730 731 req.ctx_id = tfp_cpu_to_le_32(*ctx_id); 732 733 parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR; 734 parms.req_data = (uint32_t *)&req; 735 parms.req_size = sizeof(req); 736 parms.resp_data = (uint32_t *)&resp; 737 parms.resp_size = sizeof(resp); 738 parms.mailbox = TF_KONG_MB; 739 740 rc = tfp_send_msg_direct(tfp, 741 &parms); 742 return rc; 743 } 744 745 int 746 tf_msg_em_qcaps(struct tf *tfp, 747 int dir, 748 struct tf_em_caps *em_caps) 749 { 750 int rc; 751 struct hwrm_tf_ext_em_qcaps_input req = {0}; 752 struct hwrm_tf_ext_em_qcaps_output resp = { 0 }; 753 uint32_t flags; 754 struct tfp_send_msg_parms parms = { 0 }; 755 756 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX : 757 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX); 758 req.flags = tfp_cpu_to_le_32(flags); 759 760 parms.tf_type = HWRM_TF_EXT_EM_QCAPS; 761 parms.req_data = (uint32_t *)&req; 762 parms.req_size = sizeof(req); 763 parms.resp_data = (uint32_t *)&resp; 764 parms.resp_size = sizeof(resp); 765 parms.mailbox = TF_KONG_MB; 766 767 rc = tfp_send_msg_direct(tfp, 768 &parms); 769 if (rc) 770 return rc; 771 772 em_caps->supported = tfp_le_to_cpu_32(resp.supported); 773 em_caps->max_entries_supported = 774 tfp_le_to_cpu_32(resp.max_entries_supported); 775 em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size); 776 em_caps->record_entry_size = 777 tfp_le_to_cpu_16(resp.record_entry_size); 778 em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size); 779 780 return rc; 781 } 782 783 int 784 tf_msg_em_cfg(struct tf *tfp, 785 uint32_t num_entries, 786 uint16_t key0_ctx_id, 787 uint16_t key1_ctx_id, 788 uint16_t record_ctx_id, 789 uint16_t efc_ctx_id, 790 uint8_t flush_interval, 791 int dir) 792 { 793 int rc; 794 struct hwrm_tf_ext_em_cfg_input req = {0}; 795 struct hwrm_tf_ext_em_cfg_output resp = {0}; 796 uint32_t flags; 797 struct tfp_send_msg_parms parms = { 0 }; 798 799 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX : 800 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX); 801 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD; 802 803 req.flags = tfp_cpu_to_le_32(flags); 804 req.num_entries = tfp_cpu_to_le_32(num_entries); 805 806 req.flush_interval = flush_interval; 807 808 req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id); 809 req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id); 810 req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id); 811 req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id); 812 813 parms.tf_type = HWRM_TF_EXT_EM_CFG; 814 parms.req_data = (uint32_t *)&req; 815 parms.req_size = sizeof(req); 816 parms.resp_data = (uint32_t *)&resp; 817 parms.resp_size = sizeof(resp); 818 parms.mailbox = TF_KONG_MB; 819 820 rc = tfp_send_msg_direct(tfp, 821 &parms); 822 return rc; 823 } 824 825 int 826 tf_msg_em_op(struct tf *tfp, 827 int dir, 828 uint16_t op) 829 { 830 int rc; 831 struct hwrm_tf_ext_em_op_input req = {0}; 832 struct hwrm_tf_ext_em_op_output resp = {0}; 833 uint32_t flags; 834 struct tfp_send_msg_parms parms = { 0 }; 835 836 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX : 837 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX); 838 req.flags = tfp_cpu_to_le_32(flags); 839 req.op = tfp_cpu_to_le_16(op); 840 841 parms.tf_type = HWRM_TF_EXT_EM_OP; 842 parms.req_data = (uint32_t *)&req; 843 parms.req_size = sizeof(req); 844 parms.resp_data = (uint32_t *)&resp; 845 parms.resp_size = sizeof(resp); 846 parms.mailbox = TF_KONG_MB; 847 848 rc = tfp_send_msg_direct(tfp, 849 &parms); 850 return rc; 851 } 852 853 int 854 tf_msg_tcam_entry_set(struct tf *tfp, 855 struct tf_tcam_set_parms *parms) 856 { 857 int rc; 858 struct tfp_send_msg_parms mparms = { 0 }; 859 struct hwrm_tf_tcam_set_input req = { 0 }; 860 struct hwrm_tf_tcam_set_output resp = { 0 }; 861 struct tf_msg_dma_buf buf = { 0 }; 862 uint8_t *data = NULL; 863 int data_size = 0; 864 uint8_t fw_session_id; 865 866 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 867 if (rc) { 868 TFP_DRV_LOG(ERR, 869 "%s: Unable to lookup FW id, rc:%s\n", 870 tf_dir_2_str(parms->dir), 871 strerror(-rc)); 872 return rc; 873 } 874 875 /* Populate the request */ 876 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 877 req.type = parms->hcapi_type; 878 req.idx = tfp_cpu_to_le_16(parms->idx); 879 if (parms->dir == TF_DIR_TX) 880 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX; 881 882 req.key_size = parms->key_size; 883 req.mask_offset = parms->key_size; 884 /* Result follows after key and mask, thus multiply by 2 */ 885 req.result_offset = 2 * parms->key_size; 886 req.result_size = parms->result_size; 887 data_size = 2 * req.key_size + req.result_size; 888 889 if (data_size <= TF_PCI_BUF_SIZE_MAX) { 890 /* use pci buffer */ 891 data = &req.dev_data[0]; 892 } else { 893 /* use dma buffer */ 894 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA; 895 rc = tf_msg_alloc_dma_buf(&buf, data_size); 896 if (rc) 897 goto cleanup; 898 data = buf.va_addr; 899 tfp_memcpy(&req.dev_data[0], 900 &buf.pa_addr, 901 sizeof(buf.pa_addr)); 902 } 903 904 tfp_memcpy(&data[0], parms->key, parms->key_size); 905 tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size); 906 tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size); 907 908 mparms.tf_type = HWRM_TF_TCAM_SET; 909 mparms.req_data = (uint32_t *)&req; 910 mparms.req_size = sizeof(req); 911 mparms.resp_data = (uint32_t *)&resp; 912 mparms.resp_size = sizeof(resp); 913 mparms.mailbox = TF_KONG_MB; 914 915 rc = tfp_send_msg_direct(tfp, 916 &mparms); 917 918 cleanup: 919 tf_msg_free_dma_buf(&buf); 920 921 return rc; 922 } 923 924 int 925 tf_msg_tcam_entry_free(struct tf *tfp, 926 struct tf_tcam_free_parms *in_parms) 927 { 928 int rc; 929 struct hwrm_tf_tcam_free_input req = { 0 }; 930 struct hwrm_tf_tcam_free_output resp = { 0 }; 931 struct tfp_send_msg_parms parms = { 0 }; 932 uint8_t fw_session_id; 933 934 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 935 if (rc) { 936 TFP_DRV_LOG(ERR, 937 "%s: Unable to lookup FW id, rc:%s\n", 938 tf_dir_2_str(in_parms->dir), 939 strerror(-rc)); 940 return rc; 941 } 942 943 /* Populate the request */ 944 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 945 req.type = in_parms->hcapi_type; 946 req.count = 1; 947 req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx); 948 if (in_parms->dir == TF_DIR_TX) 949 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX; 950 951 parms.tf_type = HWRM_TF_TCAM_FREE; 952 parms.req_data = (uint32_t *)&req; 953 parms.req_size = sizeof(req); 954 parms.resp_data = (uint32_t *)&resp; 955 parms.resp_size = sizeof(resp); 956 parms.mailbox = TF_KONG_MB; 957 958 rc = tfp_send_msg_direct(tfp, 959 &parms); 960 return rc; 961 } 962 963 int 964 tf_msg_set_tbl_entry(struct tf *tfp, 965 enum tf_dir dir, 966 uint16_t hcapi_type, 967 uint16_t size, 968 uint8_t *data, 969 uint32_t index) 970 { 971 int rc; 972 struct hwrm_tf_tbl_type_set_input req = { 0 }; 973 struct hwrm_tf_tbl_type_set_output resp = { 0 }; 974 struct tfp_send_msg_parms parms = { 0 }; 975 uint8_t fw_session_id; 976 977 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 978 if (rc) { 979 TFP_DRV_LOG(ERR, 980 "%s: Unable to lookup FW id, rc:%s\n", 981 tf_dir_2_str(dir), 982 strerror(-rc)); 983 return rc; 984 } 985 986 /* Populate the request */ 987 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 988 req.flags = tfp_cpu_to_le_16(dir); 989 req.type = tfp_cpu_to_le_32(hcapi_type); 990 req.size = tfp_cpu_to_le_16(size); 991 req.index = tfp_cpu_to_le_32(index); 992 993 /* Check for data size conformity */ 994 if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) { 995 rc = -EINVAL; 996 TFP_DRV_LOG(ERR, 997 "%s: Invalid parameters for msg type, rc:%s\n", 998 tf_dir_2_str(dir), 999 strerror(-rc)); 1000 return rc; 1001 } 1002 1003 tfp_memcpy(&req.data, 1004 data, 1005 size); 1006 1007 parms.tf_type = HWRM_TF_TBL_TYPE_SET; 1008 parms.req_data = (uint32_t *)&req; 1009 parms.req_size = sizeof(req); 1010 parms.resp_data = (uint32_t *)&resp; 1011 parms.resp_size = sizeof(resp); 1012 parms.mailbox = TF_KONG_MB; 1013 1014 rc = tfp_send_msg_direct(tfp, 1015 &parms); 1016 if (rc) 1017 return rc; 1018 1019 return tfp_le_to_cpu_32(parms.tf_resp_code); 1020 } 1021 1022 int 1023 tf_msg_get_tbl_entry(struct tf *tfp, 1024 enum tf_dir dir, 1025 uint16_t hcapi_type, 1026 uint16_t size, 1027 uint8_t *data, 1028 uint32_t index) 1029 { 1030 int rc; 1031 struct hwrm_tf_tbl_type_get_input req = { 0 }; 1032 struct hwrm_tf_tbl_type_get_output resp = { 0 }; 1033 struct tfp_send_msg_parms parms = { 0 }; 1034 uint8_t fw_session_id; 1035 1036 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1037 if (rc) { 1038 TFP_DRV_LOG(ERR, 1039 "%s: Unable to lookup FW id, rc:%s\n", 1040 tf_dir_2_str(dir), 1041 strerror(-rc)); 1042 return rc; 1043 } 1044 1045 /* Populate the request */ 1046 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1047 req.flags = tfp_cpu_to_le_16(dir); 1048 req.type = tfp_cpu_to_le_32(hcapi_type); 1049 req.index = tfp_cpu_to_le_32(index); 1050 1051 parms.tf_type = HWRM_TF_TBL_TYPE_GET; 1052 parms.req_data = (uint32_t *)&req; 1053 parms.req_size = sizeof(req); 1054 parms.resp_data = (uint32_t *)&resp; 1055 parms.resp_size = sizeof(resp); 1056 parms.mailbox = TF_KONG_MB; 1057 1058 rc = tfp_send_msg_direct(tfp, 1059 &parms); 1060 if (rc) 1061 return rc; 1062 1063 /* Verify that we got enough buffer to return the requested data */ 1064 if (tfp_le_to_cpu_32(resp.size) != size) 1065 return -EINVAL; 1066 1067 tfp_memcpy(data, 1068 &resp.data, 1069 size); 1070 1071 return tfp_le_to_cpu_32(parms.tf_resp_code); 1072 } 1073 1074 /* HWRM Tunneled messages */ 1075 1076 int 1077 tf_msg_get_global_cfg(struct tf *tfp, 1078 struct tf_dev_global_cfg_parms *params) 1079 { 1080 int rc = 0; 1081 struct tfp_send_msg_parms parms = { 0 }; 1082 struct hwrm_tf_global_cfg_get_input req = { 0 }; 1083 struct hwrm_tf_global_cfg_get_output resp = { 0 }; 1084 uint32_t flags = 0; 1085 uint8_t fw_session_id; 1086 uint16_t resp_size = 0; 1087 1088 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1089 if (rc) { 1090 TFP_DRV_LOG(ERR, 1091 "%s: Unable to lookup FW id, rc:%s\n", 1092 tf_dir_2_str(params->dir), 1093 strerror(-rc)); 1094 return rc; 1095 } 1096 1097 flags = (params->dir == TF_DIR_TX ? 1098 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX : 1099 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX); 1100 1101 /* Populate the request */ 1102 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1103 req.flags = tfp_cpu_to_le_32(flags); 1104 req.type = tfp_cpu_to_le_32(params->type); 1105 req.offset = tfp_cpu_to_le_32(params->offset); 1106 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes); 1107 1108 parms.tf_type = HWRM_TF_GLOBAL_CFG_GET; 1109 parms.req_data = (uint32_t *)&req; 1110 parms.req_size = sizeof(req); 1111 parms.resp_data = (uint32_t *)&resp; 1112 parms.resp_size = sizeof(resp); 1113 parms.mailbox = TF_KONG_MB; 1114 1115 rc = tfp_send_msg_direct(tfp, &parms); 1116 if (rc != 0) 1117 return rc; 1118 1119 /* Verify that we got enough buffer to return the requested data */ 1120 resp_size = tfp_le_to_cpu_16(resp.size); 1121 if (resp_size < params->config_sz_in_bytes) 1122 return -EINVAL; 1123 1124 if (params->config) 1125 tfp_memcpy(params->config, 1126 resp.data, 1127 resp_size); 1128 else 1129 return -EFAULT; 1130 1131 return tfp_le_to_cpu_32(parms.tf_resp_code); 1132 } 1133 1134 int 1135 tf_msg_set_global_cfg(struct tf *tfp, 1136 struct tf_dev_global_cfg_parms *params) 1137 { 1138 int rc = 0; 1139 struct tfp_send_msg_parms parms = { 0 }; 1140 struct hwrm_tf_global_cfg_set_input req = { 0 }; 1141 struct hwrm_tf_global_cfg_set_output resp = { 0 }; 1142 uint32_t flags = 0; 1143 uint8_t fw_session_id; 1144 1145 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1146 if (rc) { 1147 TFP_DRV_LOG(ERR, 1148 "%s: Unable to lookup FW id, rc:%s\n", 1149 tf_dir_2_str(params->dir), 1150 strerror(-rc)); 1151 return rc; 1152 } 1153 1154 flags = (params->dir == TF_DIR_TX ? 1155 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX : 1156 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX); 1157 1158 /* Populate the request */ 1159 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1160 req.flags = tfp_cpu_to_le_32(flags); 1161 req.type = tfp_cpu_to_le_32(params->type); 1162 req.offset = tfp_cpu_to_le_32(params->offset); 1163 1164 /* Check for data size conformity */ 1165 if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) { 1166 rc = -EINVAL; 1167 TFP_DRV_LOG(ERR, 1168 "%s: Invalid parameters for msg type, rc:%s\n", 1169 tf_dir_2_str(params->dir), 1170 strerror(-rc)); 1171 return rc; 1172 } 1173 1174 tfp_memcpy(req.data, params->config, 1175 params->config_sz_in_bytes); 1176 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes); 1177 1178 parms.tf_type = HWRM_TF_GLOBAL_CFG_SET; 1179 parms.req_data = (uint32_t *)&req; 1180 parms.req_size = sizeof(req); 1181 parms.resp_data = (uint32_t *)&resp; 1182 parms.resp_size = sizeof(resp); 1183 parms.mailbox = TF_KONG_MB; 1184 1185 rc = tfp_send_msg_direct(tfp, &parms); 1186 1187 if (rc != 0) 1188 return rc; 1189 1190 return tfp_le_to_cpu_32(parms.tf_resp_code); 1191 } 1192 1193 int 1194 tf_msg_bulk_get_tbl_entry(struct tf *tfp, 1195 enum tf_dir dir, 1196 uint16_t hcapi_type, 1197 uint32_t starting_idx, 1198 uint16_t num_entries, 1199 uint16_t entry_sz_in_bytes, 1200 uint64_t physical_mem_addr) 1201 { 1202 int rc; 1203 struct tfp_send_msg_parms parms = { 0 }; 1204 struct tf_tbl_type_bulk_get_input req = { 0 }; 1205 struct tf_tbl_type_bulk_get_output resp = { 0 }; 1206 int data_size = 0; 1207 uint8_t fw_session_id; 1208 1209 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1210 if (rc) { 1211 TFP_DRV_LOG(ERR, 1212 "%s: Unable to lookup FW id, rc:%s\n", 1213 tf_dir_2_str(dir), 1214 strerror(-rc)); 1215 return rc; 1216 } 1217 1218 /* Populate the request */ 1219 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1220 req.flags = tfp_cpu_to_le_16(dir); 1221 req.type = tfp_cpu_to_le_32(hcapi_type); 1222 req.start_index = tfp_cpu_to_le_32(starting_idx); 1223 req.num_entries = tfp_cpu_to_le_32(num_entries); 1224 1225 data_size = num_entries * entry_sz_in_bytes; 1226 1227 req.host_addr = tfp_cpu_to_le_64(physical_mem_addr); 1228 1229 MSG_PREP(parms, 1230 TF_KONG_MB, 1231 HWRM_TF, 1232 HWRM_TFT_TBL_TYPE_BULK_GET, 1233 req, 1234 resp); 1235 1236 rc = tfp_send_msg_tunneled(tfp, &parms); 1237 if (rc) 1238 return rc; 1239 1240 /* Verify that we got enough buffer to return the requested data */ 1241 if (tfp_le_to_cpu_32(resp.size) != data_size) 1242 return -EINVAL; 1243 1244 return tfp_le_to_cpu_32(parms.tf_resp_code); 1245 } 1246 1247 int 1248 tf_msg_get_if_tbl_entry(struct tf *tfp, 1249 struct tf_if_tbl_get_parms *params) 1250 { 1251 int rc = 0; 1252 struct tfp_send_msg_parms parms = { 0 }; 1253 struct hwrm_tf_if_tbl_get_input req = { 0 }; 1254 struct hwrm_tf_if_tbl_get_output resp = { 0 }; 1255 uint32_t flags = 0; 1256 struct tf_session *tfs; 1257 1258 /* Retrieve the session information */ 1259 rc = tf_session_get_session(tfp, &tfs); 1260 if (rc) { 1261 TFP_DRV_LOG(ERR, 1262 "%s: Failed to lookup session, rc:%s\n", 1263 tf_dir_2_str(params->dir), 1264 strerror(-rc)); 1265 return rc; 1266 } 1267 1268 flags = (params->dir == TF_DIR_TX ? 1269 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_TX : 1270 HWRM_TF_IF_TBL_GET_INPUT_FLAGS_DIR_RX); 1271 1272 /* Populate the request */ 1273 req.fw_session_id = 1274 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); 1275 req.flags = flags; 1276 req.type = params->hcapi_type; 1277 req.index = tfp_cpu_to_le_16(params->idx); 1278 req.size = tfp_cpu_to_le_16(params->data_sz_in_bytes); 1279 1280 parms.tf_type = HWRM_TF_IF_TBL_GET; 1281 parms.req_data = (uint32_t *)&req; 1282 parms.req_size = sizeof(req); 1283 parms.resp_data = (uint32_t *)&resp; 1284 parms.resp_size = sizeof(resp); 1285 parms.mailbox = TF_KONG_MB; 1286 1287 rc = tfp_send_msg_direct(tfp, &parms); 1288 1289 if (rc != 0) 1290 return rc; 1291 1292 if (parms.tf_resp_code != 0) 1293 return tfp_le_to_cpu_32(parms.tf_resp_code); 1294 1295 tfp_memcpy(¶ms->data[0], resp.data, req.size); 1296 1297 return tfp_le_to_cpu_32(parms.tf_resp_code); 1298 } 1299 1300 int 1301 tf_msg_set_if_tbl_entry(struct tf *tfp, 1302 struct tf_if_tbl_set_parms *params) 1303 { 1304 int rc = 0; 1305 struct tfp_send_msg_parms parms = { 0 }; 1306 struct hwrm_tf_if_tbl_set_input req = { 0 }; 1307 struct hwrm_tf_if_tbl_get_output resp = { 0 }; 1308 uint32_t flags = 0; 1309 struct tf_session *tfs; 1310 1311 /* Retrieve the session information */ 1312 rc = tf_session_get_session(tfp, &tfs); 1313 if (rc) { 1314 TFP_DRV_LOG(ERR, 1315 "%s: Failed to lookup session, rc:%s\n", 1316 tf_dir_2_str(params->dir), 1317 strerror(-rc)); 1318 return rc; 1319 } 1320 1321 1322 flags = (params->dir == TF_DIR_TX ? 1323 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_TX : 1324 HWRM_TF_IF_TBL_SET_INPUT_FLAGS_DIR_RX); 1325 1326 /* Populate the request */ 1327 req.fw_session_id = 1328 tfp_cpu_to_le_32(tfs->session_id.internal.fw_session_id); 1329 req.flags = flags; 1330 req.type = params->hcapi_type; 1331 req.index = tfp_cpu_to_le_32(params->idx); 1332 req.size = tfp_cpu_to_le_32(params->data_sz_in_bytes); 1333 tfp_memcpy(&req.data[0], params->data, params->data_sz_in_bytes); 1334 1335 parms.tf_type = HWRM_TF_IF_TBL_SET; 1336 parms.req_data = (uint32_t *)&req; 1337 parms.req_size = sizeof(req); 1338 parms.resp_data = (uint32_t *)&resp; 1339 parms.resp_size = sizeof(resp); 1340 parms.mailbox = TF_KONG_MB; 1341 1342 rc = tfp_send_msg_direct(tfp, &parms); 1343 1344 if (rc != 0) 1345 return rc; 1346 1347 return tfp_le_to_cpu_32(parms.tf_resp_code); 1348 } 1349