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 uint8_t *sram_profile) 385 { 386 int rc; 387 int i; 388 struct tfp_send_msg_parms parms = { 0 }; 389 struct hwrm_tf_session_resc_qcaps_input req = { 0 }; 390 struct hwrm_tf_session_resc_qcaps_output resp = { 0 }; 391 struct tf_msg_dma_buf qcaps_buf = { 0 }; 392 struct tf_rm_resc_req_entry *data; 393 int dma_size; 394 395 TF_CHECK_PARMS3(tfp, query, resv_strategy); 396 397 /* Prepare DMA buffer */ 398 dma_size = size * sizeof(struct tf_rm_resc_req_entry); 399 rc = tf_msg_alloc_dma_buf(&qcaps_buf, dma_size); 400 if (rc) 401 return rc; 402 403 /* Populate the request */ 404 req.fw_session_id = 0; 405 req.flags = tfp_cpu_to_le_16(dir); 406 req.qcaps_size = size; 407 req.qcaps_addr = tfp_cpu_to_le_64(qcaps_buf.pa_addr); 408 409 parms.tf_type = HWRM_TF_SESSION_RESC_QCAPS; 410 parms.req_data = (uint32_t *)&req; 411 parms.req_size = sizeof(req); 412 parms.resp_data = (uint32_t *)&resp; 413 parms.resp_size = sizeof(resp); 414 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 415 416 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 417 if (rc) 418 goto cleanup; 419 420 /* Process the response 421 * Should always get expected number of entries 422 */ 423 if (tfp_le_to_cpu_32(resp.size) != size) { 424 TFP_DRV_LOG(WARNING, 425 "%s: QCAPS message size error, rc:%s, request %d vs response %d\n", 426 tf_dir_2_str(dir), 427 strerror(EINVAL), 428 size, 429 resp.size); 430 } 431 432 /* Post process the response */ 433 data = (struct tf_rm_resc_req_entry *)qcaps_buf.va_addr; 434 435 for (i = 0; i < resp.size; i++) { 436 query[i].type = tfp_le_to_cpu_32(data[i].type); 437 query[i].min = tfp_le_to_cpu_16(data[i].min); 438 query[i].max = tfp_le_to_cpu_16(data[i].max); 439 } 440 441 *resv_strategy = resp.flags & 442 HWRM_TF_SESSION_RESC_QCAPS_OUTPUT_FLAGS_SESS_RESV_STRATEGY_MASK; 443 444 if (sram_profile != NULL) 445 *sram_profile = resp.sram_profile; 446 447 cleanup: 448 tf_msg_free_dma_buf(&qcaps_buf); 449 450 return rc; 451 } 452 453 int 454 tf_msg_session_resc_alloc(struct tf *tfp, 455 struct tf_dev_info *dev, 456 enum tf_dir dir, 457 uint16_t size, 458 struct tf_rm_resc_req_entry *request, 459 struct tf_rm_resc_entry *resv) 460 { 461 int rc; 462 int i; 463 struct tfp_send_msg_parms parms = { 0 }; 464 struct hwrm_tf_session_resc_alloc_input req = { 0 }; 465 struct hwrm_tf_session_resc_alloc_output resp = { 0 }; 466 uint8_t fw_session_id; 467 struct tf_msg_dma_buf req_buf = { 0 }; 468 struct tf_msg_dma_buf resv_buf = { 0 }; 469 struct tf_rm_resc_req_entry *req_data; 470 struct tf_rm_resc_entry *resv_data; 471 int dma_size; 472 struct tf_session *tfs; 473 474 /* Retrieve the session information */ 475 rc = tf_session_get_session_internal(tfp, &tfs); 476 if (rc) { 477 TFP_DRV_LOG(ERR, 478 "Failed to lookup session, rc:%s\n", 479 strerror(-rc)); 480 return rc; 481 } 482 483 TF_CHECK_PARMS3(tfp, request, resv); 484 485 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 486 if (rc) { 487 TFP_DRV_LOG(ERR, 488 "%s: Unable to lookup FW id, rc:%s\n", 489 tf_dir_2_str(dir), 490 strerror(-rc)); 491 return rc; 492 } 493 494 /* Prepare DMA buffers */ 495 dma_size = size * sizeof(struct tf_rm_resc_req_entry); 496 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size); 497 if (rc) 498 return rc; 499 500 dma_size = size * sizeof(struct tf_rm_resc_entry); 501 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size); 502 if (rc) { 503 tf_msg_free_dma_buf(&req_buf); 504 return rc; 505 } 506 507 /* Populate the request */ 508 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 509 req.flags = tfp_cpu_to_le_16(dir); 510 req.req_size = size; 511 512 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr; 513 for (i = 0; i < size; i++) { 514 req_data[i].type = tfp_cpu_to_le_32(request[i].type); 515 req_data[i].min = tfp_cpu_to_le_16(request[i].min); 516 req_data[i].max = tfp_cpu_to_le_16(request[i].max); 517 } 518 519 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr); 520 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr); 521 522 parms.tf_type = HWRM_TF_SESSION_RESC_ALLOC; 523 parms.req_data = (uint32_t *)&req; 524 parms.req_size = sizeof(req); 525 parms.resp_data = (uint32_t *)&resp; 526 parms.resp_size = sizeof(resp); 527 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 528 529 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 530 if (rc) 531 goto cleanup; 532 533 /* Process the response 534 * Should always get expected number of entries 535 */ 536 if (tfp_le_to_cpu_32(resp.size) != size) { 537 TFP_DRV_LOG(ERR, 538 "%s: Alloc message size error, rc:%s\n", 539 tf_dir_2_str(dir), 540 strerror(EINVAL)); 541 rc = -EINVAL; 542 goto cleanup; 543 } 544 545 /* Post process the response */ 546 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr; 547 for (i = 0; i < size; i++) { 548 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type); 549 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start); 550 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride); 551 } 552 553 cleanup: 554 tf_msg_free_dma_buf(&req_buf); 555 tf_msg_free_dma_buf(&resv_buf); 556 557 return rc; 558 } 559 560 int 561 tf_msg_session_resc_info(struct tf *tfp, 562 struct tf_dev_info *dev, 563 enum tf_dir dir, 564 uint16_t size, 565 struct tf_rm_resc_req_entry *request, 566 struct tf_rm_resc_entry *resv) 567 { 568 int rc; 569 int i; 570 struct tfp_send_msg_parms parms = { 0 }; 571 struct hwrm_tf_session_resc_info_input req = { 0 }; 572 struct hwrm_tf_session_resc_info_output resp = { 0 }; 573 uint8_t fw_session_id; 574 struct tf_msg_dma_buf req_buf = { 0 }; 575 struct tf_msg_dma_buf resv_buf = { 0 }; 576 struct tf_rm_resc_req_entry *req_data; 577 struct tf_rm_resc_entry *resv_data; 578 int dma_size; 579 struct tf_session *tfs; 580 581 /* Retrieve the session information */ 582 rc = tf_session_get_session_internal(tfp, &tfs); 583 if (rc) { 584 TFP_DRV_LOG(ERR, 585 "Failed to lookup session, rc:%s\n", 586 strerror(-rc)); 587 return rc; 588 } 589 590 TF_CHECK_PARMS3(tfp, request, resv); 591 592 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 593 if (rc) { 594 TFP_DRV_LOG(ERR, 595 "%s: Unable to lookup FW id, rc:%s\n", 596 tf_dir_2_str(dir), 597 strerror(-rc)); 598 return rc; 599 } 600 601 /* Prepare DMA buffers */ 602 dma_size = size * sizeof(struct tf_rm_resc_req_entry); 603 rc = tf_msg_alloc_dma_buf(&req_buf, dma_size); 604 if (rc) 605 return rc; 606 607 dma_size = size * sizeof(struct tf_rm_resc_entry); 608 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size); 609 if (rc) { 610 tf_msg_free_dma_buf(&req_buf); 611 return rc; 612 } 613 614 /* Populate the request */ 615 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 616 req.flags = tfp_cpu_to_le_16(dir); 617 req.req_size = size; 618 619 req_data = (struct tf_rm_resc_req_entry *)req_buf.va_addr; 620 for (i = 0; i < size; i++) { 621 req_data[i].type = tfp_cpu_to_le_32(request[i].type); 622 req_data[i].min = tfp_cpu_to_le_16(request[i].min); 623 req_data[i].max = tfp_cpu_to_le_16(request[i].max); 624 } 625 626 req.req_addr = tfp_cpu_to_le_64(req_buf.pa_addr); 627 req.resc_addr = tfp_cpu_to_le_64(resv_buf.pa_addr); 628 629 parms.tf_type = HWRM_TF_SESSION_RESC_INFO; 630 parms.req_data = (uint32_t *)&req; 631 parms.req_size = sizeof(req); 632 parms.resp_data = (uint32_t *)&resp; 633 parms.resp_size = sizeof(resp); 634 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 635 636 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 637 if (rc) 638 goto cleanup; 639 640 /* Process the response 641 * Should always get expected number of entries 642 */ 643 if (tfp_le_to_cpu_32(resp.size) != size) { 644 TFP_DRV_LOG(ERR, 645 "%s: Alloc message size error, rc:%s\n", 646 tf_dir_2_str(dir), 647 strerror(EINVAL)); 648 rc = -EINVAL; 649 goto cleanup; 650 } 651 652 /* Post process the response */ 653 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr; 654 for (i = 0; i < size; i++) { 655 resv[i].type = tfp_le_to_cpu_32(resv_data[i].type); 656 resv[i].start = tfp_le_to_cpu_16(resv_data[i].start); 657 resv[i].stride = tfp_le_to_cpu_16(resv_data[i].stride); 658 } 659 660 cleanup: 661 tf_msg_free_dma_buf(&req_buf); 662 tf_msg_free_dma_buf(&resv_buf); 663 664 return rc; 665 } 666 667 int 668 tf_msg_session_resc_flush(struct tf *tfp, 669 enum tf_dir dir, 670 uint16_t size, 671 struct tf_rm_resc_entry *resv) 672 { 673 int rc; 674 int i; 675 struct tfp_send_msg_parms parms = { 0 }; 676 struct hwrm_tf_session_resc_flush_input req = { 0 }; 677 struct hwrm_tf_session_resc_flush_output resp = { 0 }; 678 uint8_t fw_session_id; 679 struct tf_msg_dma_buf resv_buf = { 0 }; 680 struct tf_rm_resc_entry *resv_data; 681 int dma_size; 682 struct tf_dev_info *dev; 683 struct tf_session *tfs; 684 685 TF_CHECK_PARMS2(tfp, resv); 686 687 /* Retrieve the session information */ 688 rc = tf_session_get_session_internal(tfp, &tfs); 689 if (rc) { 690 TFP_DRV_LOG(ERR, 691 "%s: Failed to lookup session, rc:%s\n", 692 tf_dir_2_str(dir), 693 strerror(-rc)); 694 return rc; 695 } 696 697 /* Retrieve the device information */ 698 rc = tf_session_get_device(tfs, &dev); 699 if (rc) { 700 TFP_DRV_LOG(ERR, 701 "%s: Failed to lookup device, rc:%s\n", 702 tf_dir_2_str(dir), 703 strerror(-rc)); 704 return rc; 705 } 706 707 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 708 if (rc) { 709 TFP_DRV_LOG(ERR, 710 "%s: Unable to lookup FW id, rc:%s\n", 711 tf_dir_2_str(dir), 712 strerror(-rc)); 713 return rc; 714 } 715 716 /* Prepare DMA buffers */ 717 dma_size = size * sizeof(struct tf_rm_resc_entry); 718 rc = tf_msg_alloc_dma_buf(&resv_buf, dma_size); 719 if (rc) 720 return rc; 721 722 /* Populate the request */ 723 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 724 req.flags = tfp_cpu_to_le_16(dir); 725 req.flush_size = size; 726 727 resv_data = (struct tf_rm_resc_entry *)resv_buf.va_addr; 728 for (i = 0; i < size; i++) { 729 resv_data[i].type = tfp_cpu_to_le_32(resv[i].type); 730 resv_data[i].start = tfp_cpu_to_le_16(resv[i].start); 731 resv_data[i].stride = tfp_cpu_to_le_16(resv[i].stride); 732 } 733 734 req.flush_addr = tfp_cpu_to_le_64(resv_buf.pa_addr); 735 736 parms.tf_type = HWRM_TF_SESSION_RESC_FLUSH; 737 parms.req_data = (uint32_t *)&req; 738 parms.req_size = sizeof(req); 739 parms.resp_data = (uint32_t *)&resp; 740 parms.resp_size = sizeof(resp); 741 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 742 743 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 744 745 tf_msg_free_dma_buf(&resv_buf); 746 747 return rc; 748 } 749 750 int 751 tf_msg_insert_em_internal_entry(struct tf *tfp, 752 struct tf_insert_em_entry_parms *em_parms, 753 uint16_t *rptr_index, 754 uint8_t *rptr_entry, 755 uint8_t *num_of_entries) 756 { 757 int rc; 758 struct tfp_send_msg_parms parms = { 0 }; 759 struct hwrm_tf_em_insert_input req = { 0 }; 760 struct hwrm_tf_em_insert_output resp = { 0 }; 761 struct tf_em_64b_entry *em_result = 762 (struct tf_em_64b_entry *)em_parms->em_record; 763 uint16_t flags; 764 uint8_t fw_session_id; 765 uint8_t msg_key_size; 766 struct tf_dev_info *dev; 767 struct tf_session *tfs; 768 769 RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_em_insert_input) != 770 TF_MSG_SIZE_HWRM_TF_EM_INSERT); 771 772 /* Retrieve the session information */ 773 rc = tf_session_get_session_internal(tfp, &tfs); 774 if (rc) { 775 TFP_DRV_LOG(ERR, 776 "%s: Failed to lookup session, rc:%s\n", 777 tf_dir_2_str(em_parms->dir), 778 strerror(-rc)); 779 return rc; 780 } 781 782 /* Retrieve the device information */ 783 rc = tf_session_get_device(tfs, &dev); 784 if (rc) { 785 TFP_DRV_LOG(ERR, 786 "%s: Failed to lookup device, rc:%s\n", 787 tf_dir_2_str(em_parms->dir), 788 strerror(-rc)); 789 return rc; 790 } 791 792 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 793 if (rc) { 794 TFP_DRV_LOG(ERR, 795 "%s: Unable to lookup FW id, rc:%s\n", 796 tf_dir_2_str(em_parms->dir), 797 strerror(-rc)); 798 return rc; 799 } 800 801 /* Populate the request */ 802 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 803 804 /* Check for key size conformity */ 805 msg_key_size = (em_parms->key_sz_in_bits + 7) / 8; 806 if (msg_key_size > TF_MSG_EM_INSERT_KEY_SIZE) { 807 rc = -EINVAL; 808 TFP_DRV_LOG(ERR, 809 "%s: Invalid parameters for msg type, rc:%s\n", 810 tf_dir_2_str(em_parms->dir), 811 strerror(-rc)); 812 return rc; 813 } 814 815 tfp_memcpy(req.em_key, 816 em_parms->key, 817 msg_key_size); 818 819 flags = (em_parms->dir == TF_DIR_TX ? 820 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX : 821 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX); 822 req.flags = tfp_cpu_to_le_16(flags); 823 req.strength = (em_result->hdr.word1 & 824 CFA_P4_EEM_ENTRY_STRENGTH_MASK) >> 825 CFA_P4_EEM_ENTRY_STRENGTH_SHIFT; 826 req.em_key_bitlen = em_parms->key_sz_in_bits; 827 req.action_ptr = em_result->hdr.pointer; 828 req.em_record_idx = *rptr_index; 829 830 parms.tf_type = HWRM_TF_EM_INSERT; 831 parms.req_data = (uint32_t *)&req; 832 parms.req_size = sizeof(req); 833 parms.resp_data = (uint32_t *)&resp; 834 parms.resp_size = sizeof(resp); 835 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 836 837 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 838 &parms); 839 if (rc) 840 return rc; 841 842 *rptr_entry = resp.rptr_entry; 843 *rptr_index = resp.rptr_index; 844 *num_of_entries = resp.num_of_entries; 845 846 return 0; 847 } 848 849 int 850 tf_msg_hash_insert_em_internal_entry(struct tf *tfp, 851 struct tf_insert_em_entry_parms *em_parms, 852 uint32_t key0_hash, 853 uint32_t key1_hash, 854 uint16_t *rptr_index, 855 uint8_t *rptr_entry, 856 uint8_t *num_of_entries) 857 { 858 int rc; 859 struct tfp_send_msg_parms parms = { 0 }; 860 struct hwrm_tf_em_hash_insert_input req = { 0 }; 861 struct hwrm_tf_em_hash_insert_output resp = { 0 }; 862 uint16_t flags; 863 uint8_t fw_session_id; 864 uint8_t msg_record_size; 865 struct tf_dev_info *dev; 866 struct tf_session *tfs; 867 868 /* Retrieve the session information */ 869 rc = tf_session_get_session_internal(tfp, &tfs); 870 if (rc) { 871 TFP_DRV_LOG(ERR, 872 "%s: Failed to lookup session, rc:%s\n", 873 tf_dir_2_str(em_parms->dir), 874 strerror(-rc)); 875 return rc; 876 } 877 878 /* Retrieve the device information */ 879 rc = tf_session_get_device(tfs, &dev); 880 if (rc) { 881 TFP_DRV_LOG(ERR, 882 "%s: Failed to lookup device, rc:%s\n", 883 tf_dir_2_str(em_parms->dir), 884 strerror(-rc)); 885 return rc; 886 } 887 888 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 889 if (rc) { 890 TFP_DRV_LOG(ERR, 891 "%s: Unable to lookup FW id, rc:%s\n", 892 tf_dir_2_str(em_parms->dir), 893 strerror(-rc)); 894 return rc; 895 } 896 897 /* Populate the request */ 898 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 899 900 /* Check for key size conformity */ 901 msg_record_size = (em_parms->em_record_sz_in_bits + 7) / 8; 902 903 if (msg_record_size > TF_MSG_EM_INSERT_RECORD_SIZE) { 904 rc = -EINVAL; 905 TFP_DRV_LOG(ERR, 906 "%s: Record size to large, rc:%s\n", 907 tf_dir_2_str(em_parms->dir), 908 strerror(-rc)); 909 return rc; 910 } 911 912 tfp_memcpy((char *)req.em_record, 913 em_parms->em_record, 914 msg_record_size); 915 916 flags = (em_parms->dir == TF_DIR_TX ? 917 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_TX : 918 HWRM_TF_EM_INSERT_INPUT_FLAGS_DIR_RX); 919 req.flags = tfp_cpu_to_le_16(flags); 920 req.em_record_size_bits = em_parms->em_record_sz_in_bits; 921 req.em_record_idx = *rptr_index; 922 req.key0_hash = key0_hash; 923 req.key1_hash = key1_hash; 924 925 parms.tf_type = HWRM_TF_EM_HASH_INSERT; 926 parms.req_data = (uint32_t *)&req; 927 parms.req_size = sizeof(req); 928 parms.resp_data = (uint32_t *)&resp; 929 parms.resp_size = sizeof(resp); 930 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 931 932 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 933 &parms); 934 if (rc) 935 return rc; 936 937 *rptr_entry = resp.rptr_entry; 938 *rptr_index = resp.rptr_index; 939 *num_of_entries = resp.num_of_entries; 940 941 return 0; 942 } 943 944 int 945 tf_msg_delete_em_entry(struct tf *tfp, 946 struct tf_delete_em_entry_parms *em_parms) 947 { 948 int rc; 949 struct tfp_send_msg_parms parms = { 0 }; 950 struct hwrm_tf_em_delete_input req = { 0 }; 951 struct hwrm_tf_em_delete_output resp = { 0 }; 952 uint16_t flags; 953 uint8_t fw_session_id; 954 struct tf_dev_info *dev; 955 struct tf_session *tfs; 956 957 /* Retrieve the session information */ 958 rc = tf_session_get_session_internal(tfp, &tfs); 959 if (rc) { 960 TFP_DRV_LOG(ERR, 961 "%s: Failed to lookup session, rc:%s\n", 962 tf_dir_2_str(em_parms->dir), 963 strerror(-rc)); 964 return rc; 965 } 966 967 /* Retrieve the device information */ 968 rc = tf_session_get_device(tfs, &dev); 969 if (rc) { 970 TFP_DRV_LOG(ERR, 971 "%s: Failed to lookup device, rc:%s\n", 972 tf_dir_2_str(em_parms->dir), 973 strerror(-rc)); 974 return rc; 975 } 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(em_parms->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 989 flags = (em_parms->dir == TF_DIR_TX ? 990 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX : 991 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX); 992 req.flags = tfp_cpu_to_le_16(flags); 993 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle); 994 995 parms.tf_type = HWRM_TF_EM_DELETE; 996 parms.req_data = (uint32_t *)&req; 997 parms.req_size = sizeof(req); 998 parms.resp_data = (uint32_t *)&resp; 999 parms.resp_size = sizeof(resp); 1000 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1001 1002 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1003 &parms); 1004 if (rc) 1005 return rc; 1006 1007 em_parms->index = tfp_le_to_cpu_16(resp.em_index); 1008 1009 return 0; 1010 } 1011 1012 int 1013 tf_msg_move_em_entry(struct tf *tfp, 1014 struct tf_move_em_entry_parms *em_parms) 1015 { 1016 int rc; 1017 struct tfp_send_msg_parms parms = { 0 }; 1018 struct hwrm_tf_em_move_input req = { 0 }; 1019 struct hwrm_tf_em_move_output resp = { 0 }; 1020 uint16_t flags; 1021 uint8_t fw_session_id; 1022 struct tf_dev_info *dev; 1023 struct tf_session *tfs; 1024 1025 /* Retrieve the session information */ 1026 rc = tf_session_get_session_internal(tfp, &tfs); 1027 if (rc) { 1028 TFP_DRV_LOG(ERR, 1029 "%s: Failed to lookup session, rc:%s\n", 1030 tf_dir_2_str(em_parms->dir), 1031 strerror(-rc)); 1032 return rc; 1033 } 1034 1035 /* Retrieve the device information */ 1036 rc = tf_session_get_device(tfs, &dev); 1037 if (rc) { 1038 TFP_DRV_LOG(ERR, 1039 "%s: Failed to lookup device, rc:%s\n", 1040 tf_dir_2_str(em_parms->dir), 1041 strerror(-rc)); 1042 return rc; 1043 } 1044 1045 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1046 if (rc) { 1047 TFP_DRV_LOG(ERR, 1048 "%s: Unable to lookup FW id, rc:%s\n", 1049 tf_dir_2_str(em_parms->dir), 1050 strerror(-rc)); 1051 return rc; 1052 } 1053 1054 /* Populate the request */ 1055 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1056 1057 flags = (em_parms->dir == TF_DIR_TX ? 1058 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_TX : 1059 HWRM_TF_EM_DELETE_INPUT_FLAGS_DIR_RX); 1060 req.flags = tfp_cpu_to_le_16(flags); 1061 req.flow_handle = tfp_cpu_to_le_64(em_parms->flow_handle); 1062 req.new_index = tfp_cpu_to_le_32(em_parms->new_index); 1063 1064 parms.tf_type = HWRM_TF_EM_MOVE; 1065 parms.req_data = (uint32_t *)&req; 1066 parms.req_size = sizeof(req); 1067 parms.resp_data = (uint32_t *)&resp; 1068 parms.resp_size = sizeof(resp); 1069 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1070 1071 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1072 &parms); 1073 if (rc) 1074 return rc; 1075 1076 em_parms->index = tfp_le_to_cpu_16(resp.em_index); 1077 1078 return 0; 1079 } 1080 1081 int tf_msg_ext_em_ctxt_mem_alloc(struct tf *tfp, 1082 struct hcapi_cfa_em_table *tbl, 1083 uint64_t *dma_addr, 1084 uint32_t *page_lvl, 1085 uint32_t *page_size) 1086 { 1087 struct tfp_send_msg_parms parms = { 0 }; 1088 struct hwrm_tf_ctxt_mem_alloc_input req = {0}; 1089 struct hwrm_tf_ctxt_mem_alloc_output resp = {0}; 1090 uint32_t mem_size_k; 1091 int rc = 0; 1092 struct tf_dev_info *dev; 1093 struct tf_session *tfs; 1094 uint32_t fw_se_id; 1095 1096 /* Retrieve the session information */ 1097 rc = tf_session_get_session_internal(tfp, &tfs); 1098 if (rc) { 1099 TFP_DRV_LOG(ERR, 1100 "Failed to lookup session, rc:%s\n", 1101 strerror(-rc)); 1102 return rc; 1103 } 1104 1105 /* Retrieve the device information */ 1106 rc = tf_session_get_device(tfs, &dev); 1107 if (rc) { 1108 TFP_DRV_LOG(ERR, 1109 "Failed to lookup device, rc:%s\n", 1110 strerror(-rc)); 1111 return rc; 1112 } 1113 /* Retrieve the session information */ 1114 fw_se_id = tfs->session_id.internal.fw_session_id; 1115 1116 if (tbl->num_entries && tbl->entry_size) { 1117 /* unit: kbytes */ 1118 mem_size_k = (tbl->num_entries / TF_KILOBYTE) * tbl->entry_size; 1119 req.mem_size = tfp_cpu_to_le_32(mem_size_k); 1120 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 1121 parms.tf_type = HWRM_TF_CTXT_MEM_ALLOC; 1122 parms.req_data = (uint32_t *)&req; 1123 parms.req_size = sizeof(req); 1124 parms.resp_data = (uint32_t *)&resp; 1125 parms.resp_size = sizeof(resp); 1126 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1127 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 1128 if (rc) { 1129 TFP_DRV_LOG(ERR, "Failed ext_em_alloc error rc:%s\n", 1130 strerror(-rc)); 1131 return rc; 1132 } 1133 1134 *dma_addr = tfp_le_to_cpu_64(resp.page_dir); 1135 *page_lvl = resp.page_level; 1136 *page_size = resp.page_size; 1137 } 1138 1139 return rc; 1140 } 1141 1142 int tf_msg_ext_em_ctxt_mem_free(struct tf *tfp, 1143 uint32_t mem_size_k, 1144 uint64_t dma_addr, 1145 uint8_t page_level, 1146 uint8_t page_size) 1147 { 1148 struct tfp_send_msg_parms parms = { 0 }; 1149 struct hwrm_tf_ctxt_mem_free_input req = {0}; 1150 struct hwrm_tf_ctxt_mem_free_output resp = {0}; 1151 int rc = 0; 1152 struct tf_dev_info *dev; 1153 struct tf_session *tfs; 1154 uint32_t fw_se_id; 1155 1156 /* Retrieve the session information */ 1157 rc = tf_session_get_session_internal(tfp, &tfs); 1158 if (rc) { 1159 TFP_DRV_LOG(ERR, 1160 "Failed to lookup session, rc:%s\n", 1161 strerror(-rc)); 1162 return rc; 1163 } 1164 1165 /* Retrieve the device information */ 1166 rc = tf_session_get_device(tfs, &dev); 1167 if (rc) { 1168 TFP_DRV_LOG(ERR, 1169 "Failed to lookup device, rc:%s\n", 1170 strerror(-rc)); 1171 return rc; 1172 } 1173 /* Retrieve the session information */ 1174 fw_se_id = tfs->session_id.internal.fw_session_id; 1175 1176 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 1177 req.mem_size = tfp_cpu_to_le_32(mem_size_k); 1178 req.page_dir = tfp_cpu_to_le_64(dma_addr); 1179 req.page_level = page_level; 1180 req.page_size = page_size; 1181 parms.tf_type = HWRM_TF_CTXT_MEM_FREE; 1182 parms.req_data = (uint32_t *)&req; 1183 parms.req_size = sizeof(req); 1184 parms.resp_data = (uint32_t *)&resp; 1185 parms.resp_size = sizeof(resp); 1186 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1187 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 1188 1189 return rc; 1190 } 1191 1192 int 1193 tf_msg_em_mem_rgtr(struct tf *tfp, 1194 int page_lvl, 1195 int page_size, 1196 uint64_t dma_addr, 1197 uint16_t *ctx_id) 1198 { 1199 int rc; 1200 struct hwrm_tf_ctxt_mem_rgtr_input req = { 0 }; 1201 struct hwrm_tf_ctxt_mem_rgtr_output resp = { 0 }; 1202 struct tfp_send_msg_parms parms = { 0 }; 1203 struct tf_dev_info *dev; 1204 struct tf_session *tfs; 1205 uint32_t fw_se_id; 1206 1207 /* Retrieve the session information */ 1208 rc = tf_session_get_session_internal(tfp, &tfs); 1209 if (rc) { 1210 TFP_DRV_LOG(ERR, 1211 "Failed to lookup session, rc:%s\n", 1212 strerror(-rc)); 1213 return rc; 1214 } 1215 1216 /* Retrieve the device information */ 1217 rc = tf_session_get_device(tfs, &dev); 1218 if (rc) { 1219 TFP_DRV_LOG(ERR, 1220 "Failed to lookup device, rc:%s\n", 1221 strerror(-rc)); 1222 return rc; 1223 } 1224 fw_se_id = tfs->session_id.internal.fw_session_id; 1225 1226 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 1227 req.page_level = page_lvl; 1228 req.page_size = page_size; 1229 req.page_dir = tfp_cpu_to_le_64(dma_addr); 1230 1231 parms.tf_type = HWRM_TF_CTXT_MEM_RGTR; 1232 parms.req_data = (uint32_t *)&req; 1233 parms.req_size = sizeof(req); 1234 parms.resp_data = (uint32_t *)&resp; 1235 parms.resp_size = sizeof(resp); 1236 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1237 1238 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1239 &parms); 1240 if (rc) 1241 return rc; 1242 1243 *ctx_id = tfp_le_to_cpu_16(resp.ctx_id); 1244 1245 return rc; 1246 } 1247 1248 int 1249 tf_msg_em_mem_unrgtr(struct tf *tfp, 1250 uint16_t *ctx_id) 1251 { 1252 int rc; 1253 struct hwrm_tf_ctxt_mem_unrgtr_input req = {0}; 1254 struct hwrm_tf_ctxt_mem_unrgtr_output resp = {0}; 1255 struct tfp_send_msg_parms parms = { 0 }; 1256 struct tf_dev_info *dev; 1257 struct tf_session *tfs; 1258 uint32_t fw_se_id; 1259 1260 /* Retrieve the session information */ 1261 rc = tf_session_get_session_internal(tfp, &tfs); 1262 if (rc) { 1263 TFP_DRV_LOG(ERR, 1264 "Failed to lookup session, rc:%s\n", 1265 strerror(-rc)); 1266 return rc; 1267 } 1268 1269 /* Retrieve the device information */ 1270 rc = tf_session_get_device(tfs, &dev); 1271 if (rc) { 1272 TFP_DRV_LOG(ERR, 1273 "Failed to lookup device, rc:%s\n", 1274 strerror(-rc)); 1275 return rc; 1276 } 1277 1278 fw_se_id = tfs->session_id.internal.fw_session_id; 1279 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 1280 1281 req.ctx_id = tfp_cpu_to_le_32(*ctx_id); 1282 1283 parms.tf_type = HWRM_TF_CTXT_MEM_UNRGTR; 1284 parms.req_data = (uint32_t *)&req; 1285 parms.req_size = sizeof(req); 1286 parms.resp_data = (uint32_t *)&resp; 1287 parms.resp_size = sizeof(resp); 1288 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1289 1290 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1291 &parms); 1292 return rc; 1293 } 1294 1295 int 1296 tf_msg_em_qcaps(struct tf *tfp, 1297 int dir, 1298 struct tf_em_caps *em_caps) 1299 { 1300 int rc; 1301 struct hwrm_tf_ext_em_qcaps_input req = {0}; 1302 struct hwrm_tf_ext_em_qcaps_output resp = { 0 }; 1303 uint32_t flags; 1304 struct tfp_send_msg_parms parms = { 0 }; 1305 struct tf_dev_info *dev; 1306 struct tf_session *tfs; 1307 uint32_t fw_se_id; 1308 1309 /* Retrieve the session information */ 1310 rc = tf_session_get_session_internal(tfp, &tfs); 1311 if (rc) { 1312 TFP_DRV_LOG(ERR, 1313 "%s: Failed to lookup session, rc:%s\n", 1314 tf_dir_2_str(dir), 1315 strerror(-rc)); 1316 return rc; 1317 } 1318 fw_se_id = tfs->session_id.internal.fw_session_id; 1319 1320 /* Retrieve the device information */ 1321 rc = tf_session_get_device(tfs, &dev); 1322 if (rc) { 1323 TFP_DRV_LOG(ERR, 1324 "%s: Failed to lookup device, rc:%s\n", 1325 tf_dir_2_str(dir), 1326 strerror(-rc)); 1327 return rc; 1328 } 1329 1330 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_TX : 1331 HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_DIR_RX); 1332 req.flags = tfp_cpu_to_le_32(flags); 1333 1334 parms.tf_type = HWRM_TF_EXT_EM_QCAPS; 1335 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 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 = dev->ops->tf_dev_get_mailbox(); 1341 1342 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1343 &parms); 1344 if (rc) 1345 return rc; 1346 1347 em_caps->supported = tfp_le_to_cpu_32(resp.supported); 1348 em_caps->max_entries_supported = 1349 tfp_le_to_cpu_32(resp.max_entries_supported); 1350 em_caps->key_entry_size = tfp_le_to_cpu_16(resp.key_entry_size); 1351 em_caps->record_entry_size = 1352 tfp_le_to_cpu_16(resp.record_entry_size); 1353 em_caps->efc_entry_size = tfp_le_to_cpu_16(resp.efc_entry_size); 1354 1355 return rc; 1356 } 1357 1358 int 1359 tf_msg_em_cfg(struct tf *tfp, 1360 uint32_t num_entries, 1361 uint16_t key0_ctx_id, 1362 uint16_t key1_ctx_id, 1363 uint16_t record_ctx_id, 1364 uint16_t efc_ctx_id, 1365 uint8_t flush_interval, 1366 int dir) 1367 { 1368 int rc; 1369 struct hwrm_tf_ext_em_cfg_input req = {0}; 1370 struct hwrm_tf_ext_em_cfg_output resp = {0}; 1371 uint32_t flags; 1372 struct tfp_send_msg_parms parms = { 0 }; 1373 struct tf_dev_info *dev; 1374 struct tf_session *tfs; 1375 1376 /* Retrieve the session information */ 1377 rc = tf_session_get_session_internal(tfp, &tfs); 1378 if (rc) { 1379 TFP_DRV_LOG(ERR, 1380 "%s: Failed to lookup session, rc:%s\n", 1381 tf_dir_2_str(dir), 1382 strerror(-rc)); 1383 return rc; 1384 } 1385 1386 /* Retrieve the device information */ 1387 rc = tf_session_get_device(tfs, &dev); 1388 if (rc) { 1389 TFP_DRV_LOG(ERR, 1390 "%s: Failed to lookup device, rc:%s\n", 1391 tf_dir_2_str(dir), 1392 strerror(-rc)); 1393 return rc; 1394 } 1395 1396 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX : 1397 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX); 1398 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD; 1399 1400 req.flags = tfp_cpu_to_le_32(flags); 1401 req.num_entries = tfp_cpu_to_le_32(num_entries); 1402 1403 req.flush_interval = flush_interval; 1404 1405 req.key0_ctx_id = tfp_cpu_to_le_16(key0_ctx_id); 1406 req.key1_ctx_id = tfp_cpu_to_le_16(key1_ctx_id); 1407 req.record_ctx_id = tfp_cpu_to_le_16(record_ctx_id); 1408 req.efc_ctx_id = tfp_cpu_to_le_16(efc_ctx_id); 1409 1410 parms.tf_type = HWRM_TF_EXT_EM_CFG; 1411 parms.req_data = (uint32_t *)&req; 1412 parms.req_size = sizeof(req); 1413 parms.resp_data = (uint32_t *)&resp; 1414 parms.resp_size = sizeof(resp); 1415 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1416 1417 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1418 &parms); 1419 return rc; 1420 } 1421 1422 int 1423 tf_msg_ext_em_cfg(struct tf *tfp, 1424 struct tf_tbl_scope_cb *tbl_scope_cb, 1425 uint32_t st_buckets, 1426 uint8_t flush_interval, 1427 enum tf_dir dir) 1428 { 1429 struct hcapi_cfa_em_ctx_mem_info *ctxp = &tbl_scope_cb->em_ctx_info[dir]; 1430 struct hcapi_cfa_em_table *lkup_tbl, *act_tbl; 1431 struct hwrm_tf_ext_em_cfg_input req = {0}; 1432 struct hwrm_tf_ext_em_cfg_output resp = {0}; 1433 struct tfp_send_msg_parms parms = { 0 }; 1434 uint32_t flags; 1435 struct tf_dev_info *dev; 1436 struct tf_session *tfs; 1437 uint32_t fw_se_id; 1438 int rc; 1439 1440 /* Retrieve the session information */ 1441 rc = tf_session_get_session_internal(tfp, &tfs); 1442 if (rc) { 1443 TFP_DRV_LOG(ERR, 1444 "%s: Failed to lookup session, rc:%s\n", 1445 tf_dir_2_str(dir), 1446 strerror(-rc)); 1447 return rc; 1448 } 1449 1450 /* Retrieve the device information */ 1451 rc = tf_session_get_device(tfs, &dev); 1452 if (rc) { 1453 TFP_DRV_LOG(ERR, 1454 "%s: Failed to lookup device, rc:%s\n", 1455 tf_dir_2_str(dir), 1456 strerror(-rc)); 1457 return rc; 1458 } 1459 fw_se_id = tfs->session_id.internal.fw_session_id; 1460 1461 lkup_tbl = &ctxp->em_tables[TF_EM_LKUP_TABLE]; 1462 act_tbl = &ctxp->em_tables[TF_ACTION_TABLE]; 1463 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX : 1464 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX); 1465 flags |= HWRM_TF_EXT_EM_QCAPS_INPUT_FLAGS_PREFERRED_OFFLOAD; 1466 1467 req.flags = tfp_cpu_to_le_32(flags); 1468 req.num_entries = tfp_cpu_to_le_32(act_tbl->num_entries); 1469 req.lkup_static_buckets = tfp_cpu_to_le_32(st_buckets); 1470 req.fw_session_id = tfp_cpu_to_le_32(fw_se_id); 1471 req.flush_interval = flush_interval; 1472 req.action_ctx_id = tfp_cpu_to_le_16(act_tbl->ctx_id); 1473 req.action_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id); 1474 req.lkup_ctx_id = tfp_cpu_to_le_16(lkup_tbl->ctx_id); 1475 req.lkup_tbl_scope = tfp_cpu_to_le_16(tbl_scope_cb->tbl_scope_id); 1476 1477 req.enables = (HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_CTX_ID | 1478 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_ACTION_TBL_SCOPE | 1479 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_CTX_ID | 1480 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_TBL_SCOPE | 1481 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_LKUP_STATIC_BUCKETS | 1482 HWRM_TF_EXT_EM_CFG_INPUT_ENABLES_NUM_ENTRIES); 1483 1484 parms.tf_type = HWRM_TF_EXT_EM_CFG; 1485 parms.req_data = (uint32_t *)&req; 1486 parms.req_size = sizeof(req); 1487 parms.resp_data = (uint32_t *)&resp; 1488 parms.resp_size = sizeof(resp); 1489 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1490 1491 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1492 &parms); 1493 return rc; 1494 } 1495 1496 int 1497 tf_msg_em_op(struct tf *tfp, 1498 int dir, 1499 uint16_t op) 1500 { 1501 int rc; 1502 struct hwrm_tf_ext_em_op_input req = {0}; 1503 struct hwrm_tf_ext_em_op_output resp = {0}; 1504 uint32_t flags; 1505 struct tfp_send_msg_parms parms = { 0 }; 1506 struct tf_dev_info *dev; 1507 struct tf_session *tfs; 1508 1509 /* Retrieve the session information */ 1510 rc = tf_session_get_session_internal(tfp, &tfs); 1511 if (rc) { 1512 TFP_DRV_LOG(ERR, 1513 "%s: Failed to lookup session, rc:%s\n", 1514 tf_dir_2_str(dir), 1515 strerror(-rc)); 1516 return rc; 1517 } 1518 1519 /* Retrieve the device information */ 1520 rc = tf_session_get_device(tfs, &dev); 1521 if (rc) { 1522 TFP_DRV_LOG(ERR, 1523 "%s: Failed to lookup device, rc:%s\n", 1524 tf_dir_2_str(dir), 1525 strerror(-rc)); 1526 return rc; 1527 } 1528 1529 flags = (dir == TF_DIR_TX ? HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_TX : 1530 HWRM_TF_EXT_EM_CFG_INPUT_FLAGS_DIR_RX); 1531 req.flags = tfp_cpu_to_le_32(flags); 1532 req.op = tfp_cpu_to_le_16(op); 1533 1534 parms.tf_type = HWRM_TF_EXT_EM_OP; 1535 parms.req_data = (uint32_t *)&req; 1536 parms.req_size = sizeof(req); 1537 parms.resp_data = (uint32_t *)&resp; 1538 parms.resp_size = sizeof(resp); 1539 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1540 1541 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1542 &parms); 1543 return rc; 1544 } 1545 1546 int 1547 tf_msg_tcam_entry_set(struct tf *tfp, 1548 struct tf_dev_info *dev, 1549 struct tf_tcam_set_parms *parms) 1550 { 1551 int rc; 1552 struct tfp_send_msg_parms mparms = { 0 }; 1553 struct hwrm_tf_tcam_set_input req = { 0 }; 1554 struct hwrm_tf_tcam_set_output resp = { 0 }; 1555 struct tf_msg_dma_buf buf = { 0 }; 1556 uint8_t *data = NULL; 1557 int data_size = 0; 1558 uint8_t fw_session_id; 1559 struct tf_session *tfs; 1560 1561 /* Retrieve the session information */ 1562 rc = tf_session_get_session_internal(tfp, &tfs); 1563 if (rc) { 1564 TFP_DRV_LOG(ERR, 1565 "Failed to lookup session, rc:%s\n", 1566 strerror(-rc)); 1567 return rc; 1568 } 1569 1570 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1571 if (rc) { 1572 TFP_DRV_LOG(ERR, 1573 "%s: Unable to lookup FW id, rc:%s\n", 1574 tf_dir_2_str(parms->dir), 1575 strerror(-rc)); 1576 return rc; 1577 } 1578 1579 /* Populate the request */ 1580 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1581 req.type = parms->hcapi_type; 1582 req.idx = tfp_cpu_to_le_16(parms->idx); 1583 if (parms->dir == TF_DIR_TX) 1584 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DIR_TX; 1585 1586 req.key_size = parms->key_size; 1587 req.mask_offset = parms->key_size; 1588 /* Result follows after key and mask, thus multiply by 2 */ 1589 req.result_offset = 2 * parms->key_size; 1590 req.result_size = parms->result_size; 1591 data_size = 2 * req.key_size + req.result_size; 1592 1593 if (data_size <= TF_PCI_BUF_SIZE_MAX) { 1594 /* use pci buffer */ 1595 data = &req.dev_data[0]; 1596 } else { 1597 /* use dma buffer */ 1598 req.flags |= HWRM_TF_TCAM_SET_INPUT_FLAGS_DMA; 1599 rc = tf_msg_alloc_dma_buf(&buf, data_size); 1600 if (rc) 1601 goto cleanup; 1602 data = buf.va_addr; 1603 tfp_memcpy(&req.dev_data[0], 1604 &buf.pa_addr, 1605 sizeof(buf.pa_addr)); 1606 } 1607 1608 tfp_memcpy(&data[0], parms->key, parms->key_size); 1609 tfp_memcpy(&data[parms->key_size], parms->mask, parms->key_size); 1610 tfp_memcpy(&data[req.result_offset], parms->result, parms->result_size); 1611 1612 mparms.tf_type = HWRM_TF_TCAM_SET; 1613 mparms.req_data = (uint32_t *)&req; 1614 mparms.req_size = sizeof(req); 1615 mparms.resp_data = (uint32_t *)&resp; 1616 mparms.resp_size = sizeof(resp); 1617 mparms.mailbox = dev->ops->tf_dev_get_mailbox(); 1618 1619 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1620 &mparms); 1621 1622 cleanup: 1623 tf_msg_free_dma_buf(&buf); 1624 1625 return rc; 1626 } 1627 1628 int 1629 tf_msg_tcam_entry_get(struct tf *tfp, 1630 struct tf_dev_info *dev, 1631 struct tf_tcam_get_parms *parms) 1632 { 1633 int rc; 1634 struct tfp_send_msg_parms mparms = { 0 }; 1635 struct hwrm_tf_tcam_get_input req = { 0 }; 1636 struct hwrm_tf_tcam_get_output resp = { 0 }; 1637 uint8_t fw_session_id; 1638 struct tf_session *tfs; 1639 1640 /* Retrieve the session information */ 1641 rc = tf_session_get_session_internal(tfp, &tfs); 1642 if (rc) { 1643 TFP_DRV_LOG(ERR, 1644 "Failed to lookup session, rc:%s\n", 1645 strerror(-rc)); 1646 return rc; 1647 } 1648 1649 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1650 if (rc) { 1651 TFP_DRV_LOG(ERR, 1652 "%s: Unable to lookup FW id, rc:%s\n", 1653 tf_dir_2_str(parms->dir), 1654 strerror(-rc)); 1655 return rc; 1656 } 1657 1658 /* Populate the request */ 1659 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1660 req.type = parms->hcapi_type; 1661 req.idx = tfp_cpu_to_le_16(parms->idx); 1662 if (parms->dir == TF_DIR_TX) 1663 req.flags |= HWRM_TF_TCAM_GET_INPUT_FLAGS_DIR_TX; 1664 1665 mparms.tf_type = HWRM_TF_TCAM_GET; 1666 mparms.req_data = (uint32_t *)&req; 1667 mparms.req_size = sizeof(req); 1668 mparms.resp_data = (uint32_t *)&resp; 1669 mparms.resp_size = sizeof(resp); 1670 mparms.mailbox = dev->ops->tf_dev_get_mailbox(); 1671 1672 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1673 &mparms); 1674 1675 if (rc != 0) 1676 return rc; 1677 1678 if (parms->key_size < resp.key_size || 1679 parms->result_size < resp.result_size) { 1680 rc = -EINVAL; 1681 TFP_DRV_LOG(ERR, 1682 "%s: Key buffer(%d) is smaller than the key(%d), rc:%s\n", 1683 tf_dir_2_str(parms->dir), 1684 parms->key_size, 1685 resp.key_size, 1686 strerror(-rc)); 1687 return rc; 1688 } 1689 parms->key_size = resp.key_size; 1690 parms->result_size = resp.result_size; 1691 tfp_memcpy(parms->key, resp.dev_data, resp.key_size); 1692 tfp_memcpy(parms->mask, &resp.dev_data[resp.key_size], resp.key_size); 1693 tfp_memcpy(parms->result, &resp.dev_data[resp.result_offset], resp.result_size); 1694 1695 return 0; 1696 } 1697 1698 int 1699 tf_msg_tcam_entry_free(struct tf *tfp, 1700 struct tf_dev_info *dev, 1701 struct tf_tcam_free_parms *in_parms) 1702 { 1703 int rc; 1704 struct hwrm_tf_tcam_free_input req = { 0 }; 1705 struct hwrm_tf_tcam_free_output resp = { 0 }; 1706 struct tfp_send_msg_parms parms = { 0 }; 1707 uint8_t fw_session_id; 1708 struct tf_session *tfs; 1709 1710 /* Retrieve the session information */ 1711 rc = tf_session_get_session_internal(tfp, &tfs); 1712 if (rc) { 1713 TFP_DRV_LOG(ERR, 1714 "Failed to lookup session, rc:%s\n", 1715 strerror(-rc)); 1716 return rc; 1717 } 1718 1719 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1720 if (rc) { 1721 TFP_DRV_LOG(ERR, 1722 "%s: Unable to lookup FW id, rc:%s\n", 1723 tf_dir_2_str(in_parms->dir), 1724 strerror(-rc)); 1725 return rc; 1726 } 1727 1728 /* Populate the request */ 1729 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1730 req.type = in_parms->hcapi_type; 1731 req.count = 1; 1732 req.idx_list[0] = tfp_cpu_to_le_16(in_parms->idx); 1733 if (in_parms->dir == TF_DIR_TX) 1734 req.flags |= HWRM_TF_TCAM_FREE_INPUT_FLAGS_DIR_TX; 1735 1736 parms.tf_type = HWRM_TF_TCAM_FREE; 1737 parms.req_data = (uint32_t *)&req; 1738 parms.req_size = sizeof(req); 1739 parms.resp_data = (uint32_t *)&resp; 1740 parms.resp_size = sizeof(resp); 1741 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1742 1743 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1744 &parms); 1745 return rc; 1746 } 1747 1748 int 1749 tf_msg_set_tbl_entry(struct tf *tfp, 1750 enum tf_dir dir, 1751 uint16_t hcapi_type, 1752 uint16_t size, 1753 uint8_t *data, 1754 uint32_t index) 1755 { 1756 int rc; 1757 struct hwrm_tf_tbl_type_set_input req = { 0 }; 1758 struct hwrm_tf_tbl_type_set_output resp = { 0 }; 1759 struct tfp_send_msg_parms parms = { 0 }; 1760 uint8_t fw_session_id; 1761 struct tf_dev_info *dev; 1762 struct tf_session *tfs; 1763 1764 RTE_BUILD_BUG_ON(sizeof(struct hwrm_tf_tbl_type_set_input) != 1765 TF_MSG_SIZE_HWRM_TF_TBL_TYPE_SET); 1766 1767 /* Retrieve the session information */ 1768 rc = tf_session_get_session_internal(tfp, &tfs); 1769 if (rc) { 1770 TFP_DRV_LOG(ERR, 1771 "%s: Failed to lookup session, rc:%s\n", 1772 tf_dir_2_str(dir), 1773 strerror(-rc)); 1774 return rc; 1775 } 1776 1777 /* Retrieve the device information */ 1778 rc = tf_session_get_device(tfs, &dev); 1779 if (rc) { 1780 TFP_DRV_LOG(ERR, 1781 "%s: Failed to lookup device, rc:%s\n", 1782 tf_dir_2_str(dir), 1783 strerror(-rc)); 1784 return rc; 1785 } 1786 1787 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1788 if (rc) { 1789 TFP_DRV_LOG(ERR, 1790 "%s: Unable to lookup FW id, rc:%s\n", 1791 tf_dir_2_str(dir), 1792 strerror(-rc)); 1793 return rc; 1794 } 1795 1796 /* Populate the request */ 1797 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1798 req.flags = tfp_cpu_to_le_16(dir); 1799 req.type = tfp_cpu_to_le_32(hcapi_type); 1800 req.size = tfp_cpu_to_le_16(size); 1801 req.index = tfp_cpu_to_le_32(index); 1802 1803 /* Check for data size conformity */ 1804 if (size > TF_MSG_TBL_TYPE_SET_DATA_SIZE) { 1805 rc = -EINVAL; 1806 TFP_DRV_LOG(ERR, 1807 "%s: Invalid parameters for msg type, rc:%s\n", 1808 tf_dir_2_str(dir), 1809 strerror(-rc)); 1810 return rc; 1811 } 1812 1813 tfp_memcpy(&req.data, 1814 data, 1815 size); 1816 1817 parms.tf_type = HWRM_TF_TBL_TYPE_SET; 1818 parms.req_data = (uint32_t *)&req; 1819 parms.req_size = sizeof(req); 1820 parms.resp_data = (uint32_t *)&resp; 1821 parms.resp_size = sizeof(resp); 1822 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1823 1824 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1825 &parms); 1826 if (rc) 1827 return rc; 1828 1829 return 0; 1830 } 1831 1832 int 1833 tf_msg_get_tbl_entry(struct tf *tfp, 1834 enum tf_dir dir, 1835 uint16_t hcapi_type, 1836 uint16_t size, 1837 uint8_t *data, 1838 uint32_t index, 1839 bool clear_on_read) 1840 { 1841 int rc; 1842 struct hwrm_tf_tbl_type_get_input req = { 0 }; 1843 struct hwrm_tf_tbl_type_get_output resp = { 0 }; 1844 struct tfp_send_msg_parms parms = { 0 }; 1845 uint8_t fw_session_id; 1846 struct tf_dev_info *dev; 1847 struct tf_session *tfs; 1848 uint32_t flags = 0; 1849 1850 /* Retrieve the session information */ 1851 rc = tf_session_get_session_internal(tfp, &tfs); 1852 if (rc) { 1853 TFP_DRV_LOG(ERR, 1854 "%s: Failed to lookup session, rc:%s\n", 1855 tf_dir_2_str(dir), 1856 strerror(-rc)); 1857 return rc; 1858 } 1859 1860 /* Retrieve the device information */ 1861 rc = tf_session_get_device(tfs, &dev); 1862 if (rc) { 1863 TFP_DRV_LOG(ERR, 1864 "%s: Failed to lookup device, rc:%s\n", 1865 tf_dir_2_str(dir), 1866 strerror(-rc)); 1867 return rc; 1868 } 1869 1870 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1871 if (rc) { 1872 TFP_DRV_LOG(ERR, 1873 "%s: Unable to lookup FW id, rc:%s\n", 1874 tf_dir_2_str(dir), 1875 strerror(-rc)); 1876 return rc; 1877 } 1878 flags = (dir == TF_DIR_TX ? 1879 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_TX : 1880 HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_DIR_RX); 1881 1882 if (clear_on_read) 1883 flags |= HWRM_TF_TBL_TYPE_GET_INPUT_FLAGS_CLEAR_ON_READ; 1884 1885 /* Populate the request */ 1886 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1887 req.flags = tfp_cpu_to_le_16(flags); 1888 req.type = tfp_cpu_to_le_32(hcapi_type); 1889 req.index = tfp_cpu_to_le_32(index); 1890 1891 parms.tf_type = HWRM_TF_TBL_TYPE_GET; 1892 parms.req_data = (uint32_t *)&req; 1893 parms.req_size = sizeof(req); 1894 parms.resp_data = (uint32_t *)&resp; 1895 parms.resp_size = sizeof(resp); 1896 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1897 1898 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), 1899 &parms); 1900 if (rc) 1901 return rc; 1902 1903 /* 1904 * The response will be 64 bytes long, the response size will 1905 * be in words (16). All we can test for is that the response 1906 * size is < to the requested size. 1907 */ 1908 if ((tfp_le_to_cpu_32(resp.size) * 4) < size) 1909 return -EINVAL; 1910 1911 /* 1912 * Copy the requested number of bytes 1913 */ 1914 tfp_memcpy(data, 1915 &resp.data, 1916 size); 1917 1918 return 0; 1919 } 1920 1921 /* HWRM Tunneled messages */ 1922 1923 int 1924 tf_msg_get_global_cfg(struct tf *tfp, 1925 struct tf_global_cfg_parms *params) 1926 { 1927 int rc = 0; 1928 struct tfp_send_msg_parms parms = { 0 }; 1929 struct hwrm_tf_global_cfg_get_input req = { 0 }; 1930 struct hwrm_tf_global_cfg_get_output resp = { 0 }; 1931 uint32_t flags = 0; 1932 uint8_t fw_session_id; 1933 uint16_t resp_size = 0; 1934 struct tf_dev_info *dev; 1935 struct tf_session *tfs; 1936 1937 /* Retrieve the session information */ 1938 rc = tf_session_get_session_internal(tfp, &tfs); 1939 if (rc) { 1940 TFP_DRV_LOG(ERR, 1941 "%s: Failed to lookup session, rc:%s\n", 1942 tf_dir_2_str(params->dir), 1943 strerror(-rc)); 1944 return rc; 1945 } 1946 1947 /* Retrieve the device information */ 1948 rc = tf_session_get_device(tfs, &dev); 1949 if (rc) { 1950 TFP_DRV_LOG(ERR, 1951 "%s: Failed to lookup device, rc:%s\n", 1952 tf_dir_2_str(params->dir), 1953 strerror(-rc)); 1954 return rc; 1955 } 1956 1957 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 1958 if (rc) { 1959 TFP_DRV_LOG(ERR, 1960 "%s: Unable to lookup FW id, rc:%s\n", 1961 tf_dir_2_str(params->dir), 1962 strerror(-rc)); 1963 return rc; 1964 } 1965 1966 flags = (params->dir == TF_DIR_TX ? 1967 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_TX : 1968 HWRM_TF_GLOBAL_CFG_GET_INPUT_FLAGS_DIR_RX); 1969 1970 /* Populate the request */ 1971 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 1972 req.flags = tfp_cpu_to_le_32(flags); 1973 req.type = tfp_cpu_to_le_32(params->type); 1974 req.offset = tfp_cpu_to_le_32(params->offset); 1975 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes); 1976 1977 parms.tf_type = HWRM_TF_GLOBAL_CFG_GET; 1978 parms.req_data = (uint32_t *)&req; 1979 parms.req_size = sizeof(req); 1980 parms.resp_data = (uint32_t *)&resp; 1981 parms.resp_size = sizeof(resp); 1982 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 1983 1984 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 1985 if (rc != 0) 1986 return rc; 1987 1988 /* Verify that we got enough buffer to return the requested data */ 1989 resp_size = tfp_le_to_cpu_16(resp.size); 1990 if (resp_size < params->config_sz_in_bytes) 1991 return -EINVAL; 1992 1993 if (params->config) 1994 tfp_memcpy(params->config, 1995 resp.data, 1996 resp_size); 1997 else 1998 return -EFAULT; 1999 2000 return 0; 2001 } 2002 2003 int 2004 tf_msg_set_global_cfg(struct tf *tfp, 2005 struct tf_global_cfg_parms *params) 2006 { 2007 int rc = 0; 2008 struct tfp_send_msg_parms parms = { 0 }; 2009 struct hwrm_tf_global_cfg_set_input req = { 0 }; 2010 struct hwrm_tf_global_cfg_set_output resp = { 0 }; 2011 uint32_t flags = 0; 2012 uint8_t fw_session_id; 2013 struct tf_dev_info *dev; 2014 struct tf_session *tfs; 2015 2016 /* Retrieve the session information */ 2017 rc = tf_session_get_session_internal(tfp, &tfs); 2018 if (rc) { 2019 TFP_DRV_LOG(ERR, 2020 "%s: Failed to lookup session, rc:%s\n", 2021 tf_dir_2_str(params->dir), 2022 strerror(-rc)); 2023 return rc; 2024 } 2025 2026 /* Retrieve the device information */ 2027 rc = tf_session_get_device(tfs, &dev); 2028 if (rc) { 2029 TFP_DRV_LOG(ERR, 2030 "%s: Failed to lookup device, rc:%s\n", 2031 tf_dir_2_str(params->dir), 2032 strerror(-rc)); 2033 return rc; 2034 } 2035 2036 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 2037 if (rc) { 2038 TFP_DRV_LOG(ERR, 2039 "%s: Unable to lookup FW id, rc:%s\n", 2040 tf_dir_2_str(params->dir), 2041 strerror(-rc)); 2042 return rc; 2043 } 2044 2045 flags = (params->dir == TF_DIR_TX ? 2046 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_TX : 2047 HWRM_TF_GLOBAL_CFG_SET_INPUT_FLAGS_DIR_RX); 2048 2049 /* Populate the request */ 2050 req.fw_session_id = tfp_cpu_to_le_32(fw_session_id); 2051 req.flags = tfp_cpu_to_le_32(flags); 2052 req.type = tfp_cpu_to_le_32(params->type); 2053 req.offset = tfp_cpu_to_le_32(params->offset); 2054 2055 /* Check for data size conformity */ 2056 if (params->config_sz_in_bytes > TF_MSG_SET_GLOBAL_CFG_DATA_SIZE) { 2057 rc = -EINVAL; 2058 TFP_DRV_LOG(ERR, 2059 "%s: Invalid parameters for msg type, rc:%s\n", 2060 tf_dir_2_str(params->dir), 2061 strerror(-rc)); 2062 return rc; 2063 } 2064 2065 tfp_memcpy(req.data, params->config, 2066 params->config_sz_in_bytes); 2067 2068 /* Only set mask if pointer is provided 2069 */ 2070 if (params->config_mask) { 2071 tfp_memcpy(req.mask, 2072 params->config_mask, 2073 params->config_sz_in_bytes); 2074 } 2075 2076 req.size = tfp_cpu_to_le_32(params->config_sz_in_bytes); 2077 2078 parms.tf_type = HWRM_TF_GLOBAL_CFG_SET; 2079 parms.req_data = (uint32_t *)&req; 2080 parms.req_size = sizeof(req); 2081 parms.resp_data = (uint32_t *)&resp; 2082 parms.resp_size = sizeof(resp); 2083 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2084 2085 rc = tfp_send_msg_direct(tf_session_get_bp(tfp), &parms); 2086 2087 if (rc != 0) 2088 return rc; 2089 2090 return 0; 2091 } 2092 2093 int 2094 tf_msg_bulk_get_tbl_entry(struct tf *tfp, 2095 enum tf_dir dir, 2096 uint16_t hcapi_type, 2097 uint32_t starting_idx, 2098 uint16_t num_entries, 2099 uint16_t entry_sz_in_bytes, 2100 uint64_t physical_mem_addr, 2101 bool clear_on_read) 2102 { 2103 int rc; 2104 struct tfp_send_msg_parms parms = { 0 }; 2105 struct hwrm_tf_tbl_type_bulk_get_input req = { 0 }; 2106 struct hwrm_tf_tbl_type_bulk_get_output resp = { 0 }; 2107 int data_size = 0; 2108 uint8_t fw_session_id; 2109 struct tf_dev_info *dev; 2110 struct tf_session *tfs; 2111 uint32_t flags = 0; 2112 2113 /* Retrieve the session information */ 2114 rc = tf_session_get_session(tfp, &tfs); 2115 if (rc) { 2116 TFP_DRV_LOG(ERR, 2117 "%s: Failed to lookup session, rc:%s\n", 2118 tf_dir_2_str(dir), 2119 strerror(-rc)); 2120 return rc; 2121 } 2122 2123 /* Retrieve the device information */ 2124 rc = tf_session_get_device(tfs, &dev); 2125 if (rc) { 2126 TFP_DRV_LOG(ERR, 2127 "%s: Failed to lookup device, rc:%s\n", 2128 tf_dir_2_str(dir), 2129 strerror(-rc)); 2130 return rc; 2131 } 2132 2133 rc = tf_session_get_fw_session_id(tfp, &fw_session_id); 2134 if (rc) { 2135 TFP_DRV_LOG(ERR, 2136 "%s: Unable to lookup FW id, rc:%s\n", 2137 tf_dir_2_str(dir), 2138 strerror(-rc)); 2139 return rc; 2140 } 2141 flags = (dir == TF_DIR_TX ? 2142 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_TX : 2143 HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_DIR_RX); 2144 2145 if (clear_on_read) 2146 flags |= HWRM_TF_TBL_TYPE_BULK_GET_INPUT_FLAGS_CLEAR_ON_READ; 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(flags); 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 2294 int 2295 tf_msg_get_version(struct bnxt *bp, 2296 struct tf_dev_info *dev, 2297 struct tf_get_version_parms *params) 2298 2299 { 2300 int rc; 2301 struct hwrm_tf_version_get_input req = { 0 }; 2302 struct hwrm_tf_version_get_output resp = { 0 }; 2303 struct tfp_send_msg_parms parms = { 0 }; 2304 2305 /* Populate the request */ 2306 parms.tf_type = HWRM_TF_VERSION_GET, 2307 parms.req_data = (uint32_t *)&req; 2308 parms.req_size = sizeof(req); 2309 parms.resp_data = (uint32_t *)&resp; 2310 parms.resp_size = sizeof(resp); 2311 parms.mailbox = dev->ops->tf_dev_get_mailbox(); 2312 2313 rc = tfp_send_msg_direct(bp, 2314 &parms); 2315 2316 params->major = resp.major; 2317 params->minor = resp.minor; 2318 params->update = resp.update; 2319 2320 dev->ops->tf_dev_map_hcapi_caps(resp.dev_caps_cfg, 2321 ¶ms->dev_ident_caps, 2322 ¶ms->dev_tcam_caps, 2323 ¶ms->dev_tbl_caps, 2324 ¶ms->dev_em_caps); 2325 2326 return rc; 2327 } 2328