iwlwifi: fix load in rfkill flow for unified firmware

When we have a single image (same firmware image for INIT and
OPERATIONAL), we couldn't load the driver and register to the
stack if we had hardware RF-Kill asserted.

Fix this. This required a few changes:

1) Run the firmware as part of the INIT phase even if its
   ucode_type is not IWL_UCODE_INIT.
2) Send the commands that are sent to the unified image in
   INIT flow even in RF-Kill.
3) Don't ask the transport to stop the hardware upon RF-Kill
   interrupt if the RF-Kill is asserted.
4) Allow the RF-Kill interrupt to take us out of L1A so that
   the RF-Kill interrupt will be received by the host (to
   enable the radio).

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Emmanuel Grumbach
2019-05-29 16:39:50 +03:00
committed by Kalle Valo
parent 23f57bfac7
commit b3500b472c
5 changed files with 33 additions and 13 deletions

View File

@@ -1209,7 +1209,8 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
bool calibrating = READ_ONCE(mvm->calibrating);
bool rfkill_safe_init_done = READ_ONCE(mvm->rfkill_safe_init_done);
bool unified = iwl_mvm_has_unified_ucode(mvm);
if (state)
set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
@@ -1218,15 +1219,23 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
iwl_mvm_set_rfkill_state(mvm);
/* iwl_run_init_mvm_ucode is waiting for results, abort it */
if (calibrating)
/* iwl_run_init_mvm_ucode is waiting for results, abort it. */
if (rfkill_safe_init_done)
iwl_abort_notification_waits(&mvm->notif_wait);
/*
* Don't ask the transport to stop the firmware. We'll do it
* after cfg80211 takes us down.
*/
if (unified)
return false;
/*
* Stop the device if we run OPERATIONAL firmware or if we are in the
* middle of the calibrations.
*/
return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT || calibrating);
return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT ||
rfkill_safe_init_done);
}
static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)