From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 40BB0A0567 for ; Wed, 10 Mar 2021 10:19:03 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 381E540687; Wed, 10 Mar 2021 10:19:03 +0100 (CET) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mails.dpdk.org (Postfix) with ESMTP id A0A9E40687 for ; Wed, 10 Mar 2021 10:19:01 +0100 (CET) IronPort-SDR: JlIDg5TpPVvLnxGsjArzNu/totDQc4IXcbCGUEciumeJHbECslClnZC5GiYDLvKO38d/KgeV5R I8H8F/xYxx0A== X-IronPort-AV: E=McAfee;i="6000,8403,9917"; a="252442150" X-IronPort-AV: E=Sophos;i="5.81,237,1610438400"; d="scan'208";a="252442150" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2021 01:18:59 -0800 IronPort-SDR: RNd0q/RKg9WhLopcQ9sMxUHa5cli2GrvdrU3t+MPU3p2T/Gvgz2BZCFcJSHvOmF8JkT2uVGCMo 6hs/jPof2MoA== X-IronPort-AV: E=Sophos;i="5.81,237,1610438400"; d="scan'208";a="603008201" Received: from unknown (HELO intel-npg-odc-srv02.cd.intel.com) ([10.240.178.186]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Mar 2021 01:18:57 -0800 From: Murphy Yang To: stable@dpdk.org Cc: Murphy Yang , Jacob Keller , Paul M Stillwell Jr , Qi Zhang Date: Wed, 10 Mar 2021 09:12:16 +0000 Message-Id: <20210310091216.86109-1-murphyx.yang@intel.com> X-Mailer: git-send-email 2.17.1 Subject: [dpdk-stable] [PATCH 19.11] net/ice/base: discover and store size of available flash X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" [ upstream commit 864f74271e70f374aaa7349c6be94fc429d63eed ] When reading from the NVM using a flat address, it is useful to know the upper bound on the size of the flash contents. This value is not stored within the NVM. We can determine the size by performing a bisection between upper and lower bounds. It is known that the size cannot exceed 16 MB (offset of 0xFFFFFF). Use a while loop to bisect the upper and lower bounds by reading one byte at a time. On a failed read, lower the maximum bound. On a successful read, increase the lower bound. Save this as the flash_size in the ice_nvm_info structure that contains data related to the NVM. Signed-off-by: Jacob Keller Signed-off-by: Paul M Stillwell Jr Signed-off-by: Qi Zhang --- drivers/net/ice/base/ice_nvm.c | 61 +++++++++++++++++++++++++++++++++ drivers/net/ice/base/ice_type.h | 1 + 2 files changed, 62 insertions(+) diff --git a/drivers/net/ice/base/ice_nvm.c b/drivers/net/ice/base/ice_nvm.c index 86194ca4f1..c5dc6049d9 100644 --- a/drivers/net/ice/base/ice_nvm.c +++ b/drivers/net/ice/base/ice_nvm.c @@ -293,6 +293,60 @@ enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data) return status; } +/** + * ice_discover_flash_size - Discover the available flash size. + * @hw: pointer to the HW struct + * + * The device flash could be up to 16MB in size. However, it is possible that + * the actual size is smaller. Use bisection to determine the accessible size + * of flash memory. + */ +static enum ice_status ice_discover_flash_size(struct ice_hw *hw) +{ + u32 min_size = 0, max_size = ICE_AQC_NVM_MAX_OFFSET + 1; + enum ice_status status; + + ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); + + status = ice_acquire_nvm(hw, ICE_RES_READ); + if (status) + return status; + + while ((max_size - min_size) > 1) { + u32 offset = (max_size + min_size) / 2; + u32 len = 1; + u8 data; + + status = ice_read_flat_nvm(hw, offset, &len, &data, false); + if (status == ICE_ERR_AQ_ERROR && + hw->adminq.sq_last_status == ICE_AQ_RC_EINVAL) { + ice_debug(hw, ICE_DBG_NVM, + "%s: New upper bound of %u bytes\n", + __func__, offset); + status = ICE_SUCCESS; + max_size = offset; + } else if (!status) { + ice_debug(hw, ICE_DBG_NVM, + "%s: New lower bound of %u bytes\n", + __func__, offset); + min_size = offset; + } else { + /* an unexpected error occurred */ + goto err_read_flat_nvm; + } + } + + ice_debug(hw, ICE_DBG_NVM, + "Predicted flash size is %u bytes\n", max_size); + + hw->nvm.flash_size = max_size; + +err_read_flat_nvm: + ice_release_nvm(hw); + + return status; +} + /** * ice_init_nvm - initializes NVM setting * @hw: pointer to the HW struct @@ -352,6 +406,13 @@ enum ice_status ice_init_nvm(struct ice_hw *hw) nvm->eetrack = (eetrack_hi << 16) | eetrack_lo; + status = ice_discover_flash_size(hw); + if (status) { + ice_debug(hw, ICE_DBG_NVM, + "NVM init error: failed to discover flash size.\n"); + return status; + } + /* the following devices do not have boot_cfg_tlv yet */ if (hw->device_id == ICE_DEV_ID_C822N_BACKPLANE || hw->device_id == ICE_DEV_ID_C822N_QSFP || diff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h index bf3c5ffd0a..39c05f941b 100644 --- a/drivers/net/ice/base/ice_type.h +++ b/drivers/net/ice/base/ice_type.h @@ -480,6 +480,7 @@ struct ice_nvm_info { u32 eetrack; /* NVM data version */ u32 oem_ver; /* OEM version info */ u16 sr_words; /* Shadow RAM size in words */ + u32 flash_size; /* Size of available flash in bytes */ u16 ver; /* dev starter version */ u8 blank_nvm_mode; /* is NVM empty (no FW present)*/ }; -- 2.17.1