summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2012-07-12 17:35:33 +0300
committerJohannes Berg <johannes.berg@intel.com>2012-07-17 12:17:42 +0200
commit88bc40e8c3d3bca7d26c756bb0b823d4abad3355 (patch)
treef792abdb4ba22c36640a85b2b89ec797c772700c
parent14cdf112019c1d4bc0f1bf9a9c832be641dbe25a (diff)
mac80211: go out of PS before sending disassoc
on disassoc, ieee80211_set_disassoc() goes out of PS before indicating BSS_CHANGED_ASSOC (not sure why this is needed, but some drivers might count on the current behavior). However, it does it after sending the disassoc frame, which results in null-data frame being sent (in order to go out of ps) after we were already sent the disassoc, which is invalid. Fix it by going out of ps before sending the disassoc. Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/mlme.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4efcbf89a72d..7c0613ce38bc 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1364,6 +1364,17 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
}
mutex_unlock(&local->sta_mtx);
+ /*
+ * if we want to get out of ps before disassoc (why?) we have
+ * to do it before sending disassoc, as otherwise the null-packet
+ * won't be valid.
+ */
+ if (local->hw.conf.flags & IEEE80211_CONF_PS) {
+ local->hw.conf.flags &= ~IEEE80211_CONF_PS;
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+ }
+ local->ps_sdata = NULL;
+
/* flush out any pending frame (e.g. DELBA) before deauth/disassoc */
if (tx)
drv_flush(local, false);
@@ -1396,12 +1407,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
del_timer_sync(&local->dynamic_ps_timer);
cancel_work_sync(&local->dynamic_ps_enable_work);
- if (local->hw.conf.flags & IEEE80211_CONF_PS) {
- local->hw.conf.flags &= ~IEEE80211_CONF_PS;
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
- }
- local->ps_sdata = NULL;
-
/* Disable ARP filtering */
if (sdata->vif.bss_conf.arp_filter_enabled) {
sdata->vif.bss_conf.arp_filter_enabled = false;