aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-02-18 15:12:07 -0500
committerDavid S. Miller <davem@davemloft.net>2013-02-18 15:12:07 -0500
commit40d1ae57a0eb2ea8196e15cd2d54ffc186497522 (patch)
tree4efa8aa9d2c1e8b70272aaea4f472a1c656d0998 /net/wireless
parent6cf1c5fc26c6507bcb0edced6fcda876a79b5a6d (diff)
parent98d5fac2330779e6eea6431a90b44c7476260dcc (diff)
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says: ==================== This probably is the last big pull request for wireless bits for 3.9. Of course, I'm sure there will be a few stragglers here and there...surely a few bug fixes as well... :-) (In fact, I see that Johannes has already queued-up a few more for me while I was preparing this...) Included are a number of pulls... For mac80211-next, Johannes says: "The biggest change I have is undoubtedly Marco's mesh powersave implementation. Beyond that, I have a patch from Emmanuel to modify the DTIM period API in mac80211, scan improvements and a removal of some previous workaround code from Stanislaw, dynamic short slot time from Thomas and 64-bit station byte counters from Vladimir. I also made a number of changes myself, some related to WoWLAN, some auth/deauth improvements and most of them BSS list cleanups." "This time, I have relatively large number of fixes in various areas of the code (a memory leak in regulatory, an RX race in mac80211, the new radar checking caused a P2P device problem, some mesh issues with stations, an older bug in tracing and for kernel-doc) as well as a number of small new features. The biggest (in the diffstat) is my work on hidden SSID tracking." "Please pull to get * radar detection work from Simon * mesh improvements from Thomas * a connection monitoring/powersave fix from Wojciech * TDLS-related station management work from Jouni * VLAN crypto fixes from Michael Braun * CCK support in minstrel_ht from Felix * an SMPS (not SMSP, oops) related improvement in mac80211 (Emmanuel) * some WoWLAN work from Amitkumar Karwar: pattern match offset and a documentation fix * some WoWLAN work from myself (TCP connection wakeup feature API) * and a lot of VHT (and some HT) work (also from myself) And a number of more random cleanups/fixes. I merged mac80211/master to avoid a merge problem there." And regarding iwlwifi-next, Johannes says: "We continue work on our new driver, but I also have a WoWLAN and AP mode improvement for the previous driver and a change to use threaded interrupts to prepare us for working with non-PCIe devices." Regarding wl12xx, Luca says: "A few more patches intended for 3.9. Mostly some clean-ups I've been doing to make it easier to support device-tree. Also including one bug fix for wl12xx where the rates we advertise were wrong and an update in the wlconf structure to support newer firmwares." For the nfc-next bits, Samuel says: "This is the second NFC pull request for 3.9. We have: - A few pn533 fixes on top of Waldemar refactorization of the driver, one of them fixes target mode. - A new driver for Inside Secure microread chipset. It supports two physical layers: i2c and MEI. The MEI one depends on a patchset that's been sent to Greg Kroah-Hartman for inclusion into the 3.9 kernel [1]. The dependency is a KConfig one which means this code is not buildable as long as the MEI API is not usptream." "This 3rd NFC pull request for 3.9 contains a fix for the microread MEI physical layer support, as the MEI bus API changed. From the MEI code, we now pass the MEI id back to the driver probe routine, and we also pass a name and a MEI id table through the mei_bus_driver structure. A few renames as well like e.g. mei_bus_driver to mei_driver or mei_bus_client to mei_device in order to be closer to the driver model practices." For the ath6kl bits, Kalle says: "There's not anything special here, most of the patches are just code cleanup. The only functional changes are using the beacon interval from user space and fixing a crash which happens when inserting and removing the module in a loop." Also, I pulled the wireless tree in order to resolve some pending merge issues. On top of that, there is a bunch of work on brcmfmac that leads up to P2P support. Also, mwifiex, rtlwifi, and a variety of other drivers see some basic cleanups and minor enhancements. Please let me know if there are problems! ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/chan.c142
-rw-r--r--net/wireless/core.c8
-rw-r--r--net/wireless/core.h35
-rw-r--r--net/wireless/ibss.c4
-rw-r--r--net/wireless/mlme.c136
-rw-r--r--net/wireless/nl80211.c783
-rw-r--r--net/wireless/nl80211.h7
-rw-r--r--net/wireless/reg.c20
-rw-r--r--net/wireless/scan.c630
-rw-r--r--net/wireless/sme.c16
-rw-r--r--net/wireless/sysfs.c2
-rw-r--r--net/wireless/trace.h80
-rw-r--r--net/wireless/util.c2
13 files changed, 1486 insertions, 379 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 396373f3ec26..fd556ac05fdb 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -147,6 +147,32 @@ static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
147 } 147 }
148} 148}
149 149
150static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
151{
152 int width;
153
154 switch (c->width) {
155 case NL80211_CHAN_WIDTH_20:
156 case NL80211_CHAN_WIDTH_20_NOHT:
157 width = 20;
158 break;
159 case NL80211_CHAN_WIDTH_40:
160 width = 40;
161 break;
162 case NL80211_CHAN_WIDTH_80P80:
163 case NL80211_CHAN_WIDTH_80:
164 width = 80;
165 break;
166 case NL80211_CHAN_WIDTH_160:
167 width = 160;
168 break;
169 default:
170 WARN_ON_ONCE(1);
171 return -1;
172 }
173 return width;
174}
175
150const struct cfg80211_chan_def * 176const struct cfg80211_chan_def *
151cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1, 177cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
152 const struct cfg80211_chan_def *c2) 178 const struct cfg80211_chan_def *c2)
@@ -192,6 +218,93 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
192} 218}
193EXPORT_SYMBOL(cfg80211_chandef_compatible); 219EXPORT_SYMBOL(cfg80211_chandef_compatible);
194 220
221static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
222 u32 bandwidth,
223 enum nl80211_dfs_state dfs_state)
224{
225 struct ieee80211_channel *c;
226 u32 freq;
227
228 for (freq = center_freq - bandwidth/2 + 10;
229 freq <= center_freq + bandwidth/2 - 10;
230 freq += 20) {
231 c = ieee80211_get_channel(wiphy, freq);
232 if (!c || !(c->flags & IEEE80211_CHAN_RADAR))
233 continue;
234
235 c->dfs_state = dfs_state;
236 c->dfs_state_entered = jiffies;
237 }
238}
239
240void cfg80211_set_dfs_state(struct wiphy *wiphy,
241 const struct cfg80211_chan_def *chandef,
242 enum nl80211_dfs_state dfs_state)
243{
244 int width;
245
246 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
247 return;
248
249 width = cfg80211_chandef_get_width(chandef);
250 if (width < 0)
251 return;
252
253 cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq1,
254 width, dfs_state);
255
256 if (!chandef->center_freq2)
257 return;
258 cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq2,
259 width, dfs_state);
260}
261
262static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
263 u32 center_freq,
264 u32 bandwidth)
265{
266 struct ieee80211_channel *c;
267 u32 freq;
268
269 for (freq = center_freq - bandwidth/2 + 10;
270 freq <= center_freq + bandwidth/2 - 10;
271 freq += 20) {
272 c = ieee80211_get_channel(wiphy, freq);
273 if (!c)
274 return -EINVAL;
275
276 if (c->flags & IEEE80211_CHAN_RADAR)
277 return 1;
278 }
279 return 0;
280}
281
282
283int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
284 const struct cfg80211_chan_def *chandef)
285{
286 int width;
287 int r;
288
289 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
290 return -EINVAL;
291
292 width = cfg80211_chandef_get_width(chandef);
293 if (width < 0)
294 return -EINVAL;
295
296 r = cfg80211_get_chans_dfs_required(wiphy, chandef->center_freq1,
297 width);
298 if (r)
299 return r;
300
301 if (!chandef->center_freq2)
302 return 0;
303
304 return cfg80211_get_chans_dfs_required(wiphy, chandef->center_freq2,
305 width);
306}
307
195static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, 308static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
196 u32 center_freq, u32 bandwidth, 309 u32 center_freq, u32 bandwidth,
197 u32 prohibited_flags) 310 u32 prohibited_flags)
@@ -203,7 +316,16 @@ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
203 freq <= center_freq + bandwidth/2 - 10; 316 freq <= center_freq + bandwidth/2 - 10;
204 freq += 20) { 317 freq += 20) {
205 c = ieee80211_get_channel(wiphy, freq); 318 c = ieee80211_get_channel(wiphy, freq);
206 if (!c || c->flags & prohibited_flags) 319 if (!c)
320 return false;
321
322 /* check for radar flags */
323 if ((prohibited_flags & c->flags & IEEE80211_CHAN_RADAR) &&
324 (c->dfs_state != NL80211_DFS_AVAILABLE))
325 return false;
326
327 /* check for the other flags */
328 if (c->flags & prohibited_flags & ~IEEE80211_CHAN_RADAR)
207 return false; 329 return false;
208 } 330 }
209 331
@@ -253,6 +375,7 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
253 case NL80211_CHAN_WIDTH_80: 375 case NL80211_CHAN_WIDTH_80:
254 if (!vht_cap->vht_supported) 376 if (!vht_cap->vht_supported)
255 return false; 377 return false;
378 prohibited_flags |= IEEE80211_CHAN_NO_80MHZ;
256 width = 80; 379 width = 80;
257 break; 380 break;
258 case NL80211_CHAN_WIDTH_160: 381 case NL80211_CHAN_WIDTH_160:
@@ -260,6 +383,7 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
260 return false; 383 return false;
261 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)) 384 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ))
262 return false; 385 return false;
386 prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
263 width = 160; 387 width = 160;
264 break; 388 break;
265 default: 389 default:
@@ -267,7 +391,16 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
267 return false; 391 return false;
268 } 392 }
269 393
270 /* TODO: missing regulatory check on 80/160 bandwidth */ 394 /*
395 * TODO: What if there are only certain 80/160/80+80 MHz channels
396 * allowed by the driver, or only certain combinations?
397 * For 40 MHz the driver can set the NO_HT40 flags, but for
398 * 80/160 MHz and in particular 80+80 MHz this isn't really
399 * feasible and we only have NO_80MHZ/NO_160MHZ so far but
400 * no way to cover 80+80 MHz or more complex restrictions.
401 * Note that such restrictions also need to be advertised to
402 * userspace, for example for P2P channel selection.
403 */
271 404
272 if (width > 20) 405 if (width > 20)
273 prohibited_flags |= IEEE80211_CHAN_NO_OFDM; 406 prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
@@ -344,7 +477,10 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
344 break; 477 break;
345 case NL80211_IFTYPE_AP: 478 case NL80211_IFTYPE_AP:
346 case NL80211_IFTYPE_P2P_GO: 479 case NL80211_IFTYPE_P2P_GO:
347 if (wdev->beacon_interval) { 480 if (wdev->cac_started) {
481 *chan = wdev->channel;
482 *chanmode = CHAN_MODE_SHARED;
483 } else if (wdev->beacon_interval) {
348 *chan = wdev->channel; 484 *chan = wdev->channel;
349 *chanmode = CHAN_MODE_SHARED; 485 *chanmode = CHAN_MODE_SHARED;
350 } 486 }
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 40dbe37cfbf6..5ffff039b017 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -324,6 +324,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
324 INIT_LIST_HEAD(&rdev->bss_list); 324 INIT_LIST_HEAD(&rdev->bss_list);
325 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 325 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
326 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results); 326 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
327 INIT_DELAYED_WORK(&rdev->dfs_update_channels_wk,
328 cfg80211_dfs_channels_update_work);
327#ifdef CONFIG_CFG80211_WEXT 329#ifdef CONFIG_CFG80211_WEXT
328 rdev->wiphy.wext = &cfg80211_wext_handler; 330 rdev->wiphy.wext = &cfg80211_wext_handler;
329#endif 331#endif
@@ -365,7 +367,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
365 rdev->wiphy.rts_threshold = (u32) -1; 367 rdev->wiphy.rts_threshold = (u32) -1;
366 rdev->wiphy.coverage_class = 0; 368 rdev->wiphy.coverage_class = 0;
367 369
368 rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH; 370 rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH |
371 NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
369 372
370 return &rdev->wiphy; 373 return &rdev->wiphy;
371} 374}
@@ -695,6 +698,7 @@ void wiphy_unregister(struct wiphy *wiphy)
695 flush_work(&rdev->scan_done_wk); 698 flush_work(&rdev->scan_done_wk);
696 cancel_work_sync(&rdev->conn_work); 699 cancel_work_sync(&rdev->conn_work);
697 flush_work(&rdev->event_work); 700 flush_work(&rdev->event_work);
701 cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
698 702
699 if (rdev->wowlan && rdev->ops->set_wakeup) 703 if (rdev->wowlan && rdev->ops->set_wakeup)
700 rdev_set_wakeup(rdev, false); 704 rdev_set_wakeup(rdev, false);
@@ -715,7 +719,7 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
715 kfree(reg); 719 kfree(reg);
716 } 720 }
717 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) 721 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
718 cfg80211_put_bss(&scan->pub); 722 cfg80211_put_bss(&rdev->wiphy, &scan->pub);
719 kfree(rdev); 723 kfree(rdev);
720} 724}
721 725
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 8396f7671c8d..3aec0e429d8a 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -8,7 +8,6 @@
8#include <linux/mutex.h> 8#include <linux/mutex.h>
9#include <linux/list.h> 9#include <linux/list.h>
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/kref.h>
12#include <linux/rbtree.h> 11#include <linux/rbtree.h>
13#include <linux/debugfs.h> 12#include <linux/debugfs.h>
14#include <linux/rfkill.h> 13#include <linux/rfkill.h>
@@ -87,6 +86,8 @@ struct cfg80211_registered_device {
87 86
88 struct cfg80211_wowlan *wowlan; 87 struct cfg80211_wowlan *wowlan;
89 88
89 struct delayed_work dfs_update_channels_wk;
90
90 /* must be last because of the way we do wiphy_priv(), 91 /* must be last because of the way we do wiphy_priv(),
91 * and it should at least be aligned to NETDEV_ALIGN */ 92 * and it should at least be aligned to NETDEV_ALIGN */
92 struct wiphy wiphy __aligned(NETDEV_ALIGN); 93 struct wiphy wiphy __aligned(NETDEV_ALIGN);
@@ -109,6 +110,9 @@ cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
109 for (i = 0; i < rdev->wowlan->n_patterns; i++) 110 for (i = 0; i < rdev->wowlan->n_patterns; i++)
110 kfree(rdev->wowlan->patterns[i].mask); 111 kfree(rdev->wowlan->patterns[i].mask);
111 kfree(rdev->wowlan->patterns); 112 kfree(rdev->wowlan->patterns);
113 if (rdev->wowlan->tcp && rdev->wowlan->tcp->sock)
114 sock_release(rdev->wowlan->tcp->sock);
115 kfree(rdev->wowlan->tcp);
112 kfree(rdev->wowlan); 116 kfree(rdev->wowlan);
113} 117}
114 118
@@ -124,9 +128,10 @@ static inline void assert_cfg80211_lock(void)
124 128
125struct cfg80211_internal_bss { 129struct cfg80211_internal_bss {
126 struct list_head list; 130 struct list_head list;
131 struct list_head hidden_list;
127 struct rb_node rbn; 132 struct rb_node rbn;
128 unsigned long ts; 133 unsigned long ts;
129 struct kref ref; 134 unsigned long refcount;
130 atomic_t hold; 135 atomic_t hold;
131 136
132 /* must be last because of priv member */ 137 /* must be last because of priv member */
@@ -428,6 +433,22 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
428 enum cfg80211_chan_mode chanmode, 433 enum cfg80211_chan_mode chanmode,
429 u8 radar_detect); 434 u8 radar_detect);
430 435
436/**
437 * cfg80211_chandef_dfs_required - checks if radar detection is required
438 * @wiphy: the wiphy to validate against
439 * @chandef: the channel definition to check
440 * Return: 1 if radar detection is required, 0 if it is not, < 0 on error
441 */
442int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
443 const struct cfg80211_chan_def *c);
444
445void cfg80211_set_dfs_state(struct wiphy *wiphy,
446 const struct cfg80211_chan_def *chandef,
447 enum nl80211_dfs_state dfs_state);
448
449void cfg80211_dfs_channels_update_work(struct work_struct *work);
450
451
431static inline int 452static inline int
432cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, 453cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
433 struct wireless_dev *wdev, 454 struct wireless_dev *wdev,
@@ -454,6 +475,16 @@ cfg80211_can_use_chan(struct cfg80211_registered_device *rdev,
454 chan, chanmode, 0); 475 chan, chanmode, 0);
455} 476}
456 477
478static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
479{
480 unsigned long end = jiffies;
481
482 if (end >= start)
483 return jiffies_to_msecs(end - start);
484
485 return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
486}
487
457void 488void
458cfg80211_get_chan_state(struct wireless_dev *wdev, 489cfg80211_get_chan_state(struct wireless_dev *wdev,
459 struct ieee80211_channel **chan, 490 struct ieee80211_channel **chan,
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 9b9551e4a6f9..d80e47194d49 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -37,7 +37,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
37 37
38 if (wdev->current_bss) { 38 if (wdev->current_bss) {
39 cfg80211_unhold_bss(wdev->current_bss); 39 cfg80211_unhold_bss(wdev->current_bss);
40 cfg80211_put_bss(&wdev->current_bss->pub); 40 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
41 } 41 }
42 42
43 cfg80211_hold_bss(bss_from_pub(bss)); 43 cfg80211_hold_bss(bss_from_pub(bss));
@@ -182,7 +182,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
182 182
183 if (wdev->current_bss) { 183 if (wdev->current_bss) {
184 cfg80211_unhold_bss(wdev->current_bss); 184 cfg80211_unhold_bss(wdev->current_bss);
185 cfg80211_put_bss(&wdev->current_bss->pub); 185 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
186 } 186 }
187 187
188 wdev->current_bss = NULL; 188 wdev->current_bss = NULL;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 461e692cdfec..caddca35d686 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -58,7 +58,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
58 */ 58 */
59 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn && 59 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
60 cfg80211_sme_failed_reassoc(wdev)) { 60 cfg80211_sme_failed_reassoc(wdev)) {
61 cfg80211_put_bss(bss); 61 cfg80211_put_bss(wiphy, bss);
62 goto out; 62 goto out;
63 } 63 }
64 64
@@ -70,7 +70,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
70 * do not call connect_result() now because the 70 * do not call connect_result() now because the
71 * sme will schedule work that does it later. 71 * sme will schedule work that does it later.
72 */ 72 */
73 cfg80211_put_bss(bss); 73 cfg80211_put_bss(wiphy, bss);
74 goto out; 74 goto out;
75 } 75 }
76 76
@@ -108,7 +108,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
108 if (wdev->current_bss && 108 if (wdev->current_bss &&
109 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { 109 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
110 cfg80211_unhold_bss(wdev->current_bss); 110 cfg80211_unhold_bss(wdev->current_bss);
111 cfg80211_put_bss(&wdev->current_bss->pub); 111 cfg80211_put_bss(wiphy, &wdev->current_bss->pub);
112 wdev->current_bss = NULL; 112 wdev->current_bss = NULL;
113 was_current = true; 113 was_current = true;
114 } 114 }
@@ -164,7 +164,7 @@ void __cfg80211_send_disassoc(struct net_device *dev,
164 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { 164 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
165 cfg80211_sme_disassoc(dev, wdev->current_bss); 165 cfg80211_sme_disassoc(dev, wdev->current_bss);
166 cfg80211_unhold_bss(wdev->current_bss); 166 cfg80211_unhold_bss(wdev->current_bss);
167 cfg80211_put_bss(&wdev->current_bss->pub); 167 cfg80211_put_bss(wiphy, &wdev->current_bss->pub);
168 wdev->current_bss = NULL; 168 wdev->current_bss = NULL;
169 } else 169 } else
170 WARN_ON(1); 170 WARN_ON(1);
@@ -324,7 +324,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
324 err = rdev_auth(rdev, dev, &req); 324 err = rdev_auth(rdev, dev, &req);
325 325
326out: 326out:
327 cfg80211_put_bss(req.bss); 327 cfg80211_put_bss(&rdev->wiphy, req.bss);
328 return err; 328 return err;
329} 329}
330 330
@@ -432,7 +432,7 @@ out:
432 if (err) { 432 if (err) {
433 if (was_connected) 433 if (was_connected)
434 wdev->sme_state = CFG80211_SME_CONNECTED; 434 wdev->sme_state = CFG80211_SME_CONNECTED;
435 cfg80211_put_bss(req.bss); 435 cfg80211_put_bss(&rdev->wiphy, req.bss);
436 } 436 }
437 437
438 return err; 438 return err;
@@ -514,7 +514,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
514 if (wdev->sme_state != CFG80211_SME_CONNECTED) 514 if (wdev->sme_state != CFG80211_SME_CONNECTED)
515 return -ENOTCONN; 515 return -ENOTCONN;
516 516
517 if (WARN_ON(!wdev->current_bss)) 517 if (WARN(!wdev->current_bss, "sme_state=%d\n", wdev->sme_state))
518 return -ENOTCONN; 518 return -ENOTCONN;
519 519
520 memset(&req, 0, sizeof(req)); 520 memset(&req, 0, sizeof(req));
@@ -572,7 +572,7 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
572 572
573 if (wdev->current_bss) { 573 if (wdev->current_bss) {
574 cfg80211_unhold_bss(wdev->current_bss); 574 cfg80211_unhold_bss(wdev->current_bss);
575 cfg80211_put_bss(&wdev->current_bss->pub); 575 cfg80211_put_bss(&rdev->wiphy, &wdev->current_bss->pub);
576 wdev->current_bss = NULL; 576 wdev->current_bss = NULL;
577 } 577 }
578} 578}
@@ -987,3 +987,123 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
987 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); 987 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
988} 988}
989EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); 989EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
990
991void cfg80211_dfs_channels_update_work(struct work_struct *work)
992{
993 struct delayed_work *delayed_work;
994 struct cfg80211_registered_device *rdev;
995 struct cfg80211_chan_def chandef;
996 struct ieee80211_supported_band *sband;
997 struct ieee80211_channel *c;
998 struct wiphy *wiphy;
999 bool check_again = false;
1000 unsigned long timeout, next_time = 0;
1001 int bandid, i;
1002
1003 delayed_work = container_of(work, struct delayed_work, work);
1004 rdev = container_of(delayed_work, struct cfg80211_registered_device,
1005 dfs_update_channels_wk);
1006 wiphy = &rdev->wiphy;
1007
1008 mutex_lock(&cfg80211_mutex);
1009 for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) {
1010 sband = wiphy->bands[bandid];
1011 if (!sband)
1012 continue;
1013
1014 for (i = 0; i < sband->n_channels; i++) {
1015 c = &sband->channels[i];
1016
1017 if (c->dfs_state != NL80211_DFS_UNAVAILABLE)
1018 continue;
1019
1020 timeout = c->dfs_state_entered +
1021 IEEE80211_DFS_MIN_NOP_TIME_MS;
1022
1023 if (time_after_eq(jiffies, timeout)) {
1024 c->dfs_state = NL80211_DFS_USABLE;
1025 cfg80211_chandef_create(&chandef, c,
1026 NL80211_CHAN_NO_HT);
1027
1028 nl80211_radar_notify(rdev, &chandef,
1029 NL80211_RADAR_NOP_FINISHED,
1030 NULL, GFP_ATOMIC);
1031 continue;
1032 }
1033
1034 if (!check_again)
1035 next_time = timeout - jiffies;
1036 else
1037 next_time = min(next_time, timeout - jiffies);
1038 check_again = true;
1039 }
1040 }
1041 mutex_unlock(&cfg80211_mutex);
1042
1043 /* reschedule if there are other channels waiting to be cleared again */
1044 if (check_again)
1045 queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
1046 next_time);
1047}
1048
1049
1050void cfg80211_radar_event(struct wiphy *wiphy,
1051 struct cfg80211_chan_def *chandef,
1052 gfp_t gfp)
1053{
1054 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1055 unsigned long timeout;
1056
1057 trace_cfg80211_radar_event(wiphy, chandef);
1058
1059 /* only set the chandef supplied channel to unavailable, in
1060 * case the radar is detected on only one of multiple channels
1061 * spanned by the chandef.
1062 */
1063 cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
1064
1065 timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_NOP_TIME_MS);
1066 queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
1067 timeout);
1068
1069 nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
1070}
1071EXPORT_SYMBOL(cfg80211_radar_event);
1072
1073void cfg80211_cac_event(struct net_device *netdev,
1074 enum nl80211_radar_event event, gfp_t gfp)
1075{
1076 struct wireless_dev *wdev = netdev->ieee80211_ptr;
1077 struct wiphy *wiphy = wdev->wiphy;
1078 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1079 struct cfg80211_chan_def chandef;
1080 unsigned long timeout;
1081
1082 trace_cfg80211_cac_event(netdev, event);
1083
1084 if (WARN_ON(!wdev->cac_started))
1085 return;
1086
1087 if (WARN_ON(!wdev->channel))
1088 return;
1089
1090 cfg80211_chandef_create(&chandef, wdev->channel, NL80211_CHAN_NO_HT);
1091
1092 switch (event) {
1093 case NL80211_RADAR_CAC_FINISHED:
1094 timeout = wdev->cac_start_time +
1095 msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
1096 WARN_ON(!time_after_eq(jiffies, timeout));
1097 cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_AVAILABLE);
1098 break;
1099 case NL80211_RADAR_CAC_ABORTED:
1100 break;
1101 default:
1102 WARN_ON(1);
1103 return;
1104 }
1105 wdev->cac_started = false;
1106
1107 nl80211_radar_notify(rdev, &chandef, event, netdev, gfp);
1108}
1109EXPORT_SYMBOL(cfg80211_cac_event);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b5978ab4ad7a..580ffeaef3d5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -19,6 +19,7 @@
19#include <net/genetlink.h> 19#include <net/genetlink.h>
20#include <net/cfg80211.h> 20#include <net/cfg80211.h>
21#include <net/sock.h> 21#include <net/sock.h>
22#include <net/inet_connection_sock.h>
22#include "core.h" 23#include "core.h"
23#include "nl80211.h" 24#include "nl80211.h"
24#include "reg.h" 25#include "reg.h"
@@ -367,6 +368,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
367 [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 }, 368 [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
368 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 }, 369 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
369 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED }, 370 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
371 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
372 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
370}; 373};
371 374
372/* policy for the key attributes */ 375/* policy for the key attributes */
@@ -399,6 +402,26 @@ nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
399 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG }, 402 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
400 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG }, 403 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
401 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG }, 404 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
405 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
406};
407
408static const struct nla_policy
409nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
410 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
411 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
412 [NL80211_WOWLAN_TCP_DST_MAC] = { .len = ETH_ALEN },
413 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
414 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
415 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .len = 1 },
416 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
417 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
418 },
419 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
420 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
421 },
422 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
423 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .len = 1 },
424 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
402}; 425};
403 426
404/* policy for GTK rekey offload attributes */ 427/* policy for GTK rekey offload attributes */
@@ -531,8 +554,27 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
531 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && 554 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
532 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) 555 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS))
533 goto nla_put_failure; 556 goto nla_put_failure;
534 if ((chan->flags & IEEE80211_CHAN_RADAR) && 557 if (chan->flags & IEEE80211_CHAN_RADAR) {
535 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) 558 u32 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
559 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
560 goto nla_put_failure;
561 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
562 chan->dfs_state))
563 goto nla_put_failure;
564 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME, time))
565 goto nla_put_failure;
566 }
567 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
568 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
569 goto nla_put_failure;
570 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
571 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
572 goto nla_put_failure;
573 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
574 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
575 goto nla_put_failure;
576 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
577 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
536 goto nla_put_failure; 578 goto nla_put_failure;
537 579
538 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 580 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
@@ -872,6 +914,48 @@ nla_put_failure:
872 return -ENOBUFS; 914 return -ENOBUFS;
873} 915}
874 916
917#ifdef CONFIG_PM
918static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
919 struct sk_buff *msg)
920{
921 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp;
922 struct nlattr *nl_tcp;
923
924 if (!tcp)
925 return 0;
926
927 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
928 if (!nl_tcp)
929 return -ENOBUFS;
930
931 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
932 tcp->data_payload_max))
933 return -ENOBUFS;
934
935 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
936 tcp->data_payload_max))
937 return -ENOBUFS;
938
939 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
940 return -ENOBUFS;
941
942 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
943 sizeof(*tcp->tok), tcp->tok))
944 return -ENOBUFS;
945
946 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
947 tcp->data_interval_max))
948 return -ENOBUFS;
949
950 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
951 tcp->wake_payload_max))
952 return -ENOBUFS;
953
954 nla_nest_end(msg, nl_tcp);
955 return 0;
956}
957#endif
958
875static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags, 959static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags,
876 struct cfg80211_registered_device *dev) 960 struct cfg80211_registered_device *dev)
877{ 961{
@@ -1238,12 +1322,17 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
1238 dev->wiphy.wowlan.pattern_min_len, 1322 dev->wiphy.wowlan.pattern_min_len,
1239 .max_pattern_len = 1323 .max_pattern_len =
1240 dev->wiphy.wowlan.pattern_max_len, 1324 dev->wiphy.wowlan.pattern_max_len,
1325 .max_pkt_offset =
1326 dev->wiphy.wowlan.max_pkt_offset,
1241 }; 1327 };
1242 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, 1328 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1243 sizeof(pat), &pat)) 1329 sizeof(pat), &pat))
1244 goto nla_put_failure; 1330 goto nla_put_failure;
1245 } 1331 }
1246 1332
1333 if (nl80211_send_wowlan_tcp_caps(dev, msg))
1334 goto nla_put_failure;
1335
1247 nla_nest_end(msg, nl_wowlan); 1336 nla_nest_end(msg, nl_wowlan);
1248 } 1337 }
1249#endif 1338#endif
@@ -1276,6 +1365,15 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
1276 dev->wiphy.max_acl_mac_addrs)) 1365 dev->wiphy.max_acl_mac_addrs))
1277 goto nla_put_failure; 1366 goto nla_put_failure;
1278 1367
1368 if (dev->wiphy.extended_capabilities &&
1369 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1370 dev->wiphy.extended_capabilities_len,
1371 dev->wiphy.extended_capabilities) ||
1372 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1373 dev->wiphy.extended_capabilities_len,
1374 dev->wiphy.extended_capabilities_mask)))
1375 goto nla_put_failure;
1376
1279 return genlmsg_end(msg, hdr); 1377 return genlmsg_end(msg, hdr);
1280 1378
1281 nla_put_failure: 1379 nla_put_failure:
@@ -2707,6 +2805,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2707 struct wireless_dev *wdev = dev->ieee80211_ptr; 2805 struct wireless_dev *wdev = dev->ieee80211_ptr;
2708 struct cfg80211_ap_settings params; 2806 struct cfg80211_ap_settings params;
2709 int err; 2807 int err;
2808 u8 radar_detect_width = 0;
2710 2809
2711 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2810 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2712 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 2811 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
@@ -2825,9 +2924,19 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2825 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef)) 2924 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
2826 return -EINVAL; 2925 return -EINVAL;
2827 2926
2927 err = cfg80211_chandef_dfs_required(wdev->wiphy, &params.chandef);
2928 if (err < 0)
2929 return err;
2930 if (err) {
2931 radar_detect_width = BIT(params.chandef.width);
2932 params.radar_required = true;
2933 }
2934
2828 mutex_lock(&rdev->devlist_mtx); 2935 mutex_lock(&rdev->devlist_mtx);
2829 err = cfg80211_can_use_chan(rdev, wdev, params.chandef.chan, 2936 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
2830 CHAN_MODE_SHARED); 2937 params.chandef.chan,
2938 CHAN_MODE_SHARED,
2939 radar_detect_width);
2831 mutex_unlock(&rdev->devlist_mtx); 2940 mutex_unlock(&rdev->devlist_mtx);
2832 2941
2833 if (err) 2942 if (err)
@@ -3057,12 +3166,22 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
3057 nla_put_u32(msg, NL80211_STA_INFO_INACTIVE_TIME, 3166 nla_put_u32(msg, NL80211_STA_INFO_INACTIVE_TIME,
3058 sinfo->inactive_time)) 3167 sinfo->inactive_time))
3059 goto nla_put_failure; 3168 goto nla_put_failure;
3060 if ((sinfo->filled & STATION_INFO_RX_BYTES) && 3169 if ((sinfo->filled & (STATION_INFO_RX_BYTES |
3170 STATION_INFO_RX_BYTES64)) &&
3061 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES, 3171 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
3062 sinfo->rx_bytes)) 3172 (u32)sinfo->rx_bytes))
3063 goto nla_put_failure; 3173 goto nla_put_failure;
3064 if ((sinfo->filled & STATION_INFO_TX_BYTES) && 3174 if ((sinfo->filled & (STATION_INFO_TX_BYTES |
3175 NL80211_STA_INFO_TX_BYTES64)) &&
3065 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, 3176 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
3177 (u32)sinfo->tx_bytes))
3178 goto nla_put_failure;
3179 if ((sinfo->filled & STATION_INFO_RX_BYTES64) &&
3180 nla_put_u64(msg, NL80211_STA_INFO_RX_BYTES64,
3181 sinfo->rx_bytes))
3182 goto nla_put_failure;
3183 if ((sinfo->filled & STATION_INFO_TX_BYTES64) &&
3184 nla_put_u64(msg, NL80211_STA_INFO_TX_BYTES64,
3066 sinfo->tx_bytes)) 3185 sinfo->tx_bytes))
3067 goto nla_put_failure; 3186 goto nla_put_failure;
3068 if ((sinfo->filled & STATION_INFO_LLID) && 3187 if ((sinfo->filled & STATION_INFO_LLID) &&
@@ -3290,6 +3409,63 @@ static struct net_device *get_vlan(struct genl_info *info,
3290 return ERR_PTR(ret); 3409 return ERR_PTR(ret);
3291} 3410}
3292 3411
3412static struct nla_policy
3413nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
3414 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
3415 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
3416};
3417
3418static int nl80211_set_station_tdls(struct genl_info *info,
3419 struct station_parameters *params)
3420{
3421 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3422 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
3423 struct nlattr *nla;
3424 int err;
3425
3426 /* Can only set if TDLS ... */
3427 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
3428 return -EOPNOTSUPP;
3429
3430 /* ... with external setup is supported */
3431 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
3432 return -EOPNOTSUPP;
3433
3434 /* Dummy STA entry gets updated once the peer capabilities are known */
3435 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
3436 params->ht_capa =
3437 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
3438 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
3439 params->vht_capa =
3440 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
3441
3442 /* parse WME attributes if present */
3443 if (!info->attrs[NL80211_ATTR_STA_WME])
3444 return 0;
3445
3446 nla = info->attrs[NL80211_ATTR_STA_WME];
3447 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
3448 nl80211_sta_wme_policy);
3449 if (err)
3450 return err;
3451
3452 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
3453 params->uapsd_queues = nla_get_u8(
3454 tb[NL80211_STA_WME_UAPSD_QUEUES]);
3455 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
3456 return -EINVAL;
3457
3458 if (tb[NL80211_STA_WME_MAX_SP])
3459 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
3460
3461 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
3462 return -EINVAL;
3463
3464 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
3465
3466 return 0;
3467}
3468
3293static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) 3469static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
3294{ 3470{
3295 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 3471 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -3318,8 +3494,20 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
3318 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); 3494 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
3319 } 3495 }
3320 3496
3321 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL] || 3497 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
3322 info->attrs[NL80211_ATTR_HT_CAPABILITY]) 3498 params.capability =
3499 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
3500 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
3501 }
3502
3503 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
3504 params.ext_capab =
3505 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
3506 params.ext_capab_len =
3507 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
3508 }
3509
3510 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
3323 return -EINVAL; 3511 return -EINVAL;
3324 3512
3325 if (!rdev->ops->change_station) 3513 if (!rdev->ops->change_station)
@@ -3388,6 +3576,13 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
3388 /* reject other things that can't change */ 3576 /* reject other things that can't change */
3389 if (params.supported_rates) 3577 if (params.supported_rates)
3390 return -EINVAL; 3578 return -EINVAL;
3579 if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
3580 return -EINVAL;
3581 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
3582 return -EINVAL;
3583 if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
3584 info->attrs[NL80211_ATTR_VHT_CAPABILITY])
3585 return -EINVAL;
3391 3586
3392 /* must be last in here for error handling */ 3587 /* must be last in here for error handling */
3393 params.vlan = get_vlan(info, rdev); 3588 params.vlan = get_vlan(info, rdev);
@@ -3403,13 +3598,29 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
3403 * to change the flag. 3598 * to change the flag.
3404 */ 3599 */
3405 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); 3600 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3406 /* fall through */ 3601 /* Include parameters for TDLS peer (driver will check) */
3602 err = nl80211_set_station_tdls(info, &params);
3603 if (err)
3604 return err;
3605 /* disallow things sta doesn't support */
3606 if (params.plink_action)
3607 return -EINVAL;
3608 if (params.local_pm)
3609 return -EINVAL;
3610 /* reject any changes other than AUTHORIZED or WME (for TDLS) */
3611 if (params.sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
3612 BIT(NL80211_STA_FLAG_WME)))
3613 return -EINVAL;
3614 break;
3407 case NL80211_IFTYPE_ADHOC: 3615 case NL80211_IFTYPE_ADHOC:
3408 /* disallow things sta doesn't support */ 3616 /* disallow things sta doesn't support */
3409 if (params.plink_action) 3617 if (params.plink_action)
3410 return -EINVAL; 3618 return -EINVAL;
3411 if (params.local_pm) 3619 if (params.local_pm)
3412 return -EINVAL; 3620 return -EINVAL;
3621 if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
3622 info->attrs[NL80211_ATTR_VHT_CAPABILITY])
3623 return -EINVAL;
3413 /* reject any changes other than AUTHORIZED */ 3624 /* reject any changes other than AUTHORIZED */
3414 if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED)) 3625 if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
3415 return -EINVAL; 3626 return -EINVAL;
@@ -3420,6 +3631,13 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
3420 return -EINVAL; 3631 return -EINVAL;
3421 if (params.supported_rates) 3632 if (params.supported_rates)
3422 return -EINVAL; 3633 return -EINVAL;
3634 if (info->attrs[NL80211_ATTR_STA_CAPABILITY])
3635 return -EINVAL;
3636 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY])
3637 return -EINVAL;
3638 if (info->attrs[NL80211_ATTR_HT_CAPABILITY] ||
3639 info->attrs[NL80211_ATTR_VHT_CAPABILITY])
3640 return -EINVAL;
3423 /* 3641 /*
3424 * No special handling for TDLS here -- the userspace 3642 * No special handling for TDLS here -- the userspace
3425 * mesh code doesn't have this bug. 3643 * mesh code doesn't have this bug.
@@ -3444,12 +3662,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
3444 return err; 3662 return err;
3445} 3663}
3446 3664
3447static struct nla_policy
3448nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
3449 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
3450 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
3451};
3452
3453static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) 3665static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3454{ 3666{
3455 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 3667 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -3484,6 +3696,19 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3484 if (!params.aid || params.aid > IEEE80211_MAX_AID) 3696 if (!params.aid || params.aid > IEEE80211_MAX_AID)
3485 return -EINVAL; 3697 return -EINVAL;
3486 3698
3699 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
3700 params.capability =
3701 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
3702 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
3703 }
3704
3705 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
3706 params.ext_capab =
3707 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
3708 params.ext_capab_len =
3709 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
3710 }
3711
3487 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) 3712 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
3488 params.ht_capa = 3713 params.ht_capa =
3489 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 3714 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
@@ -4977,6 +5202,54 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb,
4977 return err; 5202 return err;
4978} 5203}
4979 5204
5205static int nl80211_start_radar_detection(struct sk_buff *skb,
5206 struct genl_info *info)
5207{
5208 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5209 struct net_device *dev = info->user_ptr[1];
5210 struct wireless_dev *wdev = dev->ieee80211_ptr;
5211 struct cfg80211_chan_def chandef;
5212 int err;
5213
5214 err = nl80211_parse_chandef(rdev, info, &chandef);
5215 if (err)
5216 return err;
5217
5218 if (wdev->cac_started)
5219 return -EBUSY;
5220
5221 err = cfg80211_chandef_dfs_required(wdev->wiphy, &chandef);
5222 if (err < 0)
5223 return err;
5224
5225 if (err == 0)
5226 return -EINVAL;
5227
5228 if (chandef.chan->dfs_state != NL80211_DFS_USABLE)
5229 return -EINVAL;
5230
5231 if (!rdev->ops->start_radar_detection)
5232 return -EOPNOTSUPP;
5233
5234 mutex_lock(&rdev->devlist_mtx);
5235 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
5236 chandef.chan, CHAN_MODE_SHARED,
5237 BIT(chandef.width));
5238 if (err)
5239 goto err_locked;
5240
5241 err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
5242 if (!err) {
5243 wdev->channel = chandef.chan;
5244 wdev->cac_started = true;
5245 wdev->cac_start_time = jiffies;
5246 }
5247err_locked:
5248 mutex_unlock(&rdev->devlist_mtx);
5249
5250 return err;
5251}
5252
4980static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, 5253static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
4981 u32 seq, int flags, 5254 u32 seq, int flags,
4982 struct cfg80211_registered_device *rdev, 5255 struct cfg80211_registered_device *rdev,
@@ -4987,6 +5260,7 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
4987 const struct cfg80211_bss_ies *ies; 5260 const struct cfg80211_bss_ies *ies;
4988 void *hdr; 5261 void *hdr;
4989 struct nlattr *bss; 5262 struct nlattr *bss;
5263 bool tsf = false;
4990 5264
4991 ASSERT_WDEV_LOCK(wdev); 5265 ASSERT_WDEV_LOCK(wdev);
4992 5266
@@ -5010,22 +5284,24 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
5010 5284
5011 rcu_read_lock(); 5285 rcu_read_lock();
5012 ies = rcu_dereference(res->ies); 5286 ies = rcu_dereference(res->ies);
5013 if (ies && ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, 5287 if (ies) {
5014 ies->len, ies->data)) { 5288 if (nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
5015 rcu_read_unlock(); 5289 goto fail_unlock_rcu;
5016 goto nla_put_failure; 5290 tsf = true;
5291 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
5292 ies->len, ies->data))
5293 goto fail_unlock_rcu;
5017 } 5294 }
5018 ies = rcu_dereference(res->beacon_ies); 5295 ies = rcu_dereference(res->beacon_ies);
5019 if (ies && ies->len && nla_put(msg, NL80211_BSS_BEACON_IES, 5296 if (ies) {
5020 ies->len, ies->data)) { 5297 if (!tsf && nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
5021 rcu_read_unlock(); 5298 goto fail_unlock_rcu;
5022 goto nla_put_failure; 5299 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
5300 ies->len, ies->data))
5301 goto fail_unlock_rcu;
5023 } 5302 }
5024 rcu_read_unlock(); 5303 rcu_read_unlock();
5025 5304
5026 if (res->tsf &&
5027 nla_put_u64(msg, NL80211_BSS_TSF, res->tsf))
5028 goto nla_put_failure;
5029 if (res->beacon_interval && 5305 if (res->beacon_interval &&
5030 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval)) 5306 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
5031 goto nla_put_failure; 5307 goto nla_put_failure;
@@ -5070,6 +5346,8 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
5070 5346
5071 return genlmsg_end(msg, hdr); 5347 return genlmsg_end(msg, hdr);
5072 5348
5349 fail_unlock_rcu:
5350 rcu_read_unlock();
5073 nla_put_failure: 5351 nla_put_failure:
5074 genlmsg_cancel(msg, hdr); 5352 genlmsg_cancel(msg, hdr);
5075 return -EMSGSIZE; 5353 return -EMSGSIZE;
@@ -6880,16 +7158,100 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
6880} 7158}
6881 7159
6882#ifdef CONFIG_PM 7160#ifdef CONFIG_PM
7161static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
7162 struct cfg80211_registered_device *rdev)
7163{
7164 struct nlattr *nl_pats, *nl_pat;
7165 int i, pat_len;
7166
7167 if (!rdev->wowlan->n_patterns)
7168 return 0;
7169
7170 nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
7171 if (!nl_pats)
7172 return -ENOBUFS;
7173
7174 for (i = 0; i < rdev->wowlan->n_patterns; i++) {
7175 nl_pat = nla_nest_start(msg, i + 1);
7176 if (!nl_pat)
7177 return -ENOBUFS;
7178 pat_len = rdev->wowlan->patterns[i].pattern_len;
7179 if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
7180 DIV_ROUND_UP(pat_len, 8),
7181 rdev->wowlan->patterns[i].mask) ||
7182 nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
7183 pat_len, rdev->wowlan->patterns[i].pattern) ||
7184 nla_put_u32(msg, NL80211_WOWLAN_PKTPAT_OFFSET,
7185 rdev->wowlan->patterns[i].pkt_offset))
7186 return -ENOBUFS;
7187 nla_nest_end(msg, nl_pat);
7188 }
7189 nla_nest_end(msg, nl_pats);
7190
7191 return 0;
7192}
7193
7194static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
7195 struct cfg80211_wowlan_tcp *tcp)
7196{
7197 struct nlattr *nl_tcp;
7198
7199 if (!tcp)
7200 return 0;
7201
7202 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
7203 if (!nl_tcp)
7204 return -ENOBUFS;
7205
7206 if (nla_put_be32(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
7207 nla_put_be32(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
7208 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
7209 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
7210 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
7211 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
7212 tcp->payload_len, tcp->payload) ||
7213 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
7214 tcp->data_interval) ||
7215 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
7216 tcp->wake_len, tcp->wake_data) ||
7217 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
7218 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
7219 return -ENOBUFS;
7220
7221 if (tcp->payload_seq.len &&
7222 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
7223 sizeof(tcp->payload_seq), &tcp->payload_seq))
7224 return -ENOBUFS;
7225
7226 if (tcp->payload_tok.len &&
7227 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
7228 sizeof(tcp->payload_tok) + tcp->tokens_size,
7229 &tcp->payload_tok))
7230 return -ENOBUFS;
7231
7232 return 0;
7233}
7234
6883static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) 7235static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
6884{ 7236{
6885 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 7237 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6886 struct sk_buff *msg; 7238 struct sk_buff *msg;
6887 void *hdr; 7239 void *hdr;
7240 u32 size = NLMSG_DEFAULT_SIZE;
6888 7241
6889 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) 7242 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns &&
7243 !rdev->wiphy.wowlan.tcp)
6890 return -EOPNOTSUPP; 7244 return -EOPNOTSUPP;
6891 7245
6892 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7246 if (rdev->wowlan && rdev->wowlan->tcp) {
7247 /* adjust size to have room for all the data */
7248 size += rdev->wowlan->tcp->tokens_size +
7249 rdev->wowlan->tcp->payload_len +
7250 rdev->wowlan->tcp->wake_len +
7251 rdev->wowlan->tcp->wake_len / 8;
7252 }
7253
7254 msg = nlmsg_new(size, GFP_KERNEL);
6893 if (!msg) 7255 if (!msg)
6894 return -ENOMEM; 7256 return -ENOMEM;
6895 7257
@@ -6920,31 +7282,12 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
6920 (rdev->wowlan->rfkill_release && 7282 (rdev->wowlan->rfkill_release &&
6921 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) 7283 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
6922 goto nla_put_failure; 7284 goto nla_put_failure;
6923 if (rdev->wowlan->n_patterns) {
6924 struct nlattr *nl_pats, *nl_pat;
6925 int i, pat_len;
6926 7285
6927 nl_pats = nla_nest_start(msg, 7286 if (nl80211_send_wowlan_patterns(msg, rdev))
6928 NL80211_WOWLAN_TRIG_PKT_PATTERN); 7287 goto nla_put_failure;
6929 if (!nl_pats)
6930 goto nla_put_failure;
6931 7288
6932 for (i = 0; i < rdev->wowlan->n_patterns; i++) { 7289 if (nl80211_send_wowlan_tcp(msg, rdev->wowlan->tcp))
6933 nl_pat = nla_nest_start(msg, i + 1); 7290 goto nla_put_failure;
6934 if (!nl_pat)
6935 goto nla_put_failure;
6936 pat_len = rdev->wowlan->patterns[i].pattern_len;
6937 if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
6938 DIV_ROUND_UP(pat_len, 8),
6939 rdev->wowlan->patterns[i].mask) ||
6940 nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
6941 pat_len,
6942 rdev->wowlan->patterns[i].pattern))
6943 goto nla_put_failure;
6944 nla_nest_end(msg, nl_pat);
6945 }
6946 nla_nest_end(msg, nl_pats);
6947 }
6948 7291
6949 nla_nest_end(msg, nl_wowlan); 7292 nla_nest_end(msg, nl_wowlan);
6950 } 7293 }
@@ -6957,6 +7300,150 @@ nla_put_failure:
6957 return -ENOBUFS; 7300 return -ENOBUFS;
6958} 7301}
6959 7302
7303static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
7304 struct nlattr *attr,
7305 struct cfg80211_wowlan *trig)
7306{
7307 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
7308 struct cfg80211_wowlan_tcp *cfg;
7309 struct nl80211_wowlan_tcp_data_token *tok = NULL;
7310 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
7311 u32 size;
7312 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
7313 int err, port;
7314
7315 if (!rdev->wiphy.wowlan.tcp)
7316 return -EINVAL;
7317
7318 err = nla_parse(tb, MAX_NL80211_WOWLAN_TCP,
7319 nla_data(attr), nla_len(attr),
7320 nl80211_wowlan_tcp_policy);
7321 if (err)
7322 return err;
7323
7324 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
7325 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
7326 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
7327 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
7328 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
7329 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
7330 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
7331 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
7332 return -EINVAL;
7333
7334 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
7335 if (data_size > rdev->wiphy.wowlan.tcp->data_payload_max)
7336 return -EINVAL;
7337
7338 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
7339 rdev->wiphy.wowlan.tcp->data_interval_max)
7340 return -EINVAL;
7341
7342 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
7343 if (wake_size > rdev->wiphy.wowlan.tcp->wake_payload_max)
7344 return -EINVAL;
7345
7346 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
7347 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
7348 return -EINVAL;
7349
7350 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
7351 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
7352
7353 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
7354 tokens_size = tokln - sizeof(*tok);
7355
7356 if (!tok->len || tokens_size % tok->len)
7357 return -EINVAL;
7358 if (!rdev->wiphy.wowlan.tcp->tok)
7359 return -EINVAL;
7360 if (tok->len > rdev->wiphy.wowlan.tcp->tok->max_len)
7361 return -EINVAL;
7362 if (tok->len < rdev->wiphy.wowlan.tcp->tok->min_len)
7363 return -EINVAL;
7364 if (tokens_size > rdev->wiphy.wowlan.tcp->tok->bufsize)
7365 return -EINVAL;
7366 if (tok->offset + tok->len > data_size)
7367 return -EINVAL;
7368 }
7369
7370 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
7371 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
7372 if (!rdev->wiphy.wowlan.tcp->seq)
7373 return -EINVAL;
7374 if (seq->len == 0 || seq->len > 4)
7375 return -EINVAL;
7376 if (seq->len + seq->offset > data_size)
7377 return -EINVAL;
7378 }
7379
7380 size = sizeof(*cfg);
7381 size += data_size;
7382 size += wake_size + wake_mask_size;
7383 size += tokens_size;
7384
7385 cfg = kzalloc(size, GFP_KERNEL);
7386 if (!cfg)
7387 return -ENOMEM;
7388 cfg->src = nla_get_be32(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
7389 cfg->dst = nla_get_be32(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
7390 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
7391 ETH_ALEN);
7392 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
7393 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
7394 else
7395 port = 0;
7396#ifdef CONFIG_INET
7397 /* allocate a socket and port for it and use it */
7398 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
7399 IPPROTO_TCP, &cfg->sock, 1);
7400 if (err) {
7401 kfree(cfg);
7402 return err;
7403 }
7404 if (inet_csk_get_port(cfg->sock->sk, port)) {
7405 sock_release(cfg->sock);
7406 kfree(cfg);
7407 return -EADDRINUSE;
7408 }
7409 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
7410#else
7411 if (!port) {
7412 kfree(cfg);
7413 return -EINVAL;
7414 }
7415 cfg->src_port = port;
7416#endif
7417
7418 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
7419 cfg->payload_len = data_size;
7420 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
7421 memcpy((void *)cfg->payload,
7422 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
7423 data_size);
7424 if (seq)
7425 cfg->payload_seq = *seq;
7426 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
7427 cfg->wake_len = wake_size;
7428 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
7429 memcpy((void *)cfg->wake_data,
7430 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
7431 wake_size);
7432 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
7433 data_size + wake_size;
7434 memcpy((void *)cfg->wake_mask,
7435 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
7436 wake_mask_size);
7437 if (tok) {
7438 cfg->tokens_size = tokens_size;
7439 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
7440 }
7441
7442 trig->tcp = cfg;
7443
7444 return 0;
7445}
7446
6960static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) 7447static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
6961{ 7448{
6962 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 7449 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6967,7 +7454,8 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
6967 int err, i; 7454 int err, i;
6968 bool prev_enabled = rdev->wowlan; 7455 bool prev_enabled = rdev->wowlan;
6969 7456
6970 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) 7457 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns &&
7458 !rdev->wiphy.wowlan.tcp)
6971 return -EOPNOTSUPP; 7459 return -EOPNOTSUPP;
6972 7460
6973 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { 7461 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
@@ -7031,7 +7519,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7031 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { 7519 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
7032 struct nlattr *pat; 7520 struct nlattr *pat;
7033 int n_patterns = 0; 7521 int n_patterns = 0;
7034 int rem, pat_len, mask_len; 7522 int rem, pat_len, mask_len, pkt_offset;
7035 struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT]; 7523 struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];
7036 7524
7037 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], 7525 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
@@ -7066,6 +7554,15 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7066 pat_len < wowlan->pattern_min_len) 7554 pat_len < wowlan->pattern_min_len)
7067 goto error; 7555 goto error;
7068 7556
7557 if (!pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET])
7558 pkt_offset = 0;
7559 else
7560 pkt_offset = nla_get_u32(
7561 pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET]);
7562 if (pkt_offset > wowlan->max_pkt_offset)
7563 goto error;
7564 new_triggers.patterns[i].pkt_offset = pkt_offset;
7565
7069 new_triggers.patterns[i].mask = 7566 new_triggers.patterns[i].mask =
7070 kmalloc(mask_len + pat_len, GFP_KERNEL); 7567 kmalloc(mask_len + pat_len, GFP_KERNEL);
7071 if (!new_triggers.patterns[i].mask) { 7568 if (!new_triggers.patterns[i].mask) {
@@ -7085,6 +7582,14 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7085 } 7582 }
7086 } 7583 }
7087 7584
7585 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
7586 err = nl80211_parse_wowlan_tcp(
7587 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
7588 &new_triggers);
7589 if (err)
7590 goto error;
7591 }
7592
7088 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL); 7593 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
7089 if (!ntrig) { 7594 if (!ntrig) {
7090 err = -ENOMEM; 7595 err = -ENOMEM;
@@ -7102,6 +7607,9 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7102 for (i = 0; i < new_triggers.n_patterns; i++) 7607 for (i = 0; i < new_triggers.n_patterns; i++)
7103 kfree(new_triggers.patterns[i].mask); 7608 kfree(new_triggers.patterns[i].mask);
7104 kfree(new_triggers.patterns); 7609 kfree(new_triggers.patterns);
7610 if (new_triggers.tcp && new_triggers.tcp->sock)
7611 sock_release(new_triggers.tcp->sock);
7612 kfree(new_triggers.tcp);
7105 return err; 7613 return err;
7106} 7614}
7107#endif 7615#endif
@@ -7992,6 +8500,14 @@ static struct genl_ops nl80211_ops[] = {
7992 .internal_flags = NL80211_FLAG_NEED_NETDEV | 8500 .internal_flags = NL80211_FLAG_NEED_NETDEV |
7993 NL80211_FLAG_NEED_RTNL, 8501 NL80211_FLAG_NEED_RTNL,
7994 }, 8502 },
8503 {
8504 .cmd = NL80211_CMD_RADAR_DETECT,
8505 .doit = nl80211_start_radar_detection,
8506 .policy = nl80211_policy,
8507 .flags = GENL_ADMIN_PERM,
8508 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
8509 NL80211_FLAG_NEED_RTNL,
8510 },
7995}; 8511};
7996 8512
7997static struct genl_multicast_group nl80211_mlme_mcgrp = { 8513static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -9189,6 +9705,57 @@ nl80211_send_cqm_txe_notify(struct cfg80211_registered_device *rdev,
9189} 9705}
9190 9706
9191void 9707void
9708nl80211_radar_notify(struct cfg80211_registered_device *rdev,
9709 struct cfg80211_chan_def *chandef,
9710 enum nl80211_radar_event event,
9711 struct net_device *netdev, gfp_t gfp)
9712{
9713 struct sk_buff *msg;
9714 void *hdr;
9715
9716 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
9717 if (!msg)
9718 return;
9719
9720 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
9721 if (!hdr) {
9722 nlmsg_free(msg);
9723 return;
9724 }
9725
9726 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
9727 goto nla_put_failure;
9728
9729 /* NOP and radar events don't need a netdev parameter */
9730 if (netdev) {
9731 struct wireless_dev *wdev = netdev->ieee80211_ptr;
9732
9733 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
9734 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
9735 goto nla_put_failure;
9736 }
9737
9738 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
9739 goto nla_put_failure;
9740
9741 if (nl80211_send_chandef(msg, chandef))
9742 goto nla_put_failure;
9743
9744 if (genlmsg_end(msg, hdr) < 0) {
9745 nlmsg_free(msg);
9746 return;
9747 }
9748
9749 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
9750 nl80211_mlme_mcgrp.id, gfp);
9751 return;
9752
9753 nla_put_failure:
9754 genlmsg_cancel(msg, hdr);
9755 nlmsg_free(msg);
9756}
9757
9758void
9192nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 9759nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
9193 struct net_device *netdev, const u8 *peer, 9760 struct net_device *netdev, const u8 *peer,
9194 u32 num_packets, gfp_t gfp) 9761 u32 num_packets, gfp_t gfp)
@@ -9323,6 +9890,114 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
9323} 9890}
9324EXPORT_SYMBOL(cfg80211_report_obss_beacon); 9891EXPORT_SYMBOL(cfg80211_report_obss_beacon);
9325 9892
9893#ifdef CONFIG_PM
9894void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
9895 struct cfg80211_wowlan_wakeup *wakeup,
9896 gfp_t gfp)
9897{
9898 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
9899 struct sk_buff *msg;
9900 void *hdr;
9901 int err, size = 200;
9902
9903 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
9904
9905 if (wakeup)
9906 size += wakeup->packet_present_len;
9907
9908 msg = nlmsg_new(size, gfp);
9909 if (!msg)
9910 return;
9911
9912 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
9913 if (!hdr)
9914 goto free_msg;
9915
9916 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
9917 nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
9918 goto free_msg;
9919
9920 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
9921 wdev->netdev->ifindex))
9922 goto free_msg;
9923
9924 if (wakeup) {
9925 struct nlattr *reasons;
9926
9927 reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
9928
9929 if (wakeup->disconnect &&
9930 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
9931 goto free_msg;
9932 if (wakeup->magic_pkt &&
9933 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
9934 goto free_msg;
9935 if (wakeup->gtk_rekey_failure &&
9936 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
9937 goto free_msg;
9938 if (wakeup->eap_identity_req &&
9939 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
9940 goto free_msg;
9941 if (wakeup->four_way_handshake &&
9942 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
9943 goto free_msg;
9944 if (wakeup->rfkill_release &&
9945 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
9946 goto free_msg;
9947
9948 if (wakeup->pattern_idx >= 0 &&
9949 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
9950 wakeup->pattern_idx))
9951 goto free_msg;
9952
9953 if (wakeup->tcp_match)
9954 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH);
9955
9956 if (wakeup->tcp_connlost)
9957 nla_put_flag(msg,
9958 NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST);
9959
9960 if (wakeup->tcp_nomoretokens)
9961 nla_put_flag(msg,
9962 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS);
9963
9964 if (wakeup->packet) {
9965 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
9966 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
9967
9968 if (!wakeup->packet_80211) {
9969 pkt_attr =
9970 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
9971 len_attr =
9972 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
9973 }
9974
9975 if (wakeup->packet_len &&
9976 nla_put_u32(msg, len_attr, wakeup->packet_len))
9977 goto free_msg;
9978
9979 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
9980 wakeup->packet))
9981 goto free_msg;
9982 }
9983
9984 nla_nest_end(msg, reasons);
9985 }
9986
9987 err = genlmsg_end(msg, hdr);
9988 if (err < 0)
9989 goto free_msg;
9990
9991 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
9992 nl80211_mlme_mcgrp.id, gfp);
9993 return;
9994
9995 free_msg:
9996 nlmsg_free(msg);
9997}
9998EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
9999#endif
10000
9326void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer, 10001void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
9327 enum nl80211_tdls_operation oper, 10002 enum nl80211_tdls_operation oper,
9328 u16 reason_code, gfp_t gfp) 10003 u16 reason_code, gfp_t gfp)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 2acba8477e9d..b061da4919e1 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -108,6 +108,13 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
108 struct net_device *netdev, 108 struct net_device *netdev,
109 enum nl80211_cqm_rssi_threshold_event rssi_event, 109 enum nl80211_cqm_rssi_threshold_event rssi_event,
110 gfp_t gfp); 110 gfp_t gfp);
111
112void
113nl80211_radar_notify(struct cfg80211_registered_device *rdev,
114 struct cfg80211_chan_def *chandef,
115 enum nl80211_radar_event event,
116 struct net_device *netdev, gfp_t gfp);
117
111void 118void
112nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 119nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
113 struct net_device *netdev, const u8 *peer, 120 struct net_device *netdev, const u8 *peer,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index de02d633c212..98532c00242d 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -866,6 +866,10 @@ static void handle_channel(struct wiphy *wiphy,
866 866
867 if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(40)) 867 if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(40))
868 bw_flags = IEEE80211_CHAN_NO_HT40; 868 bw_flags = IEEE80211_CHAN_NO_HT40;
869 if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(80))
870 bw_flags |= IEEE80211_CHAN_NO_80MHZ;
871 if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(160))
872 bw_flags |= IEEE80211_CHAN_NO_160MHZ;
869 873
870 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && 874 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
871 request_wiphy && request_wiphy == wiphy && 875 request_wiphy && request_wiphy == wiphy &&
@@ -884,6 +888,9 @@ static void handle_channel(struct wiphy *wiphy,
884 return; 888 return;
885 } 889 }
886 890
891 chan->dfs_state = NL80211_DFS_USABLE;
892 chan->dfs_state_entered = jiffies;
893
887 chan->beacon_found = false; 894 chan->beacon_found = false;
888 chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags); 895 chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags);
889 chan->max_antenna_gain = 896 chan->max_antenna_gain =
@@ -1261,6 +1268,10 @@ static void handle_channel_custom(struct wiphy *wiphy,
1261 1268
1262 if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(40)) 1269 if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(40))
1263 bw_flags = IEEE80211_CHAN_NO_HT40; 1270 bw_flags = IEEE80211_CHAN_NO_HT40;
1271 if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(80))
1272 bw_flags |= IEEE80211_CHAN_NO_80MHZ;
1273 if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(160))
1274 bw_flags |= IEEE80211_CHAN_NO_160MHZ;
1264 1275
1265 chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; 1276 chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags;
1266 chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); 1277 chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
@@ -2189,10 +2200,15 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2189 * However if a driver requested this specific regulatory 2200 * However if a driver requested this specific regulatory
2190 * domain we keep it for its private use 2201 * domain we keep it for its private use
2191 */ 2202 */
2192 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER) 2203 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER) {
2204 const struct ieee80211_regdomain *tmp;
2205
2206 tmp = get_wiphy_regdom(request_wiphy);
2193 rcu_assign_pointer(request_wiphy->regd, rd); 2207 rcu_assign_pointer(request_wiphy->regd, rd);
2194 else 2208 rcu_free_regdom(tmp);
2209 } else {
2195 kfree(rd); 2210 kfree(rd);
2211 }
2196 2212
2197 rd = NULL; 2213 rd = NULL;
2198 2214
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 45f1618c8e23..674aadca0079 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -19,55 +19,142 @@
19#include "wext-compat.h" 19#include "wext-compat.h"
20#include "rdev-ops.h" 20#include "rdev-ops.h"
21 21
22/**
23 * DOC: BSS tree/list structure
24 *
25 * At the top level, the BSS list is kept in both a list in each
26 * registered device (@bss_list) as well as an RB-tree for faster
27 * lookup. In the RB-tree, entries can be looked up using their
28 * channel, MESHID, MESHCONF (for MBSSes) or channel, BSSID, SSID
29 * for other BSSes.
30 *
31 * Due to the possibility of hidden SSIDs, there's a second level
32 * structure, the "hidden_list" and "hidden_beacon_bss" pointer.
33 * The hidden_list connects all BSSes belonging to a single AP
34 * that has a hidden SSID, and connects beacon and probe response
35 * entries. For a probe response entry for a hidden SSID, the
36 * hidden_beacon_bss pointer points to the BSS struct holding the
37 * beacon's information.
38 *
39 * Reference counting is done for all these references except for
40 * the hidden_list, so that a beacon BSS struct that is otherwise
41 * not referenced has one reference for being on the bss_list and
42 * one for each probe response entry that points to it using the
43 * hidden_beacon_bss pointer. When a BSS struct that has such a
44 * pointer is get/put, the refcount update is also propagated to
45 * the referenced struct, this ensure that it cannot get removed
46 * while somebody is using the probe response version.
47 *
48 * Note that the hidden_beacon_bss pointer never changes, due to
49 * the reference counting. Therefore, no locking is needed for
50 * it.
51 *
52 * Also note that the hidden_beacon_bss pointer is only relevant
53 * if the driver uses something other than the IEs, e.g. private
54 * data stored stored in the BSS struct, since the beacon IEs are
55 * also linked into the probe response struct.
56 */
57
22#define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ) 58#define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ)
23 59
24static void bss_release(struct kref *ref) 60static void bss_free(struct cfg80211_internal_bss *bss)
25{ 61{
26 struct cfg80211_bss_ies *ies; 62 struct cfg80211_bss_ies *ies;
27 struct cfg80211_internal_bss *bss;
28
29 bss = container_of(ref, struct cfg80211_internal_bss, ref);
30 63
31 if (WARN_ON(atomic_read(&bss->hold))) 64 if (WARN_ON(atomic_read(&bss->hold)))
32 return; 65 return;
33 66
34 if (bss->pub.free_priv)
35 bss->pub.free_priv(&bss->pub);
36
37 ies = (void *)rcu_access_pointer(bss->pub.beacon_ies); 67 ies = (void *)rcu_access_pointer(bss->pub.beacon_ies);
38 if (ies) 68 if (ies && !bss->pub.hidden_beacon_bss)
39 kfree_rcu(ies, rcu_head); 69 kfree_rcu(ies, rcu_head);
40 ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies); 70 ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies);
41 if (ies) 71 if (ies)
42 kfree_rcu(ies, rcu_head); 72 kfree_rcu(ies, rcu_head);
43 73
74 /*
75 * This happens when the module is removed, it doesn't
76 * really matter any more save for completeness
77 */
78 if (!list_empty(&bss->hidden_list))
79 list_del(&bss->hidden_list);
80
44 kfree(bss); 81 kfree(bss);
45} 82}
46 83
47/* must hold dev->bss_lock! */ 84static inline void bss_ref_get(struct cfg80211_registered_device *dev,
48static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev, 85 struct cfg80211_internal_bss *bss)
86{
87 lockdep_assert_held(&dev->bss_lock);
88
89 bss->refcount++;
90 if (bss->pub.hidden_beacon_bss) {
91 bss = container_of(bss->pub.hidden_beacon_bss,
92 struct cfg80211_internal_bss,
93 pub);
94 bss->refcount++;
95 }
96}
97
98static inline void bss_ref_put(struct cfg80211_registered_device *dev,
99 struct cfg80211_internal_bss *bss)
100{
101 lockdep_assert_held(&dev->bss_lock);
102
103 if (bss->pub.hidden_beacon_bss) {
104 struct cfg80211_internal_bss *hbss;
105 hbss = container_of(bss->pub.hidden_beacon_bss,
106 struct cfg80211_internal_bss,
107 pub);
108 hbss->refcount--;
109 if (hbss->refcount == 0)
110 bss_free(hbss);
111 }
112 bss->refcount--;
113 if (bss->refcount == 0)
114 bss_free(bss);
115}
116
117static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *dev,
49 struct cfg80211_internal_bss *bss) 118 struct cfg80211_internal_bss *bss)
50{ 119{
120 lockdep_assert_held(&dev->bss_lock);
121
122 if (!list_empty(&bss->hidden_list)) {
123 /*
124 * don't remove the beacon entry if it has
125 * probe responses associated with it
126 */
127 if (!bss->pub.hidden_beacon_bss)
128 return false;
129 /*
130 * if it's a probe response entry break its
131 * link to the other entries in the group
132 */
133 list_del_init(&bss->hidden_list);
134 }
135
51 list_del_init(&bss->list); 136 list_del_init(&bss->list);
52 rb_erase(&bss->rbn, &dev->bss_tree); 137 rb_erase(&bss->rbn, &dev->bss_tree);
53 kref_put(&bss->ref, bss_release); 138 bss_ref_put(dev, bss);
139 return true;
54} 140}
55 141
56/* must hold dev->bss_lock! */
57static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev, 142static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev,
58 unsigned long expire_time) 143 unsigned long expire_time)
59{ 144{
60 struct cfg80211_internal_bss *bss, *tmp; 145 struct cfg80211_internal_bss *bss, *tmp;
61 bool expired = false; 146 bool expired = false;
62 147
148 lockdep_assert_held(&dev->bss_lock);
149
63 list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) { 150 list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) {
64 if (atomic_read(&bss->hold)) 151 if (atomic_read(&bss->hold))
65 continue; 152 continue;
66 if (!time_after(expire_time, bss->ts)) 153 if (!time_after(expire_time, bss->ts))
67 continue; 154 continue;
68 155
69 __cfg80211_unlink_bss(dev, bss); 156 if (__cfg80211_unlink_bss(dev, bss))
70 expired = true; 157 expired = true;
71 } 158 }
72 159
73 if (expired) 160 if (expired)
@@ -234,15 +321,16 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
234 return 0; 321 return 0;
235} 322}
236 323
237/* must hold dev->bss_lock! */
238void cfg80211_bss_age(struct cfg80211_registered_device *dev, 324void cfg80211_bss_age(struct cfg80211_registered_device *dev,
239 unsigned long age_secs) 325 unsigned long age_secs)
240{ 326{
241 struct cfg80211_internal_bss *bss; 327 struct cfg80211_internal_bss *bss;
242 unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC); 328 unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
243 329
330 spin_lock_bh(&dev->bss_lock);
244 list_for_each_entry(bss, &dev->bss_list, list) 331 list_for_each_entry(bss, &dev->bss_list, list)
245 bss->ts -= age_jiffies; 332 bss->ts -= age_jiffies;
333 spin_unlock_bh(&dev->bss_lock);
246} 334}
247 335
248void cfg80211_bss_expire(struct cfg80211_registered_device *dev) 336void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
@@ -277,40 +365,24 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
277 if (!pos) 365 if (!pos)
278 return NULL; 366 return NULL;
279 367
280 if (end - pos < sizeof(*ie))
281 return NULL;
282
283 ie = (struct ieee80211_vendor_ie *)pos; 368 ie = (struct ieee80211_vendor_ie *)pos;
369
370 /* make sure we can access ie->len */
371 BUILD_BUG_ON(offsetof(struct ieee80211_vendor_ie, len) != 1);
372
373 if (ie->len < sizeof(*ie))
374 goto cont;
375
284 ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2]; 376 ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2];
285 if (ie_oui == oui && ie->oui_type == oui_type) 377 if (ie_oui == oui && ie->oui_type == oui_type)
286 return pos; 378 return pos;
287 379cont:
288 pos += 2 + ie->len; 380 pos += 2 + ie->len;
289 } 381 }
290 return NULL; 382 return NULL;
291} 383}
292EXPORT_SYMBOL(cfg80211_find_vendor_ie); 384EXPORT_SYMBOL(cfg80211_find_vendor_ie);
293 385
294static int cmp_ies(u8 num, const u8 *ies1, int len1, const u8 *ies2, int len2)
295{
296 const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
297 const u8 *ie2 = cfg80211_find_ie(num, ies2, len2);
298
299 /* equal if both missing */
300 if (!ie1 && !ie2)
301 return 0;
302 /* sort missing IE before (left of) present IE */
303 if (!ie1)
304 return -1;
305 if (!ie2)
306 return 1;
307
308 /* sort by length first, then by contents */
309 if (ie1[1] != ie2[1])
310 return ie2[1] - ie1[1];
311 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
312}
313
314static bool is_bss(struct cfg80211_bss *a, const u8 *bssid, 386static bool is_bss(struct cfg80211_bss *a, const u8 *bssid,
315 const u8 *ssid, size_t ssid_len) 387 const u8 *ssid, size_t ssid_len)
316{ 388{
@@ -334,109 +406,30 @@ static bool is_bss(struct cfg80211_bss *a, const u8 *bssid,
334 return memcmp(ssidie + 2, ssid, ssid_len) == 0; 406 return memcmp(ssidie + 2, ssid, ssid_len) == 0;
335} 407}
336 408
337static bool is_mesh_bss(struct cfg80211_bss *a) 409/**
338{ 410 * enum bss_compare_mode - BSS compare mode
339 const struct cfg80211_bss_ies *ies; 411 * @BSS_CMP_REGULAR: regular compare mode (for insertion and normal find)
340 const u8 *ie; 412 * @BSS_CMP_HIDE_ZLEN: find hidden SSID with zero-length mode
341 413 * @BSS_CMP_HIDE_NUL: find hidden SSID with NUL-ed out mode
342 if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability)) 414 */
343 return false; 415enum bss_compare_mode {
344 416 BSS_CMP_REGULAR,
345 ies = rcu_access_pointer(a->ies); 417 BSS_CMP_HIDE_ZLEN,
346 if (!ies) 418 BSS_CMP_HIDE_NUL,
347 return false; 419};
348
349 ie = cfg80211_find_ie(WLAN_EID_MESH_ID, ies->data, ies->len);
350 if (!ie)
351 return false;
352
353 ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, ies->data, ies->len);
354 if (!ie)
355 return false;
356
357 return true;
358}
359
360static bool is_mesh(struct cfg80211_bss *a,
361 const u8 *meshid, size_t meshidlen,
362 const u8 *meshcfg)
363{
364 const struct cfg80211_bss_ies *ies;
365 const u8 *ie;
366
367 if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
368 return false;
369
370 ies = rcu_access_pointer(a->ies);
371 if (!ies)
372 return false;
373
374 ie = cfg80211_find_ie(WLAN_EID_MESH_ID, ies->data, ies->len);
375 if (!ie)
376 return false;
377 if (ie[1] != meshidlen)
378 return false;
379 if (memcmp(ie + 2, meshid, meshidlen))
380 return false;
381
382 ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, ies->data, ies->len);
383 if (!ie)
384 return false;
385 if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
386 return false;
387
388 /*
389 * Ignore mesh capability (last two bytes of the IE) when
390 * comparing since that may differ between stations taking
391 * part in the same mesh.
392 */
393 return memcmp(ie + 2, meshcfg,
394 sizeof(struct ieee80211_meshconf_ie) - 2) == 0;
395}
396 420
397static int cmp_bss_core(struct cfg80211_bss *a, struct cfg80211_bss *b) 421static int cmp_bss(struct cfg80211_bss *a,
422 struct cfg80211_bss *b,
423 enum bss_compare_mode mode)
398{ 424{
399 const struct cfg80211_bss_ies *a_ies, *b_ies; 425 const struct cfg80211_bss_ies *a_ies, *b_ies;
400 int r; 426 const u8 *ie1 = NULL;
427 const u8 *ie2 = NULL;
428 int i, r;
401 429
402 if (a->channel != b->channel) 430 if (a->channel != b->channel)
403 return b->channel->center_freq - a->channel->center_freq; 431 return b->channel->center_freq - a->channel->center_freq;
404 432
405 if (is_mesh_bss(a) && is_mesh_bss(b)) {
406 a_ies = rcu_access_pointer(a->ies);
407 if (!a_ies)
408 return -1;
409 b_ies = rcu_access_pointer(b->ies);
410 if (!b_ies)
411 return 1;
412
413 r = cmp_ies(WLAN_EID_MESH_ID,
414 a_ies->data, a_ies->len,
415 b_ies->data, b_ies->len);
416 if (r)
417 return r;
418 return cmp_ies(WLAN_EID_MESH_CONFIG,
419 a_ies->data, a_ies->len,
420 b_ies->data, b_ies->len);
421 }
422
423 /*
424 * we can't use compare_ether_addr here since we need a < > operator.
425 * The binary return value of compare_ether_addr isn't enough
426 */
427 return memcmp(a->bssid, b->bssid, sizeof(a->bssid));
428}
429
430static int cmp_bss(struct cfg80211_bss *a,
431 struct cfg80211_bss *b)
432{
433 const struct cfg80211_bss_ies *a_ies, *b_ies;
434 int r;
435
436 r = cmp_bss_core(a, b);
437 if (r)
438 return r;
439
440 a_ies = rcu_access_pointer(a->ies); 433 a_ies = rcu_access_pointer(a->ies);
441 if (!a_ies) 434 if (!a_ies)
442 return -1; 435 return -1;
@@ -444,42 +437,51 @@ static int cmp_bss(struct cfg80211_bss *a,
444 if (!b_ies) 437 if (!b_ies)
445 return 1; 438 return 1;
446 439
447 return cmp_ies(WLAN_EID_SSID, 440 if (WLAN_CAPABILITY_IS_STA_BSS(a->capability))
448 a_ies->data, a_ies->len, 441 ie1 = cfg80211_find_ie(WLAN_EID_MESH_ID,
449 b_ies->data, b_ies->len); 442 a_ies->data, a_ies->len);
450} 443 if (WLAN_CAPABILITY_IS_STA_BSS(b->capability))
451 444 ie2 = cfg80211_find_ie(WLAN_EID_MESH_ID,
452static int cmp_hidden_bss(struct cfg80211_bss *a, struct cfg80211_bss *b) 445 b_ies->data, b_ies->len);
453{ 446 if (ie1 && ie2) {
454 const struct cfg80211_bss_ies *a_ies, *b_ies; 447 int mesh_id_cmp;
455 const u8 *ie1; 448
456 const u8 *ie2; 449 if (ie1[1] == ie2[1])
457 int i; 450 mesh_id_cmp = memcmp(ie1 + 2, ie2 + 2, ie1[1]);
458 int r; 451 else
452 mesh_id_cmp = ie2[1] - ie1[1];
453
454 ie1 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
455 a_ies->data, a_ies->len);
456 ie2 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
457 b_ies->data, b_ies->len);
458 if (ie1 && ie2) {
459 if (mesh_id_cmp)
460 return mesh_id_cmp;
461 if (ie1[1] != ie2[1])
462 return ie2[1] - ie1[1];
463 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
464 }
465 }
459 466
460 r = cmp_bss_core(a, b); 467 /*
468 * we can't use compare_ether_addr here since we need a < > operator.
469 * The binary return value of compare_ether_addr isn't enough
470 */
471 r = memcmp(a->bssid, b->bssid, sizeof(a->bssid));
461 if (r) 472 if (r)
462 return r; 473 return r;
463 474
464 a_ies = rcu_access_pointer(a->ies);
465 if (!a_ies)
466 return -1;
467 b_ies = rcu_access_pointer(b->ies);
468 if (!b_ies)
469 return 1;
470
471 ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len); 475 ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len);
472 ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len); 476 ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len);
473 477
478 if (!ie1 && !ie2)
479 return 0;
480
474 /* 481 /*
475 * Key comparator must use same algorithm in any rb-tree 482 * Note that with "hide_ssid", the function returns a match if
476 * search function (order is important), otherwise ordering 483 * the already-present BSS ("b") is a hidden SSID beacon for
477 * of items in the tree is broken and search gives incorrect 484 * the new BSS ("a").
478 * results. This code uses same order as cmp_ies() does.
479 *
480 * Note that due to the differring behaviour with hidden SSIDs
481 * this function only works when "b" is the tree element and
482 * "a" is the key we're looking for.
483 */ 485 */
484 486
485 /* sort missing IE before (left of) present IE */ 487 /* sort missing IE before (left of) present IE */
@@ -488,24 +490,36 @@ static int cmp_hidden_bss(struct cfg80211_bss *a, struct cfg80211_bss *b)
488 if (!ie2) 490 if (!ie2)
489 return 1; 491 return 1;
490 492
491 /* zero-size SSID is used as an indication of the hidden bss */ 493 switch (mode) {
492 if (!ie2[1]) 494 case BSS_CMP_HIDE_ZLEN:
495 /*
496 * In ZLEN mode we assume the BSS entry we're
497 * looking for has a zero-length SSID. So if
498 * the one we're looking at right now has that,
499 * return 0. Otherwise, return the difference
500 * in length, but since we're looking for the
501 * 0-length it's really equivalent to returning
502 * the length of the one we're looking at.
503 *
504 * No content comparison is needed as we assume
505 * the content length is zero.
506 */
507 return ie2[1];
508 case BSS_CMP_REGULAR:
509 default:
510 /* sort by length first, then by contents */
511 if (ie1[1] != ie2[1])
512 return ie2[1] - ie1[1];
513 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
514 case BSS_CMP_HIDE_NUL:
515 if (ie1[1] != ie2[1])
516 return ie2[1] - ie1[1];
517 /* this is equivalent to memcmp(zeroes, ie2 + 2, len) */
518 for (i = 0; i < ie2[1]; i++)
519 if (ie2[i + 2])
520 return -1;
493 return 0; 521 return 0;
494 522 }
495 /* sort by length first, then by contents */
496 if (ie1[1] != ie2[1])
497 return ie2[1] - ie1[1];
498
499 /*
500 * zeroed SSID ie is another indication of a hidden bss;
501 * if it isn't zeroed just return the regular sort value
502 * to find the next candidate
503 */
504 for (i = 0; i < ie2[1]; i++)
505 if (ie2[i + 2])
506 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
507
508 return 0;
509} 523}
510 524
511struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, 525struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
@@ -534,7 +548,7 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
534 continue; 548 continue;
535 if (is_bss(&bss->pub, bssid, ssid, ssid_len)) { 549 if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
536 res = bss; 550 res = bss;
537 kref_get(&res->ref); 551 bss_ref_get(dev, res);
538 break; 552 break;
539 } 553 }
540 } 554 }
@@ -547,34 +561,6 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
547} 561}
548EXPORT_SYMBOL(cfg80211_get_bss); 562EXPORT_SYMBOL(cfg80211_get_bss);
549 563
550struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
551 struct ieee80211_channel *channel,
552 const u8 *meshid, size_t meshidlen,
553 const u8 *meshcfg)
554{
555 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
556 struct cfg80211_internal_bss *bss, *res = NULL;
557
558 spin_lock_bh(&dev->bss_lock);
559
560 list_for_each_entry(bss, &dev->bss_list, list) {
561 if (channel && bss->pub.channel != channel)
562 continue;
563 if (is_mesh(&bss->pub, meshid, meshidlen, meshcfg)) {
564 res = bss;
565 kref_get(&res->ref);
566 break;
567 }
568 }
569
570 spin_unlock_bh(&dev->bss_lock);
571 if (!res)
572 return NULL;
573 return &res->pub;
574}
575EXPORT_SYMBOL(cfg80211_get_mesh);
576
577
578static void rb_insert_bss(struct cfg80211_registered_device *dev, 564static void rb_insert_bss(struct cfg80211_registered_device *dev,
579 struct cfg80211_internal_bss *bss) 565 struct cfg80211_internal_bss *bss)
580{ 566{
@@ -587,7 +573,7 @@ static void rb_insert_bss(struct cfg80211_registered_device *dev,
587 parent = *p; 573 parent = *p;
588 tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn); 574 tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);
589 575
590 cmp = cmp_bss(&bss->pub, &tbss->pub); 576 cmp = cmp_bss(&bss->pub, &tbss->pub, BSS_CMP_REGULAR);
591 577
592 if (WARN_ON(!cmp)) { 578 if (WARN_ON(!cmp)) {
593 /* will sort of leak this BSS */ 579 /* will sort of leak this BSS */
@@ -606,7 +592,8 @@ static void rb_insert_bss(struct cfg80211_registered_device *dev,
606 592
607static struct cfg80211_internal_bss * 593static struct cfg80211_internal_bss *
608rb_find_bss(struct cfg80211_registered_device *dev, 594rb_find_bss(struct cfg80211_registered_device *dev,
609 struct cfg80211_internal_bss *res) 595 struct cfg80211_internal_bss *res,
596 enum bss_compare_mode mode)
610{ 597{
611 struct rb_node *n = dev->bss_tree.rb_node; 598 struct rb_node *n = dev->bss_tree.rb_node;
612 struct cfg80211_internal_bss *bss; 599 struct cfg80211_internal_bss *bss;
@@ -614,7 +601,7 @@ rb_find_bss(struct cfg80211_registered_device *dev,
614 601
615 while (n) { 602 while (n) {
616 bss = rb_entry(n, struct cfg80211_internal_bss, rbn); 603 bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
617 r = cmp_bss(&res->pub, &bss->pub); 604 r = cmp_bss(&res->pub, &bss->pub, mode);
618 605
619 if (r == 0) 606 if (r == 0)
620 return bss; 607 return bss;
@@ -627,46 +614,67 @@ rb_find_bss(struct cfg80211_registered_device *dev,
627 return NULL; 614 return NULL;
628} 615}
629 616
630static struct cfg80211_internal_bss * 617static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
631rb_find_hidden_bss(struct cfg80211_registered_device *dev, 618 struct cfg80211_internal_bss *new)
632 struct cfg80211_internal_bss *res)
633{ 619{
634 struct rb_node *n = dev->bss_tree.rb_node; 620 const struct cfg80211_bss_ies *ies;
635 struct cfg80211_internal_bss *bss; 621 struct cfg80211_internal_bss *bss;
636 int r; 622 const u8 *ie;
623 int i, ssidlen;
624 u8 fold = 0;
637 625
638 while (n) { 626 ies = rcu_access_pointer(new->pub.beacon_ies);
639 bss = rb_entry(n, struct cfg80211_internal_bss, rbn); 627 if (WARN_ON(!ies))
640 r = cmp_hidden_bss(&res->pub, &bss->pub); 628 return false;
641 629
642 if (r == 0) 630 ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
643 return bss; 631 if (!ie) {
644 else if (r < 0) 632 /* nothing to do */
645 n = n->rb_left; 633 return true;
646 else
647 n = n->rb_right;
648 } 634 }
649 635
650 return NULL; 636 ssidlen = ie[1];
651} 637 for (i = 0; i < ssidlen; i++)
638 fold |= ie[2 + i];
652 639
653static void 640 if (fold) {
654copy_hidden_ies(struct cfg80211_internal_bss *res, 641 /* not a hidden SSID */
655 struct cfg80211_internal_bss *hidden) 642 return true;
656{ 643 }
657 const struct cfg80211_bss_ies *ies;
658 644
659 if (rcu_access_pointer(res->pub.beacon_ies)) 645 /* This is the bad part ... */
660 return;
661 646
662 ies = rcu_access_pointer(hidden->pub.beacon_ies); 647 list_for_each_entry(bss, &dev->bss_list, list) {
663 if (WARN_ON(!ies)) 648 if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
664 return; 649 continue;
650 if (bss->pub.channel != new->pub.channel)
651 continue;
652 if (rcu_access_pointer(bss->pub.beacon_ies))
653 continue;
654 ies = rcu_access_pointer(bss->pub.ies);
655 if (!ies)
656 continue;
657 ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
658 if (!ie)
659 continue;
660 if (ssidlen && ie[1] != ssidlen)
661 continue;
662 /* that would be odd ... */
663 if (bss->pub.beacon_ies)
664 continue;
665 if (WARN_ON_ONCE(bss->pub.hidden_beacon_bss))
666 continue;
667 if (WARN_ON_ONCE(!list_empty(&bss->hidden_list)))
668 list_del(&bss->hidden_list);
669 /* combine them */
670 list_add(&bss->hidden_list, &new->hidden_list);
671 bss->pub.hidden_beacon_bss = &new->pub;
672 new->refcount += bss->refcount;
673 rcu_assign_pointer(bss->pub.beacon_ies,
674 new->pub.beacon_ies);
675 }
665 676
666 ies = kmemdup(ies, sizeof(*ies) + ies->len, GFP_ATOMIC); 677 return true;
667 if (unlikely(!ies))
668 return;
669 rcu_assign_pointer(res->pub.beacon_ies, ies);
670} 678}
671 679
672static struct cfg80211_internal_bss * 680static struct cfg80211_internal_bss *
@@ -687,11 +695,10 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
687 return NULL; 695 return NULL;
688 } 696 }
689 697
690 found = rb_find_bss(dev, tmp); 698 found = rb_find_bss(dev, tmp, BSS_CMP_REGULAR);
691 699
692 if (found) { 700 if (found) {
693 found->pub.beacon_interval = tmp->pub.beacon_interval; 701 found->pub.beacon_interval = tmp->pub.beacon_interval;
694 found->pub.tsf = tmp->pub.tsf;
695 found->pub.signal = tmp->pub.signal; 702 found->pub.signal = tmp->pub.signal;
696 found->pub.capability = tmp->pub.capability; 703 found->pub.capability = tmp->pub.capability;
697 found->ts = tmp->ts; 704 found->ts = tmp->ts;
@@ -711,19 +718,45 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
711 kfree_rcu((struct cfg80211_bss_ies *)old, 718 kfree_rcu((struct cfg80211_bss_ies *)old,
712 rcu_head); 719 rcu_head);
713 } else if (rcu_access_pointer(tmp->pub.beacon_ies)) { 720 } else if (rcu_access_pointer(tmp->pub.beacon_ies)) {
714 const struct cfg80211_bss_ies *old, *ies; 721 const struct cfg80211_bss_ies *old;
722 struct cfg80211_internal_bss *bss;
723
724 if (found->pub.hidden_beacon_bss &&
725 !list_empty(&found->hidden_list)) {
726 /*
727 * The found BSS struct is one of the probe
728 * response members of a group, but we're
729 * receiving a beacon (beacon_ies in the tmp
730 * bss is used). This can only mean that the
731 * AP changed its beacon from not having an
732 * SSID to showing it, which is confusing so
733 * drop this information.
734 */
735 goto drop;
736 }
715 737
716 old = rcu_access_pointer(found->pub.beacon_ies); 738 old = rcu_access_pointer(found->pub.beacon_ies);
717 ies = rcu_access_pointer(found->pub.ies);
718 739
719 rcu_assign_pointer(found->pub.beacon_ies, 740 rcu_assign_pointer(found->pub.beacon_ies,
720 tmp->pub.beacon_ies); 741 tmp->pub.beacon_ies);
721 742
722 /* Override IEs if they were from a beacon before */ 743 /* Override IEs if they were from a beacon before */
723 if (old == ies) 744 if (old == rcu_access_pointer(found->pub.ies))
724 rcu_assign_pointer(found->pub.ies, 745 rcu_assign_pointer(found->pub.ies,
725 tmp->pub.beacon_ies); 746 tmp->pub.beacon_ies);
726 747
748 /* Assign beacon IEs to all sub entries */
749 list_for_each_entry(bss, &found->hidden_list,
750 hidden_list) {
751 const struct cfg80211_bss_ies *ies;
752
753 ies = rcu_access_pointer(bss->pub.beacon_ies);
754 WARN_ON(ies != old);
755
756 rcu_assign_pointer(bss->pub.beacon_ies,
757 tmp->pub.beacon_ies);
758 }
759
727 if (old) 760 if (old)
728 kfree_rcu((struct cfg80211_bss_ies *)old, 761 kfree_rcu((struct cfg80211_bss_ies *)old,
729 rcu_head); 762 rcu_head);
@@ -733,19 +766,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
733 struct cfg80211_internal_bss *hidden; 766 struct cfg80211_internal_bss *hidden;
734 struct cfg80211_bss_ies *ies; 767 struct cfg80211_bss_ies *ies;
735 768
736 /* First check if the beacon is a probe response from
737 * a hidden bss. If so, copy beacon ies (with nullified
738 * ssid) into the probe response bss entry (with real ssid).
739 * It is required basically for PSM implementation
740 * (probe responses do not contain tim ie) */
741
742 /* TODO: The code is not trying to update existing probe
743 * response bss entries when beacon ies are
744 * getting changed. */
745 hidden = rb_find_hidden_bss(dev, tmp);
746 if (hidden)
747 copy_hidden_ies(tmp, hidden);
748
749 /* 769 /*
750 * create a copy -- the "res" variable that is passed in 770 * create a copy -- the "res" variable that is passed in
751 * is allocated on the stack since it's not needed in the 771 * is allocated on the stack since it's not needed in the
@@ -760,21 +780,51 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
760 ies = (void *)rcu_dereference(tmp->pub.proberesp_ies); 780 ies = (void *)rcu_dereference(tmp->pub.proberesp_ies);
761 if (ies) 781 if (ies)
762 kfree_rcu(ies, rcu_head); 782 kfree_rcu(ies, rcu_head);
763 spin_unlock_bh(&dev->bss_lock); 783 goto drop;
764 return NULL;
765 } 784 }
766 memcpy(new, tmp, sizeof(*new)); 785 memcpy(new, tmp, sizeof(*new));
767 kref_init(&new->ref); 786 new->refcount = 1;
787 INIT_LIST_HEAD(&new->hidden_list);
788
789 if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
790 hidden = rb_find_bss(dev, tmp, BSS_CMP_HIDE_ZLEN);
791 if (!hidden)
792 hidden = rb_find_bss(dev, tmp,
793 BSS_CMP_HIDE_NUL);
794 if (hidden) {
795 new->pub.hidden_beacon_bss = &hidden->pub;
796 list_add(&new->hidden_list,
797 &hidden->hidden_list);
798 hidden->refcount++;
799 rcu_assign_pointer(new->pub.beacon_ies,
800 hidden->pub.beacon_ies);
801 }
802 } else {
803 /*
804 * Ok so we found a beacon, and don't have an entry. If
805 * it's a beacon with hidden SSID, we might be in for an
806 * expensive search for any probe responses that should
807 * be grouped with this beacon for updates ...
808 */
809 if (!cfg80211_combine_bsses(dev, new)) {
810 kfree(new);
811 goto drop;
812 }
813 }
814
768 list_add_tail(&new->list, &dev->bss_list); 815 list_add_tail(&new->list, &dev->bss_list);
769 rb_insert_bss(dev, new); 816 rb_insert_bss(dev, new);
770 found = new; 817 found = new;
771 } 818 }
772 819
773 dev->bss_generation++; 820 dev->bss_generation++;
821 bss_ref_get(dev, found);
774 spin_unlock_bh(&dev->bss_lock); 822 spin_unlock_bh(&dev->bss_lock);
775 823
776 kref_get(&found->ref);
777 return found; 824 return found;
825 drop:
826 spin_unlock_bh(&dev->bss_lock);
827 return NULL;
778} 828}
779 829
780static struct ieee80211_channel * 830static struct ieee80211_channel *
@@ -833,7 +883,6 @@ cfg80211_inform_bss(struct wiphy *wiphy,
833 memcpy(tmp.pub.bssid, bssid, ETH_ALEN); 883 memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
834 tmp.pub.channel = channel; 884 tmp.pub.channel = channel;
835 tmp.pub.signal = signal; 885 tmp.pub.signal = signal;
836 tmp.pub.tsf = tsf;
837 tmp.pub.beacon_interval = beacon_interval; 886 tmp.pub.beacon_interval = beacon_interval;
838 tmp.pub.capability = capability; 887 tmp.pub.capability = capability;
839 /* 888 /*
@@ -841,16 +890,14 @@ cfg80211_inform_bss(struct wiphy *wiphy,
841 * Response frame, we need to pick one of the options and only use it 890 * Response frame, we need to pick one of the options and only use it
842 * with the driver that does not provide the full Beacon/Probe Response 891 * with the driver that does not provide the full Beacon/Probe Response
843 * frame. Use Beacon frame pointer to avoid indicating that this should 892 * frame. Use Beacon frame pointer to avoid indicating that this should
844 * override the iies pointer should we have received an earlier 893 * override the IEs pointer should we have received an earlier
845 * indication of Probe Response data. 894 * indication of Probe Response data.
846 *
847 * The initial buffer for the IEs is allocated with the BSS entry and
848 * is located after the private area.
849 */ 895 */
850 ies = kmalloc(sizeof(*ies) + ielen, gfp); 896 ies = kmalloc(sizeof(*ies) + ielen, gfp);
851 if (!ies) 897 if (!ies)
852 return NULL; 898 return NULL;
853 ies->len = ielen; 899 ies->len = ielen;
900 ies->tsf = tsf;
854 memcpy(ies->data, ie, ielen); 901 memcpy(ies->data, ie, ielen);
855 902
856 rcu_assign_pointer(tmp.pub.beacon_ies, ies); 903 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
@@ -907,6 +954,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
907 if (!ies) 954 if (!ies)
908 return NULL; 955 return NULL;
909 ies->len = ielen; 956 ies->len = ielen;
957 ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
910 memcpy(ies->data, mgmt->u.probe_resp.variable, ielen); 958 memcpy(ies->data, mgmt->u.probe_resp.variable, ielen);
911 959
912 if (ieee80211_is_probe_resp(mgmt->frame_control)) 960 if (ieee80211_is_probe_resp(mgmt->frame_control))
@@ -918,7 +966,6 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
918 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN); 966 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN);
919 tmp.pub.channel = channel; 967 tmp.pub.channel = channel;
920 tmp.pub.signal = signal; 968 tmp.pub.signal = signal;
921 tmp.pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
922 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); 969 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
923 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); 970 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
924 971
@@ -935,27 +982,35 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
935} 982}
936EXPORT_SYMBOL(cfg80211_inform_bss_frame); 983EXPORT_SYMBOL(cfg80211_inform_bss_frame);
937 984
938void cfg80211_ref_bss(struct cfg80211_bss *pub) 985void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
939{ 986{
987 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
940 struct cfg80211_internal_bss *bss; 988 struct cfg80211_internal_bss *bss;
941 989
942 if (!pub) 990 if (!pub)
943 return; 991 return;
944 992
945 bss = container_of(pub, struct cfg80211_internal_bss, pub); 993 bss = container_of(pub, struct cfg80211_internal_bss, pub);
946 kref_get(&bss->ref); 994
995 spin_lock_bh(&dev->bss_lock);
996 bss_ref_get(dev, bss);
997 spin_unlock_bh(&dev->bss_lock);
947} 998}
948EXPORT_SYMBOL(cfg80211_ref_bss); 999EXPORT_SYMBOL(cfg80211_ref_bss);
949 1000
950void cfg80211_put_bss(struct cfg80211_bss *pub) 1001void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
951{ 1002{
1003 struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
952 struct cfg80211_internal_bss *bss; 1004 struct cfg80211_internal_bss *bss;
953 1005
954 if (!pub) 1006 if (!pub)
955 return; 1007 return;
956 1008
957 bss = container_of(pub, struct cfg80211_internal_bss, pub); 1009 bss = container_of(pub, struct cfg80211_internal_bss, pub);
958 kref_put(&bss->ref, bss_release); 1010
1011 spin_lock_bh(&dev->bss_lock);
1012 bss_ref_put(dev, bss);
1013 spin_unlock_bh(&dev->bss_lock);
959} 1014}
960EXPORT_SYMBOL(cfg80211_put_bss); 1015EXPORT_SYMBOL(cfg80211_put_bss);
961 1016
@@ -971,8 +1026,8 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
971 1026
972 spin_lock_bh(&dev->bss_lock); 1027 spin_lock_bh(&dev->bss_lock);
973 if (!list_empty(&bss->list)) { 1028 if (!list_empty(&bss->list)) {
974 __cfg80211_unlink_bss(dev, bss); 1029 if (__cfg80211_unlink_bss(dev, bss))
975 dev->bss_generation++; 1030 dev->bss_generation++;
976 } 1031 }
977 spin_unlock_bh(&dev->bss_lock); 1032 spin_unlock_bh(&dev->bss_lock);
978} 1033}
@@ -1155,16 +1210,6 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info,
1155 } 1210 }
1156} 1211}
1157 1212
1158static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
1159{
1160 unsigned long end = jiffies;
1161
1162 if (end >= start)
1163 return jiffies_to_msecs(end - start);
1164
1165 return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
1166}
1167
1168static char * 1213static char *
1169ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, 1214ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1170 struct cfg80211_internal_bss *bss, char *current_ev, 1215 struct cfg80211_internal_bss *bss, char *current_ev,
@@ -1241,15 +1286,10 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1241 1286
1242 rcu_read_lock(); 1287 rcu_read_lock();
1243 ies = rcu_dereference(bss->pub.ies); 1288 ies = rcu_dereference(bss->pub.ies);
1244 if (ies) { 1289 rem = ies->len;
1245 rem = ies->len; 1290 ie = ies->data;
1246 ie = ies->data;
1247 } else {
1248 rem = 0;
1249 ie = NULL;
1250 }
1251 1291
1252 while (ies && rem >= 2) { 1292 while (rem >= 2) {
1253 /* invalid data */ 1293 /* invalid data */
1254 if (ie[1] > rem - 2) 1294 if (ie[1] > rem - 2)
1255 break; 1295 break;
@@ -1362,7 +1402,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1362 if (buf) { 1402 if (buf) {
1363 memset(&iwe, 0, sizeof(iwe)); 1403 memset(&iwe, 0, sizeof(iwe));
1364 iwe.cmd = IWEVCUSTOM; 1404 iwe.cmd = IWEVCUSTOM;
1365 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->pub.tsf)); 1405 sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf));
1366 iwe.u.data.length = strlen(buf); 1406 iwe.u.data.length = strlen(buf);
1367 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1407 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1368 &iwe, buf); 1408 &iwe, buf);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index a825dfe12cf7..f432bd3755b1 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -301,7 +301,7 @@ static void __cfg80211_sme_scan_done(struct net_device *dev)
301 301
302 bss = cfg80211_get_conn_bss(wdev); 302 bss = cfg80211_get_conn_bss(wdev);
303 if (bss) { 303 if (bss) {
304 cfg80211_put_bss(bss); 304 cfg80211_put_bss(&rdev->wiphy, bss);
305 } else { 305 } else {
306 /* not found */ 306 /* not found */
307 if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) 307 if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)
@@ -464,7 +464,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
464 464
465 if (wdev->current_bss) { 465 if (wdev->current_bss) {
466 cfg80211_unhold_bss(wdev->current_bss); 466 cfg80211_unhold_bss(wdev->current_bss);
467 cfg80211_put_bss(&wdev->current_bss->pub); 467 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
468 wdev->current_bss = NULL; 468 wdev->current_bss = NULL;
469 } 469 }
470 470
@@ -480,7 +480,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
480 kfree(wdev->connect_keys); 480 kfree(wdev->connect_keys);
481 wdev->connect_keys = NULL; 481 wdev->connect_keys = NULL;
482 wdev->ssid_len = 0; 482 wdev->ssid_len = 0;
483 cfg80211_put_bss(bss); 483 cfg80211_put_bss(wdev->wiphy, bss);
484 return; 484 return;
485 } 485 }
486 486
@@ -586,7 +586,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev,
586 } 586 }
587 587
588 cfg80211_unhold_bss(wdev->current_bss); 588 cfg80211_unhold_bss(wdev->current_bss);
589 cfg80211_put_bss(&wdev->current_bss->pub); 589 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
590 wdev->current_bss = NULL; 590 wdev->current_bss = NULL;
591 591
592 cfg80211_hold_bss(bss_from_pub(bss)); 592 cfg80211_hold_bss(bss_from_pub(bss));
@@ -621,7 +621,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev,
621 621
622 return; 622 return;
623out: 623out:
624 cfg80211_put_bss(bss); 624 cfg80211_put_bss(wdev->wiphy, bss);
625} 625}
626 626
627void cfg80211_roamed(struct net_device *dev, 627void cfg80211_roamed(struct net_device *dev,
@@ -663,7 +663,7 @@ void cfg80211_roamed_bss(struct net_device *dev,
663 663
664 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp); 664 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
665 if (!ev) { 665 if (!ev) {
666 cfg80211_put_bss(bss); 666 cfg80211_put_bss(wdev->wiphy, bss);
667 return; 667 return;
668 } 668 }
669 669
@@ -704,7 +704,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
704 704
705 if (wdev->current_bss) { 705 if (wdev->current_bss) {
706 cfg80211_unhold_bss(wdev->current_bss); 706 cfg80211_unhold_bss(wdev->current_bss);
707 cfg80211_put_bss(&wdev->current_bss->pub); 707 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
708 } 708 }
709 709
710 wdev->current_bss = NULL; 710 wdev->current_bss = NULL;
@@ -875,7 +875,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
875 if (bss) { 875 if (bss) {
876 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; 876 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
877 err = cfg80211_conn_do_work(wdev); 877 err = cfg80211_conn_do_work(wdev);
878 cfg80211_put_bss(bss); 878 cfg80211_put_bss(wdev->wiphy, bss);
879 } else { 879 } else {
880 /* otherwise we'll need to scan for the AP first */ 880 /* otherwise we'll need to scan for the AP first */
881 err = cfg80211_conn_scan(wdev); 881 err = cfg80211_conn_scan(wdev);
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 1f6f01e2dc4c..238ee49b3868 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -106,9 +106,7 @@ static int wiphy_resume(struct device *dev)
106 int ret = 0; 106 int ret = 0;
107 107
108 /* Age scan results with time spent in suspend */ 108 /* Age scan results with time spent in suspend */
109 spin_lock_bh(&rdev->bss_lock);
110 cfg80211_bss_age(rdev, get_seconds() - rdev->suspend_at); 109 cfg80211_bss_age(rdev, get_seconds() - rdev->suspend_at);
111 spin_unlock_bh(&rdev->bss_lock);
112 110
113 if (rdev->ops->resume) { 111 if (rdev->ops->resume) {
114 rtnl_lock(); 112 rtnl_lock();
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 8bc553199686..b7a531380e19 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2051,6 +2051,21 @@ TRACE_EVENT(cfg80211_reg_can_beacon,
2051 WIPHY_PR_ARG, CHAN_DEF_PR_ARG) 2051 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
2052); 2052);
2053 2053
2054TRACE_EVENT(cfg80211_chandef_dfs_required,
2055 TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
2056 TP_ARGS(wiphy, chandef),
2057 TP_STRUCT__entry(
2058 WIPHY_ENTRY
2059 CHAN_DEF_ENTRY
2060 ),
2061 TP_fast_assign(
2062 WIPHY_ASSIGN;
2063 CHAN_DEF_ASSIGN(chandef);
2064 ),
2065 TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
2066 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
2067);
2068
2054TRACE_EVENT(cfg80211_ch_switch_notify, 2069TRACE_EVENT(cfg80211_ch_switch_notify,
2055 TP_PROTO(struct net_device *netdev, 2070 TP_PROTO(struct net_device *netdev,
2056 struct cfg80211_chan_def *chandef), 2071 struct cfg80211_chan_def *chandef),
@@ -2067,6 +2082,36 @@ TRACE_EVENT(cfg80211_ch_switch_notify,
2067 NETDEV_PR_ARG, CHAN_DEF_PR_ARG) 2082 NETDEV_PR_ARG, CHAN_DEF_PR_ARG)
2068); 2083);
2069 2084
2085TRACE_EVENT(cfg80211_radar_event,
2086 TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
2087 TP_ARGS(wiphy, chandef),
2088 TP_STRUCT__entry(
2089 WIPHY_ENTRY
2090 CHAN_DEF_ENTRY
2091 ),
2092 TP_fast_assign(
2093 WIPHY_ASSIGN;
2094 CHAN_DEF_ASSIGN(chandef);
2095 ),
2096 TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
2097 WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
2098);
2099
2100TRACE_EVENT(cfg80211_cac_event,
2101 TP_PROTO(struct net_device *netdev, enum nl80211_radar_event evt),
2102 TP_ARGS(netdev, evt),
2103 TP_STRUCT__entry(
2104 NETDEV_ENTRY
2105 __field(enum nl80211_radar_event, evt)
2106 ),
2107 TP_fast_assign(
2108 NETDEV_ASSIGN;
2109 __entry->evt = evt;
2110 ),
2111 TP_printk(NETDEV_PR_FMT ", event: %d",
2112 NETDEV_PR_ARG, __entry->evt)
2113);
2114
2070DECLARE_EVENT_CLASS(cfg80211_rx_evt, 2115DECLARE_EVENT_CLASS(cfg80211_rx_evt,
2071 TP_PROTO(struct net_device *netdev, const u8 *addr), 2116 TP_PROTO(struct net_device *netdev, const u8 *addr),
2072 TP_ARGS(netdev, addr), 2117 TP_ARGS(netdev, addr),
@@ -2333,6 +2378,41 @@ TRACE_EVENT(cfg80211_return_u32,
2333 TP_printk("ret: %u", __entry->ret) 2378 TP_printk("ret: %u", __entry->ret)
2334); 2379);
2335 2380
2381TRACE_EVENT(cfg80211_report_wowlan_wakeup,
2382 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
2383 struct cfg80211_wowlan_wakeup *wakeup),
2384 TP_ARGS(wiphy, wdev, wakeup),
2385 TP_STRUCT__entry(
2386 WIPHY_ENTRY
2387 WDEV_ENTRY
2388 __field(bool, disconnect)
2389 __field(bool, magic_pkt)
2390 __field(bool, gtk_rekey_failure)
2391 __field(bool, eap_identity_req)
2392 __field(bool, four_way_handshake)
2393 __field(bool, rfkill_release)
2394 __field(s32, pattern_idx)
2395 __field(u32, packet_len)
2396 __dynamic_array(u8, packet, wakeup->packet_present_len)
2397 ),
2398 TP_fast_assign(
2399 WIPHY_ASSIGN;
2400 WDEV_ASSIGN;
2401 __entry->disconnect = wakeup->disconnect;
2402 __entry->magic_pkt = wakeup->magic_pkt;
2403 __entry->gtk_rekey_failure = wakeup->gtk_rekey_failure;
2404 __entry->eap_identity_req = wakeup->eap_identity_req;
2405 __entry->four_way_handshake = wakeup->four_way_handshake;
2406 __entry->rfkill_release = wakeup->rfkill_release;
2407 __entry->pattern_idx = wakeup->pattern_idx;
2408 __entry->packet_len = wakeup->packet_len;
2409 if (wakeup->packet && wakeup->packet_present_len)
2410 memcpy(__get_dynamic_array(packet), wakeup->packet,
2411 wakeup->packet_present_len);
2412 ),
2413 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG)
2414);
2415
2336#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ 2416#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
2337 2417
2338#undef TRACE_INCLUDE_PATH 2418#undef TRACE_INCLUDE_PATH
diff --git a/net/wireless/util.c b/net/wireless/util.c
index d7873c7ae0ec..37a56ee1e1ed 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1217,10 +1217,10 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1217 break; 1217 break;
1218 case NL80211_IFTYPE_P2P_CLIENT: 1218 case NL80211_IFTYPE_P2P_CLIENT:
1219 case NL80211_IFTYPE_STATION: 1219 case NL80211_IFTYPE_STATION:
1220 case NL80211_IFTYPE_P2P_DEVICE:
1220 case NL80211_IFTYPE_MONITOR: 1221 case NL80211_IFTYPE_MONITOR:
1221 radar_required = false; 1222 radar_required = false;
1222 break; 1223 break;
1223 case NL80211_IFTYPE_P2P_DEVICE:
1224 case NUM_NL80211_IFTYPES: 1224 case NUM_NL80211_IFTYPES:
1225 case NL80211_IFTYPE_UNSPECIFIED: 1225 case NL80211_IFTYPE_UNSPECIFIED:
1226 default: 1226 default: