/* Broadcom NetXtreme-C/E network driver.
 *
 * Copyright (c) 2017 Broadcom Limited
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 */

#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
#include <net/devlink.h>
#include "bnxt_hsi.h"
#include "bnxt.h"
#include "bnxt_hwrm.h"
#include "bnxt_vfr.h"
#include "bnxt_devlink.h"
#include "bnxt_ethtool.h"
#include "bnxt_ulp.h"
#include "bnxt_ptp.h"
#include "bnxt_coredump.h"
#include "bnxt_nvm_defs.h"

static void __bnxt_fw_recover(struct bnxt *bp)
{
	if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) ||
	    test_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state))
		bnxt_fw_reset(bp);
	else
		bnxt_fw_exception(bp);
}

static int
bnxt_dl_flash_update(struct devlink *dl,
		     struct devlink_flash_update_params *params,
		     struct netlink_ext_ack *extack)
{
	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
	int rc;

	if (!BNXT_PF(bp)) {
		NL_SET_ERR_MSG_MOD(extack,
				   "flash update not supported from a VF");
		return -EPERM;
	}

	devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);
	rc = bnxt_flash_package_from_fw_obj(bp->dev, params->fw, 0, extack);
	if (!rc)
		devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0);
	else
		devlink_flash_update_status_notify(dl, "Flashing failed", NULL, 0, 0);
	return rc;
}

static int bnxt_hwrm_remote_dev_reset_set(struct bnxt *bp, bool remote_reset)
{
	struct hwrm_func_cfg_input *req;
	int rc;

	if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
		return -EOPNOTSUPP;

	rc = hwrm_req_init(bp, req, HWRM_FUNC_CFG);
	if (rc)
		return rc;

	req->fid = cpu_to_le16(0xffff);
	req->enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_HOT_RESET_IF_SUPPORT);
	if (remote_reset)
		req->flags = cpu_to_le32(FUNC_CFG_REQ_FLAGS_HOT_RESET_IF_EN_DIS);

	return hwrm_req_send(bp, req);
}

static char *bnxt_health_severity_str(enum bnxt_health_severity severity)
{
	switch (severity) {
	case SEVERITY_NORMAL: return "normal";
	case SEVERITY_WARNING: return "warning";
	case SEVERITY_RECOVERABLE: return "recoverable";
	case SEVERITY_FATAL: return "fatal";
	default: return "unknown";
	}
}

static char *bnxt_health_remedy_str(enum bnxt_health_remedy remedy)
{
	switch (remedy) {
	case REMEDY_DEVLINK_RECOVER: return "devlink recover";
	case REMEDY_POWER_CYCLE_DEVICE: return "device power cycle";
	case REMEDY_POWER_CYCLE_HOST: return "host power cycle";
	case REMEDY_FW_UPDATE: return "update firmware";
	case REMEDY_HW_REPLACE: return "replace hardware";
	default: return "unknown";
	}
}

static int bnxt_fw_diagnose(struct devlink_health_reporter *reporter,
			    struct devlink_fmsg *fmsg,
			    struct netlink_ext_ack *extack)
{
	struct bnxt *bp = devlink_health_reporter_priv(reporter);
	struct bnxt_fw_health *h = bp->fw_health;
	u32 fw_status, fw_resets;
	int rc;

	if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
		return devlink_fmsg_string_pair_put(fmsg, "Status", "recovering");

	if (!h->status_reliable)
		return devlink_fmsg_string_pair_put(fmsg, "Status", "unknown");

	mutex_lock(&h->lock);
	fw_status = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG);
	if (BNXT_FW_IS_BOOTING(fw_status)) {
		rc = devlink_fmsg_string_pair_put(fmsg, "Status", "initializing");
		if (rc)
			goto unlock;
	} else if (h->severity || fw_status != BNXT_FW_STATUS_HEALTHY) {
		if (!h->severity) {
			h->severity = SEVERITY_FATAL;
			h->remedy = REMEDY_POWER_CYCLE_DEVICE;
			h->diagnoses++;
			devlink_health_report(h->fw_reporter,
					      "FW error diagnosed", h);
		}
		rc = devlink_fmsg_string_pair_put(fmsg, "Status", "error");
		if (rc)
			goto unlock;
		rc = devlink_fmsg_u32_pair_put(fmsg, "Syndrome", fw_status);
		if (rc)
			goto unlock;
	} else {
		rc = devlink_fmsg_string_pair_put(fmsg, "Status", "healthy");
		if (rc)
			goto unlock;
	}

	rc = devlink_fmsg_string_pair_put(fmsg, "Severity",
					  bnxt_health_severity_str(h->severity));
	if (rc)
		goto unlock;

	if (h->severity) {
		rc = devlink_fmsg_string_pair_put(fmsg, "Remedy",
						  bnxt_health_remedy_str(h->remedy));
		if (rc)
			goto unlock;
		if (h->remedy == REMEDY_DEVLINK_RECOVER) {
			rc = devlink_fmsg_string_pair_put(fmsg, "Impact",
							  "traffic+ntuple_cfg");
			if (rc)
				goto unlock;
		}
	}

unlock:
	mutex_unlock(&h->lock);
	if (rc || !h->resets_reliable)
		return rc;

	fw_resets = bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG);
	rc = devlink_fmsg_u32_pair_put(fmsg, "Resets", fw_resets);
	if (rc)
		return rc;
	rc = devlink_fmsg_u32_pair_put(fmsg, "Arrests", h->arrests);
	if (rc)
		return rc;
	rc = devlink_fmsg_u32_pair_put(fmsg, "Survivals", h->survivals);
	if (rc)
		return rc;
	rc = devlink_fmsg_u32_pair_put(fmsg, "Discoveries", h->discoveries);
	if (rc)
		return rc;
	rc = devlink_fmsg_u32_pair_put(fmsg, "Fatalities", h->fatalities);
	if (rc)
		return rc;
	return devlink_fmsg_u32_pair_put(fmsg, "Diagnoses", h->diagnoses);
}

static int bnxt_fw_dump(struct devlink_health_reporter *reporter,
			struct devlink_fmsg *fmsg, void *priv_ctx,
			struct netlink_ext_ack *extack)
{
	struct bnxt *bp = devlink_health_reporter_priv(reporter);
	u32 dump_len;
	void *data;
	int rc;

	/* TODO: no firmware dump support in devlink_health_report() context */
	if (priv_ctx)
		return -EOPNOTSUPP;

	dump_len = bnxt_get_coredump_length(bp, BNXT_DUMP_LIVE);
	if (!dump_len)
		return -EIO;

	data = vmalloc(dump_len);
	if (!data)
		return -ENOMEM;

	rc = bnxt_get_coredump(bp, BNXT_DUMP_LIVE, data, &dump_len);
	if (!rc) {
		rc = devlink_fmsg_pair_nest_start(fmsg, "core");
		if (rc)
			goto exit;
		rc = devlink_fmsg_binary_pair_put(fmsg, "data", data, dump_len);
		if (rc)
			goto exit;
		rc = devlink_fmsg_u32_pair_put(fmsg, "size", dump_len);
		if (rc)
			goto exit;
		rc = devlink_fmsg_pair_nest_end(fmsg);
	}

exit:
	vfree(data);
	return rc;
}

static int bnxt_fw_recover(struct devlink_health_reporter *reporter,
			   void *priv_ctx,
			   struct netlink_ext_ack *extack)
{
	struct bnxt *bp = devlink_health_reporter_priv(reporter);

	if (bp->fw_health->severity == SEVERITY_FATAL)
		return -ENODEV;

	set_bit(BNXT_STATE_RECOVER, &bp->state);
	__bnxt_fw_recover(bp);

	return -EINPROGRESS;
}

static const struct devlink_health_reporter_ops bnxt_dl_fw_reporter_ops = {
	.name = "fw",
	.diagnose = bnxt_fw_diagnose,
	.dump = bnxt_fw_dump,
	.recover = bnxt_fw_recover,
};

static struct devlink_health_reporter *
__bnxt_dl_reporter_create(struct bnxt *bp,
			  const struct devlink_health_reporter_ops *ops)
{
	struct devlink_health_reporter *reporter;

	reporter = devlink_health_reporter_create(bp->dl, ops, 0, bp);
	if (IS_ERR(reporter)) {
		netdev_warn(bp->dev, "Failed to create %s health reporter, rc = %ld\n",
			    ops->name, PTR_ERR(reporter));
		return NULL;
	}

	return reporter;
}

void bnxt_dl_fw_reporters_create(struct bnxt *bp)
{
	struct bnxt_fw_health *fw_health = bp->fw_health;

	if (fw_health && !fw_health->fw_reporter)
		fw_health->fw_reporter = __bnxt_dl_reporter_create(bp, &bnxt_dl_fw_reporter_ops);
}

void bnxt_dl_fw_reporters_destroy(struct bnxt *bp)
{
	struct bnxt_fw_health *fw_health = bp->fw_health;

	if (fw_health && fw_health->fw_reporter) {
		devlink_health_reporter_destroy(fw_health->fw_reporter);
		fw_health->fw_reporter = NULL;
	}
}

void bnxt_devlink_health_fw_report(struct bnxt *bp)
{
	struct bnxt_fw_health *fw_health = bp->fw_health;
	int rc;

	if (!fw_health)
		return;

	if (!fw_health->fw_reporter) {
		__bnxt_fw_recover(bp);
		return;
	}

	mutex_lock(&fw_health->lock);
	fw_health->severity = SEVERITY_RECOVERABLE;
	fw_health->remedy = REMEDY_DEVLINK_RECOVER;
	mutex_unlock(&fw_health->lock);
	rc = devlink_health_report(fw_health->fw_reporter, "FW error reported",
				   fw_health);
	if (rc == -ECANCELED)
		__bnxt_fw_recover(bp);
}

void bnxt_dl_health_fw_status_update(struct bnxt *bp, bool healthy)
{
	struct bnxt_fw_health *fw_health = bp->fw_health;
	u8 state;

	mutex_lock(&fw_health->lock);
	if (healthy) {
		fw_health->severity = SEVERITY_NORMAL;
		state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
	} else {
		fw_health->severity = SEVERITY_FATAL;
		fw_health->remedy = REMEDY_POWER_CYCLE_DEVICE;
		state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
	}
	mutex_unlock(&fw_health->lock);
	devlink_health_reporter_state_update(fw_health->fw_reporter, state);
}

void bnxt_dl_health_fw_recovery_done(struct bnxt *bp)
{
	struct bnxt_dl *dl = devlink_priv(bp->dl);

	devlink_health_reporter_recovery_done(bp->fw_health->fw_reporter);
	bnxt_hwrm_remote_dev_reset_set(bp, dl->remote_reset);
}

static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
			    struct netlink_ext_ack *extack);

static void
bnxt_dl_livepatch_report_err(struct bnxt *bp, struct netlink_ext_ack *extack,
			     struct hwrm_fw_livepatch_output *resp)
{
	int err = ((struct hwrm_err_output *)resp)->cmd_err;

	switch (err) {
	case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_OPCODE:
		netdev_err(bp->dev, "Illegal live patch opcode");
		NL_SET_ERR_MSG_MOD(extack, "Invalid opcode");
		break;
	case FW_LIVEPATCH_CMD_ERR_CODE_NOT_SUPPORTED:
		NL_SET_ERR_MSG_MOD(extack, "Live patch operation not supported");
		break;
	case FW_LIVEPATCH_CMD_ERR_CODE_NOT_INSTALLED:
		NL_SET_ERR_MSG_MOD(extack, "Live patch not found");
		break;
	case FW_LIVEPATCH_CMD_ERR_CODE_NOT_PATCHED:
		NL_SET_ERR_MSG_MOD(extack,
				   "Live patch deactivation failed. Firmware not patched.");
		break;
	case FW_LIVEPATCH_CMD_ERR_CODE_AUTH_FAIL:
		NL_SET_ERR_MSG_MOD(extack, "Live patch not authenticated");
		break;
	case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_HEADER:
		NL_SET_ERR_MSG_MOD(extack, "Incompatible live patch");
		break;
	case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_SIZE:
		NL_SET_ERR_MSG_MOD(extack, "Live patch has invalid size");
		break;
	case FW_LIVEPATCH_CMD_ERR_CODE_ALREADY_PATCHED:
		NL_SET_ERR_MSG_MOD(extack, "Live patch already applied");
		break;
	default:
		netdev_err(bp->dev, "Unexpected live patch error: %d\n", err);
		NL_SET_ERR_MSG_MOD(extack, "Failed to activate live patch");
		break;
	}
}

/* Live patch status in NVM */
#define BNXT_LIVEPATCH_NOT_INSTALLED	0
#define BNXT_LIVEPATCH_INSTALLED	FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL
#define BNXT_LIVEPATCH_REMOVED		FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE
#define BNXT_LIVEPATCH_MASK		(FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL | \
					 FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE)
#define BNXT_LIVEPATCH_ACTIVATED	BNXT_LIVEPATCH_MASK

#define BNXT_LIVEPATCH_STATE(flags)	((flags) & BNXT_LIVEPATCH_MASK)

static int
bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
{
	struct hwrm_fw_livepatch_query_output *query_resp;
	struct hwrm_fw_livepatch_query_input *query_req;
	struct hwrm_fw_livepatch_output *patch_resp;
	struct hwrm_fw_livepatch_input *patch_req;
	u16 flags, live_patch_state;
	bool activated = false;
	u32 installed = 0;
	u8 target;
	int rc;

	if (~bp->fw_cap & BNXT_FW_CAP_LIVEPATCH) {
		NL_SET_ERR_MSG_MOD(extack, "Device does not support live patch");
		return -EOPNOTSUPP;
	}

	rc = hwrm_req_init(bp, query_req, HWRM_FW_LIVEPATCH_QUERY);
	if (rc)
		return rc;
	query_resp = hwrm_req_hold(bp, query_req);

	rc = hwrm_req_init(bp, patch_req, HWRM_FW_LIVEPATCH);
	if (rc) {
		hwrm_req_drop(bp, query_req);
		return rc;
	}
	patch_req->loadtype = FW_LIVEPATCH_REQ_LOADTYPE_NVM_INSTALL;
	patch_resp = hwrm_req_hold(bp, patch_req);

	for (target = 1; target <= FW_LIVEPATCH_REQ_FW_TARGET_LAST; target++) {
		query_req->fw_target = target;
		rc = hwrm_req_send(bp, query_req);
		if (rc) {
			NL_SET_ERR_MSG_MOD(extack, "Failed to query packages");
			break;
		}

		flags = le16_to_cpu(query_resp->status_flags);
		live_patch_state = BNXT_LIVEPATCH_STATE(flags);

		if (live_patch_state == BNXT_LIVEPATCH_NOT_INSTALLED)
			continue;

		if (live_patch_state == BNXT_LIVEPATCH_ACTIVATED) {
			activated = true;
			continue;
		}

		if (live_patch_state == BNXT_LIVEPATCH_INSTALLED)
			patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_ACTIVATE;
		else if (live_patch_state == BNXT_LIVEPATCH_REMOVED)
			patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_DEACTIVATE;

		patch_req->fw_target = target;
		rc = hwrm_req_send(bp, patch_req);
		if (rc) {
			bnxt_dl_livepatch_report_err(bp, extack, patch_resp);
			break;
		}
		installed++;
	}

	if (!rc && !installed) {
		if (activated) {
			NL_SET_ERR_MSG_MOD(extack, "Live patch already activated");
			rc = -EEXIST;
		} else {
			NL_SET_ERR_MSG_MOD(extack, "No live patches found");
			rc = -ENOENT;
		}
	}
	hwrm_req_drop(bp, query_req);
	hwrm_req_drop(bp, patch_req);
	return rc;
}

static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change,
			       enum devlink_reload_action action,
			       enum devlink_reload_limit limit,
			       struct netlink_ext_ack *extack)
{
	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
	int rc = 0;

	switch (action) {
	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: {
		rtnl_lock();
		if (bnxt_sriov_cfg(bp)) {
			NL_SET_ERR_MSG_MOD(extack,
					   "reload is unsupported while VFs are allocated or being configured");
			rtnl_unlock();
			return -EOPNOTSUPP;
		}
		if (bp->dev->reg_state == NETREG_UNREGISTERED) {
			rtnl_unlock();
			return -ENODEV;
		}
		bnxt_ulp_stop(bp);
		if (netif_running(bp->dev)) {
			rc = bnxt_close_nic(bp, true, true);
			if (rc) {
				NL_SET_ERR_MSG_MOD(extack, "Failed to close");
				dev_close(bp->dev);
				rtnl_unlock();
				break;
			}
		}
		bnxt_vf_reps_free(bp);
		rc = bnxt_hwrm_func_drv_unrgtr(bp);
		if (rc) {
			NL_SET_ERR_MSG_MOD(extack, "Failed to deregister");
			if (netif_running(bp->dev))
				dev_close(bp->dev);
			rtnl_unlock();
			break;
		}
		bnxt_cancel_reservations(bp, false);
		bnxt_free_ctx_mem(bp);
		kfree(bp->ctx);
		bp->ctx = NULL;
		break;
	}
	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: {
		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
			return bnxt_dl_livepatch_activate(bp, extack);
		if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET) {
			NL_SET_ERR_MSG_MOD(extack, "Device not capable, requires reboot");
			return -EOPNOTSUPP;
		}
		if (!bnxt_hwrm_reset_permitted(bp)) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Reset denied by firmware, it may be inhibited by remote driver");
			return -EPERM;
		}
		rtnl_lock();
		if (bp->dev->reg_state == NETREG_UNREGISTERED) {
			rtnl_unlock();
			return -ENODEV;
		}
		if (netif_running(bp->dev))
			set_bit(BNXT_STATE_FW_ACTIVATE, &bp->state);
		rc = bnxt_hwrm_firmware_reset(bp->dev,
					      FW_RESET_REQ_EMBEDDED_PROC_TYPE_CHIP,
					      FW_RESET_REQ_SELFRST_STATUS_SELFRSTASAP,
					      FW_RESET_REQ_FLAGS_RESET_GRACEFUL |
					      FW_RESET_REQ_FLAGS_FW_ACTIVATION);
		if (rc) {
			NL_SET_ERR_MSG_MOD(extack, "Failed to activate firmware");
			clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state);
			rtnl_unlock();
		}
		break;
	}
	default:
		rc = -EOPNOTSUPP;
	}

	return rc;
}

static int bnxt_dl_reload_up(struct devlink *dl, enum devlink_reload_action action,
			     enum devlink_reload_limit limit, u32 *actions_performed,
			     struct netlink_ext_ack *extack)
{
	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
	int rc = 0;

	*actions_performed = 0;
	switch (action) {
	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: {
		bnxt_fw_init_one(bp);
		bnxt_vf_reps_alloc(bp);
		if (netif_running(bp->dev))
			rc = bnxt_open_nic(bp, true, true);
		bnxt_ulp_start(bp, rc);
		if (!rc) {
			bnxt_reenable_sriov(bp);
			bnxt_ptp_reapply_pps(bp);
		}
		break;
	}
	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: {
		unsigned long start = jiffies;
		unsigned long timeout = start + BNXT_DFLT_FW_RST_MAX_DSECS * HZ / 10;

		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
			break;
		if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)
			timeout = start + bp->fw_health->normal_func_wait_dsecs * HZ / 10;
		if (!netif_running(bp->dev))
			NL_SET_ERR_MSG_MOD(extack,
					   "Device is closed, not waiting for reset notice that will never come");
		rtnl_unlock();
		while (test_bit(BNXT_STATE_FW_ACTIVATE, &bp->state)) {
			if (time_after(jiffies, timeout)) {
				NL_SET_ERR_MSG_MOD(extack, "Activation incomplete");
				rc = -ETIMEDOUT;
				break;
			}
			if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) {
				NL_SET_ERR_MSG_MOD(extack, "Activation aborted");
				rc = -ENODEV;
				break;
			}
			msleep(50);
		}
		rtnl_lock();
		if (!rc)
			*actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
		clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state);
		break;
	}
	default:
		return -EOPNOTSUPP;
	}

	if (!rc) {
		bnxt_print_device_info(bp);
		if (netif_running(bp->dev)) {
			mutex_lock(&bp->link_lock);
			bnxt_report_link(bp);
			mutex_unlock(&bp->link_lock);
		}
		*actions_performed |= BIT(action);
	} else if (netif_running(bp->dev)) {
		dev_close(bp->dev);
	}
	rtnl_unlock();
	return rc;
}

static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack)
{
	bool rc = false;
	u32 datalen;
	u16 index;
	u8 *buf;

	if (bnxt_find_nvram_item(bp->dev, BNX_DIR_TYPE_VPD,
				 BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
				 &index, NULL, &datalen) || !datalen) {
		NL_SET_ERR_MSG_MOD(extack, "nvm test vpd entry error");
		return false;
	}

	buf = kzalloc(datalen, GFP_KERNEL);
	if (!buf) {
		NL_SET_ERR_MSG_MOD(extack, "insufficient memory for nvm test");
		return false;
	}

	if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) {
		NL_SET_ERR_MSG_MOD(extack, "nvm test vpd read error");
		goto done;
	}

	if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST,
			     BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) {
		NL_SET_ERR_MSG_MOD(extack, "nvm test vpd write error");
		goto done;
	}

	rc = true;

done:
	kfree(buf);
	return rc;
}

static bool bnxt_dl_selftest_check(struct devlink *dl, unsigned int id,
				   struct netlink_ext_ack *extack)
{
	return id == DEVLINK_ATTR_SELFTEST_ID_FLASH;
}

static enum devlink_selftest_status bnxt_dl_selftest_run(struct devlink *dl,
							 unsigned int id,
							 struct netlink_ext_ack *extack)
{
	struct bnxt *bp = bnxt_get_bp_from_dl(dl);

	if (id == DEVLINK_ATTR_SELFTEST_ID_FLASH)
		return bnxt_nvm_test(bp, extack) ?
				DEVLINK_SELFTEST_STATUS_PASS :
				DEVLINK_SELFTEST_STATUS_FAIL;

	return DEVLINK_SELFTEST_STATUS_SKIP;
}

static const struct devlink_ops bnxt_dl_ops = {
#ifdef CONFIG_BNXT_SRIOV
	.eswitch_mode_set = bnxt_dl_eswitch_mode_set,
	.eswitch_mode_get = bnxt_dl_eswitch_mode_get,
#endif /* CONFIG_BNXT_SRIOV */
	.info_get	  = bnxt_dl_info_get,
	.flash_update	  = bnxt_dl_flash_update,
	.reload_actions	  = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
			    BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
	.reload_limits	  = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
	.reload_down	  = bnxt_dl_reload_down,
	.reload_up	  = bnxt_dl_reload_up,
	.selftest_check	  = bnxt_dl_selftest_check,
	.selftest_run	  = bnxt_dl_selftest_run,
};

static const struct devlink_ops bnxt_vf_dl_ops;

enum bnxt_dl_param_id {
	BNXT_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
	BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK,
};

static const struct bnxt_dl_nvm_param nvm_params[] = {
	{DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, NVM_OFF_ENABLE_SRIOV,
	 BNXT_NVM_SHARED_CFG, 1, 1},
	{DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI, NVM_OFF_IGNORE_ARI,
	 BNXT_NVM_SHARED_CFG, 1, 1},
	{DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
	 NVM_OFF_MSIX_VEC_PER_PF_MAX, BNXT_NVM_SHARED_CFG, 10, 4},
	{DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
	 NVM_OFF_MSIX_VEC_PER_PF_MIN, BNXT_NVM_SHARED_CFG, 7, 4},
	{BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK, NVM_OFF_DIS_GRE_VER_CHECK,
	 BNXT_NVM_SHARED_CFG, 1, 1},
};

union bnxt_nvm_data {
	u8	val8;
	__le32	val32;
};

static void bnxt_copy_to_nvm_data(union bnxt_nvm_data *dst,
				  union devlink_param_value *src,
				  int nvm_num_bits, int dl_num_bytes)
{
	u32 val32 = 0;

	if (nvm_num_bits == 1) {
		dst->val8 = src->vbool;
		return;
	}
	if (dl_num_bytes == 4)
		val32 = src->vu32;
	else if (dl_num_bytes == 2)
		val32 = (u32)src->vu16;
	else if (dl_num_bytes == 1)
		val32 = (u32)src->vu8;
	dst->val32 = cpu_to_le32(val32);
}

static void bnxt_copy_from_nvm_data(union devlink_param_value *dst,
				    union bnxt_nvm_data *src,
				    int nvm_num_bits, int dl_num_bytes)
{
	u32 val32;

	if (nvm_num_bits == 1) {
		dst->vbool = src->val8;
		return;
	}
	val32 = le32_to_cpu(src->val32);
	if (dl_num_bytes == 4)
		dst->vu32 = val32;
	else if (dl_num_bytes == 2)
		dst->vu16 = (u16)val32;
	else if (dl_num_bytes == 1)
		dst->vu8 = (u8)val32;
}

static int bnxt_hwrm_get_nvm_cfg_ver(struct bnxt *bp, u32 *nvm_cfg_ver)
{
	struct hwrm_nvm_get_variable_input *req;
	u16 bytes = BNXT_NVM_CFG_VER_BYTES;
	u16 bits = BNXT_NVM_CFG_VER_BITS;
	union devlink_param_value ver;
	union bnxt_nvm_data *data;
	dma_addr_t data_dma_addr;
	int rc, i = 2;
	u16 dim = 1;

	rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE);
	if (rc)
		return rc;

	data = hwrm_req_dma_slice(bp, req, sizeof(*data), &data_dma_addr);
	if (!data) {
		rc = -ENOMEM;
		goto exit;
	}

	/* earlier devices present as an array of raw bytes */
	if (!BNXT_CHIP_P5(bp)) {
		dim = 0;
		i = 0;
		bits *= 3;  /* array of 3 version components */
		bytes *= 4; /* copy whole word */
	}

	hwrm_req_hold(bp, req);
	req->dest_data_addr = cpu_to_le64(data_dma_addr);
	req->data_len = cpu_to_le16(bits);
	req->option_num = cpu_to_le16(NVM_OFF_NVM_CFG_VER);
	req->dimensions = cpu_to_le16(dim);

	while (i >= 0) {
		req->index_0 = cpu_to_le16(i--);
		rc = hwrm_req_send_silent(bp, req);
		if (rc)
			goto exit;
		bnxt_copy_from_nvm_data(&ver, data, bits, bytes);

		if (BNXT_CHIP_P5(bp)) {
			*nvm_cfg_ver <<= 8;
			*nvm_cfg_ver |= ver.vu8;
		} else {
			*nvm_cfg_ver = ver.vu32;
		}
	}

exit:
	hwrm_req_drop(bp, req);
	return rc;
}

static int bnxt_dl_info_put(struct bnxt *bp, struct devlink_info_req *req,
			    enum bnxt_dl_version_type type, const char *key,
			    char *buf)
{
	if (!strlen(buf))
		return 0;

	if ((bp->flags & BNXT_FLAG_CHIP_P5) &&
	    (!strcmp(key, DEVLINK_INFO_VERSION_GENERIC_FW_NCSI) ||
	     !strcmp(key, DEVLINK_INFO_VERSION_GENERIC_FW_ROCE)))
		return 0;

	switch (type) {
	case BNXT_VERSION_FIXED:
		return devlink_info_version_fixed_put(req, key, buf);
	case BNXT_VERSION_RUNNING:
		return devlink_info_version_running_put(req, key, buf);
	case BNXT_VERSION_STORED:
		return devlink_info_version_stored_put(req, key, buf);
	}
	return 0;
}

#define BNXT_FW_SRT_PATCH	"fw.srt.patch"
#define BNXT_FW_CRT_PATCH	"fw.crt.patch"

static int bnxt_dl_livepatch_info_put(struct bnxt *bp,
				      struct devlink_info_req *req,
				      const char *key)
{
	struct hwrm_fw_livepatch_query_input *query;
	struct hwrm_fw_livepatch_query_output *resp;
	u16 flags;
	int rc;

	if (~bp->fw_cap & BNXT_FW_CAP_LIVEPATCH)
		return 0;

	rc = hwrm_req_init(bp, query, HWRM_FW_LIVEPATCH_QUERY);
	if (rc)
		return rc;

	if (!strcmp(key, BNXT_FW_SRT_PATCH))
		query->fw_target = FW_LIVEPATCH_QUERY_REQ_FW_TARGET_SECURE_FW;
	else if (!strcmp(key, BNXT_FW_CRT_PATCH))
		query->fw_target = FW_LIVEPATCH_QUERY_REQ_FW_TARGET_COMMON_FW;
	else
		goto exit;

	resp = hwrm_req_hold(bp, query);
	rc = hwrm_req_send(bp, query);
	if (rc)
		goto exit;

	flags = le16_to_cpu(resp->status_flags);
	if (flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE) {
		resp->active_ver[sizeof(resp->active_ver) - 1] = '\0';
		rc = devlink_info_version_running_put(req, key, resp->active_ver);
		if (rc)
			goto exit;
	}

	if (flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL) {
		resp->install_ver[sizeof(resp->install_ver) - 1] = '\0';
		rc = devlink_info_version_stored_put(req, key, resp->install_ver);
		if (rc)
			goto exit;
	}

exit:
	hwrm_req_drop(bp, query);
	return rc;
}

#define HWRM_FW_VER_STR_LEN	16

static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
			    struct netlink_ext_ack *extack)
{
	struct hwrm_nvm_get_dev_info_output nvm_dev_info;
	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
	struct hwrm_ver_get_output *ver_resp;
	char mgmt_ver[FW_VER_STR_LEN];
	char roce_ver[FW_VER_STR_LEN];
	char ncsi_ver[FW_VER_STR_LEN];
	char buf[32];
	u32 ver = 0;
	int rc;

	rc = devlink_info_driver_name_put(req, DRV_MODULE_NAME);
	if (rc)
		return rc;

	if (BNXT_PF(bp) && (bp->flags & BNXT_FLAG_DSN_VALID)) {
		sprintf(buf, "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X",
			bp->dsn[7], bp->dsn[6], bp->dsn[5], bp->dsn[4],
			bp->dsn[3], bp->dsn[2], bp->dsn[1], bp->dsn[0]);
		rc = devlink_info_serial_number_put(req, buf);
		if (rc)
			return rc;
	}

	if (strlen(bp->board_serialno)) {
		rc = devlink_info_board_serial_number_put(req, bp->board_serialno);
		if (rc)
			return rc;
	}

	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED,
			      DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
			      bp->board_partno);
	if (rc)
		return rc;

	sprintf(buf, "%X", bp->chip_num);
	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED,
			      DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, buf);
	if (rc)
		return rc;

	ver_resp = &bp->ver_resp;
	sprintf(buf, "%c%d", 'A' + ver_resp->chip_rev, ver_resp->chip_metal);
	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED,
			      DEVLINK_INFO_VERSION_GENERIC_ASIC_REV, buf);
	if (rc)
		return rc;

	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
			      DEVLINK_INFO_VERSION_GENERIC_FW_PSID,
			      bp->nvm_cfg_ver);
	if (rc)
		return rc;

	buf[0] = 0;
	strncat(buf, ver_resp->active_pkg_name, HWRM_FW_VER_STR_LEN);
	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
			      DEVLINK_INFO_VERSION_GENERIC_FW, buf);
	if (rc)
		return rc;

	if (BNXT_PF(bp) && !bnxt_hwrm_get_nvm_cfg_ver(bp, &ver)) {
		sprintf(buf, "%d.%d.%d", (ver >> 16) & 0xff, (ver >> 8) & 0xff,
			ver & 0xff);
		rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
				      DEVLINK_INFO_VERSION_GENERIC_FW_PSID,
				      buf);
		if (rc)
			return rc;
	}

	if (ver_resp->flags & VER_GET_RESP_FLAGS_EXT_VER_AVAIL) {
		snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
			 ver_resp->hwrm_fw_major, ver_resp->hwrm_fw_minor,
			 ver_resp->hwrm_fw_build, ver_resp->hwrm_fw_patch);

		snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
			 ver_resp->mgmt_fw_major, ver_resp->mgmt_fw_minor,
			 ver_resp->mgmt_fw_build, ver_resp->mgmt_fw_patch);

		snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
			 ver_resp->roce_fw_major, ver_resp->roce_fw_minor,
			 ver_resp->roce_fw_build, ver_resp->roce_fw_patch);
	} else {
		snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
			 ver_resp->hwrm_fw_maj_8b, ver_resp->hwrm_fw_min_8b,
			 ver_resp->hwrm_fw_bld_8b, ver_resp->hwrm_fw_rsvd_8b);

		snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
			 ver_resp->mgmt_fw_maj_8b, ver_resp->mgmt_fw_min_8b,
			 ver_resp->mgmt_fw_bld_8b, ver_resp->mgmt_fw_rsvd_8b);

		snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
			 ver_resp->roce_fw_maj_8b, ver_resp->roce_fw_min_8b,
			 ver_resp->roce_fw_bld_8b, ver_resp->roce_fw_rsvd_8b);
	}
	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
			      DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, mgmt_ver);
	if (rc)
		return rc;

	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
			      DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API,
			      bp->hwrm_ver_supp);
	if (rc)
		return rc;

	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
			      DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, ncsi_ver);
	if (rc)
		return rc;

	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
			      DEVLINK_INFO_VERSION_GENERIC_FW_ROCE, roce_ver);
	if (rc)
		return rc;

	rc = bnxt_hwrm_nvm_get_dev_info(bp, &nvm_dev_info);
	if (rc ||
	    !(nvm_dev_info.flags & NVM_GET_DEV_INFO_RESP_FLAGS_FW_VER_VALID)) {
		if (!bnxt_get_pkginfo(bp->dev, buf, sizeof(buf)))
			return bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
						DEVLINK_INFO_VERSION_GENERIC_FW,
						buf);
		return 0;
	}

	buf[0] = 0;
	strncat(buf, nvm_dev_info.pkg_name, HWRM_FW_VER_STR_LEN);
	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
			      DEVLINK_INFO_VERSION_GENERIC_FW, buf);
	if (rc)
		return rc;

	snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
		 nvm_dev_info.hwrm_fw_major, nvm_dev_info.hwrm_fw_minor,
		 nvm_dev_info.hwrm_fw_build, nvm_dev_info.hwrm_fw_patch);
	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
			      DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, mgmt_ver);
	if (rc)
		return rc;

	snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
		 nvm_dev_info.mgmt_fw_major, nvm_dev_info.mgmt_fw_minor,
		 nvm_dev_info.mgmt_fw_build, nvm_dev_info.mgmt_fw_patch);
	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
			      DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, ncsi_ver);
	if (rc)
		return rc;

	snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
		 nvm_dev_info.roce_fw_major, nvm_dev_info.roce_fw_minor,
		 nvm_dev_info.roce_fw_build, nvm_dev_info.roce_fw_patch);
	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
			      DEVLINK_INFO_VERSION_GENERIC_FW_ROCE, roce_ver);
	if (rc)
		return rc;

	if (BNXT_CHIP_P5(bp)) {
		rc = bnxt_dl_livepatch_info_put(bp, req, BNXT_FW_SRT_PATCH);
		if (rc)
			return rc;
	}
	return bnxt_dl_livepatch_info_put(bp, req, BNXT_FW_CRT_PATCH);

}

static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
			     union devlink_param_value *val)
{
	struct hwrm_nvm_get_variable_input *req = msg;
	struct bnxt_dl_nvm_param nvm_param;
	struct hwrm_err_output *resp;
	union bnxt_nvm_data *data;
	dma_addr_t data_dma_addr;
	int idx = 0, rc, i;

	/* Get/Set NVM CFG parameter is supported only on PFs */
	if (BNXT_VF(bp)) {
		hwrm_req_drop(bp, req);
		return -EPERM;
	}

	for (i = 0; i < ARRAY_SIZE(nvm_params); i++) {
		if (nvm_params[i].id == param_id) {
			nvm_param = nvm_params[i];
			break;
		}
	}

	if (i == ARRAY_SIZE(nvm_params)) {
		hwrm_req_drop(bp, req);
		return -EOPNOTSUPP;
	}

	if (nvm_param.dir_type == BNXT_NVM_PORT_CFG)
		idx = bp->pf.port_id;
	else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG)
		idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID;

	data = hwrm_req_dma_slice(bp, req, sizeof(*data), &data_dma_addr);

	if (!data) {
		hwrm_req_drop(bp, req);
		return -ENOMEM;
	}

	req->dest_data_addr = cpu_to_le64(data_dma_addr);
	req->data_len = cpu_to_le16(nvm_param.nvm_num_bits);
	req->option_num = cpu_to_le16(nvm_param.offset);
	req->index_0 = cpu_to_le16(idx);
	if (idx)
		req->dimensions = cpu_to_le16(1);

	resp = hwrm_req_hold(bp, req);
	if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) {
		bnxt_copy_to_nvm_data(data, val, nvm_param.nvm_num_bits,
				      nvm_param.dl_num_bytes);
		rc = hwrm_req_send(bp, msg);
	} else {
		rc = hwrm_req_send_silent(bp, msg);
		if (!rc) {
			bnxt_copy_from_nvm_data(val, data,
						nvm_param.nvm_num_bits,
						nvm_param.dl_num_bytes);
		} else {
			if (resp->cmd_err ==
				NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST)
				rc = -EOPNOTSUPP;
		}
	}
	hwrm_req_drop(bp, req);
	if (rc == -EACCES)
		netdev_err(bp->dev, "PF does not have admin privileges to modify NVM config\n");
	return rc;
}

static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id,
				 struct devlink_param_gset_ctx *ctx)
{
	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
	struct hwrm_nvm_get_variable_input *req;
	int rc;

	rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE);
	if (rc)
		return rc;

	rc = bnxt_hwrm_nvm_req(bp, id, req, &ctx->val);
	if (!rc && id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
		ctx->val.vbool = !ctx->val.vbool;

	return rc;
}

static int bnxt_dl_nvm_param_set(struct devlink *dl, u32 id,
				 struct devlink_param_gset_ctx *ctx)
{
	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
	struct hwrm_nvm_set_variable_input *req;
	int rc;

	rc = hwrm_req_init(bp, req, HWRM_NVM_SET_VARIABLE);
	if (rc)
		return rc;

	if (id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
		ctx->val.vbool = !ctx->val.vbool;

	return bnxt_hwrm_nvm_req(bp, id, req, &ctx->val);
}

static int bnxt_dl_msix_validate(struct devlink *dl, u32 id,
				 union devlink_param_value val,
				 struct netlink_ext_ack *extack)
{
	int max_val = -1;

	if (id == DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX)
		max_val = BNXT_MSIX_VEC_MAX;

	if (id == DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN)
		max_val = BNXT_MSIX_VEC_MIN_MAX;

	if (val.vu32 > max_val) {
		NL_SET_ERR_MSG_MOD(extack, "MSIX value is exceeding the range");
		return -EINVAL;
	}

	return 0;
}

static int bnxt_remote_dev_reset_get(struct devlink *dl, u32 id,
				     struct devlink_param_gset_ctx *ctx)
{
	struct bnxt *bp = bnxt_get_bp_from_dl(dl);

	if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
		return -EOPNOTSUPP;

	ctx->val.vbool = bnxt_dl_get_remote_reset(dl);
	return 0;
}

static int bnxt_remote_dev_reset_set(struct devlink *dl, u32 id,
				     struct devlink_param_gset_ctx *ctx)
{
	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
	int rc;

	rc = bnxt_hwrm_remote_dev_reset_set(bp, ctx->val.vbool);
	if (rc)
		return rc;

	bnxt_dl_set_remote_reset(dl, ctx->val.vbool);
	return rc;
}

static const struct devlink_param bnxt_dl_params[] = {
	DEVLINK_PARAM_GENERIC(ENABLE_SRIOV,
			      BIT(DEVLINK_PARAM_CMODE_PERMANENT),
			      bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
			      NULL),
	DEVLINK_PARAM_GENERIC(IGNORE_ARI,
			      BIT(DEVLINK_PARAM_CMODE_PERMANENT),
			      bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
			      NULL),
	DEVLINK_PARAM_GENERIC(MSIX_VEC_PER_PF_MAX,
			      BIT(DEVLINK_PARAM_CMODE_PERMANENT),
			      bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
			      bnxt_dl_msix_validate),
	DEVLINK_PARAM_GENERIC(MSIX_VEC_PER_PF_MIN,
			      BIT(DEVLINK_PARAM_CMODE_PERMANENT),
			      bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
			      bnxt_dl_msix_validate),
	DEVLINK_PARAM_DRIVER(BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK,
			     "gre_ver_check", DEVLINK_PARAM_TYPE_BOOL,
			     BIT(DEVLINK_PARAM_CMODE_PERMANENT),
			     bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
			     NULL),
	/* keep REMOTE_DEV_RESET last, it is excluded based on caps */
	DEVLINK_PARAM_GENERIC(ENABLE_REMOTE_DEV_RESET,
			      BIT(DEVLINK_PARAM_CMODE_RUNTIME),
			      bnxt_remote_dev_reset_get,
			      bnxt_remote_dev_reset_set, NULL),
};

static int bnxt_dl_params_register(struct bnxt *bp)
{
	int num_params = ARRAY_SIZE(bnxt_dl_params);
	int rc;

	if (bp->hwrm_spec_code < 0x10600)
		return 0;

	if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
		num_params--;

	rc = devlink_params_register(bp->dl, bnxt_dl_params, num_params);
	if (rc)
		netdev_warn(bp->dev, "devlink_params_register failed. rc=%d\n",
			    rc);
	return rc;
}

static void bnxt_dl_params_unregister(struct bnxt *bp)
{
	int num_params = ARRAY_SIZE(bnxt_dl_params);

	if (bp->hwrm_spec_code < 0x10600)
		return;

	if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
		num_params--;

	devlink_params_unregister(bp->dl, bnxt_dl_params, num_params);
}

int bnxt_dl_register(struct bnxt *bp)
{
	const struct devlink_ops *devlink_ops;
	struct devlink_port_attrs attrs = {};
	struct bnxt_dl *bp_dl;
	struct devlink *dl;
	int rc;

	if (BNXT_PF(bp))
		devlink_ops = &bnxt_dl_ops;
	else
		devlink_ops = &bnxt_vf_dl_ops;

	dl = devlink_alloc(devlink_ops, sizeof(struct bnxt_dl), &bp->pdev->dev);
	if (!dl) {
		netdev_warn(bp->dev, "devlink_alloc failed\n");
		return -ENOMEM;
	}

	bp->dl = dl;
	bp_dl = devlink_priv(dl);
	bp_dl->bp = bp;
	bnxt_dl_set_remote_reset(dl, true);

	/* Add switchdev eswitch mode setting, if SRIOV supported */
	if (pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV) &&
	    bp->hwrm_spec_code > 0x10803)
		bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY;

	if (!BNXT_PF(bp))
		goto out;

	attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
	attrs.phys.port_number = bp->pf.port_id;
	memcpy(attrs.switch_id.id, bp->dsn, sizeof(bp->dsn));
	attrs.switch_id.id_len = sizeof(bp->dsn);
	devlink_port_attrs_set(&bp->dl_port, &attrs);
	rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id);
	if (rc) {
		netdev_err(bp->dev, "devlink_port_register failed\n");
		goto err_dl_free;
	}

	rc = bnxt_dl_params_register(bp);
	if (rc)
		goto err_dl_port_unreg;

	devlink_set_features(dl, DEVLINK_F_RELOAD);
out:
	devlink_register(dl);
	return 0;

err_dl_port_unreg:
	devlink_port_unregister(&bp->dl_port);
err_dl_free:
	devlink_free(dl);
	return rc;
}

void bnxt_dl_unregister(struct bnxt *bp)
{
	struct devlink *dl = bp->dl;

	devlink_unregister(dl);
	if (BNXT_PF(bp)) {
		bnxt_dl_params_unregister(bp);
		devlink_port_unregister(&bp->dl_port);
	}
	devlink_free(dl);
}
