diff options
Diffstat (limited to 'net/mac80211/pm.c')
-rw-r--r-- | net/mac80211/pm.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c new file mode 100644 index 000000000000..44525f517077 --- /dev/null +++ b/net/mac80211/pm.c | |||
@@ -0,0 +1,117 @@ | |||
1 | #include <net/mac80211.h> | ||
2 | #include <net/rtnetlink.h> | ||
3 | |||
4 | #include "ieee80211_i.h" | ||
5 | #include "led.h" | ||
6 | |||
7 | int __ieee80211_suspend(struct ieee80211_hw *hw) | ||
8 | { | ||
9 | struct ieee80211_local *local = hw_to_local(hw); | ||
10 | struct ieee80211_sub_if_data *sdata; | ||
11 | struct ieee80211_if_init_conf conf; | ||
12 | struct sta_info *sta; | ||
13 | |||
14 | flush_workqueue(local->hw.workqueue); | ||
15 | |||
16 | /* disable keys */ | ||
17 | list_for_each_entry(sdata, &local->interfaces, list) | ||
18 | ieee80211_disable_keys(sdata); | ||
19 | |||
20 | /* remove STAs */ | ||
21 | list_for_each_entry(sta, &local->sta_list, list) { | ||
22 | |||
23 | if (local->ops->sta_notify) { | ||
24 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
25 | sdata = container_of(sdata->bss, | ||
26 | struct ieee80211_sub_if_data, | ||
27 | u.ap); | ||
28 | |||
29 | local->ops->sta_notify(hw, &sdata->vif, | ||
30 | STA_NOTIFY_REMOVE, &sta->sta); | ||
31 | } | ||
32 | } | ||
33 | |||
34 | /* remove all interfaces */ | ||
35 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
36 | |||
37 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | ||
38 | sdata->vif.type != NL80211_IFTYPE_MONITOR && | ||
39 | netif_running(sdata->dev)) { | ||
40 | conf.vif = &sdata->vif; | ||
41 | conf.type = sdata->vif.type; | ||
42 | conf.mac_addr = sdata->dev->dev_addr; | ||
43 | local->ops->remove_interface(hw, &conf); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | /* flush again, in case driver queued work */ | ||
48 | flush_workqueue(local->hw.workqueue); | ||
49 | |||
50 | /* stop hardware */ | ||
51 | if (local->open_count) { | ||
52 | ieee80211_led_radio(local, false); | ||
53 | local->ops->stop(hw); | ||
54 | } | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | int __ieee80211_resume(struct ieee80211_hw *hw) | ||
59 | { | ||
60 | struct ieee80211_local *local = hw_to_local(hw); | ||
61 | struct ieee80211_sub_if_data *sdata; | ||
62 | struct ieee80211_if_init_conf conf; | ||
63 | struct sta_info *sta; | ||
64 | int res; | ||
65 | |||
66 | /* restart hardware */ | ||
67 | if (local->open_count) { | ||
68 | res = local->ops->start(hw); | ||
69 | |||
70 | ieee80211_led_radio(local, hw->conf.radio_enabled); | ||
71 | } | ||
72 | |||
73 | /* add interfaces */ | ||
74 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
75 | |||
76 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | ||
77 | sdata->vif.type != NL80211_IFTYPE_MONITOR && | ||
78 | netif_running(sdata->dev)) { | ||
79 | conf.vif = &sdata->vif; | ||
80 | conf.type = sdata->vif.type; | ||
81 | conf.mac_addr = sdata->dev->dev_addr; | ||
82 | res = local->ops->add_interface(hw, &conf); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | /* add STAs back */ | ||
87 | list_for_each_entry(sta, &local->sta_list, list) { | ||
88 | |||
89 | if (local->ops->sta_notify) { | ||
90 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
91 | sdata = container_of(sdata->bss, | ||
92 | struct ieee80211_sub_if_data, | ||
93 | u.ap); | ||
94 | |||
95 | local->ops->sta_notify(hw, &sdata->vif, | ||
96 | STA_NOTIFY_ADD, &sta->sta); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /* add back keys */ | ||
101 | list_for_each_entry(sdata, &local->interfaces, list) | ||
102 | if (netif_running(sdata->dev)) | ||
103 | ieee80211_enable_keys(sdata); | ||
104 | |||
105 | /* setup RTS threshold */ | ||
106 | if (local->ops->set_rts_threshold) | ||
107 | local->ops->set_rts_threshold(hw, local->rts_threshold); | ||
108 | |||
109 | /* reconfigure hardware */ | ||
110 | ieee80211_hw_config(local, ~0); | ||
111 | |||
112 | netif_addr_lock_bh(local->mdev); | ||
113 | ieee80211_configure_filter(local); | ||
114 | netif_addr_unlock_bh(local->mdev); | ||
115 | |||
116 | return 0; | ||
117 | } | ||