aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-03-29 16:41:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-03-29 16:41:36 -0400
commit9a574cd67a447059f9c14bbef47873315d7f7b35 (patch)
tree0ebb71d213d868d8884b1fa0e05b7393c66c665b /net/wireless
parent689b66cb53fbb5d567aa4e095eaa828aff73aef0 (diff)
parent2e1253d640eb7f8707d2591c93097c1e9f9c71d5 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts: net/mac80211/sta_info.c net/wireless/core.h
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c64
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/nl80211.c52
-rw-r--r--net/wireless/scan.c24
-rw-r--r--net/wireless/sme.c6
-rw-r--r--net/wireless/trace.h5
-rw-r--r--net/wireless/wext-sme.c6
7 files changed, 106 insertions, 54 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 92e3fd44e3b0..84c9ad7e1dca 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -212,6 +212,39 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
212 rdev_rfkill_poll(rdev); 212 rdev_rfkill_poll(rdev);
213} 213}
214 214
215void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
216 struct wireless_dev *wdev)
217{
218 lockdep_assert_held(&rdev->devlist_mtx);
219 lockdep_assert_held(&rdev->sched_scan_mtx);
220
221 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE))
222 return;
223
224 if (!wdev->p2p_started)
225 return;
226
227 rdev_stop_p2p_device(rdev, wdev);
228 wdev->p2p_started = false;
229
230 rdev->opencount--;
231
232 if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
233 bool busy = work_busy(&rdev->scan_done_wk);
234
235 /*
236 * If the work isn't pending or running (in which case it would
237 * be waiting for the lock we hold) the driver didn't properly
238 * cancel the scan when the interface was removed. In this case
239 * warn and leak the scan request object to not crash later.
240 */
241 WARN_ON(!busy);
242
243 rdev->scan_req->aborted = true;
244 ___cfg80211_scan_done(rdev, !busy);
245 }
246}
247
215static int cfg80211_rfkill_set_block(void *data, bool blocked) 248static int cfg80211_rfkill_set_block(void *data, bool blocked)
216{ 249{
217 struct cfg80211_registered_device *rdev = data; 250 struct cfg80211_registered_device *rdev = data;
@@ -221,7 +254,8 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
221 return 0; 254 return 0;
222 255
223 rtnl_lock(); 256 rtnl_lock();
224 mutex_lock(&rdev->devlist_mtx); 257
258 /* read-only iteration need not hold the devlist_mtx */
225 259
226 list_for_each_entry(wdev, &rdev->wdev_list, list) { 260 list_for_each_entry(wdev, &rdev->wdev_list, list) {
227 if (wdev->netdev) { 261 if (wdev->netdev) {
@@ -231,18 +265,18 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
231 /* otherwise, check iftype */ 265 /* otherwise, check iftype */
232 switch (wdev->iftype) { 266 switch (wdev->iftype) {
233 case NL80211_IFTYPE_P2P_DEVICE: 267 case NL80211_IFTYPE_P2P_DEVICE:
234 if (!wdev->p2p_started) 268 /* but this requires it */
235 break; 269 mutex_lock(&rdev->devlist_mtx);
236 rdev_stop_p2p_device(rdev, wdev); 270 mutex_lock(&rdev->sched_scan_mtx);
237 wdev->p2p_started = false; 271 cfg80211_stop_p2p_device(rdev, wdev);
238 rdev->opencount--; 272 mutex_unlock(&rdev->sched_scan_mtx);
273 mutex_unlock(&rdev->devlist_mtx);
239 break; 274 break;
240 default: 275 default:
241 break; 276 break;
242 } 277 }
243 } 278 }
244 279
245 mutex_unlock(&rdev->devlist_mtx);
246 rtnl_unlock(); 280 rtnl_unlock();
247 281
248 return 0; 282 return 0;
@@ -745,17 +779,13 @@ static void wdev_cleanup_work(struct work_struct *work)
745 wdev = container_of(work, struct wireless_dev, cleanup_work); 779 wdev = container_of(work, struct wireless_dev, cleanup_work);
746 rdev = wiphy_to_dev(wdev->wiphy); 780 rdev = wiphy_to_dev(wdev->wiphy);
747 781
748 cfg80211_lock_rdev(rdev); 782 mutex_lock(&rdev->sched_scan_mtx);
749 783
750 if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) { 784 if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) {
751 rdev->scan_req->aborted = true; 785 rdev->scan_req->aborted = true;
752 ___cfg80211_scan_done(rdev, true); 786 ___cfg80211_scan_done(rdev, true);
753 } 787 }
754 788
755 cfg80211_unlock_rdev(rdev);
756
757 mutex_lock(&rdev->sched_scan_mtx);
758
759 if (WARN_ON(rdev->sched_scan_req && 789 if (WARN_ON(rdev->sched_scan_req &&
760 rdev->sched_scan_req->dev == wdev->netdev)) { 790 rdev->sched_scan_req->dev == wdev->netdev)) {
761 __cfg80211_stop_sched_scan(rdev, false); 791 __cfg80211_stop_sched_scan(rdev, false);
@@ -781,21 +811,19 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
781 return; 811 return;
782 812
783 mutex_lock(&rdev->devlist_mtx); 813 mutex_lock(&rdev->devlist_mtx);
814 mutex_lock(&rdev->sched_scan_mtx);
784 list_del_rcu(&wdev->list); 815 list_del_rcu(&wdev->list);
785 rdev->devlist_generation++; 816 rdev->devlist_generation++;
786 817
787 switch (wdev->iftype) { 818 switch (wdev->iftype) {
788 case NL80211_IFTYPE_P2P_DEVICE: 819 case NL80211_IFTYPE_P2P_DEVICE:
789 if (!wdev->p2p_started) 820 cfg80211_stop_p2p_device(rdev, wdev);
790 break;
791 rdev_stop_p2p_device(rdev, wdev);
792 wdev->p2p_started = false;
793 rdev->opencount--;
794 break; 821 break;
795 default: 822 default:
796 WARN_ON_ONCE(1); 823 WARN_ON_ONCE(1);
797 break; 824 break;
798 } 825 }
826 mutex_unlock(&rdev->sched_scan_mtx);
799 mutex_unlock(&rdev->devlist_mtx); 827 mutex_unlock(&rdev->devlist_mtx);
800} 828}
801EXPORT_SYMBOL(cfg80211_unregister_wdev); 829EXPORT_SYMBOL(cfg80211_unregister_wdev);
@@ -945,6 +973,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
945 cfg80211_update_iface_num(rdev, wdev->iftype, 1); 973 cfg80211_update_iface_num(rdev, wdev->iftype, 1);
946 cfg80211_lock_rdev(rdev); 974 cfg80211_lock_rdev(rdev);
947 mutex_lock(&rdev->devlist_mtx); 975 mutex_lock(&rdev->devlist_mtx);
976 mutex_lock(&rdev->sched_scan_mtx);
948 wdev_lock(wdev); 977 wdev_lock(wdev);
949 switch (wdev->iftype) { 978 switch (wdev->iftype) {
950#ifdef CONFIG_CFG80211_WEXT 979#ifdef CONFIG_CFG80211_WEXT
@@ -976,6 +1005,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
976 break; 1005 break;
977 } 1006 }
978 wdev_unlock(wdev); 1007 wdev_unlock(wdev);
1008 mutex_unlock(&rdev->sched_scan_mtx);
979 rdev->opencount++; 1009 rdev->opencount++;
980 mutex_unlock(&rdev->devlist_mtx); 1010 mutex_unlock(&rdev->devlist_mtx);
981 cfg80211_unlock_rdev(rdev); 1011 cfg80211_unlock_rdev(rdev);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index d5d06fdea961..124e5e773fbc 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -503,6 +503,9 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
503void cfg80211_leave(struct cfg80211_registered_device *rdev, 503void cfg80211_leave(struct cfg80211_registered_device *rdev,
504 struct wireless_dev *wdev); 504 struct wireless_dev *wdev);
505 505
506void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
507 struct wireless_dev *wdev);
508
506#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 509#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
507 510
508#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 511#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f924d45af1b8..671b69a3c136 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5048,14 +5048,19 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5048 if (!rdev->ops->scan) 5048 if (!rdev->ops->scan)
5049 return -EOPNOTSUPP; 5049 return -EOPNOTSUPP;
5050 5050
5051 if (rdev->scan_req) 5051 mutex_lock(&rdev->sched_scan_mtx);
5052 return -EBUSY; 5052 if (rdev->scan_req) {
5053 err = -EBUSY;
5054 goto unlock;
5055 }
5053 5056
5054 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { 5057 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
5055 n_channels = validate_scan_freqs( 5058 n_channels = validate_scan_freqs(
5056 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); 5059 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
5057 if (!n_channels) 5060 if (!n_channels) {
5058 return -EINVAL; 5061 err = -EINVAL;
5062 goto unlock;
5063 }
5059 } else { 5064 } else {
5060 enum ieee80211_band band; 5065 enum ieee80211_band band;
5061 n_channels = 0; 5066 n_channels = 0;
@@ -5069,23 +5074,29 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5069 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) 5074 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
5070 n_ssids++; 5075 n_ssids++;
5071 5076
5072 if (n_ssids > wiphy->max_scan_ssids) 5077 if (n_ssids > wiphy->max_scan_ssids) {
5073 return -EINVAL; 5078 err = -EINVAL;
5079 goto unlock;
5080 }
5074 5081
5075 if (info->attrs[NL80211_ATTR_IE]) 5082 if (info->attrs[NL80211_ATTR_IE])
5076 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 5083 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
5077 else 5084 else
5078 ie_len = 0; 5085 ie_len = 0;
5079 5086
5080 if (ie_len > wiphy->max_scan_ie_len) 5087 if (ie_len > wiphy->max_scan_ie_len) {
5081 return -EINVAL; 5088 err = -EINVAL;
5089 goto unlock;
5090 }
5082 5091
5083 request = kzalloc(sizeof(*request) 5092 request = kzalloc(sizeof(*request)
5084 + sizeof(*request->ssids) * n_ssids 5093 + sizeof(*request->ssids) * n_ssids
5085 + sizeof(*request->channels) * n_channels 5094 + sizeof(*request->channels) * n_channels
5086 + ie_len, GFP_KERNEL); 5095 + ie_len, GFP_KERNEL);
5087 if (!request) 5096 if (!request) {
5088 return -ENOMEM; 5097 err = -ENOMEM;
5098 goto unlock;
5099 }
5089 5100
5090 if (n_ssids) 5101 if (n_ssids)
5091 request->ssids = (void *)&request->channels[n_channels]; 5102 request->ssids = (void *)&request->channels[n_channels];
@@ -5222,6 +5233,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5222 kfree(request); 5233 kfree(request);
5223 } 5234 }
5224 5235
5236 unlock:
5237 mutex_unlock(&rdev->sched_scan_mtx);
5225 return err; 5238 return err;
5226} 5239}
5227 5240
@@ -8130,20 +8143,9 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
8130 if (!rdev->ops->stop_p2p_device) 8143 if (!rdev->ops->stop_p2p_device)
8131 return -EOPNOTSUPP; 8144 return -EOPNOTSUPP;
8132 8145
8133 if (!wdev->p2p_started) 8146 mutex_lock(&rdev->sched_scan_mtx);
8134 return 0; 8147 cfg80211_stop_p2p_device(rdev, wdev);
8135 8148 mutex_unlock(&rdev->sched_scan_mtx);
8136 rdev_stop_p2p_device(rdev, wdev);
8137 wdev->p2p_started = false;
8138
8139 mutex_lock(&rdev->devlist_mtx);
8140 rdev->opencount--;
8141 mutex_unlock(&rdev->devlist_mtx);
8142
8143 if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) {
8144 rdev->scan_req->aborted = true;
8145 ___cfg80211_scan_done(rdev, true);
8146 }
8147 8149
8148 return 0; 8150 return 0;
8149} 8151}
@@ -8929,7 +8931,7 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
8929 struct nlattr *nest; 8931 struct nlattr *nest;
8930 int i; 8932 int i;
8931 8933
8932 ASSERT_RDEV_LOCK(rdev); 8934 lockdep_assert_held(&rdev->sched_scan_mtx);
8933 8935
8934 if (WARN_ON(!req)) 8936 if (WARN_ON(!req))
8935 return 0; 8937 return 0;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 674aadca0079..fd99ea495b7e 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 ASSERT_RDEV_LOCK(rdev); 172 lockdep_assert_held(&rdev->sched_scan_mtx);
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 cfg80211_lock_rdev(rdev); 233 mutex_lock(&rdev->sched_scan_mtx);
234 ___cfg80211_scan_done(rdev, false); 234 ___cfg80211_scan_done(rdev, false);
235 cfg80211_unlock_rdev(rdev); 235 mutex_unlock(&rdev->sched_scan_mtx);
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)
@@ -698,11 +698,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
698 found = rb_find_bss(dev, tmp, BSS_CMP_REGULAR); 698 found = rb_find_bss(dev, tmp, BSS_CMP_REGULAR);
699 699
700 if (found) { 700 if (found) {
701 found->pub.beacon_interval = tmp->pub.beacon_interval;
702 found->pub.signal = tmp->pub.signal;
703 found->pub.capability = tmp->pub.capability;
704 found->ts = tmp->ts;
705
706 /* Update IEs */ 701 /* Update IEs */
707 if (rcu_access_pointer(tmp->pub.proberesp_ies)) { 702 if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
708 const struct cfg80211_bss_ies *old; 703 const struct cfg80211_bss_ies *old;
@@ -723,6 +718,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
723 718
724 if (found->pub.hidden_beacon_bss && 719 if (found->pub.hidden_beacon_bss &&
725 !list_empty(&found->hidden_list)) { 720 !list_empty(&found->hidden_list)) {
721 const struct cfg80211_bss_ies *f;
722
726 /* 723 /*
727 * The found BSS struct is one of the probe 724 * The found BSS struct is one of the probe
728 * response members of a group, but we're 725 * response members of a group, but we're
@@ -732,6 +729,10 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
732 * SSID to showing it, which is confusing so 729 * SSID to showing it, which is confusing so
733 * drop this information. 730 * drop this information.
734 */ 731 */
732
733 f = rcu_access_pointer(tmp->pub.beacon_ies);
734 kfree_rcu((struct cfg80211_bss_ies *)f,
735 rcu_head);
735 goto drop; 736 goto drop;
736 } 737 }
737 738
@@ -761,6 +762,11 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
761 kfree_rcu((struct cfg80211_bss_ies *)old, 762 kfree_rcu((struct cfg80211_bss_ies *)old,
762 rcu_head); 763 rcu_head);
763 } 764 }
765
766 found->pub.beacon_interval = tmp->pub.beacon_interval;
767 found->pub.signal = tmp->pub.signal;
768 found->pub.capability = tmp->pub.capability;
769 found->ts = tmp->ts;
764 } else { 770 } else {
765 struct cfg80211_internal_bss *new; 771 struct cfg80211_internal_bss *new;
766 struct cfg80211_internal_bss *hidden; 772 struct cfg80211_internal_bss *hidden;
@@ -1056,6 +1062,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
1056 if (IS_ERR(rdev)) 1062 if (IS_ERR(rdev))
1057 return PTR_ERR(rdev); 1063 return PTR_ERR(rdev);
1058 1064
1065 mutex_lock(&rdev->sched_scan_mtx);
1059 if (rdev->scan_req) { 1066 if (rdev->scan_req) {
1060 err = -EBUSY; 1067 err = -EBUSY;
1061 goto out; 1068 goto out;
@@ -1162,6 +1169,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
1162 dev_hold(dev); 1169 dev_hold(dev);
1163 } 1170 }
1164 out: 1171 out:
1172 mutex_unlock(&rdev->sched_scan_mtx);
1165 kfree(creq); 1173 kfree(creq);
1166 cfg80211_unlock_rdev(rdev); 1174 cfg80211_unlock_rdev(rdev);
1167 return err; 1175 return err;
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 88fc9aa54fe0..818ad637819a 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -85,6 +85,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
85 ASSERT_RTNL(); 85 ASSERT_RTNL();
86 ASSERT_RDEV_LOCK(rdev); 86 ASSERT_RDEV_LOCK(rdev);
87 ASSERT_WDEV_LOCK(wdev); 87 ASSERT_WDEV_LOCK(wdev);
88 lockdep_assert_held(&rdev->sched_scan_mtx);
88 89
89 if (rdev->scan_req) 90 if (rdev->scan_req)
90 return -EBUSY; 91 return -EBUSY;
@@ -324,11 +325,9 @@ void cfg80211_sme_scan_done(struct net_device *dev)
324{ 325{
325 struct wireless_dev *wdev = dev->ieee80211_ptr; 326 struct wireless_dev *wdev = dev->ieee80211_ptr;
326 327
327 mutex_lock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx);
328 wdev_lock(wdev); 328 wdev_lock(wdev);
329 __cfg80211_sme_scan_done(dev); 329 __cfg80211_sme_scan_done(dev);
330 wdev_unlock(wdev); 330 wdev_unlock(wdev);
331 mutex_unlock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx);
332} 331}
333 332
334void cfg80211_sme_rx_auth(struct net_device *dev, 333void cfg80211_sme_rx_auth(struct net_device *dev,
@@ -928,9 +927,12 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
928 int err; 927 int err;
929 928
930 mutex_lock(&rdev->devlist_mtx); 929 mutex_lock(&rdev->devlist_mtx);
930 /* might request scan - scan_mtx -> wdev_mtx dependency */
931 mutex_lock(&rdev->sched_scan_mtx);
931 wdev_lock(dev->ieee80211_ptr); 932 wdev_lock(dev->ieee80211_ptr);
932 err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL); 933 err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL);
933 wdev_unlock(dev->ieee80211_ptr); 934 wdev_unlock(dev->ieee80211_ptr);
935 mutex_unlock(&rdev->sched_scan_mtx);
934 mutex_unlock(&rdev->devlist_mtx); 936 mutex_unlock(&rdev->devlist_mtx);
935 937
936 return err; 938 return err;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ccadef2106ac..3c2033b8f596 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -27,7 +27,8 @@
27#define WIPHY_PR_ARG __entry->wiphy_name 27#define WIPHY_PR_ARG __entry->wiphy_name
28 28
29#define WDEV_ENTRY __field(u32, id) 29#define WDEV_ENTRY __field(u32, id)
30#define WDEV_ASSIGN (__entry->id) = (wdev ? wdev->identifier : 0) 30#define WDEV_ASSIGN (__entry->id) = (!IS_ERR_OR_NULL(wdev) \
31 ? wdev->identifier : 0)
31#define WDEV_PR_FMT "wdev(%u)" 32#define WDEV_PR_FMT "wdev(%u)"
32#define WDEV_PR_ARG (__entry->id) 33#define WDEV_PR_ARG (__entry->id)
33 34
@@ -1778,7 +1779,7 @@ TRACE_EVENT(rdev_set_mac_acl,
1778 ), 1779 ),
1779 TP_fast_assign( 1780 TP_fast_assign(
1780 WIPHY_ASSIGN; 1781 WIPHY_ASSIGN;
1781 WIPHY_ASSIGN; 1782 NETDEV_ASSIGN;
1782 __entry->acl_policy = params->acl_policy; 1783 __entry->acl_policy = params->acl_policy;
1783 ), 1784 ),
1784 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", acl policy: %d", 1785 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", acl policy: %d",
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index fb9622f6d99c..e79cb5c0655a 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -89,6 +89,7 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
89 89
90 cfg80211_lock_rdev(rdev); 90 cfg80211_lock_rdev(rdev);
91 mutex_lock(&rdev->devlist_mtx); 91 mutex_lock(&rdev->devlist_mtx);
92 mutex_lock(&rdev->sched_scan_mtx);
92 wdev_lock(wdev); 93 wdev_lock(wdev);
93 94
94 if (wdev->sme_state != CFG80211_SME_IDLE) { 95 if (wdev->sme_state != CFG80211_SME_IDLE) {
@@ -135,6 +136,7 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
135 err = cfg80211_mgd_wext_connect(rdev, wdev); 136 err = cfg80211_mgd_wext_connect(rdev, wdev);
136 out: 137 out:
137 wdev_unlock(wdev); 138 wdev_unlock(wdev);
139 mutex_unlock(&rdev->sched_scan_mtx);
138 mutex_unlock(&rdev->devlist_mtx); 140 mutex_unlock(&rdev->devlist_mtx);
139 cfg80211_unlock_rdev(rdev); 141 cfg80211_unlock_rdev(rdev);
140 return err; 142 return err;
@@ -190,6 +192,7 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
190 192
191 cfg80211_lock_rdev(rdev); 193 cfg80211_lock_rdev(rdev);
192 mutex_lock(&rdev->devlist_mtx); 194 mutex_lock(&rdev->devlist_mtx);
195 mutex_lock(&rdev->sched_scan_mtx);
193 wdev_lock(wdev); 196 wdev_lock(wdev);
194 197
195 err = 0; 198 err = 0;
@@ -223,6 +226,7 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
223 err = cfg80211_mgd_wext_connect(rdev, wdev); 226 err = cfg80211_mgd_wext_connect(rdev, wdev);
224 out: 227 out:
225 wdev_unlock(wdev); 228 wdev_unlock(wdev);
229 mutex_unlock(&rdev->sched_scan_mtx);
226 mutex_unlock(&rdev->devlist_mtx); 230 mutex_unlock(&rdev->devlist_mtx);
227 cfg80211_unlock_rdev(rdev); 231 cfg80211_unlock_rdev(rdev);
228 return err; 232 return err;
@@ -285,6 +289,7 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
285 289
286 cfg80211_lock_rdev(rdev); 290 cfg80211_lock_rdev(rdev);
287 mutex_lock(&rdev->devlist_mtx); 291 mutex_lock(&rdev->devlist_mtx);
292 mutex_lock(&rdev->sched_scan_mtx);
288 wdev_lock(wdev); 293 wdev_lock(wdev);
289 294
290 if (wdev->sme_state != CFG80211_SME_IDLE) { 295 if (wdev->sme_state != CFG80211_SME_IDLE) {
@@ -313,6 +318,7 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
313 err = cfg80211_mgd_wext_connect(rdev, wdev); 318 err = cfg80211_mgd_wext_connect(rdev, wdev);
314 out: 319 out:
315 wdev_unlock(wdev); 320 wdev_unlock(wdev);
321 mutex_unlock(&rdev->sched_scan_mtx);
316 mutex_unlock(&rdev->devlist_mtx); 322 mutex_unlock(&rdev->devlist_mtx);
317 cfg80211_unlock_rdev(rdev); 323 cfg80211_unlock_rdev(rdev);
318 return err; 324 return err;