浏览代码

iwlwifi: mvm: disable the device as soon as RFKILL fires

The firmware needs to be stopped quickly (100ms) after the
RFKILL interrupt fired. Failing to do so would allow the
firmware to access the radio registers which would lead to
a hardware error.

Before this change, we would kill the firmware only when
mac80211 stops the device which can take a fair amount of
time. Take a shortcut by stopping the device right away
in the interrupt.

This is not relevant if the current firmware is INIT
firmware since that firmware can run while in RFKILL.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Emmanuel Grumbach 11 年之前
父节点
当前提交
aaa4e74110
共有 2 个文件被更改,包括 9 次插入2 次删除
  1. 2 0
      drivers/net/wireless/iwlwifi/mvm/ops.c
  2. 7 2
      drivers/net/wireless/iwlwifi/mvm/scan.c

+ 2 - 0
drivers/net/wireless/iwlwifi/mvm/ops.c

@@ -665,6 +665,8 @@ static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
 	else
 		clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
 
+	if (state && mvm->cur_ucode != IWL_UCODE_INIT)
+		iwl_trans_stop_device(mvm->trans);
 	wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
 }
 

+ 7 - 2
drivers/net/wireless/iwlwifi/mvm/scan.c

@@ -473,13 +473,18 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
 	if (mvm->scan_status == IWL_MVM_SCAN_NONE)
 		return;
 
+	if (iwl_mvm_is_radio_killed(mvm)) {
+		ieee80211_scan_completed(mvm->hw, true);
+		mvm->scan_status = IWL_MVM_SCAN_NONE;
+		return;
+	}
+
 	iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort,
 				   scan_abort_notif,
 				   ARRAY_SIZE(scan_abort_notif),
 				   iwl_mvm_scan_abort_notif, NULL);
 
-	ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD,
-				   CMD_SYNC | CMD_SEND_IN_RFKILL, 0, NULL);
+	ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, CMD_SYNC, 0, NULL);
 	if (ret) {
 		IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret);
 		/* mac80211's state will be cleaned in the fw_restart flow */