iwlwifi: pcie: support loading FW with extended mem range
authorArik Nemtsov <arik@wizery.com>
Mon, 17 Nov 2014 13:46:37 +0000 (15:46 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Sun, 23 Nov 2014 18:11:33 +0000 (20:11 +0200)
Toggle the LMPM_CHICK register when writing chunks into the FW's extended
SRAM. This tells the FW to put the chunk into a different memory space.

Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/pcie/trans.c

index 1560f45..90011b1 100644 (file)
@@ -368,4 +368,10 @@ enum secure_load_status_reg {
 #define MON_BUFF_WRPTR                 (0xa03c44)
 #define MON_BUFF_CYCLE_CNT             (0xa03c48)
 
+/* FW chicken bits */
+#define LMPM_CHICK                     0xA01FF8
+enum {
+       LMPM_CHICK_EXTENDED_ADDR_SPACE = BIT(0),
+};
+
 #endif                         /* __iwl_prph_h__ */
index b81d141..a3b63b7 100644 (file)
 #include "iwl-fw-error-dump.h"
 #include "internal.h"
 
+/* extended range in FW SRAM */
+#define IWL_FW_MEM_EXTENDED_START      0x40000
+#define IWL_FW_MEM_EXTENDED_END                0x57FFF
+
 static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -627,14 +631,28 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
        }
 
        for (offset = 0; offset < section->len; offset += chunk_sz) {
-               u32 copy_size;
+               u32 copy_size, dst_addr;
+               bool extended_addr = false;
 
                copy_size = min_t(u32, chunk_sz, section->len - offset);
+               dst_addr = section->offset + offset;
+
+               if (dst_addr >= IWL_FW_MEM_EXTENDED_START &&
+                   dst_addr <= IWL_FW_MEM_EXTENDED_END)
+                       extended_addr = true;
+
+               if (extended_addr)
+                       iwl_set_bits_prph(trans, LMPM_CHICK,
+                                         LMPM_CHICK_EXTENDED_ADDR_SPACE);
 
                memcpy(v_addr, (u8 *)section->data + offset, copy_size);
-               ret = iwl_pcie_load_firmware_chunk(trans,
-                                                  section->offset + offset,
-                                                  p_addr, copy_size);
+               ret = iwl_pcie_load_firmware_chunk(trans, dst_addr, p_addr,
+                                                  copy_size);
+
+               if (extended_addr)
+                       iwl_clear_bits_prph(trans, LMPM_CHICK,
+                                           LMPM_CHICK_EXTENDED_ADDR_SPACE);
+
                if (ret) {
                        IWL_ERR(trans,
                                "Could not load the [%d] uCode section\n",