diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-03-29 16:41:36 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-03-29 16:41:36 -0400 |
commit | 9a574cd67a447059f9c14bbef47873315d7f7b35 (patch) | |
tree | 0ebb71d213d868d8884b1fa0e05b7393c66c665b /net/wireless | |
parent | 689b66cb53fbb5d567aa4e095eaa828aff73aef0 (diff) | |
parent | 2e1253d640eb7f8707d2591c93097c1e9f9c71d5 (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.c | 64 | ||||
-rw-r--r-- | net/wireless/core.h | 3 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 52 | ||||
-rw-r--r-- | net/wireless/scan.c | 24 | ||||
-rw-r--r-- | net/wireless/sme.c | 6 | ||||
-rw-r--r-- | net/wireless/trace.h | 5 | ||||
-rw-r--r-- | net/wireless/wext-sme.c | 6 |
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 | ||
215 | void 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 | |||
215 | static int cfg80211_rfkill_set_block(void *data, bool blocked) | 248 | static 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 | } |
801 | EXPORT_SYMBOL(cfg80211_unregister_wdev); | 829 | EXPORT_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, | |||
503 | void cfg80211_leave(struct cfg80211_registered_device *rdev, | 503 | void cfg80211_leave(struct cfg80211_registered_device *rdev, |
504 | struct wireless_dev *wdev); | 504 | struct wireless_dev *wdev); |
505 | 505 | ||
506 | void 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 | ||
238 | void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) | 238 | void 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 | ||
334 | void cfg80211_sme_rx_auth(struct net_device *dev, | 333 | void 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; |