aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-07-12 15:21:05 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-07-12 15:21:05 -0400
commitd07d152892aadd8dc3209ecef6788dfc83475676 (patch)
tree0f140aa244ddc2c52494155342298cef64fc8456 /net/mac80211
parent2f8684ce7a47c91da7e0ccba2686277c103d02b6 (diff)
parent685fb72b63faf09a767cc28332545f5830b91be8 (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Conflicts: drivers/net/wireless/iwmc3200wifi/cfg80211.c drivers/net/wireless/mwifiex/cfg80211.c
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/agg-tx.c3
-rw-r--r--net/mac80211/cfg.c48
-rw-r--r--net/mac80211/debugfs.c2
-rw-r--r--net/mac80211/ieee80211_i.h20
-rw-r--r--net/mac80211/iface.c44
-rw-r--r--net/mac80211/key.c20
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mlme.c45
-rw-r--r--net/mac80211/offchannel.c6
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c8
-rw-r--r--net/mac80211/rx.c49
-rw-r--r--net/mac80211/scan.c116
-rw-r--r--net/mac80211/status.c9
-rw-r--r--net/mac80211/trace.h6
-rw-r--r--net/mac80211/tx.c25
-rw-r--r--net/mac80211/util.c11
16 files changed, 209 insertions, 206 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 5cc1bf7d8033..d0deb3edae21 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -135,7 +135,8 @@ void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
135 bar->control = cpu_to_le16(bar_control); 135 bar->control = cpu_to_le16(bar_control);
136 bar->start_seq_num = cpu_to_le16(ssn); 136 bar->start_seq_num = cpu_to_le16(ssn);
137 137
138 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 138 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
139 IEEE80211_TX_CTL_REQ_TX_STATUS;
139 ieee80211_tx_skb_tid(sdata, skb, tid); 140 ieee80211_tx_skb_tid(sdata, skb, tid);
140} 141}
141EXPORT_SYMBOL(ieee80211_send_bar); 142EXPORT_SYMBOL(ieee80211_send_bar);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ccbe2413142a..cfdc03f59e27 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -20,31 +20,31 @@
20#include "rate.h" 20#include "rate.h"
21#include "mesh.h" 21#include "mesh.h"
22 22
23static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name, 23static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, char *name,
24 enum nl80211_iftype type, 24 enum nl80211_iftype type,
25 u32 *flags, 25 u32 *flags,
26 struct vif_params *params) 26 struct vif_params *params)
27{ 27{
28 struct ieee80211_local *local = wiphy_priv(wiphy); 28 struct ieee80211_local *local = wiphy_priv(wiphy);
29 struct net_device *dev; 29 struct wireless_dev *wdev;
30 struct ieee80211_sub_if_data *sdata; 30 struct ieee80211_sub_if_data *sdata;
31 int err; 31 int err;
32 32
33 err = ieee80211_if_add(local, name, &dev, type, params); 33 err = ieee80211_if_add(local, name, &wdev, type, params);
34 if (err) 34 if (err)
35 return ERR_PTR(err); 35 return ERR_PTR(err);
36 36
37 if (type == NL80211_IFTYPE_MONITOR && flags) { 37 if (type == NL80211_IFTYPE_MONITOR && flags) {
38 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 38 sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
39 sdata->u.mntr_flags = *flags; 39 sdata->u.mntr_flags = *flags;
40 } 40 }
41 41
42 return dev; 42 return wdev;
43} 43}
44 44
45static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev) 45static int ieee80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
46{ 46{
47 ieee80211_if_remove(IEEE80211_DEV_TO_SUB_IF(dev)); 47 ieee80211_if_remove(IEEE80211_WDEV_TO_SUB_IF(wdev));
48 48
49 return 0; 49 return 0;
50} 50}
@@ -1741,6 +1741,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1741 return -EINVAL; 1741 return -EINVAL;
1742 } 1742 }
1743 1743
1744 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
1745
1744 return 0; 1746 return 0;
1745} 1747}
1746 1748
@@ -1761,10 +1763,11 @@ static int ieee80211_resume(struct wiphy *wiphy)
1761#endif 1763#endif
1762 1764
1763static int ieee80211_scan(struct wiphy *wiphy, 1765static int ieee80211_scan(struct wiphy *wiphy,
1764 struct net_device *dev,
1765 struct cfg80211_scan_request *req) 1766 struct cfg80211_scan_request *req)
1766{ 1767{
1767 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1768 struct ieee80211_sub_if_data *sdata;
1769
1770 sdata = IEEE80211_WDEV_TO_SUB_IF(req->wdev);
1768 1771
1769 switch (ieee80211_vif_type_p2p(&sdata->vif)) { 1772 switch (ieee80211_vif_type_p2p(&sdata->vif)) {
1770 case NL80211_IFTYPE_STATION: 1773 case NL80211_IFTYPE_STATION:
@@ -2297,13 +2300,13 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2297} 2300}
2298 2301
2299static int ieee80211_remain_on_channel(struct wiphy *wiphy, 2302static int ieee80211_remain_on_channel(struct wiphy *wiphy,
2300 struct net_device *dev, 2303 struct wireless_dev *wdev,
2301 struct ieee80211_channel *chan, 2304 struct ieee80211_channel *chan,
2302 enum nl80211_channel_type channel_type, 2305 enum nl80211_channel_type channel_type,
2303 unsigned int duration, 2306 unsigned int duration,
2304 u64 *cookie) 2307 u64 *cookie)
2305{ 2308{
2306 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2309 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2307 struct ieee80211_local *local = sdata->local; 2310 struct ieee80211_local *local = sdata->local;
2308 int ret; 2311 int ret;
2309 2312
@@ -2390,23 +2393,23 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
2390} 2393}
2391 2394
2392static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, 2395static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
2393 struct net_device *dev, 2396 struct wireless_dev *wdev,
2394 u64 cookie) 2397 u64 cookie)
2395{ 2398{
2396 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2399 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2397 struct ieee80211_local *local = sdata->local; 2400 struct ieee80211_local *local = sdata->local;
2398 2401
2399 return ieee80211_cancel_roc(local, cookie, false); 2402 return ieee80211_cancel_roc(local, cookie, false);
2400} 2403}
2401 2404
2402static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, 2405static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2403 struct ieee80211_channel *chan, bool offchan, 2406 struct ieee80211_channel *chan, bool offchan,
2404 enum nl80211_channel_type channel_type, 2407 enum nl80211_channel_type channel_type,
2405 bool channel_type_valid, unsigned int wait, 2408 bool channel_type_valid, unsigned int wait,
2406 const u8 *buf, size_t len, bool no_cck, 2409 const u8 *buf, size_t len, bool no_cck,
2407 bool dont_wait_for_ack, u64 *cookie) 2410 bool dont_wait_for_ack, u64 *cookie)
2408{ 2411{
2409 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2412 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2410 struct ieee80211_local *local = sdata->local; 2413 struct ieee80211_local *local = sdata->local;
2411 struct sk_buff *skb; 2414 struct sk_buff *skb;
2412 struct sta_info *sta; 2415 struct sta_info *sta;
@@ -2511,21 +2514,20 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
2511} 2514}
2512 2515
2513static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, 2516static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
2514 struct net_device *dev, 2517 struct wireless_dev *wdev,
2515 u64 cookie) 2518 u64 cookie)
2516{ 2519{
2517 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2520 struct ieee80211_local *local = wiphy_priv(wiphy);
2518 struct ieee80211_local *local = sdata->local;
2519 2521
2520 return ieee80211_cancel_roc(local, cookie, true); 2522 return ieee80211_cancel_roc(local, cookie, true);
2521} 2523}
2522 2524
2523static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, 2525static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
2524 struct net_device *dev, 2526 struct wireless_dev *wdev,
2525 u16 frame_type, bool reg) 2527 u16 frame_type, bool reg)
2526{ 2528{
2527 struct ieee80211_local *local = wiphy_priv(wiphy); 2529 struct ieee80211_local *local = wiphy_priv(wiphy);
2528 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2530 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2529 2531
2530 switch (frame_type) { 2532 switch (frame_type) {
2531 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH: 2533 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH:
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 778e5916d7c3..b8dfb440c8ef 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -325,8 +325,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
325 local->rx_handlers_drop_defrag); 325 local->rx_handlers_drop_defrag);
326 DEBUGFS_STATS_ADD(rx_handlers_drop_short, 326 DEBUGFS_STATS_ADD(rx_handlers_drop_short,
327 local->rx_handlers_drop_short); 327 local->rx_handlers_drop_short);
328 DEBUGFS_STATS_ADD(rx_handlers_drop_passive_scan,
329 local->rx_handlers_drop_passive_scan);
330 DEBUGFS_STATS_ADD(tx_expand_skb_head, 328 DEBUGFS_STATS_ADD(tx_expand_skb_head,
331 local->tx_expand_skb_head); 329 local->tx_expand_skb_head);
332 DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned, 330 DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e0423f8c0ce1..7998513ec831 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -85,6 +85,8 @@ struct ieee80211_bss {
85 size_t ssid_len; 85 size_t ssid_len;
86 u8 ssid[IEEE80211_MAX_SSID_LEN]; 86 u8 ssid[IEEE80211_MAX_SSID_LEN];
87 87
88 u32 device_ts;
89
88 u8 dtim_period; 90 u8 dtim_period;
89 91
90 bool wmm_used; 92 bool wmm_used;
@@ -207,7 +209,6 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
207 * enum ieee80211_packet_rx_flags - packet RX flags 209 * enum ieee80211_packet_rx_flags - packet RX flags
208 * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed 210 * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed
209 * (incl. multicast frames) 211 * (incl. multicast frames)
210 * @IEEE80211_RX_IN_SCAN: received while scanning
211 * @IEEE80211_RX_FRAGMENTED: fragmented frame 212 * @IEEE80211_RX_FRAGMENTED: fragmented frame
212 * @IEEE80211_RX_AMSDU: a-MSDU packet 213 * @IEEE80211_RX_AMSDU: a-MSDU packet
213 * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed 214 * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed
@@ -217,7 +218,6 @@ typedef unsigned __bitwise__ ieee80211_rx_result;
217 * @rx_flags field of &struct ieee80211_rx_status. 218 * @rx_flags field of &struct ieee80211_rx_status.
218 */ 219 */
219enum ieee80211_packet_rx_flags { 220enum ieee80211_packet_rx_flags {
220 IEEE80211_RX_IN_SCAN = BIT(0),
221 IEEE80211_RX_RA_MATCH = BIT(1), 221 IEEE80211_RX_RA_MATCH = BIT(1),
222 IEEE80211_RX_FRAGMENTED = BIT(2), 222 IEEE80211_RX_FRAGMENTED = BIT(2),
223 IEEE80211_RX_AMSDU = BIT(3), 223 IEEE80211_RX_AMSDU = BIT(3),
@@ -965,14 +965,14 @@ struct ieee80211_local {
965 int scan_channel_idx; 965 int scan_channel_idx;
966 int scan_ies_len; 966 int scan_ies_len;
967 967
968 bool sched_scanning;
969 struct ieee80211_sched_scan_ies sched_scan_ies; 968 struct ieee80211_sched_scan_ies sched_scan_ies;
970 struct work_struct sched_scan_stopped_work; 969 struct work_struct sched_scan_stopped_work;
970 struct ieee80211_sub_if_data __rcu *sched_scan_sdata;
971 971
972 unsigned long leave_oper_channel_time; 972 unsigned long leave_oper_channel_time;
973 enum mac80211_scan_state next_scan_state; 973 enum mac80211_scan_state next_scan_state;
974 struct delayed_work scan_work; 974 struct delayed_work scan_work;
975 struct ieee80211_sub_if_data *scan_sdata; 975 struct ieee80211_sub_if_data __rcu *scan_sdata;
976 enum nl80211_channel_type _oper_channel_type; 976 enum nl80211_channel_type _oper_channel_type;
977 struct ieee80211_channel *oper_channel, *csa_channel; 977 struct ieee80211_channel *oper_channel, *csa_channel;
978 978
@@ -1014,7 +1014,6 @@ struct ieee80211_local {
1014 unsigned int rx_handlers_drop_nullfunc; 1014 unsigned int rx_handlers_drop_nullfunc;
1015 unsigned int rx_handlers_drop_defrag; 1015 unsigned int rx_handlers_drop_defrag;
1016 unsigned int rx_handlers_drop_short; 1016 unsigned int rx_handlers_drop_short;
1017 unsigned int rx_handlers_drop_passive_scan;
1018 unsigned int tx_expand_skb_head; 1017 unsigned int tx_expand_skb_head;
1019 unsigned int tx_expand_skb_head_cloned; 1018 unsigned int tx_expand_skb_head_cloned;
1020 unsigned int rx_expand_skb_head; 1019 unsigned int rx_expand_skb_head;
@@ -1091,6 +1090,12 @@ IEEE80211_DEV_TO_SUB_IF(struct net_device *dev)
1091 return netdev_priv(dev); 1090 return netdev_priv(dev);
1092} 1091}
1093 1092
1093static inline struct ieee80211_sub_if_data *
1094IEEE80211_WDEV_TO_SUB_IF(struct wireless_dev *wdev)
1095{
1096 return container_of(wdev, struct ieee80211_sub_if_data, wdev);
1097}
1098
1094/* this struct represents 802.11n's RA/TID combination */ 1099/* this struct represents 802.11n's RA/TID combination */
1095struct ieee80211_ra_tid { 1100struct ieee80211_ra_tid {
1096 u8 ra[ETH_ALEN]; 1101 u8 ra[ETH_ALEN];
@@ -1241,8 +1246,7 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
1241 struct cfg80211_scan_request *req); 1246 struct cfg80211_scan_request *req);
1242void ieee80211_scan_cancel(struct ieee80211_local *local); 1247void ieee80211_scan_cancel(struct ieee80211_local *local);
1243void ieee80211_run_deferred_scan(struct ieee80211_local *local); 1248void ieee80211_run_deferred_scan(struct ieee80211_local *local);
1244ieee80211_rx_result 1249void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb);
1245ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
1246 1250
1247void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); 1251void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
1248struct ieee80211_bss * 1252struct ieee80211_bss *
@@ -1278,7 +1282,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc);
1278int ieee80211_iface_init(void); 1282int ieee80211_iface_init(void);
1279void ieee80211_iface_exit(void); 1283void ieee80211_iface_exit(void);
1280int ieee80211_if_add(struct ieee80211_local *local, const char *name, 1284int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1281 struct net_device **new_dev, enum nl80211_iftype type, 1285 struct wireless_dev **new_wdev, enum nl80211_iftype type,
1282 struct vif_params *params); 1286 struct vif_params *params);
1283int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, 1287int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
1284 enum nl80211_iftype type); 1288 enum nl80211_iftype type);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index fbef7a1ada7a..334ee0fb18ca 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -112,10 +112,11 @@ static u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
112 } 112 }
113 } 113 }
114 114
115 if (local->scan_sdata && 115 sdata = rcu_dereference_protected(local->scan_sdata,
116 !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { 116 lockdep_is_held(&local->mtx));
117 if (sdata && !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) {
117 scanning = true; 118 scanning = true;
118 local->scan_sdata->vif.bss_conf.idle = false; 119 sdata->vif.bss_conf.idle = false;
119 } 120 }
120 121
121 list_for_each_entry(sdata, &local->interfaces, list) { 122 list_for_each_entry(sdata, &local->interfaces, list) {
@@ -333,17 +334,21 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata)
333int ieee80211_add_virtual_monitor(struct ieee80211_local *local) 334int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
334{ 335{
335 struct ieee80211_sub_if_data *sdata; 336 struct ieee80211_sub_if_data *sdata;
336 int ret; 337 int ret = 0;
337 338
338 if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) 339 if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))
339 return 0; 340 return 0;
340 341
342 mutex_lock(&local->iflist_mtx);
343
341 if (local->monitor_sdata) 344 if (local->monitor_sdata)
342 return 0; 345 goto out_unlock;
343 346
344 sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); 347 sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL);
345 if (!sdata) 348 if (!sdata) {
346 return -ENOMEM; 349 ret = -ENOMEM;
350 goto out_unlock;
351 }
347 352
348 /* set up data */ 353 /* set up data */
349 sdata->local = local; 354 sdata->local = local;
@@ -357,18 +362,19 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
357 if (WARN_ON(ret)) { 362 if (WARN_ON(ret)) {
358 /* ok .. stupid driver, it asked for this! */ 363 /* ok .. stupid driver, it asked for this! */
359 kfree(sdata); 364 kfree(sdata);
360 return ret; 365 goto out_unlock;
361 } 366 }
362 367
363 ret = ieee80211_check_queues(sdata); 368 ret = ieee80211_check_queues(sdata);
364 if (ret) { 369 if (ret) {
365 kfree(sdata); 370 kfree(sdata);
366 return ret; 371 goto out_unlock;
367 } 372 }
368 373
369 rcu_assign_pointer(local->monitor_sdata, sdata); 374 rcu_assign_pointer(local->monitor_sdata, sdata);
370 375 out_unlock:
371 return 0; 376 mutex_unlock(&local->iflist_mtx);
377 return ret;
372} 378}
373 379
374void ieee80211_del_virtual_monitor(struct ieee80211_local *local) 380void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
@@ -378,10 +384,12 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
378 if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) 384 if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))
379 return; 385 return;
380 386
381 sdata = rtnl_dereference(local->monitor_sdata); 387 mutex_lock(&local->iflist_mtx);
382 388
389 sdata = rcu_dereference_protected(local->monitor_sdata,
390 lockdep_is_held(&local->iflist_mtx));
383 if (!sdata) 391 if (!sdata)
384 return; 392 goto out_unlock;
385 393
386 rcu_assign_pointer(local->monitor_sdata, NULL); 394 rcu_assign_pointer(local->monitor_sdata, NULL);
387 synchronize_net(); 395 synchronize_net();
@@ -389,6 +397,8 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
389 drv_remove_interface(local, sdata); 397 drv_remove_interface(local, sdata);
390 398
391 kfree(sdata); 399 kfree(sdata);
400 out_unlock:
401 mutex_unlock(&local->iflist_mtx);
392} 402}
393 403
394/* 404/*
@@ -628,7 +638,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
628 638
629 clear_bit(SDATA_STATE_RUNNING, &sdata->state); 639 clear_bit(SDATA_STATE_RUNNING, &sdata->state);
630 640
631 if (local->scan_sdata == sdata) 641 if (rcu_access_pointer(local->scan_sdata) == sdata)
632 ieee80211_scan_cancel(local); 642 ieee80211_scan_cancel(local);
633 643
634 /* 644 /*
@@ -1373,7 +1383,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
1373} 1383}
1374 1384
1375int ieee80211_if_add(struct ieee80211_local *local, const char *name, 1385int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1376 struct net_device **new_dev, enum nl80211_iftype type, 1386 struct wireless_dev **new_wdev, enum nl80211_iftype type,
1377 struct vif_params *params) 1387 struct vif_params *params)
1378{ 1388{
1379 struct net_device *ndev; 1389 struct net_device *ndev;
@@ -1463,8 +1473,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1463 list_add_tail_rcu(&sdata->list, &local->interfaces); 1473 list_add_tail_rcu(&sdata->list, &local->interfaces);
1464 mutex_unlock(&local->iflist_mtx); 1474 mutex_unlock(&local->iflist_mtx);
1465 1475
1466 if (new_dev) 1476 if (new_wdev)
1467 *new_dev = ndev; 1477 *new_wdev = &sdata->wdev;
1468 1478
1469 return 0; 1479 return 0;
1470 1480
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index b3b7e526e245..7ae678ba5d67 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -194,26 +194,6 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
194 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; 194 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
195} 195}
196 196
197void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
198{
199 struct ieee80211_key *key;
200
201 key = container_of(key_conf, struct ieee80211_key, conf);
202
203 might_sleep();
204 assert_key_lock(key->local);
205
206 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
207
208 /*
209 * Flush TX path to avoid attempts to use this key
210 * after this function returns. Until then, drivers
211 * must be prepared to handle the key.
212 */
213 synchronize_rcu();
214}
215EXPORT_SYMBOL_GPL(ieee80211_key_removed);
216
217static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, 197static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
218 int idx, bool uni, bool multi) 198 int idx, bool uni, bool multi)
219{ 199{
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index c794101f8987..c26e231c733a 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -322,7 +322,8 @@ static void ieee80211_restart_work(struct work_struct *work)
322 322
323 mutex_lock(&local->mtx); 323 mutex_lock(&local->mtx);
324 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) || 324 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
325 local->sched_scanning, 325 rcu_dereference_protected(local->sched_scan_sdata,
326 lockdep_is_held(&local->mtx)),
326 "%s called with hardware scan in progress\n", __func__); 327 "%s called with hardware scan in progress\n", __func__);
327 mutex_unlock(&local->mtx); 328 mutex_unlock(&local->mtx);
328 329
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f49f14f8ba82..de4350fce11e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1108,7 +1108,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data)
1108} 1108}
1109 1109
1110/* MLME */ 1110/* MLME */
1111static void ieee80211_sta_wmm_params(struct ieee80211_local *local, 1111static bool ieee80211_sta_wmm_params(struct ieee80211_local *local,
1112 struct ieee80211_sub_if_data *sdata, 1112 struct ieee80211_sub_if_data *sdata,
1113 u8 *wmm_param, size_t wmm_param_len) 1113 u8 *wmm_param, size_t wmm_param_len)
1114{ 1114{
@@ -1119,23 +1119,23 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
1119 u8 *pos, uapsd_queues = 0; 1119 u8 *pos, uapsd_queues = 0;
1120 1120
1121 if (!local->ops->conf_tx) 1121 if (!local->ops->conf_tx)
1122 return; 1122 return false;
1123 1123
1124 if (local->hw.queues < IEEE80211_NUM_ACS) 1124 if (local->hw.queues < IEEE80211_NUM_ACS)
1125 return; 1125 return false;
1126 1126
1127 if (!wmm_param) 1127 if (!wmm_param)
1128 return; 1128 return false;
1129 1129
1130 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) 1130 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
1131 return; 1131 return false;
1132 1132
1133 if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) 1133 if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
1134 uapsd_queues = ifmgd->uapsd_queues; 1134 uapsd_queues = ifmgd->uapsd_queues;
1135 1135
1136 count = wmm_param[6] & 0x0f; 1136 count = wmm_param[6] & 0x0f;
1137 if (count == ifmgd->wmm_last_param_set) 1137 if (count == ifmgd->wmm_last_param_set)
1138 return; 1138 return false;
1139 ifmgd->wmm_last_param_set = count; 1139 ifmgd->wmm_last_param_set = count;
1140 1140
1141 pos = wmm_param + 8; 1141 pos = wmm_param + 8;
@@ -1202,6 +1202,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
1202 1202
1203 /* enable WMM or activate new settings */ 1203 /* enable WMM or activate new settings */
1204 sdata->vif.bss_conf.qos = true; 1204 sdata->vif.bss_conf.qos = true;
1205 return true;
1205} 1206}
1206 1207
1207static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata) 1208static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
@@ -1268,11 +1269,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1268 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 1269 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
1269 1270
1270 bss_info_changed |= BSS_CHANGED_ASSOC; 1271 bss_info_changed |= BSS_CHANGED_ASSOC;
1271 /* set timing information */
1272 bss_conf->beacon_int = cbss->beacon_interval;
1273 bss_conf->last_tsf = cbss->tsf;
1274
1275 bss_info_changed |= BSS_CHANGED_BEACON_INT;
1276 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 1272 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
1277 bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value); 1273 bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value);
1278 1274
@@ -2435,14 +2431,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2435 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, 2431 directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
2436 ifmgd->aid); 2432 ifmgd->aid);
2437 2433
2438 if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) {
2439 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
2440 true);
2441
2442 ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
2443 elems.wmm_param_len);
2444 }
2445
2446 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { 2434 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
2447 if (directed_tim) { 2435 if (directed_tim) {
2448 if (local->hw.conf.dynamic_ps_timeout > 0) { 2436 if (local->hw.conf.dynamic_ps_timeout > 0) {
@@ -2473,6 +2461,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2473 ifmgd->beacon_crc = ncrc; 2461 ifmgd->beacon_crc = ncrc;
2474 ifmgd->beacon_crc_valid = true; 2462 ifmgd->beacon_crc_valid = true;
2475 2463
2464 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
2465 true);
2466
2467 if (ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
2468 elems.wmm_param_len))
2469 changed |= BSS_CHANGED_QOS;
2470
2476 if (elems.erp_info && elems.erp_info_len >= 1) { 2471 if (elems.erp_info && elems.erp_info_len >= 1) {
2477 erp_valid = true; 2472 erp_valid = true;
2478 erp_value = elems.erp_info[0]; 2473 erp_value = elems.erp_info[0];
@@ -2974,7 +2969,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2974/* scan finished notification */ 2969/* scan finished notification */
2975void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) 2970void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
2976{ 2971{
2977 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 2972 struct ieee80211_sub_if_data *sdata;
2978 2973
2979 /* Restart STA timers */ 2974 /* Restart STA timers */
2980 rcu_read_lock(); 2975 rcu_read_lock();
@@ -3132,9 +3127,15 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3132 3127
3133 memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN); 3128 memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN);
3134 3129
3135 /* tell driver about BSSID and basic rates */ 3130 /* set timing information */
3131 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
3132 sdata->vif.bss_conf.sync_tsf = cbss->tsf;
3133 sdata->vif.bss_conf.sync_device_ts = bss->device_ts;
3134
3135 /* tell driver about BSSID, basic rates and timing */
3136 ieee80211_bss_info_change_notify(sdata, 3136 ieee80211_bss_info_change_notify(sdata,
3137 BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES); 3137 BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES |
3138 BSS_CHANGED_BEACON_INT);
3138 3139
3139 if (assoc) 3140 if (assoc)
3140 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); 3141 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index b0fb6a2b89ad..8c047fc8b325 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -191,7 +191,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
191 roc->frame = NULL; 191 roc->frame = NULL;
192 } 192 }
193 } else { 193 } else {
194 cfg80211_ready_on_channel(roc->sdata->dev, (unsigned long)roc, 194 cfg80211_ready_on_channel(&roc->sdata->wdev, (unsigned long)roc,
195 roc->chan, roc->chan_type, 195 roc->chan, roc->chan_type,
196 roc->req_duration, GFP_KERNEL); 196 roc->req_duration, GFP_KERNEL);
197 } 197 }
@@ -299,7 +299,7 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
299 299
300 /* was never transmitted */ 300 /* was never transmitted */
301 if (roc->frame) { 301 if (roc->frame) {
302 cfg80211_mgmt_tx_status(roc->sdata->dev, 302 cfg80211_mgmt_tx_status(&roc->sdata->wdev,
303 (unsigned long)roc->frame, 303 (unsigned long)roc->frame,
304 roc->frame->data, roc->frame->len, 304 roc->frame->data, roc->frame->len,
305 false, GFP_KERNEL); 305 false, GFP_KERNEL);
@@ -307,7 +307,7 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
307 } 307 }
308 308
309 if (!roc->mgmt_tx_cookie) 309 if (!roc->mgmt_tx_cookie)
310 cfg80211_remain_on_channel_expired(roc->sdata->dev, 310 cfg80211_remain_on_channel_expired(&roc->sdata->wdev,
311 (unsigned long)roc, 311 (unsigned long)roc,
312 roc->chan, roc->chan_type, 312 roc->chan, roc->chan_type,
313 GFP_KERNEL); 313 GFP_KERNEL);
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index f9e51ef8dfa2..fb1d4aa65e8c 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -626,8 +626,12 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
626 626
627#ifdef CONFIG_MAC80211_DEBUGFS 627#ifdef CONFIG_MAC80211_DEBUGFS
628 /* use fixed index if set */ 628 /* use fixed index if set */
629 if (mp->fixed_rate_idx != -1) 629 if (mp->fixed_rate_idx != -1) {
630 sample_idx = mp->fixed_rate_idx; 630 mi->max_tp_rate = mp->fixed_rate_idx;
631 mi->max_tp_rate2 = mp->fixed_rate_idx;
632 mi->max_prob_rate = mp->fixed_rate_idx;
633 sample_idx = -1;
634 }
631#endif 635#endif
632 636
633 if (sample_idx >= 0) { 637 if (sample_idx >= 0) {
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 839cac8fab57..090d417919af 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -413,29 +413,6 @@ static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx)
413 413
414/* rx handlers */ 414/* rx handlers */
415 415
416static ieee80211_rx_result debug_noinline
417ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
418{
419 struct ieee80211_local *local = rx->local;
420 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
421 struct sk_buff *skb = rx->skb;
422
423 if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN) &&
424 !local->sched_scanning))
425 return RX_CONTINUE;
426
427 if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
428 test_bit(SCAN_SW_SCANNING, &local->scanning) ||
429 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
430 local->sched_scanning)
431 return ieee80211_scan_rx(rx->sdata, skb);
432
433 /* scanning finished during invoking of handlers */
434 I802_DEBUG_INC(local->rx_handlers_drop_passive_scan);
435 return RX_DROP_UNUSABLE;
436}
437
438
439static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) 416static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb)
440{ 417{
441 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 418 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -2404,7 +2381,7 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
2404 if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 2381 if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
2405 sig = status->signal; 2382 sig = status->signal;
2406 2383
2407 if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, sig, 2384 if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig,
2408 rx->skb->data, rx->skb->len, 2385 rx->skb->data, rx->skb->len,
2409 GFP_ATOMIC)) { 2386 GFP_ATOMIC)) {
2410 if (rx->sta) 2387 if (rx->sta)
@@ -2695,7 +2672,6 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
2695 goto rxh_next; \ 2672 goto rxh_next; \
2696 } while (0); 2673 } while (0);
2697 2674
2698 CALL_RXH(ieee80211_rx_h_passive_scan)
2699 CALL_RXH(ieee80211_rx_h_check) 2675 CALL_RXH(ieee80211_rx_h_check)
2700 2676
2701 ieee80211_rx_reorder_ampdu(rx); 2677 ieee80211_rx_reorder_ampdu(rx);
@@ -2765,11 +2741,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2765 return 0; 2741 return 0;
2766 if (ieee80211_is_beacon(hdr->frame_control)) { 2742 if (ieee80211_is_beacon(hdr->frame_control)) {
2767 return 1; 2743 return 1;
2768 } 2744 } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) {
2769 else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { 2745 return 0;
2770 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN))
2771 return 0;
2772 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2773 } else if (!multicast && 2746 } else if (!multicast &&
2774 !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { 2747 !ether_addr_equal(sdata->vif.addr, hdr->addr1)) {
2775 if (!(sdata->dev->flags & IFF_PROMISC)) 2748 if (!(sdata->dev->flags & IFF_PROMISC))
@@ -2807,11 +2780,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
2807 * and location updates. Note that mac80211 2780 * and location updates. Note that mac80211
2808 * itself never looks at these frames. 2781 * itself never looks at these frames.
2809 */ 2782 */
2810 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && 2783 if (ieee80211_is_public_action(hdr, skb->len))
2811 ieee80211_is_public_action(hdr, skb->len))
2812 return 1; 2784 return 1;
2813 if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && 2785 if (!ieee80211_is_beacon(hdr->frame_control))
2814 !ieee80211_is_beacon(hdr->frame_control))
2815 return 0; 2786 return 0;
2816 status->rx_flags &= ~IEEE80211_RX_RA_MATCH; 2787 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2817 } 2788 }
@@ -2877,7 +2848,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
2877static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, 2848static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2878 struct sk_buff *skb) 2849 struct sk_buff *skb)
2879{ 2850{
2880 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2881 struct ieee80211_local *local = hw_to_local(hw); 2851 struct ieee80211_local *local = hw_to_local(hw);
2882 struct ieee80211_sub_if_data *sdata; 2852 struct ieee80211_sub_if_data *sdata;
2883 struct ieee80211_hdr *hdr; 2853 struct ieee80211_hdr *hdr;
@@ -2895,11 +2865,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2895 if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) 2865 if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
2896 local->dot11ReceivedFragmentCount++; 2866 local->dot11ReceivedFragmentCount++;
2897 2867
2898 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
2899 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
2900 test_bit(SCAN_SW_SCANNING, &local->scanning)))
2901 status->rx_flags |= IEEE80211_RX_IN_SCAN;
2902
2903 if (ieee80211_is_mgmt(fc)) 2868 if (ieee80211_is_mgmt(fc))
2904 err = skb_linearize(skb); 2869 err = skb_linearize(skb);
2905 else 2870 else
@@ -2914,6 +2879,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2914 ieee80211_parse_qos(&rx); 2879 ieee80211_parse_qos(&rx);
2915 ieee80211_verify_alignment(&rx); 2880 ieee80211_verify_alignment(&rx);
2916 2881
2882 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control) ||
2883 ieee80211_is_beacon(hdr->frame_control)))
2884 ieee80211_scan_rx(local, skb);
2885
2917 if (ieee80211_is_data(fc)) { 2886 if (ieee80211_is_data(fc)) {
2918 prev_sta = NULL; 2887 prev_sta = NULL;
2919 2888
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 379f178eab5f..e80a8b644aa0 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -83,13 +83,14 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
83 83
84 cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel, 84 cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel,
85 mgmt, len, signal, GFP_ATOMIC); 85 mgmt, len, signal, GFP_ATOMIC);
86
87 if (!cbss) 86 if (!cbss)
88 return NULL; 87 return NULL;
89 88
90 cbss->free_priv = ieee80211_rx_bss_free; 89 cbss->free_priv = ieee80211_rx_bss_free;
91 bss = (void *)cbss->priv; 90 bss = (void *)cbss->priv;
92 91
92 bss->device_ts = rx_status->device_timestamp;
93
93 if (elems->parse_error) { 94 if (elems->parse_error) {
94 if (beacon) 95 if (beacon)
95 bss->corrupt_data |= IEEE80211_BSS_CORRUPT_BEACON; 96 bss->corrupt_data |= IEEE80211_BSS_CORRUPT_BEACON;
@@ -165,52 +166,47 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
165 return bss; 166 return bss;
166} 167}
167 168
168ieee80211_rx_result 169void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
169ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
170{ 170{
171 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 171 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
172 struct ieee80211_mgmt *mgmt; 172 struct ieee80211_sub_if_data *sdata1, *sdata2;
173 struct ieee80211_mgmt *mgmt = (void *)skb->data;
173 struct ieee80211_bss *bss; 174 struct ieee80211_bss *bss;
174 u8 *elements; 175 u8 *elements;
175 struct ieee80211_channel *channel; 176 struct ieee80211_channel *channel;
176 size_t baselen; 177 size_t baselen;
177 int freq; 178 int freq;
178 __le16 fc; 179 bool beacon;
179 bool presp, beacon = false;
180 struct ieee802_11_elems elems; 180 struct ieee802_11_elems elems;
181 181
182 if (skb->len < 2) 182 if (skb->len < 24 ||
183 return RX_DROP_UNUSABLE; 183 (!ieee80211_is_probe_resp(mgmt->frame_control) &&
184 184 !ieee80211_is_beacon(mgmt->frame_control)))
185 mgmt = (struct ieee80211_mgmt *) skb->data; 185 return;
186 fc = mgmt->frame_control;
187 186
188 if (ieee80211_is_ctl(fc)) 187 sdata1 = rcu_dereference(local->scan_sdata);
189 return RX_CONTINUE; 188 sdata2 = rcu_dereference(local->sched_scan_sdata);
190 189
191 if (skb->len < 24) 190 if (likely(!sdata1 && !sdata2))
192 return RX_CONTINUE; 191 return;
193 192
194 presp = ieee80211_is_probe_resp(fc); 193 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
195 if (presp) {
196 /* ignore ProbeResp to foreign address */ 194 /* ignore ProbeResp to foreign address */
197 if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) 195 if ((!sdata1 || !ether_addr_equal(mgmt->da, sdata1->vif.addr)) &&
198 return RX_DROP_MONITOR; 196 (!sdata2 || !ether_addr_equal(mgmt->da, sdata2->vif.addr)))
197 return;
199 198
200 presp = true;
201 elements = mgmt->u.probe_resp.variable; 199 elements = mgmt->u.probe_resp.variable;
202 baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); 200 baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
201 beacon = false;
203 } else { 202 } else {
204 beacon = ieee80211_is_beacon(fc);
205 baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); 203 baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
206 elements = mgmt->u.beacon.variable; 204 elements = mgmt->u.beacon.variable;
205 beacon = true;
207 } 206 }
208 207
209 if (!presp && !beacon)
210 return RX_CONTINUE;
211
212 if (baselen > skb->len) 208 if (baselen > skb->len)
213 return RX_DROP_MONITOR; 209 return;
214 210
215 ieee802_11_parse_elems(elements, skb->len - baselen, &elems); 211 ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
216 212
@@ -220,22 +216,16 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
220 else 216 else
221 freq = rx_status->freq; 217 freq = rx_status->freq;
222 218
223 channel = ieee80211_get_channel(sdata->local->hw.wiphy, freq); 219 channel = ieee80211_get_channel(local->hw.wiphy, freq);
224 220
225 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) 221 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
226 return RX_DROP_MONITOR; 222 return;
227 223
228 bss = ieee80211_bss_info_update(sdata->local, rx_status, 224 bss = ieee80211_bss_info_update(local, rx_status,
229 mgmt, skb->len, &elems, 225 mgmt, skb->len, &elems,
230 channel, beacon); 226 channel, beacon);
231 if (bss) 227 if (bss)
232 ieee80211_rx_bss_put(sdata->local, bss); 228 ieee80211_rx_bss_put(local, bss);
233
234 if (channel == sdata->local->oper_channel)
235 return RX_CONTINUE;
236
237 dev_kfree_skb(skb);
238 return RX_QUEUED;
239} 229}
240 230
241/* return false if no more work */ 231/* return false if no more work */
@@ -293,7 +283,13 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
293 return; 283 return;
294 284
295 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { 285 if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) {
296 int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req); 286 int rc;
287
288 rc = drv_hw_scan(local,
289 rcu_dereference_protected(local->scan_sdata,
290 lockdep_is_held(&local->mtx)),
291 local->hw_scan_req);
292
297 if (rc == 0) 293 if (rc == 0)
298 return; 294 return;
299 } 295 }
@@ -394,7 +390,10 @@ void ieee80211_run_deferred_scan(struct ieee80211_local *local)
394 if (!local->scan_req || local->scanning) 390 if (!local->scan_req || local->scanning)
395 return; 391 return;
396 392
397 if (!ieee80211_can_scan(local, local->scan_sdata)) 393 if (!ieee80211_can_scan(local,
394 rcu_dereference_protected(
395 local->scan_sdata,
396 lockdep_is_held(&local->mtx))))
398 return; 397 return;
399 398
400 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 399 ieee80211_queue_delayed_work(&local->hw, &local->scan_work,
@@ -405,9 +404,12 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
405 unsigned long *next_delay) 404 unsigned long *next_delay)
406{ 405{
407 int i; 406 int i;
408 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 407 struct ieee80211_sub_if_data *sdata;
409 enum ieee80211_band band = local->hw.conf.channel->band; 408 enum ieee80211_band band = local->hw.conf.channel->band;
410 409
410 sdata = rcu_dereference_protected(local->scan_sdata,
411 lockdep_is_held(&local->mtx));;
412
411 for (i = 0; i < local->scan_req->n_ssids; i++) 413 for (i = 0; i < local->scan_req->n_ssids; i++)
412 ieee80211_send_probe_req( 414 ieee80211_send_probe_req(
413 sdata, NULL, 415 sdata, NULL,
@@ -439,7 +441,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
439 if (!ieee80211_can_scan(local, sdata)) { 441 if (!ieee80211_can_scan(local, sdata)) {
440 /* wait for the work to finish/time out */ 442 /* wait for the work to finish/time out */
441 local->scan_req = req; 443 local->scan_req = req;
442 local->scan_sdata = sdata; 444 rcu_assign_pointer(local->scan_sdata, sdata);
443 return 0; 445 return 0;
444 } 446 }
445 447
@@ -473,7 +475,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
473 } 475 }
474 476
475 local->scan_req = req; 477 local->scan_req = req;
476 local->scan_sdata = sdata; 478 rcu_assign_pointer(local->scan_sdata, sdata);
477 479
478 if (local->ops->hw_scan) { 480 if (local->ops->hw_scan) {
479 __set_bit(SCAN_HW_SCANNING, &local->scanning); 481 __set_bit(SCAN_HW_SCANNING, &local->scanning);
@@ -533,7 +535,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
533 ieee80211_recalc_idle(local); 535 ieee80211_recalc_idle(local);
534 536
535 local->scan_req = NULL; 537 local->scan_req = NULL;
536 local->scan_sdata = NULL; 538 rcu_assign_pointer(local->scan_sdata, NULL);
537 } 539 }
538 540
539 return rc; 541 return rc;
@@ -720,7 +722,8 @@ void ieee80211_scan_work(struct work_struct *work)
720 722
721 mutex_lock(&local->mtx); 723 mutex_lock(&local->mtx);
722 724
723 sdata = local->scan_sdata; 725 sdata = rcu_dereference_protected(local->scan_sdata,
726 lockdep_is_held(&local->mtx));
724 727
725 /* When scanning on-channel, the first-callback means completed. */ 728 /* When scanning on-channel, the first-callback means completed. */
726 if (test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning)) { 729 if (test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning)) {
@@ -741,7 +744,7 @@ void ieee80211_scan_work(struct work_struct *work)
741 int rc; 744 int rc;
742 745
743 local->scan_req = NULL; 746 local->scan_req = NULL;
744 local->scan_sdata = NULL; 747 rcu_assign_pointer(local->scan_sdata, NULL);
745 748
746 rc = __ieee80211_start_scan(sdata, req); 749 rc = __ieee80211_start_scan(sdata, req);
747 if (rc) { 750 if (rc) {
@@ -893,7 +896,9 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
893 896
894 if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { 897 if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
895 if (local->ops->cancel_hw_scan) 898 if (local->ops->cancel_hw_scan)
896 drv_cancel_hw_scan(local, local->scan_sdata); 899 drv_cancel_hw_scan(local,
900 rcu_dereference_protected(local->scan_sdata,
901 lockdep_is_held(&local->mtx)));
897 goto out; 902 goto out;
898 } 903 }
899 904
@@ -915,9 +920,9 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
915 struct ieee80211_local *local = sdata->local; 920 struct ieee80211_local *local = sdata->local;
916 int ret, i; 921 int ret, i;
917 922
918 mutex_lock(&sdata->local->mtx); 923 mutex_lock(&local->mtx);
919 924
920 if (local->sched_scanning) { 925 if (rcu_access_pointer(local->sched_scan_sdata)) {
921 ret = -EBUSY; 926 ret = -EBUSY;
922 goto out; 927 goto out;
923 } 928 }
@@ -928,6 +933,9 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
928 } 933 }
929 934
930 for (i = 0; i < IEEE80211_NUM_BANDS; i++) { 935 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
936 if (!local->hw.wiphy->bands[i])
937 continue;
938
931 local->sched_scan_ies.ie[i] = kzalloc(2 + 939 local->sched_scan_ies.ie[i] = kzalloc(2 +
932 IEEE80211_MAX_SSID_LEN + 940 IEEE80211_MAX_SSID_LEN +
933 local->scan_ies_len + 941 local->scan_ies_len +
@@ -948,7 +956,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
948 ret = drv_sched_scan_start(local, sdata, req, 956 ret = drv_sched_scan_start(local, sdata, req,
949 &local->sched_scan_ies); 957 &local->sched_scan_ies);
950 if (ret == 0) { 958 if (ret == 0) {
951 local->sched_scanning = true; 959 rcu_assign_pointer(local->sched_scan_sdata, sdata);
952 goto out; 960 goto out;
953 } 961 }
954 962
@@ -956,7 +964,7 @@ out_free:
956 while (i > 0) 964 while (i > 0)
957 kfree(local->sched_scan_ies.ie[--i]); 965 kfree(local->sched_scan_ies.ie[--i]);
958out: 966out:
959 mutex_unlock(&sdata->local->mtx); 967 mutex_unlock(&local->mtx);
960 return ret; 968 return ret;
961} 969}
962 970
@@ -965,22 +973,22 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
965 struct ieee80211_local *local = sdata->local; 973 struct ieee80211_local *local = sdata->local;
966 int ret = 0, i; 974 int ret = 0, i;
967 975
968 mutex_lock(&sdata->local->mtx); 976 mutex_lock(&local->mtx);
969 977
970 if (!local->ops->sched_scan_stop) { 978 if (!local->ops->sched_scan_stop) {
971 ret = -ENOTSUPP; 979 ret = -ENOTSUPP;
972 goto out; 980 goto out;
973 } 981 }
974 982
975 if (local->sched_scanning) { 983 if (rcu_access_pointer(local->sched_scan_sdata)) {
976 for (i = 0; i < IEEE80211_NUM_BANDS; i++) 984 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
977 kfree(local->sched_scan_ies.ie[i]); 985 kfree(local->sched_scan_ies.ie[i]);
978 986
979 drv_sched_scan_stop(local, sdata); 987 drv_sched_scan_stop(local, sdata);
980 local->sched_scanning = false; 988 rcu_assign_pointer(local->sched_scan_sdata, NULL);
981 } 989 }
982out: 990out:
983 mutex_unlock(&sdata->local->mtx); 991 mutex_unlock(&local->mtx);
984 992
985 return ret; 993 return ret;
986} 994}
@@ -1004,7 +1012,7 @@ void ieee80211_sched_scan_stopped_work(struct work_struct *work)
1004 1012
1005 mutex_lock(&local->mtx); 1013 mutex_lock(&local->mtx);
1006 1014
1007 if (!local->sched_scanning) { 1015 if (!rcu_access_pointer(local->sched_scan_sdata)) {
1008 mutex_unlock(&local->mtx); 1016 mutex_unlock(&local->mtx);
1009 return; 1017 return;
1010 } 1018 }
@@ -1012,7 +1020,7 @@ void ieee80211_sched_scan_stopped_work(struct work_struct *work)
1012 for (i = 0; i < IEEE80211_NUM_BANDS; i++) 1020 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
1013 kfree(local->sched_scan_ies.ie[i]); 1021 kfree(local->sched_scan_ies.ie[i]);
1014 1022
1015 local->sched_scanning = false; 1023 rcu_assign_pointer(local->sched_scan_sdata, NULL);
1016 1024
1017 mutex_unlock(&local->mtx); 1025 mutex_unlock(&local->mtx);
1018 1026
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 2ed2f27fe8a7..8cd72914cdaf 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -519,14 +519,19 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
519 u64 cookie = (unsigned long)skb; 519 u64 cookie = (unsigned long)skb;
520 acked = info->flags & IEEE80211_TX_STAT_ACK; 520 acked = info->flags & IEEE80211_TX_STAT_ACK;
521 521
522 /*
523 * TODO: When we have non-netdev frame TX,
524 * we cannot use skb->dev->ieee80211_ptr
525 */
526
522 if (ieee80211_is_nullfunc(hdr->frame_control) || 527 if (ieee80211_is_nullfunc(hdr->frame_control) ||
523 ieee80211_is_qos_nullfunc(hdr->frame_control)) 528 ieee80211_is_qos_nullfunc(hdr->frame_control))
524 cfg80211_probe_status(skb->dev, hdr->addr1, 529 cfg80211_probe_status(skb->dev, hdr->addr1,
525 cookie, acked, GFP_ATOMIC); 530 cookie, acked, GFP_ATOMIC);
526 else 531 else
527 cfg80211_mgmt_tx_status( 532 cfg80211_mgmt_tx_status(
528 skb->dev, cookie, skb->data, skb->len, 533 skb->dev->ieee80211_ptr, cookie, skb->data,
529 acked, GFP_ATOMIC); 534 skb->len, acked, GFP_ATOMIC);
530 } 535 }
531 536
532 if (unlikely(info->ack_frame_id)) { 537 if (unlikely(info->ack_frame_id)) {
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index e1e9d10ec2e7..c6d33b55b2df 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -306,7 +306,8 @@ TRACE_EVENT(drv_bss_info_changed,
306 __field(u8, dtimper) 306 __field(u8, dtimper)
307 __field(u16, bcnint) 307 __field(u16, bcnint)
308 __field(u16, assoc_cap) 308 __field(u16, assoc_cap)
309 __field(u64, timestamp) 309 __field(u64, sync_tsf)
310 __field(u32, sync_device_ts)
310 __field(u32, basic_rates) 311 __field(u32, basic_rates)
311 __field(u32, changed) 312 __field(u32, changed)
312 __field(bool, enable_beacon) 313 __field(bool, enable_beacon)
@@ -325,7 +326,8 @@ TRACE_EVENT(drv_bss_info_changed,
325 __entry->dtimper = info->dtim_period; 326 __entry->dtimper = info->dtim_period;
326 __entry->bcnint = info->beacon_int; 327 __entry->bcnint = info->beacon_int;
327 __entry->assoc_cap = info->assoc_capability; 328 __entry->assoc_cap = info->assoc_capability;
328 __entry->timestamp = info->last_tsf; 329 __entry->sync_tsf = info->sync_tsf;
330 __entry->sync_device_ts = info->sync_device_ts;
329 __entry->basic_rates = info->basic_rates; 331 __entry->basic_rates = info->basic_rates;
330 __entry->enable_beacon = info->enable_beacon; 332 __entry->enable_beacon = info->enable_beacon;
331 __entry->ht_operation_mode = info->ht_operation_mode; 333 __entry->ht_operation_mode = info->ht_operation_mode;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c9d2175d15c1..b755e778b0c4 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -523,7 +523,7 @@ ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx)
523static ieee80211_tx_result debug_noinline 523static ieee80211_tx_result debug_noinline
524ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) 524ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
525{ 525{
526 struct ieee80211_key *key = NULL; 526 struct ieee80211_key *key;
527 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 527 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
528 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 528 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
529 529
@@ -542,16 +542,23 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
542 else if (!is_multicast_ether_addr(hdr->addr1) && 542 else if (!is_multicast_ether_addr(hdr->addr1) &&
543 (key = rcu_dereference(tx->sdata->default_unicast_key))) 543 (key = rcu_dereference(tx->sdata->default_unicast_key)))
544 tx->key = key; 544 tx->key = key;
545 else if (tx->sdata->drop_unencrypted && 545 else if (info->flags & IEEE80211_TX_CTL_INJECTED)
546 (tx->skb->protocol != tx->sdata->control_port_protocol) && 546 tx->key = NULL;
547 !(info->flags & IEEE80211_TX_CTL_INJECTED) && 547 else if (!tx->sdata->drop_unencrypted)
548 (!ieee80211_is_robust_mgmt_frame(hdr) || 548 tx->key = NULL;
549 (ieee80211_is_action(hdr->frame_control) && 549 else if (tx->skb->protocol == tx->sdata->control_port_protocol)
550 tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))) { 550 tx->key = NULL;
551 else if (ieee80211_is_robust_mgmt_frame(hdr) &&
552 !(ieee80211_is_action(hdr->frame_control) &&
553 tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))
554 tx->key = NULL;
555 else if (ieee80211_is_mgmt(hdr->frame_control) &&
556 !ieee80211_is_robust_mgmt_frame(hdr))
557 tx->key = NULL;
558 else {
551 I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); 559 I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
552 return TX_DROP; 560 return TX_DROP;
553 } else 561 }
554 tx->key = NULL;
555 562
556 if (tx->key) { 563 if (tx->key) {
557 bool skip_hw = false; 564 bool skip_hw = false;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 64493a7bef1a..39b82fee4904 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -529,6 +529,11 @@ void ieee80211_iterate_active_interfaces(
529 &sdata->vif); 529 &sdata->vif);
530 } 530 }
531 531
532 sdata = rcu_dereference_protected(local->monitor_sdata,
533 lockdep_is_held(&local->iflist_mtx));
534 if (sdata)
535 iterator(data, sdata->vif.addr, &sdata->vif);
536
532 mutex_unlock(&local->iflist_mtx); 537 mutex_unlock(&local->iflist_mtx);
533} 538}
534EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); 539EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);
@@ -557,6 +562,10 @@ void ieee80211_iterate_active_interfaces_atomic(
557 &sdata->vif); 562 &sdata->vif);
558 } 563 }
559 564
565 sdata = rcu_dereference(local->monitor_sdata);
566 if (sdata)
567 iterator(data, sdata->vif.addr, &sdata->vif);
568
560 rcu_read_unlock(); 569 rcu_read_unlock();
561} 570}
562EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); 571EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
@@ -999,6 +1008,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
999 int ext_rates_len; 1008 int ext_rates_len;
1000 1009
1001 sband = local->hw.wiphy->bands[band]; 1010 sband = local->hw.wiphy->bands[band];
1011 if (WARN_ON_ONCE(!sband))
1012 return 0;
1002 1013
1003 pos = buffer; 1014 pos = buffer;
1004 1015