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