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