aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-02-13 14:43:02 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-02-13 14:43:02 -0500
commit0e028ab0fb2da47fd235dafd4159859892e73d08 (patch)
treee9e1348372b413e6b1b503209582b03c9005f614 /net/wireless
parente57f1734d87aa0e9a00905ed08888f0c62f56227 (diff)
parent348f7d4adee97f222e3ad9ff97956ca3793d11c6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c17
-rw-r--r--net/wireless/core.h4
-rw-r--r--net/wireless/nl80211.c32
-rw-r--r--net/wireless/nl80211.h8
-rw-r--r--net/wireless/scan.c40
-rw-r--r--net/wireless/sme.c2
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
210static int cfg80211_rfkill_set_block(void *data, bool blocked) 213static 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);
365void __cfg80211_scan_done(struct work_struct *wk); 366void __cfg80211_scan_done(struct work_struct *wk);
366void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev); 367void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
368 bool send_message);
367void __cfg80211_sched_scan_results(struct work_struct *wk); 369void __cfg80211_sched_scan_results(struct work_struct *wk);
368int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, 370int __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 ebea1a197afb..8e6b6a2d35cb 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
10119void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, 10120struct 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
10138void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 10139void 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);
8void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); 8void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
9void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, 9void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
10 struct wireless_dev *wdev); 10 struct wireless_dev *wdev);
11void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, 11struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
12 struct wireless_dev *wdev); 12 struct wireless_dev *wdev, bool aborted);
13void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 13void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
14 struct wireless_dev *wdev); 14 struct sk_buff *msg);
15void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, 15void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
16 struct net_device *netdev, u32 cmd); 16 struct net_device *netdev, u32 cmd);
17void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, 17void 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
164void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) 164void ___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
216void __cfg80211_scan_done(struct work_struct *wk) 226void __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)