iwlwifi: update nmi register
authorLiad Kaufman <liad.kaufman@intel.com>
Sun, 27 Apr 2014 13:46:09 +0000 (16:46 +0300)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Thu, 15 May 2014 16:50:51 +0000 (19:50 +0300)
In the 8000 HW family the register for forcing an NMI has
changed, so this allows to still be able to force an NMI
while taking into account the HW in order to write to the
correct register.

Signed-off-by: Liad Kaufman <liad.kaufman@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/iwl-io.c
drivers/net/wireless/iwlwifi/iwl-io.h
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/pcie/tx.c

index 44cc3cf45762d1465e47627b70eea990f257e3a3..5eef4ae7333bad13527327cc851f022f23e3f991 100644 (file)
@@ -33,6 +33,7 @@
 #include "iwl-io.h"
 #include "iwl-csr.h"
 #include "iwl-debug.h"
+#include "iwl-prph.h"
 #include "iwl-fh.h"
 
 #define IWL_POLL_INTERVAL 10   /* microseconds */
@@ -183,6 +184,23 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
 }
 IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
 
+void iwl_force_nmi(struct iwl_trans *trans)
+{
+       /*
+        * In HW previous to the 8000 HW family, and in the 8000 HW family
+        * itself when the revision step==0, the DEVICE_SET_NMI_REG is used
+        * to force an NMI. Otherwise, a different register -
+        * DEVICE_SET_NMI_8000B_REG - is used.
+        */
+       if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) ||
+           ((trans->hw_rev & 0xc) == 0x0))
+               iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL);
+       else
+               iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG,
+                              DEVICE_SET_NMI_8000B_VAL);
+}
+IWL_EXPORT_SYMBOL(iwl_force_nmi);
+
 static const char *get_fh_string(int cmd)
 {
 #define IWL_CMD(x) case x: return #x
index 665ddd9dbbc48ff5dec47f246b8efb0639fb5c86..705d12c079e8b2ef2492ca82a56aa92d64cfe09b 100644 (file)
@@ -80,6 +80,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask);
 void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
                            u32 bits, u32 mask);
 void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask);
+void iwl_force_nmi(struct iwl_trans *trans);
 
 /* Error handling */
 int iwl_dump_fh(struct iwl_trans *trans, char **buf);
index 779311080a9ef8c0a18dd2a305121fa4d058a128..4997e27672b3ae22b4176df391a5bbb3ae9e1f4d 100644 (file)
 
 /* Device NMI register */
 #define DEVICE_SET_NMI_REG 0x00a01c30
+#define DEVICE_SET_NMI_VAL 0x1
+#define DEVICE_SET_NMI_8000B_REG 0x00a01c24
+#define DEVICE_SET_NMI_8000B_VAL 0x1000000
 
 /* Shared registers (0x0..0x3ff, via target indirect or periphery */
 #define SHR_BASE       0x00a10000
index e57812999033fedb25d0e7daab63fc22cf8f3c16..29ca72695eaa60e0f53121dd45f1d080cdefba1d 100644 (file)
@@ -65,7 +65,6 @@
 #include "mvm.h"
 #include "sta.h"
 #include "iwl-io.h"
-#include "iwl-prph.h"
 #include "debugfs.h"
 #include "iwl-fw-error-dump.h"
 
@@ -691,7 +690,7 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
 static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
                                      size_t count, loff_t *ppos)
 {
-       iwl_write_prph(mvm->trans, DEVICE_SET_NMI_REG, 1);
+       iwl_force_nmi(mvm->trans);
 
        return count;
 }
index 2841af350f2a132ab681d9671e3a55617d76b6d3..038940afbdc57d8d176908bb4869fc8791f250eb 100644 (file)
@@ -201,7 +201,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
                IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
                        le32_to_cpu(txq->scratchbufs[i].scratch));
 
-       iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1);
+       iwl_force_nmi(trans);
 }
 
 /*
@@ -1029,7 +1029,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
                if (nfreed++ > 0) {
                        IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n",
                                idx, q->write_ptr, q->read_ptr);
-                       iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1);
+                       iwl_force_nmi(trans);
                }
        }
 
@@ -1600,7 +1600,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
                               get_cmd_string(trans_pcie, cmd->id));
                ret = -ETIMEDOUT;
 
-               iwl_write_prph(trans, DEVICE_SET_NMI_REG, 1);
+               iwl_force_nmi(trans);
                iwl_trans_fw_error(trans);
 
                goto cancel;