diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/driver-trace.c | 3 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 6 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 9 | ||||
-rw-r--r-- | net/mac80211/iface.c | 36 | ||||
-rw-r--r-- | net/mac80211/main.c | 40 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 10 | ||||
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 4 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 113 | ||||
-rw-r--r-- | net/mac80211/pm.c | 8 | ||||
-rw-r--r-- | net/mac80211/scan.c | 8 | ||||
-rw-r--r-- | net/mac80211/tx.c | 2 | ||||
-rw-r--r-- | net/mac80211/util.c | 41 |
12 files changed, 199 insertions, 81 deletions
diff --git a/net/mac80211/driver-trace.c b/net/mac80211/driver-trace.c index 6da6f79932fc..8ed8711b1a6d 100644 --- a/net/mac80211/driver-trace.c +++ b/net/mac80211/driver-trace.c | |||
@@ -1,6 +1,9 @@ | |||
1 | /* bug in tracepoint.h, it should include this */ | 1 | /* bug in tracepoint.h, it should include this */ |
2 | #include <linux/module.h> | 2 | #include <linux/module.h> |
3 | 3 | ||
4 | /* sparse isn't too happy with all macros... */ | ||
5 | #ifndef __CHECKER__ | ||
4 | #include "driver-ops.h" | 6 | #include "driver-ops.h" |
5 | #define CREATE_TRACE_POINTS | 7 | #define CREATE_TRACE_POINTS |
6 | #include "driver-trace.h" | 8 | #include "driver-trace.h" |
9 | #endif | ||
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 6e3cca65c460..920ec8792f4b 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -781,7 +781,7 @@ static void ieee80211_ibss_timer(unsigned long data) | |||
781 | } | 781 | } |
782 | 782 | ||
783 | set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request); | 783 | set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request); |
784 | queue_work(local->hw.workqueue, &ifibss->work); | 784 | ieee80211_queue_work(&local->hw, &ifibss->work); |
785 | } | 785 | } |
786 | 786 | ||
787 | #ifdef CONFIG_PM | 787 | #ifdef CONFIG_PM |
@@ -853,7 +853,7 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
853 | case IEEE80211_STYPE_PROBE_REQ: | 853 | case IEEE80211_STYPE_PROBE_REQ: |
854 | case IEEE80211_STYPE_AUTH: | 854 | case IEEE80211_STYPE_AUTH: |
855 | skb_queue_tail(&sdata->u.ibss.skb_queue, skb); | 855 | skb_queue_tail(&sdata->u.ibss.skb_queue, skb); |
856 | queue_work(local->hw.workqueue, &sdata->u.ibss.work); | 856 | ieee80211_queue_work(&local->hw, &sdata->u.ibss.work); |
857 | return RX_QUEUED; | 857 | return RX_QUEUED; |
858 | } | 858 | } |
859 | 859 | ||
@@ -912,7 +912,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
912 | ieee80211_recalc_idle(sdata->local); | 912 | ieee80211_recalc_idle(sdata->local); |
913 | 913 | ||
914 | set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); | 914 | set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); |
915 | queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work); | 915 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.ibss.work); |
916 | 916 | ||
917 | return 0; | 917 | return 0; |
918 | } | 918 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index aec6853cb435..630a438180fd 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -280,6 +280,7 @@ struct ieee80211_if_managed { | |||
280 | struct work_struct beacon_loss_work; | 280 | struct work_struct beacon_loss_work; |
281 | 281 | ||
282 | unsigned long probe_timeout; | 282 | unsigned long probe_timeout; |
283 | int probe_send_count; | ||
283 | 284 | ||
284 | struct mutex mtx; | 285 | struct mutex mtx; |
285 | struct ieee80211_bss *associated; | 286 | struct ieee80211_bss *associated; |
@@ -614,6 +615,12 @@ struct ieee80211_local { | |||
614 | 615 | ||
615 | const struct ieee80211_ops *ops; | 616 | const struct ieee80211_ops *ops; |
616 | 617 | ||
618 | /* | ||
619 | * private workqueue to mac80211. mac80211 makes this accessible | ||
620 | * via ieee80211_queue_work() | ||
621 | */ | ||
622 | struct workqueue_struct *workqueue; | ||
623 | |||
617 | unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; | 624 | unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; |
618 | /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ | 625 | /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ |
619 | spinlock_t queue_stop_reason_lock; | 626 | spinlock_t queue_stop_reason_lock; |
@@ -621,7 +628,7 @@ struct ieee80211_local { | |||
621 | int open_count; | 628 | int open_count; |
622 | int monitors, cooked_mntrs; | 629 | int monitors, cooked_mntrs; |
623 | /* number of interfaces with corresponding FIF_ flags */ | 630 | /* number of interfaces with corresponding FIF_ flags */ |
624 | int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss; | 631 | int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; |
625 | unsigned int filter_flags; /* FIF_* */ | 632 | unsigned int filter_flags; /* FIF_* */ |
626 | struct iw_statistics wstats; | 633 | struct iw_statistics wstats; |
627 | 634 | ||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 6c655b6547fb..e8fb03b91a44 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -220,8 +220,10 @@ static int ieee80211_open(struct net_device *dev) | |||
220 | local->fif_fcsfail++; | 220 | local->fif_fcsfail++; |
221 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | 221 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) |
222 | local->fif_plcpfail++; | 222 | local->fif_plcpfail++; |
223 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | 223 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) { |
224 | local->fif_control++; | 224 | local->fif_control++; |
225 | local->fif_pspoll++; | ||
226 | } | ||
225 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | 227 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) |
226 | local->fif_other_bss++; | 228 | local->fif_other_bss++; |
227 | 229 | ||
@@ -244,7 +246,14 @@ static int ieee80211_open(struct net_device *dev) | |||
244 | spin_unlock_bh(&local->filter_lock); | 246 | spin_unlock_bh(&local->filter_lock); |
245 | 247 | ||
246 | ieee80211_start_mesh(sdata); | 248 | ieee80211_start_mesh(sdata); |
249 | } else if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
250 | local->fif_pspoll++; | ||
251 | |||
252 | spin_lock_bh(&local->filter_lock); | ||
253 | ieee80211_configure_filter(local); | ||
254 | spin_unlock_bh(&local->filter_lock); | ||
247 | } | 255 | } |
256 | |||
248 | changed |= ieee80211_reset_erp_info(sdata); | 257 | changed |= ieee80211_reset_erp_info(sdata); |
249 | ieee80211_bss_info_change_notify(sdata, changed); | 258 | ieee80211_bss_info_change_notify(sdata, changed); |
250 | ieee80211_enable_keys(sdata); | 259 | ieee80211_enable_keys(sdata); |
@@ -312,7 +321,7 @@ static int ieee80211_open(struct net_device *dev) | |||
312 | * to fix this. | 321 | * to fix this. |
313 | */ | 322 | */ |
314 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 323 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
315 | queue_work(local->hw.workqueue, &sdata->u.mgd.work); | 324 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); |
316 | 325 | ||
317 | netif_tx_start_all_queues(dev); | 326 | netif_tx_start_all_queues(dev); |
318 | 327 | ||
@@ -388,6 +397,9 @@ static int ieee80211_stop(struct net_device *dev) | |||
388 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | 397 | if (sdata->flags & IEEE80211_SDATA_PROMISC) |
389 | atomic_dec(&local->iff_promiscs); | 398 | atomic_dec(&local->iff_promiscs); |
390 | 399 | ||
400 | if (sdata->vif.type == NL80211_IFTYPE_AP) | ||
401 | local->fif_pspoll--; | ||
402 | |||
391 | netif_addr_lock_bh(dev); | 403 | netif_addr_lock_bh(dev); |
392 | spin_lock_bh(&local->filter_lock); | 404 | spin_lock_bh(&local->filter_lock); |
393 | __dev_addr_unsync(&local->mc_list, &local->mc_count, | 405 | __dev_addr_unsync(&local->mc_list, &local->mc_count, |
@@ -401,7 +413,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
401 | 413 | ||
402 | /* APs need special treatment */ | 414 | /* APs need special treatment */ |
403 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 415 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
404 | struct ieee80211_sub_if_data *vlan, *tmp; | 416 | struct ieee80211_sub_if_data *vlan, *tmpsdata; |
405 | struct beacon_data *old_beacon = sdata->u.ap.beacon; | 417 | struct beacon_data *old_beacon = sdata->u.ap.beacon; |
406 | 418 | ||
407 | /* remove beacon */ | 419 | /* remove beacon */ |
@@ -410,7 +422,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
410 | kfree(old_beacon); | 422 | kfree(old_beacon); |
411 | 423 | ||
412 | /* down all dependent devices, that is VLANs */ | 424 | /* down all dependent devices, that is VLANs */ |
413 | list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans, | 425 | list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, |
414 | u.vlan.list) | 426 | u.vlan.list) |
415 | dev_close(vlan->dev); | 427 | dev_close(vlan->dev); |
416 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); | 428 | WARN_ON(!list_empty(&sdata->u.ap.vlans)); |
@@ -439,8 +451,10 @@ static int ieee80211_stop(struct net_device *dev) | |||
439 | local->fif_fcsfail--; | 451 | local->fif_fcsfail--; |
440 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | 452 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) |
441 | local->fif_plcpfail--; | 453 | local->fif_plcpfail--; |
442 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | 454 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) { |
455 | local->fif_pspoll--; | ||
443 | local->fif_control--; | 456 | local->fif_control--; |
457 | } | ||
444 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | 458 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) |
445 | local->fif_other_bss--; | 459 | local->fif_other_bss--; |
446 | 460 | ||
@@ -522,6 +536,16 @@ static int ieee80211_stop(struct net_device *dev) | |||
522 | ieee80211_scan_completed(&local->hw, true); | 536 | ieee80211_scan_completed(&local->hw, true); |
523 | } | 537 | } |
524 | 538 | ||
539 | /* | ||
540 | * Disable beaconing for AP and mesh, IBSS can't | ||
541 | * still be joined to a network at this point. | ||
542 | */ | ||
543 | if (sdata->vif.type == NL80211_IFTYPE_AP || | ||
544 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) { | ||
545 | ieee80211_bss_info_change_notify(sdata, | ||
546 | BSS_CHANGED_BEACON_ENABLED); | ||
547 | } | ||
548 | |||
525 | conf.vif = &sdata->vif; | 549 | conf.vif = &sdata->vif; |
526 | conf.type = sdata->vif.type; | 550 | conf.type = sdata->vif.type; |
527 | conf.mac_addr = dev->dev_addr; | 551 | conf.mac_addr = dev->dev_addr; |
@@ -541,7 +565,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
541 | 565 | ||
542 | ieee80211_led_radio(local, false); | 566 | ieee80211_led_radio(local, false); |
543 | 567 | ||
544 | flush_workqueue(local->hw.workqueue); | 568 | flush_workqueue(local->workqueue); |
545 | 569 | ||
546 | tasklet_disable(&local->tx_pending_tasklet); | 570 | tasklet_disable(&local->tx_pending_tasklet); |
547 | tasklet_disable(&local->tasklet); | 571 | tasklet_disable(&local->tasklet); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c1a799194fff..0c4f8e122ed6 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -77,6 +77,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local) | |||
77 | if (local->fif_other_bss) | 77 | if (local->fif_other_bss) |
78 | new_flags |= FIF_OTHER_BSS; | 78 | new_flags |= FIF_OTHER_BSS; |
79 | 79 | ||
80 | if (local->fif_pspoll) | ||
81 | new_flags |= FIF_PSPOLL; | ||
82 | |||
80 | changed_flags = local->filter_flags ^ new_flags; | 83 | changed_flags = local->filter_flags ^ new_flags; |
81 | 84 | ||
82 | /* be a bit nasty */ | 85 | /* be a bit nasty */ |
@@ -198,7 +201,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
198 | } | 201 | } |
199 | 202 | ||
200 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | 203 | if (changed & BSS_CHANGED_BEACON_ENABLED) { |
201 | if (test_bit(SCAN_SW_SCANNING, &local->scanning)) { | 204 | if (local->quiescing || !netif_running(sdata->dev) || |
205 | test_bit(SCAN_SW_SCANNING, &local->scanning)) { | ||
202 | sdata->vif.bss_conf.enable_beacon = false; | 206 | sdata->vif.bss_conf.enable_beacon = false; |
203 | } else { | 207 | } else { |
204 | /* | 208 | /* |
@@ -310,6 +314,31 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
310 | { | 314 | { |
311 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 315 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
312 | 316 | ||
317 | /* | ||
318 | * XXX: This is temporary! | ||
319 | * | ||
320 | * The problem here is that when we get here, the driver will | ||
321 | * quite likely have pretty much overwritten info->control by | ||
322 | * using info->driver_data or info->rate_driver_data. Thus, | ||
323 | * when passing out the frame to the driver again, we would be | ||
324 | * passing completely bogus data since the driver would then | ||
325 | * expect a properly filled info->control. In mac80211 itself | ||
326 | * the same problem occurs, since we need info->control.vif | ||
327 | * internally. | ||
328 | * | ||
329 | * To fix this, we should send the frame through TX processing | ||
330 | * again. However, it's not that simple, since the frame will | ||
331 | * have been software-encrypted (if applicable) already, and | ||
332 | * encrypting it again doesn't do much good. So to properly do | ||
333 | * that, we not only have to skip the actual 'raw' encryption | ||
334 | * (key selection etc. still has to be done!) but also the | ||
335 | * sequence number assignment since that impacts the crypto | ||
336 | * encapsulation, of course. | ||
337 | * | ||
338 | * Hence, for now, fix the bug by just dropping the frame. | ||
339 | */ | ||
340 | goto drop; | ||
341 | |||
313 | sta->tx_filtered_count++; | 342 | sta->tx_filtered_count++; |
314 | 343 | ||
315 | /* | 344 | /* |
@@ -363,6 +392,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
363 | return; | 392 | return; |
364 | } | 393 | } |
365 | 394 | ||
395 | drop: | ||
366 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 396 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
367 | if (net_ratelimit()) | 397 | if (net_ratelimit()) |
368 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | 398 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " |
@@ -794,9 +824,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
794 | if (hw->queues > IEEE80211_MAX_QUEUES) | 824 | if (hw->queues > IEEE80211_MAX_QUEUES) |
795 | hw->queues = IEEE80211_MAX_QUEUES; | 825 | hw->queues = IEEE80211_MAX_QUEUES; |
796 | 826 | ||
797 | local->hw.workqueue = | 827 | local->workqueue = |
798 | create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); | 828 | create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); |
799 | if (!local->hw.workqueue) { | 829 | if (!local->workqueue) { |
800 | result = -ENOMEM; | 830 | result = -ENOMEM; |
801 | goto fail_workqueue; | 831 | goto fail_workqueue; |
802 | } | 832 | } |
@@ -886,7 +916,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
886 | sta_info_stop(local); | 916 | sta_info_stop(local); |
887 | fail_sta_info: | 917 | fail_sta_info: |
888 | debugfs_hw_del(local); | 918 | debugfs_hw_del(local); |
889 | destroy_workqueue(local->hw.workqueue); | 919 | destroy_workqueue(local->workqueue); |
890 | fail_workqueue: | 920 | fail_workqueue: |
891 | wiphy_unregister(local->hw.wiphy); | 921 | wiphy_unregister(local->hw.wiphy); |
892 | fail_wiphy_register: | 922 | fail_wiphy_register: |
@@ -928,7 +958,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
928 | skb_queue_purge(&local->skb_queue); | 958 | skb_queue_purge(&local->skb_queue); |
929 | skb_queue_purge(&local->skb_queue_unreliable); | 959 | skb_queue_purge(&local->skb_queue_unreliable); |
930 | 960 | ||
931 | destroy_workqueue(local->hw.workqueue); | 961 | destroy_workqueue(local->workqueue); |
932 | wiphy_unregister(local->hw.wiphy); | 962 | wiphy_unregister(local->hw.wiphy); |
933 | ieee80211_wep_free(local); | 963 | ieee80211_wep_free(local); |
934 | ieee80211_led_exit(local); | 964 | ieee80211_led_exit(local); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 9a3826978b1c..2f4f518ab45c 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -54,7 +54,7 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data) | |||
54 | return; | 54 | return; |
55 | } | 55 | } |
56 | 56 | ||
57 | queue_work(local->hw.workqueue, &ifmsh->work); | 57 | ieee80211_queue_work(local->hw.workqueue, &ifmsh->work); |
58 | } | 58 | } |
59 | 59 | ||
60 | /** | 60 | /** |
@@ -357,7 +357,7 @@ static void ieee80211_mesh_path_timer(unsigned long data) | |||
357 | return; | 357 | return; |
358 | } | 358 | } |
359 | 359 | ||
360 | queue_work(local->hw.workqueue, &ifmsh->work); | 360 | ieee80211_queue_work(local->hw.workqueue, &ifmsh->work); |
361 | } | 361 | } |
362 | 362 | ||
363 | struct mesh_table *mesh_table_grow(struct mesh_table *tbl) | 363 | struct mesh_table *mesh_table_grow(struct mesh_table *tbl) |
@@ -471,7 +471,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
471 | struct ieee80211_local *local = sdata->local; | 471 | struct ieee80211_local *local = sdata->local; |
472 | 472 | ||
473 | ifmsh->housekeeping = true; | 473 | ifmsh->housekeeping = true; |
474 | queue_work(local->hw.workqueue, &ifmsh->work); | 474 | ieee80211_queue_work(local->hw.workqueue, &ifmsh->work); |
475 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | | 475 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | |
476 | BSS_CHANGED_BEACON_ENABLED); | 476 | BSS_CHANGED_BEACON_ENABLED); |
477 | } | 477 | } |
@@ -619,7 +619,7 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) | |||
619 | rcu_read_lock(); | 619 | rcu_read_lock(); |
620 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 620 | list_for_each_entry_rcu(sdata, &local->interfaces, list) |
621 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 621 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
622 | queue_work(local->hw.workqueue, &sdata->u.mesh.work); | 622 | ieee80211_queue_work(local->hw.workqueue, &sdata->u.mesh.work); |
623 | rcu_read_unlock(); | 623 | rcu_read_unlock(); |
624 | } | 624 | } |
625 | 625 | ||
@@ -692,7 +692,7 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
692 | case IEEE80211_STYPE_PROBE_RESP: | 692 | case IEEE80211_STYPE_PROBE_RESP: |
693 | case IEEE80211_STYPE_BEACON: | 693 | case IEEE80211_STYPE_BEACON: |
694 | skb_queue_tail(&ifmsh->skb_queue, skb); | 694 | skb_queue_tail(&ifmsh->skb_queue, skb); |
695 | queue_work(local->hw.workqueue, &ifmsh->work); | 695 | ieee80211_queue_work(local->hw.workqueue, &ifmsh->work); |
696 | return RX_QUEUED; | 696 | return RX_QUEUED; |
697 | } | 697 | } |
698 | 698 | ||
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index e93c37ef6a48..11ab71a68ff9 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -660,14 +660,14 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) | |||
660 | spin_unlock(&ifmsh->mesh_preq_queue_lock); | 660 | spin_unlock(&ifmsh->mesh_preq_queue_lock); |
661 | 661 | ||
662 | if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata))) | 662 | if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata))) |
663 | queue_work(sdata->local->hw.workqueue, &ifmsh->work); | 663 | ieee80211_queue_work(sdata->local->hw.workqueue, &ifmsh->work); |
664 | 664 | ||
665 | else if (time_before(jiffies, ifmsh->last_preq)) { | 665 | else if (time_before(jiffies, ifmsh->last_preq)) { |
666 | /* avoid long wait if did not send preqs for a long time | 666 | /* avoid long wait if did not send preqs for a long time |
667 | * and jiffies wrapped around | 667 | * and jiffies wrapped around |
668 | */ | 668 | */ |
669 | ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; | 669 | ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; |
670 | queue_work(sdata->local->hw.workqueue, &ifmsh->work); | 670 | ieee80211_queue_work(sdata->local->hw.workqueue, &ifmsh->work); |
671 | } else | 671 | } else |
672 | mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq + | 672 | mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq + |
673 | min_preq_int_jiff(sdata)); | 673 | min_preq_int_jiff(sdata)); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index ee83125ed179..6d5a1ee0445f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #define IEEE80211_AUTH_MAX_TRIES 3 | 31 | #define IEEE80211_AUTH_MAX_TRIES 3 |
32 | #define IEEE80211_ASSOC_TIMEOUT (HZ / 5) | 32 | #define IEEE80211_ASSOC_TIMEOUT (HZ / 5) |
33 | #define IEEE80211_ASSOC_MAX_TRIES 3 | 33 | #define IEEE80211_ASSOC_MAX_TRIES 3 |
34 | #define IEEE80211_MAX_PROBE_TRIES 5 | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * beacon loss detection timeout | 37 | * beacon loss detection timeout |
@@ -41,13 +42,13 @@ | |||
41 | * Time the connection can be idle before we probe | 42 | * Time the connection can be idle before we probe |
42 | * it to see if we can still talk to the AP. | 43 | * it to see if we can still talk to the AP. |
43 | */ | 44 | */ |
44 | #define IEEE80211_CONNECTION_IDLE_TIME (2 * HZ) | 45 | #define IEEE80211_CONNECTION_IDLE_TIME (30 * HZ) |
45 | /* | 46 | /* |
46 | * Time we wait for a probe response after sending | 47 | * Time we wait for a probe response after sending |
47 | * a probe request because of beacon loss or for | 48 | * a probe request because of beacon loss or for |
48 | * checking the connection still works. | 49 | * checking the connection still works. |
49 | */ | 50 | */ |
50 | #define IEEE80211_PROBE_WAIT (HZ / 5) | 51 | #define IEEE80211_PROBE_WAIT (HZ / 2) |
51 | 52 | ||
52 | #define TMR_RUNNING_TIMER 0 | 53 | #define TMR_RUNNING_TIMER 0 |
53 | #define TMR_RUNNING_CHANSW 1 | 54 | #define TMR_RUNNING_CHANSW 1 |
@@ -565,7 +566,7 @@ static void ieee80211_chswitch_timer(unsigned long data) | |||
565 | return; | 566 | return; |
566 | } | 567 | } |
567 | 568 | ||
568 | queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work); | 569 | ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work); |
569 | } | 570 | } |
570 | 571 | ||
571 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | 572 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, |
@@ -597,7 +598,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
597 | sdata->local->csa_channel = new_ch; | 598 | sdata->local->csa_channel = new_ch; |
598 | 599 | ||
599 | if (sw_elem->count <= 1) { | 600 | if (sw_elem->count <= 1) { |
600 | queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work); | 601 | ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work); |
601 | } else { | 602 | } else { |
602 | ieee80211_stop_queues_by_reason(&sdata->local->hw, | 603 | ieee80211_stop_queues_by_reason(&sdata->local->hw, |
603 | IEEE80211_QUEUE_STOP_REASON_CSA); | 604 | IEEE80211_QUEUE_STOP_REASON_CSA); |
@@ -763,7 +764,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data) | |||
763 | if (local->quiescing || local->suspended) | 764 | if (local->quiescing || local->suspended) |
764 | return; | 765 | return; |
765 | 766 | ||
766 | queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); | 767 | ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work); |
767 | } | 768 | } |
768 | 769 | ||
769 | /* MLME */ | 770 | /* MLME */ |
@@ -916,12 +917,9 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
916 | 917 | ||
917 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); | 918 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); |
918 | 919 | ||
919 | /* will be same as sdata */ | 920 | mutex_lock(&local->iflist_mtx); |
920 | if (local->ps_sdata) { | 921 | ieee80211_recalc_ps(local, -1); |
921 | mutex_lock(&local->iflist_mtx); | 922 | mutex_unlock(&local->iflist_mtx); |
922 | ieee80211_recalc_ps(local, -1); | ||
923 | mutex_unlock(&local->iflist_mtx); | ||
924 | } | ||
925 | 923 | ||
926 | netif_tx_start_all_queues(sdata->dev); | 924 | netif_tx_start_all_queues(sdata->dev); |
927 | netif_carrier_on(sdata->dev); | 925 | netif_carrier_on(sdata->dev); |
@@ -950,7 +948,7 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | |||
950 | * due to work needing to be done. Hence, queue the STAs work | 948 | * due to work needing to be done. Hence, queue the STAs work |
951 | * again for that. | 949 | * again for that. |
952 | */ | 950 | */ |
953 | queue_work(local->hw.workqueue, &ifmgd->work); | 951 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
954 | return RX_MGMT_CFG80211_AUTH_TO; | 952 | return RX_MGMT_CFG80211_AUTH_TO; |
955 | } | 953 | } |
956 | 954 | ||
@@ -995,7 +993,7 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, | |||
995 | * due to work needing to be done. Hence, queue the STAs work | 993 | * due to work needing to be done. Hence, queue the STAs work |
996 | * again for that. | 994 | * again for that. |
997 | */ | 995 | */ |
998 | queue_work(local->hw.workqueue, &ifmgd->work); | 996 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
999 | return RX_MGMT_CFG80211_AUTH_TO; | 997 | return RX_MGMT_CFG80211_AUTH_TO; |
1000 | } | 998 | } |
1001 | 999 | ||
@@ -1124,7 +1122,7 @@ ieee80211_associate(struct ieee80211_sub_if_data *sdata, | |||
1124 | * due to work needing to be done. Hence, queue the STAs work | 1122 | * due to work needing to be done. Hence, queue the STAs work |
1125 | * again for that. | 1123 | * again for that. |
1126 | */ | 1124 | */ |
1127 | queue_work(local->hw.workqueue, &ifmgd->work); | 1125 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
1128 | return RX_MGMT_CFG80211_ASSOC_TO; | 1126 | return RX_MGMT_CFG80211_ASSOC_TO; |
1129 | } | 1127 | } |
1130 | 1128 | ||
@@ -1156,11 +1154,24 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | |||
1156 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); | 1154 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); |
1157 | } | 1155 | } |
1158 | 1156 | ||
1157 | static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | ||
1158 | { | ||
1159 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
1160 | const u8 *ssid; | ||
1161 | |||
1162 | ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID); | ||
1163 | ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, | ||
1164 | ssid + 2, ssid[1], NULL, 0); | ||
1165 | |||
1166 | ifmgd->probe_send_count++; | ||
1167 | ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; | ||
1168 | run_again(ifmgd, ifmgd->probe_timeout); | ||
1169 | } | ||
1170 | |||
1159 | static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | 1171 | static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, |
1160 | bool beacon) | 1172 | bool beacon) |
1161 | { | 1173 | { |
1162 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1174 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1163 | const u8 *ssid; | ||
1164 | bool already = false; | 1175 | bool already = false; |
1165 | 1176 | ||
1166 | if (!netif_running(sdata->dev)) | 1177 | if (!netif_running(sdata->dev)) |
@@ -1203,18 +1214,12 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
1203 | if (already) | 1214 | if (already) |
1204 | goto out; | 1215 | goto out; |
1205 | 1216 | ||
1206 | ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; | ||
1207 | |||
1208 | mutex_lock(&sdata->local->iflist_mtx); | 1217 | mutex_lock(&sdata->local->iflist_mtx); |
1209 | ieee80211_recalc_ps(sdata->local, -1); | 1218 | ieee80211_recalc_ps(sdata->local, -1); |
1210 | mutex_unlock(&sdata->local->iflist_mtx); | 1219 | mutex_unlock(&sdata->local->iflist_mtx); |
1211 | 1220 | ||
1212 | ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID); | 1221 | ifmgd->probe_send_count = 0; |
1213 | ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, | 1222 | ieee80211_mgd_probe_ap_send(sdata); |
1214 | ssid + 2, ssid[1], NULL, 0); | ||
1215 | |||
1216 | run_again(ifmgd, ifmgd->probe_timeout); | ||
1217 | |||
1218 | out: | 1223 | out: |
1219 | mutex_unlock(&ifmgd->mtx); | 1224 | mutex_unlock(&ifmgd->mtx); |
1220 | } | 1225 | } |
@@ -1232,8 +1237,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif) | |||
1232 | { | 1237 | { |
1233 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 1238 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
1234 | 1239 | ||
1235 | queue_work(sdata->local->hw.workqueue, | 1240 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); |
1236 | &sdata->u.mgd.beacon_loss_work); | ||
1237 | } | 1241 | } |
1238 | EXPORT_SYMBOL(ieee80211_beacon_loss); | 1242 | EXPORT_SYMBOL(ieee80211_beacon_loss); |
1239 | 1243 | ||
@@ -1570,6 +1574,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1570 | wk->bss->cbss.bssid, | 1574 | wk->bss->cbss.bssid, |
1571 | ap_ht_cap_flags); | 1575 | ap_ht_cap_flags); |
1572 | 1576 | ||
1577 | /* delete work item -- must be before set_associated for PS */ | ||
1578 | list_del(&wk->list); | ||
1579 | |||
1573 | /* set AID and assoc capability, | 1580 | /* set AID and assoc capability, |
1574 | * ieee80211_set_associated() will tell the driver */ | 1581 | * ieee80211_set_associated() will tell the driver */ |
1575 | bss_conf->aid = aid; | 1582 | bss_conf->aid = aid; |
@@ -1583,7 +1590,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1583 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); | 1590 | ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); |
1584 | mod_beacon_timer(sdata); | 1591 | mod_beacon_timer(sdata); |
1585 | 1592 | ||
1586 | list_del(&wk->list); | ||
1587 | kfree(wk); | 1593 | kfree(wk); |
1588 | return RX_MGMT_CFG80211_ASSOC; | 1594 | return RX_MGMT_CFG80211_ASSOC; |
1589 | } | 1595 | } |
@@ -1847,12 +1853,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1847 | bssid, ap_ht_cap_flags); | 1853 | bssid, ap_ht_cap_flags); |
1848 | } | 1854 | } |
1849 | 1855 | ||
1856 | /* Note: country IE parsing is done for us by cfg80211 */ | ||
1850 | if (elems.country_elem) { | 1857 | if (elems.country_elem) { |
1851 | /* Note we are only reviewing this on beacons | ||
1852 | * for the BSSID we are associated to */ | ||
1853 | regulatory_hint_11d(local->hw.wiphy, | ||
1854 | elems.country_elem, elems.country_elem_len); | ||
1855 | |||
1856 | /* TODO: IBSS also needs this */ | 1858 | /* TODO: IBSS also needs this */ |
1857 | if (elems.pwr_constr_elem) | 1859 | if (elems.pwr_constr_elem) |
1858 | ieee80211_handle_pwr_constr(sdata, | 1860 | ieee80211_handle_pwr_constr(sdata, |
@@ -1888,7 +1890,7 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1888 | case IEEE80211_STYPE_DISASSOC: | 1890 | case IEEE80211_STYPE_DISASSOC: |
1889 | case IEEE80211_STYPE_ACTION: | 1891 | case IEEE80211_STYPE_ACTION: |
1890 | skb_queue_tail(&sdata->u.mgd.skb_queue, skb); | 1892 | skb_queue_tail(&sdata->u.mgd.skb_queue, skb); |
1891 | queue_work(local->hw.workqueue, &sdata->u.mgd.work); | 1893 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); |
1892 | return RX_QUEUED; | 1894 | return RX_QUEUED; |
1893 | } | 1895 | } |
1894 | 1896 | ||
@@ -2026,7 +2028,7 @@ static void ieee80211_sta_timer(unsigned long data) | |||
2026 | return; | 2028 | return; |
2027 | } | 2029 | } |
2028 | 2030 | ||
2029 | queue_work(local->hw.workqueue, &ifmgd->work); | 2031 | ieee80211_queue_work(&local->hw, &ifmgd->work); |
2030 | } | 2032 | } |
2031 | 2033 | ||
2032 | static void ieee80211_sta_work(struct work_struct *work) | 2034 | static void ieee80211_sta_work(struct work_struct *work) |
@@ -2051,13 +2053,11 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2051 | return; | 2053 | return; |
2052 | 2054 | ||
2053 | /* | 2055 | /* |
2054 | * Nothing should have been stuffed into the workqueue during | 2056 | * ieee80211_queue_work() should have picked up most cases, |
2055 | * the suspend->resume cycle. If this WARN is seen then there | 2057 | * here we'll pick the the rest. |
2056 | * is a bug with either the driver suspend or something in | ||
2057 | * mac80211 stuffing into the workqueue which we haven't yet | ||
2058 | * cleared during mac80211's suspend cycle. | ||
2059 | */ | 2058 | */ |
2060 | if (WARN_ON(local->suspended)) | 2059 | if (WARN(local->suspended, "STA MLME work scheduled while " |
2060 | "going to suspend\n")) | ||
2061 | return; | 2061 | return; |
2062 | 2062 | ||
2063 | ifmgd = &sdata->u.mgd; | 2063 | ifmgd = &sdata->u.mgd; |
@@ -2072,17 +2072,27 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2072 | if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | 2072 | if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | |
2073 | IEEE80211_STA_CONNECTION_POLL) && | 2073 | IEEE80211_STA_CONNECTION_POLL) && |
2074 | ifmgd->associated) { | 2074 | ifmgd->associated) { |
2075 | u8 bssid[ETH_ALEN]; | ||
2076 | |||
2077 | memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN); | ||
2075 | if (time_is_after_jiffies(ifmgd->probe_timeout)) | 2078 | if (time_is_after_jiffies(ifmgd->probe_timeout)) |
2076 | run_again(ifmgd, ifmgd->probe_timeout); | 2079 | run_again(ifmgd, ifmgd->probe_timeout); |
2077 | else { | 2080 | |
2078 | u8 bssid[ETH_ALEN]; | 2081 | else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { |
2082 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
2083 | printk(KERN_DEBUG "No probe response from AP %pM" | ||
2084 | " after %dms, try %d\n", bssid, | ||
2085 | (1000 * IEEE80211_PROBE_WAIT)/HZ, | ||
2086 | ifmgd->probe_send_count); | ||
2087 | #endif | ||
2088 | ieee80211_mgd_probe_ap_send(sdata); | ||
2089 | } else { | ||
2079 | /* | 2090 | /* |
2080 | * We actually lost the connection ... or did we? | 2091 | * We actually lost the connection ... or did we? |
2081 | * Let's make sure! | 2092 | * Let's make sure! |
2082 | */ | 2093 | */ |
2083 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | | 2094 | ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | |
2084 | IEEE80211_STA_BEACON_POLL); | 2095 | IEEE80211_STA_BEACON_POLL); |
2085 | memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN); | ||
2086 | printk(KERN_DEBUG "No probe response from AP %pM" | 2096 | printk(KERN_DEBUG "No probe response from AP %pM" |
2087 | " after %dms, disconnecting.\n", | 2097 | " after %dms, disconnecting.\n", |
2088 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); | 2098 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); |
@@ -2113,9 +2123,9 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2113 | mutex_unlock(&ifmgd->mtx); | 2123 | mutex_unlock(&ifmgd->mtx); |
2114 | 2124 | ||
2115 | if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) | 2125 | if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) |
2116 | queue_delayed_work(local->hw.workqueue, | 2126 | ieee80211_queue_delayed_work(&local->hw, |
2117 | &local->scan_work, | 2127 | &local->scan_work, |
2118 | round_jiffies_relative(0)); | 2128 | round_jiffies_relative(0)); |
2119 | return; | 2129 | return; |
2120 | } | 2130 | } |
2121 | 2131 | ||
@@ -2196,8 +2206,7 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data) | |||
2196 | if (local->quiescing) | 2206 | if (local->quiescing) |
2197 | return; | 2207 | return; |
2198 | 2208 | ||
2199 | queue_work(sdata->local->hw.workqueue, | 2209 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); |
2200 | &sdata->u.mgd.beacon_loss_work); | ||
2201 | } | 2210 | } |
2202 | 2211 | ||
2203 | static void ieee80211_sta_conn_mon_timer(unsigned long data) | 2212 | static void ieee80211_sta_conn_mon_timer(unsigned long data) |
@@ -2210,7 +2219,7 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data) | |||
2210 | if (local->quiescing) | 2219 | if (local->quiescing) |
2211 | return; | 2220 | return; |
2212 | 2221 | ||
2213 | queue_work(local->hw.workqueue, &ifmgd->monitor_work); | 2222 | ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); |
2214 | } | 2223 | } |
2215 | 2224 | ||
2216 | static void ieee80211_sta_monitor_work(struct work_struct *work) | 2225 | static void ieee80211_sta_monitor_work(struct work_struct *work) |
@@ -2229,10 +2238,10 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) | |||
2229 | IEEE80211_STA_CONNECTION_POLL); | 2238 | IEEE80211_STA_CONNECTION_POLL); |
2230 | 2239 | ||
2231 | /* let's probe the connection once */ | 2240 | /* let's probe the connection once */ |
2232 | queue_work(sdata->local->hw.workqueue, | 2241 | ieee80211_queue_work(&sdata->local->hw, |
2233 | &sdata->u.mgd.monitor_work); | 2242 | &sdata->u.mgd.monitor_work); |
2234 | /* and do all the other regular work too */ | 2243 | /* and do all the other regular work too */ |
2235 | queue_work(sdata->local->hw.workqueue, | 2244 | ieee80211_queue_work(&sdata->local->hw, |
2236 | &sdata->u.mgd.work); | 2245 | &sdata->u.mgd.work); |
2237 | } | 2246 | } |
2238 | } | 2247 | } |
@@ -2393,7 +2402,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
2393 | list_add(&wk->list, &sdata->u.mgd.work_list); | 2402 | list_add(&wk->list, &sdata->u.mgd.work_list); |
2394 | mutex_unlock(&ifmgd->mtx); | 2403 | mutex_unlock(&ifmgd->mtx); |
2395 | 2404 | ||
2396 | queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work); | 2405 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work); |
2397 | return 0; | 2406 | return 0; |
2398 | } | 2407 | } |
2399 | 2408 | ||
@@ -2467,7 +2476,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2467 | else | 2476 | else |
2468 | ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; | 2477 | ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; |
2469 | 2478 | ||
2470 | queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work); | 2479 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work); |
2471 | 2480 | ||
2472 | err = 0; | 2481 | err = 0; |
2473 | 2482 | ||
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 5e3d476972f9..a5d2f1fb4417 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -26,7 +26,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
26 | /* make quiescing visible to timers everywhere */ | 26 | /* make quiescing visible to timers everywhere */ |
27 | mb(); | 27 | mb(); |
28 | 28 | ||
29 | flush_workqueue(local->hw.workqueue); | 29 | flush_workqueue(local->workqueue); |
30 | 30 | ||
31 | /* Don't try to run timers while suspended. */ | 31 | /* Don't try to run timers while suspended. */ |
32 | del_timer_sync(&local->sta_cleanup); | 32 | del_timer_sync(&local->sta_cleanup); |
@@ -96,6 +96,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
96 | if (!netif_running(sdata->dev)) | 96 | if (!netif_running(sdata->dev)) |
97 | continue; | 97 | continue; |
98 | 98 | ||
99 | /* disable beaconing */ | ||
100 | ieee80211_bss_info_change_notify(sdata, | ||
101 | BSS_CHANGED_BEACON_ENABLED); | ||
102 | |||
99 | conf.vif = &sdata->vif; | 103 | conf.vif = &sdata->vif; |
100 | conf.type = sdata->vif.type; | 104 | conf.type = sdata->vif.type; |
101 | conf.mac_addr = sdata->dev->dev_addr; | 105 | conf.mac_addr = sdata->dev->dev_addr; |
@@ -113,7 +117,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) | |||
113 | * shouldn't be doing (or cancel everything in the | 117 | * shouldn't be doing (or cancel everything in the |
114 | * stop callback) that but better safe than sorry. | 118 | * stop callback) that but better safe than sorry. |
115 | */ | 119 | */ |
116 | flush_workqueue(local->hw.workqueue); | 120 | flush_workqueue(local->workqueue); |
117 | 121 | ||
118 | local->suspended = true; | 122 | local->suspended = true; |
119 | /* need suspended to be visible before quiescing is false */ | 123 | /* need suspended to be visible before quiescing is false */ |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 45731000eb8d..244f53f3c8b4 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -385,8 +385,9 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
385 | spin_unlock_bh(&local->filter_lock); | 385 | spin_unlock_bh(&local->filter_lock); |
386 | 386 | ||
387 | /* TODO: start scan as soon as all nullfunc frames are ACKed */ | 387 | /* TODO: start scan as soon as all nullfunc frames are ACKed */ |
388 | queue_delayed_work(local->hw.workqueue, &local->scan_work, | 388 | ieee80211_queue_delayed_work(&local->hw, |
389 | IEEE80211_CHANNEL_TIME); | 389 | &local->scan_work, |
390 | IEEE80211_CHANNEL_TIME); | ||
390 | 391 | ||
391 | return 0; | 392 | return 0; |
392 | } | 393 | } |
@@ -715,8 +716,7 @@ void ieee80211_scan_work(struct work_struct *work) | |||
715 | } | 716 | } |
716 | } while (next_delay == 0); | 717 | } while (next_delay == 0); |
717 | 718 | ||
718 | queue_delayed_work(local->hw.workqueue, &local->scan_work, | 719 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); |
719 | next_delay); | ||
720 | } | 720 | } |
721 | 721 | ||
722 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | 722 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 4e1b2ba122cd..7cffaa046b33 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1400,7 +1400,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1400 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 1400 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
1401 | ieee80211_stop_queues_by_reason(&local->hw, | 1401 | ieee80211_stop_queues_by_reason(&local->hw, |
1402 | IEEE80211_QUEUE_STOP_REASON_PS); | 1402 | IEEE80211_QUEUE_STOP_REASON_PS); |
1403 | queue_work(local->hw.workqueue, | 1403 | ieee80211_queue_work(&local->hw, |
1404 | &local->dynamic_ps_disable_work); | 1404 | &local->dynamic_ps_disable_work); |
1405 | } | 1405 | } |
1406 | 1406 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 8502936e5314..e55d57f559ec 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -511,6 +511,46 @@ void ieee80211_iterate_active_interfaces_atomic( | |||
511 | } | 511 | } |
512 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | 512 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); |
513 | 513 | ||
514 | /* | ||
515 | * Nothing should have been stuffed into the workqueue during | ||
516 | * the suspend->resume cycle. If this WARN is seen then there | ||
517 | * is a bug with either the driver suspend or something in | ||
518 | * mac80211 stuffing into the workqueue which we haven't yet | ||
519 | * cleared during mac80211's suspend cycle. | ||
520 | */ | ||
521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) | ||
522 | { | ||
523 | if (WARN(local->suspended, "queueing ieee80211 work while " | ||
524 | "going to suspend\n")) | ||
525 | return false; | ||
526 | |||
527 | return true; | ||
528 | } | ||
529 | |||
530 | void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work) | ||
531 | { | ||
532 | struct ieee80211_local *local = hw_to_local(hw); | ||
533 | |||
534 | if (!ieee80211_can_queue_work(local)) | ||
535 | return; | ||
536 | |||
537 | queue_work(local->workqueue, work); | ||
538 | } | ||
539 | EXPORT_SYMBOL(ieee80211_queue_work); | ||
540 | |||
541 | void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, | ||
542 | struct delayed_work *dwork, | ||
543 | unsigned long delay) | ||
544 | { | ||
545 | struct ieee80211_local *local = hw_to_local(hw); | ||
546 | |||
547 | if (!ieee80211_can_queue_work(local)) | ||
548 | return; | ||
549 | |||
550 | queue_delayed_work(local->workqueue, dwork, delay); | ||
551 | } | ||
552 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); | ||
553 | |||
514 | void ieee802_11_parse_elems(u8 *start, size_t len, | 554 | void ieee802_11_parse_elems(u8 *start, size_t len, |
515 | struct ieee802_11_elems *elems) | 555 | struct ieee802_11_elems *elems) |
516 | { | 556 | { |
@@ -1114,3 +1154,4 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1114 | #endif | 1154 | #endif |
1115 | return 0; | 1155 | return 0; |
1116 | } | 1156 | } |
1157 | |||