diff options
Diffstat (limited to 'net/mac80211/offchannel.c')
-rw-r--r-- | net/mac80211/offchannel.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index c36b1911987a..4b564091e51d 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -22,12 +22,16 @@ | |||
22 | static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) | 22 | static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) |
23 | { | 23 | { |
24 | struct ieee80211_local *local = sdata->local; | 24 | struct ieee80211_local *local = sdata->local; |
25 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
25 | 26 | ||
26 | local->offchannel_ps_enabled = false; | 27 | local->offchannel_ps_enabled = false; |
27 | 28 | ||
28 | /* FIXME: what to do when local->pspolling is true? */ | 29 | /* FIXME: what to do when local->pspolling is true? */ |
29 | 30 | ||
30 | del_timer_sync(&local->dynamic_ps_timer); | 31 | del_timer_sync(&local->dynamic_ps_timer); |
32 | del_timer_sync(&ifmgd->bcn_mon_timer); | ||
33 | del_timer_sync(&ifmgd->conn_mon_timer); | ||
34 | |||
31 | cancel_work_sync(&local->dynamic_ps_enable_work); | 35 | cancel_work_sync(&local->dynamic_ps_enable_work); |
32 | 36 | ||
33 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 37 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
@@ -85,6 +89,9 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata) | |||
85 | mod_timer(&local->dynamic_ps_timer, jiffies + | 89 | mod_timer(&local->dynamic_ps_timer, jiffies + |
86 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | 90 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); |
87 | } | 91 | } |
92 | |||
93 | ieee80211_sta_reset_beacon_monitor(sdata); | ||
94 | ieee80211_sta_reset_conn_monitor(sdata); | ||
88 | } | 95 | } |
89 | 96 | ||
90 | void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) | 97 | void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) |
@@ -112,8 +119,10 @@ void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) | |||
112 | * used from user space controlled off-channel operations. | 119 | * used from user space controlled off-channel operations. |
113 | */ | 120 | */ |
114 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 121 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
115 | sdata->vif.type != NL80211_IFTYPE_MONITOR) | 122 | sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
123 | set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); | ||
116 | netif_tx_stop_all_queues(sdata->dev); | 124 | netif_tx_stop_all_queues(sdata->dev); |
125 | } | ||
117 | } | 126 | } |
118 | mutex_unlock(&local->iflist_mtx); | 127 | mutex_unlock(&local->iflist_mtx); |
119 | } | 128 | } |
@@ -131,6 +140,7 @@ void ieee80211_offchannel_stop_station(struct ieee80211_local *local) | |||
131 | continue; | 140 | continue; |
132 | 141 | ||
133 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 142 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
143 | set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); | ||
134 | netif_tx_stop_all_queues(sdata->dev); | 144 | netif_tx_stop_all_queues(sdata->dev); |
135 | if (sdata->u.mgd.associated) | 145 | if (sdata->u.mgd.associated) |
136 | ieee80211_offchannel_ps_enable(sdata); | 146 | ieee80211_offchannel_ps_enable(sdata); |
@@ -155,8 +165,20 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, | |||
155 | ieee80211_offchannel_ps_disable(sdata); | 165 | ieee80211_offchannel_ps_disable(sdata); |
156 | } | 166 | } |
157 | 167 | ||
158 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) | 168 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
169 | clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); | ||
170 | /* | ||
171 | * This may wake up queues even though the driver | ||
172 | * currently has them stopped. This is not very | ||
173 | * likely, since the driver won't have gotten any | ||
174 | * (or hardly any) new packets while we weren't | ||
175 | * on the right channel, and even if it happens | ||
176 | * it will at most lead to queueing up one more | ||
177 | * packet per queue in mac80211 rather than on | ||
178 | * the interface qdisc. | ||
179 | */ | ||
159 | netif_tx_wake_all_queues(sdata->dev); | 180 | netif_tx_wake_all_queues(sdata->dev); |
181 | } | ||
160 | 182 | ||
161 | /* re-enable beaconing */ | 183 | /* re-enable beaconing */ |
162 | if (enable_beaconing && | 184 | if (enable_beaconing && |