Linux Audio

Check our new training course

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