summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/pcie
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-11-02 16:48:09 +0300
committerLuis Henriques <luis.henriques@canonical.com>2014-11-20 15:01:53 +0300
commitbcc79e2d7550ebb9ed7a24f0a659b651202aeac9 (patch)
treed6c7063bd4447c7d2528ed48545aff3a05735bf9 /drivers/net/wireless/iwlwifi/pcie
parentd792d804a87988cd3b9c792c581cde5f21c5025d (diff)
downloadlinux-bcc79e2d7550ebb9ed7a24f0a659b651202aeac9.tar.xz
iwlwifi: fix RFkill while calibrating
commit 31b8b343e019e0a0c57ca9c13520a87f9cab884b upstream. If the RFkill interrupt fires while we calibrate, it would make the firmware fail and the driver wasn't able to recover. Change the flow so that the driver will kill the firmware in that case. Since we have now two flows that are calling trans_stop_device (the RFkill interrupt and the op_mode_mvm_start function) - we need to better sync this. Use the STATUS_DEVICE_ENABLED in the pcie transport in an atomic way to achieve this. This fixes: https://bugzilla.kernel.org/show_bug.cgi?id=86231 Reviewed-by: Johannes Berg <johannes.berg@intel.com> Reviewed-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> [ luis: used Emmanuel's backport to 3.17 ] Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie')
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 3aefff039df0..9788fc59c13b 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -835,7 +835,8 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
* restart. So don't process again if the device is
* already dead.
*/
- if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
+ if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
+ IWL_DEBUG_INFO(trans, "DEVICE_ENABLED bit was set and is now cleared\n");
iwl_pcie_tx_stop(trans);
iwl_pcie_rx_stop(trans);
@@ -865,7 +866,6 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
/* clear all status bits */
clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
clear_bit(STATUS_INT_ENABLED, &trans->status);
- clear_bit(STATUS_DEVICE_ENABLED, &trans->status);
clear_bit(STATUS_TPOWER_PMI, &trans->status);
clear_bit(STATUS_RFKILL, &trans->status);