diff options
author | Loic Poulain <loic.poulain@linaro.org> | 2021-10-21 10:45:27 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2021-10-21 17:27:51 +0200 |
commit | b33fb28c867d7c86df3bdd257b0320ed148e3dc3 (patch) | |
tree | a340129bab72454b3b8c653565c34f33120a0692 /net/mac80211/pm.c | |
parent | 63fa04266629b9559d66c4dc18b03e0f9fc04a02 (diff) | |
download | lwn-b33fb28c867d7c86df3bdd257b0320ed148e3dc3.tar.gz lwn-b33fb28c867d7c86df3bdd257b0320ed148e3dc3.zip |
mac80211: Prevent AP probing during suspend
Submitting AP probe/null during suspend can cause unexpected
disconnect on resume because of timeout waiting for ack status:
wlan0: Failed to send nullfunc to AP 11:22:33:44:55:66 after 500ms, disconnecting
This is especially the case when we enter suspend when a scan is
ongoing, indeed, scan is cancelled from __ieee80211_suspend, leading
to a corresponding (aborted) scan complete event, which in turn causes
the submission of an immediate monitor null frame (restart_sta_timer).
The corresponding packet or ack will not be processed before resuming,
causing a timeout & disconnect on resume.
Delay the AP probing when suspending/suspended.
Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Link: https://lore.kernel.org/r/1634805927-1113-1-git-send-email-loic.poulain@linaro.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/pm.c')
-rw-r--r-- | net/mac80211/pm.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 7809a906d7fe..0ccb5701c7f3 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -27,6 +27,9 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) if (!local->open_count) goto suspend; + local->suspending = true; + mb(); /* make suspending visible before any cancellation */ + ieee80211_scan_cancel(local); ieee80211_dfs_cac_cancel(local); @@ -176,6 +179,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) /* need suspended to be visible before quiescing is false */ barrier(); local->quiescing = false; + local->suspending = false; return 0; } |