Commit bfe4b80e authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by John W. Linville

iwlwifi: always check if got h/w access before write

Before we write to the device registers always check if
iwl_grap_nic_access() was successful.

On the way change return type of grab_nic_access() to bool, and add
likely()/unlikely() statement.
Signed-off-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent aa5affba
...@@ -189,7 +189,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) ...@@ -189,7 +189,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data)
} }
iwl_read32(trans(priv), CSR_UCODE_DRV_GP1); iwl_read32(trans(priv), CSR_UCODE_DRV_GP1);
spin_lock_irqsave(&trans(priv)->reg_lock, flags); spin_lock_irqsave(&trans(priv)->reg_lock, flags);
if (!iwl_grab_nic_access(trans(priv))) if (likely(iwl_grab_nic_access(trans(priv))))
iwl_release_nic_access(trans(priv)); iwl_release_nic_access(trans(priv));
spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); spin_unlock_irqrestore(&trans(priv)->reg_lock, flags);
......
...@@ -327,7 +327,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, ...@@ -327,7 +327,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
/* Make sure device is powered up for SRAM reads */ /* Make sure device is powered up for SRAM reads */
spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags); spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags);
if (iwl_grab_nic_access(trans(priv))) { if (unlikely(!iwl_grab_nic_access(trans(priv)))) {
spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags);
return; return;
} }
......
...@@ -118,16 +118,17 @@ int iwl_grab_nic_access_silent(struct iwl_trans *trans) ...@@ -118,16 +118,17 @@ int iwl_grab_nic_access_silent(struct iwl_trans *trans)
return 0; return 0;
} }
int iwl_grab_nic_access(struct iwl_trans *trans) bool iwl_grab_nic_access(struct iwl_trans *trans)
{ {
int ret = iwl_grab_nic_access_silent(trans); int ret = iwl_grab_nic_access_silent(trans);
if (unlikely(ret)) { if (unlikely(ret)) {
u32 val = iwl_read32(trans, CSR_GP_CNTRL); u32 val = iwl_read32(trans, CSR_GP_CNTRL);
WARN_ONCE(1, "Timeout waiting for hardware access " WARN_ONCE(1, "Timeout waiting for hardware access "
"(CSR_GP_CNTRL 0x%08x)\n", val); "(CSR_GP_CNTRL 0x%08x)\n", val);
return false;
} }
return ret; return true;
} }
void iwl_release_nic_access(struct iwl_trans *trans) void iwl_release_nic_access(struct iwl_trans *trans)
...@@ -156,7 +157,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) ...@@ -156,7 +157,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
if (!iwl_grab_nic_access(trans)) { if (likely(iwl_grab_nic_access(trans))) {
iwl_write32(trans, reg, value); iwl_write32(trans, reg, value);
iwl_release_nic_access(trans); iwl_release_nic_access(trans);
} }
...@@ -211,7 +212,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) ...@@ -211,7 +212,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
if (!iwl_grab_nic_access(trans)) { if (likely(iwl_grab_nic_access(trans))) {
__iwl_write_prph(trans, addr, val); __iwl_write_prph(trans, addr, val);
iwl_release_nic_access(trans); iwl_release_nic_access(trans);
} }
...@@ -223,9 +224,11 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) ...@@ -223,9 +224,11 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
iwl_grab_nic_access(trans); if (likely(iwl_grab_nic_access(trans))) {
__iwl_write_prph(trans, reg, __iwl_read_prph(trans, reg) | mask); __iwl_write_prph(trans, reg,
iwl_release_nic_access(trans); __iwl_read_prph(trans, reg) | mask);
iwl_release_nic_access(trans);
}
spin_unlock_irqrestore(&trans->reg_lock, flags); spin_unlock_irqrestore(&trans->reg_lock, flags);
} }
...@@ -235,10 +238,11 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, ...@@ -235,10 +238,11 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg,
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
iwl_grab_nic_access(trans); if (likely(iwl_grab_nic_access(trans))) {
__iwl_write_prph(trans, reg, __iwl_write_prph(trans, reg,
(__iwl_read_prph(trans, reg) & mask) | bits); (__iwl_read_prph(trans, reg) & mask) | bits);
iwl_release_nic_access(trans); iwl_release_nic_access(trans);
}
spin_unlock_irqrestore(&trans->reg_lock, flags); spin_unlock_irqrestore(&trans->reg_lock, flags);
} }
...@@ -248,10 +252,11 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) ...@@ -248,10 +252,11 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask)
u32 val; u32 val;
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
iwl_grab_nic_access(trans); if (likely(iwl_grab_nic_access(trans))) {
val = __iwl_read_prph(trans, reg); val = __iwl_read_prph(trans, reg);
__iwl_write_prph(trans, reg, (val & ~mask)); __iwl_write_prph(trans, reg, (val & ~mask));
iwl_release_nic_access(trans); iwl_release_nic_access(trans);
}
spin_unlock_irqrestore(&trans->reg_lock, flags); spin_unlock_irqrestore(&trans->reg_lock, flags);
} }
...@@ -263,15 +268,13 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, ...@@ -263,15 +268,13 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr,
u32 *vals = buf; u32 *vals = buf;
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
iwl_grab_nic_access(trans); if (likely(iwl_grab_nic_access(trans))) {
iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); rmb();
rmb(); for (offs = 0; offs < words; offs++)
vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
for (offs = 0; offs < words; offs++) iwl_release_nic_access(trans);
vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); }
iwl_release_nic_access(trans);
spin_unlock_irqrestore(&trans->reg_lock, flags); spin_unlock_irqrestore(&trans->reg_lock, flags);
} }
...@@ -292,7 +295,7 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, ...@@ -292,7 +295,7 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr,
u32 *vals = buf; u32 *vals = buf;
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
if (!iwl_grab_nic_access(trans)) { if (likely(iwl_grab_nic_access(trans))) {
iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
wmb(); wmb();
......
...@@ -61,7 +61,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, ...@@ -61,7 +61,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
int timeout); int timeout);
int iwl_grab_nic_access_silent(struct iwl_trans *trans); int iwl_grab_nic_access_silent(struct iwl_trans *trans);
int iwl_grab_nic_access(struct iwl_trans *trans); bool iwl_grab_nic_access(struct iwl_trans *trans);
void iwl_release_nic_access(struct iwl_trans *trans); void iwl_release_nic_access(struct iwl_trans *trans);
u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg);
......
...@@ -445,7 +445,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) ...@@ -445,7 +445,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
if (iwlagn_hw_valid_rtc_data_addr(base)) { if (iwlagn_hw_valid_rtc_data_addr(base)) {
spin_lock_irqsave(&trans(priv)->reg_lock, flags); spin_lock_irqsave(&trans(priv)->reg_lock, flags);
ret = iwl_grab_nic_access_silent(trans(priv)); ret = iwl_grab_nic_access_silent(trans(priv));
if (ret == 0) { if (likely(ret == 0)) {
iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base);
status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
iwl_release_nic_access(trans(priv)); iwl_release_nic_access(trans(priv));
......
...@@ -745,7 +745,8 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, ...@@ -745,7 +745,8 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
/* Make sure device is powered up for SRAM reads */ /* Make sure device is powered up for SRAM reads */
spin_lock_irqsave(&trans->reg_lock, reg_flags); spin_lock_irqsave(&trans->reg_lock, reg_flags);
iwl_grab_nic_access(trans); if (unlikely(!iwl_grab_nic_access(trans)))
goto out_unlock;
/* Set starting address; reads will auto-increment */ /* Set starting address; reads will auto-increment */
iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr);
...@@ -785,6 +786,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, ...@@ -785,6 +786,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
/* Allow device to power down */ /* Allow device to power down */
iwl_release_nic_access(trans); iwl_release_nic_access(trans);
out_unlock:
spin_unlock_irqrestore(&trans->reg_lock, reg_flags); spin_unlock_irqrestore(&trans->reg_lock, reg_flags);
return pos; return pos;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment