diff options
Diffstat (limited to 'net/mac80211/offchannel.c')
-rw-r--r-- | net/mac80211/offchannel.c | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index a3ad4c3c80a3..cc79b4a2e821 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -113,6 +113,15 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local) | |||
113 | * notify the AP about us leaving the channel and stop all | 113 | * notify the AP about us leaving the channel and stop all |
114 | * STA interfaces. | 114 | * STA interfaces. |
115 | */ | 115 | */ |
116 | |||
117 | /* | ||
118 | * Stop queues and transmit all frames queued by the driver | ||
119 | * before sending nullfunc to enable powersave at the AP. | ||
120 | */ | ||
121 | ieee80211_stop_queues_by_reason(&local->hw, | ||
122 | IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); | ||
123 | drv_flush(local, false); | ||
124 | |||
116 | mutex_lock(&local->iflist_mtx); | 125 | mutex_lock(&local->iflist_mtx); |
117 | list_for_each_entry(sdata, &local->interfaces, list) { | 126 | list_for_each_entry(sdata, &local->interfaces, list) { |
118 | if (!ieee80211_sdata_running(sdata)) | 127 | if (!ieee80211_sdata_running(sdata)) |
@@ -125,18 +134,17 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local) | |||
125 | set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); | 134 | set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); |
126 | 135 | ||
127 | /* Check to see if we should disable beaconing. */ | 136 | /* Check to see if we should disable beaconing. */ |
128 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 137 | if (sdata->vif.bss_conf.enable_beacon) { |
129 | sdata->vif.type == NL80211_IFTYPE_ADHOC || | 138 | set_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, |
130 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | 139 | &sdata->state); |
140 | sdata->vif.bss_conf.enable_beacon = false; | ||
131 | ieee80211_bss_info_change_notify( | 141 | ieee80211_bss_info_change_notify( |
132 | sdata, BSS_CHANGED_BEACON_ENABLED); | 142 | sdata, BSS_CHANGED_BEACON_ENABLED); |
133 | |||
134 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { | ||
135 | netif_tx_stop_all_queues(sdata->dev); | ||
136 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
137 | sdata->u.mgd.associated) | ||
138 | ieee80211_offchannel_ps_enable(sdata); | ||
139 | } | 143 | } |
144 | |||
145 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
146 | sdata->u.mgd.associated) | ||
147 | ieee80211_offchannel_ps_enable(sdata); | ||
140 | } | 148 | } |
141 | mutex_unlock(&local->iflist_mtx); | 149 | mutex_unlock(&local->iflist_mtx); |
142 | } | 150 | } |
@@ -164,27 +172,17 @@ void ieee80211_offchannel_return(struct ieee80211_local *local) | |||
164 | sdata->u.mgd.associated) | 172 | sdata->u.mgd.associated) |
165 | ieee80211_offchannel_ps_disable(sdata); | 173 | ieee80211_offchannel_ps_disable(sdata); |
166 | 174 | ||
167 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { | 175 | if (test_and_clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, |
168 | /* | 176 | &sdata->state)) { |
169 | * This may wake up queues even though the driver | 177 | sdata->vif.bss_conf.enable_beacon = true; |
170 | * currently has them stopped. This is not very | ||
171 | * likely, since the driver won't have gotten any | ||
172 | * (or hardly any) new packets while we weren't | ||
173 | * on the right channel, and even if it happens | ||
174 | * it will at most lead to queueing up one more | ||
175 | * packet per queue in mac80211 rather than on | ||
176 | * the interface qdisc. | ||
177 | */ | ||
178 | netif_tx_wake_all_queues(sdata->dev); | ||
179 | } | ||
180 | |||
181 | if (sdata->vif.type == NL80211_IFTYPE_AP || | ||
182 | sdata->vif.type == NL80211_IFTYPE_ADHOC || | ||
183 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | ||
184 | ieee80211_bss_info_change_notify( | 178 | ieee80211_bss_info_change_notify( |
185 | sdata, BSS_CHANGED_BEACON_ENABLED); | 179 | sdata, BSS_CHANGED_BEACON_ENABLED); |
180 | } | ||
186 | } | 181 | } |
187 | mutex_unlock(&local->iflist_mtx); | 182 | mutex_unlock(&local->iflist_mtx); |
183 | |||
184 | ieee80211_wake_queues_by_reason(&local->hw, | ||
185 | IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); | ||
188 | } | 186 | } |
189 | 187 | ||
190 | void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) | 188 | void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) |