diff options
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r-- | net/mac80211/iface.c | 170 |
1 files changed, 73 insertions, 97 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index b7c8a4484298..b8295cbd7e8f 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -190,10 +190,6 @@ static int ieee80211_open(struct net_device *dev) | |||
190 | ETH_ALEN); | 190 | ETH_ALEN); |
191 | } | 191 | } |
192 | 192 | ||
193 | if (compare_ether_addr(null_addr, local->mdev->dev_addr) == 0) | ||
194 | memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr, | ||
195 | ETH_ALEN); | ||
196 | |||
197 | /* | 193 | /* |
198 | * Validate the MAC address for this device. | 194 | * Validate the MAC address for this device. |
199 | */ | 195 | */ |
@@ -224,18 +220,15 @@ static int ieee80211_open(struct net_device *dev) | |||
224 | local->fif_fcsfail++; | 220 | local->fif_fcsfail++; |
225 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | 221 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) |
226 | local->fif_plcpfail++; | 222 | local->fif_plcpfail++; |
227 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | 223 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) { |
228 | local->fif_control++; | 224 | local->fif_control++; |
225 | local->fif_pspoll++; | ||
226 | } | ||
229 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | 227 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) |
230 | local->fif_other_bss++; | 228 | local->fif_other_bss++; |
231 | 229 | ||
232 | netif_addr_lock_bh(local->mdev); | ||
233 | ieee80211_configure_filter(local); | 230 | ieee80211_configure_filter(local); |
234 | netif_addr_unlock_bh(local->mdev); | ||
235 | break; | 231 | break; |
236 | case NL80211_IFTYPE_STATION: | ||
237 | sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET; | ||
238 | /* fall through */ | ||
239 | default: | 232 | default: |
240 | conf.vif = &sdata->vif; | 233 | conf.vif = &sdata->vif; |
241 | conf.type = sdata->vif.type; | 234 | conf.type = sdata->vif.type; |
@@ -246,12 +239,15 @@ static int ieee80211_open(struct net_device *dev) | |||
246 | 239 | ||
247 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 240 | if (ieee80211_vif_is_mesh(&sdata->vif)) { |
248 | local->fif_other_bss++; | 241 | local->fif_other_bss++; |
249 | netif_addr_lock_bh(local->mdev); | ||
250 | ieee80211_configure_filter(local); | 242 | ieee80211_configure_filter(local); |
251 | netif_addr_unlock_bh(local->mdev); | ||
252 | 243 | ||
253 | ieee80211_start_mesh(sdata); | 244 | ieee80211_start_mesh(sdata); |
245 | } else if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
246 | local->fif_pspoll++; | ||
247 | |||
248 | ieee80211_configure_filter(local); | ||
254 | } | 249 | } |
250 | |||
255 | changed |= ieee80211_reset_erp_info(sdata); | 251 | changed |= ieee80211_reset_erp_info(sdata); |
256 | ieee80211_bss_info_change_notify(sdata, changed); | 252 | ieee80211_bss_info_change_notify(sdata, changed); |
257 | ieee80211_enable_keys(sdata); | 253 | ieee80211_enable_keys(sdata); |
@@ -281,15 +277,6 @@ static int ieee80211_open(struct net_device *dev) | |||
281 | } | 277 | } |
282 | } | 278 | } |
283 | 279 | ||
284 | if (local->open_count == 0) { | ||
285 | res = dev_open(local->mdev); | ||
286 | WARN_ON(res); | ||
287 | if (res) | ||
288 | goto err_del_interface; | ||
289 | tasklet_enable(&local->tx_pending_tasklet); | ||
290 | tasklet_enable(&local->tasklet); | ||
291 | } | ||
292 | |||
293 | /* | 280 | /* |
294 | * set_multicast_list will be invoked by the networking core | 281 | * set_multicast_list will be invoked by the networking core |
295 | * which will check whether any increments here were done in | 282 | * which will check whether any increments here were done in |
@@ -323,7 +310,7 @@ static int ieee80211_open(struct net_device *dev) | |||
323 | * to fix this. | 310 | * to fix this. |
324 | */ | 311 | */ |
325 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 312 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
326 | queue_work(local->hw.workqueue, &sdata->u.mgd.work); | 313 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); |
327 | 314 | ||
328 | netif_tx_start_all_queues(dev); | 315 | netif_tx_start_all_queues(dev); |
329 | 316 | ||
@@ -346,7 +333,10 @@ static int ieee80211_stop(struct net_device *dev) | |||
346 | struct ieee80211_local *local = sdata->local; | 333 | struct ieee80211_local *local = sdata->local; |
347 | struct ieee80211_if_init_conf conf; | 334 | struct ieee80211_if_init_conf conf; |
348 | struct sta_info *sta; | 335 | struct sta_info *sta; |
336 | unsigned long flags; | ||
337 | struct sk_buff *skb, *tmp; | ||
349 | u32 hw_reconf_flags = 0; | 338 | u32 hw_reconf_flags = 0; |
339 | int i; | ||
350 | 340 | ||
351 | /* | 341 | /* |
352 | * Stop TX on this interface first. | 342 | * Stop TX on this interface first. |
@@ -366,18 +356,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
366 | rcu_read_unlock(); | 356 | rcu_read_unlock(); |
367 | 357 | ||
368 | /* | 358 | /* |
369 | * Announce that we are leaving the network, in case we are a | ||
370 | * station interface type. This must be done before removing | ||
371 | * all stations associated with sta_info_flush, otherwise STA | ||
372 | * information will be gone and no announce being done. | ||
373 | */ | ||
374 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
375 | if (sdata->u.mgd.state != IEEE80211_STA_MLME_DISABLED) | ||
376 | ieee80211_sta_deauthenticate(sdata, | ||
377 | WLAN_REASON_DEAUTH_LEAVING); | ||
378 | } | ||
379 | |||
380 | /* | ||
381 | * Remove all stations associated with this interface. | 359 | * Remove all stations associated with this interface. |
382 | * | 360 | * |
383 | * This must be done before calling ops->remove_interface() | 361 | * This must be done before calling ops->remove_interface() |
@@ -408,13 +386,24 @@ static int ieee80211_stop(struct net_device *dev) | |||
408 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | 386 | if (sdata->flags & IEEE80211_SDATA_PROMISC) |
409 | atomic_dec(&local->iff_promiscs); | 387 | atomic_dec(&local->iff_promiscs); |
410 | 388 | ||
411 | dev_mc_unsync(local->mdev, dev); | 389 | if (sdata->vif.type == NL80211_IFTYPE_AP) |
390 | local->fif_pspoll--; | ||
391 | |||
392 | netif_addr_lock_bh(dev); | ||
393 | spin_lock_bh(&local->filter_lock); | ||
394 | __dev_addr_unsync(&local->mc_list, &local->mc_count, | ||
395 | &dev->mc_list, &dev->mc_count); | ||
396 | spin_unlock_bh(&local->filter_lock); | ||
397 | netif_addr_unlock_bh(dev); | ||
398 | |||
399 | ieee80211_configure_filter(local); | ||
400 | |||
412 | del_timer_sync(&local->dynamic_ps_timer); | 401 | del_timer_sync(&local->dynamic_ps_timer); |
413 | cancel_work_sync(&local->dynamic_ps_enable_work); | 402 | cancel_work_sync(&local->dynamic_ps_enable_work); |
414 | 403 | ||
415 | /* APs need special treatment */ | 404 | /* APs need special treatment */ |
416 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 405 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
417 | struct ieee80211_sub_if_data *vlan, *tmp; | 406 | struct ieee80211_sub_if_data *vlan, *tmpsdata; |
418 | struct beacon_data *old_beacon = sdata->u.ap.beacon; | 407 | struct beacon_data *old_beacon = sdata->u.ap.beacon; |
419 | 408 | ||
420 | /* remove beacon */ | 409 | /* remove beacon */ |
@@ -423,7 +412,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
423 | kfree(old_beacon); | 412 | kfree(old_beacon); |
424 | 413 | ||
425 | /* down all dependent devices, that is VLANs */ | 414 | /* down all dependent devices, that is VLANs */ |
426 | list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans, | 415 | list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, |
427 | u.vlan.list) | 416 | u.vlan.list) |
428 | dev_close(vlan->dev); | 417 | dev_close(vlan->dev); |
429 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); | 418 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); |
@@ -452,29 +441,30 @@ static int ieee80211_stop(struct net_device *dev) | |||
452 | local->fif_fcsfail--; | 441 | local->fif_fcsfail--; |
453 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | 442 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) |
454 | local->fif_plcpfail--; | 443 | local->fif_plcpfail--; |
455 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | 444 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) { |
445 | local->fif_pspoll--; | ||
456 | local->fif_control--; | 446 | local->fif_control--; |
447 | } | ||
457 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | 448 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) |
458 | local->fif_other_bss--; | 449 | local->fif_other_bss--; |
459 | 450 | ||
460 | netif_addr_lock_bh(local->mdev); | ||
461 | ieee80211_configure_filter(local); | 451 | ieee80211_configure_filter(local); |
462 | netif_addr_unlock_bh(local->mdev); | ||
463 | break; | 452 | break; |
464 | case NL80211_IFTYPE_STATION: | 453 | case NL80211_IFTYPE_STATION: |
465 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); | ||
466 | del_timer_sync(&sdata->u.mgd.chswitch_timer); | 454 | del_timer_sync(&sdata->u.mgd.chswitch_timer); |
467 | del_timer_sync(&sdata->u.mgd.timer); | 455 | del_timer_sync(&sdata->u.mgd.timer); |
456 | del_timer_sync(&sdata->u.mgd.conn_mon_timer); | ||
457 | del_timer_sync(&sdata->u.mgd.bcn_mon_timer); | ||
468 | /* | 458 | /* |
469 | * If the timer fired while we waited for it, it will have | 459 | * If any of the timers fired while we waited for it, it will |
470 | * requeued the work. Now the work will be running again | 460 | * have queued its work. Now the work will be running again |
471 | * but will not rearm the timer again because it checks | 461 | * but will not rearm the timer again because it checks |
472 | * whether the interface is running, which, at this point, | 462 | * whether the interface is running, which, at this point, |
473 | * it no longer is. | 463 | * it no longer is. |
474 | */ | 464 | */ |
475 | cancel_work_sync(&sdata->u.mgd.work); | 465 | cancel_work_sync(&sdata->u.mgd.work); |
476 | cancel_work_sync(&sdata->u.mgd.chswitch_work); | 466 | cancel_work_sync(&sdata->u.mgd.chswitch_work); |
477 | 467 | cancel_work_sync(&sdata->u.mgd.monitor_work); | |
478 | cancel_work_sync(&sdata->u.mgd.beacon_loss_work); | 468 | cancel_work_sync(&sdata->u.mgd.beacon_loss_work); |
479 | 469 | ||
480 | /* | 470 | /* |
@@ -485,12 +475,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
485 | */ | 475 | */ |
486 | synchronize_rcu(); | 476 | synchronize_rcu(); |
487 | skb_queue_purge(&sdata->u.mgd.skb_queue); | 477 | skb_queue_purge(&sdata->u.mgd.skb_queue); |
488 | |||
489 | sdata->u.mgd.flags &= ~(IEEE80211_STA_PRIVACY_INVOKED | | ||
490 | IEEE80211_STA_TKIP_WEP_USED); | ||
491 | kfree(sdata->u.mgd.extra_ie); | ||
492 | sdata->u.mgd.extra_ie = NULL; | ||
493 | sdata->u.mgd.extra_ie_len = 0; | ||
494 | /* fall through */ | 478 | /* fall through */ |
495 | case NL80211_IFTYPE_ADHOC: | 479 | case NL80211_IFTYPE_ADHOC: |
496 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | 480 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { |
@@ -507,37 +491,23 @@ static int ieee80211_stop(struct net_device *dev) | |||
507 | local->fif_other_bss--; | 491 | local->fif_other_bss--; |
508 | atomic_dec(&local->iff_allmultis); | 492 | atomic_dec(&local->iff_allmultis); |
509 | 493 | ||
510 | netif_addr_lock_bh(local->mdev); | ||
511 | ieee80211_configure_filter(local); | 494 | ieee80211_configure_filter(local); |
512 | netif_addr_unlock_bh(local->mdev); | ||
513 | 495 | ||
514 | ieee80211_stop_mesh(sdata); | 496 | ieee80211_stop_mesh(sdata); |
515 | } | 497 | } |
516 | /* fall through */ | 498 | /* fall through */ |
517 | default: | 499 | default: |
518 | if (local->scan_sdata == sdata) { | 500 | if (local->scan_sdata == sdata) |
519 | if (!local->ops->hw_scan) | 501 | ieee80211_scan_cancel(local); |
520 | cancel_delayed_work_sync(&local->scan_work); | 502 | |
521 | /* | 503 | /* |
522 | * The software scan can no longer run now, so we can | 504 | * Disable beaconing for AP and mesh, IBSS can't |
523 | * clear out the scan_sdata reference. However, the | 505 | * still be joined to a network at this point. |
524 | * hardware scan may still be running. The complete | 506 | */ |
525 | * function must be prepared to handle a NULL value. | 507 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
526 | */ | 508 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) { |
527 | local->scan_sdata = NULL; | 509 | ieee80211_bss_info_change_notify(sdata, |
528 | /* | 510 | BSS_CHANGED_BEACON_ENABLED); |
529 | * The memory barrier guarantees that another CPU | ||
530 | * that is hardware-scanning will now see the fact | ||
531 | * that this interface is gone. | ||
532 | */ | ||
533 | smp_mb(); | ||
534 | /* | ||
535 | * If software scanning, complete the scan but since | ||
536 | * the scan_sdata is NULL already don't send out a | ||
537 | * scan event to userspace -- the scan is incomplete. | ||
538 | */ | ||
539 | if (local->sw_scanning) | ||
540 | ieee80211_scan_completed(&local->hw, true); | ||
541 | } | 511 | } |
542 | 512 | ||
543 | conf.vif = &sdata->vif; | 513 | conf.vif = &sdata->vif; |
@@ -555,17 +525,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
555 | ieee80211_recalc_ps(local, -1); | 525 | ieee80211_recalc_ps(local, -1); |
556 | 526 | ||
557 | if (local->open_count == 0) { | 527 | if (local->open_count == 0) { |
558 | if (netif_running(local->mdev)) | 528 | ieee80211_clear_tx_pending(local); |
559 | dev_close(local->mdev); | 529 | ieee80211_stop_device(local); |
560 | |||
561 | drv_stop(local); | ||
562 | |||
563 | ieee80211_led_radio(local, false); | ||
564 | |||
565 | flush_workqueue(local->hw.workqueue); | ||
566 | |||
567 | tasklet_disable(&local->tx_pending_tasklet); | ||
568 | tasklet_disable(&local->tasklet); | ||
569 | 530 | ||
570 | /* no reconfiguring after stop! */ | 531 | /* no reconfiguring after stop! */ |
571 | hw_reconf_flags = 0; | 532 | hw_reconf_flags = 0; |
@@ -575,6 +536,18 @@ static int ieee80211_stop(struct net_device *dev) | |||
575 | if (hw_reconf_flags) | 536 | if (hw_reconf_flags) |
576 | ieee80211_hw_config(local, hw_reconf_flags); | 537 | ieee80211_hw_config(local, hw_reconf_flags); |
577 | 538 | ||
539 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
540 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { | ||
541 | skb_queue_walk_safe(&local->pending[i], skb, tmp) { | ||
542 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
543 | if (info->control.vif == &sdata->vif) { | ||
544 | __skb_unlink(skb, &local->pending[i]); | ||
545 | dev_kfree_skb_irq(skb); | ||
546 | } | ||
547 | } | ||
548 | } | ||
549 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
550 | |||
578 | return 0; | 551 | return 0; |
579 | } | 552 | } |
580 | 553 | ||
@@ -604,8 +577,11 @@ static void ieee80211_set_multicast_list(struct net_device *dev) | |||
604 | atomic_dec(&local->iff_promiscs); | 577 | atomic_dec(&local->iff_promiscs); |
605 | sdata->flags ^= IEEE80211_SDATA_PROMISC; | 578 | sdata->flags ^= IEEE80211_SDATA_PROMISC; |
606 | } | 579 | } |
607 | 580 | spin_lock_bh(&local->filter_lock); | |
608 | dev_mc_sync(local->mdev, dev); | 581 | __dev_addr_sync(&local->mc_list, &local->mc_count, |
582 | &dev->mc_list, &dev->mc_count); | ||
583 | spin_unlock_bh(&local->filter_lock); | ||
584 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); | ||
609 | } | 585 | } |
610 | 586 | ||
611 | /* | 587 | /* |
@@ -652,11 +628,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev) | |||
652 | kfree_skb(sdata->u.ibss.presp); | 628 | kfree_skb(sdata->u.ibss.presp); |
653 | break; | 629 | break; |
654 | case NL80211_IFTYPE_STATION: | 630 | case NL80211_IFTYPE_STATION: |
655 | kfree(sdata->u.mgd.extra_ie); | ||
656 | kfree(sdata->u.mgd.assocreq_ies); | ||
657 | kfree(sdata->u.mgd.assocresp_ies); | ||
658 | kfree(sdata->u.mgd.sme_auth_ie); | ||
659 | break; | ||
660 | case NL80211_IFTYPE_WDS: | 631 | case NL80211_IFTYPE_WDS: |
661 | case NL80211_IFTYPE_AP_VLAN: | 632 | case NL80211_IFTYPE_AP_VLAN: |
662 | case NL80211_IFTYPE_MONITOR: | 633 | case NL80211_IFTYPE_MONITOR: |
@@ -695,7 +666,6 @@ static void ieee80211_if_setup(struct net_device *dev) | |||
695 | { | 666 | { |
696 | ether_setup(dev); | 667 | ether_setup(dev); |
697 | dev->netdev_ops = &ieee80211_dataif_ops; | 668 | dev->netdev_ops = &ieee80211_dataif_ops; |
698 | dev->wireless_handlers = &ieee80211_iw_handler_def; | ||
699 | dev->destructor = free_netdev; | 669 | dev->destructor = free_netdev; |
700 | } | 670 | } |
701 | 671 | ||
@@ -784,6 +754,10 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
784 | return 0; | 754 | return 0; |
785 | } | 755 | } |
786 | 756 | ||
757 | static struct device_type wiphy_type = { | ||
758 | .name = "wlan", | ||
759 | }; | ||
760 | |||
787 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 761 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
788 | struct net_device **new_dev, enum nl80211_iftype type, | 762 | struct net_device **new_dev, enum nl80211_iftype type, |
789 | struct vif_params *params) | 763 | struct vif_params *params) |
@@ -798,6 +772,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
798 | name, ieee80211_if_setup); | 772 | name, ieee80211_if_setup); |
799 | if (!ndev) | 773 | if (!ndev) |
800 | return -ENOMEM; | 774 | return -ENOMEM; |
775 | dev_net_set(ndev, wiphy_net(local->hw.wiphy)); | ||
801 | 776 | ||
802 | ndev->needed_headroom = local->tx_headroom + | 777 | ndev->needed_headroom = local->tx_headroom + |
803 | 4*6 /* four MAC addresses */ | 778 | 4*6 /* four MAC addresses */ |
@@ -814,7 +789,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
814 | 789 | ||
815 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); | 790 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); |
816 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); | 791 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); |
817 | ndev->features |= NETIF_F_NETNS_LOCAL; | 792 | SET_NETDEV_DEVTYPE(ndev, &wiphy_type); |
818 | 793 | ||
819 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ | 794 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ |
820 | sdata = netdev_priv(ndev); | 795 | sdata = netdev_priv(ndev); |
@@ -931,7 +906,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
931 | struct ieee80211_sub_if_data *sdata; | 906 | struct ieee80211_sub_if_data *sdata; |
932 | int count = 0; | 907 | int count = 0; |
933 | 908 | ||
934 | if (local->hw_scanning || local->sw_scanning) | 909 | if (local->scanning) |
935 | return ieee80211_idle_off(local, "scanning"); | 910 | return ieee80211_idle_off(local, "scanning"); |
936 | 911 | ||
937 | list_for_each_entry(sdata, &local->interfaces, list) { | 912 | list_for_each_entry(sdata, &local->interfaces, list) { |
@@ -939,7 +914,8 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
939 | continue; | 914 | continue; |
940 | /* do not count disabled managed interfaces */ | 915 | /* do not count disabled managed interfaces */ |
941 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 916 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
942 | sdata->u.mgd.state == IEEE80211_STA_MLME_DISABLED) | 917 | !sdata->u.mgd.associated && |
918 | list_empty(&sdata->u.mgd.work_list)) | ||
943 | continue; | 919 | continue; |
944 | /* do not count unused IBSS interfaces */ | 920 | /* do not count unused IBSS interfaces */ |
945 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | 921 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && |