aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-08-06 15:57:18 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-06 15:57:18 -0400
commitbfe34ebbaa125f00da309f59cc9d30febe1e3115 (patch)
tree505b43fc81be09ec5b42f82a3e64f300a5e838d5 /net
parent3d7ddd540b4c2d24c6a3e7a52c083a0c31e6151c (diff)
parent6b4f645a491ac29c7dced415d034eea7736155a6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/driver-trace.c3
-rw-r--r--net/mac80211/ibss.c6
-rw-r--r--net/mac80211/ieee80211_i.h9
-rw-r--r--net/mac80211/iface.c36
-rw-r--r--net/mac80211/main.c40
-rw-r--r--net/mac80211/mesh.c10
-rw-r--r--net/mac80211/mesh_hwmp.c4
-rw-r--r--net/mac80211/mlme.c113
-rw-r--r--net/mac80211/pm.c8
-rw-r--r--net/mac80211/scan.c8
-rw-r--r--net/mac80211/tx.c2
-rw-r--r--net/mac80211/util.c41
-rw-r--r--net/rfkill/core.c4
-rw-r--r--net/wireless/core.c24
-rw-r--r--net/wireless/core.h8
-rw-r--r--net/wireless/mlme.c38
-rw-r--r--net/wireless/reg.c107
-rw-r--r--net/wireless/reg.h15
-rw-r--r--net/wireless/sme.c55
-rw-r--r--net/wireless/wext.c1
20 files changed, 349 insertions, 183 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
363struct mesh_table *mesh_table_grow(struct mesh_table *tbl) 363struct 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
571void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, 572void 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
1157static 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
1159static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, 1171static 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}
1238EXPORT_SYMBOL(ieee80211_beacon_loss); 1242EXPORT_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
2032static void ieee80211_sta_work(struct work_struct *work) 2034static 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
2203static void ieee80211_sta_conn_mon_timer(unsigned long data) 2212static 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
2216static void ieee80211_sta_monitor_work(struct work_struct *work) 2225static 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
722int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 722int 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}
512EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); 512EXPORT_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 */
521static 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
530void 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}
539EXPORT_SYMBOL(ieee80211_queue_work);
540
541void 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}
552EXPORT_SYMBOL(ieee80211_queue_delayed_work);
553
514void ieee802_11_parse_elems(u8 *start, size_t len, 554void 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
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 044de1c6af3d..dbeaf2983822 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -589,11 +589,13 @@ static const char *rfkill_get_type_str(enum rfkill_type type)
589 return "wimax"; 589 return "wimax";
590 case RFKILL_TYPE_WWAN: 590 case RFKILL_TYPE_WWAN:
591 return "wwan"; 591 return "wwan";
592 case RFKILL_TYPE_GPS:
593 return "gps";
592 default: 594 default:
593 BUG(); 595 BUG();
594 } 596 }
595 597
596 BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_WWAN + 1); 598 BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_GPS + 1);
597} 599}
598 600
599static ssize_t rfkill_type_show(struct device *dev, 601static ssize_t rfkill_type_show(struct device *dev,
diff --git a/net/wireless/core.c b/net/wireless/core.c
index f9fee65dc06a..1e189306560d 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -34,9 +34,7 @@ MODULE_DESCRIPTION("wireless configuration support");
34LIST_HEAD(cfg80211_rdev_list); 34LIST_HEAD(cfg80211_rdev_list);
35 35
36/* 36/*
37 * This is used to protect the cfg80211_rdev_list, cfg80211_regdomain, 37 * This is used to protect the cfg80211_rdev_list
38 * country_ie_regdomain, the reg_beacon_list and the the last regulatory
39 * request receipt (last_request).
40 */ 38 */
41DEFINE_MUTEX(cfg80211_mutex); 39DEFINE_MUTEX(cfg80211_mutex);
42 40
@@ -314,7 +312,8 @@ static void cfg80211_process_events(struct wireless_dev *wdev)
314 ev->cr.req_ie, ev->cr.req_ie_len, 312 ev->cr.req_ie, ev->cr.req_ie_len,
315 ev->cr.resp_ie, ev->cr.resp_ie_len, 313 ev->cr.resp_ie, ev->cr.resp_ie_len,
316 ev->cr.status, 314 ev->cr.status,
317 ev->cr.status == WLAN_STATUS_SUCCESS); 315 ev->cr.status == WLAN_STATUS_SUCCESS,
316 NULL);
318 break; 317 break;
319 case EVENT_ROAMED: 318 case EVENT_ROAMED:
320 __cfg80211_roamed(wdev, ev->rm.bssid, 319 __cfg80211_roamed(wdev, ev->rm.bssid,
@@ -672,7 +671,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
672 wdev->wext.default_mgmt_key = -1; 671 wdev->wext.default_mgmt_key = -1;
673 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; 672 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
674 wdev->wext.ps = CONFIG_CFG80211_DEFAULT_PS_VALUE; 673 wdev->wext.ps = CONFIG_CFG80211_DEFAULT_PS_VALUE;
675 wdev->wext.ps_timeout = 500; 674 wdev->wext.ps_timeout = 100;
676 if (rdev->ops->set_power_mgmt) 675 if (rdev->ops->set_power_mgmt)
677 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, 676 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
678 wdev->wext.ps, 677 wdev->wext.ps,
@@ -724,15 +723,22 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
724 break; 723 break;
725 case NETDEV_UNREGISTER: 724 case NETDEV_UNREGISTER:
726 mutex_lock(&rdev->devlist_mtx); 725 mutex_lock(&rdev->devlist_mtx);
726 /*
727 * It is possible to get NETDEV_UNREGISTER
728 * multiple times. To detect that, check
729 * that the interface is still on the list
730 * of registered interfaces, and only then
731 * remove and clean it up.
732 */
727 if (!list_empty(&wdev->list)) { 733 if (!list_empty(&wdev->list)) {
728 sysfs_remove_link(&dev->dev.kobj, "phy80211"); 734 sysfs_remove_link(&dev->dev.kobj, "phy80211");
729 list_del_init(&wdev->list); 735 list_del_init(&wdev->list);
730 } 736 mutex_destroy(&wdev->mtx);
731 mutex_unlock(&rdev->devlist_mtx);
732 mutex_destroy(&wdev->mtx);
733#ifdef CONFIG_WIRELESS_EXT 737#ifdef CONFIG_WIRELESS_EXT
734 kfree(wdev->wext.keys); 738 kfree(wdev->wext.keys);
735#endif 739#endif
740 }
741 mutex_unlock(&rdev->devlist_mtx);
736 break; 742 break;
737 case NETDEV_PRE_UP: 743 case NETDEV_PRE_UP:
738 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) 744 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 6d903c1d721d..325c17e6198c 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -127,6 +127,11 @@ static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pu
127 return container_of(pub, struct cfg80211_internal_bss, pub); 127 return container_of(pub, struct cfg80211_internal_bss, pub);
128} 128}
129 129
130static inline void cfg80211_ref_bss(struct cfg80211_internal_bss *bss)
131{
132 kref_get(&bss->ref);
133}
134
130static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss) 135static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
131{ 136{
132 atomic_inc(&bss->hold); 137 atomic_inc(&bss->hold);
@@ -323,7 +328,8 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
323void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 328void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
324 const u8 *req_ie, size_t req_ie_len, 329 const u8 *req_ie, size_t req_ie_len,
325 const u8 *resp_ie, size_t resp_ie_len, 330 const u8 *resp_ie, size_t resp_ie_len,
326 u16 status, bool wextev); 331 u16 status, bool wextev,
332 struct cfg80211_bss *bss);
327 333
328/* SME */ 334/* SME */
329int __cfg80211_connect(struct cfg80211_registered_device *rdev, 335int __cfg80211_connect(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 097a87d7bae1..525e8e247b30 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -61,7 +61,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
61 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 61 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
62 u8 *ie = mgmt->u.assoc_resp.variable; 62 u8 *ie = mgmt->u.assoc_resp.variable;
63 int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); 63 int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
64 bool done; 64 struct cfg80211_internal_bss *bss = NULL;
65 65
66 wdev_lock(wdev); 66 wdev_lock(wdev);
67 67
@@ -69,22 +69,32 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
69 69
70 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL); 70 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
71 71
72 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
73 status_code,
74 status_code == WLAN_STATUS_SUCCESS);
75
76 if (status_code == WLAN_STATUS_SUCCESS) { 72 if (status_code == WLAN_STATUS_SUCCESS) {
77 for (i = 0; wdev->current_bss && i < MAX_AUTH_BSSES; i++) { 73 for (i = 0; i < MAX_AUTH_BSSES; i++) {
78 if (wdev->auth_bsses[i] == wdev->current_bss) { 74 if (!wdev->auth_bsses[i])
79 cfg80211_unhold_bss(wdev->auth_bsses[i]); 75 continue;
80 cfg80211_put_bss(&wdev->auth_bsses[i]->pub); 76 if (memcmp(wdev->auth_bsses[i]->pub.bssid, mgmt->bssid,
77 ETH_ALEN) == 0) {
78 bss = wdev->auth_bsses[i];
81 wdev->auth_bsses[i] = NULL; 79 wdev->auth_bsses[i] = NULL;
82 done = true; 80 /* additional reference to drop hold */
81 cfg80211_ref_bss(bss);
83 break; 82 break;
84 } 83 }
85 } 84 }
86 85
87 WARN_ON(!done); 86 WARN_ON(!bss);
87 }
88
89 /* this consumes one bss reference (unless bss is NULL) */
90 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
91 status_code,
92 status_code == WLAN_STATUS_SUCCESS,
93 bss ? &bss->pub : NULL);
94 /* drop hold now, and also reference acquired above */
95 if (bss) {
96 cfg80211_unhold_bss(bss);
97 cfg80211_put_bss(&bss->pub);
88 } 98 }
89 99
90 wdev_unlock(wdev); 100 wdev_unlock(wdev);
@@ -144,7 +154,7 @@ static void __cfg80211_send_deauth(struct net_device *dev,
144 } else if (wdev->sme_state == CFG80211_SME_CONNECTING) { 154 } else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
145 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, 155 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
146 WLAN_STATUS_UNSPECIFIED_FAILURE, 156 WLAN_STATUS_UNSPECIFIED_FAILURE,
147 false); 157 false, NULL);
148 } 158 }
149} 159}
150 160
@@ -241,7 +251,7 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
241 if (wdev->sme_state == CFG80211_SME_CONNECTING) 251 if (wdev->sme_state == CFG80211_SME_CONNECTING)
242 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 252 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
243 WLAN_STATUS_UNSPECIFIED_FAILURE, 253 WLAN_STATUS_UNSPECIFIED_FAILURE,
244 false); 254 false, NULL);
245 255
246 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { 256 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
247 if (wdev->authtry_bsses[i] && 257 if (wdev->authtry_bsses[i] &&
@@ -275,7 +285,7 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
275 if (wdev->sme_state == CFG80211_SME_CONNECTING) 285 if (wdev->sme_state == CFG80211_SME_CONNECTING)
276 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 286 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
277 WLAN_STATUS_UNSPECIFIED_FAILURE, 287 WLAN_STATUS_UNSPECIFIED_FAILURE,
278 false); 288 false, NULL);
279 289
280 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { 290 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
281 if (wdev->auth_bsses[i] && 291 if (wdev->auth_bsses[i] &&
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index fb40428a5946..b3ac0aace0e5 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -62,6 +62,16 @@ const struct ieee80211_regdomain *cfg80211_regdomain;
62 */ 62 */
63static const struct ieee80211_regdomain *country_ie_regdomain; 63static const struct ieee80211_regdomain *country_ie_regdomain;
64 64
65/*
66 * Protects static reg.c components:
67 * - cfg80211_world_regdom
68 * - cfg80211_regdom
69 * - country_ie_regdomain
70 * - last_request
71 */
72DEFINE_MUTEX(reg_mutex);
73#define assert_reg_lock() WARN_ON(!mutex_is_locked(&reg_mutex))
74
65/* Used to queue up regulatory hints */ 75/* Used to queue up regulatory hints */
66static LIST_HEAD(reg_requests_list); 76static LIST_HEAD(reg_requests_list);
67static spinlock_t reg_requests_lock; 77static spinlock_t reg_requests_lock;
@@ -1293,7 +1303,7 @@ static void handle_channel_custom(struct wiphy *wiphy,
1293 struct ieee80211_supported_band *sband; 1303 struct ieee80211_supported_band *sband;
1294 struct ieee80211_channel *chan; 1304 struct ieee80211_channel *chan;
1295 1305
1296 assert_cfg80211_lock(); 1306 assert_reg_lock();
1297 1307
1298 sband = wiphy->bands[band]; 1308 sband = wiphy->bands[band];
1299 BUG_ON(chan_idx >= sband->n_channels); 1309 BUG_ON(chan_idx >= sband->n_channels);
@@ -1342,14 +1352,14 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
1342 enum ieee80211_band band; 1352 enum ieee80211_band band;
1343 unsigned int bands_set = 0; 1353 unsigned int bands_set = 0;
1344 1354
1345 mutex_lock(&cfg80211_mutex); 1355 mutex_lock(&reg_mutex);
1346 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1356 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1347 if (!wiphy->bands[band]) 1357 if (!wiphy->bands[band])
1348 continue; 1358 continue;
1349 handle_band_custom(wiphy, band, regd); 1359 handle_band_custom(wiphy, band, regd);
1350 bands_set++; 1360 bands_set++;
1351 } 1361 }
1352 mutex_unlock(&cfg80211_mutex); 1362 mutex_unlock(&reg_mutex);
1353 1363
1354 /* 1364 /*
1355 * no point in calling this if it won't have any effect 1365 * no point in calling this if it won't have any effect
@@ -1495,7 +1505,7 @@ static int ignore_request(struct wiphy *wiphy,
1495 * Returns zero if all went fine, %-EALREADY if a regulatory domain had 1505 * Returns zero if all went fine, %-EALREADY if a regulatory domain had
1496 * already been set or other standard error codes. 1506 * already been set or other standard error codes.
1497 * 1507 *
1498 * Caller must hold &cfg80211_mutex 1508 * Caller must hold &cfg80211_mutex and &reg_mutex
1499 */ 1509 */
1500static int __regulatory_hint(struct wiphy *wiphy, 1510static int __regulatory_hint(struct wiphy *wiphy,
1501 struct regulatory_request *pending_request) 1511 struct regulatory_request *pending_request)
@@ -1570,6 +1580,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1570 BUG_ON(!reg_request->alpha2); 1580 BUG_ON(!reg_request->alpha2);
1571 1581
1572 mutex_lock(&cfg80211_mutex); 1582 mutex_lock(&cfg80211_mutex);
1583 mutex_lock(&reg_mutex);
1573 1584
1574 if (wiphy_idx_valid(reg_request->wiphy_idx)) 1585 if (wiphy_idx_valid(reg_request->wiphy_idx))
1575 wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx); 1586 wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);
@@ -1585,6 +1596,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1585 if (r == -EALREADY && wiphy && wiphy->strict_regulatory) 1596 if (r == -EALREADY && wiphy && wiphy->strict_regulatory)
1586 wiphy_update_regulatory(wiphy, reg_request->initiator); 1597 wiphy_update_regulatory(wiphy, reg_request->initiator);
1587out: 1598out:
1599 mutex_unlock(&reg_mutex);
1588 mutex_unlock(&cfg80211_mutex); 1600 mutex_unlock(&cfg80211_mutex);
1589} 1601}
1590 1602
@@ -1613,6 +1625,10 @@ static void reg_process_pending_beacon_hints(void)
1613 struct cfg80211_registered_device *rdev; 1625 struct cfg80211_registered_device *rdev;
1614 struct reg_beacon *pending_beacon, *tmp; 1626 struct reg_beacon *pending_beacon, *tmp;
1615 1627
1628 /*
1629 * No need to hold the reg_mutex here as we just touch wiphys
1630 * and do not read or access regulatory variables.
1631 */
1616 mutex_lock(&cfg80211_mutex); 1632 mutex_lock(&cfg80211_mutex);
1617 1633
1618 /* This goes through the _pending_ beacon list */ 1634 /* This goes through the _pending_ beacon list */
@@ -1734,12 +1750,13 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
1734} 1750}
1735EXPORT_SYMBOL(regulatory_hint); 1751EXPORT_SYMBOL(regulatory_hint);
1736 1752
1753/* Caller must hold reg_mutex */
1737static bool reg_same_country_ie_hint(struct wiphy *wiphy, 1754static bool reg_same_country_ie_hint(struct wiphy *wiphy,
1738 u32 country_ie_checksum) 1755 u32 country_ie_checksum)
1739{ 1756{
1740 struct wiphy *request_wiphy; 1757 struct wiphy *request_wiphy;
1741 1758
1742 assert_cfg80211_lock(); 1759 assert_reg_lock();
1743 1760
1744 if (unlikely(last_request->initiator != 1761 if (unlikely(last_request->initiator !=
1745 NL80211_REGDOM_SET_BY_COUNTRY_IE)) 1762 NL80211_REGDOM_SET_BY_COUNTRY_IE))
@@ -1762,6 +1779,10 @@ static bool reg_same_country_ie_hint(struct wiphy *wiphy,
1762 return false; 1779 return false;
1763} 1780}
1764 1781
1782/*
1783 * We hold wdev_lock() here so we cannot hold cfg80211_mutex() and
1784 * therefore cannot iterate over the rdev list here.
1785 */
1765void regulatory_hint_11d(struct wiphy *wiphy, 1786void regulatory_hint_11d(struct wiphy *wiphy,
1766 u8 *country_ie, 1787 u8 *country_ie,
1767 u8 country_ie_len) 1788 u8 country_ie_len)
@@ -1772,12 +1793,10 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1772 enum environment_cap env = ENVIRON_ANY; 1793 enum environment_cap env = ENVIRON_ANY;
1773 struct regulatory_request *request; 1794 struct regulatory_request *request;
1774 1795
1775 mutex_lock(&cfg80211_mutex); 1796 mutex_lock(&reg_mutex);
1776 1797
1777 if (unlikely(!last_request)) { 1798 if (unlikely(!last_request))
1778 mutex_unlock(&cfg80211_mutex); 1799 goto out;
1779 return;
1780 }
1781 1800
1782 /* IE len must be evenly divisible by 2 */ 1801 /* IE len must be evenly divisible by 2 */
1783 if (country_ie_len & 0x01) 1802 if (country_ie_len & 0x01)
@@ -1803,54 +1822,14 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1803 env = ENVIRON_OUTDOOR; 1822 env = ENVIRON_OUTDOOR;
1804 1823
1805 /* 1824 /*
1806 * We will run this for *every* beacon processed for the BSSID, so 1825 * We will run this only upon a successful connection on cfg80211.
1807 * we optimize an early check to exit out early if we don't have to 1826 * We leave conflict resolution to the workqueue, where can hold
1808 * do anything 1827 * cfg80211_mutex.
1809 */ 1828 */
1810 if (likely(last_request->initiator == 1829 if (likely(last_request->initiator ==
1811 NL80211_REGDOM_SET_BY_COUNTRY_IE && 1830 NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1812 wiphy_idx_valid(last_request->wiphy_idx))) { 1831 wiphy_idx_valid(last_request->wiphy_idx)))
1813 struct cfg80211_registered_device *rdev_last_ie; 1832 goto out;
1814
1815 rdev_last_ie =
1816 cfg80211_rdev_by_wiphy_idx(last_request->wiphy_idx);
1817
1818 /*
1819 * Lets keep this simple -- we trust the first AP
1820 * after we intersect with CRDA
1821 */
1822 if (likely(&rdev_last_ie->wiphy == wiphy)) {
1823 /*
1824 * Ignore IEs coming in on this wiphy with
1825 * the same alpha2 and environment cap
1826 */
1827 if (likely(alpha2_equal(rdev_last_ie->country_ie_alpha2,
1828 alpha2) &&
1829 env == rdev_last_ie->env)) {
1830 goto out;
1831 }
1832 /*
1833 * the wiphy moved on to another BSSID or the AP
1834 * was reconfigured. XXX: We need to deal with the
1835 * case where the user suspends and goes to goes
1836 * to another country, and then gets IEs from an
1837 * AP with different settings
1838 */
1839 goto out;
1840 } else {
1841 /*
1842 * Ignore IEs coming in on two separate wiphys with
1843 * the same alpha2 and environment cap
1844 */
1845 if (likely(alpha2_equal(rdev_last_ie->country_ie_alpha2,
1846 alpha2) &&
1847 env == rdev_last_ie->env)) {
1848 goto out;
1849 }
1850 /* We could potentially intersect though */
1851 goto out;
1852 }
1853 }
1854 1833
1855 rd = country_ie_2_rd(country_ie, country_ie_len, &checksum); 1834 rd = country_ie_2_rd(country_ie, country_ie_len, &checksum);
1856 if (!rd) 1835 if (!rd)
@@ -1885,7 +1864,7 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1885 request->country_ie_checksum = checksum; 1864 request->country_ie_checksum = checksum;
1886 request->country_ie_env = env; 1865 request->country_ie_env = env;
1887 1866
1888 mutex_unlock(&cfg80211_mutex); 1867 mutex_unlock(&reg_mutex);
1889 1868
1890 queue_regulatory_request(request); 1869 queue_regulatory_request(request);
1891 1870
@@ -1894,9 +1873,8 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1894free_rd_out: 1873free_rd_out:
1895 kfree(rd); 1874 kfree(rd);
1896out: 1875out:
1897 mutex_unlock(&cfg80211_mutex); 1876 mutex_unlock(&reg_mutex);
1898} 1877}
1899EXPORT_SYMBOL(regulatory_hint_11d);
1900 1878
1901static bool freq_is_chan_12_13_14(u16 freq) 1879static bool freq_is_chan_12_13_14(u16 freq)
1902{ 1880{
@@ -2227,10 +2205,13 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2227 2205
2228 assert_cfg80211_lock(); 2206 assert_cfg80211_lock();
2229 2207
2208 mutex_lock(&reg_mutex);
2209
2230 /* Note that this doesn't update the wiphys, this is done below */ 2210 /* Note that this doesn't update the wiphys, this is done below */
2231 r = __set_regdom(rd); 2211 r = __set_regdom(rd);
2232 if (r) { 2212 if (r) {
2233 kfree(rd); 2213 kfree(rd);
2214 mutex_unlock(&reg_mutex);
2234 return r; 2215 return r;
2235 } 2216 }
2236 2217
@@ -2245,6 +2226,8 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2245 2226
2246 nl80211_send_reg_change_event(last_request); 2227 nl80211_send_reg_change_event(last_request);
2247 2228
2229 mutex_unlock(&reg_mutex);
2230
2248 return r; 2231 return r;
2249} 2232}
2250 2233
@@ -2255,16 +2238,20 @@ void reg_device_remove(struct wiphy *wiphy)
2255 2238
2256 assert_cfg80211_lock(); 2239 assert_cfg80211_lock();
2257 2240
2241 mutex_lock(&reg_mutex);
2242
2258 kfree(wiphy->regd); 2243 kfree(wiphy->regd);
2259 2244
2260 if (last_request) 2245 if (last_request)
2261 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 2246 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
2262 2247
2263 if (!request_wiphy || request_wiphy != wiphy) 2248 if (!request_wiphy || request_wiphy != wiphy)
2264 return; 2249 goto out;
2265 2250
2266 last_request->wiphy_idx = WIPHY_IDX_STALE; 2251 last_request->wiphy_idx = WIPHY_IDX_STALE;
2267 last_request->country_ie_env = ENVIRON_ANY; 2252 last_request->country_ie_env = ENVIRON_ANY;
2253out:
2254 mutex_unlock(&reg_mutex);
2268} 2255}
2269 2256
2270int regulatory_init(void) 2257int regulatory_init(void)
@@ -2325,6 +2312,7 @@ void regulatory_exit(void)
2325 cancel_work_sync(&reg_work); 2312 cancel_work_sync(&reg_work);
2326 2313
2327 mutex_lock(&cfg80211_mutex); 2314 mutex_lock(&cfg80211_mutex);
2315 mutex_lock(&reg_mutex);
2328 2316
2329 reset_regdomains(); 2317 reset_regdomains();
2330 2318
@@ -2363,5 +2351,6 @@ void regulatory_exit(void)
2363 } 2351 }
2364 spin_unlock(&reg_requests_lock); 2352 spin_unlock(&reg_requests_lock);
2365 2353
2354 mutex_unlock(&reg_mutex);
2366 mutex_unlock(&cfg80211_mutex); 2355 mutex_unlock(&cfg80211_mutex);
2367} 2356}
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index e37829a49dc4..662a9dad76d5 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -36,4 +36,19 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
36 struct ieee80211_channel *beacon_chan, 36 struct ieee80211_channel *beacon_chan,
37 gfp_t gfp); 37 gfp_t gfp);
38 38
39/**
40 * regulatory_hint_11d - hints a country IE as a regulatory domain
41 * @wiphy: the wireless device giving the hint (used only for reporting
42 * conflicts)
43 * @country_ie: pointer to the country IE
44 * @country_ie_len: length of the country IE
45 *
46 * We will intersect the rd with the what CRDA tells us should apply
47 * for the alpha2 this country IE belongs to, this prevents APs from
48 * sending us incorrect or outdated information against a country.
49 */
50void regulatory_hint_11d(struct wiphy *wiphy,
51 u8 *country_ie,
52 u8 country_ie_len);
53
39#endif /* __NET_WIRELESS_REG_H */ 54#endif /* __NET_WIRELESS_REG_H */
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index d2b5d4ce0a00..8a7dcbf90602 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -13,6 +13,7 @@
13#include <net/cfg80211.h> 13#include <net/cfg80211.h>
14#include <net/rtnetlink.h> 14#include <net/rtnetlink.h>
15#include "nl80211.h" 15#include "nl80211.h"
16#include "reg.h"
16 17
17struct cfg80211_conn { 18struct cfg80211_conn {
18 struct cfg80211_connect_params params; 19 struct cfg80211_connect_params params;
@@ -182,7 +183,7 @@ void cfg80211_conn_work(struct work_struct *work)
182 wdev->conn->params.bssid, 183 wdev->conn->params.bssid,
183 NULL, 0, NULL, 0, 184 NULL, 0, NULL, 0,
184 WLAN_STATUS_UNSPECIFIED_FAILURE, 185 WLAN_STATUS_UNSPECIFIED_FAILURE,
185 false); 186 false, NULL);
186 wdev_unlock(wdev); 187 wdev_unlock(wdev);
187 } 188 }
188 189
@@ -247,7 +248,7 @@ static void __cfg80211_sme_scan_done(struct net_device *dev)
247 wdev->conn->params.bssid, 248 wdev->conn->params.bssid,
248 NULL, 0, NULL, 0, 249 NULL, 0, NULL, 0,
249 WLAN_STATUS_UNSPECIFIED_FAILURE, 250 WLAN_STATUS_UNSPECIFIED_FAILURE,
250 false); 251 false, NULL);
251 } 252 }
252} 253}
253 254
@@ -305,7 +306,7 @@ void cfg80211_sme_rx_auth(struct net_device *dev,
305 schedule_work(&rdev->conn_work); 306 schedule_work(&rdev->conn_work);
306 } else if (status_code != WLAN_STATUS_SUCCESS) { 307 } else if (status_code != WLAN_STATUS_SUCCESS) {
307 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, 308 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
308 status_code, false); 309 status_code, false, NULL);
309 } else if (wdev->sme_state == CFG80211_SME_CONNECTING && 310 } else if (wdev->sme_state == CFG80211_SME_CONNECTING &&
310 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) { 311 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
311 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; 312 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
@@ -316,10 +317,11 @@ void cfg80211_sme_rx_auth(struct net_device *dev,
316void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 317void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
317 const u8 *req_ie, size_t req_ie_len, 318 const u8 *req_ie, size_t req_ie_len,
318 const u8 *resp_ie, size_t resp_ie_len, 319 const u8 *resp_ie, size_t resp_ie_len,
319 u16 status, bool wextev) 320 u16 status, bool wextev,
321 struct cfg80211_bss *bss)
320{ 322{
321 struct wireless_dev *wdev = dev->ieee80211_ptr; 323 struct wireless_dev *wdev = dev->ieee80211_ptr;
322 struct cfg80211_bss *bss; 324 u8 *country_ie;
323#ifdef CONFIG_WIRELESS_EXT 325#ifdef CONFIG_WIRELESS_EXT
324 union iwreq_data wrqu; 326 union iwreq_data wrqu;
325#endif 327#endif
@@ -361,6 +363,12 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
361 } 363 }
362#endif 364#endif
363 365
366 if (wdev->current_bss) {
367 cfg80211_unhold_bss(wdev->current_bss);
368 cfg80211_put_bss(&wdev->current_bss->pub);
369 wdev->current_bss = NULL;
370 }
371
364 if (status == WLAN_STATUS_SUCCESS && 372 if (status == WLAN_STATUS_SUCCESS &&
365 wdev->sme_state == CFG80211_SME_IDLE) 373 wdev->sme_state == CFG80211_SME_IDLE)
366 goto success; 374 goto success;
@@ -368,12 +376,6 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
368 if (wdev->sme_state != CFG80211_SME_CONNECTING) 376 if (wdev->sme_state != CFG80211_SME_CONNECTING)
369 return; 377 return;
370 378
371 if (wdev->current_bss) {
372 cfg80211_unhold_bss(wdev->current_bss);
373 cfg80211_put_bss(&wdev->current_bss->pub);
374 wdev->current_bss = NULL;
375 }
376
377 if (wdev->conn) 379 if (wdev->conn)
378 wdev->conn->state = CFG80211_CONN_IDLE; 380 wdev->conn->state = CFG80211_CONN_IDLE;
379 381
@@ -383,13 +385,16 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
383 wdev->conn = NULL; 385 wdev->conn = NULL;
384 kfree(wdev->connect_keys); 386 kfree(wdev->connect_keys);
385 wdev->connect_keys = NULL; 387 wdev->connect_keys = NULL;
388 wdev->ssid_len = 0;
386 return; 389 return;
387 } 390 }
388 391
389 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, 392 success:
390 wdev->ssid, wdev->ssid_len, 393 if (!bss)
391 WLAN_CAPABILITY_ESS, 394 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
392 WLAN_CAPABILITY_ESS); 395 wdev->ssid, wdev->ssid_len,
396 WLAN_CAPABILITY_ESS,
397 WLAN_CAPABILITY_ESS);
393 398
394 if (WARN_ON(!bss)) 399 if (WARN_ON(!bss))
395 return; 400 return;
@@ -397,9 +402,22 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
397 cfg80211_hold_bss(bss_from_pub(bss)); 402 cfg80211_hold_bss(bss_from_pub(bss));
398 wdev->current_bss = bss_from_pub(bss); 403 wdev->current_bss = bss_from_pub(bss);
399 404
400 success:
401 wdev->sme_state = CFG80211_SME_CONNECTED; 405 wdev->sme_state = CFG80211_SME_CONNECTED;
402 cfg80211_upload_connect_keys(wdev); 406 cfg80211_upload_connect_keys(wdev);
407
408 country_ie = (u8 *) ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
409
410 if (!country_ie)
411 return;
412
413 /*
414 * ieee80211_bss_get_ie() ensures we can access:
415 * - country_ie + 2, the start of the country ie data, and
416 * - and country_ie[1] which is the IE length
417 */
418 regulatory_hint_11d(wdev->wiphy,
419 country_ie + 2,
420 country_ie[1]);
403} 421}
404 422
405void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 423void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
@@ -549,6 +567,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
549 567
550 wdev->current_bss = NULL; 568 wdev->current_bss = NULL;
551 wdev->sme_state = CFG80211_SME_IDLE; 569 wdev->sme_state = CFG80211_SME_IDLE;
570 wdev->ssid_len = 0;
552 571
553 if (wdev->conn) { 572 if (wdev->conn) {
554 kfree(wdev->conn->ie); 573 kfree(wdev->conn->ie);
@@ -704,6 +723,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
704 wdev->conn = NULL; 723 wdev->conn = NULL;
705 wdev->sme_state = CFG80211_SME_IDLE; 724 wdev->sme_state = CFG80211_SME_IDLE;
706 wdev->connect_keys = NULL; 725 wdev->connect_keys = NULL;
726 wdev->ssid_len = 0;
707 } 727 }
708 728
709 return err; 729 return err;
@@ -768,6 +788,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
768 wdev->sme_state = CFG80211_SME_IDLE; 788 wdev->sme_state = CFG80211_SME_IDLE;
769 kfree(wdev->conn); 789 kfree(wdev->conn);
770 wdev->conn = NULL; 790 wdev->conn = NULL;
791 wdev->ssid_len = 0;
771 return 0; 792 return 0;
772 } 793 }
773 794
@@ -788,7 +809,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
788 else if (wdev->sme_state == CFG80211_SME_CONNECTING) 809 else if (wdev->sme_state == CFG80211_SME_CONNECTING)
789 __cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0, 810 __cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0,
790 WLAN_STATUS_UNSPECIFIED_FAILURE, 811 WLAN_STATUS_UNSPECIFIED_FAILURE,
791 wextev); 812 wextev, NULL);
792 813
793 return 0; 814 return 0;
794} 815}
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index 3fe3c2c0ce11..5b4a0cee4418 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -1291,7 +1291,6 @@ static struct pernet_operations wext_pernet_ops = {
1291static int __init wireless_nlevent_init(void) 1291static int __init wireless_nlevent_init(void)
1292{ 1292{
1293 return register_pernet_subsys(&wext_pernet_ops); 1293 return register_pernet_subsys(&wext_pernet_ops);
1294 return 0;
1295} 1294}
1296 1295
1297subsys_initcall(wireless_nlevent_init); 1296subsys_initcall(wireless_nlevent_init);