linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Emmanuel Grumbach <egrumbach@gmail.com>
To: linux-wireless@vger.kernel.org
Cc: Eran Harary <eran.harary@intel.com>,
	Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Subject: [PATCH 17/24] iwlwifi: mvm: revisit the NVM handling code
Date: Thu, 15 May 2014 20:04:34 +0300	[thread overview]
Message-ID: <1400173481-9047-17-git-send-email-egrumbach@gmail.com> (raw)
In-Reply-To: <5374F373.6040902@gmail.com>

From: Eran Harary <eran.harary@intel.com>

Fix a bug in nvm_read_section function if size of the section
is a multiple of 2K:

   - if the size of the section is *not* multiple of 2K,
   then we will have: read(2K) - return 2K ... read(2K) - return 2K
   read(2K) - return the rest (in bytes) and exit the while loop.
   - else, if the size of the section is a multiple of 2K,
   then we have: read(2K) - return 2K read(2K) - return 2K read(2K) -
   return 2K read(2K) - return 0 and exit the while with an error.

We should not return an error in the latter case, because it
might well be that the section was completely read.

Also, we try now to read all the sections as this is needed
for new devices.

Signed-off-by: Eran Harary <eran.harary@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-config.h |  2 +-
 drivers/net/wireless/iwlwifi/mvm/nvm.c    | 64 +++++++++++++++----------------
 2 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 8a62068..b7047905 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -195,7 +195,7 @@ struct iwl_ht_params {
 
 /* lower blocks contain EEPROM image and calibration data */
 #define OTP_LOW_IMAGE_SIZE		(2 * 512 * sizeof(u16)) /* 2 KB */
-#define OTP_LOW_IMAGE_SIZE_FAMILY_7000	(4 * 512 * sizeof(u16)) /* 4 KB */
+#define OTP_LOW_IMAGE_SIZE_FAMILY_7000	(16 * 512 * sizeof(u16)) /* 16 KB */
 #define OTP_LOW_IMAGE_SIZE_FAMILY_8000	(32 * 512 * sizeof(u16)) /* 32 KB */
 
 struct iwl_eeprom_params {
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 8acb9f9..808f78f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -74,6 +74,12 @@
 #define NVM_WRITE_OPCODE 1
 #define NVM_READ_OPCODE 0
 
+/* load nvm chunk response */
+enum {
+	READ_NVM_CHUNK_SUCCEED = 0,
+	READ_NVM_CHUNK_NOT_VALID_ADDRESS = 1
+};
+
 /*
  * prepare the NVM host command w/ the pointers to the nvm buffer
  * and send it to fw
@@ -139,10 +145,26 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
 	offset_read = le16_to_cpu(nvm_resp->offset);
 	resp_data = nvm_resp->data;
 	if (ret) {
-		IWL_ERR(mvm,
-			"NVM access command failed with status %d (device: %s)\n",
-			ret, mvm->cfg->name);
-		ret = -EINVAL;
+		if ((offset != 0) &&
+		    (ret == READ_NVM_CHUNK_NOT_VALID_ADDRESS)) {
+			/*
+			 * meaning of NOT_VALID_ADDRESS:
+			 * driver try to read chunk from address that is
+			 * multiple of 2K and got an error since addr is empty.
+			 * meaning of (offset != 0): driver already
+			 * read valid data from another chunk so this case
+			 * is not an error.
+			 */
+			IWL_DEBUG_EEPROM(mvm->trans->dev,
+					 "NVM access command failed on offset 0x%x since that section size is multiple 2K\n",
+					 offset);
+			ret = 0;
+		} else {
+			IWL_DEBUG_EEPROM(mvm->trans->dev,
+					 "NVM access command failed with status %d (device: %s)\n",
+					 ret, mvm->cfg->name);
+			ret = -EIO;
+		}
 		goto exit;
 	}
 
@@ -211,9 +233,9 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
 	while (ret == length) {
 		ret = iwl_nvm_read_chunk(mvm, section, offset, length, data);
 		if (ret < 0) {
-			IWL_ERR(mvm,
-				"Cannot read NVM from section %d offset %d, length %d\n",
-				section, offset, length);
+			IWL_DEBUG_EEPROM(mvm->trans->dev,
+					 "Cannot read NVM from section %d offset %d, length %d\n",
+					 section, offset, length);
 			return ret;
 		}
 		offset += ret;
@@ -436,32 +458,14 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
 
 int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
 {
-	int ret, i, section;
+	int ret, section;
 	u8 *nvm_buffer, *temp;
-	int nvm_to_read[NVM_MAX_NUM_SECTIONS];
-	int num_of_sections_to_read;
 
 	if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS))
 		return -EINVAL;
 
 	/* load NVM values from nic */
 	if (read_nvm_from_nic) {
-		/* list of NVM sections we are allowed/need to read */
-		if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
-			nvm_to_read[0] = mvm->cfg->nvm_hw_section_num;
-			nvm_to_read[1] = NVM_SECTION_TYPE_SW;
-			nvm_to_read[2] = NVM_SECTION_TYPE_CALIBRATION;
-			nvm_to_read[3] = NVM_SECTION_TYPE_PRODUCTION;
-			num_of_sections_to_read = 4;
-		} else {
-			nvm_to_read[0] = NVM_SECTION_TYPE_SW;
-			nvm_to_read[1] = NVM_SECTION_TYPE_CALIBRATION;
-			nvm_to_read[2] = NVM_SECTION_TYPE_PRODUCTION;
-			nvm_to_read[3] = NVM_SECTION_TYPE_REGULATORY;
-			nvm_to_read[4] = NVM_SECTION_TYPE_MAC_OVERRIDE;
-			num_of_sections_to_read = 5;
-		}
-
 		/* Read From FW NVM */
 		IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
 
@@ -469,12 +473,11 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
 				     GFP_KERNEL);
 		if (!nvm_buffer)
 			return -ENOMEM;
-		for (i = 0; i < num_of_sections_to_read; i++) {
-			section = nvm_to_read[i];
+		for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) {
 			/* we override the constness for initial read */
 			ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
 			if (ret < 0)
-				break;
+				continue;
 			temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
 			if (!temp) {
 				ret = -ENOMEM;
@@ -503,13 +506,10 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
 					mvm->nvm_hw_blob.size = ret;
 					break;
 				}
-				WARN(1, "section: %d", section);
 			}
 #endif
 		}
 		kfree(nvm_buffer);
-		if (ret < 0)
-			return ret;
 	}
 
 	/* load external NVM if configured */
-- 
1.8.3.2


  parent reply	other threads:[~2014-05-15 17:05 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-15 17:03 pull request iwlwifi-next 2014-05-15 Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 01/24] iwlwifi: add missing trailing newlines to debug messages Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 02/24] iwlwifi: dvm: don't use _ni mac80211's callbacks Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 03/24] iwlwifi: 8000: add default NVM file name in family 8000 Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 04/24] iwlwifi: pcie: try to get ownership several times Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 05/24] iwlwifi: mvm: add channel 14 to the low band list Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 06/24] iwlwifi: mvm: notify sched scan complete from stop routine Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 07/24] iwlwifi: mvm: stop sched scan before association Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 08/24] iwlwifi: mvm: Add power management support for P2P DCM Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 09/24] iwlwifi: mvm: Disable uAPSD for a DCM client Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 10/24] iwlwifi: cause build error on missing newline Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 11/24] iwlwifi: remove spurious newline in Kconfig Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 12/24] iwlwifi: remove CMD_SYNC Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 13/24] iwlwifi: use dev_printk instead of dev_dbg for debug logs Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 14/24] iwlwifi: pcie: disable BHs in iwl_pcie_txq_check_wrptrs Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 15/24] iwlwifi: mvm: set SKIP_OVER_DTIM flag only if needed Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 16/24] iwlwifi: mvm: BT Coex - fix boost register / LUT values Emmanuel Grumbach
2014-05-15 17:04 ` Emmanuel Grumbach [this message]
2014-05-15 17:04 ` [PATCH 18/24] iwlwifi: mvm: enable RX chain diversity if needed Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 19/24] iwlwifi: allow dynamic configuration of internal memory Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 20/24] iwlwifi: mvm: add uapsd_disable module parameter Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 21/24] iwlwifi: mvm: BT Coex - send channel inhibition before association Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 22/24] iwlwifi: mvm: combine p2p and station mac context functions Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 23/24] iwlwifi: update nmi register Emmanuel Grumbach
2014-05-15 17:04 ` [PATCH 24/24] iwlwifi: fix LED support Kconfig dependencies Emmanuel Grumbach
2014-05-16 18:19 ` pull request iwlwifi-next 2014-05-15 John W. Linville

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=1400173481-9047-17-git-send-email-egrumbach@gmail.com \
    --to=egrumbach@gmail.com \
    --cc=emmanuel.grumbach@intel.com \
    --cc=eran.harary@intel.com \
    --cc=linux-wireless@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).