summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2014-11-17 14:46:37 +0100
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-11-23 19:11:33 +0100
commitfe45773b5baa154468416aac1304f6325939f775 (patch)
treef5266e692475fdc716e231440fba11843590454a /drivers/net/wireless/iwlwifi
parentiwlwifi: mvm: disable beacon filtering escape timer (diff)
downloadlinux-fe45773b5baa154468416aac1304f6325939f775.tar.xz
linux-fe45773b5baa154468416aac1304f6325939f775.zip
iwlwifi: pcie: support loading FW with extended mem range
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>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h6
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c26
2 files changed, 28 insertions, 4 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 1560f4576c7d..90011b13fc9c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -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__ */
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index b81d1412c352..a3b63b77b4ba 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -79,6 +79,10 @@
#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",