diff options
Diffstat (limited to 'net/mac80211/pm.c')
-rw-r--r-- | net/mac80211/pm.c | 51 |
1 files changed, 33 insertions, 18 deletions
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 730778a2c90c..f87e993e713b 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -6,6 +6,28 @@ | |||
6 | #include "driver-ops.h" | 6 | #include "driver-ops.h" |
7 | #include "led.h" | 7 | #include "led.h" |
8 | 8 | ||
9 | /* return value indicates whether the driver should be further notified */ | ||
10 | static bool ieee80211_quiesce(struct ieee80211_sub_if_data *sdata) | ||
11 | { | ||
12 | switch (sdata->vif.type) { | ||
13 | case NL80211_IFTYPE_STATION: | ||
14 | ieee80211_sta_quiesce(sdata); | ||
15 | return true; | ||
16 | case NL80211_IFTYPE_ADHOC: | ||
17 | ieee80211_ibss_quiesce(sdata); | ||
18 | return true; | ||
19 | case NL80211_IFTYPE_MESH_POINT: | ||
20 | ieee80211_mesh_quiesce(sdata); | ||
21 | return true; | ||
22 | case NL80211_IFTYPE_AP_VLAN: | ||
23 | case NL80211_IFTYPE_MONITOR: | ||
24 | /* don't tell driver about this */ | ||
25 | return false; | ||
26 | default: | ||
27 | return true; | ||
28 | } | ||
29 | } | ||
30 | |||
9 | int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | 31 | int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) |
10 | { | 32 | { |
11 | struct ieee80211_local *local = hw_to_local(hw); | 33 | struct ieee80211_local *local = hw_to_local(hw); |
@@ -50,11 +72,19 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
50 | local->wowlan = wowlan && local->open_count; | 72 | local->wowlan = wowlan && local->open_count; |
51 | if (local->wowlan) { | 73 | if (local->wowlan) { |
52 | int err = drv_suspend(local, wowlan); | 74 | int err = drv_suspend(local, wowlan); |
53 | if (err) { | 75 | if (err < 0) { |
54 | local->quiescing = false; | 76 | local->quiescing = false; |
55 | return err; | 77 | return err; |
78 | } else if (err > 0) { | ||
79 | WARN_ON(err != 1); | ||
80 | local->wowlan = false; | ||
81 | } else { | ||
82 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
83 | cancel_work_sync(&sdata->work); | ||
84 | ieee80211_quiesce(sdata); | ||
85 | } | ||
86 | goto suspend; | ||
56 | } | 87 | } |
57 | goto suspend; | ||
58 | } | 88 | } |
59 | 89 | ||
60 | /* disable keys */ | 90 | /* disable keys */ |
@@ -82,23 +112,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
82 | list_for_each_entry(sdata, &local->interfaces, list) { | 112 | list_for_each_entry(sdata, &local->interfaces, list) { |
83 | cancel_work_sync(&sdata->work); | 113 | cancel_work_sync(&sdata->work); |
84 | 114 | ||
85 | switch(sdata->vif.type) { | 115 | if (!ieee80211_quiesce(sdata)) |
86 | case NL80211_IFTYPE_STATION: | ||
87 | ieee80211_sta_quiesce(sdata); | ||
88 | break; | ||
89 | case NL80211_IFTYPE_ADHOC: | ||
90 | ieee80211_ibss_quiesce(sdata); | ||
91 | break; | ||
92 | case NL80211_IFTYPE_MESH_POINT: | ||
93 | ieee80211_mesh_quiesce(sdata); | ||
94 | break; | ||
95 | case NL80211_IFTYPE_AP_VLAN: | ||
96 | case NL80211_IFTYPE_MONITOR: | ||
97 | /* don't tell driver about this */ | ||
98 | continue; | 116 | continue; |
99 | default: | ||
100 | break; | ||
101 | } | ||
102 | 117 | ||
103 | if (!ieee80211_sdata_running(sdata)) | 118 | if (!ieee80211_sdata_running(sdata)) |
104 | continue; | 119 | continue; |