aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r--net/mac80211/scan.c349
1 files changed, 147 insertions, 202 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 71e10cabf811..85507bd9e341 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -12,11 +12,9 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15/* TODO: figure out how to avoid that the "current BSS" expires */
16
17#include <linux/wireless.h>
18#include <linux/if_arp.h> 15#include <linux/if_arp.h>
19#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <linux/slab.h>
20#include <net/mac80211.h> 18#include <net/mac80211.h>
21 19
22#include "ieee80211_i.h" 20#include "ieee80211_i.h"
@@ -31,16 +29,19 @@ struct ieee80211_bss *
31ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, 29ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
32 u8 *ssid, u8 ssid_len) 30 u8 *ssid, u8 ssid_len)
33{ 31{
34 return (void *)cfg80211_get_bss(local->hw.wiphy, 32 struct cfg80211_bss *cbss;
35 ieee80211_get_channel(local->hw.wiphy, 33
36 freq), 34 cbss = cfg80211_get_bss(local->hw.wiphy,
37 bssid, ssid, ssid_len, 35 ieee80211_get_channel(local->hw.wiphy, freq),
38 0, 0); 36 bssid, ssid, ssid_len, 0, 0);
37 if (!cbss)
38 return NULL;
39 return (void *)cbss->priv;
39} 40}
40 41
41static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss) 42static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
42{ 43{
43 struct ieee80211_bss *bss = (void *)cbss; 44 struct ieee80211_bss *bss = (void *)cbss->priv;
44 45
45 kfree(bss_mesh_id(bss)); 46 kfree(bss_mesh_id(bss));
46 kfree(bss_mesh_cfg(bss)); 47 kfree(bss_mesh_cfg(bss));
@@ -49,7 +50,26 @@ static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
49void ieee80211_rx_bss_put(struct ieee80211_local *local, 50void ieee80211_rx_bss_put(struct ieee80211_local *local,
50 struct ieee80211_bss *bss) 51 struct ieee80211_bss *bss)
51{ 52{
52 cfg80211_put_bss((struct cfg80211_bss *)bss); 53 if (!bss)
54 return;
55 cfg80211_put_bss(container_of((void *)bss, struct cfg80211_bss, priv));
56}
57
58static bool is_uapsd_supported(struct ieee802_11_elems *elems)
59{
60 u8 qos_info;
61
62 if (elems->wmm_info && elems->wmm_info_len == 7
63 && elems->wmm_info[5] == 1)
64 qos_info = elems->wmm_info[6];
65 else if (elems->wmm_param && elems->wmm_param_len == 24
66 && elems->wmm_param[5] == 1)
67 qos_info = elems->wmm_param[6];
68 else
69 /* no valid wmm information or parameter element found */
70 return false;
71
72 return qos_info & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD;
53} 73}
54 74
55struct ieee80211_bss * 75struct ieee80211_bss *
@@ -61,6 +81,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
61 struct ieee80211_channel *channel, 81 struct ieee80211_channel *channel,
62 bool beacon) 82 bool beacon)
63{ 83{
84 struct cfg80211_bss *cbss;
64 struct ieee80211_bss *bss; 85 struct ieee80211_bss *bss;
65 int clen; 86 int clen;
66 s32 signal = 0; 87 s32 signal = 0;
@@ -70,13 +91,14 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
70 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 91 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
71 signal = (rx_status->signal * 100) / local->hw.max_signal; 92 signal = (rx_status->signal * 100) / local->hw.max_signal;
72 93
73 bss = (void *)cfg80211_inform_bss_frame(local->hw.wiphy, channel, 94 cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel,
74 mgmt, len, signal, GFP_ATOMIC); 95 mgmt, len, signal, GFP_ATOMIC);
75 96
76 if (!bss) 97 if (!cbss)
77 return NULL; 98 return NULL;
78 99
79 bss->cbss.free_priv = ieee80211_rx_bss_free; 100 cbss->free_priv = ieee80211_rx_bss_free;
101 bss = (void *)cbss->priv;
80 102
81 /* save the ERP value so that it is available at association time */ 103 /* save the ERP value so that it is available at association time */
82 if (elems->erp_info && elems->erp_info_len >= 1) { 104 if (elems->erp_info && elems->erp_info_len >= 1) {
@@ -90,10 +112,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
90 bss->dtim_period = tim_ie->dtim_period; 112 bss->dtim_period = tim_ie->dtim_period;
91 } 113 }
92 114
93 /* set default value for buggy AP/no TIM element */
94 if (bss->dtim_period == 0)
95 bss->dtim_period = 1;
96
97 bss->supp_rates_len = 0; 115 bss->supp_rates_len = 0;
98 if (elems->supp_rates) { 116 if (elems->supp_rates) {
99 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; 117 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
@@ -113,6 +131,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
113 } 131 }
114 132
115 bss->wmm_used = elems->wmm_param || elems->wmm_info; 133 bss->wmm_used = elems->wmm_param || elems->wmm_info;
134 bss->uapsd_supported = is_uapsd_supported(elems);
116 135
117 if (!beacon) 136 if (!beacon)
118 bss->last_probe_resp = jiffies; 137 bss->last_probe_resp = jiffies;
@@ -149,7 +168,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
149 presp = ieee80211_is_probe_resp(fc); 168 presp = ieee80211_is_probe_resp(fc);
150 if (presp) { 169 if (presp) {
151 /* ignore ProbeResp to foreign address */ 170 /* ignore ProbeResp to foreign address */
152 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN)) 171 if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
153 return RX_DROP_MONITOR; 172 return RX_DROP_MONITOR;
154 173
155 presp = true; 174 presp = true;
@@ -189,100 +208,76 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
189 return RX_QUEUED; 208 return RX_QUEUED;
190} 209}
191 210
192/* 211/* return false if no more work */
193 * inform AP that we will go to sleep so that it will buffer the frames 212static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
194 * while we scan
195 */
196static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata)
197{ 213{
198 struct ieee80211_local *local = sdata->local; 214 struct cfg80211_scan_request *req = local->scan_req;
199 bool ps = false; 215 enum ieee80211_band band;
216 int i, ielen, n_chans;
200 217
201 /* FIXME: what to do when local->pspolling is true? */ 218 do {
219 if (local->hw_scan_band == IEEE80211_NUM_BANDS)
220 return false;
221
222 band = local->hw_scan_band;
223 n_chans = 0;
224 for (i = 0; i < req->n_channels; i++) {
225 if (req->channels[i]->band == band) {
226 local->hw_scan_req->channels[n_chans] =
227 req->channels[i];
228 n_chans++;
229 }
230 }
202 231
203 del_timer_sync(&local->dynamic_ps_timer); 232 local->hw_scan_band++;
204 cancel_work_sync(&local->dynamic_ps_enable_work); 233 } while (!n_chans);
205 234
206 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 235 local->hw_scan_req->n_channels = n_chans;
207 ps = true;
208 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
209 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
210 }
211 236
212 if (!ps || !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) 237 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
213 /* 238 req->ie, req->ie_len, band);
214 * If power save was enabled, no need to send a nullfunc 239 local->hw_scan_req->ie_len = ielen;
215 * frame because AP knows that we are sleeping. But if the
216 * hardware is creating the nullfunc frame for power save
217 * status (ie. IEEE80211_HW_PS_NULLFUNC_STACK is not
218 * enabled) and power save was enabled, the firmware just
219 * sent a null frame with power save disabled. So we need
220 * to send a new nullfunc frame to inform the AP that we
221 * are again sleeping.
222 */
223 ieee80211_send_nullfunc(local, sdata, 1);
224}
225
226/* inform AP that we are awake again, unless power save is enabled */
227static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
228{
229 struct ieee80211_local *local = sdata->local;
230
231 if (!local->ps_sdata)
232 ieee80211_send_nullfunc(local, sdata, 0);
233 else {
234 /*
235 * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware
236 * will send a nullfunc frame with the powersave bit set
237 * even though the AP already knows that we are sleeping.
238 * This could be avoided by sending a null frame with power
239 * save bit disabled before enabling the power save, but
240 * this doesn't gain anything.
241 *
242 * When IEEE80211_HW_PS_NULLFUNC_STACK is enabled, no need
243 * to send a nullfunc frame because AP already knows that
244 * we are sleeping, let's just enable power save mode in
245 * hardware.
246 */
247 local->hw.conf.flags |= IEEE80211_CONF_PS;
248 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
249 }
250}
251 240
252static void ieee80211_restore_scan_ies(struct ieee80211_local *local) 241 return true;
253{
254 kfree(local->scan_req->ie);
255 local->scan_req->ie = local->orig_ies;
256 local->scan_req->ie_len = local->orig_ies_len;
257} 242}
258 243
259void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) 244void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
260{ 245{
261 struct ieee80211_local *local = hw_to_local(hw); 246 struct ieee80211_local *local = hw_to_local(hw);
262 struct ieee80211_sub_if_data *sdata;
263 bool was_hw_scan; 247 bool was_hw_scan;
264 248
265 mutex_lock(&local->scan_mtx); 249 mutex_lock(&local->scan_mtx);
266 250
267 if (WARN_ON(!local->scanning)) { 251 /*
252 * It's ok to abort a not-yet-running scan (that
253 * we have one at all will be verified by checking
254 * local->scan_req next), but not to complete it
255 * successfully.
256 */
257 if (WARN_ON(!local->scanning && !aborted))
258 aborted = true;
259
260 if (WARN_ON(!local->scan_req)) {
268 mutex_unlock(&local->scan_mtx); 261 mutex_unlock(&local->scan_mtx);
269 return; 262 return;
270 } 263 }
271 264
272 if (WARN_ON(!local->scan_req)) { 265 was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
266 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
267 ieee80211_queue_delayed_work(&local->hw,
268 &local->scan_work, 0);
273 mutex_unlock(&local->scan_mtx); 269 mutex_unlock(&local->scan_mtx);
274 return; 270 return;
275 } 271 }
276 272
277 if (test_bit(SCAN_HW_SCANNING, &local->scanning)) 273 kfree(local->hw_scan_req);
278 ieee80211_restore_scan_ies(local); 274 local->hw_scan_req = NULL;
279 275
280 if (local->scan_req != local->int_scan_req) 276 if (local->scan_req != local->int_scan_req)
281 cfg80211_scan_done(local->scan_req, aborted); 277 cfg80211_scan_done(local->scan_req, aborted);
282 local->scan_req = NULL; 278 local->scan_req = NULL;
283 local->scan_sdata = NULL; 279 local->scan_sdata = NULL;
284 280
285 was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
286 local->scanning = 0; 281 local->scanning = 0;
287 local->scan_channel = NULL; 282 local->scan_channel = NULL;
288 283
@@ -297,41 +292,19 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
297 292
298 drv_sw_scan_complete(local); 293 drv_sw_scan_complete(local);
299 294
300 mutex_lock(&local->iflist_mtx); 295 ieee80211_offchannel_return(local, true);
301 list_for_each_entry(sdata, &local->interfaces, list) {
302 if (!netif_running(sdata->dev))
303 continue;
304
305 /* Tell AP we're back */
306 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
307 if (sdata->u.mgd.associated) {
308 ieee80211_scan_ps_disable(sdata);
309 netif_tx_wake_all_queues(sdata->dev);
310 }
311 } else
312 netif_tx_wake_all_queues(sdata->dev);
313
314 /* re-enable beaconing */
315 if (sdata->vif.type == NL80211_IFTYPE_AP ||
316 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
317 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
318 ieee80211_bss_info_change_notify(
319 sdata, BSS_CHANGED_BEACON_ENABLED);
320 }
321 mutex_unlock(&local->iflist_mtx);
322 296
323 done: 297 done:
324 ieee80211_recalc_idle(local); 298 ieee80211_recalc_idle(local);
325 ieee80211_mlme_notify_scan_completed(local); 299 ieee80211_mlme_notify_scan_completed(local);
326 ieee80211_ibss_notify_scan_completed(local); 300 ieee80211_ibss_notify_scan_completed(local);
327 ieee80211_mesh_notify_scan_completed(local); 301 ieee80211_mesh_notify_scan_completed(local);
302 ieee80211_queue_work(&local->hw, &local->work_work);
328} 303}
329EXPORT_SYMBOL(ieee80211_scan_completed); 304EXPORT_SYMBOL(ieee80211_scan_completed);
330 305
331static int ieee80211_start_sw_scan(struct ieee80211_local *local) 306static int ieee80211_start_sw_scan(struct ieee80211_local *local)
332{ 307{
333 struct ieee80211_sub_if_data *sdata;
334
335 /* 308 /*
336 * Hardware/driver doesn't support hw_scan, so use software 309 * Hardware/driver doesn't support hw_scan, so use software
337 * scanning instead. First send a nullfunc frame with power save 310 * scanning instead. First send a nullfunc frame with power save
@@ -347,33 +320,15 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
347 */ 320 */
348 drv_sw_scan_start(local); 321 drv_sw_scan_start(local);
349 322
350 mutex_lock(&local->iflist_mtx); 323 ieee80211_offchannel_stop_beaconing(local);
351 list_for_each_entry(sdata, &local->interfaces, list) {
352 if (!netif_running(sdata->dev))
353 continue;
354
355 /* disable beaconing */
356 if (sdata->vif.type == NL80211_IFTYPE_AP ||
357 sdata->vif.type == NL80211_IFTYPE_ADHOC ||
358 sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
359 ieee80211_bss_info_change_notify(
360 sdata, BSS_CHANGED_BEACON_ENABLED);
361
362 /*
363 * only handle non-STA interfaces here, STA interfaces
364 * are handled in the scan state machine
365 */
366 if (sdata->vif.type != NL80211_IFTYPE_STATION)
367 netif_tx_stop_all_queues(sdata->dev);
368 }
369 mutex_unlock(&local->iflist_mtx);
370 324
371 local->next_scan_state = SCAN_DECISION; 325 local->next_scan_state = SCAN_DECISION;
372 local->scan_channel_idx = 0; 326 local->scan_channel_idx = 0;
373 327
328 drv_flush(local, false);
329
374 ieee80211_configure_filter(local); 330 ieee80211_configure_filter(local);
375 331
376 /* TODO: start scan as soon as all nullfunc frames are ACKed */
377 ieee80211_queue_delayed_work(&local->hw, 332 ieee80211_queue_delayed_work(&local->hw,
378 &local->scan_work, 333 &local->scan_work,
379 IEEE80211_CHANNEL_TIME); 334 IEEE80211_CHANNEL_TIME);
@@ -386,68 +341,80 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
386 struct cfg80211_scan_request *req) 341 struct cfg80211_scan_request *req)
387{ 342{
388 struct ieee80211_local *local = sdata->local; 343 struct ieee80211_local *local = sdata->local;
389 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
390 int rc; 344 int rc;
391 345
392 if (local->scan_req) 346 if (local->scan_req)
393 return -EBUSY; 347 return -EBUSY;
394 348
349 if (!list_empty(&local->work_list)) {
350 /* wait for the work to finish/time out */
351 local->scan_req = req;
352 local->scan_sdata = sdata;
353 return 0;
354 }
355
395 if (local->ops->hw_scan) { 356 if (local->ops->hw_scan) {
396 u8 *ies; 357 u8 *ies;
397 int ielen;
398 358
399 ies = kmalloc(2 + IEEE80211_MAX_SSID_LEN + 359 local->hw_scan_req = kmalloc(
400 local->scan_ies_len + req->ie_len, GFP_KERNEL); 360 sizeof(*local->hw_scan_req) +
401 if (!ies) 361 req->n_channels * sizeof(req->channels[0]) +
362 2 + IEEE80211_MAX_SSID_LEN + local->scan_ies_len +
363 req->ie_len, GFP_KERNEL);
364 if (!local->hw_scan_req)
402 return -ENOMEM; 365 return -ENOMEM;
403 366
404 ielen = ieee80211_build_preq_ies(local, ies, 367 local->hw_scan_req->ssids = req->ssids;
405 req->ie, req->ie_len); 368 local->hw_scan_req->n_ssids = req->n_ssids;
406 local->orig_ies = req->ie; 369 ies = (u8 *)local->hw_scan_req +
407 local->orig_ies_len = req->ie_len; 370 sizeof(*local->hw_scan_req) +
408 req->ie = ies; 371 req->n_channels * sizeof(req->channels[0]);
409 req->ie_len = ielen; 372 local->hw_scan_req->ie = ies;
373
374 local->hw_scan_band = 0;
375
376 /*
377 * After allocating local->hw_scan_req, we must
378 * go through until ieee80211_prep_hw_scan(), so
379 * anything that might be changed here and leave
380 * this function early must not go after this
381 * allocation.
382 */
410 } 383 }
411 384
412 local->scan_req = req; 385 local->scan_req = req;
413 local->scan_sdata = sdata; 386 local->scan_sdata = sdata;
414 387
415 if (req != local->int_scan_req &&
416 sdata->vif.type == NL80211_IFTYPE_STATION &&
417 !list_empty(&ifmgd->work_list)) {
418 /* actually wait for the work it's doing to finish/time out */
419 set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
420 return 0;
421 }
422
423 if (local->ops->hw_scan) 388 if (local->ops->hw_scan)
424 __set_bit(SCAN_HW_SCANNING, &local->scanning); 389 __set_bit(SCAN_HW_SCANNING, &local->scanning);
425 else 390 else
426 __set_bit(SCAN_SW_SCANNING, &local->scanning); 391 __set_bit(SCAN_SW_SCANNING, &local->scanning);
392
427 /* 393 /*
428 * Kicking off the scan need not be protected, 394 * Kicking off the scan need not be protected,
429 * only the scan variable stuff, since now 395 * only the scan variable stuff, since now
430 * local->scan_req is assigned and other callers 396 * local->scan_req is assigned and other callers
431 * will abort their scan attempts. 397 * will abort their scan attempts.
432 * 398 *
433 * This avoids getting a scan_mtx -> iflist_mtx 399 * This avoids too many locking dependencies
434 * dependency, so that the scan completed calls 400 * so that the scan completed calls have more
435 * have more locking freedom. 401 * locking freedom.
436 */ 402 */
437 403
438 ieee80211_recalc_idle(local); 404 ieee80211_recalc_idle(local);
439 mutex_unlock(&local->scan_mtx); 405 mutex_unlock(&local->scan_mtx);
440 406
441 if (local->ops->hw_scan) 407 if (local->ops->hw_scan) {
442 rc = drv_hw_scan(local, local->scan_req); 408 WARN_ON(!ieee80211_prep_hw_scan(local));
443 else 409 rc = drv_hw_scan(local, local->hw_scan_req);
410 } else
444 rc = ieee80211_start_sw_scan(local); 411 rc = ieee80211_start_sw_scan(local);
445 412
446 mutex_lock(&local->scan_mtx); 413 mutex_lock(&local->scan_mtx);
447 414
448 if (rc) { 415 if (rc) {
449 if (local->ops->hw_scan) 416 kfree(local->hw_scan_req);
450 ieee80211_restore_scan_ies(local); 417 local->hw_scan_req = NULL;
451 local->scanning = 0; 418 local->scanning = 0;
452 419
453 ieee80211_recalc_idle(local); 420 ieee80211_recalc_idle(local);
@@ -474,7 +441,7 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
474 /* check if at least one STA interface is associated */ 441 /* check if at least one STA interface is associated */
475 mutex_lock(&local->iflist_mtx); 442 mutex_lock(&local->iflist_mtx);
476 list_for_each_entry(sdata, &local->interfaces, list) { 443 list_for_each_entry(sdata, &local->interfaces, list) {
477 if (!netif_running(sdata->dev)) 444 if (!ieee80211_sdata_running(sdata))
478 continue; 445 continue;
479 446
480 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 447 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
@@ -512,56 +479,35 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
512static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, 479static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
513 unsigned long *next_delay) 480 unsigned long *next_delay)
514{ 481{
515 struct ieee80211_sub_if_data *sdata; 482 ieee80211_offchannel_stop_station(local);
483
484 __set_bit(SCAN_OFF_CHANNEL, &local->scanning);
516 485
517 /* 486 /*
518 * notify the AP about us leaving the channel and stop all STA interfaces 487 * What if the nullfunc frames didn't arrive?
519 */ 488 */
520 mutex_lock(&local->iflist_mtx); 489 drv_flush(local, false);
521 list_for_each_entry(sdata, &local->interfaces, list) { 490 if (local->ops->flush)
522 if (!netif_running(sdata->dev)) 491 *next_delay = 0;
523 continue; 492 else
524 493 *next_delay = HZ / 10;
525 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
526 netif_tx_stop_all_queues(sdata->dev);
527 if (sdata->u.mgd.associated)
528 ieee80211_scan_ps_enable(sdata);
529 }
530 }
531 mutex_unlock(&local->iflist_mtx);
532
533 __set_bit(SCAN_OFF_CHANNEL, &local->scanning);
534 494
535 /* advance to the next channel to be scanned */ 495 /* advance to the next channel to be scanned */
536 *next_delay = HZ / 10;
537 local->next_scan_state = SCAN_SET_CHANNEL; 496 local->next_scan_state = SCAN_SET_CHANNEL;
538} 497}
539 498
540static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local, 499static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local,
541 unsigned long *next_delay) 500 unsigned long *next_delay)
542{ 501{
543 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
544
545 /* switch back to the operating channel */ 502 /* switch back to the operating channel */
546 local->scan_channel = NULL; 503 local->scan_channel = NULL;
547 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 504 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
548 505
549 /* 506 /*
550 * notify the AP about us being back and restart all STA interfaces 507 * Only re-enable station mode interface now; beaconing will be
508 * re-enabled once the full scan has been completed.
551 */ 509 */
552 mutex_lock(&local->iflist_mtx); 510 ieee80211_offchannel_return(local, false);
553 list_for_each_entry(sdata, &local->interfaces, list) {
554 if (!netif_running(sdata->dev))
555 continue;
556
557 /* Tell AP we're back */
558 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
559 if (sdata->u.mgd.associated)
560 ieee80211_scan_ps_disable(sdata);
561 netif_tx_wake_all_queues(sdata->dev);
562 }
563 }
564 mutex_unlock(&local->iflist_mtx);
565 511
566 __clear_bit(SCAN_OFF_CHANNEL, &local->scanning); 512 __clear_bit(SCAN_OFF_CHANNEL, &local->scanning);
567 513
@@ -574,23 +520,14 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
574{ 520{
575 int skip; 521 int skip;
576 struct ieee80211_channel *chan; 522 struct ieee80211_channel *chan;
577 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
578 523
579 skip = 0; 524 skip = 0;
580 chan = local->scan_req->channels[local->scan_channel_idx]; 525 chan = local->scan_req->channels[local->scan_channel_idx];
581 526
582 if (chan->flags & IEEE80211_CHAN_DISABLED || 527 local->scan_channel = chan;
583 (sdata->vif.type == NL80211_IFTYPE_ADHOC && 528 if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))
584 chan->flags & IEEE80211_CHAN_NO_IBSS))
585 skip = 1; 529 skip = 1;
586 530
587 if (!skip) {
588 local->scan_channel = chan;
589 if (ieee80211_hw_config(local,
590 IEEE80211_CONF_CHANGE_CHANNEL))
591 skip = 1;
592 }
593
594 /* advance state machine to next channel/band */ 531 /* advance state machine to next channel/band */
595 local->scan_channel_idx++; 532 local->scan_channel_idx++;
596 533
@@ -656,6 +593,14 @@ void ieee80211_scan_work(struct work_struct *work)
656 return; 593 return;
657 } 594 }
658 595
596 if (local->hw_scan_req) {
597 int rc = drv_hw_scan(local, local->hw_scan_req);
598 mutex_unlock(&local->scan_mtx);
599 if (rc)
600 ieee80211_scan_completed(&local->hw, true);
601 return;
602 }
603
659 if (local->scan_req && !local->scanning) { 604 if (local->scan_req && !local->scanning) {
660 struct cfg80211_scan_request *req = local->scan_req; 605 struct cfg80211_scan_request *req = local->scan_req;
661 int rc; 606 int rc;
@@ -676,7 +621,7 @@ void ieee80211_scan_work(struct work_struct *work)
676 /* 621 /*
677 * Avoid re-scheduling when the sdata is going away. 622 * Avoid re-scheduling when the sdata is going away.
678 */ 623 */
679 if (!netif_running(sdata->dev)) { 624 if (!ieee80211_sdata_running(sdata)) {
680 ieee80211_scan_completed(&local->hw, true); 625 ieee80211_scan_completed(&local->hw, true);
681 return; 626 return;
682 } 627 }