]> bbs.cooldavid.org Git - net-next-2.6.git/blame - net/mac80211/pm.c
ath5k: remove dummy PCI "retry timeout" fix
[net-next-2.6.git] / net / mac80211 / pm.c
CommitLineData
665af4fc
BC
1#include <net/mac80211.h>
2#include <net/rtnetlink.h>
3
4#include "ieee80211_i.h"
5#include "led.h"
6
7int __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;
7f0216a4 13 unsigned long flags;
665af4fc 14
25420604
JB
15 ieee80211_stop_queues_by_reason(hw,
16 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
17
665af4fc
BC
18 flush_workqueue(local->hw.workqueue);
19
20 /* disable keys */
21 list_for_each_entry(sdata, &local->interfaces, list)
22 ieee80211_disable_keys(sdata);
23
24 /* remove STAs */
7f0216a4
JB
25 if (local->ops->sta_notify) {
26 spin_lock_irqsave(&local->sta_lock, flags);
27 list_for_each_entry(sta, &local->sta_list, list) {
665af4fc
BC
28 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
29 sdata = container_of(sdata->bss,
30 struct ieee80211_sub_if_data,
31 u.ap);
32
33 local->ops->sta_notify(hw, &sdata->vif,
34 STA_NOTIFY_REMOVE, &sta->sta);
35 }
7f0216a4 36 spin_unlock_irqrestore(&local->sta_lock, flags);
665af4fc
BC
37 }
38
39 /* remove all interfaces */
40 list_for_each_entry(sdata, &local->interfaces, list) {
665af4fc
BC
41 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
42 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
43 netif_running(sdata->dev)) {
44 conf.vif = &sdata->vif;
45 conf.type = sdata->vif.type;
46 conf.mac_addr = sdata->dev->dev_addr;
47 local->ops->remove_interface(hw, &conf);
48 }
49 }
50
e874e658
BC
51 /* flush again, in case driver queued work */
52 flush_workqueue(local->hw.workqueue);
53
665af4fc
BC
54 /* stop hardware */
55 if (local->open_count) {
56 ieee80211_led_radio(local, false);
57 local->ops->stop(hw);
58 }
59 return 0;
60}
61
62int __ieee80211_resume(struct ieee80211_hw *hw)
63{
64 struct ieee80211_local *local = hw_to_local(hw);
65 struct ieee80211_sub_if_data *sdata;
66 struct ieee80211_if_init_conf conf;
67 struct sta_info *sta;
7f0216a4 68 unsigned long flags;
665af4fc
BC
69 int res;
70
71 /* restart hardware */
72 if (local->open_count) {
73 res = local->ops->start(hw);
74
75 ieee80211_led_radio(local, hw->conf.radio_enabled);
76 }
77
78 /* add interfaces */
79 list_for_each_entry(sdata, &local->interfaces, list) {
665af4fc
BC
80 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
81 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
82 netif_running(sdata->dev)) {
83 conf.vif = &sdata->vif;
84 conf.type = sdata->vif.type;
85 conf.mac_addr = sdata->dev->dev_addr;
86 res = local->ops->add_interface(hw, &conf);
87 }
88 }
89
90 /* add STAs back */
7f0216a4
JB
91 if (local->ops->sta_notify) {
92 spin_lock_irqsave(&local->sta_lock, flags);
93 list_for_each_entry(sta, &local->sta_list, list) {
665af4fc
BC
94 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
95 sdata = container_of(sdata->bss,
96 struct ieee80211_sub_if_data,
97 u.ap);
98
99 local->ops->sta_notify(hw, &sdata->vif,
100 STA_NOTIFY_ADD, &sta->sta);
101 }
7f0216a4 102 spin_unlock_irqrestore(&local->sta_lock, flags);
665af4fc
BC
103 }
104
105 /* add back keys */
106 list_for_each_entry(sdata, &local->interfaces, list)
107 if (netif_running(sdata->dev))
108 ieee80211_enable_keys(sdata);
109
110 /* setup RTS threshold */
111 if (local->ops->set_rts_threshold)
112 local->ops->set_rts_threshold(hw, local->rts_threshold);
113
114 /* reconfigure hardware */
115 ieee80211_hw_config(local, ~0);
116
117 netif_addr_lock_bh(local->mdev);
118 ieee80211_configure_filter(local);
119 netif_addr_unlock_bh(local->mdev);
120
25420604
JB
121 ieee80211_wake_queues_by_reason(hw,
122 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
123
665af4fc
BC
124 return 0;
125}