1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */ 3 4 #include <linux/unaligned.h> 5 #include <linux/pci.h> 6 #include <linux/pldmfw.h> 7 #include <linux/types.h> 8 #include <net/devlink.h> 9 10 #include "fbnic.h" 11 #include "fbnic_fw.h" 12 #include "fbnic_tlv.h" 13 14 #define FBNIC_SN_STR_LEN 24 15 16 static int fbnic_version_running_put(struct devlink_info_req *req, 17 struct fbnic_fw_ver *fw_ver, 18 char *ver_name) 19 { 20 char running_ver[FBNIC_FW_VER_MAX_SIZE]; 21 int err; 22 23 fbnic_mk_fw_ver_str(fw_ver->version, running_ver); 24 err = devlink_info_version_running_put(req, ver_name, running_ver); 25 if (err) 26 return err; 27 28 if (strlen(fw_ver->commit) > 0) { 29 char commit_name[FBNIC_SN_STR_LEN]; 30 31 snprintf(commit_name, FBNIC_SN_STR_LEN, "%s.commit", ver_name); 32 err = devlink_info_version_running_put(req, commit_name, 33 fw_ver->commit); 34 if (err) 35 return err; 36 } 37 38 return 0; 39 } 40 41 static int fbnic_version_stored_put(struct devlink_info_req *req, 42 struct fbnic_fw_ver *fw_ver, 43 char *ver_name) 44 { 45 char stored_ver[FBNIC_FW_VER_MAX_SIZE]; 46 int err; 47 48 fbnic_mk_fw_ver_str(fw_ver->version, stored_ver); 49 err = devlink_info_version_stored_put(req, ver_name, stored_ver); 50 if (err) 51 return err; 52 53 if (strlen(fw_ver->commit) > 0) { 54 char commit_name[FBNIC_SN_STR_LEN]; 55 56 snprintf(commit_name, FBNIC_SN_STR_LEN, "%s.commit", ver_name); 57 err = devlink_info_version_stored_put(req, commit_name, 58 fw_ver->commit); 59 if (err) 60 return err; 61 } 62 63 return 0; 64 } 65 66 static int fbnic_devlink_info_get(struct devlink *devlink, 67 struct devlink_info_req *req, 68 struct netlink_ext_ack *extack) 69 { 70 struct fbnic_dev *fbd = devlink_priv(devlink); 71 int err; 72 73 err = fbnic_version_running_put(req, &fbd->fw_cap.running.mgmt, 74 DEVLINK_INFO_VERSION_GENERIC_FW); 75 if (err) 76 return err; 77 78 err = fbnic_version_running_put(req, &fbd->fw_cap.running.bootloader, 79 DEVLINK_INFO_VERSION_GENERIC_FW_BOOTLOADER); 80 if (err) 81 return err; 82 83 err = fbnic_version_stored_put(req, &fbd->fw_cap.stored.mgmt, 84 DEVLINK_INFO_VERSION_GENERIC_FW); 85 if (err) 86 return err; 87 88 err = fbnic_version_stored_put(req, &fbd->fw_cap.stored.bootloader, 89 DEVLINK_INFO_VERSION_GENERIC_FW_BOOTLOADER); 90 if (err) 91 return err; 92 93 err = fbnic_version_stored_put(req, &fbd->fw_cap.stored.undi, 94 DEVLINK_INFO_VERSION_GENERIC_FW_UNDI); 95 if (err) 96 return err; 97 98 if (fbd->dsn) { 99 unsigned char serial[FBNIC_SN_STR_LEN]; 100 u8 dsn[8]; 101 102 put_unaligned_be64(fbd->dsn, dsn); 103 err = snprintf(serial, FBNIC_SN_STR_LEN, "%8phD", dsn); 104 if (err < 0) 105 return err; 106 107 err = devlink_info_serial_number_put(req, serial); 108 if (err) 109 return err; 110 } 111 112 return 0; 113 } 114 115 static bool 116 fbnic_pldm_match_record(struct pldmfw *context, struct pldmfw_record *record) 117 { 118 struct pldmfw_desc_tlv *desc; 119 u32 anti_rollback_ver = 0; 120 struct devlink *devlink; 121 struct fbnic_dev *fbd; 122 struct pci_dev *pdev; 123 124 /* First, use the standard PCI matching function */ 125 if (!pldmfw_op_pci_match_record(context, record)) 126 return false; 127 128 pdev = to_pci_dev(context->dev); 129 fbd = pci_get_drvdata(pdev); 130 devlink = priv_to_devlink(fbd); 131 132 /* If PCI match is successful, check for vendor-specific descriptors */ 133 list_for_each_entry(desc, &record->descs, entry) { 134 if (desc->type != PLDM_DESC_ID_VENDOR_DEFINED) 135 continue; 136 137 if (desc->size < 21 || desc->data[0] != 1 || 138 desc->data[1] != 15) 139 continue; 140 141 if (memcmp(desc->data + 2, "AntiRollbackVer", 15) != 0) 142 continue; 143 144 anti_rollback_ver = get_unaligned_le32(desc->data + 17); 145 break; 146 } 147 148 /* Compare versions and return error if they do not match */ 149 if (anti_rollback_ver < fbd->fw_cap.anti_rollback_version) { 150 char buf[128]; 151 152 snprintf(buf, sizeof(buf), 153 "New firmware anti-rollback version (0x%x) is older than device version (0x%x)!", 154 anti_rollback_ver, fbd->fw_cap.anti_rollback_version); 155 devlink_flash_update_status_notify(devlink, buf, 156 "Anti-Rollback", 0, 0); 157 158 return false; 159 } 160 161 return true; 162 } 163 164 static int 165 fbnic_flash_start(struct fbnic_dev *fbd, struct pldmfw_component *component) 166 { 167 struct fbnic_fw_completion *cmpl; 168 int err; 169 170 cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_FW_START_UPGRADE_REQ); 171 if (!cmpl) 172 return -ENOMEM; 173 174 err = fbnic_fw_xmit_fw_start_upgrade(fbd, cmpl, 175 component->identifier, 176 component->component_size); 177 if (err) 178 goto cmpl_free; 179 180 /* Wait for firmware to ack firmware upgrade start */ 181 if (wait_for_completion_timeout(&cmpl->done, 10 * HZ)) 182 err = cmpl->result; 183 else 184 err = -ETIMEDOUT; 185 186 fbnic_mbx_clear_cmpl(fbd, cmpl); 187 cmpl_free: 188 fbnic_fw_put_cmpl(cmpl); 189 190 return err; 191 } 192 193 static int 194 fbnic_flash_component(struct pldmfw *context, 195 struct pldmfw_component *component) 196 { 197 const u8 *data = component->component_data; 198 const u32 size = component->component_size; 199 struct fbnic_fw_completion *cmpl; 200 const char *component_name; 201 struct devlink *devlink; 202 struct fbnic_dev *fbd; 203 struct pci_dev *pdev; 204 u32 offset = 0; 205 u32 length = 0; 206 char buf[32]; 207 int err; 208 209 pdev = to_pci_dev(context->dev); 210 fbd = pci_get_drvdata(pdev); 211 devlink = priv_to_devlink(fbd); 212 213 switch (component->identifier) { 214 case QSPI_SECTION_CMRT: 215 component_name = "boot1"; 216 break; 217 case QSPI_SECTION_CONTROL_FW: 218 component_name = "boot2"; 219 break; 220 case QSPI_SECTION_OPTION_ROM: 221 component_name = "option-rom"; 222 break; 223 default: 224 snprintf(buf, sizeof(buf), "Unknown component ID %u!", 225 component->identifier); 226 devlink_flash_update_status_notify(devlink, buf, NULL, 0, 227 size); 228 return -EINVAL; 229 } 230 231 /* Once firmware receives the request to start upgrading it responds 232 * with two messages: 233 * 1. An ACK that it received the message and possible error code 234 * indicating that an upgrade is not currently possible. 235 * 2. A request for the first chunk of data 236 * 237 * Setup completions for write before issuing the start message so 238 * the driver can catch both messages. 239 */ 240 cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_REQ); 241 if (!cmpl) 242 return -ENOMEM; 243 244 err = fbnic_mbx_set_cmpl(fbd, cmpl); 245 if (err) 246 goto cmpl_free; 247 248 devlink_flash_update_timeout_notify(devlink, "Initializing", 249 component_name, 15); 250 err = fbnic_flash_start(fbd, component); 251 if (err) 252 goto err_no_msg; 253 254 while (offset < size) { 255 if (!wait_for_completion_timeout(&cmpl->done, 15 * HZ)) { 256 err = -ETIMEDOUT; 257 break; 258 } 259 260 err = cmpl->result; 261 if (err) 262 break; 263 264 /* Verify firmware is requesting the next chunk in the seq. */ 265 if (cmpl->u.fw_update.offset != offset + length) { 266 err = -EFAULT; 267 break; 268 } 269 270 offset = cmpl->u.fw_update.offset; 271 length = cmpl->u.fw_update.length; 272 273 if (length > TLV_MAX_DATA || offset + length > size) { 274 err = -EFAULT; 275 break; 276 } 277 278 devlink_flash_update_status_notify(devlink, "Flashing", 279 component_name, 280 offset, size); 281 282 /* Mailbox will set length to 0 once it receives the finish 283 * message. 284 */ 285 if (!length) 286 continue; 287 288 reinit_completion(&cmpl->done); 289 err = fbnic_fw_xmit_fw_write_chunk(fbd, data, offset, length, 290 0); 291 if (err) 292 break; 293 } 294 295 if (err) { 296 fbnic_fw_xmit_fw_write_chunk(fbd, NULL, 0, 0, err); 297 err_no_msg: 298 snprintf(buf, sizeof(buf), "Mailbox encountered error %d!", 299 err); 300 devlink_flash_update_status_notify(devlink, buf, 301 component_name, 0, 0); 302 } 303 304 fbnic_mbx_clear_cmpl(fbd, cmpl); 305 cmpl_free: 306 fbnic_fw_put_cmpl(cmpl); 307 308 return err; 309 } 310 311 static const struct pldmfw_ops fbnic_pldmfw_ops = { 312 .match_record = fbnic_pldm_match_record, 313 .flash_component = fbnic_flash_component, 314 }; 315 316 static int 317 fbnic_devlink_flash_update(struct devlink *devlink, 318 struct devlink_flash_update_params *params, 319 struct netlink_ext_ack *extack) 320 { 321 struct fbnic_dev *fbd = devlink_priv(devlink); 322 const struct firmware *fw = params->fw; 323 struct device *dev = fbd->dev; 324 struct pldmfw context; 325 char *err_msg; 326 int err; 327 328 context.ops = &fbnic_pldmfw_ops; 329 context.dev = dev; 330 331 err = pldmfw_flash_image(&context, fw); 332 if (err) { 333 switch (err) { 334 case -EINVAL: 335 err_msg = "Invalid image"; 336 break; 337 case -EOPNOTSUPP: 338 err_msg = "Unsupported image"; 339 break; 340 case -ENOMEM: 341 err_msg = "Out of memory"; 342 break; 343 case -EFAULT: 344 err_msg = "Invalid header"; 345 break; 346 case -ENOENT: 347 err_msg = "No matching record"; 348 break; 349 case -ENODEV: 350 err_msg = "No matching device"; 351 break; 352 case -ETIMEDOUT: 353 err_msg = "Timed out waiting for reply"; 354 break; 355 default: 356 err_msg = "Unknown error"; 357 break; 358 } 359 360 NL_SET_ERR_MSG_FMT_MOD(extack, 361 "Failed to flash PLDM Image: %s (error: %d)", 362 err_msg, err); 363 } 364 365 return err; 366 } 367 368 static const struct devlink_ops fbnic_devlink_ops = { 369 .info_get = fbnic_devlink_info_get, 370 .flash_update = fbnic_devlink_flash_update, 371 }; 372 373 static int fbnic_fw_reporter_dump(struct devlink_health_reporter *reporter, 374 struct devlink_fmsg *fmsg, void *priv_ctx, 375 struct netlink_ext_ack *extack) 376 { 377 struct fbnic_dev *fbd = devlink_health_reporter_priv(reporter); 378 u32 offset, index, index_count, length, size; 379 struct fbnic_fw_completion *fw_cmpl; 380 u8 *dump_data, **data; 381 int err; 382 383 fw_cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_COREDUMP_GET_INFO_RESP); 384 if (!fw_cmpl) 385 return -ENOMEM; 386 387 err = fbnic_fw_xmit_coredump_info_msg(fbd, fw_cmpl, true); 388 if (err) { 389 NL_SET_ERR_MSG_MOD(extack, 390 "Failed to transmit core dump info msg"); 391 goto cmpl_free; 392 } 393 if (!wait_for_completion_timeout(&fw_cmpl->done, 2 * HZ)) { 394 NL_SET_ERR_MSG_MOD(extack, 395 "Timed out waiting on core dump info"); 396 err = -ETIMEDOUT; 397 goto cmpl_cleanup; 398 } 399 400 size = fw_cmpl->u.coredump_info.size; 401 err = fw_cmpl->result; 402 403 fbnic_mbx_clear_cmpl(fbd, fw_cmpl); 404 fbnic_fw_put_cmpl(fw_cmpl); 405 406 /* Handle error returned by firmware */ 407 if (err) { 408 NL_SET_ERR_MSG_MOD(extack, "Firmware core dump returned error"); 409 return err; 410 } 411 if (!size) { 412 NL_SET_ERR_MSG_MOD(extack, 413 "Firmware core dump returned size 0"); 414 return -EIO; 415 } 416 417 /* Read the dump, we can only transfer TLV_MAX_DATA at a time */ 418 index_count = DIV_ROUND_UP(size, TLV_MAX_DATA); 419 420 fw_cmpl = __fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_COREDUMP_READ_RESP, 421 sizeof(void *) * index_count + size); 422 if (!fw_cmpl) 423 return -ENOMEM; 424 425 /* Populate pointer table w/ pointer offsets */ 426 dump_data = (void *)&fw_cmpl->u.coredump.data[index_count]; 427 data = fw_cmpl->u.coredump.data; 428 fw_cmpl->u.coredump.size = size; 429 fw_cmpl->u.coredump.stride = TLV_MAX_DATA; 430 431 for (index = 0; index < index_count; index++) { 432 /* First iteration installs completion */ 433 struct fbnic_fw_completion *cmpl_arg = index ? NULL : fw_cmpl; 434 435 offset = index * TLV_MAX_DATA; 436 length = min(size - offset, TLV_MAX_DATA); 437 438 data[index] = dump_data + offset; 439 err = fbnic_fw_xmit_coredump_read_msg(fbd, cmpl_arg, 440 offset, length); 441 if (err) { 442 NL_SET_ERR_MSG_MOD(extack, 443 "Failed to transmit core dump msg"); 444 if (cmpl_arg) 445 goto cmpl_free; 446 else 447 goto cmpl_cleanup; 448 } 449 450 if (wait_for_completion_timeout(&fw_cmpl->done, 2 * HZ)) { 451 reinit_completion(&fw_cmpl->done); 452 } else { 453 NL_SET_ERR_MSG_FMT_MOD(extack, 454 "Timed out waiting on core dump (%d/%d)", 455 index + 1, index_count); 456 err = -ETIMEDOUT; 457 goto cmpl_cleanup; 458 } 459 460 /* If we didn't see the reply record as incomplete */ 461 if (fw_cmpl->u.coredump.data[index]) { 462 NL_SET_ERR_MSG_FMT_MOD(extack, 463 "No data for core dump chunk (%d/%d)", 464 index + 1, index_count); 465 err = -EIO; 466 goto cmpl_cleanup; 467 } 468 } 469 470 devlink_fmsg_binary_pair_nest_start(fmsg, "FW coredump"); 471 472 for (offset = 0; offset < size; offset += length) { 473 length = min_t(u32, size - offset, TLV_MAX_DATA); 474 475 devlink_fmsg_binary_put(fmsg, dump_data + offset, length); 476 } 477 478 devlink_fmsg_binary_pair_nest_end(fmsg); 479 480 cmpl_cleanup: 481 fbnic_mbx_clear_cmpl(fbd, fw_cmpl); 482 cmpl_free: 483 fbnic_fw_put_cmpl(fw_cmpl); 484 485 return err; 486 } 487 488 static int 489 fbnic_fw_reporter_diagnose(struct devlink_health_reporter *reporter, 490 struct devlink_fmsg *fmsg, 491 struct netlink_ext_ack *extack) 492 { 493 struct fbnic_dev *fbd = devlink_health_reporter_priv(reporter); 494 u32 sec, msec; 495 496 /* Device is most likely down, we're not exchanging heartbeats */ 497 if (!fbd->prev_firmware_time) 498 return 0; 499 500 sec = div_u64_rem(fbd->firmware_time, MSEC_PER_SEC, &msec); 501 502 devlink_fmsg_pair_nest_start(fmsg, "last_heartbeat"); 503 devlink_fmsg_obj_nest_start(fmsg); 504 devlink_fmsg_pair_nest_start(fmsg, "fw_uptime"); 505 devlink_fmsg_obj_nest_start(fmsg); 506 devlink_fmsg_u32_pair_put(fmsg, "sec", sec); 507 devlink_fmsg_u32_pair_put(fmsg, "msec", msec); 508 devlink_fmsg_obj_nest_end(fmsg); 509 devlink_fmsg_pair_nest_end(fmsg); 510 devlink_fmsg_obj_nest_end(fmsg); 511 devlink_fmsg_pair_nest_end(fmsg); 512 513 return 0; 514 } 515 516 void __printf(2, 3) 517 fbnic_devlink_fw_report(struct fbnic_dev *fbd, const char *format, ...) 518 { 519 char msg[FBNIC_FW_LOG_MAX_SIZE]; 520 va_list args; 521 522 va_start(args, format); 523 vsnprintf(msg, FBNIC_FW_LOG_MAX_SIZE, format, args); 524 va_end(args); 525 526 devlink_health_report(fbd->fw_reporter, msg, fbd); 527 if (fbnic_fw_log_ready(fbd)) 528 fbnic_fw_log_write(fbd, 0, fbd->firmware_time, msg); 529 } 530 531 static const struct devlink_health_reporter_ops fbnic_fw_ops = { 532 .name = "fw", 533 .dump = fbnic_fw_reporter_dump, 534 .diagnose = fbnic_fw_reporter_diagnose, 535 }; 536 537 static u32 fbnic_read_otp_status(struct fbnic_dev *fbd) 538 { 539 return fbnic_fw_rd32(fbd, FBNIC_NS_OTP_STATUS); 540 } 541 542 static int 543 fbnic_otp_reporter_dump(struct devlink_health_reporter *reporter, 544 struct devlink_fmsg *fmsg, void *priv_ctx, 545 struct netlink_ext_ack *extack) 546 { 547 struct fbnic_dev *fbd = devlink_health_reporter_priv(reporter); 548 u32 otp_status, otp_write_status, m; 549 550 otp_status = fbnic_read_otp_status(fbd); 551 otp_write_status = fbnic_fw_rd32(fbd, FBNIC_NS_OTP_WRITE_STATUS); 552 553 /* Dump OTP status */ 554 devlink_fmsg_pair_nest_start(fmsg, "OTP"); 555 devlink_fmsg_obj_nest_start(fmsg); 556 557 devlink_fmsg_u32_pair_put(fmsg, "Status", otp_status); 558 559 /* Extract OTP Write Data status */ 560 m = FBNIC_NS_OTP_WRITE_DATA_STATUS_MASK; 561 devlink_fmsg_u32_pair_put(fmsg, "Data", 562 FIELD_GET(m, otp_write_status)); 563 564 /* Extract OTP Write ECC status */ 565 m = FBNIC_NS_OTP_WRITE_ECC_STATUS_MASK; 566 devlink_fmsg_u32_pair_put(fmsg, "ECC", 567 FIELD_GET(m, otp_write_status)); 568 569 devlink_fmsg_obj_nest_end(fmsg); 570 devlink_fmsg_pair_nest_end(fmsg); 571 572 return 0; 573 } 574 575 void fbnic_devlink_otp_check(struct fbnic_dev *fbd, const char *msg) 576 { 577 /* Check if there is anything to report */ 578 if (!fbnic_read_otp_status(fbd)) 579 return; 580 581 devlink_health_report(fbd->otp_reporter, msg, fbd); 582 if (fbnic_fw_log_ready(fbd)) 583 fbnic_fw_log_write(fbd, 0, fbd->firmware_time, msg); 584 } 585 586 static const struct devlink_health_reporter_ops fbnic_otp_ops = { 587 .name = "otp", 588 .dump = fbnic_otp_reporter_dump, 589 }; 590 591 int fbnic_devlink_health_create(struct fbnic_dev *fbd) 592 { 593 fbd->fw_reporter = devlink_health_reporter_create(priv_to_devlink(fbd), 594 &fbnic_fw_ops, fbd); 595 if (IS_ERR(fbd->fw_reporter)) { 596 dev_warn(fbd->dev, 597 "Failed to create FW fault reporter: %pe\n", 598 fbd->fw_reporter); 599 return PTR_ERR(fbd->fw_reporter); 600 } 601 602 fbd->otp_reporter = devlink_health_reporter_create(priv_to_devlink(fbd), 603 &fbnic_otp_ops, fbd); 604 if (IS_ERR(fbd->otp_reporter)) { 605 devlink_health_reporter_destroy(fbd->fw_reporter); 606 dev_warn(fbd->dev, 607 "Failed to create OTP fault reporter: %pe\n", 608 fbd->otp_reporter); 609 return PTR_ERR(fbd->otp_reporter); 610 } 611 612 return 0; 613 } 614 615 void fbnic_devlink_health_destroy(struct fbnic_dev *fbd) 616 { 617 devlink_health_reporter_destroy(fbd->otp_reporter); 618 devlink_health_reporter_destroy(fbd->fw_reporter); 619 } 620 621 void fbnic_devlink_free(struct fbnic_dev *fbd) 622 { 623 struct devlink *devlink = priv_to_devlink(fbd); 624 625 devlink_free(devlink); 626 } 627 628 struct fbnic_dev *fbnic_devlink_alloc(struct pci_dev *pdev) 629 { 630 void __iomem * const *iomap_table; 631 struct devlink *devlink; 632 struct fbnic_dev *fbd; 633 634 devlink = devlink_alloc(&fbnic_devlink_ops, sizeof(struct fbnic_dev), 635 &pdev->dev); 636 if (!devlink) 637 return NULL; 638 639 fbd = devlink_priv(devlink); 640 pci_set_drvdata(pdev, fbd); 641 fbd->dev = &pdev->dev; 642 643 iomap_table = pcim_iomap_table(pdev); 644 fbd->uc_addr0 = iomap_table[0]; 645 fbd->uc_addr4 = iomap_table[4]; 646 647 fbd->dsn = pci_get_dsn(pdev); 648 fbd->mps = pcie_get_mps(pdev); 649 fbd->readrq = pcie_get_readrq(pdev); 650 651 fbd->mac_addr_boundary = FBNIC_RPC_TCAM_MACDA_DEFAULT_BOUNDARY; 652 653 return fbd; 654 } 655 656 void fbnic_devlink_register(struct fbnic_dev *fbd) 657 { 658 struct devlink *devlink = priv_to_devlink(fbd); 659 660 devlink_register(devlink); 661 } 662 663 void fbnic_devlink_unregister(struct fbnic_dev *fbd) 664 { 665 struct devlink *devlink = priv_to_devlink(fbd); 666 667 devlink_unregister(devlink); 668 } 669