Skip to content

Commit

Permalink
ice: implement direct read for NVM and Shadow RAM regions
Browse files Browse the repository at this point in the history
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: Jacob Keller <jacob.e.keller@intel.com>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jacob Keller authored and Jakub Kicinski committed Dec 1, 2022
1 parent 2d01978 commit 3af4b40
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
8 changes: 6 additions & 2 deletions Documentation/networking/devlink/ice.rst
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,12 @@ device data.
- The contents of the device firmware's capabilities buffer. Useful to
determine the current state and configuration of the device.

Users can request an immediate capture of a snapshot via the
``DEVLINK_CMD_REGION_NEW``
Both the ``nvm-flash`` and ``shadow-ram`` regions can be accessed without a
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
Expand Down
69 changes: 69 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1687,6 +1687,73 @@ static int ice_devlink_nvm_snapshot(struct devlink *devlink,
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
* @devlink: the devlink instance
Expand Down Expand Up @@ -1735,12 +1802,14 @@ static const struct devlink_region_ops ice_nvm_region_ops = {
.name = "nvm-flash",
.destructor = vfree,
.snapshot = ice_devlink_nvm_snapshot,
.read = ice_devlink_nvm_read,
};

static const struct devlink_region_ops ice_sram_region_ops = {
.name = "shadow-ram",
.destructor = vfree,
.snapshot = ice_devlink_nvm_snapshot,
.read = ice_devlink_nvm_read,
};

static const struct devlink_region_ops ice_devcaps_region_ops = {
Expand Down

0 comments on commit 3af4b40

Please sign in to comment.