0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/pci.h>
0011 #include <linux/netdevice.h>
0012 #include <linux/vmalloc.h>
0013 #include <net/devlink.h>
0014 #include "bnxt_hsi.h"
0015 #include "bnxt.h"
0016 #include "bnxt_hwrm.h"
0017 #include "bnxt_vfr.h"
0018 #include "bnxt_devlink.h"
0019 #include "bnxt_ethtool.h"
0020 #include "bnxt_ulp.h"
0021 #include "bnxt_ptp.h"
0022 #include "bnxt_coredump.h"
0023 #include "bnxt_nvm_defs.h"
0024
0025 static void __bnxt_fw_recover(struct bnxt *bp)
0026 {
0027 if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) ||
0028 test_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state))
0029 bnxt_fw_reset(bp);
0030 else
0031 bnxt_fw_exception(bp);
0032 }
0033
0034 static int
0035 bnxt_dl_flash_update(struct devlink *dl,
0036 struct devlink_flash_update_params *params,
0037 struct netlink_ext_ack *extack)
0038 {
0039 struct bnxt *bp = bnxt_get_bp_from_dl(dl);
0040 int rc;
0041
0042 if (!BNXT_PF(bp)) {
0043 NL_SET_ERR_MSG_MOD(extack,
0044 "flash update not supported from a VF");
0045 return -EPERM;
0046 }
0047
0048 devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);
0049 rc = bnxt_flash_package_from_fw_obj(bp->dev, params->fw, 0, extack);
0050 if (!rc)
0051 devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0);
0052 else
0053 devlink_flash_update_status_notify(dl, "Flashing failed", NULL, 0, 0);
0054 return rc;
0055 }
0056
0057 static int bnxt_hwrm_remote_dev_reset_set(struct bnxt *bp, bool remote_reset)
0058 {
0059 struct hwrm_func_cfg_input *req;
0060 int rc;
0061
0062 if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
0063 return -EOPNOTSUPP;
0064
0065 rc = hwrm_req_init(bp, req, HWRM_FUNC_CFG);
0066 if (rc)
0067 return rc;
0068
0069 req->fid = cpu_to_le16(0xffff);
0070 req->enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_HOT_RESET_IF_SUPPORT);
0071 if (remote_reset)
0072 req->flags = cpu_to_le32(FUNC_CFG_REQ_FLAGS_HOT_RESET_IF_EN_DIS);
0073
0074 return hwrm_req_send(bp, req);
0075 }
0076
0077 static char *bnxt_health_severity_str(enum bnxt_health_severity severity)
0078 {
0079 switch (severity) {
0080 case SEVERITY_NORMAL: return "normal";
0081 case SEVERITY_WARNING: return "warning";
0082 case SEVERITY_RECOVERABLE: return "recoverable";
0083 case SEVERITY_FATAL: return "fatal";
0084 default: return "unknown";
0085 }
0086 }
0087
0088 static char *bnxt_health_remedy_str(enum bnxt_health_remedy remedy)
0089 {
0090 switch (remedy) {
0091 case REMEDY_DEVLINK_RECOVER: return "devlink recover";
0092 case REMEDY_POWER_CYCLE_DEVICE: return "device power cycle";
0093 case REMEDY_POWER_CYCLE_HOST: return "host power cycle";
0094 case REMEDY_FW_UPDATE: return "update firmware";
0095 case REMEDY_HW_REPLACE: return "replace hardware";
0096 default: return "unknown";
0097 }
0098 }
0099
0100 static int bnxt_fw_diagnose(struct devlink_health_reporter *reporter,
0101 struct devlink_fmsg *fmsg,
0102 struct netlink_ext_ack *extack)
0103 {
0104 struct bnxt *bp = devlink_health_reporter_priv(reporter);
0105 struct bnxt_fw_health *h = bp->fw_health;
0106 u32 fw_status, fw_resets;
0107 int rc;
0108
0109 if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
0110 return devlink_fmsg_string_pair_put(fmsg, "Status", "recovering");
0111
0112 if (!h->status_reliable)
0113 return devlink_fmsg_string_pair_put(fmsg, "Status", "unknown");
0114
0115 mutex_lock(&h->lock);
0116 fw_status = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG);
0117 if (BNXT_FW_IS_BOOTING(fw_status)) {
0118 rc = devlink_fmsg_string_pair_put(fmsg, "Status", "initializing");
0119 if (rc)
0120 goto unlock;
0121 } else if (h->severity || fw_status != BNXT_FW_STATUS_HEALTHY) {
0122 if (!h->severity) {
0123 h->severity = SEVERITY_FATAL;
0124 h->remedy = REMEDY_POWER_CYCLE_DEVICE;
0125 h->diagnoses++;
0126 devlink_health_report(h->fw_reporter,
0127 "FW error diagnosed", h);
0128 }
0129 rc = devlink_fmsg_string_pair_put(fmsg, "Status", "error");
0130 if (rc)
0131 goto unlock;
0132 rc = devlink_fmsg_u32_pair_put(fmsg, "Syndrome", fw_status);
0133 if (rc)
0134 goto unlock;
0135 } else {
0136 rc = devlink_fmsg_string_pair_put(fmsg, "Status", "healthy");
0137 if (rc)
0138 goto unlock;
0139 }
0140
0141 rc = devlink_fmsg_string_pair_put(fmsg, "Severity",
0142 bnxt_health_severity_str(h->severity));
0143 if (rc)
0144 goto unlock;
0145
0146 if (h->severity) {
0147 rc = devlink_fmsg_string_pair_put(fmsg, "Remedy",
0148 bnxt_health_remedy_str(h->remedy));
0149 if (rc)
0150 goto unlock;
0151 if (h->remedy == REMEDY_DEVLINK_RECOVER) {
0152 rc = devlink_fmsg_string_pair_put(fmsg, "Impact",
0153 "traffic+ntuple_cfg");
0154 if (rc)
0155 goto unlock;
0156 }
0157 }
0158
0159 unlock:
0160 mutex_unlock(&h->lock);
0161 if (rc || !h->resets_reliable)
0162 return rc;
0163
0164 fw_resets = bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG);
0165 rc = devlink_fmsg_u32_pair_put(fmsg, "Resets", fw_resets);
0166 if (rc)
0167 return rc;
0168 rc = devlink_fmsg_u32_pair_put(fmsg, "Arrests", h->arrests);
0169 if (rc)
0170 return rc;
0171 rc = devlink_fmsg_u32_pair_put(fmsg, "Survivals", h->survivals);
0172 if (rc)
0173 return rc;
0174 rc = devlink_fmsg_u32_pair_put(fmsg, "Discoveries", h->discoveries);
0175 if (rc)
0176 return rc;
0177 rc = devlink_fmsg_u32_pair_put(fmsg, "Fatalities", h->fatalities);
0178 if (rc)
0179 return rc;
0180 return devlink_fmsg_u32_pair_put(fmsg, "Diagnoses", h->diagnoses);
0181 }
0182
0183 static int bnxt_fw_dump(struct devlink_health_reporter *reporter,
0184 struct devlink_fmsg *fmsg, void *priv_ctx,
0185 struct netlink_ext_ack *extack)
0186 {
0187 struct bnxt *bp = devlink_health_reporter_priv(reporter);
0188 u32 dump_len;
0189 void *data;
0190 int rc;
0191
0192
0193 if (priv_ctx)
0194 return -EOPNOTSUPP;
0195
0196 dump_len = bnxt_get_coredump_length(bp, BNXT_DUMP_LIVE);
0197 if (!dump_len)
0198 return -EIO;
0199
0200 data = vmalloc(dump_len);
0201 if (!data)
0202 return -ENOMEM;
0203
0204 rc = bnxt_get_coredump(bp, BNXT_DUMP_LIVE, data, &dump_len);
0205 if (!rc) {
0206 rc = devlink_fmsg_pair_nest_start(fmsg, "core");
0207 if (rc)
0208 goto exit;
0209 rc = devlink_fmsg_binary_pair_put(fmsg, "data", data, dump_len);
0210 if (rc)
0211 goto exit;
0212 rc = devlink_fmsg_u32_pair_put(fmsg, "size", dump_len);
0213 if (rc)
0214 goto exit;
0215 rc = devlink_fmsg_pair_nest_end(fmsg);
0216 }
0217
0218 exit:
0219 vfree(data);
0220 return rc;
0221 }
0222
0223 static int bnxt_fw_recover(struct devlink_health_reporter *reporter,
0224 void *priv_ctx,
0225 struct netlink_ext_ack *extack)
0226 {
0227 struct bnxt *bp = devlink_health_reporter_priv(reporter);
0228
0229 if (bp->fw_health->severity == SEVERITY_FATAL)
0230 return -ENODEV;
0231
0232 set_bit(BNXT_STATE_RECOVER, &bp->state);
0233 __bnxt_fw_recover(bp);
0234
0235 return -EINPROGRESS;
0236 }
0237
0238 static const struct devlink_health_reporter_ops bnxt_dl_fw_reporter_ops = {
0239 .name = "fw",
0240 .diagnose = bnxt_fw_diagnose,
0241 .dump = bnxt_fw_dump,
0242 .recover = bnxt_fw_recover,
0243 };
0244
0245 static struct devlink_health_reporter *
0246 __bnxt_dl_reporter_create(struct bnxt *bp,
0247 const struct devlink_health_reporter_ops *ops)
0248 {
0249 struct devlink_health_reporter *reporter;
0250
0251 reporter = devlink_health_reporter_create(bp->dl, ops, 0, bp);
0252 if (IS_ERR(reporter)) {
0253 netdev_warn(bp->dev, "Failed to create %s health reporter, rc = %ld\n",
0254 ops->name, PTR_ERR(reporter));
0255 return NULL;
0256 }
0257
0258 return reporter;
0259 }
0260
0261 void bnxt_dl_fw_reporters_create(struct bnxt *bp)
0262 {
0263 struct bnxt_fw_health *fw_health = bp->fw_health;
0264
0265 if (fw_health && !fw_health->fw_reporter)
0266 fw_health->fw_reporter = __bnxt_dl_reporter_create(bp, &bnxt_dl_fw_reporter_ops);
0267 }
0268
0269 void bnxt_dl_fw_reporters_destroy(struct bnxt *bp)
0270 {
0271 struct bnxt_fw_health *fw_health = bp->fw_health;
0272
0273 if (fw_health && fw_health->fw_reporter) {
0274 devlink_health_reporter_destroy(fw_health->fw_reporter);
0275 fw_health->fw_reporter = NULL;
0276 }
0277 }
0278
0279 void bnxt_devlink_health_fw_report(struct bnxt *bp)
0280 {
0281 struct bnxt_fw_health *fw_health = bp->fw_health;
0282 int rc;
0283
0284 if (!fw_health)
0285 return;
0286
0287 if (!fw_health->fw_reporter) {
0288 __bnxt_fw_recover(bp);
0289 return;
0290 }
0291
0292 mutex_lock(&fw_health->lock);
0293 fw_health->severity = SEVERITY_RECOVERABLE;
0294 fw_health->remedy = REMEDY_DEVLINK_RECOVER;
0295 mutex_unlock(&fw_health->lock);
0296 rc = devlink_health_report(fw_health->fw_reporter, "FW error reported",
0297 fw_health);
0298 if (rc == -ECANCELED)
0299 __bnxt_fw_recover(bp);
0300 }
0301
0302 void bnxt_dl_health_fw_status_update(struct bnxt *bp, bool healthy)
0303 {
0304 struct bnxt_fw_health *fw_health = bp->fw_health;
0305 u8 state;
0306
0307 mutex_lock(&fw_health->lock);
0308 if (healthy) {
0309 fw_health->severity = SEVERITY_NORMAL;
0310 state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
0311 } else {
0312 fw_health->severity = SEVERITY_FATAL;
0313 fw_health->remedy = REMEDY_POWER_CYCLE_DEVICE;
0314 state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
0315 }
0316 mutex_unlock(&fw_health->lock);
0317 devlink_health_reporter_state_update(fw_health->fw_reporter, state);
0318 }
0319
0320 void bnxt_dl_health_fw_recovery_done(struct bnxt *bp)
0321 {
0322 struct bnxt_dl *dl = devlink_priv(bp->dl);
0323
0324 devlink_health_reporter_recovery_done(bp->fw_health->fw_reporter);
0325 bnxt_hwrm_remote_dev_reset_set(bp, dl->remote_reset);
0326 }
0327
0328 static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
0329 struct netlink_ext_ack *extack);
0330
0331 static void
0332 bnxt_dl_livepatch_report_err(struct bnxt *bp, struct netlink_ext_ack *extack,
0333 struct hwrm_fw_livepatch_output *resp)
0334 {
0335 int err = ((struct hwrm_err_output *)resp)->cmd_err;
0336
0337 switch (err) {
0338 case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_OPCODE:
0339 netdev_err(bp->dev, "Illegal live patch opcode");
0340 NL_SET_ERR_MSG_MOD(extack, "Invalid opcode");
0341 break;
0342 case FW_LIVEPATCH_CMD_ERR_CODE_NOT_SUPPORTED:
0343 NL_SET_ERR_MSG_MOD(extack, "Live patch operation not supported");
0344 break;
0345 case FW_LIVEPATCH_CMD_ERR_CODE_NOT_INSTALLED:
0346 NL_SET_ERR_MSG_MOD(extack, "Live patch not found");
0347 break;
0348 case FW_LIVEPATCH_CMD_ERR_CODE_NOT_PATCHED:
0349 NL_SET_ERR_MSG_MOD(extack,
0350 "Live patch deactivation failed. Firmware not patched.");
0351 break;
0352 case FW_LIVEPATCH_CMD_ERR_CODE_AUTH_FAIL:
0353 NL_SET_ERR_MSG_MOD(extack, "Live patch not authenticated");
0354 break;
0355 case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_HEADER:
0356 NL_SET_ERR_MSG_MOD(extack, "Incompatible live patch");
0357 break;
0358 case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_SIZE:
0359 NL_SET_ERR_MSG_MOD(extack, "Live patch has invalid size");
0360 break;
0361 case FW_LIVEPATCH_CMD_ERR_CODE_ALREADY_PATCHED:
0362 NL_SET_ERR_MSG_MOD(extack, "Live patch already applied");
0363 break;
0364 default:
0365 netdev_err(bp->dev, "Unexpected live patch error: %d\n", err);
0366 NL_SET_ERR_MSG_MOD(extack, "Failed to activate live patch");
0367 break;
0368 }
0369 }
0370
0371
0372 #define BNXT_LIVEPATCH_NOT_INSTALLED 0
0373 #define BNXT_LIVEPATCH_INSTALLED FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL
0374 #define BNXT_LIVEPATCH_REMOVED FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE
0375 #define BNXT_LIVEPATCH_MASK (FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL | \
0376 FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE)
0377 #define BNXT_LIVEPATCH_ACTIVATED BNXT_LIVEPATCH_MASK
0378
0379 #define BNXT_LIVEPATCH_STATE(flags) ((flags) & BNXT_LIVEPATCH_MASK)
0380
0381 static int
0382 bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
0383 {
0384 struct hwrm_fw_livepatch_query_output *query_resp;
0385 struct hwrm_fw_livepatch_query_input *query_req;
0386 struct hwrm_fw_livepatch_output *patch_resp;
0387 struct hwrm_fw_livepatch_input *patch_req;
0388 u16 flags, live_patch_state;
0389 bool activated = false;
0390 u32 installed = 0;
0391 u8 target;
0392 int rc;
0393
0394 if (~bp->fw_cap & BNXT_FW_CAP_LIVEPATCH) {
0395 NL_SET_ERR_MSG_MOD(extack, "Device does not support live patch");
0396 return -EOPNOTSUPP;
0397 }
0398
0399 rc = hwrm_req_init(bp, query_req, HWRM_FW_LIVEPATCH_QUERY);
0400 if (rc)
0401 return rc;
0402 query_resp = hwrm_req_hold(bp, query_req);
0403
0404 rc = hwrm_req_init(bp, patch_req, HWRM_FW_LIVEPATCH);
0405 if (rc) {
0406 hwrm_req_drop(bp, query_req);
0407 return rc;
0408 }
0409 patch_req->loadtype = FW_LIVEPATCH_REQ_LOADTYPE_NVM_INSTALL;
0410 patch_resp = hwrm_req_hold(bp, patch_req);
0411
0412 for (target = 1; target <= FW_LIVEPATCH_REQ_FW_TARGET_LAST; target++) {
0413 query_req->fw_target = target;
0414 rc = hwrm_req_send(bp, query_req);
0415 if (rc) {
0416 NL_SET_ERR_MSG_MOD(extack, "Failed to query packages");
0417 break;
0418 }
0419
0420 flags = le16_to_cpu(query_resp->status_flags);
0421 live_patch_state = BNXT_LIVEPATCH_STATE(flags);
0422
0423 if (live_patch_state == BNXT_LIVEPATCH_NOT_INSTALLED)
0424 continue;
0425
0426 if (live_patch_state == BNXT_LIVEPATCH_ACTIVATED) {
0427 activated = true;
0428 continue;
0429 }
0430
0431 if (live_patch_state == BNXT_LIVEPATCH_INSTALLED)
0432 patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_ACTIVATE;
0433 else if (live_patch_state == BNXT_LIVEPATCH_REMOVED)
0434 patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_DEACTIVATE;
0435
0436 patch_req->fw_target = target;
0437 rc = hwrm_req_send(bp, patch_req);
0438 if (rc) {
0439 bnxt_dl_livepatch_report_err(bp, extack, patch_resp);
0440 break;
0441 }
0442 installed++;
0443 }
0444
0445 if (!rc && !installed) {
0446 if (activated) {
0447 NL_SET_ERR_MSG_MOD(extack, "Live patch already activated");
0448 rc = -EEXIST;
0449 } else {
0450 NL_SET_ERR_MSG_MOD(extack, "No live patches found");
0451 rc = -ENOENT;
0452 }
0453 }
0454 hwrm_req_drop(bp, query_req);
0455 hwrm_req_drop(bp, patch_req);
0456 return rc;
0457 }
0458
0459 static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change,
0460 enum devlink_reload_action action,
0461 enum devlink_reload_limit limit,
0462 struct netlink_ext_ack *extack)
0463 {
0464 struct bnxt *bp = bnxt_get_bp_from_dl(dl);
0465 int rc = 0;
0466
0467 switch (action) {
0468 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: {
0469 rtnl_lock();
0470 if (bnxt_sriov_cfg(bp)) {
0471 NL_SET_ERR_MSG_MOD(extack,
0472 "reload is unsupported while VFs are allocated or being configured");
0473 rtnl_unlock();
0474 return -EOPNOTSUPP;
0475 }
0476 if (bp->dev->reg_state == NETREG_UNREGISTERED) {
0477 rtnl_unlock();
0478 return -ENODEV;
0479 }
0480 bnxt_ulp_stop(bp);
0481 if (netif_running(bp->dev)) {
0482 rc = bnxt_close_nic(bp, true, true);
0483 if (rc) {
0484 NL_SET_ERR_MSG_MOD(extack, "Failed to close");
0485 dev_close(bp->dev);
0486 rtnl_unlock();
0487 break;
0488 }
0489 }
0490 bnxt_vf_reps_free(bp);
0491 rc = bnxt_hwrm_func_drv_unrgtr(bp);
0492 if (rc) {
0493 NL_SET_ERR_MSG_MOD(extack, "Failed to deregister");
0494 if (netif_running(bp->dev))
0495 dev_close(bp->dev);
0496 rtnl_unlock();
0497 break;
0498 }
0499 bnxt_cancel_reservations(bp, false);
0500 bnxt_free_ctx_mem(bp);
0501 kfree(bp->ctx);
0502 bp->ctx = NULL;
0503 break;
0504 }
0505 case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: {
0506 if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
0507 return bnxt_dl_livepatch_activate(bp, extack);
0508 if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET) {
0509 NL_SET_ERR_MSG_MOD(extack, "Device not capable, requires reboot");
0510 return -EOPNOTSUPP;
0511 }
0512 if (!bnxt_hwrm_reset_permitted(bp)) {
0513 NL_SET_ERR_MSG_MOD(extack,
0514 "Reset denied by firmware, it may be inhibited by remote driver");
0515 return -EPERM;
0516 }
0517 rtnl_lock();
0518 if (bp->dev->reg_state == NETREG_UNREGISTERED) {
0519 rtnl_unlock();
0520 return -ENODEV;
0521 }
0522 if (netif_running(bp->dev))
0523 set_bit(BNXT_STATE_FW_ACTIVATE, &bp->state);
0524 rc = bnxt_hwrm_firmware_reset(bp->dev,
0525 FW_RESET_REQ_EMBEDDED_PROC_TYPE_CHIP,
0526 FW_RESET_REQ_SELFRST_STATUS_SELFRSTASAP,
0527 FW_RESET_REQ_FLAGS_RESET_GRACEFUL |
0528 FW_RESET_REQ_FLAGS_FW_ACTIVATION);
0529 if (rc) {
0530 NL_SET_ERR_MSG_MOD(extack, "Failed to activate firmware");
0531 clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state);
0532 rtnl_unlock();
0533 }
0534 break;
0535 }
0536 default:
0537 rc = -EOPNOTSUPP;
0538 }
0539
0540 return rc;
0541 }
0542
0543 static int bnxt_dl_reload_up(struct devlink *dl, enum devlink_reload_action action,
0544 enum devlink_reload_limit limit, u32 *actions_performed,
0545 struct netlink_ext_ack *extack)
0546 {
0547 struct bnxt *bp = bnxt_get_bp_from_dl(dl);
0548 int rc = 0;
0549
0550 *actions_performed = 0;
0551 switch (action) {
0552 case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: {
0553 bnxt_fw_init_one(bp);
0554 bnxt_vf_reps_alloc(bp);
0555 if (netif_running(bp->dev))
0556 rc = bnxt_open_nic(bp, true, true);
0557 bnxt_ulp_start(bp, rc);
0558 if (!rc) {
0559 bnxt_reenable_sriov(bp);
0560 bnxt_ptp_reapply_pps(bp);
0561 }
0562 break;
0563 }
0564 case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: {
0565 unsigned long start = jiffies;
0566 unsigned long timeout = start + BNXT_DFLT_FW_RST_MAX_DSECS * HZ / 10;
0567
0568 if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
0569 break;
0570 if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)
0571 timeout = start + bp->fw_health->normal_func_wait_dsecs * HZ / 10;
0572 if (!netif_running(bp->dev))
0573 NL_SET_ERR_MSG_MOD(extack,
0574 "Device is closed, not waiting for reset notice that will never come");
0575 rtnl_unlock();
0576 while (test_bit(BNXT_STATE_FW_ACTIVATE, &bp->state)) {
0577 if (time_after(jiffies, timeout)) {
0578 NL_SET_ERR_MSG_MOD(extack, "Activation incomplete");
0579 rc = -ETIMEDOUT;
0580 break;
0581 }
0582 if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) {
0583 NL_SET_ERR_MSG_MOD(extack, "Activation aborted");
0584 rc = -ENODEV;
0585 break;
0586 }
0587 msleep(50);
0588 }
0589 rtnl_lock();
0590 if (!rc)
0591 *actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
0592 clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state);
0593 break;
0594 }
0595 default:
0596 return -EOPNOTSUPP;
0597 }
0598
0599 if (!rc) {
0600 bnxt_print_device_info(bp);
0601 if (netif_running(bp->dev)) {
0602 mutex_lock(&bp->link_lock);
0603 bnxt_report_link(bp);
0604 mutex_unlock(&bp->link_lock);
0605 }
0606 *actions_performed |= BIT(action);
0607 } else if (netif_running(bp->dev)) {
0608 dev_close(bp->dev);
0609 }
0610 rtnl_unlock();
0611 return rc;
0612 }
0613
0614 static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack)
0615 {
0616 u32 datalen;
0617 u16 index;
0618 u8 *buf;
0619
0620 if (bnxt_find_nvram_item(bp->dev, BNX_DIR_TYPE_VPD,
0621 BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
0622 &index, NULL, &datalen) || !datalen) {
0623 NL_SET_ERR_MSG_MOD(extack, "nvm test vpd entry error");
0624 return false;
0625 }
0626
0627 buf = kzalloc(datalen, GFP_KERNEL);
0628 if (!buf) {
0629 NL_SET_ERR_MSG_MOD(extack, "insufficient memory for nvm test");
0630 return false;
0631 }
0632
0633 if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) {
0634 NL_SET_ERR_MSG_MOD(extack, "nvm test vpd read error");
0635 goto err;
0636 }
0637
0638 if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST,
0639 BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) {
0640 NL_SET_ERR_MSG_MOD(extack, "nvm test vpd write error");
0641 goto err;
0642 }
0643
0644 return true;
0645
0646 err:
0647 kfree(buf);
0648 return false;
0649 }
0650
0651 static bool bnxt_dl_selftest_check(struct devlink *dl, unsigned int id,
0652 struct netlink_ext_ack *extack)
0653 {
0654 return id == DEVLINK_ATTR_SELFTEST_ID_FLASH;
0655 }
0656
0657 static enum devlink_selftest_status bnxt_dl_selftest_run(struct devlink *dl,
0658 unsigned int id,
0659 struct netlink_ext_ack *extack)
0660 {
0661 struct bnxt *bp = bnxt_get_bp_from_dl(dl);
0662
0663 if (id == DEVLINK_ATTR_SELFTEST_ID_FLASH)
0664 return bnxt_nvm_test(bp, extack) ?
0665 DEVLINK_SELFTEST_STATUS_PASS :
0666 DEVLINK_SELFTEST_STATUS_FAIL;
0667
0668 return DEVLINK_SELFTEST_STATUS_SKIP;
0669 }
0670
0671 static const struct devlink_ops bnxt_dl_ops = {
0672 #ifdef CONFIG_BNXT_SRIOV
0673 .eswitch_mode_set = bnxt_dl_eswitch_mode_set,
0674 .eswitch_mode_get = bnxt_dl_eswitch_mode_get,
0675 #endif
0676 .info_get = bnxt_dl_info_get,
0677 .flash_update = bnxt_dl_flash_update,
0678 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
0679 BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
0680 .reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
0681 .reload_down = bnxt_dl_reload_down,
0682 .reload_up = bnxt_dl_reload_up,
0683 .selftest_check = bnxt_dl_selftest_check,
0684 .selftest_run = bnxt_dl_selftest_run,
0685 };
0686
0687 static const struct devlink_ops bnxt_vf_dl_ops;
0688
0689 enum bnxt_dl_param_id {
0690 BNXT_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
0691 BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK,
0692 };
0693
0694 static const struct bnxt_dl_nvm_param nvm_params[] = {
0695 {DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, NVM_OFF_ENABLE_SRIOV,
0696 BNXT_NVM_SHARED_CFG, 1, 1},
0697 {DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI, NVM_OFF_IGNORE_ARI,
0698 BNXT_NVM_SHARED_CFG, 1, 1},
0699 {DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
0700 NVM_OFF_MSIX_VEC_PER_PF_MAX, BNXT_NVM_SHARED_CFG, 10, 4},
0701 {DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
0702 NVM_OFF_MSIX_VEC_PER_PF_MIN, BNXT_NVM_SHARED_CFG, 7, 4},
0703 {BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK, NVM_OFF_DIS_GRE_VER_CHECK,
0704 BNXT_NVM_SHARED_CFG, 1, 1},
0705 };
0706
0707 union bnxt_nvm_data {
0708 u8 val8;
0709 __le32 val32;
0710 };
0711
0712 static void bnxt_copy_to_nvm_data(union bnxt_nvm_data *dst,
0713 union devlink_param_value *src,
0714 int nvm_num_bits, int dl_num_bytes)
0715 {
0716 u32 val32 = 0;
0717
0718 if (nvm_num_bits == 1) {
0719 dst->val8 = src->vbool;
0720 return;
0721 }
0722 if (dl_num_bytes == 4)
0723 val32 = src->vu32;
0724 else if (dl_num_bytes == 2)
0725 val32 = (u32)src->vu16;
0726 else if (dl_num_bytes == 1)
0727 val32 = (u32)src->vu8;
0728 dst->val32 = cpu_to_le32(val32);
0729 }
0730
0731 static void bnxt_copy_from_nvm_data(union devlink_param_value *dst,
0732 union bnxt_nvm_data *src,
0733 int nvm_num_bits, int dl_num_bytes)
0734 {
0735 u32 val32;
0736
0737 if (nvm_num_bits == 1) {
0738 dst->vbool = src->val8;
0739 return;
0740 }
0741 val32 = le32_to_cpu(src->val32);
0742 if (dl_num_bytes == 4)
0743 dst->vu32 = val32;
0744 else if (dl_num_bytes == 2)
0745 dst->vu16 = (u16)val32;
0746 else if (dl_num_bytes == 1)
0747 dst->vu8 = (u8)val32;
0748 }
0749
0750 static int bnxt_hwrm_get_nvm_cfg_ver(struct bnxt *bp, u32 *nvm_cfg_ver)
0751 {
0752 struct hwrm_nvm_get_variable_input *req;
0753 u16 bytes = BNXT_NVM_CFG_VER_BYTES;
0754 u16 bits = BNXT_NVM_CFG_VER_BITS;
0755 union devlink_param_value ver;
0756 union bnxt_nvm_data *data;
0757 dma_addr_t data_dma_addr;
0758 int rc, i = 2;
0759 u16 dim = 1;
0760
0761 rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE);
0762 if (rc)
0763 return rc;
0764
0765 data = hwrm_req_dma_slice(bp, req, sizeof(*data), &data_dma_addr);
0766 if (!data) {
0767 rc = -ENOMEM;
0768 goto exit;
0769 }
0770
0771
0772 if (!BNXT_CHIP_P5(bp)) {
0773 dim = 0;
0774 i = 0;
0775 bits *= 3;
0776 bytes *= 4;
0777 }
0778
0779 hwrm_req_hold(bp, req);
0780 req->dest_data_addr = cpu_to_le64(data_dma_addr);
0781 req->data_len = cpu_to_le16(bits);
0782 req->option_num = cpu_to_le16(NVM_OFF_NVM_CFG_VER);
0783 req->dimensions = cpu_to_le16(dim);
0784
0785 while (i >= 0) {
0786 req->index_0 = cpu_to_le16(i--);
0787 rc = hwrm_req_send_silent(bp, req);
0788 if (rc)
0789 goto exit;
0790 bnxt_copy_from_nvm_data(&ver, data, bits, bytes);
0791
0792 if (BNXT_CHIP_P5(bp)) {
0793 *nvm_cfg_ver <<= 8;
0794 *nvm_cfg_ver |= ver.vu8;
0795 } else {
0796 *nvm_cfg_ver = ver.vu32;
0797 }
0798 }
0799
0800 exit:
0801 hwrm_req_drop(bp, req);
0802 return rc;
0803 }
0804
0805 static int bnxt_dl_info_put(struct bnxt *bp, struct devlink_info_req *req,
0806 enum bnxt_dl_version_type type, const char *key,
0807 char *buf)
0808 {
0809 if (!strlen(buf))
0810 return 0;
0811
0812 if ((bp->flags & BNXT_FLAG_CHIP_P5) &&
0813 (!strcmp(key, DEVLINK_INFO_VERSION_GENERIC_FW_NCSI) ||
0814 !strcmp(key, DEVLINK_INFO_VERSION_GENERIC_FW_ROCE)))
0815 return 0;
0816
0817 switch (type) {
0818 case BNXT_VERSION_FIXED:
0819 return devlink_info_version_fixed_put(req, key, buf);
0820 case BNXT_VERSION_RUNNING:
0821 return devlink_info_version_running_put(req, key, buf);
0822 case BNXT_VERSION_STORED:
0823 return devlink_info_version_stored_put(req, key, buf);
0824 }
0825 return 0;
0826 }
0827
0828 #define BNXT_FW_SRT_PATCH "fw.srt.patch"
0829 #define BNXT_FW_CRT_PATCH "fw.crt.patch"
0830
0831 static int bnxt_dl_livepatch_info_put(struct bnxt *bp,
0832 struct devlink_info_req *req,
0833 const char *key)
0834 {
0835 struct hwrm_fw_livepatch_query_input *query;
0836 struct hwrm_fw_livepatch_query_output *resp;
0837 u16 flags;
0838 int rc;
0839
0840 if (~bp->fw_cap & BNXT_FW_CAP_LIVEPATCH)
0841 return 0;
0842
0843 rc = hwrm_req_init(bp, query, HWRM_FW_LIVEPATCH_QUERY);
0844 if (rc)
0845 return rc;
0846
0847 if (!strcmp(key, BNXT_FW_SRT_PATCH))
0848 query->fw_target = FW_LIVEPATCH_QUERY_REQ_FW_TARGET_SECURE_FW;
0849 else if (!strcmp(key, BNXT_FW_CRT_PATCH))
0850 query->fw_target = FW_LIVEPATCH_QUERY_REQ_FW_TARGET_COMMON_FW;
0851 else
0852 goto exit;
0853
0854 resp = hwrm_req_hold(bp, query);
0855 rc = hwrm_req_send(bp, query);
0856 if (rc)
0857 goto exit;
0858
0859 flags = le16_to_cpu(resp->status_flags);
0860 if (flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE) {
0861 resp->active_ver[sizeof(resp->active_ver) - 1] = '\0';
0862 rc = devlink_info_version_running_put(req, key, resp->active_ver);
0863 if (rc)
0864 goto exit;
0865 }
0866
0867 if (flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL) {
0868 resp->install_ver[sizeof(resp->install_ver) - 1] = '\0';
0869 rc = devlink_info_version_stored_put(req, key, resp->install_ver);
0870 if (rc)
0871 goto exit;
0872 }
0873
0874 exit:
0875 hwrm_req_drop(bp, query);
0876 return rc;
0877 }
0878
0879 #define HWRM_FW_VER_STR_LEN 16
0880
0881 static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
0882 struct netlink_ext_ack *extack)
0883 {
0884 struct hwrm_nvm_get_dev_info_output nvm_dev_info;
0885 struct bnxt *bp = bnxt_get_bp_from_dl(dl);
0886 struct hwrm_ver_get_output *ver_resp;
0887 char mgmt_ver[FW_VER_STR_LEN];
0888 char roce_ver[FW_VER_STR_LEN];
0889 char ncsi_ver[FW_VER_STR_LEN];
0890 char buf[32];
0891 u32 ver = 0;
0892 int rc;
0893
0894 rc = devlink_info_driver_name_put(req, DRV_MODULE_NAME);
0895 if (rc)
0896 return rc;
0897
0898 if (BNXT_PF(bp) && (bp->flags & BNXT_FLAG_DSN_VALID)) {
0899 sprintf(buf, "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X",
0900 bp->dsn[7], bp->dsn[6], bp->dsn[5], bp->dsn[4],
0901 bp->dsn[3], bp->dsn[2], bp->dsn[1], bp->dsn[0]);
0902 rc = devlink_info_serial_number_put(req, buf);
0903 if (rc)
0904 return rc;
0905 }
0906
0907 if (strlen(bp->board_serialno)) {
0908 rc = devlink_info_board_serial_number_put(req, bp->board_serialno);
0909 if (rc)
0910 return rc;
0911 }
0912
0913 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED,
0914 DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
0915 bp->board_partno);
0916 if (rc)
0917 return rc;
0918
0919 sprintf(buf, "%X", bp->chip_num);
0920 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED,
0921 DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, buf);
0922 if (rc)
0923 return rc;
0924
0925 ver_resp = &bp->ver_resp;
0926 sprintf(buf, "%c%d", 'A' + ver_resp->chip_rev, ver_resp->chip_metal);
0927 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED,
0928 DEVLINK_INFO_VERSION_GENERIC_ASIC_REV, buf);
0929 if (rc)
0930 return rc;
0931
0932 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
0933 DEVLINK_INFO_VERSION_GENERIC_FW_PSID,
0934 bp->nvm_cfg_ver);
0935 if (rc)
0936 return rc;
0937
0938 buf[0] = 0;
0939 strncat(buf, ver_resp->active_pkg_name, HWRM_FW_VER_STR_LEN);
0940 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
0941 DEVLINK_INFO_VERSION_GENERIC_FW, buf);
0942 if (rc)
0943 return rc;
0944
0945 if (BNXT_PF(bp) && !bnxt_hwrm_get_nvm_cfg_ver(bp, &ver)) {
0946 sprintf(buf, "%d.%d.%d", (ver >> 16) & 0xff, (ver >> 8) & 0xff,
0947 ver & 0xff);
0948 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
0949 DEVLINK_INFO_VERSION_GENERIC_FW_PSID,
0950 buf);
0951 if (rc)
0952 return rc;
0953 }
0954
0955 if (ver_resp->flags & VER_GET_RESP_FLAGS_EXT_VER_AVAIL) {
0956 snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
0957 ver_resp->hwrm_fw_major, ver_resp->hwrm_fw_minor,
0958 ver_resp->hwrm_fw_build, ver_resp->hwrm_fw_patch);
0959
0960 snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
0961 ver_resp->mgmt_fw_major, ver_resp->mgmt_fw_minor,
0962 ver_resp->mgmt_fw_build, ver_resp->mgmt_fw_patch);
0963
0964 snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
0965 ver_resp->roce_fw_major, ver_resp->roce_fw_minor,
0966 ver_resp->roce_fw_build, ver_resp->roce_fw_patch);
0967 } else {
0968 snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
0969 ver_resp->hwrm_fw_maj_8b, ver_resp->hwrm_fw_min_8b,
0970 ver_resp->hwrm_fw_bld_8b, ver_resp->hwrm_fw_rsvd_8b);
0971
0972 snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
0973 ver_resp->mgmt_fw_maj_8b, ver_resp->mgmt_fw_min_8b,
0974 ver_resp->mgmt_fw_bld_8b, ver_resp->mgmt_fw_rsvd_8b);
0975
0976 snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
0977 ver_resp->roce_fw_maj_8b, ver_resp->roce_fw_min_8b,
0978 ver_resp->roce_fw_bld_8b, ver_resp->roce_fw_rsvd_8b);
0979 }
0980 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
0981 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, mgmt_ver);
0982 if (rc)
0983 return rc;
0984
0985 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
0986 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API,
0987 bp->hwrm_ver_supp);
0988 if (rc)
0989 return rc;
0990
0991 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
0992 DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, ncsi_ver);
0993 if (rc)
0994 return rc;
0995
0996 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
0997 DEVLINK_INFO_VERSION_GENERIC_FW_ROCE, roce_ver);
0998 if (rc)
0999 return rc;
1000
1001 rc = bnxt_hwrm_nvm_get_dev_info(bp, &nvm_dev_info);
1002 if (rc ||
1003 !(nvm_dev_info.flags & NVM_GET_DEV_INFO_RESP_FLAGS_FW_VER_VALID)) {
1004 if (!bnxt_get_pkginfo(bp->dev, buf, sizeof(buf)))
1005 return bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
1006 DEVLINK_INFO_VERSION_GENERIC_FW,
1007 buf);
1008 return 0;
1009 }
1010
1011 buf[0] = 0;
1012 strncat(buf, nvm_dev_info.pkg_name, HWRM_FW_VER_STR_LEN);
1013 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
1014 DEVLINK_INFO_VERSION_GENERIC_FW, buf);
1015 if (rc)
1016 return rc;
1017
1018 snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
1019 nvm_dev_info.hwrm_fw_major, nvm_dev_info.hwrm_fw_minor,
1020 nvm_dev_info.hwrm_fw_build, nvm_dev_info.hwrm_fw_patch);
1021 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
1022 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, mgmt_ver);
1023 if (rc)
1024 return rc;
1025
1026 snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
1027 nvm_dev_info.mgmt_fw_major, nvm_dev_info.mgmt_fw_minor,
1028 nvm_dev_info.mgmt_fw_build, nvm_dev_info.mgmt_fw_patch);
1029 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
1030 DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, ncsi_ver);
1031 if (rc)
1032 return rc;
1033
1034 snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
1035 nvm_dev_info.roce_fw_major, nvm_dev_info.roce_fw_minor,
1036 nvm_dev_info.roce_fw_build, nvm_dev_info.roce_fw_patch);
1037 rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
1038 DEVLINK_INFO_VERSION_GENERIC_FW_ROCE, roce_ver);
1039 if (rc)
1040 return rc;
1041
1042 if (BNXT_CHIP_P5(bp)) {
1043 rc = bnxt_dl_livepatch_info_put(bp, req, BNXT_FW_SRT_PATCH);
1044 if (rc)
1045 return rc;
1046 }
1047 return bnxt_dl_livepatch_info_put(bp, req, BNXT_FW_CRT_PATCH);
1048
1049 }
1050
1051 static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
1052 union devlink_param_value *val)
1053 {
1054 struct hwrm_nvm_get_variable_input *req = msg;
1055 struct bnxt_dl_nvm_param nvm_param;
1056 struct hwrm_err_output *resp;
1057 union bnxt_nvm_data *data;
1058 dma_addr_t data_dma_addr;
1059 int idx = 0, rc, i;
1060
1061
1062 if (BNXT_VF(bp)) {
1063 hwrm_req_drop(bp, req);
1064 return -EPERM;
1065 }
1066
1067 for (i = 0; i < ARRAY_SIZE(nvm_params); i++) {
1068 if (nvm_params[i].id == param_id) {
1069 nvm_param = nvm_params[i];
1070 break;
1071 }
1072 }
1073
1074 if (i == ARRAY_SIZE(nvm_params)) {
1075 hwrm_req_drop(bp, req);
1076 return -EOPNOTSUPP;
1077 }
1078
1079 if (nvm_param.dir_type == BNXT_NVM_PORT_CFG)
1080 idx = bp->pf.port_id;
1081 else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG)
1082 idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID;
1083
1084 data = hwrm_req_dma_slice(bp, req, sizeof(*data), &data_dma_addr);
1085
1086 if (!data) {
1087 hwrm_req_drop(bp, req);
1088 return -ENOMEM;
1089 }
1090
1091 req->dest_data_addr = cpu_to_le64(data_dma_addr);
1092 req->data_len = cpu_to_le16(nvm_param.nvm_num_bits);
1093 req->option_num = cpu_to_le16(nvm_param.offset);
1094 req->index_0 = cpu_to_le16(idx);
1095 if (idx)
1096 req->dimensions = cpu_to_le16(1);
1097
1098 resp = hwrm_req_hold(bp, req);
1099 if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) {
1100 bnxt_copy_to_nvm_data(data, val, nvm_param.nvm_num_bits,
1101 nvm_param.dl_num_bytes);
1102 rc = hwrm_req_send(bp, msg);
1103 } else {
1104 rc = hwrm_req_send_silent(bp, msg);
1105 if (!rc) {
1106 bnxt_copy_from_nvm_data(val, data,
1107 nvm_param.nvm_num_bits,
1108 nvm_param.dl_num_bytes);
1109 } else {
1110 if (resp->cmd_err ==
1111 NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST)
1112 rc = -EOPNOTSUPP;
1113 }
1114 }
1115 hwrm_req_drop(bp, req);
1116 if (rc == -EACCES)
1117 netdev_err(bp->dev, "PF does not have admin privileges to modify NVM config\n");
1118 return rc;
1119 }
1120
1121 static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id,
1122 struct devlink_param_gset_ctx *ctx)
1123 {
1124 struct bnxt *bp = bnxt_get_bp_from_dl(dl);
1125 struct hwrm_nvm_get_variable_input *req;
1126 int rc;
1127
1128 rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE);
1129 if (rc)
1130 return rc;
1131
1132 rc = bnxt_hwrm_nvm_req(bp, id, req, &ctx->val);
1133 if (!rc && id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
1134 ctx->val.vbool = !ctx->val.vbool;
1135
1136 return rc;
1137 }
1138
1139 static int bnxt_dl_nvm_param_set(struct devlink *dl, u32 id,
1140 struct devlink_param_gset_ctx *ctx)
1141 {
1142 struct bnxt *bp = bnxt_get_bp_from_dl(dl);
1143 struct hwrm_nvm_set_variable_input *req;
1144 int rc;
1145
1146 rc = hwrm_req_init(bp, req, HWRM_NVM_SET_VARIABLE);
1147 if (rc)
1148 return rc;
1149
1150 if (id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
1151 ctx->val.vbool = !ctx->val.vbool;
1152
1153 return bnxt_hwrm_nvm_req(bp, id, req, &ctx->val);
1154 }
1155
1156 static int bnxt_dl_msix_validate(struct devlink *dl, u32 id,
1157 union devlink_param_value val,
1158 struct netlink_ext_ack *extack)
1159 {
1160 int max_val = -1;
1161
1162 if (id == DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX)
1163 max_val = BNXT_MSIX_VEC_MAX;
1164
1165 if (id == DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN)
1166 max_val = BNXT_MSIX_VEC_MIN_MAX;
1167
1168 if (val.vu32 > max_val) {
1169 NL_SET_ERR_MSG_MOD(extack, "MSIX value is exceeding the range");
1170 return -EINVAL;
1171 }
1172
1173 return 0;
1174 }
1175
1176 static int bnxt_remote_dev_reset_get(struct devlink *dl, u32 id,
1177 struct devlink_param_gset_ctx *ctx)
1178 {
1179 struct bnxt *bp = bnxt_get_bp_from_dl(dl);
1180
1181 if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
1182 return -EOPNOTSUPP;
1183
1184 ctx->val.vbool = bnxt_dl_get_remote_reset(dl);
1185 return 0;
1186 }
1187
1188 static int bnxt_remote_dev_reset_set(struct devlink *dl, u32 id,
1189 struct devlink_param_gset_ctx *ctx)
1190 {
1191 struct bnxt *bp = bnxt_get_bp_from_dl(dl);
1192 int rc;
1193
1194 rc = bnxt_hwrm_remote_dev_reset_set(bp, ctx->val.vbool);
1195 if (rc)
1196 return rc;
1197
1198 bnxt_dl_set_remote_reset(dl, ctx->val.vbool);
1199 return rc;
1200 }
1201
1202 static const struct devlink_param bnxt_dl_params[] = {
1203 DEVLINK_PARAM_GENERIC(ENABLE_SRIOV,
1204 BIT(DEVLINK_PARAM_CMODE_PERMANENT),
1205 bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
1206 NULL),
1207 DEVLINK_PARAM_GENERIC(IGNORE_ARI,
1208 BIT(DEVLINK_PARAM_CMODE_PERMANENT),
1209 bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
1210 NULL),
1211 DEVLINK_PARAM_GENERIC(MSIX_VEC_PER_PF_MAX,
1212 BIT(DEVLINK_PARAM_CMODE_PERMANENT),
1213 bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
1214 bnxt_dl_msix_validate),
1215 DEVLINK_PARAM_GENERIC(MSIX_VEC_PER_PF_MIN,
1216 BIT(DEVLINK_PARAM_CMODE_PERMANENT),
1217 bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
1218 bnxt_dl_msix_validate),
1219 DEVLINK_PARAM_DRIVER(BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK,
1220 "gre_ver_check", DEVLINK_PARAM_TYPE_BOOL,
1221 BIT(DEVLINK_PARAM_CMODE_PERMANENT),
1222 bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
1223 NULL),
1224
1225 DEVLINK_PARAM_GENERIC(ENABLE_REMOTE_DEV_RESET,
1226 BIT(DEVLINK_PARAM_CMODE_RUNTIME),
1227 bnxt_remote_dev_reset_get,
1228 bnxt_remote_dev_reset_set, NULL),
1229 };
1230
1231 static int bnxt_dl_params_register(struct bnxt *bp)
1232 {
1233 int num_params = ARRAY_SIZE(bnxt_dl_params);
1234 int rc;
1235
1236 if (bp->hwrm_spec_code < 0x10600)
1237 return 0;
1238
1239 if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
1240 num_params--;
1241
1242 rc = devlink_params_register(bp->dl, bnxt_dl_params, num_params);
1243 if (rc)
1244 netdev_warn(bp->dev, "devlink_params_register failed. rc=%d\n",
1245 rc);
1246 return rc;
1247 }
1248
1249 static void bnxt_dl_params_unregister(struct bnxt *bp)
1250 {
1251 int num_params = ARRAY_SIZE(bnxt_dl_params);
1252
1253 if (bp->hwrm_spec_code < 0x10600)
1254 return;
1255
1256 if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
1257 num_params--;
1258
1259 devlink_params_unregister(bp->dl, bnxt_dl_params, num_params);
1260 }
1261
1262 int bnxt_dl_register(struct bnxt *bp)
1263 {
1264 const struct devlink_ops *devlink_ops;
1265 struct devlink_port_attrs attrs = {};
1266 struct bnxt_dl *bp_dl;
1267 struct devlink *dl;
1268 int rc;
1269
1270 if (BNXT_PF(bp))
1271 devlink_ops = &bnxt_dl_ops;
1272 else
1273 devlink_ops = &bnxt_vf_dl_ops;
1274
1275 dl = devlink_alloc(devlink_ops, sizeof(struct bnxt_dl), &bp->pdev->dev);
1276 if (!dl) {
1277 netdev_warn(bp->dev, "devlink_alloc failed\n");
1278 return -ENOMEM;
1279 }
1280
1281 bp->dl = dl;
1282 bp_dl = devlink_priv(dl);
1283 bp_dl->bp = bp;
1284 bnxt_dl_set_remote_reset(dl, true);
1285
1286
1287 if (pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV) &&
1288 bp->hwrm_spec_code > 0x10803)
1289 bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY;
1290
1291 if (!BNXT_PF(bp))
1292 goto out;
1293
1294 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
1295 attrs.phys.port_number = bp->pf.port_id;
1296 memcpy(attrs.switch_id.id, bp->dsn, sizeof(bp->dsn));
1297 attrs.switch_id.id_len = sizeof(bp->dsn);
1298 devlink_port_attrs_set(&bp->dl_port, &attrs);
1299 rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id);
1300 if (rc) {
1301 netdev_err(bp->dev, "devlink_port_register failed\n");
1302 goto err_dl_free;
1303 }
1304
1305 rc = bnxt_dl_params_register(bp);
1306 if (rc)
1307 goto err_dl_port_unreg;
1308
1309 devlink_set_features(dl, DEVLINK_F_RELOAD);
1310 out:
1311 devlink_register(dl);
1312 return 0;
1313
1314 err_dl_port_unreg:
1315 devlink_port_unregister(&bp->dl_port);
1316 err_dl_free:
1317 devlink_free(dl);
1318 return rc;
1319 }
1320
1321 void bnxt_dl_unregister(struct bnxt *bp)
1322 {
1323 struct devlink *dl = bp->dl;
1324
1325 devlink_unregister(dl);
1326 if (BNXT_PF(bp)) {
1327 bnxt_dl_params_unregister(bp);
1328 devlink_port_unregister(&bp->dl_port);
1329 }
1330 devlink_free(dl);
1331 }