Commit 728e825f authored by Luca Coelho's avatar Luca Coelho Committed by Emmanuel Grumbach

iwlwifi: mvm: add a scan timeout for regular scans

If something goes wrong with the firmware and we never get a scan
complete notification, we stay stuck forever.  In order to avoid this
situation, add a timeout and trigger an NMI if it expires before
receiving the notification., so we can clean things up.
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 097129c9
......@@ -710,6 +710,7 @@ struct iwl_mvm {
struct iwl_mcast_filter_cmd *mcast_filter_cmd;
enum iwl_mvm_scan_type scan_type;
enum iwl_mvm_sched_scan_pass_all_states sched_scan_pass_all;
struct timer_list scan_timer;
/* max number of simultaneous scans the FW supports */
unsigned int max_scans;
......@@ -1314,6 +1315,7 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm);
int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify);
int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm);
void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm);
void iwl_mvm_scan_timeout(unsigned long data);
/* Scheduled scan */
void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
......
......@@ -728,6 +728,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
iwl_mvm_tof_init(mvm);
setup_timer(&mvm->scan_timer, iwl_mvm_scan_timeout,
(unsigned long)mvm);
return op_mode;
out_unregister:
......@@ -783,6 +786,8 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
iwl_mvm_tof_clean(mvm);
del_timer_sync(&mvm->scan_timer);
mutex_destroy(&mvm->mutex);
mutex_destroy(&mvm->d0i3_suspend_mutex);
......
......@@ -70,6 +70,7 @@
#include "mvm.h"
#include "fw-api-scan.h"
#include "iwl-io.h"
#define IWL_DENSE_EBS_SCAN_RATIO 5
#define IWL_SPARSE_EBS_SCAN_RATIO 1
......@@ -398,6 +399,10 @@ void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
ieee80211_scan_completed(mvm->hw,
scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED);
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
del_timer(&mvm->scan_timer);
} else {
IWL_ERR(mvm,
"got scan complete notification but no scan is running\n");
}
mvm->last_ebs_successful =
......@@ -1217,6 +1222,18 @@ static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type)
return -EIO;
}
#define SCAN_TIMEOUT (16 * HZ)
void iwl_mvm_scan_timeout(unsigned long data)
{
struct iwl_mvm *mvm = (struct iwl_mvm *)data;
IWL_ERR(mvm, "regular scan timed out\n");
del_timer(&mvm->scan_timer);
iwl_force_nmi(mvm->trans);
}
int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct cfg80211_scan_request *req,
struct ieee80211_scan_ies *ies)
......@@ -1296,6 +1313,8 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
mvm->scan_status |= IWL_MVM_SCAN_REGULAR;
iwl_mvm_ref(mvm, IWL_MVM_REF_SCAN);
mod_timer(&mvm->scan_timer, jiffies + SCAN_TIMEOUT);
return 0;
}
......@@ -1413,6 +1432,7 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_REGULAR) {
ieee80211_scan_completed(mvm->hw, aborted);
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
del_timer(&mvm->scan_timer);
} else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
ieee80211_sched_scan_stopped(mvm->hw);
mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
......@@ -1608,6 +1628,7 @@ int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify)
* to release the scan reference here.
*/
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
del_timer(&mvm->scan_timer);
if (notify)
ieee80211_scan_completed(mvm->hw, true);
} else if (notify) {
......
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