aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel/iwlwifi/iwl-io.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-io.c82
1 files changed, 53 insertions, 29 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c
index 2b7ef1583e7f..33d42e08d5b8 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c
@@ -66,10 +66,10 @@ IWL_EXPORT_SYMBOL(iwl_poll_bit);
u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
{
u32 value = 0x5a5a5a5a;
- unsigned long flags;
- if (iwl_trans_grab_nic_access(trans, &flags)) {
+
+ if (iwl_trans_grab_nic_access(trans)) {
value = iwl_read32(trans, reg);
- iwl_trans_release_nic_access(trans, &flags);
+ iwl_trans_release_nic_access(trans);
}
return value;
@@ -78,22 +78,18 @@ IWL_EXPORT_SYMBOL(iwl_read_direct32);
void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
{
- unsigned long flags;
-
- if (iwl_trans_grab_nic_access(trans, &flags)) {
+ if (iwl_trans_grab_nic_access(trans)) {
iwl_write32(trans, reg, value);
- iwl_trans_release_nic_access(trans, &flags);
+ iwl_trans_release_nic_access(trans);
}
}
IWL_EXPORT_SYMBOL(iwl_write_direct32);
void iwl_write_direct64(struct iwl_trans *trans, u64 reg, u64 value)
{
- unsigned long flags;
-
- if (iwl_trans_grab_nic_access(trans, &flags)) {
+ if (iwl_trans_grab_nic_access(trans)) {
iwl_write64(trans, reg, value);
- iwl_trans_release_nic_access(trans, &flags);
+ iwl_trans_release_nic_access(trans);
}
}
IWL_EXPORT_SYMBOL(iwl_write_direct64);
@@ -139,12 +135,11 @@ IWL_EXPORT_SYMBOL(iwl_write_prph64_no_grab);
u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
{
- unsigned long flags;
u32 val = 0x5a5a5a5a;
- if (iwl_trans_grab_nic_access(trans, &flags)) {
+ if (iwl_trans_grab_nic_access(trans)) {
val = iwl_read_prph_no_grab(trans, ofs);
- iwl_trans_release_nic_access(trans, &flags);
+ iwl_trans_release_nic_access(trans);
}
return val;
}
@@ -152,12 +147,10 @@ IWL_EXPORT_SYMBOL(iwl_read_prph);
void iwl_write_prph_delay(struct iwl_trans *trans, u32 ofs, u32 val, u32 delay_ms)
{
- unsigned long flags;
-
- if (iwl_trans_grab_nic_access(trans, &flags)) {
+ if (iwl_trans_grab_nic_access(trans)) {
mdelay(delay_ms);
iwl_write_prph_no_grab(trans, ofs, val);
- iwl_trans_release_nic_access(trans, &flags);
+ iwl_trans_release_nic_access(trans);
}
}
IWL_EXPORT_SYMBOL(iwl_write_prph_delay);
@@ -179,13 +172,11 @@ int iwl_poll_prph_bit(struct iwl_trans *trans, u32 addr,
void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
{
- unsigned long flags;
-
- if (iwl_trans_grab_nic_access(trans, &flags)) {
+ if (iwl_trans_grab_nic_access(trans)) {
iwl_write_prph_no_grab(trans, ofs,
iwl_read_prph_no_grab(trans, ofs) |
mask);
- iwl_trans_release_nic_access(trans, &flags);
+ iwl_trans_release_nic_access(trans);
}
}
IWL_EXPORT_SYMBOL(iwl_set_bits_prph);
@@ -193,26 +184,23 @@ IWL_EXPORT_SYMBOL(iwl_set_bits_prph);
void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
u32 bits, u32 mask)
{
- unsigned long flags;
-
- if (iwl_trans_grab_nic_access(trans, &flags)) {
+ if (iwl_trans_grab_nic_access(trans)) {
iwl_write_prph_no_grab(trans, ofs,
(iwl_read_prph_no_grab(trans, ofs) &
mask) | bits);
- iwl_trans_release_nic_access(trans, &flags);
+ iwl_trans_release_nic_access(trans);
}
}
IWL_EXPORT_SYMBOL(iwl_set_bits_mask_prph);
void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
{
- unsigned long flags;
u32 val;
- if (iwl_trans_grab_nic_access(trans, &flags)) {
+ if (iwl_trans_grab_nic_access(trans)) {
val = iwl_read_prph_no_grab(trans, ofs);
iwl_write_prph_no_grab(trans, ofs, (val & ~mask));
- iwl_trans_release_nic_access(trans, &flags);
+ iwl_trans_release_nic_access(trans);
}
}
IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
@@ -446,3 +434,39 @@ int iwl_finish_nic_init(struct iwl_trans *trans,
return err < 0 ? err : 0;
}
IWL_EXPORT_SYMBOL(iwl_finish_nic_init);
+
+void iwl_trans_sync_nmi_with_addr(struct iwl_trans *trans, u32 inta_addr,
+ u32 sw_err_bit)
+{
+ unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT;
+ bool interrupts_enabled = test_bit(STATUS_INT_ENABLED, &trans->status);
+
+ /* if the interrupts were already disabled, there is no point in
+ * calling iwl_disable_interrupts
+ */
+ if (interrupts_enabled)
+ iwl_trans_interrupts(trans, false);
+
+ iwl_force_nmi(trans);
+ while (time_after(timeout, jiffies)) {
+ u32 inta_hw = iwl_read32(trans, inta_addr);
+
+ /* Error detected by uCode */
+ if (inta_hw & sw_err_bit) {
+ /* Clear causes register */
+ iwl_write32(trans, inta_addr, inta_hw & sw_err_bit);
+ break;
+ }
+
+ mdelay(1);
+ }
+
+ /* enable interrupts only if there were already enabled before this
+ * function to avoid a case were the driver enable interrupts before
+ * proper configurations were made
+ */
+ if (interrupts_enabled)
+ iwl_trans_interrupts(trans, true);
+
+ iwl_trans_fw_error(trans);
+}