1 /* Broadcom NetXtreme-C/E network driver. 2 * 3 * Copyright (c) 2017 Broadcom Limited 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation. 8 */ 9 10 #include <linux/pci.h> 11 #include <linux/netdevice.h> 12 #include <linux/vmalloc.h> 13 #include <net/devlink.h> 14 #include "bnxt_hsi.h" 15 #include "bnxt.h" 16 #include "bnxt_hwrm.h" 17 #include "bnxt_vfr.h" 18 #include "bnxt_devlink.h" 19 #include "bnxt_ethtool.h" 20 #include "bnxt_ulp.h" 21 #include "bnxt_ptp.h" 22 #include "bnxt_coredump.h" 23 #include "bnxt_nvm_defs.h" /* NVRAM content constant and structure defs */ 24 25 static void __bnxt_fw_recover(struct bnxt *bp) 26 { 27 if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) || 28 test_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state)) 29 bnxt_fw_reset(bp); 30 else 31 bnxt_fw_exception(bp); 32 } 33 34 static int 35 bnxt_dl_flash_update(struct devlink *dl, 36 struct devlink_flash_update_params *params, 37 struct netlink_ext_ack *extack) 38 { 39 struct bnxt *bp = bnxt_get_bp_from_dl(dl); 40 int rc; 41 42 if (!BNXT_PF(bp)) { 43 NL_SET_ERR_MSG_MOD(extack, 44 "flash update not supported from a VF"); 45 return -EPERM; 46 } 47 48 devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0); 49 rc = bnxt_flash_package_from_fw_obj(bp->dev, params->fw, 0); 50 if (!rc) 51 devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0); 52 else 53 devlink_flash_update_status_notify(dl, "Flashing failed", NULL, 0, 0); 54 return rc; 55 } 56 57 static int bnxt_hwrm_remote_dev_reset_set(struct bnxt *bp, bool remote_reset) 58 { 59 struct hwrm_func_cfg_input *req; 60 int rc; 61 62 if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF) 63 return -EOPNOTSUPP; 64 65 rc = hwrm_req_init(bp, req, HWRM_FUNC_CFG); 66 if (rc) 67 return rc; 68 69 req->fid = cpu_to_le16(0xffff); 70 req->enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_HOT_RESET_IF_SUPPORT); 71 if (remote_reset) 72 req->flags = cpu_to_le32(FUNC_CFG_REQ_FLAGS_HOT_RESET_IF_EN_DIS); 73 74 return hwrm_req_send(bp, req); 75 } 76 77 static char *bnxt_health_severity_str(enum bnxt_health_severity severity) 78 { 79 switch (severity) { 80 case SEVERITY_NORMAL: return "normal"; 81 case SEVERITY_WARNING: return "warning"; 82 case SEVERITY_RECOVERABLE: return "recoverable"; 83 case SEVERITY_FATAL: return "fatal"; 84 default: return "unknown"; 85 } 86 } 87 88 static char *bnxt_health_remedy_str(enum bnxt_health_remedy remedy) 89 { 90 switch (remedy) { 91 case REMEDY_DEVLINK_RECOVER: return "devlink recover"; 92 case REMEDY_POWER_CYCLE_DEVICE: return "device power cycle"; 93 case REMEDY_POWER_CYCLE_HOST: return "host power cycle"; 94 case REMEDY_FW_UPDATE: return "update firmware"; 95 case REMEDY_HW_REPLACE: return "replace hardware"; 96 default: return "unknown"; 97 } 98 } 99 100 static int bnxt_fw_diagnose(struct devlink_health_reporter *reporter, 101 struct devlink_fmsg *fmsg, 102 struct netlink_ext_ack *extack) 103 { 104 struct bnxt *bp = devlink_health_reporter_priv(reporter); 105 struct bnxt_fw_health *h = bp->fw_health; 106 u32 fw_status, fw_resets; 107 int rc; 108 109 if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) 110 return devlink_fmsg_string_pair_put(fmsg, "Status", "recovering"); 111 112 if (!h->status_reliable) 113 return devlink_fmsg_string_pair_put(fmsg, "Status", "unknown"); 114 115 mutex_lock(&h->lock); 116 fw_status = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG); 117 if (BNXT_FW_IS_BOOTING(fw_status)) { 118 rc = devlink_fmsg_string_pair_put(fmsg, "Status", "initializing"); 119 if (rc) 120 goto unlock; 121 } else if (h->severity || fw_status != BNXT_FW_STATUS_HEALTHY) { 122 if (!h->severity) { 123 h->severity = SEVERITY_FATAL; 124 h->remedy = REMEDY_POWER_CYCLE_DEVICE; 125 h->diagnoses++; 126 devlink_health_report(h->fw_reporter, 127 "FW error diagnosed", h); 128 } 129 rc = devlink_fmsg_string_pair_put(fmsg, "Status", "error"); 130 if (rc) 131 goto unlock; 132 rc = devlink_fmsg_u32_pair_put(fmsg, "Syndrome", fw_status); 133 if (rc) 134 goto unlock; 135 } else { 136 rc = devlink_fmsg_string_pair_put(fmsg, "Status", "healthy"); 137 if (rc) 138 goto unlock; 139 } 140 141 rc = devlink_fmsg_string_pair_put(fmsg, "Severity", 142 bnxt_health_severity_str(h->severity)); 143 if (rc) 144 goto unlock; 145 146 if (h->severity) { 147 rc = devlink_fmsg_string_pair_put(fmsg, "Remedy", 148 bnxt_health_remedy_str(h->remedy)); 149 if (rc) 150 goto unlock; 151 if (h->remedy == REMEDY_DEVLINK_RECOVER) { 152 rc = devlink_fmsg_string_pair_put(fmsg, "Impact", 153 "traffic+ntuple_cfg"); 154 if (rc) 155 goto unlock; 156 } 157 } 158 159 unlock: 160 mutex_unlock(&h->lock); 161 if (rc || !h->resets_reliable) 162 return rc; 163 164 fw_resets = bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG); 165 rc = devlink_fmsg_u32_pair_put(fmsg, "Resets", fw_resets); 166 if (rc) 167 return rc; 168 rc = devlink_fmsg_u32_pair_put(fmsg, "Arrests", h->arrests); 169 if (rc) 170 return rc; 171 rc = devlink_fmsg_u32_pair_put(fmsg, "Survivals", h->survivals); 172 if (rc) 173 return rc; 174 rc = devlink_fmsg_u32_pair_put(fmsg, "Discoveries", h->discoveries); 175 if (rc) 176 return rc; 177 rc = devlink_fmsg_u32_pair_put(fmsg, "Fatalities", h->fatalities); 178 if (rc) 179 return rc; 180 return devlink_fmsg_u32_pair_put(fmsg, "Diagnoses", h->diagnoses); 181 } 182 183 static int bnxt_fw_dump(struct devlink_health_reporter *reporter, 184 struct devlink_fmsg *fmsg, void *priv_ctx, 185 struct netlink_ext_ack *extack) 186 { 187 struct bnxt *bp = devlink_health_reporter_priv(reporter); 188 u32 dump_len; 189 void *data; 190 int rc; 191 192 /* TODO: no firmware dump support in devlink_health_report() context */ 193 if (priv_ctx) 194 return -EOPNOTSUPP; 195 196 dump_len = bnxt_get_coredump_length(bp, BNXT_DUMP_LIVE); 197 if (!dump_len) 198 return -EIO; 199 200 data = vmalloc(dump_len); 201 if (!data) 202 return -ENOMEM; 203 204 rc = bnxt_get_coredump(bp, BNXT_DUMP_LIVE, data, &dump_len); 205 if (!rc) { 206 rc = devlink_fmsg_pair_nest_start(fmsg, "core"); 207 if (rc) 208 goto exit; 209 rc = devlink_fmsg_binary_pair_put(fmsg, "data", data, dump_len); 210 if (rc) 211 goto exit; 212 rc = devlink_fmsg_u32_pair_put(fmsg, "size", dump_len); 213 if (rc) 214 goto exit; 215 rc = devlink_fmsg_pair_nest_end(fmsg); 216 } 217 218 exit: 219 vfree(data); 220 return rc; 221 } 222 223 static int bnxt_fw_recover(struct devlink_health_reporter *reporter, 224 void *priv_ctx, 225 struct netlink_ext_ack *extack) 226 { 227 struct bnxt *bp = devlink_health_reporter_priv(reporter); 228 229 if (bp->fw_health->severity == SEVERITY_FATAL) 230 return -ENODEV; 231 232 set_bit(BNXT_STATE_RECOVER, &bp->state); 233 __bnxt_fw_recover(bp); 234 235 return -EINPROGRESS; 236 } 237 238 static const struct devlink_health_reporter_ops bnxt_dl_fw_reporter_ops = { 239 .name = "fw", 240 .diagnose = bnxt_fw_diagnose, 241 .dump = bnxt_fw_dump, 242 .recover = bnxt_fw_recover, 243 }; 244 245 static int bnxt_hw_recover(struct devlink_health_reporter *reporter, 246 void *priv_ctx, 247 struct netlink_ext_ack *extack) 248 { 249 struct bnxt *bp = devlink_health_reporter_priv(reporter); 250 struct bnxt_hw_health *hw_health = &bp->hw_health; 251 252 hw_health->synd = BNXT_HW_STATUS_HEALTHY; 253 return 0; 254 } 255 256 static const char *hw_err_str(u8 synd) 257 { 258 switch (synd) { 259 case BNXT_HW_STATUS_HEALTHY: 260 return "healthy"; 261 case BNXT_HW_STATUS_NVM_WRITE_ERR: 262 return "nvm write error"; 263 case BNXT_HW_STATUS_NVM_ERASE_ERR: 264 return "nvm erase error"; 265 case BNXT_HW_STATUS_NVM_UNKNOWN_ERR: 266 return "unrecognized nvm error"; 267 case BNXT_HW_STATUS_NVM_TEST_VPD_ENT_ERR: 268 return "nvm test vpd entry error"; 269 case BNXT_HW_STATUS_NVM_TEST_VPD_READ_ERR: 270 return "nvm test vpd read error"; 271 case BNXT_HW_STATUS_NVM_TEST_VPD_WRITE_ERR: 272 return "nvm test vpd write error"; 273 case BNXT_HW_STATUS_NVM_TEST_INCMPL_ERR: 274 return "nvm test incomplete error"; 275 default: 276 return "unknown hw error"; 277 } 278 } 279 280 static void bnxt_nvm_test(struct bnxt *bp) 281 { 282 struct bnxt_hw_health *h = &bp->hw_health; 283 u32 datalen; 284 u16 index; 285 u8 *buf; 286 287 if (!h->nvm_test_result) { 288 if (!h->nvm_test_timestamp || 289 time_after(jiffies, h->nvm_test_timestamp + 290 msecs_to_jiffies(HW_RETEST_MIN_TIME))) 291 h->nvm_test_timestamp = jiffies; 292 else 293 return; 294 } 295 296 if (bnxt_find_nvram_item(bp->dev, BNX_DIR_TYPE_VPD, 297 BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE, 298 &index, NULL, &datalen) || !datalen) { 299 h->nvm_test_result = BNXT_HW_STATUS_NVM_TEST_VPD_ENT_ERR; 300 h->nvm_test_vpd_ent_errors++; 301 return; 302 } 303 304 buf = kzalloc(datalen, GFP_KERNEL); 305 if (!buf) { 306 h->nvm_test_result = BNXT_HW_STATUS_NVM_TEST_INCMPL_ERR; 307 h->nvm_test_incmpl_errors++; 308 return; 309 } 310 311 if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) { 312 h->nvm_test_result = BNXT_HW_STATUS_NVM_TEST_VPD_READ_ERR; 313 h->nvm_test_vpd_read_errors++; 314 goto err; 315 } 316 317 if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST, 318 BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) { 319 h->nvm_test_result = BNXT_HW_STATUS_NVM_TEST_VPD_WRITE_ERR; 320 h->nvm_test_vpd_write_errors++; 321 } 322 323 err: 324 kfree(buf); 325 } 326 327 static int bnxt_hw_diagnose(struct devlink_health_reporter *reporter, 328 struct devlink_fmsg *fmsg, 329 struct netlink_ext_ack *extack) 330 { 331 struct bnxt *bp = devlink_health_reporter_priv(reporter); 332 struct bnxt_hw_health *h = &bp->hw_health; 333 u8 synd = h->synd; 334 int rc; 335 336 bnxt_nvm_test(bp); 337 if (h->nvm_test_result) { 338 synd = h->nvm_test_result; 339 devlink_health_report(h->hw_reporter, hw_err_str(synd), NULL); 340 } 341 342 rc = devlink_fmsg_string_pair_put(fmsg, "Status", hw_err_str(synd)); 343 if (rc) 344 return rc; 345 rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_write_errors", h->nvm_write_errors); 346 if (rc) 347 return rc; 348 rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_erase_errors", h->nvm_erase_errors); 349 if (rc) 350 return rc; 351 rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_test_vpd_ent_errors", 352 h->nvm_test_vpd_ent_errors); 353 if (rc) 354 return rc; 355 rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_test_vpd_read_errors", 356 h->nvm_test_vpd_read_errors); 357 if (rc) 358 return rc; 359 rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_test_vpd_write_errors", 360 h->nvm_test_vpd_write_errors); 361 if (rc) 362 return rc; 363 rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_test_incomplete_errors", 364 h->nvm_test_incmpl_errors); 365 if (rc) 366 return rc; 367 368 return 0; 369 } 370 371 void bnxt_devlink_health_hw_report(struct bnxt *bp) 372 { 373 struct bnxt_hw_health *hw_health = &bp->hw_health; 374 375 netdev_warn(bp->dev, "%s reported at address 0x%x\n", hw_err_str(hw_health->synd), 376 hw_health->nvm_err_address); 377 378 devlink_health_report(hw_health->hw_reporter, hw_err_str(hw_health->synd), NULL); 379 } 380 381 static const struct devlink_health_reporter_ops bnxt_dl_hw_reporter_ops = { 382 .name = "hw", 383 .diagnose = bnxt_hw_diagnose, 384 .recover = bnxt_hw_recover, 385 }; 386 387 static struct devlink_health_reporter * 388 __bnxt_dl_reporter_create(struct bnxt *bp, 389 const struct devlink_health_reporter_ops *ops) 390 { 391 struct devlink_health_reporter *reporter; 392 393 reporter = devlink_health_reporter_create(bp->dl, ops, 0, bp); 394 if (IS_ERR(reporter)) { 395 netdev_warn(bp->dev, "Failed to create %s health reporter, rc = %ld\n", 396 ops->name, PTR_ERR(reporter)); 397 return NULL; 398 } 399 400 return reporter; 401 } 402 403 void bnxt_dl_fw_reporters_create(struct bnxt *bp) 404 { 405 struct bnxt_fw_health *fw_health = bp->fw_health; 406 struct bnxt_hw_health *hw_health = &bp->hw_health; 407 408 if (!hw_health->hw_reporter) 409 hw_health->hw_reporter = __bnxt_dl_reporter_create(bp, &bnxt_dl_hw_reporter_ops); 410 411 if (fw_health && !fw_health->fw_reporter) 412 fw_health->fw_reporter = __bnxt_dl_reporter_create(bp, &bnxt_dl_fw_reporter_ops); 413 } 414 415 void bnxt_dl_fw_reporters_destroy(struct bnxt *bp) 416 { 417 struct bnxt_fw_health *fw_health = bp->fw_health; 418 struct bnxt_hw_health *hw_health = &bp->hw_health; 419 420 if (hw_health->hw_reporter) { 421 devlink_health_reporter_destroy(hw_health->hw_reporter); 422 hw_health->hw_reporter = NULL; 423 } 424 425 if (fw_health && fw_health->fw_reporter) { 426 devlink_health_reporter_destroy(fw_health->fw_reporter); 427 fw_health->fw_reporter = NULL; 428 } 429 } 430 431 void bnxt_devlink_health_fw_report(struct bnxt *bp) 432 { 433 struct bnxt_fw_health *fw_health = bp->fw_health; 434 int rc; 435 436 if (!fw_health) 437 return; 438 439 if (!fw_health->fw_reporter) { 440 __bnxt_fw_recover(bp); 441 return; 442 } 443 444 mutex_lock(&fw_health->lock); 445 fw_health->severity = SEVERITY_RECOVERABLE; 446 fw_health->remedy = REMEDY_DEVLINK_RECOVER; 447 mutex_unlock(&fw_health->lock); 448 rc = devlink_health_report(fw_health->fw_reporter, "FW error reported", 449 fw_health); 450 if (rc == -ECANCELED) 451 __bnxt_fw_recover(bp); 452 } 453 454 void bnxt_dl_health_fw_status_update(struct bnxt *bp, bool healthy) 455 { 456 struct bnxt_fw_health *fw_health = bp->fw_health; 457 u8 state; 458 459 mutex_lock(&fw_health->lock); 460 if (healthy) { 461 fw_health->severity = SEVERITY_NORMAL; 462 state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY; 463 } else { 464 fw_health->severity = SEVERITY_FATAL; 465 fw_health->remedy = REMEDY_POWER_CYCLE_DEVICE; 466 state = DEVLINK_HEALTH_REPORTER_STATE_ERROR; 467 } 468 mutex_unlock(&fw_health->lock); 469 devlink_health_reporter_state_update(fw_health->fw_reporter, state); 470 } 471 472 void bnxt_dl_health_fw_recovery_done(struct bnxt *bp) 473 { 474 struct bnxt_dl *dl = devlink_priv(bp->dl); 475 476 devlink_health_reporter_recovery_done(bp->fw_health->fw_reporter); 477 bnxt_hwrm_remote_dev_reset_set(bp, dl->remote_reset); 478 } 479 480 static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req, 481 struct netlink_ext_ack *extack); 482 483 static void 484 bnxt_dl_livepatch_report_err(struct bnxt *bp, struct netlink_ext_ack *extack, 485 struct hwrm_fw_livepatch_output *resp) 486 { 487 int err = ((struct hwrm_err_output *)resp)->cmd_err; 488 489 switch (err) { 490 case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_OPCODE: 491 netdev_err(bp->dev, "Illegal live patch opcode"); 492 NL_SET_ERR_MSG_MOD(extack, "Invalid opcode"); 493 break; 494 case FW_LIVEPATCH_CMD_ERR_CODE_NOT_SUPPORTED: 495 NL_SET_ERR_MSG_MOD(extack, "Live patch operation not supported"); 496 break; 497 case FW_LIVEPATCH_CMD_ERR_CODE_NOT_INSTALLED: 498 NL_SET_ERR_MSG_MOD(extack, "Live patch not found"); 499 break; 500 case FW_LIVEPATCH_CMD_ERR_CODE_NOT_PATCHED: 501 NL_SET_ERR_MSG_MOD(extack, 502 "Live patch deactivation failed. Firmware not patched."); 503 break; 504 case FW_LIVEPATCH_CMD_ERR_CODE_AUTH_FAIL: 505 NL_SET_ERR_MSG_MOD(extack, "Live patch not authenticated"); 506 break; 507 case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_HEADER: 508 NL_SET_ERR_MSG_MOD(extack, "Incompatible live patch"); 509 break; 510 case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_SIZE: 511 NL_SET_ERR_MSG_MOD(extack, "Live patch has invalid size"); 512 break; 513 case FW_LIVEPATCH_CMD_ERR_CODE_ALREADY_PATCHED: 514 NL_SET_ERR_MSG_MOD(extack, "Live patch already applied"); 515 break; 516 default: 517 netdev_err(bp->dev, "Unexpected live patch error: %d\n", err); 518 NL_SET_ERR_MSG_MOD(extack, "Failed to activate live patch"); 519 break; 520 } 521 } 522 523 /* Live patch status in NVM */ 524 #define BNXT_LIVEPATCH_NOT_INSTALLED 0 525 #define BNXT_LIVEPATCH_INSTALLED FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL 526 #define BNXT_LIVEPATCH_REMOVED FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE 527 #define BNXT_LIVEPATCH_MASK (FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL | \ 528 FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE) 529 #define BNXT_LIVEPATCH_ACTIVATED BNXT_LIVEPATCH_MASK 530 531 #define BNXT_LIVEPATCH_STATE(flags) ((flags) & BNXT_LIVEPATCH_MASK) 532 533 static int 534 bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack) 535 { 536 struct hwrm_fw_livepatch_query_output *query_resp; 537 struct hwrm_fw_livepatch_query_input *query_req; 538 struct hwrm_fw_livepatch_output *patch_resp; 539 struct hwrm_fw_livepatch_input *patch_req; 540 u16 flags, live_patch_state; 541 bool activated = false; 542 u32 installed = 0; 543 u8 target; 544 int rc; 545 546 if (~bp->fw_cap & BNXT_FW_CAP_LIVEPATCH) { 547 NL_SET_ERR_MSG_MOD(extack, "Device does not support live patch"); 548 return -EOPNOTSUPP; 549 } 550 551 rc = hwrm_req_init(bp, query_req, HWRM_FW_LIVEPATCH_QUERY); 552 if (rc) 553 return rc; 554 query_resp = hwrm_req_hold(bp, query_req); 555 556 rc = hwrm_req_init(bp, patch_req, HWRM_FW_LIVEPATCH); 557 if (rc) { 558 hwrm_req_drop(bp, query_req); 559 return rc; 560 } 561 patch_req->loadtype = FW_LIVEPATCH_REQ_LOADTYPE_NVM_INSTALL; 562 patch_resp = hwrm_req_hold(bp, patch_req); 563 564 for (target = 1; target <= FW_LIVEPATCH_REQ_FW_TARGET_LAST; target++) { 565 query_req->fw_target = target; 566 rc = hwrm_req_send(bp, query_req); 567 if (rc) { 568 NL_SET_ERR_MSG_MOD(extack, "Failed to query packages"); 569 break; 570 } 571 572 flags = le16_to_cpu(query_resp->status_flags); 573 live_patch_state = BNXT_LIVEPATCH_STATE(flags); 574 575 if (live_patch_state == BNXT_LIVEPATCH_NOT_INSTALLED) 576 continue; 577 578 if (live_patch_state == BNXT_LIVEPATCH_ACTIVATED) { 579 activated = true; 580 continue; 581 } 582 583 if (live_patch_state == BNXT_LIVEPATCH_INSTALLED) 584 patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_ACTIVATE; 585 else if (live_patch_state == BNXT_LIVEPATCH_REMOVED) 586 patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_DEACTIVATE; 587 588 patch_req->fw_target = target; 589 rc = hwrm_req_send(bp, patch_req); 590 if (rc) { 591 bnxt_dl_livepatch_report_err(bp, extack, patch_resp); 592 break; 593 } 594 installed++; 595 } 596 597 if (!rc && !installed) { 598 if (activated) { 599 NL_SET_ERR_MSG_MOD(extack, "Live patch already activated"); 600 rc = -EEXIST; 601 } else { 602 NL_SET_ERR_MSG_MOD(extack, "No live patches found"); 603 rc = -ENOENT; 604 } 605 } 606 hwrm_req_drop(bp, query_req); 607 hwrm_req_drop(bp, patch_req); 608 return rc; 609 } 610 611 static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change, 612 enum devlink_reload_action action, 613 enum devlink_reload_limit limit, 614 struct netlink_ext_ack *extack) 615 { 616 struct bnxt *bp = bnxt_get_bp_from_dl(dl); 617 int rc = 0; 618 619 switch (action) { 620 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: { 621 rtnl_lock(); 622 if (bnxt_sriov_cfg(bp)) { 623 NL_SET_ERR_MSG_MOD(extack, 624 "reload is unsupported while VFs are allocated or being configured"); 625 rtnl_unlock(); 626 return -EOPNOTSUPP; 627 } 628 if (bp->dev->reg_state == NETREG_UNREGISTERED) { 629 rtnl_unlock(); 630 return -ENODEV; 631 } 632 bnxt_ulp_stop(bp); 633 if (netif_running(bp->dev)) { 634 rc = bnxt_close_nic(bp, true, true); 635 if (rc) { 636 NL_SET_ERR_MSG_MOD(extack, "Failed to close"); 637 dev_close(bp->dev); 638 rtnl_unlock(); 639 break; 640 } 641 } 642 bnxt_vf_reps_free(bp); 643 rc = bnxt_hwrm_func_drv_unrgtr(bp); 644 if (rc) { 645 NL_SET_ERR_MSG_MOD(extack, "Failed to deregister"); 646 if (netif_running(bp->dev)) 647 dev_close(bp->dev); 648 rtnl_unlock(); 649 break; 650 } 651 bnxt_cancel_reservations(bp, false); 652 bnxt_free_ctx_mem(bp); 653 kfree(bp->ctx); 654 bp->ctx = NULL; 655 break; 656 } 657 case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: { 658 if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET) 659 return bnxt_dl_livepatch_activate(bp, extack); 660 if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET) { 661 NL_SET_ERR_MSG_MOD(extack, "Device not capable, requires reboot"); 662 return -EOPNOTSUPP; 663 } 664 if (!bnxt_hwrm_reset_permitted(bp)) { 665 NL_SET_ERR_MSG_MOD(extack, 666 "Reset denied by firmware, it may be inhibited by remote driver"); 667 return -EPERM; 668 } 669 rtnl_lock(); 670 if (bp->dev->reg_state == NETREG_UNREGISTERED) { 671 rtnl_unlock(); 672 return -ENODEV; 673 } 674 if (netif_running(bp->dev)) 675 set_bit(BNXT_STATE_FW_ACTIVATE, &bp->state); 676 rc = bnxt_hwrm_firmware_reset(bp->dev, 677 FW_RESET_REQ_EMBEDDED_PROC_TYPE_CHIP, 678 FW_RESET_REQ_SELFRST_STATUS_SELFRSTASAP, 679 FW_RESET_REQ_FLAGS_RESET_GRACEFUL | 680 FW_RESET_REQ_FLAGS_FW_ACTIVATION); 681 if (rc) { 682 NL_SET_ERR_MSG_MOD(extack, "Failed to activate firmware"); 683 clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state); 684 rtnl_unlock(); 685 } 686 break; 687 } 688 default: 689 rc = -EOPNOTSUPP; 690 } 691 692 return rc; 693 } 694 695 static int bnxt_dl_reload_up(struct devlink *dl, enum devlink_reload_action action, 696 enum devlink_reload_limit limit, u32 *actions_performed, 697 struct netlink_ext_ack *extack) 698 { 699 struct bnxt *bp = bnxt_get_bp_from_dl(dl); 700 int rc = 0; 701 702 *actions_performed = 0; 703 switch (action) { 704 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: { 705 bnxt_fw_init_one(bp); 706 bnxt_vf_reps_alloc(bp); 707 if (netif_running(bp->dev)) 708 rc = bnxt_open_nic(bp, true, true); 709 bnxt_ulp_start(bp, rc); 710 if (!rc) { 711 bnxt_reenable_sriov(bp); 712 bnxt_ptp_reapply_pps(bp); 713 } 714 break; 715 } 716 case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: { 717 unsigned long start = jiffies; 718 unsigned long timeout = start + BNXT_DFLT_FW_RST_MAX_DSECS * HZ / 10; 719 720 if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET) 721 break; 722 if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) 723 timeout = start + bp->fw_health->normal_func_wait_dsecs * HZ / 10; 724 if (!netif_running(bp->dev)) 725 NL_SET_ERR_MSG_MOD(extack, 726 "Device is closed, not waiting for reset notice that will never come"); 727 rtnl_unlock(); 728 while (test_bit(BNXT_STATE_FW_ACTIVATE, &bp->state)) { 729 if (time_after(jiffies, timeout)) { 730 NL_SET_ERR_MSG_MOD(extack, "Activation incomplete"); 731 rc = -ETIMEDOUT; 732 break; 733 } 734 if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) { 735 NL_SET_ERR_MSG_MOD(extack, "Activation aborted"); 736 rc = -ENODEV; 737 break; 738 } 739 msleep(50); 740 } 741 rtnl_lock(); 742 if (!rc) 743 *actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); 744 clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state); 745 break; 746 } 747 default: 748 return -EOPNOTSUPP; 749 } 750 751 if (!rc) { 752 bnxt_print_device_info(bp); 753 if (netif_running(bp->dev)) { 754 mutex_lock(&bp->link_lock); 755 bnxt_report_link(bp); 756 mutex_unlock(&bp->link_lock); 757 } 758 *actions_performed |= BIT(action); 759 } else if (netif_running(bp->dev)) { 760 dev_close(bp->dev); 761 } 762 rtnl_unlock(); 763 return rc; 764 } 765 766 static const struct devlink_ops bnxt_dl_ops = { 767 #ifdef CONFIG_BNXT_SRIOV 768 .eswitch_mode_set = bnxt_dl_eswitch_mode_set, 769 .eswitch_mode_get = bnxt_dl_eswitch_mode_get, 770 #endif /* CONFIG_BNXT_SRIOV */ 771 .info_get = bnxt_dl_info_get, 772 .flash_update = bnxt_dl_flash_update, 773 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | 774 BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), 775 .reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET), 776 .reload_down = bnxt_dl_reload_down, 777 .reload_up = bnxt_dl_reload_up, 778 }; 779 780 static const struct devlink_ops bnxt_vf_dl_ops; 781 782 enum bnxt_dl_param_id { 783 BNXT_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, 784 BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK, 785 }; 786 787 static const struct bnxt_dl_nvm_param nvm_params[] = { 788 {DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, NVM_OFF_ENABLE_SRIOV, 789 BNXT_NVM_SHARED_CFG, 1, 1}, 790 {DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI, NVM_OFF_IGNORE_ARI, 791 BNXT_NVM_SHARED_CFG, 1, 1}, 792 {DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX, 793 NVM_OFF_MSIX_VEC_PER_PF_MAX, BNXT_NVM_SHARED_CFG, 10, 4}, 794 {DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN, 795 NVM_OFF_MSIX_VEC_PER_PF_MIN, BNXT_NVM_SHARED_CFG, 7, 4}, 796 {BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK, NVM_OFF_DIS_GRE_VER_CHECK, 797 BNXT_NVM_SHARED_CFG, 1, 1}, 798 }; 799 800 union bnxt_nvm_data { 801 u8 val8; 802 __le32 val32; 803 }; 804 805 static void bnxt_copy_to_nvm_data(union bnxt_nvm_data *dst, 806 union devlink_param_value *src, 807 int nvm_num_bits, int dl_num_bytes) 808 { 809 u32 val32 = 0; 810 811 if (nvm_num_bits == 1) { 812 dst->val8 = src->vbool; 813 return; 814 } 815 if (dl_num_bytes == 4) 816 val32 = src->vu32; 817 else if (dl_num_bytes == 2) 818 val32 = (u32)src->vu16; 819 else if (dl_num_bytes == 1) 820 val32 = (u32)src->vu8; 821 dst->val32 = cpu_to_le32(val32); 822 } 823 824 static void bnxt_copy_from_nvm_data(union devlink_param_value *dst, 825 union bnxt_nvm_data *src, 826 int nvm_num_bits, int dl_num_bytes) 827 { 828 u32 val32; 829 830 if (nvm_num_bits == 1) { 831 dst->vbool = src->val8; 832 return; 833 } 834 val32 = le32_to_cpu(src->val32); 835 if (dl_num_bytes == 4) 836 dst->vu32 = val32; 837 else if (dl_num_bytes == 2) 838 dst->vu16 = (u16)val32; 839 else if (dl_num_bytes == 1) 840 dst->vu8 = (u8)val32; 841 } 842 843 static int bnxt_hwrm_get_nvm_cfg_ver(struct bnxt *bp, u32 *nvm_cfg_ver) 844 { 845 struct hwrm_nvm_get_variable_input *req; 846 u16 bytes = BNXT_NVM_CFG_VER_BYTES; 847 u16 bits = BNXT_NVM_CFG_VER_BITS; 848 union devlink_param_value ver; 849 union bnxt_nvm_data *data; 850 dma_addr_t data_dma_addr; 851 int rc, i = 2; 852 u16 dim = 1; 853 854 rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE); 855 if (rc) 856 return rc; 857 858 data = hwrm_req_dma_slice(bp, req, sizeof(*data), &data_dma_addr); 859 if (!data) { 860 rc = -ENOMEM; 861 goto exit; 862 } 863 864 /* earlier devices present as an array of raw bytes */ 865 if (!BNXT_CHIP_P5(bp)) { 866 dim = 0; 867 i = 0; 868 bits *= 3; /* array of 3 version components */ 869 bytes *= 4; /* copy whole word */ 870 } 871 872 hwrm_req_hold(bp, req); 873 req->dest_data_addr = cpu_to_le64(data_dma_addr); 874 req->data_len = cpu_to_le16(bits); 875 req->option_num = cpu_to_le16(NVM_OFF_NVM_CFG_VER); 876 req->dimensions = cpu_to_le16(dim); 877 878 while (i >= 0) { 879 req->index_0 = cpu_to_le16(i--); 880 rc = hwrm_req_send_silent(bp, req); 881 if (rc) 882 goto exit; 883 bnxt_copy_from_nvm_data(&ver, data, bits, bytes); 884 885 if (BNXT_CHIP_P5(bp)) { 886 *nvm_cfg_ver <<= 8; 887 *nvm_cfg_ver |= ver.vu8; 888 } else { 889 *nvm_cfg_ver = ver.vu32; 890 } 891 } 892 893 exit: 894 hwrm_req_drop(bp, req); 895 return rc; 896 } 897 898 static int bnxt_dl_info_put(struct bnxt *bp, struct devlink_info_req *req, 899 enum bnxt_dl_version_type type, const char *key, 900 char *buf) 901 { 902 if (!strlen(buf)) 903 return 0; 904 905 if ((bp->flags & BNXT_FLAG_CHIP_P5) && 906 (!strcmp(key, DEVLINK_INFO_VERSION_GENERIC_FW_NCSI) || 907 !strcmp(key, DEVLINK_INFO_VERSION_GENERIC_FW_ROCE))) 908 return 0; 909 910 switch (type) { 911 case BNXT_VERSION_FIXED: 912 return devlink_info_version_fixed_put(req, key, buf); 913 case BNXT_VERSION_RUNNING: 914 return devlink_info_version_running_put(req, key, buf); 915 case BNXT_VERSION_STORED: 916 return devlink_info_version_stored_put(req, key, buf); 917 } 918 return 0; 919 } 920 921 #define BNXT_FW_SRT_PATCH "fw.srt.patch" 922 #define BNXT_FW_CRT_PATCH "fw.crt.patch" 923 924 static int bnxt_dl_livepatch_info_put(struct bnxt *bp, 925 struct devlink_info_req *req, 926 const char *key) 927 { 928 struct hwrm_fw_livepatch_query_input *query; 929 struct hwrm_fw_livepatch_query_output *resp; 930 u16 flags; 931 int rc; 932 933 if (~bp->fw_cap & BNXT_FW_CAP_LIVEPATCH) 934 return 0; 935 936 rc = hwrm_req_init(bp, query, HWRM_FW_LIVEPATCH_QUERY); 937 if (rc) 938 return rc; 939 940 if (!strcmp(key, BNXT_FW_SRT_PATCH)) 941 query->fw_target = FW_LIVEPATCH_QUERY_REQ_FW_TARGET_SECURE_FW; 942 else if (!strcmp(key, BNXT_FW_CRT_PATCH)) 943 query->fw_target = FW_LIVEPATCH_QUERY_REQ_FW_TARGET_COMMON_FW; 944 else 945 goto exit; 946 947 resp = hwrm_req_hold(bp, query); 948 rc = hwrm_req_send(bp, query); 949 if (rc) 950 goto exit; 951 952 flags = le16_to_cpu(resp->status_flags); 953 if (flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE) { 954 resp->active_ver[sizeof(resp->active_ver) - 1] = '\0'; 955 rc = devlink_info_version_running_put(req, key, resp->active_ver); 956 if (rc) 957 goto exit; 958 } 959 960 if (flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL) { 961 resp->install_ver[sizeof(resp->install_ver) - 1] = '\0'; 962 rc = devlink_info_version_stored_put(req, key, resp->install_ver); 963 if (rc) 964 goto exit; 965 } 966 967 exit: 968 hwrm_req_drop(bp, query); 969 return rc; 970 } 971 972 #define HWRM_FW_VER_STR_LEN 16 973 974 static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req, 975 struct netlink_ext_ack *extack) 976 { 977 struct hwrm_nvm_get_dev_info_output nvm_dev_info; 978 struct bnxt *bp = bnxt_get_bp_from_dl(dl); 979 struct hwrm_ver_get_output *ver_resp; 980 char mgmt_ver[FW_VER_STR_LEN]; 981 char roce_ver[FW_VER_STR_LEN]; 982 char ncsi_ver[FW_VER_STR_LEN]; 983 char buf[32]; 984 u32 ver = 0; 985 int rc; 986 987 rc = devlink_info_driver_name_put(req, DRV_MODULE_NAME); 988 if (rc) 989 return rc; 990 991 if (BNXT_PF(bp) && (bp->flags & BNXT_FLAG_DSN_VALID)) { 992 sprintf(buf, "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X", 993 bp->dsn[7], bp->dsn[6], bp->dsn[5], bp->dsn[4], 994 bp->dsn[3], bp->dsn[2], bp->dsn[1], bp->dsn[0]); 995 rc = devlink_info_serial_number_put(req, buf); 996 if (rc) 997 return rc; 998 } 999 1000 if (strlen(bp->board_serialno)) { 1001 rc = devlink_info_board_serial_number_put(req, bp->board_serialno); 1002 if (rc) 1003 return rc; 1004 } 1005 1006 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED, 1007 DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, 1008 bp->board_partno); 1009 if (rc) 1010 return rc; 1011 1012 sprintf(buf, "%X", bp->chip_num); 1013 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED, 1014 DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, buf); 1015 if (rc) 1016 return rc; 1017 1018 ver_resp = &bp->ver_resp; 1019 sprintf(buf, "%c%d", 'A' + ver_resp->chip_rev, ver_resp->chip_metal); 1020 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED, 1021 DEVLINK_INFO_VERSION_GENERIC_ASIC_REV, buf); 1022 if (rc) 1023 return rc; 1024 1025 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING, 1026 DEVLINK_INFO_VERSION_GENERIC_FW_PSID, 1027 bp->nvm_cfg_ver); 1028 if (rc) 1029 return rc; 1030 1031 buf[0] = 0; 1032 strncat(buf, ver_resp->active_pkg_name, HWRM_FW_VER_STR_LEN); 1033 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING, 1034 DEVLINK_INFO_VERSION_GENERIC_FW, buf); 1035 if (rc) 1036 return rc; 1037 1038 if (BNXT_PF(bp) && !bnxt_hwrm_get_nvm_cfg_ver(bp, &ver)) { 1039 sprintf(buf, "%d.%d.%d", (ver >> 16) & 0xff, (ver >> 8) & 0xff, 1040 ver & 0xff); 1041 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED, 1042 DEVLINK_INFO_VERSION_GENERIC_FW_PSID, 1043 buf); 1044 if (rc) 1045 return rc; 1046 } 1047 1048 if (ver_resp->flags & VER_GET_RESP_FLAGS_EXT_VER_AVAIL) { 1049 snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d", 1050 ver_resp->hwrm_fw_major, ver_resp->hwrm_fw_minor, 1051 ver_resp->hwrm_fw_build, ver_resp->hwrm_fw_patch); 1052 1053 snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d", 1054 ver_resp->mgmt_fw_major, ver_resp->mgmt_fw_minor, 1055 ver_resp->mgmt_fw_build, ver_resp->mgmt_fw_patch); 1056 1057 snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d", 1058 ver_resp->roce_fw_major, ver_resp->roce_fw_minor, 1059 ver_resp->roce_fw_build, ver_resp->roce_fw_patch); 1060 } else { 1061 snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d", 1062 ver_resp->hwrm_fw_maj_8b, ver_resp->hwrm_fw_min_8b, 1063 ver_resp->hwrm_fw_bld_8b, ver_resp->hwrm_fw_rsvd_8b); 1064 1065 snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d", 1066 ver_resp->mgmt_fw_maj_8b, ver_resp->mgmt_fw_min_8b, 1067 ver_resp->mgmt_fw_bld_8b, ver_resp->mgmt_fw_rsvd_8b); 1068 1069 snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d", 1070 ver_resp->roce_fw_maj_8b, ver_resp->roce_fw_min_8b, 1071 ver_resp->roce_fw_bld_8b, ver_resp->roce_fw_rsvd_8b); 1072 } 1073 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING, 1074 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, mgmt_ver); 1075 if (rc) 1076 return rc; 1077 1078 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING, 1079 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API, 1080 bp->hwrm_ver_supp); 1081 if (rc) 1082 return rc; 1083 1084 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING, 1085 DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, ncsi_ver); 1086 if (rc) 1087 return rc; 1088 1089 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING, 1090 DEVLINK_INFO_VERSION_GENERIC_FW_ROCE, roce_ver); 1091 if (rc) 1092 return rc; 1093 1094 rc = bnxt_hwrm_nvm_get_dev_info(bp, &nvm_dev_info); 1095 if (rc || 1096 !(nvm_dev_info.flags & NVM_GET_DEV_INFO_RESP_FLAGS_FW_VER_VALID)) { 1097 if (!bnxt_get_pkginfo(bp->dev, buf, sizeof(buf))) 1098 return bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED, 1099 DEVLINK_INFO_VERSION_GENERIC_FW, 1100 buf); 1101 return 0; 1102 } 1103 1104 buf[0] = 0; 1105 strncat(buf, nvm_dev_info.pkg_name, HWRM_FW_VER_STR_LEN); 1106 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED, 1107 DEVLINK_INFO_VERSION_GENERIC_FW, buf); 1108 if (rc) 1109 return rc; 1110 1111 snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d", 1112 nvm_dev_info.hwrm_fw_major, nvm_dev_info.hwrm_fw_minor, 1113 nvm_dev_info.hwrm_fw_build, nvm_dev_info.hwrm_fw_patch); 1114 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED, 1115 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, mgmt_ver); 1116 if (rc) 1117 return rc; 1118 1119 snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d", 1120 nvm_dev_info.mgmt_fw_major, nvm_dev_info.mgmt_fw_minor, 1121 nvm_dev_info.mgmt_fw_build, nvm_dev_info.mgmt_fw_patch); 1122 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED, 1123 DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, ncsi_ver); 1124 if (rc) 1125 return rc; 1126 1127 snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d", 1128 nvm_dev_info.roce_fw_major, nvm_dev_info.roce_fw_minor, 1129 nvm_dev_info.roce_fw_build, nvm_dev_info.roce_fw_patch); 1130 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED, 1131 DEVLINK_INFO_VERSION_GENERIC_FW_ROCE, roce_ver); 1132 if (rc) 1133 return rc; 1134 1135 rc = bnxt_dl_livepatch_info_put(bp, req, BNXT_FW_SRT_PATCH); 1136 if (rc) 1137 return rc; 1138 return bnxt_dl_livepatch_info_put(bp, req, BNXT_FW_CRT_PATCH); 1139 1140 } 1141 1142 static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, 1143 union devlink_param_value *val) 1144 { 1145 struct hwrm_nvm_get_variable_input *req = msg; 1146 struct bnxt_dl_nvm_param nvm_param; 1147 struct hwrm_err_output *resp; 1148 union bnxt_nvm_data *data; 1149 dma_addr_t data_dma_addr; 1150 int idx = 0, rc, i; 1151 1152 /* Get/Set NVM CFG parameter is supported only on PFs */ 1153 if (BNXT_VF(bp)) { 1154 hwrm_req_drop(bp, req); 1155 return -EPERM; 1156 } 1157 1158 for (i = 0; i < ARRAY_SIZE(nvm_params); i++) { 1159 if (nvm_params[i].id == param_id) { 1160 nvm_param = nvm_params[i]; 1161 break; 1162 } 1163 } 1164 1165 if (i == ARRAY_SIZE(nvm_params)) { 1166 hwrm_req_drop(bp, req); 1167 return -EOPNOTSUPP; 1168 } 1169 1170 if (nvm_param.dir_type == BNXT_NVM_PORT_CFG) 1171 idx = bp->pf.port_id; 1172 else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG) 1173 idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID; 1174 1175 data = hwrm_req_dma_slice(bp, req, sizeof(*data), &data_dma_addr); 1176 1177 if (!data) { 1178 hwrm_req_drop(bp, req); 1179 return -ENOMEM; 1180 } 1181 1182 req->dest_data_addr = cpu_to_le64(data_dma_addr); 1183 req->data_len = cpu_to_le16(nvm_param.nvm_num_bits); 1184 req->option_num = cpu_to_le16(nvm_param.offset); 1185 req->index_0 = cpu_to_le16(idx); 1186 if (idx) 1187 req->dimensions = cpu_to_le16(1); 1188 1189 resp = hwrm_req_hold(bp, req); 1190 if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) { 1191 bnxt_copy_to_nvm_data(data, val, nvm_param.nvm_num_bits, 1192 nvm_param.dl_num_bytes); 1193 rc = hwrm_req_send(bp, msg); 1194 } else { 1195 rc = hwrm_req_send_silent(bp, msg); 1196 if (!rc) { 1197 bnxt_copy_from_nvm_data(val, data, 1198 nvm_param.nvm_num_bits, 1199 nvm_param.dl_num_bytes); 1200 } else { 1201 if (resp->cmd_err == 1202 NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST) 1203 rc = -EOPNOTSUPP; 1204 } 1205 } 1206 hwrm_req_drop(bp, req); 1207 if (rc == -EACCES) 1208 netdev_err(bp->dev, "PF does not have admin privileges to modify NVM config\n"); 1209 return rc; 1210 } 1211 1212 static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id, 1213 struct devlink_param_gset_ctx *ctx) 1214 { 1215 struct bnxt *bp = bnxt_get_bp_from_dl(dl); 1216 struct hwrm_nvm_get_variable_input *req; 1217 int rc; 1218 1219 rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE); 1220 if (rc) 1221 return rc; 1222 1223 rc = bnxt_hwrm_nvm_req(bp, id, req, &ctx->val); 1224 if (!rc && id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK) 1225 ctx->val.vbool = !ctx->val.vbool; 1226 1227 return rc; 1228 } 1229 1230 static int bnxt_dl_nvm_param_set(struct devlink *dl, u32 id, 1231 struct devlink_param_gset_ctx *ctx) 1232 { 1233 struct bnxt *bp = bnxt_get_bp_from_dl(dl); 1234 struct hwrm_nvm_set_variable_input *req; 1235 int rc; 1236 1237 rc = hwrm_req_init(bp, req, HWRM_NVM_SET_VARIABLE); 1238 if (rc) 1239 return rc; 1240 1241 if (id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK) 1242 ctx->val.vbool = !ctx->val.vbool; 1243 1244 return bnxt_hwrm_nvm_req(bp, id, req, &ctx->val); 1245 } 1246 1247 static int bnxt_dl_msix_validate(struct devlink *dl, u32 id, 1248 union devlink_param_value val, 1249 struct netlink_ext_ack *extack) 1250 { 1251 int max_val = -1; 1252 1253 if (id == DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX) 1254 max_val = BNXT_MSIX_VEC_MAX; 1255 1256 if (id == DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN) 1257 max_val = BNXT_MSIX_VEC_MIN_MAX; 1258 1259 if (val.vu32 > max_val) { 1260 NL_SET_ERR_MSG_MOD(extack, "MSIX value is exceeding the range"); 1261 return -EINVAL; 1262 } 1263 1264 return 0; 1265 } 1266 1267 static int bnxt_remote_dev_reset_get(struct devlink *dl, u32 id, 1268 struct devlink_param_gset_ctx *ctx) 1269 { 1270 struct bnxt *bp = bnxt_get_bp_from_dl(dl); 1271 1272 if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF) 1273 return -EOPNOTSUPP; 1274 1275 ctx->val.vbool = bnxt_dl_get_remote_reset(dl); 1276 return 0; 1277 } 1278 1279 static int bnxt_remote_dev_reset_set(struct devlink *dl, u32 id, 1280 struct devlink_param_gset_ctx *ctx) 1281 { 1282 struct bnxt *bp = bnxt_get_bp_from_dl(dl); 1283 int rc; 1284 1285 rc = bnxt_hwrm_remote_dev_reset_set(bp, ctx->val.vbool); 1286 if (rc) 1287 return rc; 1288 1289 bnxt_dl_set_remote_reset(dl, ctx->val.vbool); 1290 return rc; 1291 } 1292 1293 static const struct devlink_param bnxt_dl_params[] = { 1294 DEVLINK_PARAM_GENERIC(ENABLE_SRIOV, 1295 BIT(DEVLINK_PARAM_CMODE_PERMANENT), 1296 bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set, 1297 NULL), 1298 DEVLINK_PARAM_GENERIC(IGNORE_ARI, 1299 BIT(DEVLINK_PARAM_CMODE_PERMANENT), 1300 bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set, 1301 NULL), 1302 DEVLINK_PARAM_GENERIC(MSIX_VEC_PER_PF_MAX, 1303 BIT(DEVLINK_PARAM_CMODE_PERMANENT), 1304 bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set, 1305 bnxt_dl_msix_validate), 1306 DEVLINK_PARAM_GENERIC(MSIX_VEC_PER_PF_MIN, 1307 BIT(DEVLINK_PARAM_CMODE_PERMANENT), 1308 bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set, 1309 bnxt_dl_msix_validate), 1310 DEVLINK_PARAM_DRIVER(BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK, 1311 "gre_ver_check", DEVLINK_PARAM_TYPE_BOOL, 1312 BIT(DEVLINK_PARAM_CMODE_PERMANENT), 1313 bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set, 1314 NULL), 1315 /* keep REMOTE_DEV_RESET last, it is excluded based on caps */ 1316 DEVLINK_PARAM_GENERIC(ENABLE_REMOTE_DEV_RESET, 1317 BIT(DEVLINK_PARAM_CMODE_RUNTIME), 1318 bnxt_remote_dev_reset_get, 1319 bnxt_remote_dev_reset_set, NULL), 1320 }; 1321 1322 static int bnxt_dl_params_register(struct bnxt *bp) 1323 { 1324 int num_params = ARRAY_SIZE(bnxt_dl_params); 1325 int rc; 1326 1327 if (bp->hwrm_spec_code < 0x10600) 1328 return 0; 1329 1330 if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF) 1331 num_params--; 1332 1333 rc = devlink_params_register(bp->dl, bnxt_dl_params, num_params); 1334 if (rc) 1335 netdev_warn(bp->dev, "devlink_params_register failed. rc=%d\n", 1336 rc); 1337 return rc; 1338 } 1339 1340 static void bnxt_dl_params_unregister(struct bnxt *bp) 1341 { 1342 int num_params = ARRAY_SIZE(bnxt_dl_params); 1343 1344 if (bp->hwrm_spec_code < 0x10600) 1345 return; 1346 1347 if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF) 1348 num_params--; 1349 1350 devlink_params_unregister(bp->dl, bnxt_dl_params, num_params); 1351 } 1352 1353 int bnxt_dl_register(struct bnxt *bp) 1354 { 1355 const struct devlink_ops *devlink_ops; 1356 struct devlink_port_attrs attrs = {}; 1357 struct bnxt_dl *bp_dl; 1358 struct devlink *dl; 1359 int rc; 1360 1361 if (BNXT_PF(bp)) 1362 devlink_ops = &bnxt_dl_ops; 1363 else 1364 devlink_ops = &bnxt_vf_dl_ops; 1365 1366 dl = devlink_alloc(devlink_ops, sizeof(struct bnxt_dl), &bp->pdev->dev); 1367 if (!dl) { 1368 netdev_warn(bp->dev, "devlink_alloc failed\n"); 1369 return -ENOMEM; 1370 } 1371 1372 bp->dl = dl; 1373 bp_dl = devlink_priv(dl); 1374 bp_dl->bp = bp; 1375 bnxt_dl_set_remote_reset(dl, true); 1376 1377 /* Add switchdev eswitch mode setting, if SRIOV supported */ 1378 if (pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV) && 1379 bp->hwrm_spec_code > 0x10803) 1380 bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY; 1381 1382 if (!BNXT_PF(bp)) 1383 goto out; 1384 1385 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 1386 attrs.phys.port_number = bp->pf.port_id; 1387 memcpy(attrs.switch_id.id, bp->dsn, sizeof(bp->dsn)); 1388 attrs.switch_id.id_len = sizeof(bp->dsn); 1389 devlink_port_attrs_set(&bp->dl_port, &attrs); 1390 rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id); 1391 if (rc) { 1392 netdev_err(bp->dev, "devlink_port_register failed\n"); 1393 goto err_dl_free; 1394 } 1395 1396 rc = bnxt_dl_params_register(bp); 1397 if (rc) 1398 goto err_dl_port_unreg; 1399 1400 out: 1401 devlink_register(dl); 1402 return 0; 1403 1404 err_dl_port_unreg: 1405 devlink_port_unregister(&bp->dl_port); 1406 err_dl_free: 1407 devlink_free(dl); 1408 return rc; 1409 } 1410 1411 void bnxt_dl_unregister(struct bnxt *bp) 1412 { 1413 struct devlink *dl = bp->dl; 1414 1415 devlink_unregister(dl); 1416 if (BNXT_PF(bp)) { 1417 bnxt_dl_params_unregister(bp); 1418 devlink_port_unregister(&bp->dl_port); 1419 } 1420 devlink_free(dl); 1421 } 1422