diff options
author | Johannes Berg <johannes.berg@intel.com> | 2014-02-20 05:55:12 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-02-20 05:55:12 -0500 |
commit | bf5f48339a019c9b4b42284c3f45d58942cbda27 (patch) | |
tree | 79976135166ffbdaf4ccb91bcadb17ddb551f060 /net/wireless | |
parent | d85dad75566674ca8012715ac00a84ced3697972 (diff) | |
parent | 35582ad9d342025653aaf28ed321bf5352488d7f (diff) |
Merge remote-tracking branch 'wireless-next/master' into mac80211-next
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/core.c | 17 | ||||
-rw-r--r-- | net/wireless/core.h | 4 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 32 | ||||
-rw-r--r-- | net/wireless/nl80211.h | 8 | ||||
-rw-r--r-- | net/wireless/scan.c | 40 | ||||
-rw-r--r-- | net/wireless/sme.c | 2 |
6 files changed, 55 insertions, 48 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c index b5ff39a6f6ed..76ae6a605abb 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -203,8 +203,11 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, | |||
203 | 203 | ||
204 | rdev->opencount--; | 204 | rdev->opencount--; |
205 | 205 | ||
206 | WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev && | 206 | if (rdev->scan_req && rdev->scan_req->wdev == wdev) { |
207 | !rdev->scan_req->notified); | 207 | if (WARN_ON(!rdev->scan_req->notified)) |
208 | rdev->scan_req->aborted = true; | ||
209 | ___cfg80211_scan_done(rdev, false); | ||
210 | } | ||
208 | } | 211 | } |
209 | 212 | ||
210 | static int cfg80211_rfkill_set_block(void *data, bool blocked) | 213 | static int cfg80211_rfkill_set_block(void *data, bool blocked) |
@@ -440,9 +443,6 @@ int wiphy_register(struct wiphy *wiphy) | |||
440 | int i; | 443 | int i; |
441 | u16 ifmodes = wiphy->interface_modes; | 444 | u16 ifmodes = wiphy->interface_modes; |
442 | 445 | ||
443 | /* support for 5/10 MHz is broken due to nl80211 API mess - disable */ | ||
444 | wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ; | ||
445 | |||
446 | /* | 446 | /* |
447 | * There are major locking problems in nl80211/mac80211 for CSA, | 447 | * There are major locking problems in nl80211/mac80211 for CSA, |
448 | * disable for all drivers until this has been reworked. | 448 | * disable for all drivers until this has been reworked. |
@@ -859,8 +859,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
859 | break; | 859 | break; |
860 | case NETDEV_DOWN: | 860 | case NETDEV_DOWN: |
861 | cfg80211_update_iface_num(rdev, wdev->iftype, -1); | 861 | cfg80211_update_iface_num(rdev, wdev->iftype, -1); |
862 | WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev && | 862 | if (rdev->scan_req && rdev->scan_req->wdev == wdev) { |
863 | !rdev->scan_req->notified); | 863 | if (WARN_ON(!rdev->scan_req->notified)) |
864 | rdev->scan_req->aborted = true; | ||
865 | ___cfg80211_scan_done(rdev, false); | ||
866 | } | ||
864 | 867 | ||
865 | if (WARN_ON(rdev->sched_scan_req && | 868 | if (WARN_ON(rdev->sched_scan_req && |
866 | rdev->sched_scan_req->dev == wdev->netdev)) { | 869 | rdev->sched_scan_req->dev == wdev->netdev)) { |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 9895ab16c051..40683004d523 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -62,6 +62,7 @@ struct cfg80211_registered_device { | |||
62 | struct rb_root bss_tree; | 62 | struct rb_root bss_tree; |
63 | u32 bss_generation; | 63 | u32 bss_generation; |
64 | struct cfg80211_scan_request *scan_req; /* protected by RTNL */ | 64 | struct cfg80211_scan_request *scan_req; /* protected by RTNL */ |
65 | struct sk_buff *scan_msg; | ||
65 | struct cfg80211_sched_scan_request *sched_scan_req; | 66 | struct cfg80211_sched_scan_request *sched_scan_req; |
66 | unsigned long suspend_at; | 67 | unsigned long suspend_at; |
67 | struct work_struct scan_done_wk; | 68 | struct work_struct scan_done_wk; |
@@ -363,7 +364,8 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, | |||
363 | struct key_params *params, int key_idx, | 364 | struct key_params *params, int key_idx, |
364 | bool pairwise, const u8 *mac_addr); | 365 | bool pairwise, const u8 *mac_addr); |
365 | void __cfg80211_scan_done(struct work_struct *wk); | 366 | void __cfg80211_scan_done(struct work_struct *wk); |
366 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev); | 367 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, |
368 | bool send_message); | ||
367 | void __cfg80211_sched_scan_results(struct work_struct *wk); | 369 | void __cfg80211_sched_scan_results(struct work_struct *wk); |
368 | int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | 370 | int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, |
369 | bool driver_initiated); | 371 | bool driver_initiated); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 179786494308..058aa0e1a462 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1740,9 +1740,10 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1740 | * We can then retry with the larger buffer. | 1740 | * We can then retry with the larger buffer. |
1741 | */ | 1741 | */ |
1742 | if ((ret == -ENOBUFS || ret == -EMSGSIZE) && | 1742 | if ((ret == -ENOBUFS || ret == -EMSGSIZE) && |
1743 | !skb->len && | 1743 | !skb->len && !state->split && |
1744 | cb->min_dump_alloc < 4096) { | 1744 | cb->min_dump_alloc < 4096) { |
1745 | cb->min_dump_alloc = 4096; | 1745 | cb->min_dump_alloc = 4096; |
1746 | state->split_start = 0; | ||
1746 | rtnl_unlock(); | 1747 | rtnl_unlock(); |
1747 | return 1; | 1748 | return 1; |
1748 | } | 1749 | } |
@@ -5274,7 +5275,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
5274 | if (!rdev->ops->scan) | 5275 | if (!rdev->ops->scan) |
5275 | return -EOPNOTSUPP; | 5276 | return -EOPNOTSUPP; |
5276 | 5277 | ||
5277 | if (rdev->scan_req) { | 5278 | if (rdev->scan_req || rdev->scan_msg) { |
5278 | err = -EBUSY; | 5279 | err = -EBUSY; |
5279 | goto unlock; | 5280 | goto unlock; |
5280 | } | 5281 | } |
@@ -10116,40 +10117,31 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | |||
10116 | NL80211_MCGRP_SCAN, GFP_KERNEL); | 10117 | NL80211_MCGRP_SCAN, GFP_KERNEL); |
10117 | } | 10118 | } |
10118 | 10119 | ||
10119 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | 10120 | struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, |
10120 | struct wireless_dev *wdev) | 10121 | struct wireless_dev *wdev, bool aborted) |
10121 | { | 10122 | { |
10122 | struct sk_buff *msg; | 10123 | struct sk_buff *msg; |
10123 | 10124 | ||
10124 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 10125 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
10125 | if (!msg) | 10126 | if (!msg) |
10126 | return; | 10127 | return NULL; |
10127 | 10128 | ||
10128 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, | 10129 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, |
10129 | NL80211_CMD_NEW_SCAN_RESULTS) < 0) { | 10130 | aborted ? NL80211_CMD_SCAN_ABORTED : |
10131 | NL80211_CMD_NEW_SCAN_RESULTS) < 0) { | ||
10130 | nlmsg_free(msg); | 10132 | nlmsg_free(msg); |
10131 | return; | 10133 | return NULL; |
10132 | } | 10134 | } |
10133 | 10135 | ||
10134 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, | 10136 | return msg; |
10135 | NL80211_MCGRP_SCAN, GFP_KERNEL); | ||
10136 | } | 10137 | } |
10137 | 10138 | ||
10138 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | 10139 | void nl80211_send_scan_result(struct cfg80211_registered_device *rdev, |
10139 | struct wireless_dev *wdev) | 10140 | struct sk_buff *msg) |
10140 | { | 10141 | { |
10141 | struct sk_buff *msg; | ||
10142 | |||
10143 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
10144 | if (!msg) | 10142 | if (!msg) |
10145 | return; | 10143 | return; |
10146 | 10144 | ||
10147 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, | ||
10148 | NL80211_CMD_SCAN_ABORTED) < 0) { | ||
10149 | nlmsg_free(msg); | ||
10150 | return; | ||
10151 | } | ||
10152 | |||
10153 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, | 10145 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
10154 | NL80211_MCGRP_SCAN, GFP_KERNEL); | 10146 | NL80211_MCGRP_SCAN, GFP_KERNEL); |
10155 | } | 10147 | } |
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index cb0216e1a004..1e6df9630f42 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -8,10 +8,10 @@ void nl80211_exit(void); | |||
8 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); | 8 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); |
9 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | 9 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, |
10 | struct wireless_dev *wdev); | 10 | struct wireless_dev *wdev); |
11 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | 11 | struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev, |
12 | struct wireless_dev *wdev); | 12 | struct wireless_dev *wdev, bool aborted); |
13 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | 13 | void nl80211_send_scan_result(struct cfg80211_registered_device *rdev, |
14 | struct wireless_dev *wdev); | 14 | struct sk_buff *msg); |
15 | void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, | 15 | void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, |
16 | struct net_device *netdev, u32 cmd); | 16 | struct net_device *netdev, u32 cmd); |
17 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, | 17 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index b528e31da2cf..d1ed4aebbbb7 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -161,18 +161,25 @@ static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev, | |||
161 | dev->bss_generation++; | 161 | dev->bss_generation++; |
162 | } | 162 | } |
163 | 163 | ||
164 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) | 164 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, |
165 | bool send_message) | ||
165 | { | 166 | { |
166 | struct cfg80211_scan_request *request; | 167 | struct cfg80211_scan_request *request; |
167 | struct wireless_dev *wdev; | 168 | struct wireless_dev *wdev; |
169 | struct sk_buff *msg; | ||
168 | #ifdef CONFIG_CFG80211_WEXT | 170 | #ifdef CONFIG_CFG80211_WEXT |
169 | union iwreq_data wrqu; | 171 | union iwreq_data wrqu; |
170 | #endif | 172 | #endif |
171 | 173 | ||
172 | ASSERT_RTNL(); | 174 | ASSERT_RTNL(); |
173 | 175 | ||
174 | request = rdev->scan_req; | 176 | if (rdev->scan_msg) { |
177 | nl80211_send_scan_result(rdev, rdev->scan_msg); | ||
178 | rdev->scan_msg = NULL; | ||
179 | return; | ||
180 | } | ||
175 | 181 | ||
182 | request = rdev->scan_req; | ||
176 | if (!request) | 183 | if (!request) |
177 | return; | 184 | return; |
178 | 185 | ||
@@ -186,18 +193,16 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) | |||
186 | if (wdev->netdev) | 193 | if (wdev->netdev) |
187 | cfg80211_sme_scan_done(wdev->netdev); | 194 | cfg80211_sme_scan_done(wdev->netdev); |
188 | 195 | ||
189 | if (request->aborted) { | 196 | if (!request->aborted && |
190 | nl80211_send_scan_aborted(rdev, wdev); | 197 | request->flags & NL80211_SCAN_FLAG_FLUSH) { |
191 | } else { | 198 | /* flush entries from previous scans */ |
192 | if (request->flags & NL80211_SCAN_FLAG_FLUSH) { | 199 | spin_lock_bh(&rdev->bss_lock); |
193 | /* flush entries from previous scans */ | 200 | __cfg80211_bss_expire(rdev, request->scan_start); |
194 | spin_lock_bh(&rdev->bss_lock); | 201 | spin_unlock_bh(&rdev->bss_lock); |
195 | __cfg80211_bss_expire(rdev, request->scan_start); | ||
196 | spin_unlock_bh(&rdev->bss_lock); | ||
197 | } | ||
198 | nl80211_send_scan_done(rdev, wdev); | ||
199 | } | 202 | } |
200 | 203 | ||
204 | msg = nl80211_build_scan_msg(rdev, wdev, request->aborted); | ||
205 | |||
201 | #ifdef CONFIG_CFG80211_WEXT | 206 | #ifdef CONFIG_CFG80211_WEXT |
202 | if (wdev->netdev && !request->aborted) { | 207 | if (wdev->netdev && !request->aborted) { |
203 | memset(&wrqu, 0, sizeof(wrqu)); | 208 | memset(&wrqu, 0, sizeof(wrqu)); |
@@ -211,6 +216,11 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) | |||
211 | 216 | ||
212 | rdev->scan_req = NULL; | 217 | rdev->scan_req = NULL; |
213 | kfree(request); | 218 | kfree(request); |
219 | |||
220 | if (!send_message) | ||
221 | rdev->scan_msg = msg; | ||
222 | else | ||
223 | nl80211_send_scan_result(rdev, msg); | ||
214 | } | 224 | } |
215 | 225 | ||
216 | void __cfg80211_scan_done(struct work_struct *wk) | 226 | void __cfg80211_scan_done(struct work_struct *wk) |
@@ -221,7 +231,7 @@ void __cfg80211_scan_done(struct work_struct *wk) | |||
221 | scan_done_wk); | 231 | scan_done_wk); |
222 | 232 | ||
223 | rtnl_lock(); | 233 | rtnl_lock(); |
224 | ___cfg80211_scan_done(rdev); | 234 | ___cfg80211_scan_done(rdev, true); |
225 | rtnl_unlock(); | 235 | rtnl_unlock(); |
226 | } | 236 | } |
227 | 237 | ||
@@ -1079,7 +1089,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
1079 | if (IS_ERR(rdev)) | 1089 | if (IS_ERR(rdev)) |
1080 | return PTR_ERR(rdev); | 1090 | return PTR_ERR(rdev); |
1081 | 1091 | ||
1082 | if (rdev->scan_req) { | 1092 | if (rdev->scan_req || rdev->scan_msg) { |
1083 | err = -EBUSY; | 1093 | err = -EBUSY; |
1084 | goto out; | 1094 | goto out; |
1085 | } | 1095 | } |
@@ -1481,7 +1491,7 @@ int cfg80211_wext_giwscan(struct net_device *dev, | |||
1481 | if (IS_ERR(rdev)) | 1491 | if (IS_ERR(rdev)) |
1482 | return PTR_ERR(rdev); | 1492 | return PTR_ERR(rdev); |
1483 | 1493 | ||
1484 | if (rdev->scan_req) | 1494 | if (rdev->scan_req || rdev->scan_msg) |
1485 | return -EAGAIN; | 1495 | return -EAGAIN; |
1486 | 1496 | ||
1487 | res = ieee80211_scan_results(rdev, info, extra, data->length); | 1497 | res = ieee80211_scan_results(rdev, info, extra, data->length); |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index a63509118508..f04d4c32e96e 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -67,7 +67,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) | |||
67 | ASSERT_RDEV_LOCK(rdev); | 67 | ASSERT_RDEV_LOCK(rdev); |
68 | ASSERT_WDEV_LOCK(wdev); | 68 | ASSERT_WDEV_LOCK(wdev); |
69 | 69 | ||
70 | if (rdev->scan_req) | 70 | if (rdev->scan_req || rdev->scan_msg) |
71 | return -EBUSY; | 71 | return -EBUSY; |
72 | 72 | ||
73 | if (wdev->conn->params.channel) | 73 | if (wdev->conn->params.channel) |