Skip to content

Commit

Permalink
Merge tag 'iwlwifi-for-john-2014-11-03' of git://git.kernel.org/pub/s…
Browse files Browse the repository at this point in the history
…cm/linux/kernel/git/iwlwifi/iwlwifi-fixes

Emmanuel Grumbach <[email protected]> says:

"I fix here two issues that are related to the firmware
loading flow. A user reported that he couldn't load the
driver because the rfkill line was pulled up while we
were running the calibrations. This was happening while
booting the system: systemd was restoring the "disable
wifi settings" and that raised an RFKILL interrupt during
the calibration. Our driver didn't handle that properly
and this is now fixed."

Signed-off-by: John W. Linville <[email protected]>
  • Loading branch information
linvjw committed Nov 4, 2014
2 parents 75a916e + 31b8b34 commit c00ed46
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 4 deletions.
10 changes: 9 additions & 1 deletion drivers/net/wireless/iwlwifi/mvm/fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)

lockdep_assert_held(&mvm->mutex);

if (WARN_ON_ONCE(mvm->init_ucode_complete))
if (WARN_ON_ONCE(mvm->init_ucode_complete || mvm->calibrating))
return 0;

iwl_init_notification_wait(&mvm->notif_wait,
Expand Down Expand Up @@ -334,6 +334,8 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
goto out;
}

mvm->calibrating = true;

/* Send TX valid antennas before triggering calibrations */
ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
if (ret)
Expand All @@ -358,11 +360,17 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
MVM_UCODE_CALIB_TIMEOUT);
if (!ret)
mvm->init_ucode_complete = true;

if (ret && iwl_mvm_is_radio_killed(mvm)) {
IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
ret = 1;
}
goto out;

error:
iwl_remove_notification(&mvm->notif_wait, &calib_wait);
out:
mvm->calibrating = false;
if (iwlmvm_mod_params.init_dbg && !mvm->nvm_data) {
/* we want to debug INIT and we have no NVM - fake */
mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) +
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/mvm/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)

mvm->scan_status = IWL_MVM_SCAN_NONE;
mvm->ps_disabled = false;
mvm->calibrating = false;

/* just in case one was running */
ieee80211_remain_on_channel_expired(mvm->hw);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/mvm/mvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ struct iwl_mvm {
enum iwl_ucode_type cur_ucode;
bool ucode_loaded;
bool init_ucode_complete;
bool calibrating;
u32 error_event_table;
u32 log_event_table;
u32 umac_error_event_table;
Expand Down
12 changes: 11 additions & 1 deletion drivers/net/wireless/iwlwifi/mvm/ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
}
mvm->sf_state = SF_UNINIT;
mvm->low_latency_agg_frame_limit = 6;
mvm->cur_ucode = IWL_UCODE_INIT;

mutex_init(&mvm->mutex);
mutex_init(&mvm->d0i3_suspend_mutex);
Expand Down Expand Up @@ -752,6 +753,7 @@ 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 = ACCESS_ONCE(mvm->calibrating);

if (state)
set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
Expand All @@ -760,7 +762,15 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)

wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));

return state && mvm->cur_ucode != IWL_UCODE_INIT;
/* iwl_run_init_mvm_ucode is waiting for results, abort it */
if (calibrating)
iwl_abort_notification_waits(&mvm->notif_wait);

/*
* Stop the device if we run OPERATIONAL firmware or if we are in the
* middle of the calibrations.
*/
return state && (mvm->cur_ucode != IWL_UCODE_INIT || calibrating);
}

static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/iwlwifi/pcie/trans.c
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,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);

Expand Down Expand Up @@ -945,7 +946,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);

Expand Down

0 comments on commit c00ed46

Please sign in to comment.