Commit 3af4b40b authored by Jacob Keller's avatar Jacob Keller Committed by Jakub Kicinski

ice: implement direct read for NVM and Shadow RAM regions

Implement the .read handler for the NVM and Shadow RAM regions. This
enables user space to read a small chunk of the flash without needing the
overhead of creating a full snapshot.

Update the documentation for ice to detail which regions have direct read
support.
Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Acked-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 2d019784
...@@ -198,8 +198,12 @@ device data. ...@@ -198,8 +198,12 @@ device data.
- The contents of the device firmware's capabilities buffer. Useful to - The contents of the device firmware's capabilities buffer. Useful to
determine the current state and configuration of the device. determine the current state and configuration of the device.
Users can request an immediate capture of a snapshot via the Both the ``nvm-flash`` and ``shadow-ram`` regions can be accessed without a
``DEVLINK_CMD_REGION_NEW`` snapshot. The ``device-caps`` region requires a snapshot as the contents are
sent by firmware and can't be split into separate reads.
Users can request an immediate capture of a snapshot for all three regions
via the ``DEVLINK_CMD_REGION_NEW`` command.
.. code:: shell .. code:: shell
......
...@@ -1687,6 +1687,73 @@ static int ice_devlink_nvm_snapshot(struct devlink *devlink, ...@@ -1687,6 +1687,73 @@ static int ice_devlink_nvm_snapshot(struct devlink *devlink,
return 0; return 0;
} }
/**
* ice_devlink_nvm_read - Read a portion of NVM flash contents
* @devlink: the devlink instance
* @ops: the devlink region to snapshot
* @extack: extended ACK response structure
* @offset: the offset to start at
* @size: the amount to read
* @data: the data buffer to read into
*
* This function is called in response to DEVLINK_CMD_REGION_READ to directly
* read a section of the NVM contents.
*
* It reads from either the nvm-flash or shadow-ram region contents.
*
* @returns zero on success, and updates the data pointer. Returns a non-zero
* error code on failure.
*/
static int ice_devlink_nvm_read(struct devlink *devlink,
const struct devlink_region_ops *ops,
struct netlink_ext_ack *extack,
u64 offset, u32 size, u8 *data)
{
struct ice_pf *pf = devlink_priv(devlink);
struct device *dev = ice_pf_to_dev(pf);
struct ice_hw *hw = &pf->hw;
bool read_shadow_ram;
u64 nvm_size;
int status;
if (ops == &ice_nvm_region_ops) {
read_shadow_ram = false;
nvm_size = hw->flash.flash_size;
} else if (ops == &ice_sram_region_ops) {
read_shadow_ram = true;
nvm_size = hw->flash.sr_words * 2u;
} else {
NL_SET_ERR_MSG_MOD(extack, "Unexpected region in snapshot function");
return -EOPNOTSUPP;
}
if (offset + size >= nvm_size) {
NL_SET_ERR_MSG_MOD(extack, "Cannot read beyond the region size");
return -ERANGE;
}
status = ice_acquire_nvm(hw, ICE_RES_READ);
if (status) {
dev_dbg(dev, "ice_acquire_nvm failed, err %d aq_err %d\n",
status, hw->adminq.sq_last_status);
NL_SET_ERR_MSG_MOD(extack, "Failed to acquire NVM semaphore");
return -EIO;
}
status = ice_read_flat_nvm(hw, (u32)offset, &size, data,
read_shadow_ram);
if (status) {
dev_dbg(dev, "ice_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n",
size, status, hw->adminq.sq_last_status);
NL_SET_ERR_MSG_MOD(extack, "Failed to read NVM contents");
ice_release_nvm(hw);
return -EIO;
}
ice_release_nvm(hw);
return 0;
}
/** /**
* ice_devlink_devcaps_snapshot - Capture snapshot of device capabilities * ice_devlink_devcaps_snapshot - Capture snapshot of device capabilities
* @devlink: the devlink instance * @devlink: the devlink instance
...@@ -1735,12 +1802,14 @@ static const struct devlink_region_ops ice_nvm_region_ops = { ...@@ -1735,12 +1802,14 @@ static const struct devlink_region_ops ice_nvm_region_ops = {
.name = "nvm-flash", .name = "nvm-flash",
.destructor = vfree, .destructor = vfree,
.snapshot = ice_devlink_nvm_snapshot, .snapshot = ice_devlink_nvm_snapshot,
.read = ice_devlink_nvm_read,
}; };
static const struct devlink_region_ops ice_sram_region_ops = { static const struct devlink_region_ops ice_sram_region_ops = {
.name = "shadow-ram", .name = "shadow-ram",
.destructor = vfree, .destructor = vfree,
.snapshot = ice_devlink_nvm_snapshot, .snapshot = ice_devlink_nvm_snapshot,
.read = ice_devlink_nvm_read,
}; };
static const struct devlink_region_ops ice_devcaps_region_ops = { static const struct devlink_region_ops ice_devcaps_region_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment