aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdan Kahlon <idanx.kahlon@intel.com>2014-11-13 08:47:20 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-12-01 05:04:43 -0500
commita4e5df283c9a84b29100a046e64f35bfb1660a9c (patch)
tree416f101c74ae1c2331b25ea4aa2d92483beca537
parent8ed4e659f34c963f7398ca1c92a1ab9593afba83 (diff)
iwlwifi: mvm: support NVM file with header
Handle NVM file header. When NVM header detected, skip the header and reading only the sections data. Signed-off-by: Idan Kahlon <idanx.kahlon@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index af074563e770..d55fd8e3654c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -339,11 +339,15 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
339 } *file_sec; 339 } *file_sec;
340 const u8 *eof, *temp; 340 const u8 *eof, *temp;
341 int max_section_size; 341 int max_section_size;
342 const __le32 *dword_buff;
342 343
343#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF)) 344#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
344#define NVM_WORD2_ID(x) (x >> 12) 345#define NVM_WORD2_ID(x) (x >> 12)
345#define NVM_WORD2_LEN_FAMILY_8000(x) (2 * ((x & 0xFF) << 8 | x >> 8)) 346#define NVM_WORD2_LEN_FAMILY_8000(x) (2 * ((x & 0xFF) << 8 | x >> 8))
346#define NVM_WORD1_ID_FAMILY_8000(x) (x >> 4) 347#define NVM_WORD1_ID_FAMILY_8000(x) (x >> 4)
348#define NVM_HEADER_0 (0x2A504C54)
349#define NVM_HEADER_1 (0x4E564D2A)
350#define NVM_HEADER_SIZE (4 * sizeof(u32))
347 351
348 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n"); 352 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
349 353
@@ -372,12 +376,6 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
372 IWL_INFO(mvm, "Loaded NVM file %s (%zu bytes)\n", 376 IWL_INFO(mvm, "Loaded NVM file %s (%zu bytes)\n",
373 mvm->nvm_file_name, fw_entry->size); 377 mvm->nvm_file_name, fw_entry->size);
374 378
375 if (fw_entry->size < sizeof(*file_sec)) {
376 IWL_ERR(mvm, "NVM file too small\n");
377 ret = -EINVAL;
378 goto out;
379 }
380
381 if (fw_entry->size > MAX_NVM_FILE_LEN) { 379 if (fw_entry->size > MAX_NVM_FILE_LEN) {
382 IWL_ERR(mvm, "NVM file too large\n"); 380 IWL_ERR(mvm, "NVM file too large\n");
383 ret = -EINVAL; 381 ret = -EINVAL;
@@ -385,8 +383,25 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
385 } 383 }
386 384
387 eof = fw_entry->data + fw_entry->size; 385 eof = fw_entry->data + fw_entry->size;
388 386 dword_buff = (__le32 *)fw_entry->data;
389 file_sec = (void *)fw_entry->data; 387
388 /* some NVM file will contain a header.
389 * The header is identified by 2 dwords header as follow:
390 * dword[0] = 0x2A504C54
391 * dword[1] = 0x4E564D2A
392 *
393 * This header must be skipped when providing the NVM data to the FW.
394 */
395 if (fw_entry->size > NVM_HEADER_SIZE &&
396 dword_buff[0] == cpu_to_le32(NVM_HEADER_0) &&
397 dword_buff[1] == cpu_to_le32(NVM_HEADER_1)) {
398 file_sec = (void *)(fw_entry->data + NVM_HEADER_SIZE);
399 IWL_INFO(mvm, "NVM Version %08X\n", le32_to_cpu(dword_buff[2]));
400 IWL_INFO(mvm, "NVM Manufacturing date %08X\n",
401 le32_to_cpu(dword_buff[3]));
402 } else {
403 file_sec = (void *)fw_entry->data;
404 }
390 405
391 while (true) { 406 while (true) {
392 if (file_sec->data > eof) { 407 if (file_sec->data > eof) {