#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 */
 }
 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
 
 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);
 
 
 /* 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
 
 #include "mvm.h"
 #include "sta.h"
 #include "iwl-io.h"
-#include "iwl-prph.h"
 #include "debugfs.h"
 #include "iwl-fw-error-dump.h"
 
 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;
 }
 
                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);
 }
 
 /*
                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);
                }
        }
 
                               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;