Back to home page

OSCL-LXR

 
 

    


0001 /* Broadcom NetXtreme-C/E network driver.
0002  *
0003  * Copyright (c) 2017 Broadcom Limited
0004  *
0005  * This program is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation.
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     /* TODO: no firmware dump support in devlink_health_report() context */
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 /* Live patch status in NVM */
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 /* CONFIG_BNXT_SRIOV */
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     /* earlier devices present as an array of raw bytes */
0772     if (!BNXT_CHIP_P5(bp)) {
0773         dim = 0;
0774         i = 0;
0775         bits *= 3;  /* array of 3 version components */
0776         bytes *= 4; /* copy whole word */
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     /* Get/Set NVM CFG parameter is supported only on PFs */
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     /* keep REMOTE_DEV_RESET last, it is excluded based on caps */
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     /* Add switchdev eswitch mode setting, if SRIOV supported */
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 }