diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-12-13 20:16:45 +0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-01-03 16:01:34 +0400 |
commit | 529ba6e9313dbe60dab7e72c6fdf647a012e9f5b (patch) | |
tree | a556b0d18baf4309ebf705715440e702d5acb86b /net/mac80211/pm.c | |
parent | 61e8a48cc1283c8e4358b3ce06305d886c55f7ce (diff) | |
download | linux-529ba6e9313dbe60dab7e72c6fdf647a012e9f5b.tar.xz |
mac80211: clean up association better in suspend
When suspending, bss_info_changed() is called to
disable beacons, but managed mode interfaces are
simply removed (bss_info_changed() is called with
"no change" only). This can lead to problems.
To fix this and copy the BSS configuration, clear
it during suspend and restore it on resume.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/pm.c')
-rw-r--r-- | net/mac80211/pm.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index f3217831d236..712c17ff6e22 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -121,6 +121,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) /* remove all interfaces */ list_for_each_entry(sdata, &local->interfaces, list) { + u32 changed = BSS_CHANGED_BEACON_ENABLED; + if (!ieee80211_sdata_running(sdata)) continue; @@ -129,14 +131,25 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) case NL80211_IFTYPE_MONITOR: /* skip these */ continue; + case NL80211_IFTYPE_STATION: + if (sdata->vif.bss_conf.assoc) + changed = BSS_CHANGED_ASSOC | + BSS_CHANGED_BSSID | + BSS_CHANGED_IDLE; + else + changed = 0; + /* fall through */ default: ieee80211_quiesce(sdata); break; } - /* disable beaconing */ - ieee80211_bss_info_change_notify(sdata, - BSS_CHANGED_BEACON_ENABLED); + sdata->suspend_bss_conf = sdata->vif.bss_conf; + memset(&sdata->vif.bss_conf, 0, sizeof(sdata->vif.bss_conf)); + sdata->vif.bss_conf.idle = true; + + /* disable beaconing or remove association */ + ieee80211_bss_info_change_notify(sdata, changed); if (sdata->vif.type == NL80211_IFTYPE_AP && rcu_access_pointer(sdata->u.ap.beacon)) |