Skip to content

Commit 728e825

Browse files
lucacoelhoegrumbach
authored andcommitted
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: Luca Coelho <[email protected]> Signed-off-by: Emmanuel Grumbach <[email protected]>
1 parent 097129c commit 728e825

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

drivers/net/wireless/intel/iwlwifi/mvm/mvm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ struct iwl_mvm {
710710
struct iwl_mcast_filter_cmd *mcast_filter_cmd;
711711
enum iwl_mvm_scan_type scan_type;
712712
enum iwl_mvm_sched_scan_pass_all_states sched_scan_pass_all;
713+
struct timer_list scan_timer;
713714

714715
/* max number of simultaneous scans the FW supports */
715716
unsigned int max_scans;
@@ -1314,6 +1315,7 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm);
13141315
int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify);
13151316
int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm);
13161317
void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm);
1318+
void iwl_mvm_scan_timeout(unsigned long data);
13171319

13181320
/* Scheduled scan */
13191321
void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,

drivers/net/wireless/intel/iwlwifi/mvm/ops.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
728728

729729
iwl_mvm_tof_init(mvm);
730730

731+
setup_timer(&mvm->scan_timer, iwl_mvm_scan_timeout,
732+
(unsigned long)mvm);
733+
731734
return op_mode;
732735

733736
out_unregister:
@@ -783,6 +786,8 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
783786

784787
iwl_mvm_tof_clean(mvm);
785788

789+
del_timer_sync(&mvm->scan_timer);
790+
786791
mutex_destroy(&mvm->mutex);
787792
mutex_destroy(&mvm->d0i3_suspend_mutex);
788793

drivers/net/wireless/intel/iwlwifi/mvm/scan.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070

7171
#include "mvm.h"
7272
#include "fw-api-scan.h"
73+
#include "iwl-io.h"
7374

7475
#define IWL_DENSE_EBS_SCAN_RATIO 5
7576
#define IWL_SPARSE_EBS_SCAN_RATIO 1
@@ -398,6 +399,10 @@ void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
398399
ieee80211_scan_completed(mvm->hw,
399400
scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED);
400401
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
402+
del_timer(&mvm->scan_timer);
403+
} else {
404+
IWL_ERR(mvm,
405+
"got scan complete notification but no scan is running\n");
401406
}
402407

403408
mvm->last_ebs_successful =
@@ -1217,6 +1222,18 @@ static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type)
12171222
return -EIO;
12181223
}
12191224

1225+
#define SCAN_TIMEOUT (16 * HZ)
1226+
1227+
void iwl_mvm_scan_timeout(unsigned long data)
1228+
{
1229+
struct iwl_mvm *mvm = (struct iwl_mvm *)data;
1230+
1231+
IWL_ERR(mvm, "regular scan timed out\n");
1232+
1233+
del_timer(&mvm->scan_timer);
1234+
iwl_force_nmi(mvm->trans);
1235+
}
1236+
12201237
int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
12211238
struct cfg80211_scan_request *req,
12221239
struct ieee80211_scan_ies *ies)
@@ -1296,6 +1313,8 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
12961313
mvm->scan_status |= IWL_MVM_SCAN_REGULAR;
12971314
iwl_mvm_ref(mvm, IWL_MVM_REF_SCAN);
12981315

1316+
mod_timer(&mvm->scan_timer, jiffies + SCAN_TIMEOUT);
1317+
12991318
return 0;
13001319
}
13011320

@@ -1413,6 +1432,7 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
14131432
if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_REGULAR) {
14141433
ieee80211_scan_completed(mvm->hw, aborted);
14151434
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
1435+
del_timer(&mvm->scan_timer);
14161436
} else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
14171437
ieee80211_sched_scan_stopped(mvm->hw);
14181438
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)
16081628
* to release the scan reference here.
16091629
*/
16101630
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
1631+
del_timer(&mvm->scan_timer);
16111632
if (notify)
16121633
ieee80211_scan_completed(mvm->hw, true);
16131634
} else if (notify) {

0 commit comments

Comments
 (0)