aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-06-11 14:48:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-06-11 14:48:32 -0400
commit3899ba90a4ab2f3cab8e0f91a76c14ff131c8293 (patch)
treeae82b469f8a7ceb42547d11dd1fe5c73abc8635b /net/wireless
parent45203a3b380cee28f570475c0d28c169f908c209 (diff)
parent8b3e7be437a6b62118d0485ad971e724afe23fdf (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/ath/ath9k/debug.c net/mac80211/iface.c
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c224
-rw-r--r--net/wireless/core.h93
-rw-r--r--net/wireless/debugfs.c4
-rw-r--r--net/wireless/ibss.c10
-rw-r--r--net/wireless/mesh.c3
-rw-r--r--net/wireless/mlme.c216
-rw-r--r--net/wireless/nl80211.c350
-rw-r--r--net/wireless/reg.c136
-rw-r--r--net/wireless/scan.c47
-rw-r--r--net/wireless/sme.c107
-rw-r--r--net/wireless/sysfs.c8
-rw-r--r--net/wireless/trace.h4
-rw-r--r--net/wireless/util.c39
-rw-r--r--net/wireless/wext-compat.c22
-rw-r--r--net/wireless/wext-sme.c41
15 files changed, 443 insertions, 861 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 01e41191f1bf..e4df77490229 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -34,13 +34,12 @@
34MODULE_AUTHOR("Johannes Berg"); 34MODULE_AUTHOR("Johannes Berg");
35MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
36MODULE_DESCRIPTION("wireless configuration support"); 36MODULE_DESCRIPTION("wireless configuration support");
37MODULE_ALIAS_GENL_FAMILY(NL80211_GENL_NAME);
37 38
38/* RCU-protected (and cfg80211_mutex for writers) */ 39/* RCU-protected (and RTNL for writers) */
39LIST_HEAD(cfg80211_rdev_list); 40LIST_HEAD(cfg80211_rdev_list);
40int cfg80211_rdev_list_generation; 41int cfg80211_rdev_list_generation;
41 42
42DEFINE_MUTEX(cfg80211_mutex);
43
44/* for debugfs */ 43/* for debugfs */
45static struct dentry *ieee80211_debugfs_dir; 44static struct dentry *ieee80211_debugfs_dir;
46 45
@@ -52,12 +51,11 @@ module_param(cfg80211_disable_40mhz_24ghz, bool, 0644);
52MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz, 51MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz,
53 "Disable 40MHz support in the 2.4GHz band"); 52 "Disable 40MHz support in the 2.4GHz band");
54 53
55/* requires cfg80211_mutex to be held! */
56struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx) 54struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
57{ 55{
58 struct cfg80211_registered_device *result = NULL, *rdev; 56 struct cfg80211_registered_device *result = NULL, *rdev;
59 57
60 assert_cfg80211_lock(); 58 ASSERT_RTNL();
61 59
62 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 60 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
63 if (rdev->wiphy_idx == wiphy_idx) { 61 if (rdev->wiphy_idx == wiphy_idx) {
@@ -76,12 +74,11 @@ int get_wiphy_idx(struct wiphy *wiphy)
76 return rdev->wiphy_idx; 74 return rdev->wiphy_idx;
77} 75}
78 76
79/* requires cfg80211_rdev_mutex to be held! */
80struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx) 77struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
81{ 78{
82 struct cfg80211_registered_device *rdev; 79 struct cfg80211_registered_device *rdev;
83 80
84 assert_cfg80211_lock(); 81 ASSERT_RTNL();
85 82
86 rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx); 83 rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx);
87 if (!rdev) 84 if (!rdev)
@@ -89,35 +86,13 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
89 return &rdev->wiphy; 86 return &rdev->wiphy;
90} 87}
91 88
92struct cfg80211_registered_device *
93cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
94{
95 struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV);
96 struct net_device *dev;
97
98 mutex_lock(&cfg80211_mutex);
99 dev = dev_get_by_index(net, ifindex);
100 if (!dev)
101 goto out;
102 if (dev->ieee80211_ptr) {
103 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
104 mutex_lock(&rdev->mtx);
105 } else
106 rdev = ERR_PTR(-ENODEV);
107 dev_put(dev);
108 out:
109 mutex_unlock(&cfg80211_mutex);
110 return rdev;
111}
112
113/* requires cfg80211_mutex to be held */
114int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, 89int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
115 char *newname) 90 char *newname)
116{ 91{
117 struct cfg80211_registered_device *rdev2; 92 struct cfg80211_registered_device *rdev2;
118 int wiphy_idx, taken = -1, result, digits; 93 int wiphy_idx, taken = -1, result, digits;
119 94
120 assert_cfg80211_lock(); 95 ASSERT_RTNL();
121 96
122 /* prohibit calling the thing phy%d when %d is not its number */ 97 /* prohibit calling the thing phy%d when %d is not its number */
123 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); 98 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
@@ -215,8 +190,7 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
215void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, 190void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
216 struct wireless_dev *wdev) 191 struct wireless_dev *wdev)
217{ 192{
218 lockdep_assert_held(&rdev->devlist_mtx); 193 ASSERT_RTNL();
219 lockdep_assert_held(&rdev->sched_scan_mtx);
220 194
221 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)) 195 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE))
222 return; 196 return;
@@ -230,18 +204,15 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
230 rdev->opencount--; 204 rdev->opencount--;
231 205
232 if (rdev->scan_req && rdev->scan_req->wdev == wdev) { 206 if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
233 bool busy = work_busy(&rdev->scan_done_wk);
234
235 /* 207 /*
236 * If the work isn't pending or running (in which case it would 208 * If the scan request wasn't notified as done, set it
237 * be waiting for the lock we hold) the driver didn't properly 209 * to aborted and leak it after a warning. The driver
238 * cancel the scan when the interface was removed. In this case 210 * should have notified us that it ended at the latest
239 * warn and leak the scan request object to not crash later. 211 * during rdev_stop_p2p_device().
240 */ 212 */
241 WARN_ON(!busy); 213 if (WARN_ON(!rdev->scan_req->notified))
242 214 rdev->scan_req->aborted = true;
243 rdev->scan_req->aborted = true; 215 ___cfg80211_scan_done(rdev, !rdev->scan_req->notified);
244 ___cfg80211_scan_done(rdev, !busy);
245 } 216 }
246} 217}
247 218
@@ -255,8 +226,6 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
255 226
256 rtnl_lock(); 227 rtnl_lock();
257 228
258 /* read-only iteration need not hold the devlist_mtx */
259
260 list_for_each_entry(wdev, &rdev->wdev_list, list) { 229 list_for_each_entry(wdev, &rdev->wdev_list, list) {
261 if (wdev->netdev) { 230 if (wdev->netdev) {
262 dev_close(wdev->netdev); 231 dev_close(wdev->netdev);
@@ -265,12 +234,7 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
265 /* otherwise, check iftype */ 234 /* otherwise, check iftype */
266 switch (wdev->iftype) { 235 switch (wdev->iftype) {
267 case NL80211_IFTYPE_P2P_DEVICE: 236 case NL80211_IFTYPE_P2P_DEVICE:
268 /* but this requires it */
269 mutex_lock(&rdev->devlist_mtx);
270 mutex_lock(&rdev->sched_scan_mtx);
271 cfg80211_stop_p2p_device(rdev, wdev); 237 cfg80211_stop_p2p_device(rdev, wdev);
272 mutex_unlock(&rdev->sched_scan_mtx);
273 mutex_unlock(&rdev->devlist_mtx);
274 break; 238 break;
275 default: 239 default:
276 break; 240 break;
@@ -298,10 +262,7 @@ static void cfg80211_event_work(struct work_struct *work)
298 event_work); 262 event_work);
299 263
300 rtnl_lock(); 264 rtnl_lock();
301 cfg80211_lock_rdev(rdev);
302
303 cfg80211_process_rdev_events(rdev); 265 cfg80211_process_rdev_events(rdev);
304 cfg80211_unlock_rdev(rdev);
305 rtnl_unlock(); 266 rtnl_unlock();
306} 267}
307 268
@@ -309,7 +270,7 @@ static void cfg80211_event_work(struct work_struct *work)
309 270
310struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) 271struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
311{ 272{
312 static int wiphy_counter; 273 static atomic_t wiphy_counter = ATOMIC_INIT(0);
313 274
314 struct cfg80211_registered_device *rdev; 275 struct cfg80211_registered_device *rdev;
315 int alloc_size; 276 int alloc_size;
@@ -331,26 +292,18 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
331 292
332 rdev->ops = ops; 293 rdev->ops = ops;
333 294
334 mutex_lock(&cfg80211_mutex); 295 rdev->wiphy_idx = atomic_inc_return(&wiphy_counter);
335
336 rdev->wiphy_idx = wiphy_counter++;
337 296
338 if (unlikely(rdev->wiphy_idx < 0)) { 297 if (unlikely(rdev->wiphy_idx < 0)) {
339 wiphy_counter--;
340 mutex_unlock(&cfg80211_mutex);
341 /* ugh, wrapped! */ 298 /* ugh, wrapped! */
299 atomic_dec(&wiphy_counter);
342 kfree(rdev); 300 kfree(rdev);
343 return NULL; 301 return NULL;
344 } 302 }
345 303
346 mutex_unlock(&cfg80211_mutex);
347
348 /* give it a proper name */ 304 /* give it a proper name */
349 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 305 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
350 306
351 mutex_init(&rdev->mtx);
352 mutex_init(&rdev->devlist_mtx);
353 mutex_init(&rdev->sched_scan_mtx);
354 INIT_LIST_HEAD(&rdev->wdev_list); 307 INIT_LIST_HEAD(&rdev->wdev_list);
355 INIT_LIST_HEAD(&rdev->beacon_registrations); 308 INIT_LIST_HEAD(&rdev->beacon_registrations);
356 spin_lock_init(&rdev->beacon_registrations_lock); 309 spin_lock_init(&rdev->beacon_registrations_lock);
@@ -598,11 +551,11 @@ int wiphy_register(struct wiphy *wiphy)
598 /* check and set up bitrates */ 551 /* check and set up bitrates */
599 ieee80211_set_bitrate_flags(wiphy); 552 ieee80211_set_bitrate_flags(wiphy);
600 553
601 mutex_lock(&cfg80211_mutex); 554 rtnl_lock();
602 555
603 res = device_add(&rdev->wiphy.dev); 556 res = device_add(&rdev->wiphy.dev);
604 if (res) { 557 if (res) {
605 mutex_unlock(&cfg80211_mutex); 558 rtnl_unlock();
606 return res; 559 return res;
607 } 560 }
608 561
@@ -631,25 +584,18 @@ int wiphy_register(struct wiphy *wiphy)
631 } 584 }
632 585
633 cfg80211_debugfs_rdev_add(rdev); 586 cfg80211_debugfs_rdev_add(rdev);
634 mutex_unlock(&cfg80211_mutex);
635 587
636 /*
637 * due to a locking dependency this has to be outside of the
638 * cfg80211_mutex lock
639 */
640 res = rfkill_register(rdev->rfkill); 588 res = rfkill_register(rdev->rfkill);
641 if (res) { 589 if (res) {
642 device_del(&rdev->wiphy.dev); 590 device_del(&rdev->wiphy.dev);
643 591
644 mutex_lock(&cfg80211_mutex);
645 debugfs_remove_recursive(rdev->wiphy.debugfsdir); 592 debugfs_remove_recursive(rdev->wiphy.debugfsdir);
646 list_del_rcu(&rdev->list); 593 list_del_rcu(&rdev->list);
647 wiphy_regulatory_deregister(wiphy); 594 wiphy_regulatory_deregister(wiphy);
648 mutex_unlock(&cfg80211_mutex); 595 rtnl_unlock();
649 return res; 596 return res;
650 } 597 }
651 598
652 rtnl_lock();
653 rdev->wiphy.registered = true; 599 rdev->wiphy.registered = true;
654 rtnl_unlock(); 600 rtnl_unlock();
655 return 0; 601 return 0;
@@ -679,25 +625,19 @@ void wiphy_unregister(struct wiphy *wiphy)
679{ 625{
680 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 626 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
681 627
682 rtnl_lock();
683 rdev->wiphy.registered = false;
684 rtnl_unlock();
685
686 rfkill_unregister(rdev->rfkill);
687
688 /* protect the device list */
689 mutex_lock(&cfg80211_mutex);
690
691 wait_event(rdev->dev_wait, ({ 628 wait_event(rdev->dev_wait, ({
692 int __count; 629 int __count;
693 mutex_lock(&rdev->devlist_mtx); 630 rtnl_lock();
694 __count = rdev->opencount; 631 __count = rdev->opencount;
695 mutex_unlock(&rdev->devlist_mtx); 632 rtnl_unlock();
696 __count == 0; })); 633 __count == 0; }));
697 634
698 mutex_lock(&rdev->devlist_mtx); 635 rtnl_lock();
636 rdev->wiphy.registered = false;
637
638 rfkill_unregister(rdev->rfkill);
639
699 BUG_ON(!list_empty(&rdev->wdev_list)); 640 BUG_ON(!list_empty(&rdev->wdev_list));
700 mutex_unlock(&rdev->devlist_mtx);
701 641
702 /* 642 /*
703 * First remove the hardware from everywhere, this makes 643 * First remove the hardware from everywhere, this makes
@@ -708,20 +648,6 @@ void wiphy_unregister(struct wiphy *wiphy)
708 synchronize_rcu(); 648 synchronize_rcu();
709 649
710 /* 650 /*
711 * Try to grab rdev->mtx. If a command is still in progress,
712 * hopefully the driver will refuse it since it's tearing
713 * down the device already. We wait for this command to complete
714 * before unlinking the item from the list.
715 * Note: as codified by the BUG_ON above we cannot get here if
716 * a virtual interface is still present. Hence, we can only get
717 * to lock contention here if userspace issues a command that
718 * identified the hardware by wiphy index.
719 */
720 cfg80211_lock_rdev(rdev);
721 /* nothing */
722 cfg80211_unlock_rdev(rdev);
723
724 /*
725 * If this device got a regulatory hint tell core its 651 * If this device got a regulatory hint tell core its
726 * free to listen now to a new shiny device regulatory hint 652 * free to listen now to a new shiny device regulatory hint
727 */ 653 */
@@ -730,15 +656,17 @@ void wiphy_unregister(struct wiphy *wiphy)
730 cfg80211_rdev_list_generation++; 656 cfg80211_rdev_list_generation++;
731 device_del(&rdev->wiphy.dev); 657 device_del(&rdev->wiphy.dev);
732 658
733 mutex_unlock(&cfg80211_mutex); 659 rtnl_unlock();
734 660
735 flush_work(&rdev->scan_done_wk); 661 flush_work(&rdev->scan_done_wk);
736 cancel_work_sync(&rdev->conn_work); 662 cancel_work_sync(&rdev->conn_work);
737 flush_work(&rdev->event_work); 663 flush_work(&rdev->event_work);
738 cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); 664 cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
739 665
740 if (rdev->wowlan && rdev->ops->set_wakeup) 666#ifdef CONFIG_PM
667 if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
741 rdev_set_wakeup(rdev, false); 668 rdev_set_wakeup(rdev, false);
669#endif
742 cfg80211_rdev_free_wowlan(rdev); 670 cfg80211_rdev_free_wowlan(rdev);
743} 671}
744EXPORT_SYMBOL(wiphy_unregister); 672EXPORT_SYMBOL(wiphy_unregister);
@@ -748,9 +676,6 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
748 struct cfg80211_internal_bss *scan, *tmp; 676 struct cfg80211_internal_bss *scan, *tmp;
749 struct cfg80211_beacon_registration *reg, *treg; 677 struct cfg80211_beacon_registration *reg, *treg;
750 rfkill_destroy(rdev->rfkill); 678 rfkill_destroy(rdev->rfkill);
751 mutex_destroy(&rdev->mtx);
752 mutex_destroy(&rdev->devlist_mtx);
753 mutex_destroy(&rdev->sched_scan_mtx);
754 list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) { 679 list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) {
755 list_del(&reg->list); 680 list_del(&reg->list);
756 kfree(reg); 681 kfree(reg);
@@ -775,36 +700,6 @@ void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked)
775} 700}
776EXPORT_SYMBOL(wiphy_rfkill_set_hw_state); 701EXPORT_SYMBOL(wiphy_rfkill_set_hw_state);
777 702
778static void wdev_cleanup_work(struct work_struct *work)
779{
780 struct wireless_dev *wdev;
781 struct cfg80211_registered_device *rdev;
782
783 wdev = container_of(work, struct wireless_dev, cleanup_work);
784 rdev = wiphy_to_dev(wdev->wiphy);
785
786 mutex_lock(&rdev->sched_scan_mtx);
787
788 if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) {
789 rdev->scan_req->aborted = true;
790 ___cfg80211_scan_done(rdev, true);
791 }
792
793 if (WARN_ON(rdev->sched_scan_req &&
794 rdev->sched_scan_req->dev == wdev->netdev)) {
795 __cfg80211_stop_sched_scan(rdev, false);
796 }
797
798 mutex_unlock(&rdev->sched_scan_mtx);
799
800 mutex_lock(&rdev->devlist_mtx);
801 rdev->opencount--;
802 mutex_unlock(&rdev->devlist_mtx);
803 wake_up(&rdev->dev_wait);
804
805 dev_put(wdev->netdev);
806}
807
808void cfg80211_unregister_wdev(struct wireless_dev *wdev) 703void cfg80211_unregister_wdev(struct wireless_dev *wdev)
809{ 704{
810 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 705 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -814,8 +709,6 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
814 if (WARN_ON(wdev->netdev)) 709 if (WARN_ON(wdev->netdev))
815 return; 710 return;
816 711
817 mutex_lock(&rdev->devlist_mtx);
818 mutex_lock(&rdev->sched_scan_mtx);
819 list_del_rcu(&wdev->list); 712 list_del_rcu(&wdev->list);
820 rdev->devlist_generation++; 713 rdev->devlist_generation++;
821 714
@@ -827,8 +720,6 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
827 WARN_ON_ONCE(1); 720 WARN_ON_ONCE(1);
828 break; 721 break;
829 } 722 }
830 mutex_unlock(&rdev->sched_scan_mtx);
831 mutex_unlock(&rdev->devlist_mtx);
832} 723}
833EXPORT_SYMBOL(cfg80211_unregister_wdev); 724EXPORT_SYMBOL(cfg80211_unregister_wdev);
834 725
@@ -847,7 +738,7 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
847} 738}
848 739
849void cfg80211_leave(struct cfg80211_registered_device *rdev, 740void cfg80211_leave(struct cfg80211_registered_device *rdev,
850 struct wireless_dev *wdev) 741 struct wireless_dev *wdev)
851{ 742{
852 struct net_device *dev = wdev->netdev; 743 struct net_device *dev = wdev->netdev;
853 744
@@ -857,9 +748,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
857 break; 748 break;
858 case NL80211_IFTYPE_P2P_CLIENT: 749 case NL80211_IFTYPE_P2P_CLIENT:
859 case NL80211_IFTYPE_STATION: 750 case NL80211_IFTYPE_STATION:
860 mutex_lock(&rdev->sched_scan_mtx);
861 __cfg80211_stop_sched_scan(rdev, false); 751 __cfg80211_stop_sched_scan(rdev, false);
862 mutex_unlock(&rdev->sched_scan_mtx);
863 752
864 wdev_lock(wdev); 753 wdev_lock(wdev);
865#ifdef CONFIG_CFG80211_WEXT 754#ifdef CONFIG_CFG80211_WEXT
@@ -868,8 +757,8 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
868 wdev->wext.ie_len = 0; 757 wdev->wext.ie_len = 0;
869 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; 758 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
870#endif 759#endif
871 __cfg80211_disconnect(rdev, dev, 760 cfg80211_disconnect(rdev, dev,
872 WLAN_REASON_DEAUTH_LEAVING, true); 761 WLAN_REASON_DEAUTH_LEAVING, true);
873 wdev_unlock(wdev); 762 wdev_unlock(wdev);
874 break; 763 break;
875 case NL80211_IFTYPE_MESH_POINT: 764 case NL80211_IFTYPE_MESH_POINT:
@@ -911,13 +800,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
911 * are added with nl80211. 800 * are added with nl80211.
912 */ 801 */
913 mutex_init(&wdev->mtx); 802 mutex_init(&wdev->mtx);
914 INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work);
915 INIT_LIST_HEAD(&wdev->event_list); 803 INIT_LIST_HEAD(&wdev->event_list);
916 spin_lock_init(&wdev->event_lock); 804 spin_lock_init(&wdev->event_lock);
917 INIT_LIST_HEAD(&wdev->mgmt_registrations); 805 INIT_LIST_HEAD(&wdev->mgmt_registrations);
918 spin_lock_init(&wdev->mgmt_registrations_lock); 806 spin_lock_init(&wdev->mgmt_registrations_lock);
919 807
920 mutex_lock(&rdev->devlist_mtx);
921 wdev->identifier = ++rdev->wdev_id; 808 wdev->identifier = ++rdev->wdev_id;
922 list_add_rcu(&wdev->list, &rdev->wdev_list); 809 list_add_rcu(&wdev->list, &rdev->wdev_list);
923 rdev->devlist_generation++; 810 rdev->devlist_generation++;
@@ -930,7 +817,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
930 } 817 }
931 wdev->netdev = dev; 818 wdev->netdev = dev;
932 wdev->sme_state = CFG80211_SME_IDLE; 819 wdev->sme_state = CFG80211_SME_IDLE;
933 mutex_unlock(&rdev->devlist_mtx);
934#ifdef CONFIG_CFG80211_WEXT 820#ifdef CONFIG_CFG80211_WEXT
935 wdev->wext.default_key = -1; 821 wdev->wext.default_key = -1;
936 wdev->wext.default_mgmt_key = -1; 822 wdev->wext.default_mgmt_key = -1;
@@ -956,26 +842,22 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
956 break; 842 break;
957 case NETDEV_DOWN: 843 case NETDEV_DOWN:
958 cfg80211_update_iface_num(rdev, wdev->iftype, -1); 844 cfg80211_update_iface_num(rdev, wdev->iftype, -1);
959 dev_hold(dev); 845 if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
960 queue_work(cfg80211_wq, &wdev->cleanup_work); 846 if (WARN_ON(!rdev->scan_req->notified))
847 rdev->scan_req->aborted = true;
848 ___cfg80211_scan_done(rdev, true);
849 }
850
851 if (WARN_ON(rdev->sched_scan_req &&
852 rdev->sched_scan_req->dev == wdev->netdev)) {
853 __cfg80211_stop_sched_scan(rdev, false);
854 }
855
856 rdev->opencount--;
857 wake_up(&rdev->dev_wait);
961 break; 858 break;
962 case NETDEV_UP: 859 case NETDEV_UP:
963 /*
964 * If we have a really quick DOWN/UP succession we may
965 * have this work still pending ... cancel it and see
966 * if it was pending, in which case we need to account
967 * for some of the work it would have done.
968 */
969 if (cancel_work_sync(&wdev->cleanup_work)) {
970 mutex_lock(&rdev->devlist_mtx);
971 rdev->opencount--;
972 mutex_unlock(&rdev->devlist_mtx);
973 dev_put(dev);
974 }
975 cfg80211_update_iface_num(rdev, wdev->iftype, 1); 860 cfg80211_update_iface_num(rdev, wdev->iftype, 1);
976 cfg80211_lock_rdev(rdev);
977 mutex_lock(&rdev->devlist_mtx);
978 mutex_lock(&rdev->sched_scan_mtx);
979 wdev_lock(wdev); 861 wdev_lock(wdev);
980 switch (wdev->iftype) { 862 switch (wdev->iftype) {
981#ifdef CONFIG_CFG80211_WEXT 863#ifdef CONFIG_CFG80211_WEXT
@@ -1007,10 +889,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1007 break; 889 break;
1008 } 890 }
1009 wdev_unlock(wdev); 891 wdev_unlock(wdev);
1010 mutex_unlock(&rdev->sched_scan_mtx);
1011 rdev->opencount++; 892 rdev->opencount++;
1012 mutex_unlock(&rdev->devlist_mtx);
1013 cfg80211_unlock_rdev(rdev);
1014 893
1015 /* 894 /*
1016 * Configure power management to the driver here so that its 895 * Configure power management to the driver here so that its
@@ -1027,12 +906,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1027 break; 906 break;
1028 case NETDEV_UNREGISTER: 907 case NETDEV_UNREGISTER:
1029 /* 908 /*
1030 * NB: cannot take rdev->mtx here because this may be
1031 * called within code protected by it when interfaces
1032 * are removed with nl80211.
1033 */
1034 mutex_lock(&rdev->devlist_mtx);
1035 /*
1036 * It is possible to get NETDEV_UNREGISTER 909 * It is possible to get NETDEV_UNREGISTER
1037 * multiple times. To detect that, check 910 * multiple times. To detect that, check
1038 * that the interface is still on the list 911 * that the interface is still on the list
@@ -1048,7 +921,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1048 kfree(wdev->wext.keys); 921 kfree(wdev->wext.keys);
1049#endif 922#endif
1050 } 923 }
1051 mutex_unlock(&rdev->devlist_mtx);
1052 /* 924 /*
1053 * synchronise (so that we won't find this netdev 925 * synchronise (so that we won't find this netdev
1054 * from other code any more) and then clear the list 926 * from other code any more) and then clear the list
@@ -1068,9 +940,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1068 return notifier_from_errno(-EOPNOTSUPP); 940 return notifier_from_errno(-EOPNOTSUPP);
1069 if (rfkill_blocked(rdev->rfkill)) 941 if (rfkill_blocked(rdev->rfkill))
1070 return notifier_from_errno(-ERFKILL); 942 return notifier_from_errno(-ERFKILL);
1071 mutex_lock(&rdev->devlist_mtx);
1072 ret = cfg80211_can_add_interface(rdev, wdev->iftype); 943 ret = cfg80211_can_add_interface(rdev, wdev->iftype);
1073 mutex_unlock(&rdev->devlist_mtx);
1074 if (ret) 944 if (ret)
1075 return notifier_from_errno(ret); 945 return notifier_from_errno(ret);
1076 break; 946 break;
@@ -1088,12 +958,10 @@ static void __net_exit cfg80211_pernet_exit(struct net *net)
1088 struct cfg80211_registered_device *rdev; 958 struct cfg80211_registered_device *rdev;
1089 959
1090 rtnl_lock(); 960 rtnl_lock();
1091 mutex_lock(&cfg80211_mutex);
1092 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 961 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1093 if (net_eq(wiphy_net(&rdev->wiphy), net)) 962 if (net_eq(wiphy_net(&rdev->wiphy), net))
1094 WARN_ON(cfg80211_switch_netns(rdev, &init_net)); 963 WARN_ON(cfg80211_switch_netns(rdev, &init_net));
1095 } 964 }
1096 mutex_unlock(&cfg80211_mutex);
1097 rtnl_unlock(); 965 rtnl_unlock();
1098} 966}
1099 967
diff --git a/net/wireless/core.h b/net/wireless/core.h
index fd35dae547c4..a65eaf8a84c1 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -5,7 +5,6 @@
5 */ 5 */
6#ifndef __NET_WIRELESS_CORE_H 6#ifndef __NET_WIRELESS_CORE_H
7#define __NET_WIRELESS_CORE_H 7#define __NET_WIRELESS_CORE_H
8#include <linux/mutex.h>
9#include <linux/list.h> 8#include <linux/list.h>
10#include <linux/netdevice.h> 9#include <linux/netdevice.h>
11#include <linux/rbtree.h> 10#include <linux/rbtree.h>
@@ -23,11 +22,6 @@
23struct cfg80211_registered_device { 22struct cfg80211_registered_device {
24 const struct cfg80211_ops *ops; 23 const struct cfg80211_ops *ops;
25 struct list_head list; 24 struct list_head list;
26 /* we hold this mutex during any call so that
27 * we cannot do multiple calls at once, and also
28 * to avoid the deregister call to proceed while
29 * any call is in progress */
30 struct mutex mtx;
31 25
32 /* rfkill support */ 26 /* rfkill support */
33 struct rfkill_ops rfkill_ops; 27 struct rfkill_ops rfkill_ops;
@@ -49,9 +43,7 @@ struct cfg80211_registered_device {
49 /* wiphy index, internal only */ 43 /* wiphy index, internal only */
50 int wiphy_idx; 44 int wiphy_idx;
51 45
52 /* associated wireless interfaces */ 46 /* associated wireless interfaces, protected by rtnl or RCU */
53 struct mutex devlist_mtx;
54 /* protected by devlist_mtx or RCU */
55 struct list_head wdev_list; 47 struct list_head wdev_list;
56 int devlist_generation, wdev_id; 48 int devlist_generation, wdev_id;
57 int opencount; /* also protected by devlist_mtx */ 49 int opencount; /* also protected by devlist_mtx */
@@ -75,8 +67,6 @@ struct cfg80211_registered_device {
75 struct work_struct scan_done_wk; 67 struct work_struct scan_done_wk;
76 struct work_struct sched_scan_results_wk; 68 struct work_struct sched_scan_results_wk;
77 69
78 struct mutex sched_scan_mtx;
79
80#ifdef CONFIG_NL80211_TESTMODE 70#ifdef CONFIG_NL80211_TESTMODE
81 struct genl_info *testmode_info; 71 struct genl_info *testmode_info;
82#endif 72#endif
@@ -84,8 +74,6 @@ struct cfg80211_registered_device {
84 struct work_struct conn_work; 74 struct work_struct conn_work;
85 struct work_struct event_work; 75 struct work_struct event_work;
86 76
87 struct cfg80211_wowlan *wowlan;
88
89 struct delayed_work dfs_update_channels_wk; 77 struct delayed_work dfs_update_channels_wk;
90 78
91 /* netlink port which started critical protocol (0 means not started) */ 79 /* netlink port which started critical protocol (0 means not started) */
@@ -106,29 +94,26 @@ struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy)
106static inline void 94static inline void
107cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev) 95cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
108{ 96{
97#ifdef CONFIG_PM
109 int i; 98 int i;
110 99
111 if (!rdev->wowlan) 100 if (!rdev->wiphy.wowlan_config)
112 return; 101 return;
113 for (i = 0; i < rdev->wowlan->n_patterns; i++) 102 for (i = 0; i < rdev->wiphy.wowlan_config->n_patterns; i++)
114 kfree(rdev->wowlan->patterns[i].mask); 103 kfree(rdev->wiphy.wowlan_config->patterns[i].mask);
115 kfree(rdev->wowlan->patterns); 104 kfree(rdev->wiphy.wowlan_config->patterns);
116 if (rdev->wowlan->tcp && rdev->wowlan->tcp->sock) 105 if (rdev->wiphy.wowlan_config->tcp &&
117 sock_release(rdev->wowlan->tcp->sock); 106 rdev->wiphy.wowlan_config->tcp->sock)
118 kfree(rdev->wowlan->tcp); 107 sock_release(rdev->wiphy.wowlan_config->tcp->sock);
119 kfree(rdev->wowlan); 108 kfree(rdev->wiphy.wowlan_config->tcp);
109 kfree(rdev->wiphy.wowlan_config);
110#endif
120} 111}
121 112
122extern struct workqueue_struct *cfg80211_wq; 113extern struct workqueue_struct *cfg80211_wq;
123extern struct mutex cfg80211_mutex;
124extern struct list_head cfg80211_rdev_list; 114extern struct list_head cfg80211_rdev_list;
125extern int cfg80211_rdev_list_generation; 115extern int cfg80211_rdev_list_generation;
126 116
127static inline void assert_cfg80211_lock(void)
128{
129 lockdep_assert_held(&cfg80211_mutex);
130}
131
132struct cfg80211_internal_bss { 117struct cfg80211_internal_bss {
133 struct list_head list; 118 struct list_head list;
134 struct list_head hidden_list; 119 struct list_head hidden_list;
@@ -161,27 +146,11 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
161struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); 146struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
162int get_wiphy_idx(struct wiphy *wiphy); 147int get_wiphy_idx(struct wiphy *wiphy);
163 148
164/* requires cfg80211_rdev_mutex to be held! */
165struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); 149struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
166 150
167/* identical to cfg80211_get_dev_from_info but only operate on ifindex */
168extern struct cfg80211_registered_device *
169cfg80211_get_dev_from_ifindex(struct net *net, int ifindex);
170
171int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, 151int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
172 struct net *net); 152 struct net *net);
173 153
174static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev)
175{
176 mutex_lock(&rdev->mtx);
177}
178
179static inline void cfg80211_unlock_rdev(struct cfg80211_registered_device *rdev)
180{
181 BUG_ON(IS_ERR(rdev) || !rdev);
182 mutex_unlock(&rdev->mtx);
183}
184
185static inline void wdev_lock(struct wireless_dev *wdev) 154static inline void wdev_lock(struct wireless_dev *wdev)
186 __acquires(wdev) 155 __acquires(wdev)
187{ 156{
@@ -196,7 +165,7 @@ static inline void wdev_unlock(struct wireless_dev *wdev)
196 mutex_unlock(&wdev->mtx); 165 mutex_unlock(&wdev->mtx);
197} 166}
198 167
199#define ASSERT_RDEV_LOCK(rdev) lockdep_assert_held(&(rdev)->mtx) 168#define ASSERT_RDEV_LOCK(rdev) ASSERT_RTNL()
200#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx) 169#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx)
201 170
202static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev) 171static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev)
@@ -314,38 +283,21 @@ int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
314 struct net_device *dev); 283 struct net_device *dev);
315 284
316/* MLME */ 285/* MLME */
317int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
318 struct net_device *dev,
319 struct ieee80211_channel *chan,
320 enum nl80211_auth_type auth_type,
321 const u8 *bssid,
322 const u8 *ssid, int ssid_len,
323 const u8 *ie, int ie_len,
324 const u8 *key, int key_len, int key_idx,
325 const u8 *sae_data, int sae_data_len);
326int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 286int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
327 struct net_device *dev, struct ieee80211_channel *chan, 287 struct net_device *dev,
328 enum nl80211_auth_type auth_type, const u8 *bssid, 288 struct ieee80211_channel *chan,
289 enum nl80211_auth_type auth_type,
290 const u8 *bssid,
329 const u8 *ssid, int ssid_len, 291 const u8 *ssid, int ssid_len,
330 const u8 *ie, int ie_len, 292 const u8 *ie, int ie_len,
331 const u8 *key, int key_len, int key_idx, 293 const u8 *key, int key_len, int key_idx,
332 const u8 *sae_data, int sae_data_len); 294 const u8 *sae_data, int sae_data_len);
333int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
334 struct net_device *dev,
335 struct ieee80211_channel *chan,
336 const u8 *bssid,
337 const u8 *ssid, int ssid_len,
338 struct cfg80211_assoc_request *req);
339int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 295int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
340 struct net_device *dev, 296 struct net_device *dev,
341 struct ieee80211_channel *chan, 297 struct ieee80211_channel *chan,
342 const u8 *bssid, 298 const u8 *bssid,
343 const u8 *ssid, int ssid_len, 299 const u8 *ssid, int ssid_len,
344 struct cfg80211_assoc_request *req); 300 struct cfg80211_assoc_request *req);
345int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
346 struct net_device *dev, const u8 *bssid,
347 const u8 *ie, int ie_len, u16 reason,
348 bool local_state_change);
349int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 301int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
350 struct net_device *dev, const u8 *bssid, 302 struct net_device *dev, const u8 *bssid,
351 const u8 *ie, int ie_len, u16 reason, 303 const u8 *ie, int ie_len, u16 reason,
@@ -377,18 +329,11 @@ void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
377 const struct ieee80211_vht_cap *vht_capa_mask); 329 const struct ieee80211_vht_cap *vht_capa_mask);
378 330
379/* SME */ 331/* SME */
380int __cfg80211_connect(struct cfg80211_registered_device *rdev,
381 struct net_device *dev,
382 struct cfg80211_connect_params *connect,
383 struct cfg80211_cached_keys *connkeys,
384 const u8 *prev_bssid);
385int cfg80211_connect(struct cfg80211_registered_device *rdev, 332int cfg80211_connect(struct cfg80211_registered_device *rdev,
386 struct net_device *dev, 333 struct net_device *dev,
387 struct cfg80211_connect_params *connect, 334 struct cfg80211_connect_params *connect,
388 struct cfg80211_cached_keys *connkeys); 335 struct cfg80211_cached_keys *connkeys,
389int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, 336 const u8 *prev_bssid);
390 struct net_device *dev, u16 reason,
391 bool wextev);
392int cfg80211_disconnect(struct cfg80211_registered_device *rdev, 337int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
393 struct net_device *dev, u16 reason, 338 struct net_device *dev, u16 reason,
394 bool wextev); 339 bool wextev);
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
index 920cabe0461b..90d050036624 100644
--- a/net/wireless/debugfs.c
+++ b/net/wireless/debugfs.c
@@ -74,7 +74,7 @@ static ssize_t ht40allow_map_read(struct file *file,
74 if (!buf) 74 if (!buf)
75 return -ENOMEM; 75 return -ENOMEM;
76 76
77 mutex_lock(&cfg80211_mutex); 77 rtnl_lock();
78 78
79 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 79 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
80 sband = wiphy->bands[band]; 80 sband = wiphy->bands[band];
@@ -85,7 +85,7 @@ static ssize_t ht40allow_map_read(struct file *file,
85 buf, buf_size, offset); 85 buf, buf_size, offset);
86 } 86 }
87 87
88 mutex_unlock(&cfg80211_mutex); 88 rtnl_unlock();
89 89
90 r = simple_read_from_buffer(user_buf, count, ppos, buf, offset); 90 r = simple_read_from_buffer(user_buf, count, ppos, buf, offset);
91 91
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index d80e47194d49..5449c5a6de84 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -152,11 +152,11 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
152 struct wireless_dev *wdev = dev->ieee80211_ptr; 152 struct wireless_dev *wdev = dev->ieee80211_ptr;
153 int err; 153 int err;
154 154
155 mutex_lock(&rdev->devlist_mtx); 155 ASSERT_RTNL();
156
156 wdev_lock(wdev); 157 wdev_lock(wdev);
157 err = __cfg80211_join_ibss(rdev, dev, params, connkeys); 158 err = __cfg80211_join_ibss(rdev, dev, params, connkeys);
158 wdev_unlock(wdev); 159 wdev_unlock(wdev);
159 mutex_unlock(&rdev->devlist_mtx);
160 160
161 return err; 161 return err;
162} 162}
@@ -359,11 +359,9 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
359 wdev->wext.ibss.channel_fixed = false; 359 wdev->wext.ibss.channel_fixed = false;
360 } 360 }
361 361
362 mutex_lock(&rdev->devlist_mtx);
363 wdev_lock(wdev); 362 wdev_lock(wdev);
364 err = cfg80211_ibss_wext_join(rdev, wdev); 363 err = cfg80211_ibss_wext_join(rdev, wdev);
365 wdev_unlock(wdev); 364 wdev_unlock(wdev);
366 mutex_unlock(&rdev->devlist_mtx);
367 365
368 return err; 366 return err;
369} 367}
@@ -429,11 +427,9 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
429 memcpy(wdev->wext.ibss.ssid, ssid, len); 427 memcpy(wdev->wext.ibss.ssid, ssid, len);
430 wdev->wext.ibss.ssid_len = len; 428 wdev->wext.ibss.ssid_len = len;
431 429
432 mutex_lock(&rdev->devlist_mtx);
433 wdev_lock(wdev); 430 wdev_lock(wdev);
434 err = cfg80211_ibss_wext_join(rdev, wdev); 431 err = cfg80211_ibss_wext_join(rdev, wdev);
435 wdev_unlock(wdev); 432 wdev_unlock(wdev);
436 mutex_unlock(&rdev->devlist_mtx);
437 433
438 return err; 434 return err;
439} 435}
@@ -512,11 +508,9 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
512 } else 508 } else
513 wdev->wext.ibss.bssid = NULL; 509 wdev->wext.ibss.bssid = NULL;
514 510
515 mutex_lock(&rdev->devlist_mtx);
516 wdev_lock(wdev); 511 wdev_lock(wdev);
517 err = cfg80211_ibss_wext_join(rdev, wdev); 512 err = cfg80211_ibss_wext_join(rdev, wdev);
518 wdev_unlock(wdev); 513 wdev_unlock(wdev);
519 mutex_unlock(&rdev->devlist_mtx);
520 514
521 return err; 515 return err;
522} 516}
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 0bb93f3061a4..5dfb289ab761 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -82,6 +82,7 @@ const struct mesh_setup default_mesh_setup = {
82 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, 82 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET,
83 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, 83 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
84 .path_metric = IEEE80211_PATH_METRIC_AIRTIME, 84 .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
85 .auth_id = 0, /* open */
85 .ie = NULL, 86 .ie = NULL,
86 .ie_len = 0, 87 .ie_len = 0,
87 .is_secure = false, 88 .is_secure = false,
@@ -185,11 +186,9 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
185 struct wireless_dev *wdev = dev->ieee80211_ptr; 186 struct wireless_dev *wdev = dev->ieee80211_ptr;
186 int err; 187 int err;
187 188
188 mutex_lock(&rdev->devlist_mtx);
189 wdev_lock(wdev); 189 wdev_lock(wdev);
190 err = __cfg80211_join_mesh(rdev, dev, setup, conf); 190 err = __cfg80211_join_mesh(rdev, dev, setup, conf);
191 wdev_unlock(wdev); 191 wdev_unlock(wdev);
192 mutex_unlock(&rdev->devlist_mtx);
193 192
194 return err; 193 return err;
195} 194}
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 0c7b7dd855f6..7bde5d9c0003 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -25,12 +25,9 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
25 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 25 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
26 26
27 trace_cfg80211_send_rx_auth(dev); 27 trace_cfg80211_send_rx_auth(dev);
28 wdev_lock(wdev);
29 28
30 nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL); 29 nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
31 cfg80211_sme_rx_auth(dev, buf, len); 30 cfg80211_sme_rx_auth(dev, buf, len);
32
33 wdev_unlock(wdev);
34} 31}
35EXPORT_SYMBOL(cfg80211_send_rx_auth); 32EXPORT_SYMBOL(cfg80211_send_rx_auth);
36 33
@@ -46,7 +43,6 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
46 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); 43 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
47 44
48 trace_cfg80211_send_rx_assoc(dev, bss); 45 trace_cfg80211_send_rx_assoc(dev, bss);
49 wdev_lock(wdev);
50 46
51 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); 47 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
52 48
@@ -59,7 +55,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
59 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn && 55 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
60 cfg80211_sme_failed_reassoc(wdev)) { 56 cfg80211_sme_failed_reassoc(wdev)) {
61 cfg80211_put_bss(wiphy, bss); 57 cfg80211_put_bss(wiphy, bss);
62 goto out; 58 return;
63 } 59 }
64 60
65 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL); 61 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
@@ -71,7 +67,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
71 * sme will schedule work that does it later. 67 * sme will schedule work that does it later.
72 */ 68 */
73 cfg80211_put_bss(wiphy, bss); 69 cfg80211_put_bss(wiphy, bss);
74 goto out; 70 return;
75 } 71 }
76 72
77 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) { 73 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
@@ -87,13 +83,11 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
87 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, 83 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
88 status_code, 84 status_code,
89 status_code == WLAN_STATUS_SUCCESS, bss); 85 status_code == WLAN_STATUS_SUCCESS, bss);
90 out:
91 wdev_unlock(wdev);
92} 86}
93EXPORT_SYMBOL(cfg80211_send_rx_assoc); 87EXPORT_SYMBOL(cfg80211_send_rx_assoc);
94 88
95void __cfg80211_send_deauth(struct net_device *dev, 89void cfg80211_send_deauth(struct net_device *dev,
96 const u8 *buf, size_t len) 90 const u8 *buf, size_t len)
97{ 91{
98 struct wireless_dev *wdev = dev->ieee80211_ptr; 92 struct wireless_dev *wdev = dev->ieee80211_ptr;
99 struct wiphy *wiphy = wdev->wiphy; 93 struct wiphy *wiphy = wdev->wiphy;
@@ -102,7 +96,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
102 const u8 *bssid = mgmt->bssid; 96 const u8 *bssid = mgmt->bssid;
103 bool was_current = false; 97 bool was_current = false;
104 98
105 trace___cfg80211_send_deauth(dev); 99 trace_cfg80211_send_deauth(dev);
106 ASSERT_WDEV_LOCK(wdev); 100 ASSERT_WDEV_LOCK(wdev);
107 101
108 if (wdev->current_bss && 102 if (wdev->current_bss &&
@@ -129,20 +123,10 @@ void __cfg80211_send_deauth(struct net_device *dev,
129 false, NULL); 123 false, NULL);
130 } 124 }
131} 125}
132EXPORT_SYMBOL(__cfg80211_send_deauth);
133
134void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
135{
136 struct wireless_dev *wdev = dev->ieee80211_ptr;
137
138 wdev_lock(wdev);
139 __cfg80211_send_deauth(dev, buf, len);
140 wdev_unlock(wdev);
141}
142EXPORT_SYMBOL(cfg80211_send_deauth); 126EXPORT_SYMBOL(cfg80211_send_deauth);
143 127
144void __cfg80211_send_disassoc(struct net_device *dev, 128void cfg80211_send_disassoc(struct net_device *dev,
145 const u8 *buf, size_t len) 129 const u8 *buf, size_t len)
146{ 130{
147 struct wireless_dev *wdev = dev->ieee80211_ptr; 131 struct wireless_dev *wdev = dev->ieee80211_ptr;
148 struct wiphy *wiphy = wdev->wiphy; 132 struct wiphy *wiphy = wdev->wiphy;
@@ -152,7 +136,7 @@ void __cfg80211_send_disassoc(struct net_device *dev,
152 u16 reason_code; 136 u16 reason_code;
153 bool from_ap; 137 bool from_ap;
154 138
155 trace___cfg80211_send_disassoc(dev); 139 trace_cfg80211_send_disassoc(dev);
156 ASSERT_WDEV_LOCK(wdev); 140 ASSERT_WDEV_LOCK(wdev);
157 141
158 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL); 142 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
@@ -175,16 +159,6 @@ void __cfg80211_send_disassoc(struct net_device *dev,
175 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr); 159 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr);
176 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 160 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
177} 161}
178EXPORT_SYMBOL(__cfg80211_send_disassoc);
179
180void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
181{
182 struct wireless_dev *wdev = dev->ieee80211_ptr;
183
184 wdev_lock(wdev);
185 __cfg80211_send_disassoc(dev, buf, len);
186 wdev_unlock(wdev);
187}
188EXPORT_SYMBOL(cfg80211_send_disassoc); 162EXPORT_SYMBOL(cfg80211_send_disassoc);
189 163
190void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) 164void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
@@ -194,15 +168,12 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
194 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 168 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
195 169
196 trace_cfg80211_send_auth_timeout(dev, addr); 170 trace_cfg80211_send_auth_timeout(dev, addr);
197 wdev_lock(wdev);
198 171
199 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); 172 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
200 if (wdev->sme_state == CFG80211_SME_CONNECTING) 173 if (wdev->sme_state == CFG80211_SME_CONNECTING)
201 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 174 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
202 WLAN_STATUS_UNSPECIFIED_FAILURE, 175 WLAN_STATUS_UNSPECIFIED_FAILURE,
203 false, NULL); 176 false, NULL);
204
205 wdev_unlock(wdev);
206} 177}
207EXPORT_SYMBOL(cfg80211_send_auth_timeout); 178EXPORT_SYMBOL(cfg80211_send_auth_timeout);
208 179
@@ -213,15 +184,12 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
213 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 184 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
214 185
215 trace_cfg80211_send_assoc_timeout(dev, addr); 186 trace_cfg80211_send_assoc_timeout(dev, addr);
216 wdev_lock(wdev);
217 187
218 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); 188 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
219 if (wdev->sme_state == CFG80211_SME_CONNECTING) 189 if (wdev->sme_state == CFG80211_SME_CONNECTING)
220 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 190 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
221 WLAN_STATUS_UNSPECIFIED_FAILURE, 191 WLAN_STATUS_UNSPECIFIED_FAILURE,
222 false, NULL); 192 false, NULL);
223
224 wdev_unlock(wdev);
225} 193}
226EXPORT_SYMBOL(cfg80211_send_assoc_timeout); 194EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
227 195
@@ -253,18 +221,27 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
253EXPORT_SYMBOL(cfg80211_michael_mic_failure); 221EXPORT_SYMBOL(cfg80211_michael_mic_failure);
254 222
255/* some MLME handling for userspace SME */ 223/* some MLME handling for userspace SME */
256int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 224int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
257 struct net_device *dev, 225 struct net_device *dev,
258 struct ieee80211_channel *chan, 226 struct ieee80211_channel *chan,
259 enum nl80211_auth_type auth_type, 227 enum nl80211_auth_type auth_type,
260 const u8 *bssid, 228 const u8 *bssid,
261 const u8 *ssid, int ssid_len, 229 const u8 *ssid, int ssid_len,
262 const u8 *ie, int ie_len, 230 const u8 *ie, int ie_len,
263 const u8 *key, int key_len, int key_idx, 231 const u8 *key, int key_len, int key_idx,
264 const u8 *sae_data, int sae_data_len) 232 const u8 *sae_data, int sae_data_len)
265{ 233{
266 struct wireless_dev *wdev = dev->ieee80211_ptr; 234 struct wireless_dev *wdev = dev->ieee80211_ptr;
267 struct cfg80211_auth_request req; 235 struct cfg80211_auth_request req = {
236 .ie = ie,
237 .ie_len = ie_len,
238 .sae_data = sae_data,
239 .sae_data_len = sae_data_len,
240 .auth_type = auth_type,
241 .key = key,
242 .key_len = key_len,
243 .key_idx = key_idx,
244 };
268 int err; 245 int err;
269 246
270 ASSERT_WDEV_LOCK(wdev); 247 ASSERT_WDEV_LOCK(wdev);
@@ -277,18 +254,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
277 ether_addr_equal(bssid, wdev->current_bss->pub.bssid)) 254 ether_addr_equal(bssid, wdev->current_bss->pub.bssid))
278 return -EALREADY; 255 return -EALREADY;
279 256
280 memset(&req, 0, sizeof(req));
281
282 req.ie = ie;
283 req.ie_len = ie_len;
284 req.sae_data = sae_data;
285 req.sae_data_len = sae_data_len;
286 req.auth_type = auth_type;
287 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 257 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
288 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 258 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
289 req.key = key;
290 req.key_len = key_len;
291 req.key_idx = key_idx;
292 if (!req.bss) 259 if (!req.bss)
293 return -ENOENT; 260 return -ENOENT;
294 261
@@ -304,28 +271,6 @@ out:
304 return err; 271 return err;
305} 272}
306 273
307int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
308 struct net_device *dev, struct ieee80211_channel *chan,
309 enum nl80211_auth_type auth_type, const u8 *bssid,
310 const u8 *ssid, int ssid_len,
311 const u8 *ie, int ie_len,
312 const u8 *key, int key_len, int key_idx,
313 const u8 *sae_data, int sae_data_len)
314{
315 int err;
316
317 mutex_lock(&rdev->devlist_mtx);
318 wdev_lock(dev->ieee80211_ptr);
319 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
320 ssid, ssid_len, ie, ie_len,
321 key, key_len, key_idx,
322 sae_data, sae_data_len);
323 wdev_unlock(dev->ieee80211_ptr);
324 mutex_unlock(&rdev->devlist_mtx);
325
326 return err;
327}
328
329/* Do a logical ht_capa &= ht_capa_mask. */ 274/* Do a logical ht_capa &= ht_capa_mask. */
330void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, 275void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
331 const struct ieee80211_ht_cap *ht_capa_mask) 276 const struct ieee80211_ht_cap *ht_capa_mask)
@@ -360,12 +305,12 @@ void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
360 p1[i] &= p2[i]; 305 p1[i] &= p2[i];
361} 306}
362 307
363int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 308int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
364 struct net_device *dev, 309 struct net_device *dev,
365 struct ieee80211_channel *chan, 310 struct ieee80211_channel *chan,
366 const u8 *bssid, 311 const u8 *bssid,
367 const u8 *ssid, int ssid_len, 312 const u8 *ssid, int ssid_len,
368 struct cfg80211_assoc_request *req) 313 struct cfg80211_assoc_request *req)
369{ 314{
370 struct wireless_dev *wdev = dev->ieee80211_ptr; 315 struct wireless_dev *wdev = dev->ieee80211_ptr;
371 int err; 316 int err;
@@ -415,30 +360,10 @@ out:
415 return err; 360 return err;
416} 361}
417 362
418int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 363int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
419 struct net_device *dev, 364 struct net_device *dev, const u8 *bssid,
420 struct ieee80211_channel *chan, 365 const u8 *ie, int ie_len, u16 reason,
421 const u8 *bssid, 366 bool local_state_change)
422 const u8 *ssid, int ssid_len,
423 struct cfg80211_assoc_request *req)
424{
425 struct wireless_dev *wdev = dev->ieee80211_ptr;
426 int err;
427
428 mutex_lock(&rdev->devlist_mtx);
429 wdev_lock(wdev);
430 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid,
431 ssid, ssid_len, req);
432 wdev_unlock(wdev);
433 mutex_unlock(&rdev->devlist_mtx);
434
435 return err;
436}
437
438int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
439 struct net_device *dev, const u8 *bssid,
440 const u8 *ie, int ie_len, u16 reason,
441 bool local_state_change)
442{ 367{
443 struct wireless_dev *wdev = dev->ieee80211_ptr; 368 struct wireless_dev *wdev = dev->ieee80211_ptr;
444 struct cfg80211_deauth_request req = { 369 struct cfg80211_deauth_request req = {
@@ -458,29 +383,18 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
458 return rdev_deauth(rdev, dev, &req); 383 return rdev_deauth(rdev, dev, &req);
459} 384}
460 385
461int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 386int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
462 struct net_device *dev, const u8 *bssid, 387 struct net_device *dev, const u8 *bssid,
463 const u8 *ie, int ie_len, u16 reason, 388 const u8 *ie, int ie_len, u16 reason,
464 bool local_state_change) 389 bool local_state_change)
465{
466 struct wireless_dev *wdev = dev->ieee80211_ptr;
467 int err;
468
469 wdev_lock(wdev);
470 err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
471 local_state_change);
472 wdev_unlock(wdev);
473
474 return err;
475}
476
477static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
478 struct net_device *dev, const u8 *bssid,
479 const u8 *ie, int ie_len, u16 reason,
480 bool local_state_change)
481{ 390{
482 struct wireless_dev *wdev = dev->ieee80211_ptr; 391 struct wireless_dev *wdev = dev->ieee80211_ptr;
483 struct cfg80211_disassoc_request req; 392 struct cfg80211_disassoc_request req = {
393 .reason_code = reason,
394 .local_state_change = local_state_change,
395 .ie = ie,
396 .ie_len = ie_len,
397 };
484 398
485 ASSERT_WDEV_LOCK(wdev); 399 ASSERT_WDEV_LOCK(wdev);
486 400
@@ -490,11 +404,6 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
490 if (WARN(!wdev->current_bss, "sme_state=%d\n", wdev->sme_state)) 404 if (WARN(!wdev->current_bss, "sme_state=%d\n", wdev->sme_state))
491 return -ENOTCONN; 405 return -ENOTCONN;
492 406
493 memset(&req, 0, sizeof(req));
494 req.reason_code = reason;
495 req.local_state_change = local_state_change;
496 req.ie = ie;
497 req.ie_len = ie_len;
498 if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) 407 if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
499 req.bss = &wdev->current_bss->pub; 408 req.bss = &wdev->current_bss->pub;
500 else 409 else
@@ -503,44 +412,25 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
503 return rdev_disassoc(rdev, dev, &req); 412 return rdev_disassoc(rdev, dev, &req);
504} 413}
505 414
506int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
507 struct net_device *dev, const u8 *bssid,
508 const u8 *ie, int ie_len, u16 reason,
509 bool local_state_change)
510{
511 struct wireless_dev *wdev = dev->ieee80211_ptr;
512 int err;
513
514 wdev_lock(wdev);
515 err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
516 local_state_change);
517 wdev_unlock(wdev);
518
519 return err;
520}
521
522void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, 415void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
523 struct net_device *dev) 416 struct net_device *dev)
524{ 417{
525 struct wireless_dev *wdev = dev->ieee80211_ptr; 418 struct wireless_dev *wdev = dev->ieee80211_ptr;
526 struct cfg80211_deauth_request req;
527 u8 bssid[ETH_ALEN]; 419 u8 bssid[ETH_ALEN];
420 struct cfg80211_deauth_request req = {
421 .reason_code = WLAN_REASON_DEAUTH_LEAVING,
422 .bssid = bssid,
423 };
528 424
529 ASSERT_WDEV_LOCK(wdev); 425 ASSERT_WDEV_LOCK(wdev);
530 426
531 if (!rdev->ops->deauth) 427 if (!rdev->ops->deauth)
532 return; 428 return;
533 429
534 memset(&req, 0, sizeof(req));
535 req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
536 req.ie = NULL;
537 req.ie_len = 0;
538
539 if (!wdev->current_bss) 430 if (!wdev->current_bss)
540 return; 431 return;
541 432
542 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); 433 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
543 req.bssid = bssid;
544 rdev_deauth(rdev, dev, &req); 434 rdev_deauth(rdev, dev, &req);
545 435
546 if (wdev->current_bss) { 436 if (wdev->current_bss) {
@@ -848,7 +738,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
848 dfs_update_channels_wk); 738 dfs_update_channels_wk);
849 wiphy = &rdev->wiphy; 739 wiphy = &rdev->wiphy;
850 740
851 mutex_lock(&cfg80211_mutex); 741 rtnl_lock();
852 for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) { 742 for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) {
853 sband = wiphy->bands[bandid]; 743 sband = wiphy->bands[bandid];
854 if (!sband) 744 if (!sband)
@@ -881,7 +771,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
881 check_again = true; 771 check_again = true;
882 } 772 }
883 } 773 }
884 mutex_unlock(&cfg80211_mutex); 774 rtnl_unlock();
885 775
886 /* reschedule if there are other channels waiting to be cleared again */ 776 /* reschedule if there are other channels waiting to be cleared again */
887 if (check_again) 777 if (check_again)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d5aed3bb3945..31d265f36d2c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -37,10 +37,10 @@ static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
37 37
38/* the netlink family */ 38/* the netlink family */
39static struct genl_family nl80211_fam = { 39static struct genl_family nl80211_fam = {
40 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ 40 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
41 .name = "nl80211", /* have users key off the name instead */ 41 .name = NL80211_GENL_NAME, /* have users key off the name instead */
42 .hdrsize = 0, /* no private header */ 42 .hdrsize = 0, /* no private header */
43 .version = 1, /* no particular meaning now */ 43 .version = 1, /* no particular meaning now */
44 .maxattr = NL80211_ATTR_MAX, 44 .maxattr = NL80211_ATTR_MAX,
45 .netnsok = true, 45 .netnsok = true,
46 .pre_doit = nl80211_pre_doit, 46 .pre_doit = nl80211_pre_doit,
@@ -59,7 +59,7 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
59 int wiphy_idx = -1; 59 int wiphy_idx = -1;
60 int ifidx = -1; 60 int ifidx = -1;
61 61
62 assert_cfg80211_lock(); 62 ASSERT_RTNL();
63 63
64 if (!have_ifidx && !have_wdev_id) 64 if (!have_ifidx && !have_wdev_id)
65 return ERR_PTR(-EINVAL); 65 return ERR_PTR(-EINVAL);
@@ -80,7 +80,6 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
80 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx) 80 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
81 continue; 81 continue;
82 82
83 mutex_lock(&rdev->devlist_mtx);
84 list_for_each_entry(wdev, &rdev->wdev_list, list) { 83 list_for_each_entry(wdev, &rdev->wdev_list, list) {
85 if (have_ifidx && wdev->netdev && 84 if (have_ifidx && wdev->netdev &&
86 wdev->netdev->ifindex == ifidx) { 85 wdev->netdev->ifindex == ifidx) {
@@ -92,7 +91,6 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
92 break; 91 break;
93 } 92 }
94 } 93 }
95 mutex_unlock(&rdev->devlist_mtx);
96 94
97 if (result) 95 if (result)
98 break; 96 break;
@@ -109,7 +107,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
109 struct cfg80211_registered_device *rdev = NULL, *tmp; 107 struct cfg80211_registered_device *rdev = NULL, *tmp;
110 struct net_device *netdev; 108 struct net_device *netdev;
111 109
112 assert_cfg80211_lock(); 110 ASSERT_RTNL();
113 111
114 if (!attrs[NL80211_ATTR_WIPHY] && 112 if (!attrs[NL80211_ATTR_WIPHY] &&
115 !attrs[NL80211_ATTR_IFINDEX] && 113 !attrs[NL80211_ATTR_IFINDEX] &&
@@ -128,14 +126,12 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
128 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32); 126 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
129 if (tmp) { 127 if (tmp) {
130 /* make sure wdev exists */ 128 /* make sure wdev exists */
131 mutex_lock(&tmp->devlist_mtx);
132 list_for_each_entry(wdev, &tmp->wdev_list, list) { 129 list_for_each_entry(wdev, &tmp->wdev_list, list) {
133 if (wdev->identifier != (u32)wdev_id) 130 if (wdev->identifier != (u32)wdev_id)
134 continue; 131 continue;
135 found = true; 132 found = true;
136 break; 133 break;
137 } 134 }
138 mutex_unlock(&tmp->devlist_mtx);
139 135
140 if (!found) 136 if (!found)
141 tmp = NULL; 137 tmp = NULL;
@@ -182,19 +178,6 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
182/* 178/*
183 * This function returns a pointer to the driver 179 * This function returns a pointer to the driver
184 * that the genl_info item that is passed refers to. 180 * that the genl_info item that is passed refers to.
185 * If successful, it returns non-NULL and also locks
186 * the driver's mutex!
187 *
188 * This means that you need to call cfg80211_unlock_rdev()
189 * before being allowed to acquire &cfg80211_mutex!
190 *
191 * This is necessary because we need to lock the global
192 * mutex to get an item off the list safely, and then
193 * we lock the rdev mutex so it doesn't go away under us.
194 *
195 * We don't want to keep cfg80211_mutex locked
196 * for all the time in order to allow requests on
197 * other interfaces to go through at the same time.
198 * 181 *
199 * The result of this can be a PTR_ERR and hence must 182 * The result of this can be a PTR_ERR and hence must
200 * be checked with IS_ERR() for errors. 183 * be checked with IS_ERR() for errors.
@@ -202,20 +185,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
202static struct cfg80211_registered_device * 185static struct cfg80211_registered_device *
203cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info) 186cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
204{ 187{
205 struct cfg80211_registered_device *rdev; 188 return __cfg80211_rdev_from_attrs(netns, info->attrs);
206
207 mutex_lock(&cfg80211_mutex);
208 rdev = __cfg80211_rdev_from_attrs(netns, info->attrs);
209
210 /* if it is not an error we grab the lock on
211 * it to assure it won't be going away while
212 * we operate on it */
213 if (!IS_ERR(rdev))
214 mutex_lock(&rdev->mtx);
215
216 mutex_unlock(&cfg80211_mutex);
217
218 return rdev;
219} 189}
220 190
221/* policy for the attributes */ 191/* policy for the attributes */
@@ -378,6 +348,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
378 [NL80211_ATTR_MDID] = { .type = NLA_U16 }, 348 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
379 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY, 349 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
380 .len = IEEE80211_MAX_DATA_LEN }, 350 .len = IEEE80211_MAX_DATA_LEN },
351 [NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
381}; 352};
382 353
383/* policy for the key attributes */ 354/* policy for the key attributes */
@@ -455,7 +426,6 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
455 int err; 426 int err;
456 427
457 rtnl_lock(); 428 rtnl_lock();
458 mutex_lock(&cfg80211_mutex);
459 429
460 if (!cb->args[0]) { 430 if (!cb->args[0]) {
461 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 431 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
@@ -484,14 +454,12 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
484 *rdev = wiphy_to_dev(wiphy); 454 *rdev = wiphy_to_dev(wiphy);
485 *wdev = NULL; 455 *wdev = NULL;
486 456
487 mutex_lock(&(*rdev)->devlist_mtx);
488 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { 457 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) {
489 if (tmp->identifier == cb->args[1]) { 458 if (tmp->identifier == cb->args[1]) {
490 *wdev = tmp; 459 *wdev = tmp;
491 break; 460 break;
492 } 461 }
493 } 462 }
494 mutex_unlock(&(*rdev)->devlist_mtx);
495 463
496 if (!*wdev) { 464 if (!*wdev) {
497 err = -ENODEV; 465 err = -ENODEV;
@@ -499,19 +467,14 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
499 } 467 }
500 } 468 }
501 469
502 cfg80211_lock_rdev(*rdev);
503
504 mutex_unlock(&cfg80211_mutex);
505 return 0; 470 return 0;
506 out_unlock: 471 out_unlock:
507 mutex_unlock(&cfg80211_mutex);
508 rtnl_unlock(); 472 rtnl_unlock();
509 return err; 473 return err;
510} 474}
511 475
512static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev) 476static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
513{ 477{
514 cfg80211_unlock_rdev(rdev);
515 rtnl_unlock(); 478 rtnl_unlock();
516} 479}
517 480
@@ -1567,7 +1530,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1567 struct nlattr **tb = nl80211_fam.attrbuf; 1530 struct nlattr **tb = nl80211_fam.attrbuf;
1568 int res; 1531 int res;
1569 1532
1570 mutex_lock(&cfg80211_mutex); 1533 rtnl_lock();
1571 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 1534 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1572 tb, nl80211_fam.maxattr, nl80211_policy); 1535 tb, nl80211_fam.maxattr, nl80211_policy);
1573 if (res == 0) { 1536 if (res == 0) {
@@ -1581,10 +1544,8 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1581 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); 1544 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1582 1545
1583 netdev = dev_get_by_index(sock_net(skb->sk), ifidx); 1546 netdev = dev_get_by_index(sock_net(skb->sk), ifidx);
1584 if (!netdev) { 1547 if (!netdev)
1585 mutex_unlock(&cfg80211_mutex);
1586 return -ENODEV; 1548 return -ENODEV;
1587 }
1588 if (netdev->ieee80211_ptr) { 1549 if (netdev->ieee80211_ptr) {
1589 dev = wiphy_to_dev( 1550 dev = wiphy_to_dev(
1590 netdev->ieee80211_ptr->wiphy); 1551 netdev->ieee80211_ptr->wiphy);
@@ -1628,7 +1589,6 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1628 !skb->len && 1589 !skb->len &&
1629 cb->min_dump_alloc < 4096) { 1590 cb->min_dump_alloc < 4096) {
1630 cb->min_dump_alloc = 4096; 1591 cb->min_dump_alloc = 4096;
1631 mutex_unlock(&cfg80211_mutex);
1632 return 1; 1592 return 1;
1633 } 1593 }
1634 idx--; 1594 idx--;
@@ -1637,7 +1597,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1637 } while (cb->args[1] > 0); 1597 } while (cb->args[1] > 0);
1638 break; 1598 break;
1639 } 1599 }
1640 mutex_unlock(&cfg80211_mutex); 1600 rtnl_unlock();
1641 1601
1642 cb->args[0] = idx; 1602 cb->args[0] = idx;
1643 1603
@@ -1792,7 +1752,6 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1792 if (result) 1752 if (result)
1793 return result; 1753 return result;
1794 1754
1795 mutex_lock(&rdev->devlist_mtx);
1796 switch (iftype) { 1755 switch (iftype) {
1797 case NL80211_IFTYPE_AP: 1756 case NL80211_IFTYPE_AP:
1798 case NL80211_IFTYPE_P2P_GO: 1757 case NL80211_IFTYPE_P2P_GO:
@@ -1816,7 +1775,6 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1816 default: 1775 default:
1817 result = -EINVAL; 1776 result = -EINVAL;
1818 } 1777 }
1819 mutex_unlock(&rdev->devlist_mtx);
1820 1778
1821 return result; 1779 return result;
1822} 1780}
@@ -1865,6 +1823,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1865 u32 frag_threshold = 0, rts_threshold = 0; 1823 u32 frag_threshold = 0, rts_threshold = 0;
1866 u8 coverage_class = 0; 1824 u8 coverage_class = 0;
1867 1825
1826 ASSERT_RTNL();
1827
1868 /* 1828 /*
1869 * Try to find the wiphy and netdev. Normally this 1829 * Try to find the wiphy and netdev. Normally this
1870 * function shouldn't need the netdev, but this is 1830 * function shouldn't need the netdev, but this is
@@ -1874,31 +1834,25 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1874 * also passed a netdev to set_wiphy, so that it is 1834 * also passed a netdev to set_wiphy, so that it is
1875 * possible to let that go to the right netdev! 1835 * possible to let that go to the right netdev!
1876 */ 1836 */
1877 mutex_lock(&cfg80211_mutex);
1878 1837
1879 if (info->attrs[NL80211_ATTR_IFINDEX]) { 1838 if (info->attrs[NL80211_ATTR_IFINDEX]) {
1880 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); 1839 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
1881 1840
1882 netdev = dev_get_by_index(genl_info_net(info), ifindex); 1841 netdev = dev_get_by_index(genl_info_net(info), ifindex);
1883 if (netdev && netdev->ieee80211_ptr) { 1842 if (netdev && netdev->ieee80211_ptr)
1884 rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy); 1843 rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy);
1885 mutex_lock(&rdev->mtx); 1844 else
1886 } else
1887 netdev = NULL; 1845 netdev = NULL;
1888 } 1846 }
1889 1847
1890 if (!netdev) { 1848 if (!netdev) {
1891 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info), 1849 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
1892 info->attrs); 1850 info->attrs);
1893 if (IS_ERR(rdev)) { 1851 if (IS_ERR(rdev))
1894 mutex_unlock(&cfg80211_mutex);
1895 return PTR_ERR(rdev); 1852 return PTR_ERR(rdev);
1896 }
1897 wdev = NULL; 1853 wdev = NULL;
1898 netdev = NULL; 1854 netdev = NULL;
1899 result = 0; 1855 result = 0;
1900
1901 mutex_lock(&rdev->mtx);
1902 } else 1856 } else
1903 wdev = netdev->ieee80211_ptr; 1857 wdev = netdev->ieee80211_ptr;
1904 1858
@@ -1911,8 +1865,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1911 result = cfg80211_dev_rename( 1865 result = cfg80211_dev_rename(
1912 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); 1866 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
1913 1867
1914 mutex_unlock(&cfg80211_mutex);
1915
1916 if (result) 1868 if (result)
1917 goto bad_res; 1869 goto bad_res;
1918 1870
@@ -2119,7 +2071,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2119 } 2071 }
2120 2072
2121 bad_res: 2073 bad_res:
2122 mutex_unlock(&rdev->mtx);
2123 if (netdev) 2074 if (netdev)
2124 dev_put(netdev); 2075 dev_put(netdev);
2125 return result; 2076 return result;
@@ -2217,7 +2168,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2217 struct cfg80211_registered_device *rdev; 2168 struct cfg80211_registered_device *rdev;
2218 struct wireless_dev *wdev; 2169 struct wireless_dev *wdev;
2219 2170
2220 mutex_lock(&cfg80211_mutex); 2171 rtnl_lock();
2221 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 2172 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2222 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk))) 2173 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
2223 continue; 2174 continue;
@@ -2227,7 +2178,6 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2227 } 2178 }
2228 if_idx = 0; 2179 if_idx = 0;
2229 2180
2230 mutex_lock(&rdev->devlist_mtx);
2231 list_for_each_entry(wdev, &rdev->wdev_list, list) { 2181 list_for_each_entry(wdev, &rdev->wdev_list, list) {
2232 if (if_idx < if_start) { 2182 if (if_idx < if_start) {
2233 if_idx++; 2183 if_idx++;
@@ -2236,17 +2186,15 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2236 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid, 2186 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
2237 cb->nlh->nlmsg_seq, NLM_F_MULTI, 2187 cb->nlh->nlmsg_seq, NLM_F_MULTI,
2238 rdev, wdev) < 0) { 2188 rdev, wdev) < 0) {
2239 mutex_unlock(&rdev->devlist_mtx);
2240 goto out; 2189 goto out;
2241 } 2190 }
2242 if_idx++; 2191 if_idx++;
2243 } 2192 }
2244 mutex_unlock(&rdev->devlist_mtx);
2245 2193
2246 wp_idx++; 2194 wp_idx++;
2247 } 2195 }
2248 out: 2196 out:
2249 mutex_unlock(&cfg80211_mutex); 2197 rtnl_unlock();
2250 2198
2251 cb->args[0] = wp_idx; 2199 cb->args[0] = wp_idx;
2252 cb->args[1] = if_idx; 2200 cb->args[1] = if_idx;
@@ -2279,6 +2227,7 @@ static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
2279 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG }, 2227 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
2280 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG }, 2228 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
2281 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG }, 2229 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
2230 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
2282}; 2231};
2283 2232
2284static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) 2233static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
@@ -2390,6 +2339,10 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
2390 change = true; 2339 change = true;
2391 } 2340 }
2392 2341
2342 if (flags && (*flags & NL80211_MNTR_FLAG_ACTIVE) &&
2343 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2344 return -EOPNOTSUPP;
2345
2393 if (change) 2346 if (change)
2394 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params); 2347 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
2395 else 2348 else
@@ -2447,6 +2400,11 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2447 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? 2400 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
2448 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, 2401 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
2449 &flags); 2402 &flags);
2403
2404 if (!err && (flags & NL80211_MNTR_FLAG_ACTIVE) &&
2405 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2406 return -EOPNOTSUPP;
2407
2450 wdev = rdev_add_virtual_intf(rdev, 2408 wdev = rdev_add_virtual_intf(rdev,
2451 nla_data(info->attrs[NL80211_ATTR_IFNAME]), 2409 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
2452 type, err ? NULL : &flags, &params); 2410 type, err ? NULL : &flags, &params);
@@ -2479,11 +2437,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2479 INIT_LIST_HEAD(&wdev->mgmt_registrations); 2437 INIT_LIST_HEAD(&wdev->mgmt_registrations);
2480 spin_lock_init(&wdev->mgmt_registrations_lock); 2438 spin_lock_init(&wdev->mgmt_registrations_lock);
2481 2439
2482 mutex_lock(&rdev->devlist_mtx);
2483 wdev->identifier = ++rdev->wdev_id; 2440 wdev->identifier = ++rdev->wdev_id;
2484 list_add_rcu(&wdev->list, &rdev->wdev_list); 2441 list_add_rcu(&wdev->list, &rdev->wdev_list);
2485 rdev->devlist_generation++; 2442 rdev->devlist_generation++;
2486 mutex_unlock(&rdev->devlist_mtx);
2487 break; 2443 break;
2488 default: 2444 default:
2489 break; 2445 break;
@@ -2992,8 +2948,6 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
2992 struct wireless_dev *wdev; 2948 struct wireless_dev *wdev;
2993 bool ret = false; 2949 bool ret = false;
2994 2950
2995 mutex_lock(&rdev->devlist_mtx);
2996
2997 list_for_each_entry(wdev, &rdev->wdev_list, list) { 2951 list_for_each_entry(wdev, &rdev->wdev_list, list) {
2998 if (wdev->iftype != NL80211_IFTYPE_AP && 2952 if (wdev->iftype != NL80211_IFTYPE_AP &&
2999 wdev->iftype != NL80211_IFTYPE_P2P_GO) 2953 wdev->iftype != NL80211_IFTYPE_P2P_GO)
@@ -3007,8 +2961,6 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
3007 break; 2961 break;
3008 } 2962 }
3009 2963
3010 mutex_unlock(&rdev->devlist_mtx);
3011
3012 return ret; 2964 return ret;
3013} 2965}
3014 2966
@@ -3170,13 +3122,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3170 params.radar_required = true; 3122 params.radar_required = true;
3171 } 3123 }
3172 3124
3173 mutex_lock(&rdev->devlist_mtx);
3174 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 3125 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
3175 params.chandef.chan, 3126 params.chandef.chan,
3176 CHAN_MODE_SHARED, 3127 CHAN_MODE_SHARED,
3177 radar_detect_width); 3128 radar_detect_width);
3178 mutex_unlock(&rdev->devlist_mtx);
3179
3180 if (err) 3129 if (err)
3181 return err; 3130 return err;
3182 3131
@@ -3376,6 +3325,32 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
3376 return true; 3325 return true;
3377} 3326}
3378 3327
3328static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
3329 int id)
3330{
3331 void *attr;
3332 int i = 0;
3333
3334 if (!mask)
3335 return true;
3336
3337 attr = nla_nest_start(msg, id);
3338 if (!attr)
3339 return false;
3340
3341 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
3342 if (!(mask & BIT(i)))
3343 continue;
3344
3345 if (nla_put_u8(msg, i, signal[i]))
3346 return false;
3347 }
3348
3349 nla_nest_end(msg, attr);
3350
3351 return true;
3352}
3353
3379static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, 3354static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
3380 int flags, 3355 int flags,
3381 struct cfg80211_registered_device *rdev, 3356 struct cfg80211_registered_device *rdev,
@@ -3447,6 +3422,18 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
3447 default: 3422 default:
3448 break; 3423 break;
3449 } 3424 }
3425 if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
3426 if (!nl80211_put_signal(msg, sinfo->chains,
3427 sinfo->chain_signal,
3428 NL80211_STA_INFO_CHAIN_SIGNAL))
3429 goto nla_put_failure;
3430 }
3431 if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
3432 if (!nl80211_put_signal(msg, sinfo->chains,
3433 sinfo->chain_signal_avg,
3434 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
3435 goto nla_put_failure;
3436 }
3450 if (sinfo->filled & STATION_INFO_TX_BITRATE) { 3437 if (sinfo->filled & STATION_INFO_TX_BITRATE) {
3451 if (!nl80211_put_sta_rate(msg, &sinfo->txrate, 3438 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
3452 NL80211_STA_INFO_TX_BITRATE)) 3439 NL80211_STA_INFO_TX_BITRATE))
@@ -3834,6 +3821,8 @@ static int nl80211_set_station_tdls(struct genl_info *info,
3834 struct station_parameters *params) 3821 struct station_parameters *params)
3835{ 3822{
3836 /* Dummy STA entry gets updated once the peer capabilities are known */ 3823 /* Dummy STA entry gets updated once the peer capabilities are known */
3824 if (info->attrs[NL80211_ATTR_PEER_AID])
3825 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3837 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) 3826 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
3838 params->ht_capa = 3827 params->ht_capa =
3839 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 3828 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
@@ -3974,7 +3963,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3974 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) 3963 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
3975 return -EINVAL; 3964 return -EINVAL;
3976 3965
3977 if (!info->attrs[NL80211_ATTR_STA_AID]) 3966 if (!info->attrs[NL80211_ATTR_STA_AID] &&
3967 !info->attrs[NL80211_ATTR_PEER_AID])
3978 return -EINVAL; 3968 return -EINVAL;
3979 3969
3980 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 3970 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
@@ -3985,7 +3975,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3985 params.listen_interval = 3975 params.listen_interval =
3986 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 3976 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
3987 3977
3988 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); 3978 if (info->attrs[NL80211_ATTR_STA_AID])
3979 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
3980 else
3981 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3989 if (!params.aid || params.aid > IEEE80211_MAX_AID) 3982 if (!params.aid || params.aid > IEEE80211_MAX_AID)
3990 return -EINVAL; 3983 return -EINVAL;
3991 3984
@@ -4634,6 +4627,7 @@ static const struct nla_policy
4634 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, 4627 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
4635 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, 4628 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
4636 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, 4629 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
4630 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
4637 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG }, 4631 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
4638 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, 4632 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
4639 .len = IEEE80211_MAX_DATA_LEN }, 4633 .len = IEEE80211_MAX_DATA_LEN },
@@ -4819,6 +4813,13 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
4819 if (setup->is_secure) 4813 if (setup->is_secure)
4820 setup->user_mpm = true; 4814 setup->user_mpm = true;
4821 4815
4816 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
4817 if (!setup->user_mpm)
4818 return -EINVAL;
4819 setup->auth_id =
4820 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
4821 }
4822
4822 return 0; 4823 return 0;
4823} 4824}
4824 4825
@@ -4861,18 +4862,13 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
4861 void *hdr = NULL; 4862 void *hdr = NULL;
4862 struct nlattr *nl_reg_rules; 4863 struct nlattr *nl_reg_rules;
4863 unsigned int i; 4864 unsigned int i;
4864 int err = -EINVAL;
4865
4866 mutex_lock(&cfg80211_mutex);
4867 4865
4868 if (!cfg80211_regdomain) 4866 if (!cfg80211_regdomain)
4869 goto out; 4867 return -EINVAL;
4870 4868
4871 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4869 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4872 if (!msg) { 4870 if (!msg)
4873 err = -ENOBUFS; 4871 return -ENOBUFS;
4874 goto out;
4875 }
4876 4872
4877 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, 4873 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
4878 NL80211_CMD_GET_REG); 4874 NL80211_CMD_GET_REG);
@@ -4931,8 +4927,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
4931 nla_nest_end(msg, nl_reg_rules); 4927 nla_nest_end(msg, nl_reg_rules);
4932 4928
4933 genlmsg_end(msg, hdr); 4929 genlmsg_end(msg, hdr);
4934 err = genlmsg_reply(msg, info); 4930 return genlmsg_reply(msg, info);
4935 goto out;
4936 4931
4937nla_put_failure_rcu: 4932nla_put_failure_rcu:
4938 rcu_read_unlock(); 4933 rcu_read_unlock();
@@ -4940,10 +4935,7 @@ nla_put_failure:
4940 genlmsg_cancel(msg, hdr); 4935 genlmsg_cancel(msg, hdr);
4941put_failure: 4936put_failure:
4942 nlmsg_free(msg); 4937 nlmsg_free(msg);
4943 err = -EMSGSIZE; 4938 return -EMSGSIZE;
4944out:
4945 mutex_unlock(&cfg80211_mutex);
4946 return err;
4947} 4939}
4948 4940
4949static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) 4941static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
@@ -5009,12 +5001,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
5009 } 5001 }
5010 } 5002 }
5011 5003
5012 mutex_lock(&cfg80211_mutex);
5013
5014 r = set_regdom(rd); 5004 r = set_regdom(rd);
5015 /* set_regdom took ownership */ 5005 /* set_regdom took ownership */
5016 rd = NULL; 5006 rd = NULL;
5017 mutex_unlock(&cfg80211_mutex);
5018 5007
5019 bad_reg: 5008 bad_reg:
5020 kfree(rd); 5009 kfree(rd);
@@ -5064,7 +5053,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5064 if (!rdev->ops->scan) 5053 if (!rdev->ops->scan)
5065 return -EOPNOTSUPP; 5054 return -EOPNOTSUPP;
5066 5055
5067 mutex_lock(&rdev->sched_scan_mtx);
5068 if (rdev->scan_req) { 5056 if (rdev->scan_req) {
5069 err = -EBUSY; 5057 err = -EBUSY;
5070 goto unlock; 5058 goto unlock;
@@ -5250,7 +5238,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5250 } 5238 }
5251 5239
5252 unlock: 5240 unlock:
5253 mutex_unlock(&rdev->sched_scan_mtx);
5254 return err; 5241 return err;
5255} 5242}
5256 5243
@@ -5322,8 +5309,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
5322 if (ie_len > wiphy->max_sched_scan_ie_len) 5309 if (ie_len > wiphy->max_sched_scan_ie_len)
5323 return -EINVAL; 5310 return -EINVAL;
5324 5311
5325 mutex_lock(&rdev->sched_scan_mtx);
5326
5327 if (rdev->sched_scan_req) { 5312 if (rdev->sched_scan_req) {
5328 err = -EINPROGRESS; 5313 err = -EINPROGRESS;
5329 goto out; 5314 goto out;
@@ -5491,7 +5476,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
5491out_free: 5476out_free:
5492 kfree(request); 5477 kfree(request);
5493out: 5478out:
5494 mutex_unlock(&rdev->sched_scan_mtx);
5495 return err; 5479 return err;
5496} 5480}
5497 5481
@@ -5499,17 +5483,12 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb,
5499 struct genl_info *info) 5483 struct genl_info *info)
5500{ 5484{
5501 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 5485 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5502 int err;
5503 5486
5504 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || 5487 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
5505 !rdev->ops->sched_scan_stop) 5488 !rdev->ops->sched_scan_stop)
5506 return -EOPNOTSUPP; 5489 return -EOPNOTSUPP;
5507 5490
5508 mutex_lock(&rdev->sched_scan_mtx); 5491 return __cfg80211_stop_sched_scan(rdev, false);
5509 err = __cfg80211_stop_sched_scan(rdev, false);
5510 mutex_unlock(&rdev->sched_scan_mtx);
5511
5512 return err;
5513} 5492}
5514 5493
5515static int nl80211_start_radar_detection(struct sk_buff *skb, 5494static int nl80211_start_radar_detection(struct sk_buff *skb,
@@ -5541,12 +5520,11 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
5541 if (!rdev->ops->start_radar_detection) 5520 if (!rdev->ops->start_radar_detection)
5542 return -EOPNOTSUPP; 5521 return -EOPNOTSUPP;
5543 5522
5544 mutex_lock(&rdev->devlist_mtx);
5545 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 5523 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
5546 chandef.chan, CHAN_MODE_SHARED, 5524 chandef.chan, CHAN_MODE_SHARED,
5547 BIT(chandef.width)); 5525 BIT(chandef.width));
5548 if (err) 5526 if (err)
5549 goto err_locked; 5527 return err;
5550 5528
5551 err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef); 5529 err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
5552 if (!err) { 5530 if (!err) {
@@ -5554,9 +5532,6 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
5554 wdev->cac_started = true; 5532 wdev->cac_started = true;
5555 wdev->cac_start_time = jiffies; 5533 wdev->cac_start_time = jiffies;
5556 } 5534 }
5557err_locked:
5558 mutex_unlock(&rdev->devlist_mtx);
5559
5560 return err; 5535 return err;
5561} 5536}
5562 5537
@@ -5939,10 +5914,13 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
5939 if (local_state_change) 5914 if (local_state_change)
5940 return 0; 5915 return 0;
5941 5916
5942 return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 5917 wdev_lock(dev->ieee80211_ptr);
5943 ssid, ssid_len, ie, ie_len, 5918 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
5944 key.p.key, key.p.key_len, key.idx, 5919 ssid, ssid_len, ie, ie_len,
5945 sae_data, sae_data_len); 5920 key.p.key, key.p.key_len, key.idx,
5921 sae_data, sae_data_len);
5922 wdev_unlock(dev->ieee80211_ptr);
5923 return err;
5946} 5924}
5947 5925
5948static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, 5926static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
@@ -6109,9 +6087,12 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
6109 } 6087 }
6110 6088
6111 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1); 6089 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
6112 if (!err) 6090 if (!err) {
6091 wdev_lock(dev->ieee80211_ptr);
6113 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, 6092 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
6114 ssid, ssid_len, &req); 6093 ssid, ssid_len, &req);
6094 wdev_unlock(dev->ieee80211_ptr);
6095 }
6115 6096
6116 return err; 6097 return err;
6117} 6098}
@@ -6121,7 +6102,7 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
6121 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6102 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6122 struct net_device *dev = info->user_ptr[1]; 6103 struct net_device *dev = info->user_ptr[1];
6123 const u8 *ie = NULL, *bssid; 6104 const u8 *ie = NULL, *bssid;
6124 int ie_len = 0; 6105 int ie_len = 0, err;
6125 u16 reason_code; 6106 u16 reason_code;
6126 bool local_state_change; 6107 bool local_state_change;
6127 6108
@@ -6156,8 +6137,11 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
6156 6137
6157 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; 6138 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
6158 6139
6159 return cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, 6140 wdev_lock(dev->ieee80211_ptr);
6160 local_state_change); 6141 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
6142 local_state_change);
6143 wdev_unlock(dev->ieee80211_ptr);
6144 return err;
6161} 6145}
6162 6146
6163static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) 6147static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
@@ -6165,7 +6149,7 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
6165 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6149 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6166 struct net_device *dev = info->user_ptr[1]; 6150 struct net_device *dev = info->user_ptr[1];
6167 const u8 *ie = NULL, *bssid; 6151 const u8 *ie = NULL, *bssid;
6168 int ie_len = 0; 6152 int ie_len = 0, err;
6169 u16 reason_code; 6153 u16 reason_code;
6170 bool local_state_change; 6154 bool local_state_change;
6171 6155
@@ -6200,8 +6184,11 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
6200 6184
6201 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; 6185 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
6202 6186
6203 return cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, 6187 wdev_lock(dev->ieee80211_ptr);
6204 local_state_change); 6188 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
6189 local_state_change);
6190 wdev_unlock(dev->ieee80211_ptr);
6191 return err;
6205} 6192}
6206 6193
6207static bool 6194static bool
@@ -6419,6 +6406,8 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6419 void *data = NULL; 6406 void *data = NULL;
6420 int data_len = 0; 6407 int data_len = 0;
6421 6408
6409 rtnl_lock();
6410
6422 if (cb->args[0]) { 6411 if (cb->args[0]) {
6423 /* 6412 /*
6424 * 0 is a valid index, but not valid for args[0], 6413 * 0 is a valid index, but not valid for args[0],
@@ -6430,18 +6419,16 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6430 nl80211_fam.attrbuf, nl80211_fam.maxattr, 6419 nl80211_fam.attrbuf, nl80211_fam.maxattr,
6431 nl80211_policy); 6420 nl80211_policy);
6432 if (err) 6421 if (err)
6433 return err; 6422 goto out_err;
6434 6423
6435 mutex_lock(&cfg80211_mutex);
6436 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), 6424 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
6437 nl80211_fam.attrbuf); 6425 nl80211_fam.attrbuf);
6438 if (IS_ERR(rdev)) { 6426 if (IS_ERR(rdev)) {
6439 mutex_unlock(&cfg80211_mutex); 6427 err = PTR_ERR(rdev);
6440 return PTR_ERR(rdev); 6428 goto out_err;
6441 } 6429 }
6442 phy_idx = rdev->wiphy_idx; 6430 phy_idx = rdev->wiphy_idx;
6443 rdev = NULL; 6431 rdev = NULL;
6444 mutex_unlock(&cfg80211_mutex);
6445 6432
6446 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) 6433 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
6447 cb->args[1] = 6434 cb->args[1] =
@@ -6453,14 +6440,11 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6453 data_len = nla_len((void *)cb->args[1]); 6440 data_len = nla_len((void *)cb->args[1]);
6454 } 6441 }
6455 6442
6456 mutex_lock(&cfg80211_mutex);
6457 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx); 6443 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
6458 if (!rdev) { 6444 if (!rdev) {
6459 mutex_unlock(&cfg80211_mutex); 6445 err = -ENOENT;
6460 return -ENOENT; 6446 goto out_err;
6461 } 6447 }
6462 cfg80211_lock_rdev(rdev);
6463 mutex_unlock(&cfg80211_mutex);
6464 6448
6465 if (!rdev->ops->testmode_dump) { 6449 if (!rdev->ops->testmode_dump) {
6466 err = -EOPNOTSUPP; 6450 err = -EOPNOTSUPP;
@@ -6501,7 +6485,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6501 /* see above */ 6485 /* see above */
6502 cb->args[0] = phy_idx + 1; 6486 cb->args[0] = phy_idx + 1;
6503 out_err: 6487 out_err:
6504 cfg80211_unlock_rdev(rdev); 6488 rtnl_unlock();
6505 return err; 6489 return err;
6506} 6490}
6507 6491
@@ -6709,7 +6693,9 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
6709 sizeof(connect.vht_capa)); 6693 sizeof(connect.vht_capa));
6710 } 6694 }
6711 6695
6712 err = cfg80211_connect(rdev, dev, &connect, connkeys); 6696 wdev_lock(dev->ieee80211_ptr);
6697 err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL);
6698 wdev_unlock(dev->ieee80211_ptr);
6713 if (err) 6699 if (err)
6714 kfree(connkeys); 6700 kfree(connkeys);
6715 return err; 6701 return err;
@@ -6720,6 +6706,7 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
6720 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6706 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6721 struct net_device *dev = info->user_ptr[1]; 6707 struct net_device *dev = info->user_ptr[1];
6722 u16 reason; 6708 u16 reason;
6709 int ret;
6723 6710
6724 if (!info->attrs[NL80211_ATTR_REASON_CODE]) 6711 if (!info->attrs[NL80211_ATTR_REASON_CODE])
6725 reason = WLAN_REASON_DEAUTH_LEAVING; 6712 reason = WLAN_REASON_DEAUTH_LEAVING;
@@ -6733,7 +6720,10 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
6733 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) 6720 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
6734 return -EOPNOTSUPP; 6721 return -EOPNOTSUPP;
6735 6722
6736 return cfg80211_disconnect(rdev, dev, reason, true); 6723 wdev_lock(dev->ieee80211_ptr);
6724 ret = cfg80211_disconnect(rdev, dev, reason, true);
6725 wdev_unlock(dev->ieee80211_ptr);
6726 return ret;
6737} 6727}
6738 6728
6739static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) 6729static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
@@ -7509,28 +7499,29 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
7509static int nl80211_send_wowlan_patterns(struct sk_buff *msg, 7499static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
7510 struct cfg80211_registered_device *rdev) 7500 struct cfg80211_registered_device *rdev)
7511{ 7501{
7502 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
7512 struct nlattr *nl_pats, *nl_pat; 7503 struct nlattr *nl_pats, *nl_pat;
7513 int i, pat_len; 7504 int i, pat_len;
7514 7505
7515 if (!rdev->wowlan->n_patterns) 7506 if (!wowlan->n_patterns)
7516 return 0; 7507 return 0;
7517 7508
7518 nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN); 7509 nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
7519 if (!nl_pats) 7510 if (!nl_pats)
7520 return -ENOBUFS; 7511 return -ENOBUFS;
7521 7512
7522 for (i = 0; i < rdev->wowlan->n_patterns; i++) { 7513 for (i = 0; i < wowlan->n_patterns; i++) {
7523 nl_pat = nla_nest_start(msg, i + 1); 7514 nl_pat = nla_nest_start(msg, i + 1);
7524 if (!nl_pat) 7515 if (!nl_pat)
7525 return -ENOBUFS; 7516 return -ENOBUFS;
7526 pat_len = rdev->wowlan->patterns[i].pattern_len; 7517 pat_len = wowlan->patterns[i].pattern_len;
7527 if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK, 7518 if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
7528 DIV_ROUND_UP(pat_len, 8), 7519 DIV_ROUND_UP(pat_len, 8),
7529 rdev->wowlan->patterns[i].mask) || 7520 wowlan->patterns[i].mask) ||
7530 nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN, 7521 nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
7531 pat_len, rdev->wowlan->patterns[i].pattern) || 7522 pat_len, wowlan->patterns[i].pattern) ||
7532 nla_put_u32(msg, NL80211_WOWLAN_PKTPAT_OFFSET, 7523 nla_put_u32(msg, NL80211_WOWLAN_PKTPAT_OFFSET,
7533 rdev->wowlan->patterns[i].pkt_offset)) 7524 wowlan->patterns[i].pkt_offset))
7534 return -ENOBUFS; 7525 return -ENOBUFS;
7535 nla_nest_end(msg, nl_pat); 7526 nla_nest_end(msg, nl_pat);
7536 } 7527 }
@@ -7593,12 +7584,12 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
7593 !rdev->wiphy.wowlan.tcp) 7584 !rdev->wiphy.wowlan.tcp)
7594 return -EOPNOTSUPP; 7585 return -EOPNOTSUPP;
7595 7586
7596 if (rdev->wowlan && rdev->wowlan->tcp) { 7587 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
7597 /* adjust size to have room for all the data */ 7588 /* adjust size to have room for all the data */
7598 size += rdev->wowlan->tcp->tokens_size + 7589 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
7599 rdev->wowlan->tcp->payload_len + 7590 rdev->wiphy.wowlan_config->tcp->payload_len +
7600 rdev->wowlan->tcp->wake_len + 7591 rdev->wiphy.wowlan_config->tcp->wake_len +
7601 rdev->wowlan->tcp->wake_len / 8; 7592 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
7602 } 7593 }
7603 7594
7604 msg = nlmsg_new(size, GFP_KERNEL); 7595 msg = nlmsg_new(size, GFP_KERNEL);
@@ -7610,33 +7601,34 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
7610 if (!hdr) 7601 if (!hdr)
7611 goto nla_put_failure; 7602 goto nla_put_failure;
7612 7603
7613 if (rdev->wowlan) { 7604 if (rdev->wiphy.wowlan_config) {
7614 struct nlattr *nl_wowlan; 7605 struct nlattr *nl_wowlan;
7615 7606
7616 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); 7607 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
7617 if (!nl_wowlan) 7608 if (!nl_wowlan)
7618 goto nla_put_failure; 7609 goto nla_put_failure;
7619 7610
7620 if ((rdev->wowlan->any && 7611 if ((rdev->wiphy.wowlan_config->any &&
7621 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) || 7612 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
7622 (rdev->wowlan->disconnect && 7613 (rdev->wiphy.wowlan_config->disconnect &&
7623 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) || 7614 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
7624 (rdev->wowlan->magic_pkt && 7615 (rdev->wiphy.wowlan_config->magic_pkt &&
7625 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) || 7616 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
7626 (rdev->wowlan->gtk_rekey_failure && 7617 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
7627 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) || 7618 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
7628 (rdev->wowlan->eap_identity_req && 7619 (rdev->wiphy.wowlan_config->eap_identity_req &&
7629 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) || 7620 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
7630 (rdev->wowlan->four_way_handshake && 7621 (rdev->wiphy.wowlan_config->four_way_handshake &&
7631 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) || 7622 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
7632 (rdev->wowlan->rfkill_release && 7623 (rdev->wiphy.wowlan_config->rfkill_release &&
7633 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) 7624 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
7634 goto nla_put_failure; 7625 goto nla_put_failure;
7635 7626
7636 if (nl80211_send_wowlan_patterns(msg, rdev)) 7627 if (nl80211_send_wowlan_patterns(msg, rdev))
7637 goto nla_put_failure; 7628 goto nla_put_failure;
7638 7629
7639 if (nl80211_send_wowlan_tcp(msg, rdev->wowlan->tcp)) 7630 if (nl80211_send_wowlan_tcp(msg,
7631 rdev->wiphy.wowlan_config->tcp))
7640 goto nla_put_failure; 7632 goto nla_put_failure;
7641 7633
7642 nla_nest_end(msg, nl_wowlan); 7634 nla_nest_end(msg, nl_wowlan);
@@ -7803,7 +7795,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7803 struct cfg80211_wowlan *ntrig; 7795 struct cfg80211_wowlan *ntrig;
7804 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; 7796 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan;
7805 int err, i; 7797 int err, i;
7806 bool prev_enabled = rdev->wowlan; 7798 bool prev_enabled = rdev->wiphy.wowlan_config;
7807 7799
7808 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns && 7800 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns &&
7809 !rdev->wiphy.wowlan.tcp) 7801 !rdev->wiphy.wowlan.tcp)
@@ -7811,7 +7803,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7811 7803
7812 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { 7804 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
7813 cfg80211_rdev_free_wowlan(rdev); 7805 cfg80211_rdev_free_wowlan(rdev);
7814 rdev->wowlan = NULL; 7806 rdev->wiphy.wowlan_config = NULL;
7815 goto set_wakeup; 7807 goto set_wakeup;
7816 } 7808 }
7817 7809
@@ -7947,11 +7939,12 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7947 goto error; 7939 goto error;
7948 } 7940 }
7949 cfg80211_rdev_free_wowlan(rdev); 7941 cfg80211_rdev_free_wowlan(rdev);
7950 rdev->wowlan = ntrig; 7942 rdev->wiphy.wowlan_config = ntrig;
7951 7943
7952 set_wakeup: 7944 set_wakeup:
7953 if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan) 7945 if (rdev->ops->set_wakeup &&
7954 rdev_set_wakeup(rdev, rdev->wowlan); 7946 prev_enabled != !!rdev->wiphy.wowlan_config)
7947 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
7955 7948
7956 return 0; 7949 return 0;
7957 error: 7950 error:
@@ -8136,9 +8129,7 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
8136 if (wdev->p2p_started) 8129 if (wdev->p2p_started)
8137 return 0; 8130 return 0;
8138 8131
8139 mutex_lock(&rdev->devlist_mtx);
8140 err = cfg80211_can_add_interface(rdev, wdev->iftype); 8132 err = cfg80211_can_add_interface(rdev, wdev->iftype);
8141 mutex_unlock(&rdev->devlist_mtx);
8142 if (err) 8133 if (err)
8143 return err; 8134 return err;
8144 8135
@@ -8147,9 +8138,7 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
8147 return err; 8138 return err;
8148 8139
8149 wdev->p2p_started = true; 8140 wdev->p2p_started = true;
8150 mutex_lock(&rdev->devlist_mtx);
8151 rdev->opencount++; 8141 rdev->opencount++;
8152 mutex_unlock(&rdev->devlist_mtx);
8153 8142
8154 return 0; 8143 return 0;
8155} 8144}
@@ -8165,11 +8154,7 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
8165 if (!rdev->ops->stop_p2p_device) 8154 if (!rdev->ops->stop_p2p_device)
8166 return -EOPNOTSUPP; 8155 return -EOPNOTSUPP;
8167 8156
8168 mutex_lock(&rdev->devlist_mtx);
8169 mutex_lock(&rdev->sched_scan_mtx);
8170 cfg80211_stop_p2p_device(rdev, wdev); 8157 cfg80211_stop_p2p_device(rdev, wdev);
8171 mutex_unlock(&rdev->sched_scan_mtx);
8172 mutex_unlock(&rdev->devlist_mtx);
8173 8158
8174 return 0; 8159 return 0;
8175} 8160}
@@ -8312,11 +8297,11 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8312 info->user_ptr[0] = rdev; 8297 info->user_ptr[0] = rdev;
8313 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV || 8298 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
8314 ops->internal_flags & NL80211_FLAG_NEED_WDEV) { 8299 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
8315 mutex_lock(&cfg80211_mutex); 8300 ASSERT_RTNL();
8301
8316 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info), 8302 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
8317 info->attrs); 8303 info->attrs);
8318 if (IS_ERR(wdev)) { 8304 if (IS_ERR(wdev)) {
8319 mutex_unlock(&cfg80211_mutex);
8320 if (rtnl) 8305 if (rtnl)
8321 rtnl_unlock(); 8306 rtnl_unlock();
8322 return PTR_ERR(wdev); 8307 return PTR_ERR(wdev);
@@ -8327,7 +8312,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8327 8312
8328 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { 8313 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
8329 if (!dev) { 8314 if (!dev) {
8330 mutex_unlock(&cfg80211_mutex);
8331 if (rtnl) 8315 if (rtnl)
8332 rtnl_unlock(); 8316 rtnl_unlock();
8333 return -EINVAL; 8317 return -EINVAL;
@@ -8341,7 +8325,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8341 if (dev) { 8325 if (dev) {
8342 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && 8326 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
8343 !netif_running(dev)) { 8327 !netif_running(dev)) {
8344 mutex_unlock(&cfg80211_mutex);
8345 if (rtnl) 8328 if (rtnl)
8346 rtnl_unlock(); 8329 rtnl_unlock();
8347 return -ENETDOWN; 8330 return -ENETDOWN;
@@ -8350,17 +8333,12 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8350 dev_hold(dev); 8333 dev_hold(dev);
8351 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) { 8334 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) {
8352 if (!wdev->p2p_started) { 8335 if (!wdev->p2p_started) {
8353 mutex_unlock(&cfg80211_mutex);
8354 if (rtnl) 8336 if (rtnl)
8355 rtnl_unlock(); 8337 rtnl_unlock();
8356 return -ENETDOWN; 8338 return -ENETDOWN;
8357 } 8339 }
8358 } 8340 }
8359 8341
8360 cfg80211_lock_rdev(rdev);
8361
8362 mutex_unlock(&cfg80211_mutex);
8363
8364 info->user_ptr[0] = rdev; 8342 info->user_ptr[0] = rdev;
8365 } 8343 }
8366 8344
@@ -8370,8 +8348,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8370static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, 8348static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
8371 struct genl_info *info) 8349 struct genl_info *info)
8372{ 8350{
8373 if (info->user_ptr[0])
8374 cfg80211_unlock_rdev(info->user_ptr[0]);
8375 if (info->user_ptr[1]) { 8351 if (info->user_ptr[1]) {
8376 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) { 8352 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
8377 struct wireless_dev *wdev = info->user_ptr[1]; 8353 struct wireless_dev *wdev = info->user_ptr[1];
@@ -8393,7 +8369,8 @@ static struct genl_ops nl80211_ops[] = {
8393 .dumpit = nl80211_dump_wiphy, 8369 .dumpit = nl80211_dump_wiphy,
8394 .policy = nl80211_policy, 8370 .policy = nl80211_policy,
8395 /* can be retrieved by unprivileged users */ 8371 /* can be retrieved by unprivileged users */
8396 .internal_flags = NL80211_FLAG_NEED_WIPHY, 8372 .internal_flags = NL80211_FLAG_NEED_WIPHY |
8373 NL80211_FLAG_NEED_RTNL,
8397 }, 8374 },
8398 { 8375 {
8399 .cmd = NL80211_CMD_SET_WIPHY, 8376 .cmd = NL80211_CMD_SET_WIPHY,
@@ -8408,7 +8385,8 @@ static struct genl_ops nl80211_ops[] = {
8408 .dumpit = nl80211_dump_interface, 8385 .dumpit = nl80211_dump_interface,
8409 .policy = nl80211_policy, 8386 .policy = nl80211_policy,
8410 /* can be retrieved by unprivileged users */ 8387 /* can be retrieved by unprivileged users */
8411 .internal_flags = NL80211_FLAG_NEED_WDEV, 8388 .internal_flags = NL80211_FLAG_NEED_WDEV |
8389 NL80211_FLAG_NEED_RTNL,
8412 }, 8390 },
8413 { 8391 {
8414 .cmd = NL80211_CMD_SET_INTERFACE, 8392 .cmd = NL80211_CMD_SET_INTERFACE,
@@ -8567,6 +8545,7 @@ static struct genl_ops nl80211_ops[] = {
8567 .cmd = NL80211_CMD_GET_REG, 8545 .cmd = NL80211_CMD_GET_REG,
8568 .doit = nl80211_get_reg, 8546 .doit = nl80211_get_reg,
8569 .policy = nl80211_policy, 8547 .policy = nl80211_policy,
8548 .internal_flags = NL80211_FLAG_NEED_RTNL,
8570 /* can be retrieved by unprivileged users */ 8549 /* can be retrieved by unprivileged users */
8571 }, 8550 },
8572 { 8551 {
@@ -8574,6 +8553,7 @@ static struct genl_ops nl80211_ops[] = {
8574 .doit = nl80211_set_reg, 8553 .doit = nl80211_set_reg,
8575 .policy = nl80211_policy, 8554 .policy = nl80211_policy,
8576 .flags = GENL_ADMIN_PERM, 8555 .flags = GENL_ADMIN_PERM,
8556 .internal_flags = NL80211_FLAG_NEED_RTNL,
8577 }, 8557 },
8578 { 8558 {
8579 .cmd = NL80211_CMD_REQ_SET_REG, 8559 .cmd = NL80211_CMD_REQ_SET_REG,
@@ -9029,8 +9009,6 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
9029 struct nlattr *nest; 9009 struct nlattr *nest;
9030 int i; 9010 int i;
9031 9011
9032 lockdep_assert_held(&rdev->sched_scan_mtx);
9033
9034 if (WARN_ON(!req)) 9012 if (WARN_ON(!req))
9035 return 0; 9013 return 0;
9036 9014
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index cc35fbaa4578..e1d6749234c6 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -81,7 +81,10 @@ static struct regulatory_request core_request_world = {
81 .country_ie_env = ENVIRON_ANY, 81 .country_ie_env = ENVIRON_ANY,
82}; 82};
83 83
84/* Receipt of information from last regulatory request */ 84/*
85 * Receipt of information from last regulatory request,
86 * protected by RTNL (and can be accessed with RCU protection)
87 */
85static struct regulatory_request __rcu *last_request = 88static struct regulatory_request __rcu *last_request =
86 (void __rcu *)&core_request_world; 89 (void __rcu *)&core_request_world;
87 90
@@ -96,39 +99,25 @@ static struct device_type reg_device_type = {
96 * Central wireless core regulatory domains, we only need two, 99 * Central wireless core regulatory domains, we only need two,
97 * the current one and a world regulatory domain in case we have no 100 * the current one and a world regulatory domain in case we have no
98 * information to give us an alpha2. 101 * information to give us an alpha2.
102 * (protected by RTNL, can be read under RCU)
99 */ 103 */
100const struct ieee80211_regdomain __rcu *cfg80211_regdomain; 104const struct ieee80211_regdomain __rcu *cfg80211_regdomain;
101 105
102/* 106/*
103 * Protects static reg.c components:
104 * - cfg80211_regdomain (if not used with RCU)
105 * - cfg80211_world_regdom
106 * - last_request (if not used with RCU)
107 * - reg_num_devs_support_basehint
108 */
109static DEFINE_MUTEX(reg_mutex);
110
111/*
112 * Number of devices that registered to the core 107 * Number of devices that registered to the core
113 * that support cellular base station regulatory hints 108 * that support cellular base station regulatory hints
109 * (protected by RTNL)
114 */ 110 */
115static int reg_num_devs_support_basehint; 111static int reg_num_devs_support_basehint;
116 112
117static inline void assert_reg_lock(void)
118{
119 lockdep_assert_held(&reg_mutex);
120}
121
122static const struct ieee80211_regdomain *get_cfg80211_regdom(void) 113static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
123{ 114{
124 return rcu_dereference_protected(cfg80211_regdomain, 115 return rtnl_dereference(cfg80211_regdomain);
125 lockdep_is_held(&reg_mutex));
126} 116}
127 117
128static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy) 118static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
129{ 119{
130 return rcu_dereference_protected(wiphy->regd, 120 return rtnl_dereference(wiphy->regd);
131 lockdep_is_held(&reg_mutex));
132} 121}
133 122
134static void rcu_free_regdom(const struct ieee80211_regdomain *r) 123static void rcu_free_regdom(const struct ieee80211_regdomain *r)
@@ -140,8 +129,7 @@ static void rcu_free_regdom(const struct ieee80211_regdomain *r)
140 129
141static struct regulatory_request *get_last_request(void) 130static struct regulatory_request *get_last_request(void)
142{ 131{
143 return rcu_dereference_check(last_request, 132 return rcu_dereference_rtnl(last_request);
144 lockdep_is_held(&reg_mutex));
145} 133}
146 134
147/* Used to queue up regulatory hints */ 135/* Used to queue up regulatory hints */
@@ -200,6 +188,7 @@ static const struct ieee80211_regdomain world_regdom = {
200 } 188 }
201}; 189};
202 190
191/* protected by RTNL */
203static const struct ieee80211_regdomain *cfg80211_world_regdom = 192static const struct ieee80211_regdomain *cfg80211_world_regdom =
204 &world_regdom; 193 &world_regdom;
205 194
@@ -215,7 +204,7 @@ static void reset_regdomains(bool full_reset,
215 const struct ieee80211_regdomain *r; 204 const struct ieee80211_regdomain *r;
216 struct regulatory_request *lr; 205 struct regulatory_request *lr;
217 206
218 assert_reg_lock(); 207 ASSERT_RTNL();
219 208
220 r = get_cfg80211_regdom(); 209 r = get_cfg80211_regdom();
221 210
@@ -377,7 +366,7 @@ static void reg_regdb_search(struct work_struct *work)
377 const struct ieee80211_regdomain *curdom, *regdom = NULL; 366 const struct ieee80211_regdomain *curdom, *regdom = NULL;
378 int i; 367 int i;
379 368
380 mutex_lock(&cfg80211_mutex); 369 rtnl_lock();
381 370
382 mutex_lock(&reg_regdb_search_mutex); 371 mutex_lock(&reg_regdb_search_mutex);
383 while (!list_empty(&reg_regdb_search_list)) { 372 while (!list_empty(&reg_regdb_search_list)) {
@@ -402,7 +391,7 @@ static void reg_regdb_search(struct work_struct *work)
402 if (!IS_ERR_OR_NULL(regdom)) 391 if (!IS_ERR_OR_NULL(regdom))
403 set_regdom(regdom); 392 set_regdom(regdom);
404 393
405 mutex_unlock(&cfg80211_mutex); 394 rtnl_unlock();
406} 395}
407 396
408static DECLARE_WORK(reg_regdb_work, reg_regdb_search); 397static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
@@ -936,13 +925,7 @@ static bool reg_request_cell_base(struct regulatory_request *request)
936 925
937bool reg_last_request_cell_base(void) 926bool reg_last_request_cell_base(void)
938{ 927{
939 bool val; 928 return reg_request_cell_base(get_last_request());
940
941 mutex_lock(&reg_mutex);
942 val = reg_request_cell_base(get_last_request());
943 mutex_unlock(&reg_mutex);
944
945 return val;
946} 929}
947 930
948#ifdef CONFIG_CFG80211_CERTIFICATION_ONUS 931#ifdef CONFIG_CFG80211_CERTIFICATION_ONUS
@@ -1225,7 +1208,7 @@ static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
1225 struct cfg80211_registered_device *rdev; 1208 struct cfg80211_registered_device *rdev;
1226 struct wiphy *wiphy; 1209 struct wiphy *wiphy;
1227 1210
1228 assert_cfg80211_lock(); 1211 ASSERT_RTNL();
1229 1212
1230 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 1213 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1231 wiphy = &rdev->wiphy; 1214 wiphy = &rdev->wiphy;
@@ -1444,8 +1427,6 @@ static void reg_set_request_processed(void)
1444 * what it believes should be the current regulatory domain. 1427 * what it believes should be the current regulatory domain.
1445 * 1428 *
1446 * Returns one of the different reg request treatment values. 1429 * Returns one of the different reg request treatment values.
1447 *
1448 * Caller must hold &reg_mutex
1449 */ 1430 */
1450static enum reg_request_treatment 1431static enum reg_request_treatment
1451__regulatory_hint(struct wiphy *wiphy, 1432__regulatory_hint(struct wiphy *wiphy,
@@ -1570,21 +1551,19 @@ static void reg_process_pending_hints(void)
1570{ 1551{
1571 struct regulatory_request *reg_request, *lr; 1552 struct regulatory_request *reg_request, *lr;
1572 1553
1573 mutex_lock(&cfg80211_mutex);
1574 mutex_lock(&reg_mutex);
1575 lr = get_last_request(); 1554 lr = get_last_request();
1576 1555
1577 /* When last_request->processed becomes true this will be rescheduled */ 1556 /* When last_request->processed becomes true this will be rescheduled */
1578 if (lr && !lr->processed) { 1557 if (lr && !lr->processed) {
1579 REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n"); 1558 REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n");
1580 goto out; 1559 return;
1581 } 1560 }
1582 1561
1583 spin_lock(&reg_requests_lock); 1562 spin_lock(&reg_requests_lock);
1584 1563
1585 if (list_empty(&reg_requests_list)) { 1564 if (list_empty(&reg_requests_list)) {
1586 spin_unlock(&reg_requests_lock); 1565 spin_unlock(&reg_requests_lock);
1587 goto out; 1566 return;
1588 } 1567 }
1589 1568
1590 reg_request = list_first_entry(&reg_requests_list, 1569 reg_request = list_first_entry(&reg_requests_list,
@@ -1595,10 +1574,6 @@ static void reg_process_pending_hints(void)
1595 spin_unlock(&reg_requests_lock); 1574 spin_unlock(&reg_requests_lock);
1596 1575
1597 reg_process_hint(reg_request, reg_request->initiator); 1576 reg_process_hint(reg_request, reg_request->initiator);
1598
1599out:
1600 mutex_unlock(&reg_mutex);
1601 mutex_unlock(&cfg80211_mutex);
1602} 1577}
1603 1578
1604/* Processes beacon hints -- this has nothing to do with country IEs */ 1579/* Processes beacon hints -- this has nothing to do with country IEs */
@@ -1607,9 +1582,6 @@ static void reg_process_pending_beacon_hints(void)
1607 struct cfg80211_registered_device *rdev; 1582 struct cfg80211_registered_device *rdev;
1608 struct reg_beacon *pending_beacon, *tmp; 1583 struct reg_beacon *pending_beacon, *tmp;
1609 1584
1610 mutex_lock(&cfg80211_mutex);
1611 mutex_lock(&reg_mutex);
1612
1613 /* This goes through the _pending_ beacon list */ 1585 /* This goes through the _pending_ beacon list */
1614 spin_lock_bh(&reg_pending_beacons_lock); 1586 spin_lock_bh(&reg_pending_beacons_lock);
1615 1587
@@ -1626,14 +1598,14 @@ static void reg_process_pending_beacon_hints(void)
1626 } 1598 }
1627 1599
1628 spin_unlock_bh(&reg_pending_beacons_lock); 1600 spin_unlock_bh(&reg_pending_beacons_lock);
1629 mutex_unlock(&reg_mutex);
1630 mutex_unlock(&cfg80211_mutex);
1631} 1601}
1632 1602
1633static void reg_todo(struct work_struct *work) 1603static void reg_todo(struct work_struct *work)
1634{ 1604{
1605 rtnl_lock();
1635 reg_process_pending_hints(); 1606 reg_process_pending_hints();
1636 reg_process_pending_beacon_hints(); 1607 reg_process_pending_beacon_hints();
1608 rtnl_unlock();
1637} 1609}
1638 1610
1639static void queue_regulatory_request(struct regulatory_request *request) 1611static void queue_regulatory_request(struct regulatory_request *request)
@@ -1717,29 +1689,23 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
1717} 1689}
1718EXPORT_SYMBOL(regulatory_hint); 1690EXPORT_SYMBOL(regulatory_hint);
1719 1691
1720/*
1721 * We hold wdev_lock() here so we cannot hold cfg80211_mutex() and
1722 * therefore cannot iterate over the rdev list here.
1723 */
1724void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band, 1692void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1725 const u8 *country_ie, u8 country_ie_len) 1693 const u8 *country_ie, u8 country_ie_len)
1726{ 1694{
1727 char alpha2[2]; 1695 char alpha2[2];
1728 enum environment_cap env = ENVIRON_ANY; 1696 enum environment_cap env = ENVIRON_ANY;
1729 struct regulatory_request *request, *lr; 1697 struct regulatory_request *request = NULL, *lr;
1730
1731 mutex_lock(&reg_mutex);
1732 lr = get_last_request();
1733
1734 if (unlikely(!lr))
1735 goto out;
1736 1698
1737 /* IE len must be evenly divisible by 2 */ 1699 /* IE len must be evenly divisible by 2 */
1738 if (country_ie_len & 0x01) 1700 if (country_ie_len & 0x01)
1739 goto out; 1701 return;
1740 1702
1741 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) 1703 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
1742 goto out; 1704 return;
1705
1706 request = kzalloc(sizeof(*request), GFP_KERNEL);
1707 if (!request)
1708 return;
1743 1709
1744 alpha2[0] = country_ie[0]; 1710 alpha2[0] = country_ie[0];
1745 alpha2[1] = country_ie[1]; 1711 alpha2[1] = country_ie[1];
@@ -1749,19 +1715,21 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1749 else if (country_ie[2] == 'O') 1715 else if (country_ie[2] == 'O')
1750 env = ENVIRON_OUTDOOR; 1716 env = ENVIRON_OUTDOOR;
1751 1717
1718 rcu_read_lock();
1719 lr = get_last_request();
1720
1721 if (unlikely(!lr))
1722 goto out;
1723
1752 /* 1724 /*
1753 * We will run this only upon a successful connection on cfg80211. 1725 * We will run this only upon a successful connection on cfg80211.
1754 * We leave conflict resolution to the workqueue, where can hold 1726 * We leave conflict resolution to the workqueue, where can hold
1755 * cfg80211_mutex. 1727 * the RTNL.
1756 */ 1728 */
1757 if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && 1729 if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1758 lr->wiphy_idx != WIPHY_IDX_INVALID) 1730 lr->wiphy_idx != WIPHY_IDX_INVALID)
1759 goto out; 1731 goto out;
1760 1732
1761 request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL);
1762 if (!request)
1763 goto out;
1764
1765 request->wiphy_idx = get_wiphy_idx(wiphy); 1733 request->wiphy_idx = get_wiphy_idx(wiphy);
1766 request->alpha2[0] = alpha2[0]; 1734 request->alpha2[0] = alpha2[0];
1767 request->alpha2[1] = alpha2[1]; 1735 request->alpha2[1] = alpha2[1];
@@ -1769,8 +1737,10 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1769 request->country_ie_env = env; 1737 request->country_ie_env = env;
1770 1738
1771 queue_regulatory_request(request); 1739 queue_regulatory_request(request);
1740 request = NULL;
1772out: 1741out:
1773 mutex_unlock(&reg_mutex); 1742 kfree(request);
1743 rcu_read_unlock();
1774} 1744}
1775 1745
1776static void restore_alpha2(char *alpha2, bool reset_user) 1746static void restore_alpha2(char *alpha2, bool reset_user)
@@ -1858,8 +1828,7 @@ static void restore_regulatory_settings(bool reset_user)
1858 LIST_HEAD(tmp_reg_req_list); 1828 LIST_HEAD(tmp_reg_req_list);
1859 struct cfg80211_registered_device *rdev; 1829 struct cfg80211_registered_device *rdev;
1860 1830
1861 mutex_lock(&cfg80211_mutex); 1831 ASSERT_RTNL();
1862 mutex_lock(&reg_mutex);
1863 1832
1864 reset_regdomains(true, &world_regdom); 1833 reset_regdomains(true, &world_regdom);
1865 restore_alpha2(alpha2, reset_user); 1834 restore_alpha2(alpha2, reset_user);
@@ -1914,9 +1883,6 @@ static void restore_regulatory_settings(bool reset_user)
1914 list_splice_tail_init(&tmp_reg_req_list, &reg_requests_list); 1883 list_splice_tail_init(&tmp_reg_req_list, &reg_requests_list);
1915 spin_unlock(&reg_requests_lock); 1884 spin_unlock(&reg_requests_lock);
1916 1885
1917 mutex_unlock(&reg_mutex);
1918 mutex_unlock(&cfg80211_mutex);
1919
1920 REG_DBG_PRINT("Kicking the queue\n"); 1886 REG_DBG_PRINT("Kicking the queue\n");
1921 1887
1922 schedule_work(&reg_work); 1888 schedule_work(&reg_work);
@@ -2231,7 +2197,6 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2231 struct regulatory_request *lr; 2197 struct regulatory_request *lr;
2232 int r; 2198 int r;
2233 2199
2234 mutex_lock(&reg_mutex);
2235 lr = get_last_request(); 2200 lr = get_last_request();
2236 2201
2237 /* Note that this doesn't update the wiphys, this is done below */ 2202 /* Note that this doesn't update the wiphys, this is done below */
@@ -2241,14 +2206,12 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2241 reg_set_request_processed(); 2206 reg_set_request_processed();
2242 2207
2243 kfree(rd); 2208 kfree(rd);
2244 goto out; 2209 return r;
2245 } 2210 }
2246 2211
2247 /* This would make this whole thing pointless */ 2212 /* This would make this whole thing pointless */
2248 if (WARN_ON(!lr->intersect && rd != get_cfg80211_regdom())) { 2213 if (WARN_ON(!lr->intersect && rd != get_cfg80211_regdom()))
2249 r = -EINVAL; 2214 return -EINVAL;
2250 goto out;
2251 }
2252 2215
2253 /* update all wiphys now with the new established regulatory domain */ 2216 /* update all wiphys now with the new established regulatory domain */
2254 update_all_wiphy_regulatory(lr->initiator); 2217 update_all_wiphy_regulatory(lr->initiator);
@@ -2259,10 +2222,7 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2259 2222
2260 reg_set_request_processed(); 2223 reg_set_request_processed();
2261 2224
2262 out: 2225 return 0;
2263 mutex_unlock(&reg_mutex);
2264
2265 return r;
2266} 2226}
2267 2227
2268int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) 2228int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
@@ -2287,23 +2247,17 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
2287 2247
2288void wiphy_regulatory_register(struct wiphy *wiphy) 2248void wiphy_regulatory_register(struct wiphy *wiphy)
2289{ 2249{
2290 mutex_lock(&reg_mutex);
2291
2292 if (!reg_dev_ignore_cell_hint(wiphy)) 2250 if (!reg_dev_ignore_cell_hint(wiphy))
2293 reg_num_devs_support_basehint++; 2251 reg_num_devs_support_basehint++;
2294 2252
2295 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); 2253 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
2296
2297 mutex_unlock(&reg_mutex);
2298} 2254}
2299 2255
2300/* Caller must hold cfg80211_mutex */
2301void wiphy_regulatory_deregister(struct wiphy *wiphy) 2256void wiphy_regulatory_deregister(struct wiphy *wiphy)
2302{ 2257{
2303 struct wiphy *request_wiphy = NULL; 2258 struct wiphy *request_wiphy = NULL;
2304 struct regulatory_request *lr; 2259 struct regulatory_request *lr;
2305 2260
2306 mutex_lock(&reg_mutex);
2307 lr = get_last_request(); 2261 lr = get_last_request();
2308 2262
2309 if (!reg_dev_ignore_cell_hint(wiphy)) 2263 if (!reg_dev_ignore_cell_hint(wiphy))
@@ -2316,12 +2270,10 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy)
2316 request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); 2270 request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx);
2317 2271
2318 if (!request_wiphy || request_wiphy != wiphy) 2272 if (!request_wiphy || request_wiphy != wiphy)
2319 goto out; 2273 return;
2320 2274
2321 lr->wiphy_idx = WIPHY_IDX_INVALID; 2275 lr->wiphy_idx = WIPHY_IDX_INVALID;
2322 lr->country_ie_env = ENVIRON_ANY; 2276 lr->country_ie_env = ENVIRON_ANY;
2323out:
2324 mutex_unlock(&reg_mutex);
2325} 2277}
2326 2278
2327static void reg_timeout_work(struct work_struct *work) 2279static void reg_timeout_work(struct work_struct *work)
@@ -2385,9 +2337,9 @@ void regulatory_exit(void)
2385 cancel_delayed_work_sync(&reg_timeout); 2337 cancel_delayed_work_sync(&reg_timeout);
2386 2338
2387 /* Lock to suppress warnings */ 2339 /* Lock to suppress warnings */
2388 mutex_lock(&reg_mutex); 2340 rtnl_lock();
2389 reset_regdomains(true, NULL); 2341 reset_regdomains(true, NULL);
2390 mutex_unlock(&reg_mutex); 2342 rtnl_unlock();
2391 2343
2392 dev_set_uevent_suppress(&reg_pdev->dev, true); 2344 dev_set_uevent_suppress(&reg_pdev->dev, true);
2393 2345
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index fd99ea495b7e..dd01b58fa78c 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -169,7 +169,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak)
169 union iwreq_data wrqu; 169 union iwreq_data wrqu;
170#endif 170#endif
171 171
172 lockdep_assert_held(&rdev->sched_scan_mtx); 172 ASSERT_RTNL();
173 173
174 request = rdev->scan_req; 174 request = rdev->scan_req;
175 175
@@ -230,9 +230,9 @@ void __cfg80211_scan_done(struct work_struct *wk)
230 rdev = container_of(wk, struct cfg80211_registered_device, 230 rdev = container_of(wk, struct cfg80211_registered_device,
231 scan_done_wk); 231 scan_done_wk);
232 232
233 mutex_lock(&rdev->sched_scan_mtx); 233 rtnl_lock();
234 ___cfg80211_scan_done(rdev, false); 234 ___cfg80211_scan_done(rdev, false);
235 mutex_unlock(&rdev->sched_scan_mtx); 235 rtnl_unlock();
236} 236}
237 237
238void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) 238void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
@@ -241,6 +241,7 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
241 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); 241 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
242 242
243 request->aborted = aborted; 243 request->aborted = aborted;
244 request->notified = true;
244 queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk); 245 queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk);
245} 246}
246EXPORT_SYMBOL(cfg80211_scan_done); 247EXPORT_SYMBOL(cfg80211_scan_done);
@@ -255,7 +256,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk)
255 256
256 request = rdev->sched_scan_req; 257 request = rdev->sched_scan_req;
257 258
258 mutex_lock(&rdev->sched_scan_mtx); 259 rtnl_lock();
259 260
260 /* we don't have sched_scan_req anymore if the scan is stopping */ 261 /* we don't have sched_scan_req anymore if the scan is stopping */
261 if (request) { 262 if (request) {
@@ -270,7 +271,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk)
270 nl80211_send_sched_scan_results(rdev, request->dev); 271 nl80211_send_sched_scan_results(rdev, request->dev);
271 } 272 }
272 273
273 mutex_unlock(&rdev->sched_scan_mtx); 274 rtnl_unlock();
274} 275}
275 276
276void cfg80211_sched_scan_results(struct wiphy *wiphy) 277void cfg80211_sched_scan_results(struct wiphy *wiphy)
@@ -289,9 +290,9 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
289 290
290 trace_cfg80211_sched_scan_stopped(wiphy); 291 trace_cfg80211_sched_scan_stopped(wiphy);
291 292
292 mutex_lock(&rdev->sched_scan_mtx); 293 rtnl_lock();
293 __cfg80211_stop_sched_scan(rdev, true); 294 __cfg80211_stop_sched_scan(rdev, true);
294 mutex_unlock(&rdev->sched_scan_mtx); 295 rtnl_unlock();
295} 296}
296EXPORT_SYMBOL(cfg80211_sched_scan_stopped); 297EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
297 298
@@ -300,7 +301,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
300{ 301{
301 struct net_device *dev; 302 struct net_device *dev;
302 303
303 lockdep_assert_held(&rdev->sched_scan_mtx); 304 ASSERT_RTNL();
304 305
305 if (!rdev->sched_scan_req) 306 if (!rdev->sched_scan_req)
306 return -ENOENT; 307 return -ENOENT;
@@ -1040,6 +1041,25 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
1040EXPORT_SYMBOL(cfg80211_unlink_bss); 1041EXPORT_SYMBOL(cfg80211_unlink_bss);
1041 1042
1042#ifdef CONFIG_CFG80211_WEXT 1043#ifdef CONFIG_CFG80211_WEXT
1044static struct cfg80211_registered_device *
1045cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
1046{
1047 struct cfg80211_registered_device *rdev;
1048 struct net_device *dev;
1049
1050 ASSERT_RTNL();
1051
1052 dev = dev_get_by_index(net, ifindex);
1053 if (!dev)
1054 return ERR_PTR(-ENODEV);
1055 if (dev->ieee80211_ptr)
1056 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
1057 else
1058 rdev = ERR_PTR(-ENODEV);
1059 dev_put(dev);
1060 return rdev;
1061}
1062
1043int cfg80211_wext_siwscan(struct net_device *dev, 1063int cfg80211_wext_siwscan(struct net_device *dev,
1044 struct iw_request_info *info, 1064 struct iw_request_info *info,
1045 union iwreq_data *wrqu, char *extra) 1065 union iwreq_data *wrqu, char *extra)
@@ -1062,7 +1082,6 @@ int cfg80211_wext_siwscan(struct net_device *dev,
1062 if (IS_ERR(rdev)) 1082 if (IS_ERR(rdev))
1063 return PTR_ERR(rdev); 1083 return PTR_ERR(rdev);
1064 1084
1065 mutex_lock(&rdev->sched_scan_mtx);
1066 if (rdev->scan_req) { 1085 if (rdev->scan_req) {
1067 err = -EBUSY; 1086 err = -EBUSY;
1068 goto out; 1087 goto out;
@@ -1169,9 +1188,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
1169 dev_hold(dev); 1188 dev_hold(dev);
1170 } 1189 }
1171 out: 1190 out:
1172 mutex_unlock(&rdev->sched_scan_mtx);
1173 kfree(creq); 1191 kfree(creq);
1174 cfg80211_unlock_rdev(rdev);
1175 return err; 1192 return err;
1176} 1193}
1177EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan); 1194EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
@@ -1470,10 +1487,8 @@ int cfg80211_wext_giwscan(struct net_device *dev,
1470 if (IS_ERR(rdev)) 1487 if (IS_ERR(rdev))
1471 return PTR_ERR(rdev); 1488 return PTR_ERR(rdev);
1472 1489
1473 if (rdev->scan_req) { 1490 if (rdev->scan_req)
1474 res = -EAGAIN; 1491 return -EAGAIN;
1475 goto out;
1476 }
1477 1492
1478 res = ieee80211_scan_results(rdev, info, extra, data->length); 1493 res = ieee80211_scan_results(rdev, info, extra, data->length);
1479 data->length = 0; 1494 data->length = 0;
@@ -1482,8 +1497,6 @@ int cfg80211_wext_giwscan(struct net_device *dev,
1482 res = 0; 1497 res = 0;
1483 } 1498 }
1484 1499
1485 out:
1486 cfg80211_unlock_rdev(rdev);
1487 return res; 1500 return res;
1488} 1501}
1489EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan); 1502EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 3ed35c345cae..81be95f3be74 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -43,35 +43,29 @@ static bool cfg80211_is_all_idle(void)
43 struct wireless_dev *wdev; 43 struct wireless_dev *wdev;
44 bool is_all_idle = true; 44 bool is_all_idle = true;
45 45
46 mutex_lock(&cfg80211_mutex);
47
48 /* 46 /*
49 * All devices must be idle as otherwise if you are actively 47 * All devices must be idle as otherwise if you are actively
50 * scanning some new beacon hints could be learned and would 48 * scanning some new beacon hints could be learned and would
51 * count as new regulatory hints. 49 * count as new regulatory hints.
52 */ 50 */
53 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 51 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
54 cfg80211_lock_rdev(rdev);
55 list_for_each_entry(wdev, &rdev->wdev_list, list) { 52 list_for_each_entry(wdev, &rdev->wdev_list, list) {
56 wdev_lock(wdev); 53 wdev_lock(wdev);
57 if (wdev->sme_state != CFG80211_SME_IDLE) 54 if (wdev->sme_state != CFG80211_SME_IDLE)
58 is_all_idle = false; 55 is_all_idle = false;
59 wdev_unlock(wdev); 56 wdev_unlock(wdev);
60 } 57 }
61 cfg80211_unlock_rdev(rdev);
62 } 58 }
63 59
64 mutex_unlock(&cfg80211_mutex);
65
66 return is_all_idle; 60 return is_all_idle;
67} 61}
68 62
69static void disconnect_work(struct work_struct *work) 63static void disconnect_work(struct work_struct *work)
70{ 64{
71 if (!cfg80211_is_all_idle()) 65 rtnl_lock();
72 return; 66 if (cfg80211_is_all_idle())
73 67 regulatory_hint_disconnect();
74 regulatory_hint_disconnect(); 68 rtnl_unlock();
75} 69}
76 70
77static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work); 71static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
@@ -85,7 +79,6 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
85 ASSERT_RTNL(); 79 ASSERT_RTNL();
86 ASSERT_RDEV_LOCK(rdev); 80 ASSERT_RDEV_LOCK(rdev);
87 ASSERT_WDEV_LOCK(wdev); 81 ASSERT_WDEV_LOCK(wdev);
88 lockdep_assert_held(&rdev->sched_scan_mtx);
89 82
90 if (rdev->scan_req) 83 if (rdev->scan_req)
91 return -EBUSY; 84 return -EBUSY;
@@ -176,13 +169,13 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
176 case CFG80211_CONN_AUTHENTICATE_NEXT: 169 case CFG80211_CONN_AUTHENTICATE_NEXT:
177 BUG_ON(!rdev->ops->auth); 170 BUG_ON(!rdev->ops->auth);
178 wdev->conn->state = CFG80211_CONN_AUTHENTICATING; 171 wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
179 return __cfg80211_mlme_auth(rdev, wdev->netdev, 172 return cfg80211_mlme_auth(rdev, wdev->netdev,
180 params->channel, params->auth_type, 173 params->channel, params->auth_type,
181 params->bssid, 174 params->bssid,
182 params->ssid, params->ssid_len, 175 params->ssid, params->ssid_len,
183 NULL, 0, 176 NULL, 0,
184 params->key, params->key_len, 177 params->key, params->key_len,
185 params->key_idx, NULL, 0); 178 params->key_idx, NULL, 0);
186 case CFG80211_CONN_ASSOCIATE_NEXT: 179 case CFG80211_CONN_ASSOCIATE_NEXT:
187 BUG_ON(!rdev->ops->assoc); 180 BUG_ON(!rdev->ops->assoc);
188 wdev->conn->state = CFG80211_CONN_ASSOCIATING; 181 wdev->conn->state = CFG80211_CONN_ASSOCIATING;
@@ -198,19 +191,19 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
198 req.vht_capa = params->vht_capa; 191 req.vht_capa = params->vht_capa;
199 req.vht_capa_mask = params->vht_capa_mask; 192 req.vht_capa_mask = params->vht_capa_mask;
200 193
201 err = __cfg80211_mlme_assoc(rdev, wdev->netdev, params->channel, 194 err = cfg80211_mlme_assoc(rdev, wdev->netdev, params->channel,
202 params->bssid, params->ssid, 195 params->bssid, params->ssid,
203 params->ssid_len, &req); 196 params->ssid_len, &req);
204 if (err) 197 if (err)
205 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 198 cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
206 NULL, 0, 199 NULL, 0,
207 WLAN_REASON_DEAUTH_LEAVING, 200 WLAN_REASON_DEAUTH_LEAVING,
208 false); 201 false);
209 return err; 202 return err;
210 case CFG80211_CONN_DEAUTH_ASSOC_FAIL: 203 case CFG80211_CONN_DEAUTH_ASSOC_FAIL:
211 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 204 cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
212 NULL, 0, 205 NULL, 0,
213 WLAN_REASON_DEAUTH_LEAVING, false); 206 WLAN_REASON_DEAUTH_LEAVING, false);
214 /* return an error so that we call __cfg80211_connect_result() */ 207 /* return an error so that we call __cfg80211_connect_result() */
215 return -EINVAL; 208 return -EINVAL;
216 default: 209 default:
@@ -226,9 +219,6 @@ void cfg80211_conn_work(struct work_struct *work)
226 u8 bssid_buf[ETH_ALEN], *bssid = NULL; 219 u8 bssid_buf[ETH_ALEN], *bssid = NULL;
227 220
228 rtnl_lock(); 221 rtnl_lock();
229 cfg80211_lock_rdev(rdev);
230 mutex_lock(&rdev->devlist_mtx);
231 mutex_lock(&rdev->sched_scan_mtx);
232 222
233 list_for_each_entry(wdev, &rdev->wdev_list, list) { 223 list_for_each_entry(wdev, &rdev->wdev_list, list) {
234 if (!wdev->netdev) 224 if (!wdev->netdev)
@@ -256,9 +246,6 @@ void cfg80211_conn_work(struct work_struct *work)
256 wdev_unlock(wdev); 246 wdev_unlock(wdev);
257 } 247 }
258 248
259 mutex_unlock(&rdev->sched_scan_mtx);
260 mutex_unlock(&rdev->devlist_mtx);
261 cfg80211_unlock_rdev(rdev);
262 rtnl_unlock(); 249 rtnl_unlock();
263} 250}
264 251
@@ -773,11 +760,11 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
773} 760}
774EXPORT_SYMBOL(cfg80211_disconnected); 761EXPORT_SYMBOL(cfg80211_disconnected);
775 762
776int __cfg80211_connect(struct cfg80211_registered_device *rdev, 763int cfg80211_connect(struct cfg80211_registered_device *rdev,
777 struct net_device *dev, 764 struct net_device *dev,
778 struct cfg80211_connect_params *connect, 765 struct cfg80211_connect_params *connect,
779 struct cfg80211_cached_keys *connkeys, 766 struct cfg80211_cached_keys *connkeys,
780 const u8 *prev_bssid) 767 const u8 *prev_bssid)
781{ 768{
782 struct wireless_dev *wdev = dev->ieee80211_ptr; 769 struct wireless_dev *wdev = dev->ieee80211_ptr;
783 struct cfg80211_bss *bss = NULL; 770 struct cfg80211_bss *bss = NULL;
@@ -924,27 +911,8 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
924 } 911 }
925} 912}
926 913
927int cfg80211_connect(struct cfg80211_registered_device *rdev, 914int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
928 struct net_device *dev, 915 struct net_device *dev, u16 reason, bool wextev)
929 struct cfg80211_connect_params *connect,
930 struct cfg80211_cached_keys *connkeys)
931{
932 int err;
933
934 mutex_lock(&rdev->devlist_mtx);
935 /* might request scan - scan_mtx -> wdev_mtx dependency */
936 mutex_lock(&rdev->sched_scan_mtx);
937 wdev_lock(dev->ieee80211_ptr);
938 err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL);
939 wdev_unlock(dev->ieee80211_ptr);
940 mutex_unlock(&rdev->sched_scan_mtx);
941 mutex_unlock(&rdev->devlist_mtx);
942
943 return err;
944}
945
946int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
947 struct net_device *dev, u16 reason, bool wextev)
948{ 916{
949 struct wireless_dev *wdev = dev->ieee80211_ptr; 917 struct wireless_dev *wdev = dev->ieee80211_ptr;
950 int err; 918 int err;
@@ -979,7 +947,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
979 } 947 }
980 948
981 /* wdev->conn->params.bssid must be set if > SCANNING */ 949 /* wdev->conn->params.bssid must be set if > SCANNING */
982 err = __cfg80211_mlme_deauth(rdev, dev, 950 err = cfg80211_mlme_deauth(rdev, dev,
983 wdev->conn->params.bssid, 951 wdev->conn->params.bssid,
984 NULL, 0, reason, false); 952 NULL, 0, reason, false);
985 if (err) 953 if (err)
@@ -1001,19 +969,6 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
1001 return 0; 969 return 0;
1002} 970}
1003 971
1004int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
1005 struct net_device *dev,
1006 u16 reason, bool wextev)
1007{
1008 int err;
1009
1010 wdev_lock(dev->ieee80211_ptr);
1011 err = __cfg80211_disconnect(rdev, dev, reason, wextev);
1012 wdev_unlock(dev->ieee80211_ptr);
1013
1014 return err;
1015}
1016
1017void cfg80211_sme_disassoc(struct net_device *dev, 972void cfg80211_sme_disassoc(struct net_device *dev,
1018 struct cfg80211_internal_bss *bss) 973 struct cfg80211_internal_bss *bss)
1019{ 974{
@@ -1036,6 +991,6 @@ void cfg80211_sme_disassoc(struct net_device *dev,
1036 991
1037 memcpy(bssid, bss->pub.bssid, ETH_ALEN); 992 memcpy(bssid, bss->pub.bssid, ETH_ALEN);
1038 993
1039 __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0, 994 cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
1040 WLAN_REASON_DEAUTH_LEAVING, false); 995 WLAN_REASON_DEAUTH_LEAVING, false);
1041} 996}
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 8f28b9f798d8..360a42c6f694 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -91,6 +91,7 @@ static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
91 cfg80211_leave(rdev, wdev); 91 cfg80211_leave(rdev, wdev);
92} 92}
93 93
94#ifdef CONFIG_PM
94static int wiphy_suspend(struct device *dev, pm_message_t state) 95static int wiphy_suspend(struct device *dev, pm_message_t state)
95{ 96{
96 struct cfg80211_registered_device *rdev = dev_to_rdev(dev); 97 struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
@@ -100,10 +101,10 @@ static int wiphy_suspend(struct device *dev, pm_message_t state)
100 101
101 rtnl_lock(); 102 rtnl_lock();
102 if (rdev->wiphy.registered) { 103 if (rdev->wiphy.registered) {
103 if (!rdev->wowlan) 104 if (!rdev->wiphy.wowlan_config)
104 cfg80211_leave_all(rdev); 105 cfg80211_leave_all(rdev);
105 if (rdev->ops->suspend) 106 if (rdev->ops->suspend)
106 ret = rdev_suspend(rdev, rdev->wowlan); 107 ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config);
107 if (ret == 1) { 108 if (ret == 1) {
108 /* Driver refuse to configure wowlan */ 109 /* Driver refuse to configure wowlan */
109 cfg80211_leave_all(rdev); 110 cfg80211_leave_all(rdev);
@@ -132,6 +133,7 @@ static int wiphy_resume(struct device *dev)
132 133
133 return ret; 134 return ret;
134} 135}
136#endif
135 137
136static const void *wiphy_namespace(struct device *d) 138static const void *wiphy_namespace(struct device *d)
137{ 139{
@@ -146,8 +148,10 @@ struct class ieee80211_class = {
146 .dev_release = wiphy_dev_release, 148 .dev_release = wiphy_dev_release,
147 .dev_attrs = ieee80211_dev_attrs, 149 .dev_attrs = ieee80211_dev_attrs,
148 .dev_uevent = wiphy_uevent, 150 .dev_uevent = wiphy_uevent,
151#ifdef CONFIG_PM
149 .suspend = wiphy_suspend, 152 .suspend = wiphy_suspend,
150 .resume = wiphy_resume, 153 .resume = wiphy_resume,
154#endif
151 .ns_type = &net_ns_type_operations, 155 .ns_type = &net_ns_type_operations,
152 .namespace = wiphy_namespace, 156 .namespace = wiphy_namespace,
153}; 157};
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 5755bc14abbd..23fafeae8a10 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1911,12 +1911,12 @@ TRACE_EVENT(cfg80211_send_rx_assoc,
1911 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) 1911 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
1912); 1912);
1913 1913
1914DEFINE_EVENT(netdev_evt_only, __cfg80211_send_deauth, 1914DEFINE_EVENT(netdev_evt_only, cfg80211_send_deauth,
1915 TP_PROTO(struct net_device *netdev), 1915 TP_PROTO(struct net_device *netdev),
1916 TP_ARGS(netdev) 1916 TP_ARGS(netdev)
1917); 1917);
1918 1918
1919DEFINE_EVENT(netdev_evt_only, __cfg80211_send_disassoc, 1919DEFINE_EVENT(netdev_evt_only, cfg80211_send_disassoc,
1920 TP_PROTO(struct net_device *netdev), 1920 TP_PROTO(struct net_device *netdev),
1921 TP_ARGS(netdev) 1921 TP_ARGS(netdev)
1922); 1922);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index f5ad4d94ba88..74458b7f61eb 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -33,6 +33,29 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
33} 33}
34EXPORT_SYMBOL(ieee80211_get_response_rate); 34EXPORT_SYMBOL(ieee80211_get_response_rate);
35 35
36u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband)
37{
38 struct ieee80211_rate *bitrates;
39 u32 mandatory_rates = 0;
40 enum ieee80211_rate_flags mandatory_flag;
41 int i;
42
43 if (WARN_ON(!sband))
44 return 1;
45
46 if (sband->band == IEEE80211_BAND_2GHZ)
47 mandatory_flag = IEEE80211_RATE_MANDATORY_B;
48 else
49 mandatory_flag = IEEE80211_RATE_MANDATORY_A;
50
51 bitrates = sband->bitrates;
52 for (i = 0; i < sband->n_bitrates; i++)
53 if (bitrates[i].flags & mandatory_flag)
54 mandatory_rates |= BIT(i);
55 return mandatory_rates;
56}
57EXPORT_SYMBOL(ieee80211_mandatory_rates);
58
36int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band) 59int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
37{ 60{
38 /* see 802.11 17.3.8.3.2 and Annex J 61 /* see 802.11 17.3.8.3.2 and Annex J
@@ -785,12 +808,8 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
785 ASSERT_RTNL(); 808 ASSERT_RTNL();
786 ASSERT_RDEV_LOCK(rdev); 809 ASSERT_RDEV_LOCK(rdev);
787 810
788 mutex_lock(&rdev->devlist_mtx);
789
790 list_for_each_entry(wdev, &rdev->wdev_list, list) 811 list_for_each_entry(wdev, &rdev->wdev_list, list)
791 cfg80211_process_wdev_events(wdev); 812 cfg80211_process_wdev_events(wdev);
792
793 mutex_unlock(&rdev->devlist_mtx);
794} 813}
795 814
796int cfg80211_change_iface(struct cfg80211_registered_device *rdev, 815int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
@@ -822,10 +841,8 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
822 return -EBUSY; 841 return -EBUSY;
823 842
824 if (ntype != otype && netif_running(dev)) { 843 if (ntype != otype && netif_running(dev)) {
825 mutex_lock(&rdev->devlist_mtx);
826 err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, 844 err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr,
827 ntype); 845 ntype);
828 mutex_unlock(&rdev->devlist_mtx);
829 if (err) 846 if (err)
830 return err; 847 return err;
831 848
@@ -841,8 +858,10 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
841 break; 858 break;
842 case NL80211_IFTYPE_STATION: 859 case NL80211_IFTYPE_STATION:
843 case NL80211_IFTYPE_P2P_CLIENT: 860 case NL80211_IFTYPE_P2P_CLIENT:
861 wdev_lock(dev->ieee80211_ptr);
844 cfg80211_disconnect(rdev, dev, 862 cfg80211_disconnect(rdev, dev,
845 WLAN_REASON_DEAUTH_LEAVING, true); 863 WLAN_REASON_DEAUTH_LEAVING, true);
864 wdev_unlock(dev->ieee80211_ptr);
846 break; 865 break;
847 case NL80211_IFTYPE_MESH_POINT: 866 case NL80211_IFTYPE_MESH_POINT:
848 /* mesh should be handled? */ 867 /* mesh should be handled? */
@@ -1169,6 +1188,9 @@ bool ieee80211_operating_class_to_band(u8 operating_class,
1169 case 84: 1188 case 84:
1170 *band = IEEE80211_BAND_2GHZ; 1189 *band = IEEE80211_BAND_2GHZ;
1171 return true; 1190 return true;
1191 case 180:
1192 *band = IEEE80211_BAND_60GHZ;
1193 return true;
1172 } 1194 }
1173 1195
1174 return false; 1196 return false;
@@ -1184,8 +1206,6 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
1184 if (!beacon_int) 1206 if (!beacon_int)
1185 return -EINVAL; 1207 return -EINVAL;
1186 1208
1187 mutex_lock(&rdev->devlist_mtx);
1188
1189 list_for_each_entry(wdev, &rdev->wdev_list, list) { 1209 list_for_each_entry(wdev, &rdev->wdev_list, list) {
1190 if (!wdev->beacon_interval) 1210 if (!wdev->beacon_interval)
1191 continue; 1211 continue;
@@ -1195,8 +1215,6 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
1195 } 1215 }
1196 } 1216 }
1197 1217
1198 mutex_unlock(&rdev->devlist_mtx);
1199
1200 return res; 1218 return res;
1201} 1219}
1202 1220
@@ -1220,7 +1238,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1220 int i, j; 1238 int i, j;
1221 1239
1222 ASSERT_RTNL(); 1240 ASSERT_RTNL();
1223 lockdep_assert_held(&rdev->devlist_mtx);
1224 1241
1225 if (WARN_ON(hweight32(radar_detect) > 1)) 1242 if (WARN_ON(hweight32(radar_detect) > 1))
1226 return -EINVAL; 1243 return -EINVAL;
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index d997d0f0c54a..e7c6e862580d 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -72,7 +72,6 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
72 struct cfg80211_registered_device *rdev; 72 struct cfg80211_registered_device *rdev;
73 struct vif_params vifparams; 73 struct vif_params vifparams;
74 enum nl80211_iftype type; 74 enum nl80211_iftype type;
75 int ret;
76 75
77 rdev = wiphy_to_dev(wdev->wiphy); 76 rdev = wiphy_to_dev(wdev->wiphy);
78 77
@@ -98,11 +97,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
98 97
99 memset(&vifparams, 0, sizeof(vifparams)); 98 memset(&vifparams, 0, sizeof(vifparams));
100 99
101 cfg80211_lock_rdev(rdev); 100 return cfg80211_change_iface(rdev, dev, type, NULL, &vifparams);
102 ret = cfg80211_change_iface(rdev, dev, type, NULL, &vifparams);
103 cfg80211_unlock_rdev(rdev);
104
105 return ret;
106} 101}
107EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode); 102EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode);
108 103
@@ -579,13 +574,10 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
579{ 574{
580 int err; 575 int err;
581 576
582 /* devlist mutex needed for possible IBSS re-join */
583 mutex_lock(&rdev->devlist_mtx);
584 wdev_lock(dev->ieee80211_ptr); 577 wdev_lock(dev->ieee80211_ptr);
585 err = __cfg80211_set_encryption(rdev, dev, pairwise, addr, 578 err = __cfg80211_set_encryption(rdev, dev, pairwise, addr,
586 remove, tx_key, idx, params); 579 remove, tx_key, idx, params);
587 wdev_unlock(dev->ieee80211_ptr); 580 wdev_unlock(dev->ieee80211_ptr);
588 mutex_unlock(&rdev->devlist_mtx);
589 581
590 return err; 582 return err;
591} 583}
@@ -787,7 +779,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
787 struct cfg80211_chan_def chandef = { 779 struct cfg80211_chan_def chandef = {
788 .width = NL80211_CHAN_WIDTH_20_NOHT, 780 .width = NL80211_CHAN_WIDTH_20_NOHT,
789 }; 781 };
790 int freq, err; 782 int freq;
791 783
792 switch (wdev->iftype) { 784 switch (wdev->iftype) {
793 case NL80211_IFTYPE_STATION: 785 case NL80211_IFTYPE_STATION:
@@ -804,10 +796,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
804 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq); 796 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
805 if (!chandef.chan) 797 if (!chandef.chan)
806 return -EINVAL; 798 return -EINVAL;
807 mutex_lock(&rdev->devlist_mtx); 799 return cfg80211_set_monitor_channel(rdev, &chandef);
808 err = cfg80211_set_monitor_channel(rdev, &chandef);
809 mutex_unlock(&rdev->devlist_mtx);
810 return err;
811 case NL80211_IFTYPE_MESH_POINT: 800 case NL80211_IFTYPE_MESH_POINT:
812 freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); 801 freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
813 if (freq < 0) 802 if (freq < 0)
@@ -818,10 +807,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
818 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq); 807 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
819 if (!chandef.chan) 808 if (!chandef.chan)
820 return -EINVAL; 809 return -EINVAL;
821 mutex_lock(&rdev->devlist_mtx); 810 return cfg80211_set_mesh_channel(rdev, wdev, &chandef);
822 err = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
823 mutex_unlock(&rdev->devlist_mtx);
824 return err;
825 default: 811 default:
826 return -EOPNOTSUPP; 812 return -EOPNOTSUPP;
827 } 813 }
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index e79cb5c0655a..a53f8404f451 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -54,8 +54,8 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
54 if (wdev->wext.prev_bssid_valid) 54 if (wdev->wext.prev_bssid_valid)
55 prev_bssid = wdev->wext.prev_bssid; 55 prev_bssid = wdev->wext.prev_bssid;
56 56
57 err = __cfg80211_connect(rdev, wdev->netdev, 57 err = cfg80211_connect(rdev, wdev->netdev,
58 &wdev->wext.connect, ck, prev_bssid); 58 &wdev->wext.connect, ck, prev_bssid);
59 if (err) 59 if (err)
60 kfree(ck); 60 kfree(ck);
61 61
@@ -87,9 +87,6 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
87 return -EINVAL; 87 return -EINVAL;
88 } 88 }
89 89
90 cfg80211_lock_rdev(rdev);
91 mutex_lock(&rdev->devlist_mtx);
92 mutex_lock(&rdev->sched_scan_mtx);
93 wdev_lock(wdev); 90 wdev_lock(wdev);
94 91
95 if (wdev->sme_state != CFG80211_SME_IDLE) { 92 if (wdev->sme_state != CFG80211_SME_IDLE) {
@@ -103,8 +100,8 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
103 /* if SSID set, we'll try right again, avoid event */ 100 /* if SSID set, we'll try right again, avoid event */
104 if (wdev->wext.connect.ssid_len) 101 if (wdev->wext.connect.ssid_len)
105 event = false; 102 event = false;
106 err = __cfg80211_disconnect(rdev, dev, 103 err = cfg80211_disconnect(rdev, dev,
107 WLAN_REASON_DEAUTH_LEAVING, event); 104 WLAN_REASON_DEAUTH_LEAVING, event);
108 if (err) 105 if (err)
109 goto out; 106 goto out;
110 } 107 }
@@ -136,9 +133,6 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
136 err = cfg80211_mgd_wext_connect(rdev, wdev); 133 err = cfg80211_mgd_wext_connect(rdev, wdev);
137 out: 134 out:
138 wdev_unlock(wdev); 135 wdev_unlock(wdev);
139 mutex_unlock(&rdev->sched_scan_mtx);
140 mutex_unlock(&rdev->devlist_mtx);
141 cfg80211_unlock_rdev(rdev);
142 return err; 136 return err;
143} 137}
144 138
@@ -190,9 +184,6 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
190 if (len > 0 && ssid[len - 1] == '\0') 184 if (len > 0 && ssid[len - 1] == '\0')
191 len--; 185 len--;
192 186
193 cfg80211_lock_rdev(rdev);
194 mutex_lock(&rdev->devlist_mtx);
195 mutex_lock(&rdev->sched_scan_mtx);
196 wdev_lock(wdev); 187 wdev_lock(wdev);
197 188
198 err = 0; 189 err = 0;
@@ -208,8 +199,8 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
208 /* if SSID set now, we'll try to connect, avoid event */ 199 /* if SSID set now, we'll try to connect, avoid event */
209 if (len) 200 if (len)
210 event = false; 201 event = false;
211 err = __cfg80211_disconnect(rdev, dev, 202 err = cfg80211_disconnect(rdev, dev,
212 WLAN_REASON_DEAUTH_LEAVING, event); 203 WLAN_REASON_DEAUTH_LEAVING, event);
213 if (err) 204 if (err)
214 goto out; 205 goto out;
215 } 206 }
@@ -226,9 +217,6 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
226 err = cfg80211_mgd_wext_connect(rdev, wdev); 217 err = cfg80211_mgd_wext_connect(rdev, wdev);
227 out: 218 out:
228 wdev_unlock(wdev); 219 wdev_unlock(wdev);
229 mutex_unlock(&rdev->sched_scan_mtx);
230 mutex_unlock(&rdev->devlist_mtx);
231 cfg80211_unlock_rdev(rdev);
232 return err; 220 return err;
233} 221}
234 222
@@ -287,9 +275,6 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
287 if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) 275 if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
288 bssid = NULL; 276 bssid = NULL;
289 277
290 cfg80211_lock_rdev(rdev);
291 mutex_lock(&rdev->devlist_mtx);
292 mutex_lock(&rdev->sched_scan_mtx);
293 wdev_lock(wdev); 278 wdev_lock(wdev);
294 279
295 if (wdev->sme_state != CFG80211_SME_IDLE) { 280 if (wdev->sme_state != CFG80211_SME_IDLE) {
@@ -303,8 +288,8 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
303 ether_addr_equal(bssid, wdev->wext.connect.bssid)) 288 ether_addr_equal(bssid, wdev->wext.connect.bssid))
304 goto out; 289 goto out;
305 290
306 err = __cfg80211_disconnect(rdev, dev, 291 err = cfg80211_disconnect(rdev, dev,
307 WLAN_REASON_DEAUTH_LEAVING, false); 292 WLAN_REASON_DEAUTH_LEAVING, false);
308 if (err) 293 if (err)
309 goto out; 294 goto out;
310 } 295 }
@@ -318,9 +303,6 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
318 err = cfg80211_mgd_wext_connect(rdev, wdev); 303 err = cfg80211_mgd_wext_connect(rdev, wdev);
319 out: 304 out:
320 wdev_unlock(wdev); 305 wdev_unlock(wdev);
321 mutex_unlock(&rdev->sched_scan_mtx);
322 mutex_unlock(&rdev->devlist_mtx);
323 cfg80211_unlock_rdev(rdev);
324 return err; 306 return err;
325} 307}
326 308
@@ -383,8 +365,8 @@ int cfg80211_wext_siwgenie(struct net_device *dev,
383 wdev->wext.ie_len = ie_len; 365 wdev->wext.ie_len = ie_len;
384 366
385 if (wdev->sme_state != CFG80211_SME_IDLE) { 367 if (wdev->sme_state != CFG80211_SME_IDLE) {
386 err = __cfg80211_disconnect(rdev, dev, 368 err = cfg80211_disconnect(rdev, dev,
387 WLAN_REASON_DEAUTH_LEAVING, false); 369 WLAN_REASON_DEAUTH_LEAVING, false);
388 if (err) 370 if (err)
389 goto out; 371 goto out;
390 } 372 }
@@ -420,8 +402,7 @@ int cfg80211_wext_siwmlme(struct net_device *dev,
420 switch (mlme->cmd) { 402 switch (mlme->cmd) {
421 case IW_MLME_DEAUTH: 403 case IW_MLME_DEAUTH:
422 case IW_MLME_DISASSOC: 404 case IW_MLME_DISASSOC:
423 err = __cfg80211_disconnect(rdev, dev, mlme->reason_code, 405 err = cfg80211_disconnect(rdev, dev, mlme->reason_code, true);
424 true);
425 break; 406 break;
426 default: 407 default:
427 err = -EOPNOTSUPP; 408 err = -EOPNOTSUPP;