aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/wireless/core.c166
-rw-r--r--net/wireless/core.h32
-rw-r--r--net/wireless/debugfs.c4
-rw-r--r--net/wireless/ibss.c10
-rw-r--r--net/wireless/mesh.c2
-rw-r--r--net/wireless/mlme.c12
-rw-r--r--net/wireless/nl80211.c178
-rw-r--r--net/wireless/reg.c36
-rw-r--r--net/wireless/scan.c42
-rw-r--r--net/wireless/sme.c26
-rw-r--r--net/wireless/util.c11
-rw-r--r--net/wireless/wext-compat.c22
-rw-r--r--net/wireless/wext-sme.c18
13 files changed, 115 insertions, 444 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 9416b8f55f50..5fc642d4071b 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -36,12 +36,10 @@ MODULE_LICENSE("GPL");
36MODULE_DESCRIPTION("wireless configuration support"); 36MODULE_DESCRIPTION("wireless configuration support");
37MODULE_ALIAS_GENL_FAMILY(NL80211_GENL_NAME); 37MODULE_ALIAS_GENL_FAMILY(NL80211_GENL_NAME);
38 38
39/* RCU-protected (and cfg80211_mutex for writers) */ 39/* RCU-protected (and RTNL for writers) */
40LIST_HEAD(cfg80211_rdev_list); 40LIST_HEAD(cfg80211_rdev_list);
41int cfg80211_rdev_list_generation; 41int cfg80211_rdev_list_generation;
42 42
43DEFINE_MUTEX(cfg80211_mutex);
44
45/* for debugfs */ 43/* for debugfs */
46static struct dentry *ieee80211_debugfs_dir; 44static struct dentry *ieee80211_debugfs_dir;
47 45
@@ -53,12 +51,11 @@ module_param(cfg80211_disable_40mhz_24ghz, bool, 0644);
53MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz, 51MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz,
54 "Disable 40MHz support in the 2.4GHz band"); 52 "Disable 40MHz support in the 2.4GHz band");
55 53
56/* requires cfg80211_mutex to be held! */
57struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx) 54struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
58{ 55{
59 struct cfg80211_registered_device *result = NULL, *rdev; 56 struct cfg80211_registered_device *result = NULL, *rdev;
60 57
61 assert_cfg80211_lock(); 58 ASSERT_RTNL();
62 59
63 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 60 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
64 if (rdev->wiphy_idx == wiphy_idx) { 61 if (rdev->wiphy_idx == wiphy_idx) {
@@ -77,12 +74,11 @@ int get_wiphy_idx(struct wiphy *wiphy)
77 return rdev->wiphy_idx; 74 return rdev->wiphy_idx;
78} 75}
79 76
80/* requires cfg80211_rdev_mutex to be held! */
81struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx) 77struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
82{ 78{
83 struct cfg80211_registered_device *rdev; 79 struct cfg80211_registered_device *rdev;
84 80
85 assert_cfg80211_lock(); 81 ASSERT_RTNL();
86 82
87 rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx); 83 rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx);
88 if (!rdev) 84 if (!rdev)
@@ -90,14 +86,13 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
90 return &rdev->wiphy; 86 return &rdev->wiphy;
91} 87}
92 88
93/* requires cfg80211_mutex to be held */
94int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, 89int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
95 char *newname) 90 char *newname)
96{ 91{
97 struct cfg80211_registered_device *rdev2; 92 struct cfg80211_registered_device *rdev2;
98 int wiphy_idx, taken = -1, result, digits; 93 int wiphy_idx, taken = -1, result, digits;
99 94
100 assert_cfg80211_lock(); 95 ASSERT_RTNL();
101 96
102 /* 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 */
103 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); 98 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
@@ -195,8 +190,7 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
195void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, 190void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
196 struct wireless_dev *wdev) 191 struct wireless_dev *wdev)
197{ 192{
198 lockdep_assert_held(&rdev->devlist_mtx); 193 ASSERT_RTNL();
199 lockdep_assert_held(&rdev->sched_scan_mtx);
200 194
201 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)) 195 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE))
202 return; 196 return;
@@ -235,8 +229,6 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
235 229
236 rtnl_lock(); 230 rtnl_lock();
237 231
238 /* read-only iteration need not hold the devlist_mtx */
239
240 list_for_each_entry(wdev, &rdev->wdev_list, list) { 232 list_for_each_entry(wdev, &rdev->wdev_list, list) {
241 if (wdev->netdev) { 233 if (wdev->netdev) {
242 dev_close(wdev->netdev); 234 dev_close(wdev->netdev);
@@ -245,12 +237,7 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
245 /* otherwise, check iftype */ 237 /* otherwise, check iftype */
246 switch (wdev->iftype) { 238 switch (wdev->iftype) {
247 case NL80211_IFTYPE_P2P_DEVICE: 239 case NL80211_IFTYPE_P2P_DEVICE:
248 /* but this requires it */
249 mutex_lock(&rdev->devlist_mtx);
250 mutex_lock(&rdev->sched_scan_mtx);
251 cfg80211_stop_p2p_device(rdev, wdev); 240 cfg80211_stop_p2p_device(rdev, wdev);
252 mutex_unlock(&rdev->sched_scan_mtx);
253 mutex_unlock(&rdev->devlist_mtx);
254 break; 241 break;
255 default: 242 default:
256 break; 243 break;
@@ -278,10 +265,7 @@ static void cfg80211_event_work(struct work_struct *work)
278 event_work); 265 event_work);
279 266
280 rtnl_lock(); 267 rtnl_lock();
281 cfg80211_lock_rdev(rdev);
282
283 cfg80211_process_rdev_events(rdev); 268 cfg80211_process_rdev_events(rdev);
284 cfg80211_unlock_rdev(rdev);
285 rtnl_unlock(); 269 rtnl_unlock();
286} 270}
287 271
@@ -323,9 +307,6 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
323 /* give it a proper name */ 307 /* give it a proper name */
324 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 308 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
325 309
326 mutex_init(&rdev->mtx);
327 mutex_init(&rdev->devlist_mtx);
328 mutex_init(&rdev->sched_scan_mtx);
329 INIT_LIST_HEAD(&rdev->wdev_list); 310 INIT_LIST_HEAD(&rdev->wdev_list);
330 INIT_LIST_HEAD(&rdev->beacon_registrations); 311 INIT_LIST_HEAD(&rdev->beacon_registrations);
331 spin_lock_init(&rdev->beacon_registrations_lock); 312 spin_lock_init(&rdev->beacon_registrations_lock);
@@ -573,11 +554,11 @@ int wiphy_register(struct wiphy *wiphy)
573 /* check and set up bitrates */ 554 /* check and set up bitrates */
574 ieee80211_set_bitrate_flags(wiphy); 555 ieee80211_set_bitrate_flags(wiphy);
575 556
576 mutex_lock(&cfg80211_mutex); 557 rtnl_lock();
577 558
578 res = device_add(&rdev->wiphy.dev); 559 res = device_add(&rdev->wiphy.dev);
579 if (res) { 560 if (res) {
580 mutex_unlock(&cfg80211_mutex); 561 rtnl_unlock();
581 return res; 562 return res;
582 } 563 }
583 564
@@ -606,25 +587,18 @@ int wiphy_register(struct wiphy *wiphy)
606 } 587 }
607 588
608 cfg80211_debugfs_rdev_add(rdev); 589 cfg80211_debugfs_rdev_add(rdev);
609 mutex_unlock(&cfg80211_mutex);
610 590
611 /*
612 * due to a locking dependency this has to be outside of the
613 * cfg80211_mutex lock
614 */
615 res = rfkill_register(rdev->rfkill); 591 res = rfkill_register(rdev->rfkill);
616 if (res) { 592 if (res) {
617 device_del(&rdev->wiphy.dev); 593 device_del(&rdev->wiphy.dev);
618 594
619 mutex_lock(&cfg80211_mutex);
620 debugfs_remove_recursive(rdev->wiphy.debugfsdir); 595 debugfs_remove_recursive(rdev->wiphy.debugfsdir);
621 list_del_rcu(&rdev->list); 596 list_del_rcu(&rdev->list);
622 wiphy_regulatory_deregister(wiphy); 597 wiphy_regulatory_deregister(wiphy);
623 mutex_unlock(&cfg80211_mutex); 598 rtnl_unlock();
624 return res; 599 return res;
625 } 600 }
626 601
627 rtnl_lock();
628 rdev->wiphy.registered = true; 602 rdev->wiphy.registered = true;
629 rtnl_unlock(); 603 rtnl_unlock();
630 return 0; 604 return 0;
@@ -654,25 +628,19 @@ void wiphy_unregister(struct wiphy *wiphy)
654{ 628{
655 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 629 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
656 630
657 rtnl_lock();
658 rdev->wiphy.registered = false;
659 rtnl_unlock();
660
661 rfkill_unregister(rdev->rfkill);
662
663 /* protect the device list */
664 mutex_lock(&cfg80211_mutex);
665
666 wait_event(rdev->dev_wait, ({ 631 wait_event(rdev->dev_wait, ({
667 int __count; 632 int __count;
668 mutex_lock(&rdev->devlist_mtx); 633 rtnl_lock();
669 __count = rdev->opencount; 634 __count = rdev->opencount;
670 mutex_unlock(&rdev->devlist_mtx); 635 rtnl_unlock();
671 __count == 0; })); 636 __count == 0; }));
672 637
673 mutex_lock(&rdev->devlist_mtx); 638 rtnl_lock();
639 rdev->wiphy.registered = false;
640
641 rfkill_unregister(rdev->rfkill);
642
674 BUG_ON(!list_empty(&rdev->wdev_list)); 643 BUG_ON(!list_empty(&rdev->wdev_list));
675 mutex_unlock(&rdev->devlist_mtx);
676 644
677 /* 645 /*
678 * First remove the hardware from everywhere, this makes 646 * First remove the hardware from everywhere, this makes
@@ -683,20 +651,6 @@ void wiphy_unregister(struct wiphy *wiphy)
683 synchronize_rcu(); 651 synchronize_rcu();
684 652
685 /* 653 /*
686 * Try to grab rdev->mtx. If a command is still in progress,
687 * hopefully the driver will refuse it since it's tearing
688 * down the device already. We wait for this command to complete
689 * before unlinking the item from the list.
690 * Note: as codified by the BUG_ON above we cannot get here if
691 * a virtual interface is still present. Hence, we can only get
692 * to lock contention here if userspace issues a command that
693 * identified the hardware by wiphy index.
694 */
695 cfg80211_lock_rdev(rdev);
696 /* nothing */
697 cfg80211_unlock_rdev(rdev);
698
699 /*
700 * If this device got a regulatory hint tell core its 654 * If this device got a regulatory hint tell core its
701 * free to listen now to a new shiny device regulatory hint 655 * free to listen now to a new shiny device regulatory hint
702 */ 656 */
@@ -705,7 +659,7 @@ void wiphy_unregister(struct wiphy *wiphy)
705 cfg80211_rdev_list_generation++; 659 cfg80211_rdev_list_generation++;
706 device_del(&rdev->wiphy.dev); 660 device_del(&rdev->wiphy.dev);
707 661
708 mutex_unlock(&cfg80211_mutex); 662 rtnl_unlock();
709 663
710 flush_work(&rdev->scan_done_wk); 664 flush_work(&rdev->scan_done_wk);
711 cancel_work_sync(&rdev->conn_work); 665 cancel_work_sync(&rdev->conn_work);
@@ -723,9 +677,6 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
723 struct cfg80211_internal_bss *scan, *tmp; 677 struct cfg80211_internal_bss *scan, *tmp;
724 struct cfg80211_beacon_registration *reg, *treg; 678 struct cfg80211_beacon_registration *reg, *treg;
725 rfkill_destroy(rdev->rfkill); 679 rfkill_destroy(rdev->rfkill);
726 mutex_destroy(&rdev->mtx);
727 mutex_destroy(&rdev->devlist_mtx);
728 mutex_destroy(&rdev->sched_scan_mtx);
729 list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) { 680 list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) {
730 list_del(&reg->list); 681 list_del(&reg->list);
731 kfree(reg); 682 kfree(reg);
@@ -750,36 +701,6 @@ void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked)
750} 701}
751EXPORT_SYMBOL(wiphy_rfkill_set_hw_state); 702EXPORT_SYMBOL(wiphy_rfkill_set_hw_state);
752 703
753static void wdev_cleanup_work(struct work_struct *work)
754{
755 struct wireless_dev *wdev;
756 struct cfg80211_registered_device *rdev;
757
758 wdev = container_of(work, struct wireless_dev, cleanup_work);
759 rdev = wiphy_to_dev(wdev->wiphy);
760
761 mutex_lock(&rdev->sched_scan_mtx);
762
763 if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) {
764 rdev->scan_req->aborted = true;
765 ___cfg80211_scan_done(rdev, true);
766 }
767
768 if (WARN_ON(rdev->sched_scan_req &&
769 rdev->sched_scan_req->dev == wdev->netdev)) {
770 __cfg80211_stop_sched_scan(rdev, false);
771 }
772
773 mutex_unlock(&rdev->sched_scan_mtx);
774
775 mutex_lock(&rdev->devlist_mtx);
776 rdev->opencount--;
777 mutex_unlock(&rdev->devlist_mtx);
778 wake_up(&rdev->dev_wait);
779
780 dev_put(wdev->netdev);
781}
782
783void cfg80211_unregister_wdev(struct wireless_dev *wdev) 704void cfg80211_unregister_wdev(struct wireless_dev *wdev)
784{ 705{
785 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 706 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -789,8 +710,6 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
789 if (WARN_ON(wdev->netdev)) 710 if (WARN_ON(wdev->netdev))
790 return; 711 return;
791 712
792 mutex_lock(&rdev->devlist_mtx);
793 mutex_lock(&rdev->sched_scan_mtx);
794 list_del_rcu(&wdev->list); 713 list_del_rcu(&wdev->list);
795 rdev->devlist_generation++; 714 rdev->devlist_generation++;
796 715
@@ -802,8 +721,6 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
802 WARN_ON_ONCE(1); 721 WARN_ON_ONCE(1);
803 break; 722 break;
804 } 723 }
805 mutex_unlock(&rdev->sched_scan_mtx);
806 mutex_unlock(&rdev->devlist_mtx);
807} 724}
808EXPORT_SYMBOL(cfg80211_unregister_wdev); 725EXPORT_SYMBOL(cfg80211_unregister_wdev);
809 726
@@ -822,7 +739,7 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
822} 739}
823 740
824void cfg80211_leave(struct cfg80211_registered_device *rdev, 741void cfg80211_leave(struct cfg80211_registered_device *rdev,
825 struct wireless_dev *wdev) 742 struct wireless_dev *wdev)
826{ 743{
827 struct net_device *dev = wdev->netdev; 744 struct net_device *dev = wdev->netdev;
828 745
@@ -832,9 +749,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
832 break; 749 break;
833 case NL80211_IFTYPE_P2P_CLIENT: 750 case NL80211_IFTYPE_P2P_CLIENT:
834 case NL80211_IFTYPE_STATION: 751 case NL80211_IFTYPE_STATION:
835 mutex_lock(&rdev->sched_scan_mtx);
836 __cfg80211_stop_sched_scan(rdev, false); 752 __cfg80211_stop_sched_scan(rdev, false);
837 mutex_unlock(&rdev->sched_scan_mtx);
838 753
839 wdev_lock(wdev); 754 wdev_lock(wdev);
840#ifdef CONFIG_CFG80211_WEXT 755#ifdef CONFIG_CFG80211_WEXT
@@ -887,13 +802,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
887 * are added with nl80211. 802 * are added with nl80211.
888 */ 803 */
889 mutex_init(&wdev->mtx); 804 mutex_init(&wdev->mtx);
890 INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work);
891 INIT_LIST_HEAD(&wdev->event_list); 805 INIT_LIST_HEAD(&wdev->event_list);
892 spin_lock_init(&wdev->event_lock); 806 spin_lock_init(&wdev->event_lock);
893 INIT_LIST_HEAD(&wdev->mgmt_registrations); 807 INIT_LIST_HEAD(&wdev->mgmt_registrations);
894 spin_lock_init(&wdev->mgmt_registrations_lock); 808 spin_lock_init(&wdev->mgmt_registrations_lock);
895 809
896 mutex_lock(&rdev->devlist_mtx);
897 wdev->identifier = ++rdev->wdev_id; 810 wdev->identifier = ++rdev->wdev_id;
898 list_add_rcu(&wdev->list, &rdev->wdev_list); 811 list_add_rcu(&wdev->list, &rdev->wdev_list);
899 rdev->devlist_generation++; 812 rdev->devlist_generation++;
@@ -906,7 +819,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
906 } 819 }
907 wdev->netdev = dev; 820 wdev->netdev = dev;
908 wdev->sme_state = CFG80211_SME_IDLE; 821 wdev->sme_state = CFG80211_SME_IDLE;
909 mutex_unlock(&rdev->devlist_mtx);
910#ifdef CONFIG_CFG80211_WEXT 822#ifdef CONFIG_CFG80211_WEXT
911 wdev->wext.default_key = -1; 823 wdev->wext.default_key = -1;
912 wdev->wext.default_mgmt_key = -1; 824 wdev->wext.default_mgmt_key = -1;
@@ -932,26 +844,22 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
932 break; 844 break;
933 case NETDEV_DOWN: 845 case NETDEV_DOWN:
934 cfg80211_update_iface_num(rdev, wdev->iftype, -1); 846 cfg80211_update_iface_num(rdev, wdev->iftype, -1);
935 dev_hold(dev); 847 if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
936 queue_work(cfg80211_wq, &wdev->cleanup_work); 848 if (WARN_ON(!rdev->scan_req->notified))
849 rdev->scan_req->aborted = true;
850 ___cfg80211_scan_done(rdev, true);
851 }
852
853 if (WARN_ON(rdev->sched_scan_req &&
854 rdev->sched_scan_req->dev == wdev->netdev)) {
855 __cfg80211_stop_sched_scan(rdev, false);
856 }
857
858 rdev->opencount--;
859 wake_up(&rdev->dev_wait);
937 break; 860 break;
938 case NETDEV_UP: 861 case NETDEV_UP:
939 /*
940 * If we have a really quick DOWN/UP succession we may
941 * have this work still pending ... cancel it and see
942 * if it was pending, in which case we need to account
943 * for some of the work it would have done.
944 */
945 if (cancel_work_sync(&wdev->cleanup_work)) {
946 mutex_lock(&rdev->devlist_mtx);
947 rdev->opencount--;
948 mutex_unlock(&rdev->devlist_mtx);
949 dev_put(dev);
950 }
951 cfg80211_update_iface_num(rdev, wdev->iftype, 1); 862 cfg80211_update_iface_num(rdev, wdev->iftype, 1);
952 cfg80211_lock_rdev(rdev);
953 mutex_lock(&rdev->devlist_mtx);
954 mutex_lock(&rdev->sched_scan_mtx);
955 wdev_lock(wdev); 863 wdev_lock(wdev);
956 switch (wdev->iftype) { 864 switch (wdev->iftype) {
957#ifdef CONFIG_CFG80211_WEXT 865#ifdef CONFIG_CFG80211_WEXT
@@ -983,10 +891,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
983 break; 891 break;
984 } 892 }
985 wdev_unlock(wdev); 893 wdev_unlock(wdev);
986 mutex_unlock(&rdev->sched_scan_mtx);
987 rdev->opencount++; 894 rdev->opencount++;
988 mutex_unlock(&rdev->devlist_mtx);
989 cfg80211_unlock_rdev(rdev);
990 895
991 /* 896 /*
992 * Configure power management to the driver here so that its 897 * Configure power management to the driver here so that its
@@ -1003,12 +908,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1003 break; 908 break;
1004 case NETDEV_UNREGISTER: 909 case NETDEV_UNREGISTER:
1005 /* 910 /*
1006 * NB: cannot take rdev->mtx here because this may be
1007 * called within code protected by it when interfaces
1008 * are removed with nl80211.
1009 */
1010 mutex_lock(&rdev->devlist_mtx);
1011 /*
1012 * It is possible to get NETDEV_UNREGISTER 911 * It is possible to get NETDEV_UNREGISTER
1013 * multiple times. To detect that, check 912 * multiple times. To detect that, check
1014 * that the interface is still on the list 913 * that the interface is still on the list
@@ -1024,7 +923,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1024 kfree(wdev->wext.keys); 923 kfree(wdev->wext.keys);
1025#endif 924#endif
1026 } 925 }
1027 mutex_unlock(&rdev->devlist_mtx);
1028 /* 926 /*
1029 * synchronise (so that we won't find this netdev 927 * synchronise (so that we won't find this netdev
1030 * from other code any more) and then clear the list 928 * from other code any more) and then clear the list
@@ -1044,9 +942,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1044 return notifier_from_errno(-EOPNOTSUPP); 942 return notifier_from_errno(-EOPNOTSUPP);
1045 if (rfkill_blocked(rdev->rfkill)) 943 if (rfkill_blocked(rdev->rfkill))
1046 return notifier_from_errno(-ERFKILL); 944 return notifier_from_errno(-ERFKILL);
1047 mutex_lock(&rdev->devlist_mtx);
1048 ret = cfg80211_can_add_interface(rdev, wdev->iftype); 945 ret = cfg80211_can_add_interface(rdev, wdev->iftype);
1049 mutex_unlock(&rdev->devlist_mtx);
1050 if (ret) 946 if (ret)
1051 return notifier_from_errno(ret); 947 return notifier_from_errno(ret);
1052 break; 948 break;
@@ -1064,12 +960,10 @@ static void __net_exit cfg80211_pernet_exit(struct net *net)
1064 struct cfg80211_registered_device *rdev; 960 struct cfg80211_registered_device *rdev;
1065 961
1066 rtnl_lock(); 962 rtnl_lock();
1067 mutex_lock(&cfg80211_mutex);
1068 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 963 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1069 if (net_eq(wiphy_net(&rdev->wiphy), net)) 964 if (net_eq(wiphy_net(&rdev->wiphy), net))
1070 WARN_ON(cfg80211_switch_netns(rdev, &init_net)); 965 WARN_ON(cfg80211_switch_netns(rdev, &init_net));
1071 } 966 }
1072 mutex_unlock(&cfg80211_mutex);
1073 rtnl_unlock(); 967 rtnl_unlock();
1074} 968}
1075 969
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 95b29075a9c8..d21a0fc01401 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
@@ -120,15 +110,9 @@ cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
120} 110}
121 111
122extern struct workqueue_struct *cfg80211_wq; 112extern struct workqueue_struct *cfg80211_wq;
123extern struct mutex cfg80211_mutex;
124extern struct list_head cfg80211_rdev_list; 113extern struct list_head cfg80211_rdev_list;
125extern int cfg80211_rdev_list_generation; 114extern int cfg80211_rdev_list_generation;
126 115
127static inline void assert_cfg80211_lock(void)
128{
129 lockdep_assert_held(&cfg80211_mutex);
130}
131
132struct cfg80211_internal_bss { 116struct cfg80211_internal_bss {
133 struct list_head list; 117 struct list_head list;
134 struct list_head hidden_list; 118 struct list_head hidden_list;
@@ -161,23 +145,11 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
161struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); 145struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
162int get_wiphy_idx(struct wiphy *wiphy); 146int get_wiphy_idx(struct wiphy *wiphy);
163 147
164/* requires cfg80211_rdev_mutex to be held! */
165struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); 148struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
166 149
167int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, 150int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
168 struct net *net); 151 struct net *net);
169 152
170static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev)
171{
172 mutex_lock(&rdev->mtx);
173}
174
175static inline void cfg80211_unlock_rdev(struct cfg80211_registered_device *rdev)
176{
177 BUG_ON(IS_ERR(rdev) || !rdev);
178 mutex_unlock(&rdev->mtx);
179}
180
181static inline void wdev_lock(struct wireless_dev *wdev) 153static inline void wdev_lock(struct wireless_dev *wdev)
182 __acquires(wdev) 154 __acquires(wdev)
183{ 155{
@@ -192,7 +164,7 @@ static inline void wdev_unlock(struct wireless_dev *wdev)
192 mutex_unlock(&wdev->mtx); 164 mutex_unlock(&wdev->mtx);
193} 165}
194 166
195#define ASSERT_RDEV_LOCK(rdev) lockdep_assert_held(&(rdev)->mtx) 167#define ASSERT_RDEV_LOCK(rdev) ASSERT_RTNL()
196#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx) 168#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx)
197 169
198static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev) 170static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev)
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 9546ad210550..5dfb289ab761 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -186,11 +186,9 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
186 struct wireless_dev *wdev = dev->ieee80211_ptr; 186 struct wireless_dev *wdev = dev->ieee80211_ptr;
187 int err; 187 int err;
188 188
189 mutex_lock(&rdev->devlist_mtx);
190 wdev_lock(wdev); 189 wdev_lock(wdev);
191 err = __cfg80211_join_mesh(rdev, dev, setup, conf); 190 err = __cfg80211_join_mesh(rdev, dev, setup, conf);
192 wdev_unlock(wdev); 191 wdev_unlock(wdev);
193 mutex_unlock(&rdev->devlist_mtx);
194 192
195 return err; 193 return err;
196} 194}
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index c21e32f9549c..68b40f21bc38 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -313,14 +313,14 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
313{ 313{
314 int err; 314 int err;
315 315
316 mutex_lock(&rdev->devlist_mtx); 316 ASSERT_RTNL();
317
317 wdev_lock(dev->ieee80211_ptr); 318 wdev_lock(dev->ieee80211_ptr);
318 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 319 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
319 ssid, ssid_len, ie, ie_len, 320 ssid, ssid_len, ie, ie_len,
320 key, key_len, key_idx, 321 key, key_len, key_idx,
321 sae_data, sae_data_len); 322 sae_data, sae_data_len);
322 wdev_unlock(dev->ieee80211_ptr); 323 wdev_unlock(dev->ieee80211_ptr);
323 mutex_unlock(&rdev->devlist_mtx);
324 324
325 return err; 325 return err;
326} 326}
@@ -424,12 +424,12 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
424 struct wireless_dev *wdev = dev->ieee80211_ptr; 424 struct wireless_dev *wdev = dev->ieee80211_ptr;
425 int err; 425 int err;
426 426
427 mutex_lock(&rdev->devlist_mtx); 427 ASSERT_RTNL();
428
428 wdev_lock(wdev); 429 wdev_lock(wdev);
429 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, 430 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid,
430 ssid, ssid_len, req); 431 ssid, ssid_len, req);
431 wdev_unlock(wdev); 432 wdev_unlock(wdev);
432 mutex_unlock(&rdev->devlist_mtx);
433 433
434 return err; 434 return err;
435} 435}
@@ -844,7 +844,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
844 dfs_update_channels_wk); 844 dfs_update_channels_wk);
845 wiphy = &rdev->wiphy; 845 wiphy = &rdev->wiphy;
846 846
847 mutex_lock(&cfg80211_mutex); 847 rtnl_lock();
848 for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) { 848 for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) {
849 sband = wiphy->bands[bandid]; 849 sband = wiphy->bands[bandid];
850 if (!sband) 850 if (!sband)
@@ -877,7 +877,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
877 check_again = true; 877 check_again = true;
878 } 878 }
879 } 879 }
880 mutex_unlock(&cfg80211_mutex); 880 rtnl_unlock();
881 881
882 /* reschedule if there are other channels waiting to be cleared again */ 882 /* reschedule if there are other channels waiting to be cleared again */
883 if (check_again) 883 if (check_again)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5bcf3a5b6465..74cdb1a0cf31 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -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 */
@@ -456,7 +426,6 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
456 int err; 426 int err;
457 427
458 rtnl_lock(); 428 rtnl_lock();
459 mutex_lock(&cfg80211_mutex);
460 429
461 if (!cb->args[0]) { 430 if (!cb->args[0]) {
462 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 431 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
@@ -485,14 +454,12 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
485 *rdev = wiphy_to_dev(wiphy); 454 *rdev = wiphy_to_dev(wiphy);
486 *wdev = NULL; 455 *wdev = NULL;
487 456
488 mutex_lock(&(*rdev)->devlist_mtx);
489 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { 457 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) {
490 if (tmp->identifier == cb->args[1]) { 458 if (tmp->identifier == cb->args[1]) {
491 *wdev = tmp; 459 *wdev = tmp;
492 break; 460 break;
493 } 461 }
494 } 462 }
495 mutex_unlock(&(*rdev)->devlist_mtx);
496 463
497 if (!*wdev) { 464 if (!*wdev) {
498 err = -ENODEV; 465 err = -ENODEV;
@@ -500,19 +467,14 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
500 } 467 }
501 } 468 }
502 469
503 cfg80211_lock_rdev(*rdev);
504
505 mutex_unlock(&cfg80211_mutex);
506 return 0; 470 return 0;
507 out_unlock: 471 out_unlock:
508 mutex_unlock(&cfg80211_mutex);
509 rtnl_unlock(); 472 rtnl_unlock();
510 return err; 473 return err;
511} 474}
512 475
513static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev) 476static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
514{ 477{
515 cfg80211_unlock_rdev(rdev);
516 rtnl_unlock(); 478 rtnl_unlock();
517} 479}
518 480
@@ -1568,7 +1530,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1568 struct nlattr **tb = nl80211_fam.attrbuf; 1530 struct nlattr **tb = nl80211_fam.attrbuf;
1569 int res; 1531 int res;
1570 1532
1571 mutex_lock(&cfg80211_mutex); 1533 rtnl_lock();
1572 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 1534 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1573 tb, nl80211_fam.maxattr, nl80211_policy); 1535 tb, nl80211_fam.maxattr, nl80211_policy);
1574 if (res == 0) { 1536 if (res == 0) {
@@ -1582,10 +1544,8 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1582 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); 1544 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1583 1545
1584 netdev = dev_get_by_index(sock_net(skb->sk), ifidx); 1546 netdev = dev_get_by_index(sock_net(skb->sk), ifidx);
1585 if (!netdev) { 1547 if (!netdev)
1586 mutex_unlock(&cfg80211_mutex);
1587 return -ENODEV; 1548 return -ENODEV;
1588 }
1589 if (netdev->ieee80211_ptr) { 1549 if (netdev->ieee80211_ptr) {
1590 dev = wiphy_to_dev( 1550 dev = wiphy_to_dev(
1591 netdev->ieee80211_ptr->wiphy); 1551 netdev->ieee80211_ptr->wiphy);
@@ -1629,7 +1589,6 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1629 !skb->len && 1589 !skb->len &&
1630 cb->min_dump_alloc < 4096) { 1590 cb->min_dump_alloc < 4096) {
1631 cb->min_dump_alloc = 4096; 1591 cb->min_dump_alloc = 4096;
1632 mutex_unlock(&cfg80211_mutex);
1633 return 1; 1592 return 1;
1634 } 1593 }
1635 idx--; 1594 idx--;
@@ -1638,7 +1597,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1638 } while (cb->args[1] > 0); 1597 } while (cb->args[1] > 0);
1639 break; 1598 break;
1640 } 1599 }
1641 mutex_unlock(&cfg80211_mutex); 1600 rtnl_unlock();
1642 1601
1643 cb->args[0] = idx; 1602 cb->args[0] = idx;
1644 1603
@@ -1793,7 +1752,6 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1793 if (result) 1752 if (result)
1794 return result; 1753 return result;
1795 1754
1796 mutex_lock(&rdev->devlist_mtx);
1797 switch (iftype) { 1755 switch (iftype) {
1798 case NL80211_IFTYPE_AP: 1756 case NL80211_IFTYPE_AP:
1799 case NL80211_IFTYPE_P2P_GO: 1757 case NL80211_IFTYPE_P2P_GO:
@@ -1817,7 +1775,6 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1817 default: 1775 default:
1818 result = -EINVAL; 1776 result = -EINVAL;
1819 } 1777 }
1820 mutex_unlock(&rdev->devlist_mtx);
1821 1778
1822 return result; 1779 return result;
1823} 1780}
@@ -1866,6 +1823,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1866 u32 frag_threshold = 0, rts_threshold = 0; 1823 u32 frag_threshold = 0, rts_threshold = 0;
1867 u8 coverage_class = 0; 1824 u8 coverage_class = 0;
1868 1825
1826 ASSERT_RTNL();
1827
1869 /* 1828 /*
1870 * Try to find the wiphy and netdev. Normally this 1829 * Try to find the wiphy and netdev. Normally this
1871 * function shouldn't need the netdev, but this is 1830 * function shouldn't need the netdev, but this is
@@ -1875,31 +1834,25 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1875 * also passed a netdev to set_wiphy, so that it is 1834 * also passed a netdev to set_wiphy, so that it is
1876 * possible to let that go to the right netdev! 1835 * possible to let that go to the right netdev!
1877 */ 1836 */
1878 mutex_lock(&cfg80211_mutex);
1879 1837
1880 if (info->attrs[NL80211_ATTR_IFINDEX]) { 1838 if (info->attrs[NL80211_ATTR_IFINDEX]) {
1881 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); 1839 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
1882 1840
1883 netdev = dev_get_by_index(genl_info_net(info), ifindex); 1841 netdev = dev_get_by_index(genl_info_net(info), ifindex);
1884 if (netdev && netdev->ieee80211_ptr) { 1842 if (netdev && netdev->ieee80211_ptr)
1885 rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy); 1843 rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy);
1886 mutex_lock(&rdev->mtx); 1844 else
1887 } else
1888 netdev = NULL; 1845 netdev = NULL;
1889 } 1846 }
1890 1847
1891 if (!netdev) { 1848 if (!netdev) {
1892 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info), 1849 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
1893 info->attrs); 1850 info->attrs);
1894 if (IS_ERR(rdev)) { 1851 if (IS_ERR(rdev))
1895 mutex_unlock(&cfg80211_mutex);
1896 return PTR_ERR(rdev); 1852 return PTR_ERR(rdev);
1897 }
1898 wdev = NULL; 1853 wdev = NULL;
1899 netdev = NULL; 1854 netdev = NULL;
1900 result = 0; 1855 result = 0;
1901
1902 mutex_lock(&rdev->mtx);
1903 } else 1856 } else
1904 wdev = netdev->ieee80211_ptr; 1857 wdev = netdev->ieee80211_ptr;
1905 1858
@@ -1912,8 +1865,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1912 result = cfg80211_dev_rename( 1865 result = cfg80211_dev_rename(
1913 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); 1866 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
1914 1867
1915 mutex_unlock(&cfg80211_mutex);
1916
1917 if (result) 1868 if (result)
1918 goto bad_res; 1869 goto bad_res;
1919 1870
@@ -2120,7 +2071,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2120 } 2071 }
2121 2072
2122 bad_res: 2073 bad_res:
2123 mutex_unlock(&rdev->mtx);
2124 if (netdev) 2074 if (netdev)
2125 dev_put(netdev); 2075 dev_put(netdev);
2126 return result; 2076 return result;
@@ -2218,7 +2168,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2218 struct cfg80211_registered_device *rdev; 2168 struct cfg80211_registered_device *rdev;
2219 struct wireless_dev *wdev; 2169 struct wireless_dev *wdev;
2220 2170
2221 mutex_lock(&cfg80211_mutex); 2171 rtnl_lock();
2222 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 2172 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2223 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk))) 2173 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
2224 continue; 2174 continue;
@@ -2228,7 +2178,6 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2228 } 2178 }
2229 if_idx = 0; 2179 if_idx = 0;
2230 2180
2231 mutex_lock(&rdev->devlist_mtx);
2232 list_for_each_entry(wdev, &rdev->wdev_list, list) { 2181 list_for_each_entry(wdev, &rdev->wdev_list, list) {
2233 if (if_idx < if_start) { 2182 if (if_idx < if_start) {
2234 if_idx++; 2183 if_idx++;
@@ -2237,17 +2186,15 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2237 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid, 2186 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
2238 cb->nlh->nlmsg_seq, NLM_F_MULTI, 2187 cb->nlh->nlmsg_seq, NLM_F_MULTI,
2239 rdev, wdev) < 0) { 2188 rdev, wdev) < 0) {
2240 mutex_unlock(&rdev->devlist_mtx);
2241 goto out; 2189 goto out;
2242 } 2190 }
2243 if_idx++; 2191 if_idx++;
2244 } 2192 }
2245 mutex_unlock(&rdev->devlist_mtx);
2246 2193
2247 wp_idx++; 2194 wp_idx++;
2248 } 2195 }
2249 out: 2196 out:
2250 mutex_unlock(&cfg80211_mutex); 2197 rtnl_unlock();
2251 2198
2252 cb->args[0] = wp_idx; 2199 cb->args[0] = wp_idx;
2253 cb->args[1] = if_idx; 2200 cb->args[1] = if_idx;
@@ -2480,11 +2427,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2480 INIT_LIST_HEAD(&wdev->mgmt_registrations); 2427 INIT_LIST_HEAD(&wdev->mgmt_registrations);
2481 spin_lock_init(&wdev->mgmt_registrations_lock); 2428 spin_lock_init(&wdev->mgmt_registrations_lock);
2482 2429
2483 mutex_lock(&rdev->devlist_mtx);
2484 wdev->identifier = ++rdev->wdev_id; 2430 wdev->identifier = ++rdev->wdev_id;
2485 list_add_rcu(&wdev->list, &rdev->wdev_list); 2431 list_add_rcu(&wdev->list, &rdev->wdev_list);
2486 rdev->devlist_generation++; 2432 rdev->devlist_generation++;
2487 mutex_unlock(&rdev->devlist_mtx);
2488 break; 2433 break;
2489 default: 2434 default:
2490 break; 2435 break;
@@ -2993,8 +2938,6 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
2993 struct wireless_dev *wdev; 2938 struct wireless_dev *wdev;
2994 bool ret = false; 2939 bool ret = false;
2995 2940
2996 mutex_lock(&rdev->devlist_mtx);
2997
2998 list_for_each_entry(wdev, &rdev->wdev_list, list) { 2941 list_for_each_entry(wdev, &rdev->wdev_list, list) {
2999 if (wdev->iftype != NL80211_IFTYPE_AP && 2942 if (wdev->iftype != NL80211_IFTYPE_AP &&
3000 wdev->iftype != NL80211_IFTYPE_P2P_GO) 2943 wdev->iftype != NL80211_IFTYPE_P2P_GO)
@@ -3008,8 +2951,6 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
3008 break; 2951 break;
3009 } 2952 }
3010 2953
3011 mutex_unlock(&rdev->devlist_mtx);
3012
3013 return ret; 2954 return ret;
3014} 2955}
3015 2956
@@ -3171,13 +3112,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3171 params.radar_required = true; 3112 params.radar_required = true;
3172 } 3113 }
3173 3114
3174 mutex_lock(&rdev->devlist_mtx);
3175 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 3115 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
3176 params.chandef.chan, 3116 params.chandef.chan,
3177 CHAN_MODE_SHARED, 3117 CHAN_MODE_SHARED,
3178 radar_detect_width); 3118 radar_detect_width);
3179 mutex_unlock(&rdev->devlist_mtx);
3180
3181 if (err) 3119 if (err)
3182 return err; 3120 return err;
3183 3121
@@ -4914,18 +4852,13 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
4914 void *hdr = NULL; 4852 void *hdr = NULL;
4915 struct nlattr *nl_reg_rules; 4853 struct nlattr *nl_reg_rules;
4916 unsigned int i; 4854 unsigned int i;
4917 int err = -EINVAL;
4918
4919 mutex_lock(&cfg80211_mutex);
4920 4855
4921 if (!cfg80211_regdomain) 4856 if (!cfg80211_regdomain)
4922 goto out; 4857 return -EINVAL;
4923 4858
4924 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4859 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4925 if (!msg) { 4860 if (!msg)
4926 err = -ENOBUFS; 4861 return -ENOBUFS;
4927 goto out;
4928 }
4929 4862
4930 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, 4863 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
4931 NL80211_CMD_GET_REG); 4864 NL80211_CMD_GET_REG);
@@ -4984,8 +4917,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
4984 nla_nest_end(msg, nl_reg_rules); 4917 nla_nest_end(msg, nl_reg_rules);
4985 4918
4986 genlmsg_end(msg, hdr); 4919 genlmsg_end(msg, hdr);
4987 err = genlmsg_reply(msg, info); 4920 return genlmsg_reply(msg, info);
4988 goto out;
4989 4921
4990nla_put_failure_rcu: 4922nla_put_failure_rcu:
4991 rcu_read_unlock(); 4923 rcu_read_unlock();
@@ -4993,10 +4925,7 @@ nla_put_failure:
4993 genlmsg_cancel(msg, hdr); 4925 genlmsg_cancel(msg, hdr);
4994put_failure: 4926put_failure:
4995 nlmsg_free(msg); 4927 nlmsg_free(msg);
4996 err = -EMSGSIZE; 4928 return -EMSGSIZE;
4997out:
4998 mutex_unlock(&cfg80211_mutex);
4999 return err;
5000} 4929}
5001 4930
5002static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) 4931static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
@@ -5062,12 +4991,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
5062 } 4991 }
5063 } 4992 }
5064 4993
5065 mutex_lock(&cfg80211_mutex);
5066
5067 r = set_regdom(rd); 4994 r = set_regdom(rd);
5068 /* set_regdom took ownership */ 4995 /* set_regdom took ownership */
5069 rd = NULL; 4996 rd = NULL;
5070 mutex_unlock(&cfg80211_mutex);
5071 4997
5072 bad_reg: 4998 bad_reg:
5073 kfree(rd); 4999 kfree(rd);
@@ -5117,7 +5043,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5117 if (!rdev->ops->scan) 5043 if (!rdev->ops->scan)
5118 return -EOPNOTSUPP; 5044 return -EOPNOTSUPP;
5119 5045
5120 mutex_lock(&rdev->sched_scan_mtx);
5121 if (rdev->scan_req) { 5046 if (rdev->scan_req) {
5122 err = -EBUSY; 5047 err = -EBUSY;
5123 goto unlock; 5048 goto unlock;
@@ -5303,7 +5228,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5303 } 5228 }
5304 5229
5305 unlock: 5230 unlock:
5306 mutex_unlock(&rdev->sched_scan_mtx);
5307 return err; 5231 return err;
5308} 5232}
5309 5233
@@ -5375,8 +5299,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
5375 if (ie_len > wiphy->max_sched_scan_ie_len) 5299 if (ie_len > wiphy->max_sched_scan_ie_len)
5376 return -EINVAL; 5300 return -EINVAL;
5377 5301
5378 mutex_lock(&rdev->sched_scan_mtx);
5379
5380 if (rdev->sched_scan_req) { 5302 if (rdev->sched_scan_req) {
5381 err = -EINPROGRESS; 5303 err = -EINPROGRESS;
5382 goto out; 5304 goto out;
@@ -5544,7 +5466,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
5544out_free: 5466out_free:
5545 kfree(request); 5467 kfree(request);
5546out: 5468out:
5547 mutex_unlock(&rdev->sched_scan_mtx);
5548 return err; 5469 return err;
5549} 5470}
5550 5471
@@ -5552,17 +5473,12 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb,
5552 struct genl_info *info) 5473 struct genl_info *info)
5553{ 5474{
5554 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 5475 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5555 int err;
5556 5476
5557 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || 5477 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
5558 !rdev->ops->sched_scan_stop) 5478 !rdev->ops->sched_scan_stop)
5559 return -EOPNOTSUPP; 5479 return -EOPNOTSUPP;
5560 5480
5561 mutex_lock(&rdev->sched_scan_mtx); 5481 return __cfg80211_stop_sched_scan(rdev, false);
5562 err = __cfg80211_stop_sched_scan(rdev, false);
5563 mutex_unlock(&rdev->sched_scan_mtx);
5564
5565 return err;
5566} 5482}
5567 5483
5568static int nl80211_start_radar_detection(struct sk_buff *skb, 5484static int nl80211_start_radar_detection(struct sk_buff *skb,
@@ -5594,12 +5510,11 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
5594 if (!rdev->ops->start_radar_detection) 5510 if (!rdev->ops->start_radar_detection)
5595 return -EOPNOTSUPP; 5511 return -EOPNOTSUPP;
5596 5512
5597 mutex_lock(&rdev->devlist_mtx);
5598 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 5513 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
5599 chandef.chan, CHAN_MODE_SHARED, 5514 chandef.chan, CHAN_MODE_SHARED,
5600 BIT(chandef.width)); 5515 BIT(chandef.width));
5601 if (err) 5516 if (err)
5602 goto err_locked; 5517 return err;
5603 5518
5604 err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef); 5519 err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
5605 if (!err) { 5520 if (!err) {
@@ -5607,9 +5522,6 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
5607 wdev->cac_started = true; 5522 wdev->cac_started = true;
5608 wdev->cac_start_time = jiffies; 5523 wdev->cac_start_time = jiffies;
5609 } 5524 }
5610err_locked:
5611 mutex_unlock(&rdev->devlist_mtx);
5612
5613 return err; 5525 return err;
5614} 5526}
5615 5527
@@ -6472,6 +6384,8 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6472 void *data = NULL; 6384 void *data = NULL;
6473 int data_len = 0; 6385 int data_len = 0;
6474 6386
6387 rtnl_lock();
6388
6475 if (cb->args[0]) { 6389 if (cb->args[0]) {
6476 /* 6390 /*
6477 * 0 is a valid index, but not valid for args[0], 6391 * 0 is a valid index, but not valid for args[0],
@@ -6483,18 +6397,16 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6483 nl80211_fam.attrbuf, nl80211_fam.maxattr, 6397 nl80211_fam.attrbuf, nl80211_fam.maxattr,
6484 nl80211_policy); 6398 nl80211_policy);
6485 if (err) 6399 if (err)
6486 return err; 6400 goto out_err;
6487 6401
6488 mutex_lock(&cfg80211_mutex);
6489 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), 6402 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
6490 nl80211_fam.attrbuf); 6403 nl80211_fam.attrbuf);
6491 if (IS_ERR(rdev)) { 6404 if (IS_ERR(rdev)) {
6492 mutex_unlock(&cfg80211_mutex); 6405 err = PTR_ERR(rdev);
6493 return PTR_ERR(rdev); 6406 goto out_err;
6494 } 6407 }
6495 phy_idx = rdev->wiphy_idx; 6408 phy_idx = rdev->wiphy_idx;
6496 rdev = NULL; 6409 rdev = NULL;
6497 mutex_unlock(&cfg80211_mutex);
6498 6410
6499 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) 6411 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
6500 cb->args[1] = 6412 cb->args[1] =
@@ -6506,14 +6418,11 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6506 data_len = nla_len((void *)cb->args[1]); 6418 data_len = nla_len((void *)cb->args[1]);
6507 } 6419 }
6508 6420
6509 mutex_lock(&cfg80211_mutex);
6510 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx); 6421 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
6511 if (!rdev) { 6422 if (!rdev) {
6512 mutex_unlock(&cfg80211_mutex); 6423 err = -ENOENT;
6513 return -ENOENT; 6424 goto out_err;
6514 } 6425 }
6515 cfg80211_lock_rdev(rdev);
6516 mutex_unlock(&cfg80211_mutex);
6517 6426
6518 if (!rdev->ops->testmode_dump) { 6427 if (!rdev->ops->testmode_dump) {
6519 err = -EOPNOTSUPP; 6428 err = -EOPNOTSUPP;
@@ -6554,7 +6463,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6554 /* see above */ 6463 /* see above */
6555 cb->args[0] = phy_idx + 1; 6464 cb->args[0] = phy_idx + 1;
6556 out_err: 6465 out_err:
6557 cfg80211_unlock_rdev(rdev); 6466 rtnl_unlock();
6558 return err; 6467 return err;
6559} 6468}
6560 6469
@@ -8189,9 +8098,7 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
8189 if (wdev->p2p_started) 8098 if (wdev->p2p_started)
8190 return 0; 8099 return 0;
8191 8100
8192 mutex_lock(&rdev->devlist_mtx);
8193 err = cfg80211_can_add_interface(rdev, wdev->iftype); 8101 err = cfg80211_can_add_interface(rdev, wdev->iftype);
8194 mutex_unlock(&rdev->devlist_mtx);
8195 if (err) 8102 if (err)
8196 return err; 8103 return err;
8197 8104
@@ -8200,9 +8107,7 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
8200 return err; 8107 return err;
8201 8108
8202 wdev->p2p_started = true; 8109 wdev->p2p_started = true;
8203 mutex_lock(&rdev->devlist_mtx);
8204 rdev->opencount++; 8110 rdev->opencount++;
8205 mutex_unlock(&rdev->devlist_mtx);
8206 8111
8207 return 0; 8112 return 0;
8208} 8113}
@@ -8218,11 +8123,7 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
8218 if (!rdev->ops->stop_p2p_device) 8123 if (!rdev->ops->stop_p2p_device)
8219 return -EOPNOTSUPP; 8124 return -EOPNOTSUPP;
8220 8125
8221 mutex_lock(&rdev->devlist_mtx);
8222 mutex_lock(&rdev->sched_scan_mtx);
8223 cfg80211_stop_p2p_device(rdev, wdev); 8126 cfg80211_stop_p2p_device(rdev, wdev);
8224 mutex_unlock(&rdev->sched_scan_mtx);
8225 mutex_unlock(&rdev->devlist_mtx);
8226 8127
8227 return 0; 8128 return 0;
8228} 8129}
@@ -8365,11 +8266,11 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8365 info->user_ptr[0] = rdev; 8266 info->user_ptr[0] = rdev;
8366 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV || 8267 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
8367 ops->internal_flags & NL80211_FLAG_NEED_WDEV) { 8268 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
8368 mutex_lock(&cfg80211_mutex); 8269 ASSERT_RTNL();
8270
8369 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info), 8271 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
8370 info->attrs); 8272 info->attrs);
8371 if (IS_ERR(wdev)) { 8273 if (IS_ERR(wdev)) {
8372 mutex_unlock(&cfg80211_mutex);
8373 if (rtnl) 8274 if (rtnl)
8374 rtnl_unlock(); 8275 rtnl_unlock();
8375 return PTR_ERR(wdev); 8276 return PTR_ERR(wdev);
@@ -8380,7 +8281,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8380 8281
8381 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { 8282 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
8382 if (!dev) { 8283 if (!dev) {
8383 mutex_unlock(&cfg80211_mutex);
8384 if (rtnl) 8284 if (rtnl)
8385 rtnl_unlock(); 8285 rtnl_unlock();
8386 return -EINVAL; 8286 return -EINVAL;
@@ -8394,7 +8294,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8394 if (dev) { 8294 if (dev) {
8395 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && 8295 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
8396 !netif_running(dev)) { 8296 !netif_running(dev)) {
8397 mutex_unlock(&cfg80211_mutex);
8398 if (rtnl) 8297 if (rtnl)
8399 rtnl_unlock(); 8298 rtnl_unlock();
8400 return -ENETDOWN; 8299 return -ENETDOWN;
@@ -8403,17 +8302,12 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8403 dev_hold(dev); 8302 dev_hold(dev);
8404 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) { 8303 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) {
8405 if (!wdev->p2p_started) { 8304 if (!wdev->p2p_started) {
8406 mutex_unlock(&cfg80211_mutex);
8407 if (rtnl) 8305 if (rtnl)
8408 rtnl_unlock(); 8306 rtnl_unlock();
8409 return -ENETDOWN; 8307 return -ENETDOWN;
8410 } 8308 }
8411 } 8309 }
8412 8310
8413 cfg80211_lock_rdev(rdev);
8414
8415 mutex_unlock(&cfg80211_mutex);
8416
8417 info->user_ptr[0] = rdev; 8311 info->user_ptr[0] = rdev;
8418 } 8312 }
8419 8313
@@ -8423,8 +8317,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8423static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, 8317static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
8424 struct genl_info *info) 8318 struct genl_info *info)
8425{ 8319{
8426 if (info->user_ptr[0])
8427 cfg80211_unlock_rdev(info->user_ptr[0]);
8428 if (info->user_ptr[1]) { 8320 if (info->user_ptr[1]) {
8429 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) { 8321 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
8430 struct wireless_dev *wdev = info->user_ptr[1]; 8322 struct wireless_dev *wdev = info->user_ptr[1];
@@ -8446,7 +8338,8 @@ static struct genl_ops nl80211_ops[] = {
8446 .dumpit = nl80211_dump_wiphy, 8338 .dumpit = nl80211_dump_wiphy,
8447 .policy = nl80211_policy, 8339 .policy = nl80211_policy,
8448 /* can be retrieved by unprivileged users */ 8340 /* can be retrieved by unprivileged users */
8449 .internal_flags = NL80211_FLAG_NEED_WIPHY, 8341 .internal_flags = NL80211_FLAG_NEED_WIPHY |
8342 NL80211_FLAG_NEED_RTNL,
8450 }, 8343 },
8451 { 8344 {
8452 .cmd = NL80211_CMD_SET_WIPHY, 8345 .cmd = NL80211_CMD_SET_WIPHY,
@@ -8461,7 +8354,8 @@ static struct genl_ops nl80211_ops[] = {
8461 .dumpit = nl80211_dump_interface, 8354 .dumpit = nl80211_dump_interface,
8462 .policy = nl80211_policy, 8355 .policy = nl80211_policy,
8463 /* can be retrieved by unprivileged users */ 8356 /* can be retrieved by unprivileged users */
8464 .internal_flags = NL80211_FLAG_NEED_WDEV, 8357 .internal_flags = NL80211_FLAG_NEED_WDEV |
8358 NL80211_FLAG_NEED_RTNL,
8465 }, 8359 },
8466 { 8360 {
8467 .cmd = NL80211_CMD_SET_INTERFACE, 8361 .cmd = NL80211_CMD_SET_INTERFACE,
@@ -8620,6 +8514,7 @@ static struct genl_ops nl80211_ops[] = {
8620 .cmd = NL80211_CMD_GET_REG, 8514 .cmd = NL80211_CMD_GET_REG,
8621 .doit = nl80211_get_reg, 8515 .doit = nl80211_get_reg,
8622 .policy = nl80211_policy, 8516 .policy = nl80211_policy,
8517 .internal_flags = NL80211_FLAG_NEED_RTNL,
8623 /* can be retrieved by unprivileged users */ 8518 /* can be retrieved by unprivileged users */
8624 }, 8519 },
8625 { 8520 {
@@ -8627,6 +8522,7 @@ static struct genl_ops nl80211_ops[] = {
8627 .doit = nl80211_set_reg, 8522 .doit = nl80211_set_reg,
8628 .policy = nl80211_policy, 8523 .policy = nl80211_policy,
8629 .flags = GENL_ADMIN_PERM, 8524 .flags = GENL_ADMIN_PERM,
8525 .internal_flags = NL80211_FLAG_NEED_RTNL,
8630 }, 8526 },
8631 { 8527 {
8632 .cmd = NL80211_CMD_REQ_SET_REG, 8528 .cmd = NL80211_CMD_REQ_SET_REG,
@@ -9082,8 +8978,6 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
9082 struct nlattr *nest; 8978 struct nlattr *nest;
9083 int i; 8979 int i;
9084 8980
9085 lockdep_assert_held(&rdev->sched_scan_mtx);
9086
9087 if (WARN_ON(!req)) 8981 if (WARN_ON(!req))
9088 return 0; 8982 return 0;
9089 8983
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index cc35fbaa4578..e76559618588 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -377,7 +377,7 @@ static void reg_regdb_search(struct work_struct *work)
377 const struct ieee80211_regdomain *curdom, *regdom = NULL; 377 const struct ieee80211_regdomain *curdom, *regdom = NULL;
378 int i; 378 int i;
379 379
380 mutex_lock(&cfg80211_mutex); 380 rtnl_lock();
381 381
382 mutex_lock(&reg_regdb_search_mutex); 382 mutex_lock(&reg_regdb_search_mutex);
383 while (!list_empty(&reg_regdb_search_list)) { 383 while (!list_empty(&reg_regdb_search_list)) {
@@ -402,7 +402,7 @@ static void reg_regdb_search(struct work_struct *work)
402 if (!IS_ERR_OR_NULL(regdom)) 402 if (!IS_ERR_OR_NULL(regdom))
403 set_regdom(regdom); 403 set_regdom(regdom);
404 404
405 mutex_unlock(&cfg80211_mutex); 405 rtnl_unlock();
406} 406}
407 407
408static DECLARE_WORK(reg_regdb_work, reg_regdb_search); 408static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
@@ -1225,7 +1225,7 @@ static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
1225 struct cfg80211_registered_device *rdev; 1225 struct cfg80211_registered_device *rdev;
1226 struct wiphy *wiphy; 1226 struct wiphy *wiphy;
1227 1227
1228 assert_cfg80211_lock(); 1228 ASSERT_RTNL();
1229 1229
1230 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 1230 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1231 wiphy = &rdev->wiphy; 1231 wiphy = &rdev->wiphy;
@@ -1570,21 +1570,19 @@ static void reg_process_pending_hints(void)
1570{ 1570{
1571 struct regulatory_request *reg_request, *lr; 1571 struct regulatory_request *reg_request, *lr;
1572 1572
1573 mutex_lock(&cfg80211_mutex);
1574 mutex_lock(&reg_mutex);
1575 lr = get_last_request(); 1573 lr = get_last_request();
1576 1574
1577 /* When last_request->processed becomes true this will be rescheduled */ 1575 /* When last_request->processed becomes true this will be rescheduled */
1578 if (lr && !lr->processed) { 1576 if (lr && !lr->processed) {
1579 REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n"); 1577 REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n");
1580 goto out; 1578 return;
1581 } 1579 }
1582 1580
1583 spin_lock(&reg_requests_lock); 1581 spin_lock(&reg_requests_lock);
1584 1582
1585 if (list_empty(&reg_requests_list)) { 1583 if (list_empty(&reg_requests_list)) {
1586 spin_unlock(&reg_requests_lock); 1584 spin_unlock(&reg_requests_lock);
1587 goto out; 1585 return;
1588 } 1586 }
1589 1587
1590 reg_request = list_first_entry(&reg_requests_list, 1588 reg_request = list_first_entry(&reg_requests_list,
@@ -1595,10 +1593,6 @@ static void reg_process_pending_hints(void)
1595 spin_unlock(&reg_requests_lock); 1593 spin_unlock(&reg_requests_lock);
1596 1594
1597 reg_process_hint(reg_request, reg_request->initiator); 1595 reg_process_hint(reg_request, reg_request->initiator);
1598
1599out:
1600 mutex_unlock(&reg_mutex);
1601 mutex_unlock(&cfg80211_mutex);
1602} 1596}
1603 1597
1604/* Processes beacon hints -- this has nothing to do with country IEs */ 1598/* Processes beacon hints -- this has nothing to do with country IEs */
@@ -1607,9 +1601,6 @@ static void reg_process_pending_beacon_hints(void)
1607 struct cfg80211_registered_device *rdev; 1601 struct cfg80211_registered_device *rdev;
1608 struct reg_beacon *pending_beacon, *tmp; 1602 struct reg_beacon *pending_beacon, *tmp;
1609 1603
1610 mutex_lock(&cfg80211_mutex);
1611 mutex_lock(&reg_mutex);
1612
1613 /* This goes through the _pending_ beacon list */ 1604 /* This goes through the _pending_ beacon list */
1614 spin_lock_bh(&reg_pending_beacons_lock); 1605 spin_lock_bh(&reg_pending_beacons_lock);
1615 1606
@@ -1626,14 +1617,16 @@ static void reg_process_pending_beacon_hints(void)
1626 } 1617 }
1627 1618
1628 spin_unlock_bh(&reg_pending_beacons_lock); 1619 spin_unlock_bh(&reg_pending_beacons_lock);
1629 mutex_unlock(&reg_mutex);
1630 mutex_unlock(&cfg80211_mutex);
1631} 1620}
1632 1621
1633static void reg_todo(struct work_struct *work) 1622static void reg_todo(struct work_struct *work)
1634{ 1623{
1624 rtnl_lock();
1625 mutex_lock(&reg_mutex);
1635 reg_process_pending_hints(); 1626 reg_process_pending_hints();
1636 reg_process_pending_beacon_hints(); 1627 reg_process_pending_beacon_hints();
1628 mutex_unlock(&reg_mutex);
1629 rtnl_unlock();
1637} 1630}
1638 1631
1639static void queue_regulatory_request(struct regulatory_request *request) 1632static void queue_regulatory_request(struct regulatory_request *request)
@@ -1717,10 +1710,6 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
1717} 1710}
1718EXPORT_SYMBOL(regulatory_hint); 1711EXPORT_SYMBOL(regulatory_hint);
1719 1712
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, 1713void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1725 const u8 *country_ie, u8 country_ie_len) 1714 const u8 *country_ie, u8 country_ie_len)
1726{ 1715{
@@ -1752,7 +1741,7 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1752 /* 1741 /*
1753 * We will run this only upon a successful connection on cfg80211. 1742 * We will run this only upon a successful connection on cfg80211.
1754 * We leave conflict resolution to the workqueue, where can hold 1743 * We leave conflict resolution to the workqueue, where can hold
1755 * cfg80211_mutex. 1744 * the RTNL.
1756 */ 1745 */
1757 if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && 1746 if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1758 lr->wiphy_idx != WIPHY_IDX_INVALID) 1747 lr->wiphy_idx != WIPHY_IDX_INVALID)
@@ -1858,7 +1847,8 @@ static void restore_regulatory_settings(bool reset_user)
1858 LIST_HEAD(tmp_reg_req_list); 1847 LIST_HEAD(tmp_reg_req_list);
1859 struct cfg80211_registered_device *rdev; 1848 struct cfg80211_registered_device *rdev;
1860 1849
1861 mutex_lock(&cfg80211_mutex); 1850 ASSERT_RTNL();
1851
1862 mutex_lock(&reg_mutex); 1852 mutex_lock(&reg_mutex);
1863 1853
1864 reset_regdomains(true, &world_regdom); 1854 reset_regdomains(true, &world_regdom);
@@ -1915,7 +1905,6 @@ static void restore_regulatory_settings(bool reset_user)
1915 spin_unlock(&reg_requests_lock); 1905 spin_unlock(&reg_requests_lock);
1916 1906
1917 mutex_unlock(&reg_mutex); 1907 mutex_unlock(&reg_mutex);
1918 mutex_unlock(&cfg80211_mutex);
1919 1908
1920 REG_DBG_PRINT("Kicking the queue\n"); 1909 REG_DBG_PRINT("Kicking the queue\n");
1921 1910
@@ -2297,7 +2286,6 @@ void wiphy_regulatory_register(struct wiphy *wiphy)
2297 mutex_unlock(&reg_mutex); 2286 mutex_unlock(&reg_mutex);
2298} 2287}
2299 2288
2300/* Caller must hold cfg80211_mutex */
2301void wiphy_regulatory_deregister(struct wiphy *wiphy) 2289void wiphy_regulatory_deregister(struct wiphy *wiphy)
2302{ 2290{
2303 struct wiphy *request_wiphy = NULL; 2291 struct wiphy *request_wiphy = NULL;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 2ce44a712f13..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;
@@ -1043,21 +1044,19 @@ EXPORT_SYMBOL(cfg80211_unlink_bss);
1043static struct cfg80211_registered_device * 1044static struct cfg80211_registered_device *
1044cfg80211_get_dev_from_ifindex(struct net *net, int ifindex) 1045cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
1045{ 1046{
1046 struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV); 1047 struct cfg80211_registered_device *rdev;
1047 struct net_device *dev; 1048 struct net_device *dev;
1048 1049
1049 mutex_lock(&cfg80211_mutex); 1050 ASSERT_RTNL();
1051
1050 dev = dev_get_by_index(net, ifindex); 1052 dev = dev_get_by_index(net, ifindex);
1051 if (!dev) 1053 if (!dev)
1052 goto out; 1054 return ERR_PTR(-ENODEV);
1053 if (dev->ieee80211_ptr) { 1055 if (dev->ieee80211_ptr)
1054 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy); 1056 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
1055 mutex_lock(&rdev->mtx); 1057 else
1056 } else
1057 rdev = ERR_PTR(-ENODEV); 1058 rdev = ERR_PTR(-ENODEV);
1058 dev_put(dev); 1059 dev_put(dev);
1059 out:
1060 mutex_unlock(&cfg80211_mutex);
1061 return rdev; 1060 return rdev;
1062} 1061}
1063 1062
@@ -1083,7 +1082,6 @@ int cfg80211_wext_siwscan(struct net_device *dev,
1083 if (IS_ERR(rdev)) 1082 if (IS_ERR(rdev))
1084 return PTR_ERR(rdev); 1083 return PTR_ERR(rdev);
1085 1084
1086 mutex_lock(&rdev->sched_scan_mtx);
1087 if (rdev->scan_req) { 1085 if (rdev->scan_req) {
1088 err = -EBUSY; 1086 err = -EBUSY;
1089 goto out; 1087 goto out;
@@ -1190,9 +1188,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
1190 dev_hold(dev); 1188 dev_hold(dev);
1191 } 1189 }
1192 out: 1190 out:
1193 mutex_unlock(&rdev->sched_scan_mtx);
1194 kfree(creq); 1191 kfree(creq);
1195 cfg80211_unlock_rdev(rdev);
1196 return err; 1192 return err;
1197} 1193}
1198EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan); 1194EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
@@ -1491,10 +1487,8 @@ int cfg80211_wext_giwscan(struct net_device *dev,
1491 if (IS_ERR(rdev)) 1487 if (IS_ERR(rdev))
1492 return PTR_ERR(rdev); 1488 return PTR_ERR(rdev);
1493 1489
1494 if (rdev->scan_req) { 1490 if (rdev->scan_req)
1495 res = -EAGAIN; 1491 return -EAGAIN;
1496 goto out;
1497 }
1498 1492
1499 res = ieee80211_scan_results(rdev, info, extra, data->length); 1493 res = ieee80211_scan_results(rdev, info, extra, data->length);
1500 data->length = 0; 1494 data->length = 0;
@@ -1503,8 +1497,6 @@ int cfg80211_wext_giwscan(struct net_device *dev,
1503 res = 0; 1497 res = 0;
1504 } 1498 }
1505 1499
1506 out:
1507 cfg80211_unlock_rdev(rdev);
1508 return res; 1500 return res;
1509} 1501}
1510EXPORT_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..4dbf31407a56 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;
@@ -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
@@ -931,14 +918,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
931{ 918{
932 int err; 919 int err;
933 920
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); 921 wdev_lock(dev->ieee80211_ptr);
938 err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL); 922 err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL);
939 wdev_unlock(dev->ieee80211_ptr); 923 wdev_unlock(dev->ieee80211_ptr);
940 mutex_unlock(&rdev->sched_scan_mtx);
941 mutex_unlock(&rdev->devlist_mtx);
942 924
943 return err; 925 return err;
944} 926}
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 0962f107f57f..501724257af5 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -808,12 +808,8 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
808 ASSERT_RTNL(); 808 ASSERT_RTNL();
809 ASSERT_RDEV_LOCK(rdev); 809 ASSERT_RDEV_LOCK(rdev);
810 810
811 mutex_lock(&rdev->devlist_mtx);
812
813 list_for_each_entry(wdev, &rdev->wdev_list, list) 811 list_for_each_entry(wdev, &rdev->wdev_list, list)
814 cfg80211_process_wdev_events(wdev); 812 cfg80211_process_wdev_events(wdev);
815
816 mutex_unlock(&rdev->devlist_mtx);
817} 813}
818 814
819int cfg80211_change_iface(struct cfg80211_registered_device *rdev, 815int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
@@ -845,10 +841,8 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
845 return -EBUSY; 841 return -EBUSY;
846 842
847 if (ntype != otype && netif_running(dev)) { 843 if (ntype != otype && netif_running(dev)) {
848 mutex_lock(&rdev->devlist_mtx);
849 err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, 844 err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr,
850 ntype); 845 ntype);
851 mutex_unlock(&rdev->devlist_mtx);
852 if (err) 846 if (err)
853 return err; 847 return err;
854 848
@@ -1210,8 +1204,6 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
1210 if (!beacon_int) 1204 if (!beacon_int)
1211 return -EINVAL; 1205 return -EINVAL;
1212 1206
1213 mutex_lock(&rdev->devlist_mtx);
1214
1215 list_for_each_entry(wdev, &rdev->wdev_list, list) { 1207 list_for_each_entry(wdev, &rdev->wdev_list, list) {
1216 if (!wdev->beacon_interval) 1208 if (!wdev->beacon_interval)
1217 continue; 1209 continue;
@@ -1221,8 +1213,6 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
1221 } 1213 }
1222 } 1214 }
1223 1215
1224 mutex_unlock(&rdev->devlist_mtx);
1225
1226 return res; 1216 return res;
1227} 1217}
1228 1218
@@ -1246,7 +1236,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1246 int i, j; 1236 int i, j;
1247 1237
1248 ASSERT_RTNL(); 1238 ASSERT_RTNL();
1249 lockdep_assert_held(&rdev->devlist_mtx);
1250 1239
1251 if (WARN_ON(hweight32(radar_detect) > 1)) 1240 if (WARN_ON(hweight32(radar_detect) > 1))
1252 return -EINVAL; 1241 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..aeefd6817189 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -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) {
@@ -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;
@@ -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) {
@@ -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