ice: implement direct read for NVM and Shadow RAM regions
authorJacob Keller <jacob.e.keller@intel.com>
Mon, 28 Nov 2022 20:36:47 +0000 (12:36 -0800)
committerJakub Kicinski <kuba@kernel.org>
Thu, 1 Dec 2022 04:54:31 +0000 (20:54 -0800)
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>
Documentation/networking/devlink/ice.rst
drivers/net/ethernet/intel/ice/ice_devlink.c

index bcd4839..625efb3 100644 (file)
@@ -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
 
index 9d35002..946d64e 100644 (file)
@@ -1688,6 +1688,73 @@ static int ice_devlink_nvm_snapshot(struct devlink *devlink,
 }
 
 /**
+ * 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
  * @ops: the devlink region being snapshotted
@@ -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 = {