Commit badc6ac3 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
100GbE Intel Wired LAN Driver Updates 2021-02-05

This series contains updates to ice driver only.

Jake adds adds reporting of timeout length during devlink flash and
implements support to report devlink info regarding the version of
firmware that is stored (downloaded) to the device, but is not yet active.
ice_devlink_info_get will report "stored" versions when there is no
pending flash update. Version info includes the UNDI Option ROM, the
Netlist module, and the fw.bundle_id.

Gustavo A. R. Silva replaces a one-element array to flexible-array
member.

Bruce utilizes flex_array_size() helper and removes dead code on a check
for a condition that can't occur.

v2:
* removed security revision implementation, and re-ordered patches to
account for this removal
* squashed patches implementing ice_read_flash_module to avoid patches
refactoring the implementation of a previous patch in the series
* modify ice_devlink_info_get to always report "stored" versions instead
of only reporting them when a pending flash update is ready.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  ice: remove dead code
  ice: use flex_array_size where possible
  ice: Replace one-element array with flexible-array member
  ice: display stored UNDI firmware version via devlink info
  ice: display stored netlist versions via devlink info
  ice: display some stored NVM versions via devlink info
  ice: introduce function for reading from flash modules
  ice: cache NVM module bank information
  ice: introduce context struct for info report
  ice: create flash_info structure and separate NVM version
  ice: report timeout length for erasing during devlink flash
====================

Link: https://lore.kernel.org/r/20210206044101.636242-1-anthony.l.nguyen@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents c273a20c 12aae8f1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -166,7 +166,7 @@ struct ice_tc_cfg {
struct ice_res_tracker {
	u16 num_entries;
	u16 end;
	u16 list[1];
	u16 list[];
};

struct ice_qs_cfg {
+0 −27
Original line number Diff line number Diff line
@@ -1334,33 +1334,6 @@ struct ice_aqc_nvm_checksum {
	u8 rsvd2[12];
};

/* The result of netlist NVM read comes in a TLV format. The actual data
 * (netlist header) starts from word offset 1 (byte 2). The FW strips
 * out the type field from the TLV header so all the netlist fields
 * should adjust their offset value by 1 word (2 bytes) in order to map
 * their correct location.
 */
#define ICE_AQC_NVM_LINK_TOPO_NETLIST_MOD_ID		0x11B
#define ICE_AQC_NVM_LINK_TOPO_NETLIST_LEN_OFFSET	1
#define ICE_AQC_NVM_LINK_TOPO_NETLIST_LEN		2 /* In bytes */
#define ICE_AQC_NVM_NETLIST_NODE_COUNT_OFFSET		2
#define ICE_AQC_NVM_NETLIST_NODE_COUNT_LEN		2 /* In bytes */
#define ICE_AQC_NVM_NETLIST_NODE_COUNT_M		ICE_M(0x3FF, 0)
#define ICE_AQC_NVM_NETLIST_ID_BLK_START_OFFSET		5
#define ICE_AQC_NVM_NETLIST_ID_BLK_LEN			0x30 /* In words */

/* netlist ID block field offsets (word offsets) */
#define ICE_AQC_NVM_NETLIST_ID_BLK_MAJOR_VER_LOW	2
#define ICE_AQC_NVM_NETLIST_ID_BLK_MAJOR_VER_HIGH	3
#define ICE_AQC_NVM_NETLIST_ID_BLK_MINOR_VER_LOW	4
#define ICE_AQC_NVM_NETLIST_ID_BLK_MINOR_VER_HIGH	5
#define ICE_AQC_NVM_NETLIST_ID_BLK_TYPE_LOW		6
#define ICE_AQC_NVM_NETLIST_ID_BLK_TYPE_HIGH		7
#define ICE_AQC_NVM_NETLIST_ID_BLK_REV_LOW		8
#define ICE_AQC_NVM_NETLIST_ID_BLK_REV_HIGH		9
#define ICE_AQC_NVM_NETLIST_ID_BLK_SHA_HASH		0xA
#define ICE_AQC_NVM_NETLIST_ID_BLK_CUST_VER		0x2F

/* Used for NVM Set Package Data command - 0x070A */
struct ice_aqc_nvm_pkg_data {
	u8 reserved[3];
+1 −1
Original line number Diff line number Diff line
@@ -1653,7 +1653,7 @@ ice_aq_alloc_free_res(struct ice_hw *hw, u16 num_entries,
	if (!buf)
		return ICE_ERR_PARAM;

	if (buf_size < (num_entries * sizeof(buf->elem[0])))
	if (buf_size < flex_array_size(buf, elem, num_entries))
		return ICE_ERR_PARAM;

	ice_fill_dflt_direct_cmd_desc(&desc, opc);
+218 −55
Original line number Diff line number Diff line
@@ -6,132 +6,226 @@
#include "ice_devlink.h"
#include "ice_fw_update.h"

static void ice_info_get_dsn(struct ice_pf *pf, char *buf, size_t len)
/* context for devlink info version reporting */
struct ice_info_ctx {
	char buf[128];
	struct ice_orom_info pending_orom;
	struct ice_nvm_info pending_nvm;
	struct ice_netlist_info pending_netlist;
	struct ice_hw_dev_caps dev_caps;
};

/* The following functions are used to format specific strings for various
 * devlink info versions. The ctx parameter is used to provide the storage
 * buffer, as well as any ancillary information calculated when the info
 * request was made.
 *
 * If a version does not exist, for example when attempting to get the
 * inactive version of flash when there is no pending update, the function
 * should leave the buffer in the ctx structure empty and return 0.
 */

static void ice_info_get_dsn(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	u8 dsn[8];

	/* Copy the DSN into an array in Big Endian format */
	put_unaligned_be64(pci_get_dsn(pf->pdev), dsn);

	snprintf(buf, len, "%8phD", dsn);
	snprintf(ctx->buf, sizeof(ctx->buf), "%8phD", dsn);
}

static int ice_info_pba(struct ice_pf *pf, char *buf, size_t len)
static int ice_info_pba(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	struct ice_hw *hw = &pf->hw;
	enum ice_status status;

	status = ice_read_pba_string(hw, (u8 *)buf, len);
	status = ice_read_pba_string(hw, (u8 *)ctx->buf, sizeof(ctx->buf));
	if (status)
		return -EIO;

	return 0;
}

static int ice_info_fw_mgmt(struct ice_pf *pf, char *buf, size_t len)
static int ice_info_fw_mgmt(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	struct ice_hw *hw = &pf->hw;

	snprintf(buf, len, "%u.%u.%u", hw->fw_maj_ver, hw->fw_min_ver,
	snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", hw->fw_maj_ver, hw->fw_min_ver,
		 hw->fw_patch);

	return 0;
}

static int ice_info_fw_api(struct ice_pf *pf, char *buf, size_t len)
static int ice_info_fw_api(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	struct ice_hw *hw = &pf->hw;

	snprintf(buf, len, "%u.%u", hw->api_maj_ver, hw->api_min_ver);
	snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u", hw->api_maj_ver, hw->api_min_ver);

	return 0;
}

static int ice_info_fw_build(struct ice_pf *pf, char *buf, size_t len)
static int ice_info_fw_build(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	struct ice_hw *hw = &pf->hw;

	snprintf(buf, len, "0x%08x", hw->fw_build);
	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", hw->fw_build);

	return 0;
}

static int ice_info_orom_ver(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	struct ice_orom_info *orom = &pf->hw.flash.orom;

	snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u", orom->major, orom->build, orom->patch);

	return 0;
}

static int
ice_info_pending_orom_ver(struct ice_pf __always_unused *pf, struct ice_info_ctx *ctx)
{
	struct ice_orom_info *orom = &ctx->pending_orom;

	if (ctx->dev_caps.common_cap.nvm_update_pending_orom)
		snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u",
			 orom->major, orom->build, orom->patch);

	return 0;
}

static int ice_info_nvm_ver(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	struct ice_nvm_info *nvm = &pf->hw.flash.nvm;

	snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor);

	return 0;
}

static int ice_info_orom_ver(struct ice_pf *pf, char *buf, size_t len)
static int
ice_info_pending_nvm_ver(struct ice_pf __always_unused *pf, struct ice_info_ctx *ctx)
{
	struct ice_orom_info *orom = &pf->hw.nvm.orom;
	struct ice_nvm_info *nvm = &ctx->pending_nvm;

	snprintf(buf, len, "%u.%u.%u", orom->major, orom->build, orom->patch);
	if (ctx->dev_caps.common_cap.nvm_update_pending_nvm)
		snprintf(ctx->buf, sizeof(ctx->buf), "%x.%02x", nvm->major, nvm->minor);

	return 0;
}

static int ice_info_nvm_ver(struct ice_pf *pf, char *buf, size_t len)
static int ice_info_eetrack(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	struct ice_nvm_info *nvm = &pf->hw.nvm;
	struct ice_nvm_info *nvm = &pf->hw.flash.nvm;

	snprintf(buf, len, "%x.%02x", nvm->major_ver, nvm->minor_ver);
	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm->eetrack);

	return 0;
}

static int ice_info_eetrack(struct ice_pf *pf, char *buf, size_t len)
static int
ice_info_pending_eetrack(struct ice_pf __always_unused *pf, struct ice_info_ctx *ctx)
{
	struct ice_nvm_info *nvm = &pf->hw.nvm;
	struct ice_nvm_info *nvm = &ctx->pending_nvm;

	snprintf(buf, len, "0x%08x", nvm->eetrack);
	if (ctx->dev_caps.common_cap.nvm_update_pending_nvm)
		snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", nvm->eetrack);

	return 0;
}

static int ice_info_ddp_pkg_name(struct ice_pf *pf, char *buf, size_t len)
static int ice_info_ddp_pkg_name(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	struct ice_hw *hw = &pf->hw;

	snprintf(buf, len, "%s", hw->active_pkg_name);
	snprintf(ctx->buf, sizeof(ctx->buf), "%s", hw->active_pkg_name);

	return 0;
}

static int ice_info_ddp_pkg_version(struct ice_pf *pf, char *buf, size_t len)
static int ice_info_ddp_pkg_version(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	struct ice_pkg_ver *pkg = &pf->hw.active_pkg_ver;

	snprintf(buf, len, "%u.%u.%u.%u", pkg->major, pkg->minor, pkg->update,
	snprintf(ctx->buf, sizeof(ctx->buf), "%u.%u.%u.%u", pkg->major, pkg->minor, pkg->update,
		 pkg->draft);

	return 0;
}

static int ice_info_ddp_pkg_bundle_id(struct ice_pf *pf, char *buf, size_t len)
static int ice_info_ddp_pkg_bundle_id(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	snprintf(buf, len, "0x%08x", pf->hw.active_track_id);
	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", pf->hw.active_track_id);

	return 0;
}

static int ice_info_netlist_ver(struct ice_pf *pf, char *buf, size_t len)
static int ice_info_netlist_ver(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	struct ice_netlist_info *netlist = &pf->hw.flash.netlist;

	/* The netlist version fields are BCD formatted */
	snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x", netlist->major, netlist->minor,
		 netlist->type >> 16, netlist->type & 0xFFFF, netlist->rev,
		 netlist->cust_ver);

	return 0;
}

static int ice_info_netlist_build(struct ice_pf *pf, struct ice_info_ctx *ctx)
{
	struct ice_netlist_info *netlist = &pf->hw.flash.netlist;

	snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash);

	return 0;
}

static int
ice_info_pending_netlist_ver(struct ice_pf __always_unused *pf, struct ice_info_ctx *ctx)
{
	struct ice_netlist_ver_info *netlist = &pf->hw.netlist_ver;
	struct ice_netlist_info *netlist = &ctx->pending_netlist;

	/* The netlist version fields are BCD formatted */
	snprintf(buf, len, "%x.%x.%x-%x.%x.%x", netlist->major, netlist->minor,
	if (ctx->dev_caps.common_cap.nvm_update_pending_netlist)
		snprintf(ctx->buf, sizeof(ctx->buf), "%x.%x.%x-%x.%x.%x",
			 netlist->major, netlist->minor,
			 netlist->type >> 16, netlist->type & 0xFFFF, netlist->rev,
			 netlist->cust_ver);

	return 0;
}

static int ice_info_netlist_build(struct ice_pf *pf, char *buf, size_t len)
static int
ice_info_pending_netlist_build(struct ice_pf __always_unused *pf, struct ice_info_ctx *ctx)
{
	struct ice_netlist_ver_info *netlist = &pf->hw.netlist_ver;
	struct ice_netlist_info *netlist = &ctx->pending_netlist;

	snprintf(buf, len, "0x%08x", netlist->hash);
	if (ctx->dev_caps.common_cap.nvm_update_pending_netlist)
		snprintf(ctx->buf, sizeof(ctx->buf), "0x%08x", netlist->hash);

	return 0;
}

#define fixed(key, getter) { ICE_VERSION_FIXED, key, getter }
#define running(key, getter) { ICE_VERSION_RUNNING, key, getter }
#define fixed(key, getter) { ICE_VERSION_FIXED, key, getter, NULL }
#define running(key, getter) { ICE_VERSION_RUNNING, key, getter, NULL }
#define stored(key, getter, fallback) { ICE_VERSION_STORED, key, getter, fallback }

/* The combined() macro inserts both the running entry as well as a stored
 * entry. The running entry will always report the version from the active
 * handler. The stored entry will first try the pending handler, and fallback
 * to the active handler if the pending function does not report a version.
 * The pending handler should check the status of a pending update for the
 * relevant flash component. It should only fill in the buffer in the case
 * where a valid pending version is available. This ensures that the related
 * stored and running versions remain in sync, and that stored versions are
 * correctly reported as expected.
 */
#define combined(key, active, pending) \
	running(key, active), \
	stored(key, pending, active)

enum ice_version_type {
	ICE_VERSION_FIXED,
@@ -142,20 +236,21 @@ enum ice_version_type {
static const struct ice_devlink_version {
	enum ice_version_type type;
	const char *key;
	int (*getter)(struct ice_pf *pf, char *buf, size_t len);
	int (*getter)(struct ice_pf *pf, struct ice_info_ctx *ctx);
	int (*fallback)(struct ice_pf *pf, struct ice_info_ctx *ctx);
} ice_devlink_versions[] = {
	fixed(DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, ice_info_pba),
	running(DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, ice_info_fw_mgmt),
	running("fw.mgmt.api", ice_info_fw_api),
	running("fw.mgmt.build", ice_info_fw_build),
	running(DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, ice_info_orom_ver),
	running("fw.psid.api", ice_info_nvm_ver),
	running(DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, ice_info_eetrack),
	combined(DEVLINK_INFO_VERSION_GENERIC_FW_UNDI, ice_info_orom_ver, ice_info_pending_orom_ver),
	combined("fw.psid.api", ice_info_nvm_ver, ice_info_pending_nvm_ver),
	combined(DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID, ice_info_eetrack, ice_info_pending_eetrack),
	running("fw.app.name", ice_info_ddp_pkg_name),
	running(DEVLINK_INFO_VERSION_GENERIC_FW_APP, ice_info_ddp_pkg_version),
	running("fw.app.bundle_id", ice_info_ddp_pkg_bundle_id),
	running("fw.netlist", ice_info_netlist_ver),
	running("fw.netlist.build", ice_info_netlist_build),
	combined("fw.netlist", ice_info_netlist_ver, ice_info_pending_netlist_ver),
	combined("fw.netlist.build", ice_info_netlist_build, ice_info_pending_netlist_build),
};

/**
@@ -174,60 +269,128 @@ static int ice_devlink_info_get(struct devlink *devlink,
				struct netlink_ext_ack *extack)
{
	struct ice_pf *pf = devlink_priv(devlink);
	char buf[100];
	struct device *dev = ice_pf_to_dev(pf);
	struct ice_hw *hw = &pf->hw;
	struct ice_info_ctx *ctx;
	enum ice_status status;
	size_t i;
	int err;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	/* discover capabilities first */
	status = ice_discover_dev_caps(hw, &ctx->dev_caps);
	if (status) {
		err = -EIO;
		goto out_free_ctx;
	}

	if (ctx->dev_caps.common_cap.nvm_update_pending_orom) {
		status = ice_get_inactive_orom_ver(hw, &ctx->pending_orom);
		if (status) {
			dev_dbg(dev, "Unable to read inactive Option ROM version data, status %s aq_err %s\n",
				ice_stat_str(status), ice_aq_str(hw->adminq.sq_last_status));

			/* disable display of pending Option ROM */
			ctx->dev_caps.common_cap.nvm_update_pending_orom = false;
		}
	}

	if (ctx->dev_caps.common_cap.nvm_update_pending_nvm) {
		status = ice_get_inactive_nvm_ver(hw, &ctx->pending_nvm);
		if (status) {
			dev_dbg(dev, "Unable to read inactive NVM version data, status %s aq_err %s\n",
				ice_stat_str(status), ice_aq_str(hw->adminq.sq_last_status));

			/* disable display of pending Option ROM */
			ctx->dev_caps.common_cap.nvm_update_pending_nvm = false;
		}
	}

	if (ctx->dev_caps.common_cap.nvm_update_pending_netlist) {
		status = ice_get_inactive_netlist_ver(hw, &ctx->pending_netlist);
		if (status) {
			dev_dbg(dev, "Unable to read inactive Netlist version data, status %s aq_err %s\n",
				ice_stat_str(status), ice_aq_str(hw->adminq.sq_last_status));

			/* disable display of pending Option ROM */
			ctx->dev_caps.common_cap.nvm_update_pending_netlist = false;
		}
	}

	err = devlink_info_driver_name_put(req, KBUILD_MODNAME);
	if (err) {
		NL_SET_ERR_MSG_MOD(extack, "Unable to set driver name");
		return err;
		goto out_free_ctx;
	}

	ice_info_get_dsn(pf, buf, sizeof(buf));
	ice_info_get_dsn(pf, ctx);

	err = devlink_info_serial_number_put(req, buf);
	err = devlink_info_serial_number_put(req, ctx->buf);
	if (err) {
		NL_SET_ERR_MSG_MOD(extack, "Unable to set serial number");
		return err;
		goto out_free_ctx;
	}

	for (i = 0; i < ARRAY_SIZE(ice_devlink_versions); i++) {
		enum ice_version_type type = ice_devlink_versions[i].type;
		const char *key = ice_devlink_versions[i].key;

		err = ice_devlink_versions[i].getter(pf, buf, sizeof(buf));
		memset(ctx->buf, 0, sizeof(ctx->buf));

		err = ice_devlink_versions[i].getter(pf, ctx);
		if (err) {
			NL_SET_ERR_MSG_MOD(extack, "Unable to obtain version info");
			return err;
			goto out_free_ctx;
		}

		/* If the default getter doesn't report a version, use the
		 * fallback function. This is primarily useful in the case of
		 * "stored" versions that want to report the same value as the
		 * running version in the normal case of no pending update.
		 */
		if (ctx->buf[0] == '\0' && ice_devlink_versions[i].fallback) {
			err = ice_devlink_versions[i].fallback(pf, ctx);
			if (err) {
				NL_SET_ERR_MSG_MOD(extack, "Unable to obtain version info");
				goto out_free_ctx;
			}
		}

		/* Do not report missing versions */
		if (ctx->buf[0] == '\0')
			continue;

		switch (type) {
		case ICE_VERSION_FIXED:
			err = devlink_info_version_fixed_put(req, key, buf);
			err = devlink_info_version_fixed_put(req, key, ctx->buf);
			if (err) {
				NL_SET_ERR_MSG_MOD(extack, "Unable to set fixed version");
				return err;
				goto out_free_ctx;
			}
			break;
		case ICE_VERSION_RUNNING:
			err = devlink_info_version_running_put(req, key, buf);
			err = devlink_info_version_running_put(req, key, ctx->buf);
			if (err) {
				NL_SET_ERR_MSG_MOD(extack, "Unable to set running version");
				return err;
				goto out_free_ctx;
			}
			break;
		case ICE_VERSION_STORED:
			err = devlink_info_version_stored_put(req, key, buf);
			err = devlink_info_version_stored_put(req, key, ctx->buf);
			if (err) {
				NL_SET_ERR_MSG_MOD(extack, "Unable to set stored version");
				return err;
				goto out_free_ctx;
			}
			break;
		}
	}

	return 0;
out_free_ctx:
	kfree(ctx);
	return err;
}

/**
@@ -433,7 +596,7 @@ static int ice_devlink_nvm_snapshot(struct devlink *devlink,
	void *nvm_data;
	u32 nvm_size;

	nvm_size = hw->nvm.flash_size;
	nvm_size = hw->flash.flash_size;
	nvm_data = vzalloc(nvm_size);
	if (!nvm_data)
		return -ENOMEM;
@@ -533,7 +696,7 @@ void ice_devlink_init_regions(struct ice_pf *pf)
	struct device *dev = ice_pf_to_dev(pf);
	u64 nvm_size;

	nvm_size = pf->hw.nvm.flash_size;
	nvm_size = pf->hw.flash.flash_size;
	pf->nvm_region = devlink_region_create(devlink, &ice_nvm_region_ops, 1,
					       nvm_size);
	if (IS_ERR(pf->nvm_region)) {
+4 −4
Original line number Diff line number Diff line
@@ -179,8 +179,8 @@ ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
	struct ice_orom_info *orom;
	struct ice_nvm_info *nvm;

	nvm = &hw->nvm;
	orom = &nvm->orom;
	nvm = &hw->flash.nvm;
	orom = &hw->flash.orom;

	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));

@@ -188,7 +188,7 @@ ice_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
	 * determined) which contains more pertinent information.
	 */
	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
		 "%x.%02x 0x%x %d.%d.%d", nvm->major_ver, nvm->minor_ver,
		 "%x.%02x 0x%x %d.%d.%d", nvm->major, nvm->minor,
		 nvm->eetrack, orom->major, orom->build, orom->patch);

	strscpy(drvinfo->bus_info, pci_name(pf->pdev),
@@ -250,7 +250,7 @@ static int ice_get_eeprom_len(struct net_device *netdev)
	struct ice_netdev_priv *np = netdev_priv(netdev);
	struct ice_pf *pf = np->vsi->back;

	return (int)pf->hw.nvm.flash_size;
	return (int)pf->hw.flash.flash_size;
}

static int
Loading