All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jacob Keller <jacob.e.keller@intel.com>
To: netdev@vger.kernel.org
Cc: jiri@resnulli.us, valex@mellanox.com, linyunsheng@huawei.com,
	lihong.yang@intel.com, Jacob Keller <jacob.e.keller@intel.com>
Subject: [PATCH 06/15] ice: create function to read a section of the NVM and Shadow RAM
Date: Thu, 30 Jan 2020 14:59:01 -0800	[thread overview]
Message-ID: <20200130225913.1671982-7-jacob.e.keller@intel.com> (raw)
In-Reply-To: <20200130225913.1671982-1-jacob.e.keller@intel.com>

The NVM contents are read via firmware by using the ice_aq_read_nvm
function. This function has a couple of limits:

1) The AdminQ commands can only take buffers sized up to 4Kb. Thus, any
   larger read must be split into multiple reads.
2) when reading from the Shadow RAM, reads must not cross sector
   boundaries. The sectors are also 4Kb in size.

Implement the ice_read_flat_nvm function to read portions of the NVM by
flat offset. That is, to read using offsets from the start of the NVM
rather than from a specific module.

This function will be able to read both from the NVM and from the Shadow
RAM. For simplicity NVM reads will always be broken up to not cross 4Kb
page boundaries, even though this is not required unless reading from
the Shadow RAM.

Use this new function as the implementation of ice_read_sr_word_aq.

The ice_read_sr_buf_aq function is not modified here. This is because
a following change will remove the only caller of that function in favor
of directly using ice_read_flat_nvm. Thus, there is little benefit to
changing it now only to remove it momentarily. At the same time, the
ice_read_sr_aq function will also be removed.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
 .../net/ethernet/intel/ice/ice_adminq_cmd.h   |  2 +
 drivers/net/ethernet/intel/ice/ice_nvm.c      | 87 +++++++++++++++++--
 drivers/net/ethernet/intel/ice/ice_nvm.h      |  3 +
 3 files changed, 85 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
index 4459bc564b11..2240f226568f 100644
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
@@ -1250,6 +1250,8 @@ struct ice_aqc_nvm {
 	__le32 addr_low;
 };
 
+#define ICE_AQC_NVM_START_POINT			0
+
 /* NVM Checksum Command (direct, 0x0706) */
 struct ice_aqc_nvm_checksum {
 	u8 flags;
diff --git a/drivers/net/ethernet/intel/ice/ice_nvm.c b/drivers/net/ethernet/intel/ice/ice_nvm.c
index 46db9bb0977f..622431aa1e22 100644
--- a/drivers/net/ethernet/intel/ice/ice_nvm.c
+++ b/drivers/net/ethernet/intel/ice/ice_nvm.c
@@ -11,13 +11,15 @@
  * @length: length of the section to be read (in bytes from the offset)
  * @data: command buffer (size [bytes] = length)
  * @last_command: tells if this is the last command in a series
+ * @read_shadow_ram: tell if this is a shadow RAM read
  * @cd: pointer to command details structure or NULL
  *
  * Read the NVM using the admin queue commands (0x0701)
  */
 static enum ice_status
 ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
-		void *data, bool last_command, struct ice_sq_cd *cd)
+		void *data, bool last_command, bool read_shadow_ram,
+		struct ice_sq_cd *cd)
 {
 	struct ice_aq_desc desc;
 	struct ice_aqc_nvm *cmd;
@@ -30,6 +32,9 @@ ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
 
 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_read);
 
+	if (!read_shadow_ram && module_typeid == ICE_AQC_NVM_START_POINT)
+		cmd->cmd_flags |= ICE_AQC_NVM_FLASH_ONLY;
+
 	/* If this is the last command in a series, set the proper flag. */
 	if (last_command)
 		cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
@@ -41,6 +46,68 @@ ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length,
 	return ice_aq_send_cmd(hw, &desc, data, length, cd);
 }
 
+/**
+ * ice_read_flat_nvm - Read portion of NVM by flat offset
+ * @hw: pointer to the HW struct
+ * @offset: offset from beginning of NVM
+ * @length: (in) number of bytes to read; (out) number of bytes actually read
+ * @data: buffer to return data in (sized to fit the specified length)
+ * @read_shadow_ram: if true, read from shadow RAM instead of NVM
+ *
+ * Reads a portion of the NVM, as a flat memory space. This function will
+ * correctly handle reading of sizes beyond a page by breaking the request
+ * into multiple reads.
+ *
+ * Returns a status code on failure. Note that the data pointer may be
+ * partially updated if some reads succeed before a failure.
+ */
+enum ice_status
+ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
+		  bool read_shadow_ram)
+{
+	enum ice_status status;
+	bool last_cmd = true;
+	u32 inlen = *length;
+	u32 bytes_read = 0;
+
+	*length = 0;
+
+	/* Verify the length of the read if this is for the Shadow RAM */
+	if (read_shadow_ram && ((offset + inlen) > (hw->nvm.sr_words * 2))) {
+		ice_debug(hw, ICE_DBG_NVM,
+			  "NVM error: requested offset is beyond Shadow RAM limit\n");
+		return ICE_ERR_PARAM;
+	}
+
+	do {
+		u32 read_size, page_offset;
+
+		/* ice_aq_read_nvm cannot read more than 4Kb at a time.
+		 * Additionally, break the reads up so that they do not cross
+		 * a page boundary.
+		 */
+		page_offset = offset % ICE_AQ_MAX_BUF_LEN;
+		read_size = min_t(u32, ICE_AQ_MAX_BUF_LEN - page_offset,
+				  inlen - bytes_read);
+
+		if ((bytes_read + read_size) < inlen)
+			last_cmd = false;
+
+		status = ice_aq_read_nvm(hw, ICE_AQC_NVM_START_POINT,
+					 offset, read_size,
+					 data + bytes_read, last_cmd,
+					 read_shadow_ram, NULL);
+		if (status)
+			break;
+
+		bytes_read += read_size;
+		offset += read_size;
+	} while (!last_cmd);
+
+	*length = bytes_read;
+	return status;
+}
+
 /**
  * ice_check_sr_access_params - verify params for Shadow RAM R/W operations.
  * @hw: pointer to the HW structure
@@ -100,7 +167,7 @@ ice_read_sr_aq(struct ice_hw *hw, u32 offset, u16 words, __le16 *data,
 	 */
 	if (!status)
 		status = ice_aq_read_nvm(hw, 0, 2 * offset, 2 * words, data,
-					 last_command, NULL);
+					 last_command, true, NULL);
 
 	return status;
 }
@@ -111,19 +178,25 @@ ice_read_sr_aq(struct ice_hw *hw, u32 offset, u16 words, __le16 *data,
  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
  * @data: word read from the Shadow RAM
  *
- * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_aq method.
+ * Reads one 16 bit word from the Shadow RAM using ice_read_flat_nvm.
  */
 static enum ice_status
 ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
 {
+	u32 bytes = sizeof(u16);
 	enum ice_status status;
 	__le16 data_local;
 
-	status = ice_read_sr_aq(hw, offset, 1, &data_local, true);
-	if (!status)
-		*data = le16_to_cpu(data_local);
+	/* Note that ice_read_flat_nvm checks if the read is past the Shadow
+	 * RAM size, and ensures we don't read across a page boundary
+	 */
+	status = ice_read_flat_nvm(hw, offset * sizeof(u16), &bytes,
+				   (u8 *)&data_local, true);
+	if (status)
+		return status;
 
-	return status;
+	*data = le16_to_cpu(data_local);
+	return 0;
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/ice/ice_nvm.h b/drivers/net/ethernet/intel/ice/ice_nvm.h
index a9fa011c22c6..4245ef988edf 100644
--- a/drivers/net/ethernet/intel/ice/ice_nvm.h
+++ b/drivers/net/ethernet/intel/ice/ice_nvm.h
@@ -4,5 +4,8 @@
 #ifndef _ICE_NVM_H_
 #define _ICE_NVM_H_
 
+enum ice_status
+ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
+		  bool read_shadow_ram);
 enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data);
 #endif /* _ICE_NVM_H_ */
-- 
2.25.0.rc1


  parent reply	other threads:[~2020-01-30 22:59 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-30 22:58 [RFC PATCH 00/13] devlink direct region reading Jacob Keller
2020-01-30 22:58 ` [PATCH 01/15] devlink: prepare to support region operations Jacob Keller
2020-01-31 18:07   ` Jakub Kicinski
2020-02-03 11:35   ` Jiri Pirko
2020-02-03 16:48     ` Jacob Keller
2020-02-03 17:07     ` Jacob Keller
2020-02-03 17:10       ` Jacob Keller
2020-02-03 17:14     ` Jacob Keller
2020-02-03 17:17     ` Jacob Keller
2020-01-30 22:58 ` [PATCH 02/15] devlink: add functions to take snapshot while locked Jacob Keller
2020-01-31 18:07   ` Jakub Kicinski
2020-01-31 18:09     ` Jacob Keller
2020-02-03 11:39   ` Jiri Pirko
2020-02-03 16:45     ` Jacob Keller
2020-01-30 22:58 ` [PATCH 03/15] devlink: add operation to take an immediate snapshot Jacob Keller
2020-01-31 18:07   ` Jakub Kicinski
2020-02-03  8:19   ` Yunsheng Lin
2020-02-03 11:50     ` Jiri Pirko
2020-02-03 11:50   ` Jiri Pirko
2020-02-03 16:33     ` Jacob Keller
2020-02-03 19:32     ` Jacob Keller
2020-02-03 21:30       ` Jiri Pirko
2020-02-04 19:20         ` Jacob Keller
2020-01-30 22:58 ` [PATCH 04/15] netdevsim: support taking immediate snapshot via devlink Jacob Keller
2020-01-31 18:07   ` Jakub Kicinski
2020-01-31 18:12     ` Jacob Keller
2020-01-30 22:59 ` [PATCH 05/15] ice: use __le16 types for explicitly Little Endian values Jacob Keller
2020-01-30 22:59 ` Jacob Keller [this message]
2020-01-30 22:59 ` [PATCH 07/15] ice: implement full NVM read from ETHTOOL_GEEPROM Jacob Keller
2020-01-30 22:59 ` [PATCH 08/15] devlink: add devres managed devlinkm_alloc and devlinkm_free Jacob Keller
2020-01-31 18:07   ` Jakub Kicinski
2020-01-31 18:16     ` Jacob Keller
2020-01-31 18:07   ` Jakub Kicinski
2020-02-01  0:51     ` Jacob Keller
2020-02-01 17:43       ` Jakub Kicinski
2020-02-03 16:35         ` Jacob Keller
2020-02-03 11:29   ` Jiri Pirko
2020-02-03 16:56     ` Jacob Keller
2020-01-30 22:59 ` [PATCH 09/15] ice: enable initial devlink support Jacob Keller
2020-01-30 22:59 ` [PATCH 10/15] ice: add basic handler for devlink .info_get Jacob Keller
2020-01-31 18:07   ` Jakub Kicinski
2020-01-31 18:25     ` Jacob Keller
2020-01-30 22:59 ` [PATCH 11/15] ice: add board identifier info to " Jacob Keller
2020-01-31 18:07   ` Jakub Kicinski
2020-01-31 18:26     ` Jacob Keller
2020-01-30 22:59 ` [PATCH 12/15] ice: add a devlink region to dump shadow RAM contents Jacob Keller
2020-01-30 22:59 ` [PATCH 13/15] devlink: support directly reading from region memory Jacob Keller
2020-01-31 18:07   ` Jakub Kicinski
2020-01-31 18:27     ` Jacob Keller
2020-01-31 19:15     ` Jacob Keller
2020-02-03 13:44   ` Jiri Pirko
2020-02-03 16:40     ` Jacob Keller
2020-01-30 22:59 ` [PATCH 14/15] ice: support direct read of the shadow ram region Jacob Keller
2020-01-30 22:59 ` [PATCH 15/15] ice: add ice.rst devlink documentation file Jacob Keller
2020-01-31 18:07   ` Jakub Kicinski
2020-01-31 18:28     ` Jacob Keller
2020-01-30 22:59 ` [RFC PATCH 1/3] Update kernel headers Jacob Keller
2020-01-30 22:59 ` [RFC PATCH 2/3] devlink: add support for DEVLINK_CMD_REGION_TAKE_SNAPSHOT Jacob Keller
2020-01-30 22:59 ` [RFC PATCH 3/3] devlink: stop requiring snapshot for regions Jacob Keller
2020-01-30 23:03 ` [RFC PATCH 00/13] devlink direct region reading Jacob Keller
2020-01-31 18:06 ` Jakub Kicinski
2020-01-31 18:09   ` Jacob Keller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200130225913.1671982-7-jacob.e.keller@intel.com \
    --to=jacob.e.keller@intel.com \
    --cc=jiri@resnulli.us \
    --cc=lihong.yang@intel.com \
    --cc=linyunsheng@huawei.com \
    --cc=netdev@vger.kernel.org \
    --cc=valex@mellanox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.