aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/Kconfig17
-rw-r--r--net/mac80211/Makefile3
-rw-r--r--net/mac80211/agg-rx.c81
-rw-r--r--net/mac80211/agg-tx.c18
-rw-r--r--net/mac80211/cfg.c123
-rw-r--r--net/mac80211/chan.c127
-rw-r--r--net/mac80211/debugfs.h1
-rw-r--r--net/mac80211/debugfs_key.c1
-rw-r--r--net/mac80211/debugfs_netdev.c13
-rw-r--r--net/mac80211/debugfs_sta.c79
-rw-r--r--net/mac80211/driver-ops.h33
-rw-r--r--net/mac80211/driver-trace.h333
-rw-r--r--net/mac80211/ht.c3
-rw-r--r--net/mac80211/ibss.c47
-rw-r--r--net/mac80211/ieee80211_i.h51
-rw-r--r--net/mac80211/iface.c125
-rw-r--r--net/mac80211/key.c2
-rw-r--r--net/mac80211/led.c1
-rw-r--r--net/mac80211/main.c32
-rw-r--r--net/mac80211/mesh.c10
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_hwmp.c10
-rw-r--r--net/mac80211/mesh_pathtbl.c1
-rw-r--r--net/mac80211/mesh_plink.c3
-rw-r--r--net/mac80211/mlme.c316
-rw-r--r--net/mac80211/pm.c2
-rw-r--r--net/mac80211/rate.c1
-rw-r--r--net/mac80211/rc80211_minstrel.c3
-rw-r--r--net/mac80211/rc80211_minstrel.h11
-rw-r--r--net/mac80211/rc80211_minstrel_debugfs.c42
-rw-r--r--net/mac80211/rc80211_pid_algo.c1
-rw-r--r--net/mac80211/rc80211_pid_debugfs.c1
-rw-r--r--net/mac80211/rx.c110
-rw-r--r--net/mac80211/scan.c127
-rw-r--r--net/mac80211/sta_info.c125
-rw-r--r--net/mac80211/sta_info.h12
-rw-r--r--net/mac80211/status.c21
-rw-r--r--net/mac80211/tx.c32
-rw-r--r--net/mac80211/util.c54
-rw-r--r--net/mac80211/wep.c1
-rw-r--r--net/mac80211/work.c63
-rw-r--r--net/mac80211/wpa.c2
42 files changed, 1634 insertions, 406 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index a952b7f8c648..8a91f6c0bb18 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -15,8 +15,12 @@ comment "CFG80211 needs to be enabled for MAC80211"
15 15
16if MAC80211 != n 16if MAC80211 != n
17 17
18config MAC80211_HAS_RC
19 def_bool n
20
18config MAC80211_RC_PID 21config MAC80211_RC_PID
19 bool "PID controller based rate control algorithm" if EMBEDDED 22 bool "PID controller based rate control algorithm" if EMBEDDED
23 select MAC80211_HAS_RC
20 ---help--- 24 ---help---
21 This option enables a TX rate control algorithm for 25 This option enables a TX rate control algorithm for
22 mac80211 that uses a PID controller to select the TX 26 mac80211 that uses a PID controller to select the TX
@@ -24,12 +28,14 @@ config MAC80211_RC_PID
24 28
25config MAC80211_RC_MINSTREL 29config MAC80211_RC_MINSTREL
26 bool "Minstrel" if EMBEDDED 30 bool "Minstrel" if EMBEDDED
31 select MAC80211_HAS_RC
27 default y 32 default y
28 ---help--- 33 ---help---
29 This option enables the 'minstrel' TX rate control algorithm 34 This option enables the 'minstrel' TX rate control algorithm
30 35
31choice 36choice
32 prompt "Default rate control algorithm" 37 prompt "Default rate control algorithm"
38 depends on MAC80211_HAS_RC
33 default MAC80211_RC_DEFAULT_MINSTREL 39 default MAC80211_RC_DEFAULT_MINSTREL
34 ---help--- 40 ---help---
35 This option selects the default rate control algorithm 41 This option selects the default rate control algorithm
@@ -62,6 +68,9 @@ config MAC80211_RC_DEFAULT
62 68
63endif 69endif
64 70
71comment "Some wireless drivers require a rate control algorithm"
72 depends on MAC80211_HAS_RC=n
73
65config MAC80211_MESH 74config MAC80211_MESH
66 bool "Enable mac80211 mesh networking (pre-802.11s) support" 75 bool "Enable mac80211 mesh networking (pre-802.11s) support"
67 depends on MAC80211 && EXPERIMENTAL 76 depends on MAC80211 && EXPERIMENTAL
@@ -212,8 +221,8 @@ config MAC80211_DRIVER_API_TRACER
212 depends on EVENT_TRACING 221 depends on EVENT_TRACING
213 help 222 help
214 Say Y here to make mac80211 register with the ftrace 223 Say Y here to make mac80211 register with the ftrace
215 framework for the driver API -- you can see which 224 framework for the driver API -- you can then see which
216 driver methods it is calling then by looking at the 225 driver methods it is calling and which API functions
217 trace. 226 drivers are calling by looking at the trace.
218 227
219 If unsure, say N. 228 If unsure, say Y.
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 04420291e7ad..84b48ba8a77e 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -23,7 +23,8 @@ mac80211-y := \
23 key.o \ 23 key.o \
24 util.o \ 24 util.o \
25 wme.o \ 25 wme.o \
26 event.o 26 event.o \
27 chan.o
27 28
28mac80211-$(CONFIG_MAC80211_LEDS) += led.o 29mac80211-$(CONFIG_MAC80211_LEDS) += led.o
29mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ 30mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index a978e666ed6f..6bb9a9a94960 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -14,27 +14,30 @@
14 */ 14 */
15 15
16#include <linux/ieee80211.h> 16#include <linux/ieee80211.h>
17#include <linux/slab.h>
17#include <net/mac80211.h> 18#include <net/mac80211.h>
18#include "ieee80211_i.h" 19#include "ieee80211_i.h"
19#include "driver-ops.h" 20#include "driver-ops.h"
20 21
21void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 22static void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
22 u16 initiator, u16 reason) 23 u16 initiator, u16 reason,
24 bool from_timer)
23{ 25{
24 struct ieee80211_local *local = sta->local; 26 struct ieee80211_local *local = sta->local;
27 struct tid_ampdu_rx *tid_rx;
25 int i; 28 int i;
26 29
27 /* check if TID is in operational state */
28 spin_lock_bh(&sta->lock); 30 spin_lock_bh(&sta->lock);
29 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) { 31
32 /* check if TID is in operational state */
33 if (!sta->ampdu_mlme.tid_active_rx[tid]) {
30 spin_unlock_bh(&sta->lock); 34 spin_unlock_bh(&sta->lock);
31 return; 35 return;
32 } 36 }
33 37
34 sta->ampdu_mlme.tid_state_rx[tid] = 38 sta->ampdu_mlme.tid_active_rx[tid] = false;
35 HT_AGG_STATE_REQ_STOP_BA_MSK | 39
36 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 40 tid_rx = sta->ampdu_mlme.tid_rx[tid];
37 spin_unlock_bh(&sta->lock);
38 41
39#ifdef CONFIG_MAC80211_HT_DEBUG 42#ifdef CONFIG_MAC80211_HT_DEBUG
40 printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n", 43 printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n",
@@ -46,61 +49,42 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
46 printk(KERN_DEBUG "HW problem - can not stop rx " 49 printk(KERN_DEBUG "HW problem - can not stop rx "
47 "aggregation for tid %d\n", tid); 50 "aggregation for tid %d\n", tid);
48 51
49 /* shutdown timer has not expired */
50 if (initiator != WLAN_BACK_TIMER)
51 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
52
53 /* check if this is a self generated aggregation halt */ 52 /* check if this is a self generated aggregation halt */
54 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER) 53 if (initiator == WLAN_BACK_RECIPIENT)
55 ieee80211_send_delba(sta->sdata, sta->sta.addr, 54 ieee80211_send_delba(sta->sdata, sta->sta.addr,
56 tid, 0, reason); 55 tid, 0, reason);
57 56
58 /* free the reordering buffer */ 57 /* free the reordering buffer */
59 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) { 58 for (i = 0; i < tid_rx->buf_size; i++) {
60 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) { 59 if (tid_rx->reorder_buf[i]) {
61 /* release the reordered frames */ 60 /* release the reordered frames */
62 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]); 61 dev_kfree_skb(tid_rx->reorder_buf[i]);
63 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--; 62 tid_rx->stored_mpdu_num--;
64 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL; 63 tid_rx->reorder_buf[i] = NULL;
65 } 64 }
66 } 65 }
67 66
68 spin_lock_bh(&sta->lock);
69 /* free resources */ 67 /* free resources */
70 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf); 68 kfree(tid_rx->reorder_buf);
71 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_time); 69 kfree(tid_rx->reorder_time);
72 70 sta->ampdu_mlme.tid_rx[tid] = NULL;
73 if (!sta->ampdu_mlme.tid_rx[tid]->shutdown) {
74 kfree(sta->ampdu_mlme.tid_rx[tid]);
75 sta->ampdu_mlme.tid_rx[tid] = NULL;
76 }
77 71
78 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
79 spin_unlock_bh(&sta->lock); 72 spin_unlock_bh(&sta->lock);
73
74 if (!from_timer)
75 del_timer_sync(&tid_rx->session_timer);
76 kfree(tid_rx);
80} 77}
81 78
82void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, 79void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
83 u16 initiator, u16 reason) 80 u16 initiator, u16 reason)
84{ 81{
85 struct sta_info *sta; 82 ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, false);
86
87 rcu_read_lock();
88
89 sta = sta_info_get(sdata, ra);
90 if (!sta) {
91 rcu_read_unlock();
92 return;
93 }
94
95 __ieee80211_stop_rx_ba_session(sta, tid, initiator, reason);
96
97 rcu_read_unlock();
98} 83}
99 84
100/* 85/*
101 * After accepting the AddBA Request we activated a timer, 86 * After accepting the AddBA Request we activated a timer,
102 * resetting it after each frame that arrives from the originator. 87 * resetting it after each frame that arrives from the originator.
103 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
104 */ 88 */
105static void sta_rx_agg_session_timer_expired(unsigned long data) 89static void sta_rx_agg_session_timer_expired(unsigned long data)
106{ 90{
@@ -116,9 +100,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
116#ifdef CONFIG_MAC80211_HT_DEBUG 100#ifdef CONFIG_MAC80211_HT_DEBUG
117 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); 101 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
118#endif 102#endif
119 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, 103 ___ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT,
120 (u16)*ptid, WLAN_BACK_TIMER, 104 WLAN_REASON_QSTA_TIMEOUT, true);
121 WLAN_REASON_QSTA_TIMEOUT);
122} 105}
123 106
124static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, 107static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
@@ -193,7 +176,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
193 176
194 status = WLAN_STATUS_REQUEST_DECLINED; 177 status = WLAN_STATUS_REQUEST_DECLINED;
195 178
196 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { 179 if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
197#ifdef CONFIG_MAC80211_HT_DEBUG 180#ifdef CONFIG_MAC80211_HT_DEBUG
198 printk(KERN_DEBUG "Suspend in progress. " 181 printk(KERN_DEBUG "Suspend in progress. "
199 "Denying ADDBA request\n"); 182 "Denying ADDBA request\n");
@@ -231,7 +214,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
231 /* examine state machine */ 214 /* examine state machine */
232 spin_lock_bh(&sta->lock); 215 spin_lock_bh(&sta->lock);
233 216
234 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { 217 if (sta->ampdu_mlme.tid_active_rx[tid]) {
235#ifdef CONFIG_MAC80211_HT_DEBUG 218#ifdef CONFIG_MAC80211_HT_DEBUG
236 if (net_ratelimit()) 219 if (net_ratelimit())
237 printk(KERN_DEBUG "unexpected AddBA Req from " 220 printk(KERN_DEBUG "unexpected AddBA Req from "
@@ -293,7 +276,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
293 } 276 }
294 277
295 /* change state and send addba resp */ 278 /* change state and send addba resp */
296 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL; 279 sta->ampdu_mlme.tid_active_rx[tid] = true;
297 tid_agg_rx->dialog_token = dialog_token; 280 tid_agg_rx->dialog_token = dialog_token;
298 tid_agg_rx->ssn = start_seq_num; 281 tid_agg_rx->ssn = start_seq_num;
299 tid_agg_rx->head_seq_num = start_seq_num; 282 tid_agg_rx->head_seq_num = start_seq_num;
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 5538e1b4a697..c163d0a149f4 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/ieee80211.h> 16#include <linux/ieee80211.h>
17#include <linux/slab.h>
17#include <net/mac80211.h> 18#include <net/mac80211.h>
18#include "ieee80211_i.h" 19#include "ieee80211_i.h"
19#include "driver-ops.h" 20#include "driver-ops.h"
@@ -183,10 +184,9 @@ static void sta_addba_resp_timer_expired(unsigned long data)
183 HT_AGG_STATE_REQ_STOP_BA_MSK)) != 184 HT_AGG_STATE_REQ_STOP_BA_MSK)) !=
184 HT_ADDBA_REQUESTED_MSK) { 185 HT_ADDBA_REQUESTED_MSK) {
185 spin_unlock_bh(&sta->lock); 186 spin_unlock_bh(&sta->lock);
186 *state = HT_AGG_STATE_IDLE;
187#ifdef CONFIG_MAC80211_HT_DEBUG 187#ifdef CONFIG_MAC80211_HT_DEBUG
188 printk(KERN_DEBUG "timer expired on tid %d but we are not " 188 printk(KERN_DEBUG "timer expired on tid %d but we are not "
189 "(or no longer) expecting addBA response there", 189 "(or no longer) expecting addBA response there\n",
190 tid); 190 tid);
191#endif 191#endif
192 return; 192 return;
@@ -214,6 +214,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
214 int ret = 0; 214 int ret = 0;
215 u16 start_seq_num; 215 u16 start_seq_num;
216 216
217 trace_api_start_tx_ba_session(pubsta, tid);
218
217 if (WARN_ON(!local->ops->ampdu_action)) 219 if (WARN_ON(!local->ops->ampdu_action))
218 return -EINVAL; 220 return -EINVAL;
219 221
@@ -245,7 +247,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
245 return -EINVAL; 247 return -EINVAL;
246 } 248 }
247 249
248 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { 250 if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
249#ifdef CONFIG_MAC80211_HT_DEBUG 251#ifdef CONFIG_MAC80211_HT_DEBUG
250 printk(KERN_DEBUG "Suspend in progress. " 252 printk(KERN_DEBUG "Suspend in progress. "
251 "Denying BA session request\n"); 253 "Denying BA session request\n");
@@ -414,7 +416,7 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
414 struct sta_info *sta, u16 tid) 416 struct sta_info *sta, u16 tid)
415{ 417{
416#ifdef CONFIG_MAC80211_HT_DEBUG 418#ifdef CONFIG_MAC80211_HT_DEBUG
417 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); 419 printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid);
418#endif 420#endif
419 421
420 spin_lock(&local->ampdu_lock); 422 spin_lock(&local->ampdu_lock);
@@ -440,6 +442,8 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
440 struct sta_info *sta; 442 struct sta_info *sta;
441 u8 *state; 443 u8 *state;
442 444
445 trace_api_start_tx_ba_cb(sdata, ra, tid);
446
443 if (tid >= STA_TID_NUM) { 447 if (tid >= STA_TID_NUM) {
444#ifdef CONFIG_MAC80211_HT_DEBUG 448#ifdef CONFIG_MAC80211_HT_DEBUG
445 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", 449 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
@@ -541,6 +545,8 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
541 struct ieee80211_sub_if_data *sdata = sta->sdata; 545 struct ieee80211_sub_if_data *sdata = sta->sdata;
542 struct ieee80211_local *local = sdata->local; 546 struct ieee80211_local *local = sdata->local;
543 547
548 trace_api_stop_tx_ba_session(pubsta, tid, initiator);
549
544 if (!local->ops->ampdu_action) 550 if (!local->ops->ampdu_action)
545 return -EINVAL; 551 return -EINVAL;
546 552
@@ -558,6 +564,8 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
558 struct sta_info *sta; 564 struct sta_info *sta;
559 u8 *state; 565 u8 *state;
560 566
567 trace_api_stop_tx_ba_cb(sdata, ra, tid);
568
561 if (tid >= STA_TID_NUM) { 569 if (tid >= STA_TID_NUM) {
562#ifdef CONFIG_MAC80211_HT_DEBUG 570#ifdef CONFIG_MAC80211_HT_DEBUG
563 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", 571 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
@@ -674,7 +682,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
674 del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 682 del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
675 683
676#ifdef CONFIG_MAC80211_HT_DEBUG 684#ifdef CONFIG_MAC80211_HT_DEBUG
677 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); 685 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
678#endif /* CONFIG_MAC80211_HT_DEBUG */ 686#endif /* CONFIG_MAC80211_HT_DEBUG */
679 687
680 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 688 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b7116ef84a3b..c7000a6ca379 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -9,6 +9,7 @@
9#include <linux/ieee80211.h> 9#include <linux/ieee80211.h>
10#include <linux/nl80211.h> 10#include <linux/nl80211.h>
11#include <linux/rtnetlink.h> 11#include <linux/rtnetlink.h>
12#include <linux/slab.h>
12#include <net/net_namespace.h> 13#include <net/net_namespace.h>
13#include <linux/rcupdate.h> 14#include <linux/rcupdate.h>
14#include <net/cfg80211.h> 15#include <net/cfg80211.h>
@@ -96,9 +97,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
96 params->mesh_id_len, 97 params->mesh_id_len,
97 params->mesh_id); 98 params->mesh_id);
98 99
99 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
100 return 0;
101
102 if (type == NL80211_IFTYPE_AP_VLAN && 100 if (type == NL80211_IFTYPE_AP_VLAN &&
103 params && params->use_4addr == 0) 101 params && params->use_4addr == 0)
104 rcu_assign_pointer(sdata->u.vlan.sta, NULL); 102 rcu_assign_pointer(sdata->u.vlan.sta, NULL);
@@ -106,7 +104,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
106 params && params->use_4addr >= 0) 104 params && params->use_4addr >= 0)
107 sdata->u.mgd.use_4addr = params->use_4addr; 105 sdata->u.mgd.use_4addr = params->use_4addr;
108 106
109 sdata->u.mntr_flags = *flags; 107 if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags)
108 sdata->u.mntr_flags = *flags;
109
110 return 0; 110 return 0;
111} 111}
112 112
@@ -410,6 +410,17 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
410 return ret; 410 return ret;
411} 411}
412 412
413static int ieee80211_dump_survey(struct wiphy *wiphy, struct net_device *dev,
414 int idx, struct survey_info *survey)
415{
416 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
417
418 if (!local->ops->get_survey)
419 return -EOPNOTSUPP;
420
421 return drv_get_survey(local, idx, survey);
422}
423
413static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, 424static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
414 u8 *mac, struct station_info *sinfo) 425 u8 *mac, struct station_info *sinfo)
415{ 426{
@@ -1103,6 +1114,13 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1103 changed |= BSS_CHANGED_BASIC_RATES; 1114 changed |= BSS_CHANGED_BASIC_RATES;
1104 } 1115 }
1105 1116
1117 if (params->ap_isolate >= 0) {
1118 if (params->ap_isolate)
1119 sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
1120 else
1121 sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
1122 }
1123
1106 ieee80211_bss_info_change_notify(sdata, changed); 1124 ieee80211_bss_info_change_notify(sdata, changed);
1107 1125
1108 return 0; 1126 return 0;
@@ -1136,19 +1154,47 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1136 return -EINVAL; 1154 return -EINVAL;
1137 } 1155 }
1138 1156
1157 /* enable WMM or activate new settings */
1158 local->hw.conf.flags |= IEEE80211_CONF_QOS;
1159 drv_config(local, IEEE80211_CONF_CHANGE_QOS);
1160
1139 return 0; 1161 return 0;
1140} 1162}
1141 1163
1142static int ieee80211_set_channel(struct wiphy *wiphy, 1164static int ieee80211_set_channel(struct wiphy *wiphy,
1165 struct net_device *netdev,
1143 struct ieee80211_channel *chan, 1166 struct ieee80211_channel *chan,
1144 enum nl80211_channel_type channel_type) 1167 enum nl80211_channel_type channel_type)
1145{ 1168{
1146 struct ieee80211_local *local = wiphy_priv(wiphy); 1169 struct ieee80211_local *local = wiphy_priv(wiphy);
1170 struct ieee80211_sub_if_data *sdata = NULL;
1171
1172 if (netdev)
1173 sdata = IEEE80211_DEV_TO_SUB_IF(netdev);
1174
1175 switch (ieee80211_get_channel_mode(local, NULL)) {
1176 case CHAN_MODE_HOPPING:
1177 return -EBUSY;
1178 case CHAN_MODE_FIXED:
1179 if (local->oper_channel != chan)
1180 return -EBUSY;
1181 if (!sdata && local->_oper_channel_type == channel_type)
1182 return 0;
1183 break;
1184 case CHAN_MODE_UNDEFINED:
1185 break;
1186 }
1147 1187
1148 local->oper_channel = chan; 1188 local->oper_channel = chan;
1149 local->oper_channel_type = channel_type;
1150 1189
1151 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 1190 if (!ieee80211_set_channel_type(local, sdata, channel_type))
1191 return -EBUSY;
1192
1193 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
1194 if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR)
1195 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
1196
1197 return 0;
1152} 1198}
1153 1199
1154#ifdef CONFIG_PM 1200#ifdef CONFIG_PM
@@ -1192,6 +1238,20 @@ static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
1192static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, 1238static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1193 struct cfg80211_assoc_request *req) 1239 struct cfg80211_assoc_request *req)
1194{ 1240{
1241 struct ieee80211_local *local = wiphy_priv(wiphy);
1242 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1243
1244 switch (ieee80211_get_channel_mode(local, sdata)) {
1245 case CHAN_MODE_HOPPING:
1246 return -EBUSY;
1247 case CHAN_MODE_FIXED:
1248 if (local->oper_channel == req->bss->channel)
1249 break;
1250 return -EBUSY;
1251 case CHAN_MODE_UNDEFINED:
1252 break;
1253 }
1254
1195 return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req); 1255 return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
1196} 1256}
1197 1257
@@ -1214,8 +1274,22 @@ static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
1214static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, 1274static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1215 struct cfg80211_ibss_params *params) 1275 struct cfg80211_ibss_params *params)
1216{ 1276{
1277 struct ieee80211_local *local = wiphy_priv(wiphy);
1217 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1278 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1218 1279
1280 switch (ieee80211_get_channel_mode(local, sdata)) {
1281 case CHAN_MODE_HOPPING:
1282 return -EBUSY;
1283 case CHAN_MODE_FIXED:
1284 if (!params->channel_fixed)
1285 return -EBUSY;
1286 if (local->oper_channel == params->channel)
1287 break;
1288 return -EBUSY;
1289 case CHAN_MODE_UNDEFINED:
1290 break;
1291 }
1292
1219 return ieee80211_ibss_join(sdata, params); 1293 return ieee80211_ibss_join(sdata, params);
1220} 1294}
1221 1295
@@ -1344,7 +1418,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1344 * association, there's no need to send an action frame. 1418 * association, there's no need to send an action frame.
1345 */ 1419 */
1346 if (!sdata->u.mgd.associated || 1420 if (!sdata->u.mgd.associated ||
1347 sdata->local->oper_channel_type == NL80211_CHAN_NO_HT) { 1421 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
1348 mutex_lock(&sdata->local->iflist_mtx); 1422 mutex_lock(&sdata->local->iflist_mtx);
1349 ieee80211_recalc_smps(sdata->local, sdata); 1423 ieee80211_recalc_smps(sdata->local, sdata);
1350 mutex_unlock(&sdata->local->iflist_mtx); 1424 mutex_unlock(&sdata->local->iflist_mtx);
@@ -1383,11 +1457,11 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1383 return -EOPNOTSUPP; 1457 return -EOPNOTSUPP;
1384 1458
1385 if (enabled == sdata->u.mgd.powersave && 1459 if (enabled == sdata->u.mgd.powersave &&
1386 timeout == conf->dynamic_ps_timeout) 1460 timeout == conf->dynamic_ps_forced_timeout)
1387 return 0; 1461 return 0;
1388 1462
1389 sdata->u.mgd.powersave = enabled; 1463 sdata->u.mgd.powersave = enabled;
1390 conf->dynamic_ps_timeout = timeout; 1464 conf->dynamic_ps_forced_timeout = timeout;
1391 1465
1392 /* no change, but if automatic follow powersave */ 1466 /* no change, but if automatic follow powersave */
1393 mutex_lock(&sdata->u.mgd.mtx); 1467 mutex_lock(&sdata->u.mgd.mtx);
@@ -1402,6 +1476,35 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1402 return 0; 1476 return 0;
1403} 1477}
1404 1478
1479static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
1480 struct net_device *dev,
1481 s32 rssi_thold, u32 rssi_hyst)
1482{
1483 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1484 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1485 struct ieee80211_vif *vif = &sdata->vif;
1486 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1487
1488 if (rssi_thold == bss_conf->cqm_rssi_thold &&
1489 rssi_hyst == bss_conf->cqm_rssi_hyst)
1490 return 0;
1491
1492 bss_conf->cqm_rssi_thold = rssi_thold;
1493 bss_conf->cqm_rssi_hyst = rssi_hyst;
1494
1495 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
1496 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1497 return -EOPNOTSUPP;
1498 return 0;
1499 }
1500
1501 /* tell the driver upon association, unless already associated */
1502 if (sdata->u.mgd.associated)
1503 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
1504
1505 return 0;
1506}
1507
1405static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, 1508static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1406 struct net_device *dev, 1509 struct net_device *dev,
1407 const u8 *addr, 1510 const u8 *addr,
@@ -1474,6 +1577,7 @@ struct cfg80211_ops mac80211_config_ops = {
1474 .change_station = ieee80211_change_station, 1577 .change_station = ieee80211_change_station,
1475 .get_station = ieee80211_get_station, 1578 .get_station = ieee80211_get_station,
1476 .dump_station = ieee80211_dump_station, 1579 .dump_station = ieee80211_dump_station,
1580 .dump_survey = ieee80211_dump_survey,
1477#ifdef CONFIG_MAC80211_MESH 1581#ifdef CONFIG_MAC80211_MESH
1478 .add_mpath = ieee80211_add_mpath, 1582 .add_mpath = ieee80211_add_mpath,
1479 .del_mpath = ieee80211_del_mpath, 1583 .del_mpath = ieee80211_del_mpath,
@@ -1506,4 +1610,5 @@ struct cfg80211_ops mac80211_config_ops = {
1506 .remain_on_channel = ieee80211_remain_on_channel, 1610 .remain_on_channel = ieee80211_remain_on_channel,
1507 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, 1611 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1508 .action = ieee80211_action, 1612 .action = ieee80211_action,
1613 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
1509}; 1614};
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
new file mode 100644
index 000000000000..5d218c530a4e
--- /dev/null
+++ b/net/mac80211/chan.c
@@ -0,0 +1,127 @@
1/*
2 * mac80211 - channel management
3 */
4
5#include <linux/nl80211.h>
6#include "ieee80211_i.h"
7
8enum ieee80211_chan_mode
9__ieee80211_get_channel_mode(struct ieee80211_local *local,
10 struct ieee80211_sub_if_data *ignore)
11{
12 struct ieee80211_sub_if_data *sdata;
13
14 WARN_ON(!mutex_is_locked(&local->iflist_mtx));
15
16 list_for_each_entry(sdata, &local->interfaces, list) {
17 if (sdata == ignore)
18 continue;
19
20 if (!ieee80211_sdata_running(sdata))
21 continue;
22
23 if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
24 continue;
25
26 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
27 !sdata->u.mgd.associated)
28 continue;
29
30 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
31 if (!sdata->u.ibss.ssid_len)
32 continue;
33 if (!sdata->u.ibss.fixed_channel)
34 return CHAN_MODE_HOPPING;
35 }
36
37 if (sdata->vif.type == NL80211_IFTYPE_AP &&
38 !sdata->u.ap.beacon)
39 continue;
40
41 return CHAN_MODE_FIXED;
42 }
43
44 return CHAN_MODE_UNDEFINED;
45}
46
47enum ieee80211_chan_mode
48ieee80211_get_channel_mode(struct ieee80211_local *local,
49 struct ieee80211_sub_if_data *ignore)
50{
51 enum ieee80211_chan_mode mode;
52
53 mutex_lock(&local->iflist_mtx);
54 mode = __ieee80211_get_channel_mode(local, ignore);
55 mutex_unlock(&local->iflist_mtx);
56
57 return mode;
58}
59
60bool ieee80211_set_channel_type(struct ieee80211_local *local,
61 struct ieee80211_sub_if_data *sdata,
62 enum nl80211_channel_type chantype)
63{
64 struct ieee80211_sub_if_data *tmp;
65 enum nl80211_channel_type superchan = NL80211_CHAN_NO_HT;
66 bool result;
67
68 mutex_lock(&local->iflist_mtx);
69
70 list_for_each_entry(tmp, &local->interfaces, list) {
71 if (tmp == sdata)
72 continue;
73
74 if (!ieee80211_sdata_running(tmp))
75 continue;
76
77 switch (tmp->vif.bss_conf.channel_type) {
78 case NL80211_CHAN_NO_HT:
79 case NL80211_CHAN_HT20:
80 superchan = tmp->vif.bss_conf.channel_type;
81 break;
82 case NL80211_CHAN_HT40PLUS:
83 WARN_ON(superchan == NL80211_CHAN_HT40MINUS);
84 superchan = NL80211_CHAN_HT40PLUS;
85 break;
86 case NL80211_CHAN_HT40MINUS:
87 WARN_ON(superchan == NL80211_CHAN_HT40PLUS);
88 superchan = NL80211_CHAN_HT40MINUS;
89 break;
90 }
91 }
92
93 switch (superchan) {
94 case NL80211_CHAN_NO_HT:
95 case NL80211_CHAN_HT20:
96 /*
97 * allow any change that doesn't go to no-HT
98 * (if it already is no-HT no change is needed)
99 */
100 if (chantype == NL80211_CHAN_NO_HT)
101 break;
102 superchan = chantype;
103 break;
104 case NL80211_CHAN_HT40PLUS:
105 case NL80211_CHAN_HT40MINUS:
106 /* allow smaller bandwidth and same */
107 if (chantype == NL80211_CHAN_NO_HT)
108 break;
109 if (chantype == NL80211_CHAN_HT20)
110 break;
111 if (superchan == chantype)
112 break;
113 result = false;
114 goto out;
115 }
116
117 local->_oper_channel_type = superchan;
118
119 if (sdata)
120 sdata->vif.bss_conf.channel_type = chantype;
121
122 result = true;
123 out:
124 mutex_unlock(&local->iflist_mtx);
125
126 return result;
127}
diff --git a/net/mac80211/debugfs.h b/net/mac80211/debugfs.h
index 68e6a2050f9a..09cc9be34796 100644
--- a/net/mac80211/debugfs.h
+++ b/net/mac80211/debugfs.h
@@ -7,7 +7,6 @@ extern int mac80211_open_file_generic(struct inode *inode, struct file *file);
7#else 7#else
8static inline void debugfs_hw_add(struct ieee80211_local *local) 8static inline void debugfs_hw_add(struct ieee80211_local *local)
9{ 9{
10 return;
11} 10}
12#endif 11#endif
13 12
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index d12e743cb4e1..97c9e46e859e 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/kobject.h> 11#include <linux/kobject.h>
12#include <linux/slab.h>
12#include "ieee80211_i.h" 13#include "ieee80211_i.h"
13#include "key.h" 14#include "key.h"
14#include "debugfs.h" 15#include "debugfs.h"
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index b4ddb2f83914..20b2998fa0ed 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -13,6 +13,7 @@
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include <linux/netdevice.h> 14#include <linux/netdevice.h>
15#include <linux/rtnetlink.h> 15#include <linux/rtnetlink.h>
16#include <linux/slab.h>
16#include <linux/notifier.h> 17#include <linux/notifier.h>
17#include <net/mac80211.h> 18#include <net/mac80211.h>
18#include <net/cfg80211.h> 19#include <net/cfg80211.h>
@@ -99,6 +100,14 @@ static ssize_t ieee80211_if_fmt_##name( \
99 return scnprintf(buf, buflen, "%pM\n", sdata->field); \ 100 return scnprintf(buf, buflen, "%pM\n", sdata->field); \
100} 101}
101 102
103#define IEEE80211_IF_FMT_DEC_DIV_16(name, field) \
104static ssize_t ieee80211_if_fmt_##name( \
105 const struct ieee80211_sub_if_data *sdata, \
106 char *buf, int buflen) \
107{ \
108 return scnprintf(buf, buflen, "%d\n", sdata->field / 16); \
109}
110
102#define __IEEE80211_IF_FILE(name, _write) \ 111#define __IEEE80211_IF_FILE(name, _write) \
103static ssize_t ieee80211_if_read_##name(struct file *file, \ 112static ssize_t ieee80211_if_read_##name(struct file *file, \
104 char __user *userbuf, \ 113 char __user *userbuf, \
@@ -139,6 +148,8 @@ IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
139/* STA attributes */ 148/* STA attributes */
140IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); 149IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
141IEEE80211_IF_FILE(aid, u.mgd.aid, DEC); 150IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
151IEEE80211_IF_FILE(last_beacon, u.mgd.last_beacon_signal, DEC);
152IEEE80211_IF_FILE(ave_beacon, u.mgd.ave_beacon_signal, DEC_DIV_16);
142 153
143static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, 154static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
144 enum ieee80211_smps_mode smps_mode) 155 enum ieee80211_smps_mode smps_mode)
@@ -275,6 +286,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
275 286
276 DEBUGFS_ADD(bssid); 287 DEBUGFS_ADD(bssid);
277 DEBUGFS_ADD(aid); 288 DEBUGFS_ADD(aid);
289 DEBUGFS_ADD(last_beacon);
290 DEBUGFS_ADD(ave_beacon);
278 DEBUGFS_ADD_MODE(smps, 0600); 291 DEBUGFS_ADD_MODE(smps, 0600);
279} 292}
280 293
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index d92800bb2d2f..e763f1529ddb 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -39,6 +39,13 @@ static const struct file_operations sta_ ##name## _ops = { \
39 .open = mac80211_open_file_generic, \ 39 .open = mac80211_open_file_generic, \
40} 40}
41 41
42#define STA_OPS_RW(name) \
43static const struct file_operations sta_ ##name## _ops = { \
44 .read = sta_##name##_read, \
45 .write = sta_##name##_write, \
46 .open = mac80211_open_file_generic, \
47}
48
42#define STA_FILE(name, field, format) \ 49#define STA_FILE(name, field, format) \
43 STA_READ_##format(name, field) \ 50 STA_READ_##format(name, field) \
44 STA_OPS(name) 51 STA_OPS(name)
@@ -57,7 +64,6 @@ STA_FILE(tx_filtered, tx_filtered_count, LU);
57STA_FILE(tx_retry_failed, tx_retry_failed, LU); 64STA_FILE(tx_retry_failed, tx_retry_failed, LU);
58STA_FILE(tx_retry_count, tx_retry_count, LU); 65STA_FILE(tx_retry_count, tx_retry_count, LU);
59STA_FILE(last_signal, last_signal, D); 66STA_FILE(last_signal, last_signal, D);
60STA_FILE(last_noise, last_noise, D);
61STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); 67STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU);
62 68
63static ssize_t sta_flags_read(struct file *file, char __user *userbuf, 69static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
@@ -120,7 +126,7 @@ STA_OPS(last_seq_ctrl);
120static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, 126static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
121 size_t count, loff_t *ppos) 127 size_t count, loff_t *ppos)
122{ 128{
123 char buf[64 + STA_TID_NUM * 40], *p = buf; 129 char buf[71 + STA_TID_NUM * 40], *p = buf;
124 int i; 130 int i;
125 struct sta_info *sta = file->private_data; 131 struct sta_info *sta = file->private_data;
126 132
@@ -128,16 +134,16 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
128 p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n", 134 p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n",
129 sta->ampdu_mlme.dialog_token_allocator + 1); 135 sta->ampdu_mlme.dialog_token_allocator + 1);
130 p += scnprintf(p, sizeof(buf) + buf - p, 136 p += scnprintf(p, sizeof(buf) + buf - p,
131 "TID\t\tRX\tDTKN\tSSN\t\tTX\tDTKN\tSSN\tpending\n"); 137 "TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tSSN\tpending\n");
132 for (i = 0; i < STA_TID_NUM; i++) { 138 for (i = 0; i < STA_TID_NUM; i++) {
133 p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i); 139 p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i);
134 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", 140 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
135 sta->ampdu_mlme.tid_state_rx[i]); 141 sta->ampdu_mlme.tid_active_rx[i]);
136 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x", 142 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
137 sta->ampdu_mlme.tid_state_rx[i] ? 143 sta->ampdu_mlme.tid_active_rx[i] ?
138 sta->ampdu_mlme.tid_rx[i]->dialog_token : 0); 144 sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
139 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x", 145 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
140 sta->ampdu_mlme.tid_state_rx[i] ? 146 sta->ampdu_mlme.tid_active_rx[i] ?
141 sta->ampdu_mlme.tid_rx[i]->ssn : 0); 147 sta->ampdu_mlme.tid_rx[i]->ssn : 0);
142 148
143 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", 149 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
@@ -157,7 +163,63 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
157 163
158 return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); 164 return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
159} 165}
160STA_OPS(agg_status); 166
167static ssize_t sta_agg_status_write(struct file *file, const char __user *userbuf,
168 size_t count, loff_t *ppos)
169{
170 char _buf[12], *buf = _buf;
171 struct sta_info *sta = file->private_data;
172 bool start, tx;
173 unsigned long tid;
174 int ret;
175
176 if (count > sizeof(_buf))
177 return -EINVAL;
178
179 if (copy_from_user(buf, userbuf, count))
180 return -EFAULT;
181
182 buf[sizeof(_buf) - 1] = '\0';
183
184 if (strncmp(buf, "tx ", 3) == 0) {
185 buf += 3;
186 tx = true;
187 } else if (strncmp(buf, "rx ", 3) == 0) {
188 buf += 3;
189 tx = false;
190 } else
191 return -EINVAL;
192
193 if (strncmp(buf, "start ", 6) == 0) {
194 buf += 6;
195 start = true;
196 if (!tx)
197 return -EINVAL;
198 } else if (strncmp(buf, "stop ", 5) == 0) {
199 buf += 5;
200 start = false;
201 } else
202 return -EINVAL;
203
204 tid = simple_strtoul(buf, NULL, 0);
205
206 if (tid >= STA_TID_NUM)
207 return -EINVAL;
208
209 if (tx) {
210 if (start)
211 ret = ieee80211_start_tx_ba_session(&sta->sta, tid);
212 else
213 ret = ieee80211_stop_tx_ba_session(&sta->sta, tid,
214 WLAN_BACK_RECIPIENT);
215 } else {
216 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3);
217 ret = 0;
218 }
219
220 return ret ?: count;
221}
222STA_OPS_RW(agg_status);
161 223
162static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf, 224static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
163 size_t count, loff_t *ppos) 225 size_t count, loff_t *ppos)
@@ -177,7 +239,7 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
177 if (htc->ht_supported) { 239 if (htc->ht_supported) {
178 p += scnprintf(p, sizeof(buf)+buf-p, "cap: %#.4x\n", htc->cap); 240 p += scnprintf(p, sizeof(buf)+buf-p, "cap: %#.4x\n", htc->cap);
179 241
180 PRINT_HT_CAP((htc->cap & BIT(0)), "RX LDCP"); 242 PRINT_HT_CAP((htc->cap & BIT(0)), "RX LDPC");
181 PRINT_HT_CAP((htc->cap & BIT(1)), "HT20/HT40"); 243 PRINT_HT_CAP((htc->cap & BIT(1)), "HT20/HT40");
182 PRINT_HT_CAP(!(htc->cap & BIT(1)), "HT20"); 244 PRINT_HT_CAP(!(htc->cap & BIT(1)), "HT20");
183 245
@@ -289,7 +351,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
289 DEBUGFS_ADD(tx_retry_failed); 351 DEBUGFS_ADD(tx_retry_failed);
290 DEBUGFS_ADD(tx_retry_count); 352 DEBUGFS_ADD(tx_retry_count);
291 DEBUGFS_ADD(last_signal); 353 DEBUGFS_ADD(last_signal);
292 DEBUGFS_ADD(last_noise);
293 DEBUGFS_ADD(wep_weak_iv_count); 354 DEBUGFS_ADD(wep_weak_iv_count);
294 DEBUGFS_ADD(ht_capa); 355 DEBUGFS_ADD(ht_capa);
295} 356}
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index c3d844093a2f..4f2271316650 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -84,16 +84,14 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
84} 84}
85 85
86static inline u64 drv_prepare_multicast(struct ieee80211_local *local, 86static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
87 int mc_count, 87 struct netdev_hw_addr_list *mc_list)
88 struct dev_addr_list *mc_list)
89{ 88{
90 u64 ret = 0; 89 u64 ret = 0;
91 90
92 if (local->ops->prepare_multicast) 91 if (local->ops->prepare_multicast)
93 ret = local->ops->prepare_multicast(&local->hw, mc_count, 92 ret = local->ops->prepare_multicast(&local->hw, mc_list);
94 mc_list);
95 93
96 trace_drv_prepare_multicast(local, mc_count, ret); 94 trace_drv_prepare_multicast(local, mc_list->count, ret);
97 95
98 return ret; 96 return ret;
99} 97}
@@ -154,14 +152,15 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local,
154} 152}
155 153
156static inline int drv_hw_scan(struct ieee80211_local *local, 154static inline int drv_hw_scan(struct ieee80211_local *local,
155 struct ieee80211_sub_if_data *sdata,
157 struct cfg80211_scan_request *req) 156 struct cfg80211_scan_request *req)
158{ 157{
159 int ret; 158 int ret;
160 159
161 might_sleep(); 160 might_sleep();
162 161
163 ret = local->ops->hw_scan(&local->hw, req); 162 ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
164 trace_drv_hw_scan(local, req, ret); 163 trace_drv_hw_scan(local, sdata, req, ret);
165 return ret; 164 return ret;
166} 165}
167 166
@@ -346,6 +345,15 @@ static inline int drv_ampdu_action(struct ieee80211_local *local,
346 return ret; 345 return ret;
347} 346}
348 347
348static inline int drv_get_survey(struct ieee80211_local *local, int idx,
349 struct survey_info *survey)
350{
351 int ret = -EOPNOTSUPP;
352 if (local->ops->conf_tx)
353 ret = local->ops->get_survey(&local->hw, idx, survey);
354 /* trace_drv_get_survey(local, idx, survey, ret); */
355 return ret;
356}
349 357
350static inline void drv_rfkill_poll(struct ieee80211_local *local) 358static inline void drv_rfkill_poll(struct ieee80211_local *local)
351{ 359{
@@ -363,4 +371,15 @@ static inline void drv_flush(struct ieee80211_local *local, bool drop)
363 if (local->ops->flush) 371 if (local->ops->flush)
364 local->ops->flush(&local->hw, drop); 372 local->ops->flush(&local->hw, drop);
365} 373}
374
375static inline void drv_channel_switch(struct ieee80211_local *local,
376 struct ieee80211_channel_switch *ch_switch)
377{
378 might_sleep();
379
380 local->ops->channel_switch(&local->hw, ch_switch);
381
382 trace_drv_channel_switch(local, ch_switch);
383}
384
366#endif /* __MAC80211_DRIVER_OPS */ 385#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 41baf730a5c7..6a9b2342a9c2 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -32,6 +32,10 @@ static inline void trace_ ## name(proto) {}
32#define VIF_PR_FMT " vif:%s(%d)" 32#define VIF_PR_FMT " vif:%s(%d)"
33#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type 33#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type
34 34
35/*
36 * Tracing for driver callbacks.
37 */
38
35TRACE_EVENT(drv_start, 39TRACE_EVENT(drv_start,
36 TP_PROTO(struct ieee80211_local *local, int ret), 40 TP_PROTO(struct ieee80211_local *local, int ret),
37 41
@@ -359,23 +363,26 @@ TRACE_EVENT(drv_update_tkip_key,
359 363
360TRACE_EVENT(drv_hw_scan, 364TRACE_EVENT(drv_hw_scan,
361 TP_PROTO(struct ieee80211_local *local, 365 TP_PROTO(struct ieee80211_local *local,
366 struct ieee80211_sub_if_data *sdata,
362 struct cfg80211_scan_request *req, int ret), 367 struct cfg80211_scan_request *req, int ret),
363 368
364 TP_ARGS(local, req, ret), 369 TP_ARGS(local, sdata, req, ret),
365 370
366 TP_STRUCT__entry( 371 TP_STRUCT__entry(
367 LOCAL_ENTRY 372 LOCAL_ENTRY
373 VIF_ENTRY
368 __field(int, ret) 374 __field(int, ret)
369 ), 375 ),
370 376
371 TP_fast_assign( 377 TP_fast_assign(
372 LOCAL_ASSIGN; 378 LOCAL_ASSIGN;
379 VIF_ASSIGN;
373 __entry->ret = ret; 380 __entry->ret = ret;
374 ), 381 ),
375 382
376 TP_printk( 383 TP_printk(
377 LOCAL_PR_FMT " ret:%d", 384 LOCAL_PR_FMT VIF_PR_FMT " ret:%d",
378 LOCAL_PR_ARG, __entry->ret 385 LOCAL_PR_ARG,VIF_PR_ARG, __entry->ret
379 ) 386 )
380); 387);
381 388
@@ -766,6 +773,326 @@ TRACE_EVENT(drv_flush,
766 LOCAL_PR_ARG, __entry->drop 773 LOCAL_PR_ARG, __entry->drop
767 ) 774 )
768); 775);
776
777TRACE_EVENT(drv_channel_switch,
778 TP_PROTO(struct ieee80211_local *local,
779 struct ieee80211_channel_switch *ch_switch),
780
781 TP_ARGS(local, ch_switch),
782
783 TP_STRUCT__entry(
784 LOCAL_ENTRY
785 __field(u64, timestamp)
786 __field(bool, block_tx)
787 __field(u16, freq)
788 __field(u8, count)
789 ),
790
791 TP_fast_assign(
792 LOCAL_ASSIGN;
793 __entry->timestamp = ch_switch->timestamp;
794 __entry->block_tx = ch_switch->block_tx;
795 __entry->freq = ch_switch->channel->center_freq;
796 __entry->count = ch_switch->count;
797 ),
798
799 TP_printk(
800 LOCAL_PR_FMT " new freq:%u count:%d",
801 LOCAL_PR_ARG, __entry->freq, __entry->count
802 )
803);
804
805/*
806 * Tracing for API calls that drivers call.
807 */
808
809TRACE_EVENT(api_start_tx_ba_session,
810 TP_PROTO(struct ieee80211_sta *sta, u16 tid),
811
812 TP_ARGS(sta, tid),
813
814 TP_STRUCT__entry(
815 STA_ENTRY
816 __field(u16, tid)
817 ),
818
819 TP_fast_assign(
820 STA_ASSIGN;
821 __entry->tid = tid;
822 ),
823
824 TP_printk(
825 STA_PR_FMT " tid:%d",
826 STA_PR_ARG, __entry->tid
827 )
828);
829
830TRACE_EVENT(api_start_tx_ba_cb,
831 TP_PROTO(struct ieee80211_sub_if_data *sdata, const u8 *ra, u16 tid),
832
833 TP_ARGS(sdata, ra, tid),
834
835 TP_STRUCT__entry(
836 VIF_ENTRY
837 __array(u8, ra, ETH_ALEN)
838 __field(u16, tid)
839 ),
840
841 TP_fast_assign(
842 VIF_ASSIGN;
843 memcpy(__entry->ra, ra, ETH_ALEN);
844 __entry->tid = tid;
845 ),
846
847 TP_printk(
848 VIF_PR_FMT " ra:%pM tid:%d",
849 VIF_PR_ARG, __entry->ra, __entry->tid
850 )
851);
852
853TRACE_EVENT(api_stop_tx_ba_session,
854 TP_PROTO(struct ieee80211_sta *sta, u16 tid, u16 initiator),
855
856 TP_ARGS(sta, tid, initiator),
857
858 TP_STRUCT__entry(
859 STA_ENTRY
860 __field(u16, tid)
861 __field(u16, initiator)
862 ),
863
864 TP_fast_assign(
865 STA_ASSIGN;
866 __entry->tid = tid;
867 __entry->initiator = initiator;
868 ),
869
870 TP_printk(
871 STA_PR_FMT " tid:%d initiator:%d",
872 STA_PR_ARG, __entry->tid, __entry->initiator
873 )
874);
875
876TRACE_EVENT(api_stop_tx_ba_cb,
877 TP_PROTO(struct ieee80211_sub_if_data *sdata, const u8 *ra, u16 tid),
878
879 TP_ARGS(sdata, ra, tid),
880
881 TP_STRUCT__entry(
882 VIF_ENTRY
883 __array(u8, ra, ETH_ALEN)
884 __field(u16, tid)
885 ),
886
887 TP_fast_assign(
888 VIF_ASSIGN;
889 memcpy(__entry->ra, ra, ETH_ALEN);
890 __entry->tid = tid;
891 ),
892
893 TP_printk(
894 VIF_PR_FMT " ra:%pM tid:%d",
895 VIF_PR_ARG, __entry->ra, __entry->tid
896 )
897);
898
899TRACE_EVENT(api_restart_hw,
900 TP_PROTO(struct ieee80211_local *local),
901
902 TP_ARGS(local),
903
904 TP_STRUCT__entry(
905 LOCAL_ENTRY
906 ),
907
908 TP_fast_assign(
909 LOCAL_ASSIGN;
910 ),
911
912 TP_printk(
913 LOCAL_PR_FMT,
914 LOCAL_PR_ARG
915 )
916);
917
918TRACE_EVENT(api_beacon_loss,
919 TP_PROTO(struct ieee80211_sub_if_data *sdata),
920
921 TP_ARGS(sdata),
922
923 TP_STRUCT__entry(
924 VIF_ENTRY
925 ),
926
927 TP_fast_assign(
928 VIF_ASSIGN;
929 ),
930
931 TP_printk(
932 VIF_PR_FMT,
933 VIF_PR_ARG
934 )
935);
936
937TRACE_EVENT(api_connection_loss,
938 TP_PROTO(struct ieee80211_sub_if_data *sdata),
939
940 TP_ARGS(sdata),
941
942 TP_STRUCT__entry(
943 VIF_ENTRY
944 ),
945
946 TP_fast_assign(
947 VIF_ASSIGN;
948 ),
949
950 TP_printk(
951 VIF_PR_FMT,
952 VIF_PR_ARG
953 )
954);
955
956TRACE_EVENT(api_cqm_rssi_notify,
957 TP_PROTO(struct ieee80211_sub_if_data *sdata,
958 enum nl80211_cqm_rssi_threshold_event rssi_event),
959
960 TP_ARGS(sdata, rssi_event),
961
962 TP_STRUCT__entry(
963 VIF_ENTRY
964 __field(u32, rssi_event)
965 ),
966
967 TP_fast_assign(
968 VIF_ASSIGN;
969 __entry->rssi_event = rssi_event;
970 ),
971
972 TP_printk(
973 VIF_PR_FMT " event:%d",
974 VIF_PR_ARG, __entry->rssi_event
975 )
976);
977
978TRACE_EVENT(api_scan_completed,
979 TP_PROTO(struct ieee80211_local *local, bool aborted),
980
981 TP_ARGS(local, aborted),
982
983 TP_STRUCT__entry(
984 LOCAL_ENTRY
985 __field(bool, aborted)
986 ),
987
988 TP_fast_assign(
989 LOCAL_ASSIGN;
990 __entry->aborted = aborted;
991 ),
992
993 TP_printk(
994 LOCAL_PR_FMT " aborted:%d",
995 LOCAL_PR_ARG, __entry->aborted
996 )
997);
998
999TRACE_EVENT(api_sta_block_awake,
1000 TP_PROTO(struct ieee80211_local *local,
1001 struct ieee80211_sta *sta, bool block),
1002
1003 TP_ARGS(local, sta, block),
1004
1005 TP_STRUCT__entry(
1006 LOCAL_ENTRY
1007 STA_ENTRY
1008 __field(bool, block)
1009 ),
1010
1011 TP_fast_assign(
1012 LOCAL_ASSIGN;
1013 STA_ASSIGN;
1014 __entry->block = block;
1015 ),
1016
1017 TP_printk(
1018 LOCAL_PR_FMT STA_PR_FMT " block:%d",
1019 LOCAL_PR_ARG, STA_PR_FMT, __entry->block
1020 )
1021);
1022
1023TRACE_EVENT(api_chswitch_done,
1024 TP_PROTO(struct ieee80211_sub_if_data *sdata, bool success),
1025
1026 TP_ARGS(sdata, success),
1027
1028 TP_STRUCT__entry(
1029 VIF_ENTRY
1030 __field(bool, success)
1031 ),
1032
1033 TP_fast_assign(
1034 VIF_ASSIGN;
1035 __entry->success = success;
1036 ),
1037
1038 TP_printk(
1039 VIF_PR_FMT " success=%d",
1040 VIF_PR_ARG, __entry->success
1041 )
1042);
1043
1044/*
1045 * Tracing for internal functions
1046 * (which may also be called in response to driver calls)
1047 */
1048
1049TRACE_EVENT(wake_queue,
1050 TP_PROTO(struct ieee80211_local *local, u16 queue,
1051 enum queue_stop_reason reason),
1052
1053 TP_ARGS(local, queue, reason),
1054
1055 TP_STRUCT__entry(
1056 LOCAL_ENTRY
1057 __field(u16, queue)
1058 __field(u32, reason)
1059 ),
1060
1061 TP_fast_assign(
1062 LOCAL_ASSIGN;
1063 __entry->queue = queue;
1064 __entry->reason = reason;
1065 ),
1066
1067 TP_printk(
1068 LOCAL_PR_FMT " queue:%d, reason:%d",
1069 LOCAL_PR_ARG, __entry->queue, __entry->reason
1070 )
1071);
1072
1073TRACE_EVENT(stop_queue,
1074 TP_PROTO(struct ieee80211_local *local, u16 queue,
1075 enum queue_stop_reason reason),
1076
1077 TP_ARGS(local, queue, reason),
1078
1079 TP_STRUCT__entry(
1080 LOCAL_ENTRY
1081 __field(u16, queue)
1082 __field(u32, reason)
1083 ),
1084
1085 TP_fast_assign(
1086 LOCAL_ASSIGN;
1087 __entry->queue = queue;
1088 __entry->reason = reason;
1089 ),
1090
1091 TP_printk(
1092 LOCAL_PR_FMT " queue:%d, reason:%d",
1093 LOCAL_PR_ARG, __entry->queue, __entry->reason
1094 )
1095);
769#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ 1096#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
770 1097
771#undef TRACE_INCLUDE_PATH 1098#undef TRACE_INCLUDE_PATH
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index bb677a73b7c9..2ab106a0a491 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -175,8 +175,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
175#endif /* CONFIG_MAC80211_HT_DEBUG */ 175#endif /* CONFIG_MAC80211_HT_DEBUG */
176 176
177 if (initiator == WLAN_BACK_INITIATOR) 177 if (initiator == WLAN_BACK_INITIATOR)
178 ieee80211_sta_stop_rx_ba_session(sdata, sta->sta.addr, tid, 178 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0);
179 WLAN_BACK_INITIATOR, 0);
180 else { /* WLAN_BACK_RECIPIENT */ 179 else { /* WLAN_BACK_RECIPIENT */
181 spin_lock_bh(&sta->lock); 180 spin_lock_bh(&sta->lock);
182 if (sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK) 181 if (sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index f3e942486749..b2cc1fda6cfd 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/slab.h>
16#include <linux/if_ether.h> 17#include <linux/if_ether.h>
17#include <linux/skbuff.h> 18#include <linux/skbuff.h>
18#include <linux/if_arp.h> 19#include <linux/if_arp.h>
@@ -91,12 +92,18 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
91 if (memcmp(ifibss->bssid, bssid, ETH_ALEN)) 92 if (memcmp(ifibss->bssid, bssid, ETH_ALEN))
92 sta_info_flush(sdata->local, sdata); 93 sta_info_flush(sdata->local, sdata);
93 94
95 /* if merging, indicate to driver that we leave the old IBSS */
96 if (sdata->vif.bss_conf.ibss_joined) {
97 sdata->vif.bss_conf.ibss_joined = false;
98 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS);
99 }
100
94 memcpy(ifibss->bssid, bssid, ETH_ALEN); 101 memcpy(ifibss->bssid, bssid, ETH_ALEN);
95 102
96 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; 103 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
97 104
98 local->oper_channel = chan; 105 local->oper_channel = chan;
99 local->oper_channel_type = NL80211_CHAN_NO_HT; 106 WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
100 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 107 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
101 108
102 sband = local->hw.wiphy->bands[chan->band]; 109 sband = local->hw.wiphy->bands[chan->band];
@@ -170,6 +177,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
170 bss_change |= BSS_CHANGED_BSSID; 177 bss_change |= BSS_CHANGED_BSSID;
171 bss_change |= BSS_CHANGED_BEACON; 178 bss_change |= BSS_CHANGED_BEACON;
172 bss_change |= BSS_CHANGED_BEACON_ENABLED; 179 bss_change |= BSS_CHANGED_BEACON_ENABLED;
180 bss_change |= BSS_CHANGED_IBSS;
181 sdata->vif.bss_conf.ibss_joined = true;
173 ieee80211_bss_info_change_notify(sdata, bss_change); 182 ieee80211_bss_info_change_notify(sdata, bss_change);
174 183
175 ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); 184 ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates);
@@ -264,17 +273,16 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
264 sta->sta.supp_rates[band] = supp_rates | 273 sta->sta.supp_rates[band] = supp_rates |
265 ieee80211_mandatory_rates(local, band); 274 ieee80211_mandatory_rates(local, band);
266 275
276 if (sta->sta.supp_rates[band] != prev_rates) {
267#ifdef CONFIG_MAC80211_IBSS_DEBUG 277#ifdef CONFIG_MAC80211_IBSS_DEBUG
268 if (sta->sta.supp_rates[band] != prev_rates)
269 printk(KERN_DEBUG "%s: updated supp_rates set " 278 printk(KERN_DEBUG "%s: updated supp_rates set "
270 "for %pM based on beacon info (0x%llx | " 279 "for %pM based on beacon/probe_response "
271 "0x%llx -> 0x%llx)\n", 280 "(0x%x -> 0x%x)\n",
272 sdata->name, 281 sdata->name, sta->sta.addr,
273 sta->sta.addr, 282 prev_rates, sta->sta.supp_rates[band]);
274 (unsigned long long) prev_rates,
275 (unsigned long long) supp_rates,
276 (unsigned long long) sta->sta.supp_rates[band]);
277#endif 283#endif
284 rate_control_rate_init(sta);
285 }
278 rcu_read_unlock(); 286 rcu_read_unlock();
279 } else { 287 } else {
280 rcu_read_unlock(); 288 rcu_read_unlock();
@@ -370,6 +378,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
370 sdata->name, mgmt->bssid); 378 sdata->name, mgmt->bssid);
371#endif 379#endif
372 ieee80211_sta_join_ibss(sdata, bss); 380 ieee80211_sta_join_ibss(sdata, bss);
381 supp_rates = ieee80211_sta_get_rates(local, elems, band);
373 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 382 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
374 supp_rates, GFP_KERNEL); 383 supp_rates, GFP_KERNEL);
375 } 384 }
@@ -480,7 +489,9 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
480 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " 489 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
481 "IBSS networks with same SSID (merge)\n", sdata->name); 490 "IBSS networks with same SSID (merge)\n", sdata->name);
482 491
483 ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len); 492 ieee80211_request_internal_scan(sdata,
493 ifibss->ssid, ifibss->ssid_len,
494 ifibss->fixed_channel ? ifibss->channel : NULL);
484} 495}
485 496
486static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) 497static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -587,8 +598,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
587 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " 598 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
588 "join\n", sdata->name); 599 "join\n", sdata->name);
589 600
590 ieee80211_request_internal_scan(sdata, ifibss->ssid, 601 ieee80211_request_internal_scan(sdata,
591 ifibss->ssid_len); 602 ifibss->ssid, ifibss->ssid_len,
603 ifibss->fixed_channel ? ifibss->channel : NULL);
592 } else { 604 } else {
593 int interval = IEEE80211_SCAN_INTERVAL; 605 int interval = IEEE80211_SCAN_INTERVAL;
594 606
@@ -896,6 +908,13 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
896 sdata->u.ibss.channel = params->channel; 908 sdata->u.ibss.channel = params->channel;
897 sdata->u.ibss.fixed_channel = params->channel_fixed; 909 sdata->u.ibss.fixed_channel = params->channel_fixed;
898 910
911 /* fix ourselves to that channel now already */
912 if (params->channel_fixed) {
913 sdata->local->oper_channel = params->channel;
914 WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata,
915 NL80211_CHAN_NO_HT));
916 }
917
899 if (params->ie) { 918 if (params->ie) {
900 sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, 919 sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len,
901 GFP_KERNEL); 920 GFP_KERNEL);
@@ -950,7 +969,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
950 kfree(sdata->u.ibss.ie); 969 kfree(sdata->u.ibss.ie);
951 skb = sdata->u.ibss.presp; 970 skb = sdata->u.ibss.presp;
952 rcu_assign_pointer(sdata->u.ibss.presp, NULL); 971 rcu_assign_pointer(sdata->u.ibss.presp, NULL);
953 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 972 sdata->vif.bss_conf.ibss_joined = false;
973 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
974 BSS_CHANGED_IBSS);
954 synchronize_rcu(); 975 synchronize_rcu();
955 kfree_skb(skb); 976 kfree_skb(skb);
956 977
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 241533e1bc03..1a9e2da37a93 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -317,6 +317,7 @@ enum ieee80211_sta_flags {
317 IEEE80211_STA_MFP_ENABLED = BIT(6), 317 IEEE80211_STA_MFP_ENABLED = BIT(6),
318 IEEE80211_STA_UAPSD_ENABLED = BIT(7), 318 IEEE80211_STA_UAPSD_ENABLED = BIT(7),
319 IEEE80211_STA_NULLFUNC_ACKED = BIT(8), 319 IEEE80211_STA_NULLFUNC_ACKED = BIT(8),
320 IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9),
320}; 321};
321 322
322struct ieee80211_if_managed { 323struct ieee80211_if_managed {
@@ -327,7 +328,7 @@ struct ieee80211_if_managed {
327 struct work_struct work; 328 struct work_struct work;
328 struct work_struct monitor_work; 329 struct work_struct monitor_work;
329 struct work_struct chswitch_work; 330 struct work_struct chswitch_work;
330 struct work_struct beacon_loss_work; 331 struct work_struct beacon_connection_loss_work;
331 332
332 unsigned long probe_timeout; 333 unsigned long probe_timeout;
333 int probe_send_count; 334 int probe_send_count;
@@ -359,6 +360,24 @@ struct ieee80211_if_managed {
359 int wmm_last_param_set; 360 int wmm_last_param_set;
360 361
361 u8 use_4addr; 362 u8 use_4addr;
363
364 /* Signal strength from the last Beacon frame in the current BSS. */
365 int last_beacon_signal;
366
367 /*
368 * Weighted average of the signal strength from Beacon frames in the
369 * current BSS. This is in units of 1/16 of the signal unit to maintain
370 * accuracy and to speed up calculations, i.e., the value need to be
371 * divided by 16 to get the actual value.
372 */
373 int ave_beacon_signal;
374
375 /*
376 * Last Beacon frame signal strength average (ave_beacon_signal / 16)
377 * that triggered a cqm event. 0 indicates that no event has been
378 * generated for the current association.
379 */
380 int last_cqm_event_signal;
362}; 381};
363 382
364enum ieee80211_ibss_request { 383enum ieee80211_ibss_request {
@@ -646,8 +665,7 @@ struct ieee80211_local {
646 struct work_struct recalc_smps; 665 struct work_struct recalc_smps;
647 666
648 /* aggregated multicast list */ 667 /* aggregated multicast list */
649 struct dev_addr_list *mc_list; 668 struct netdev_hw_addr_list mc_list;
650 int mc_count;
651 669
652 bool tim_in_locked_section; /* see ieee80211_beacon_get() */ 670 bool tim_in_locked_section; /* see ieee80211_beacon_get() */
653 671
@@ -745,10 +763,11 @@ struct ieee80211_local {
745 int scan_channel_idx; 763 int scan_channel_idx;
746 int scan_ies_len; 764 int scan_ies_len;
747 765
766 unsigned long leave_oper_channel_time;
748 enum mac80211_scan_state next_scan_state; 767 enum mac80211_scan_state next_scan_state;
749 struct delayed_work scan_work; 768 struct delayed_work scan_work;
750 struct ieee80211_sub_if_data *scan_sdata; 769 struct ieee80211_sub_if_data *scan_sdata;
751 enum nl80211_channel_type oper_channel_type; 770 enum nl80211_channel_type _oper_channel_type;
752 struct ieee80211_channel *oper_channel, *csa_channel; 771 struct ieee80211_channel *oper_channel, *csa_channel;
753 772
754 /* Temporary remain-on-channel for off-channel operations */ 773 /* Temporary remain-on-channel for off-channel operations */
@@ -979,7 +998,8 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
979 unsigned long data, void *dummy); 998 unsigned long data, void *dummy);
980void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, 999void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
981 struct ieee80211_channel_sw_ie *sw_elem, 1000 struct ieee80211_channel_sw_ie *sw_elem,
982 struct ieee80211_bss *bss); 1001 struct ieee80211_bss *bss,
1002 u64 timestamp);
983void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata); 1003void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata);
984void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); 1004void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
985 1005
@@ -1000,7 +1020,8 @@ void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata);
1000/* scan/BSS handling */ 1020/* scan/BSS handling */
1001void ieee80211_scan_work(struct work_struct *work); 1021void ieee80211_scan_work(struct work_struct *work);
1002int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, 1022int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
1003 const u8 *ssid, u8 ssid_len); 1023 const u8 *ssid, u8 ssid_len,
1024 struct ieee80211_channel *chan);
1004int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 1025int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
1005 struct cfg80211_scan_request *req); 1026 struct cfg80211_scan_request *req);
1006void ieee80211_scan_cancel(struct ieee80211_local *local); 1027void ieee80211_scan_cancel(struct ieee80211_local *local);
@@ -1078,8 +1099,6 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
1078 enum ieee80211_smps_mode smps, const u8 *da, 1099 enum ieee80211_smps_mode smps, const u8 *da,
1079 const u8 *bssid); 1100 const u8 *bssid);
1080 1101
1081void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da,
1082 u16 tid, u16 initiator, u16 reason);
1083void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 1102void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
1084 u16 initiator, u16 reason); 1103 u16 initiator, u16 reason);
1085void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); 1104void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta);
@@ -1155,7 +1174,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
1155 int powersave); 1174 int powersave);
1156void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1175void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1157 struct ieee80211_hdr *hdr); 1176 struct ieee80211_hdr *hdr);
1158void ieee80211_beacon_loss_work(struct work_struct *work); 1177void ieee80211_beacon_connection_loss_work(struct work_struct *work);
1159 1178
1160void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1179void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
1161 enum queue_stop_reason reason); 1180 enum queue_stop_reason reason);
@@ -1210,6 +1229,20 @@ int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1210int ieee80211_wk_cancel_remain_on_channel( 1229int ieee80211_wk_cancel_remain_on_channel(
1211 struct ieee80211_sub_if_data *sdata, u64 cookie); 1230 struct ieee80211_sub_if_data *sdata, u64 cookie);
1212 1231
1232/* channel management */
1233enum ieee80211_chan_mode {
1234 CHAN_MODE_UNDEFINED,
1235 CHAN_MODE_HOPPING,
1236 CHAN_MODE_FIXED,
1237};
1238
1239enum ieee80211_chan_mode
1240ieee80211_get_channel_mode(struct ieee80211_local *local,
1241 struct ieee80211_sub_if_data *ignore);
1242bool ieee80211_set_channel_type(struct ieee80211_local *local,
1243 struct ieee80211_sub_if_data *sdata,
1244 enum nl80211_channel_type chantype);
1245
1213#ifdef CONFIG_MAC80211_NOINLINE 1246#ifdef CONFIG_MAC80211_NOINLINE
1214#define debug_noinline noinline 1247#define debug_noinline noinline
1215#else 1248#else
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 0793d7a8d743..50deb017fd6e 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -10,6 +10,7 @@
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13#include <linux/slab.h>
13#include <linux/kernel.h> 14#include <linux/kernel.h>
14#include <linux/if_arp.h> 15#include <linux/if_arp.h>
15#include <linux/netdevice.h> 16#include <linux/netdevice.h>
@@ -412,8 +413,7 @@ static int ieee80211_stop(struct net_device *dev)
412 413
413 netif_addr_lock_bh(dev); 414 netif_addr_lock_bh(dev);
414 spin_lock_bh(&local->filter_lock); 415 spin_lock_bh(&local->filter_lock);
415 __dev_addr_unsync(&local->mc_list, &local->mc_count, 416 __hw_addr_unsync(&local->mc_list, &dev->mc, dev->addr_len);
416 &dev->mc_list, &dev->mc_count);
417 spin_unlock_bh(&local->filter_lock); 417 spin_unlock_bh(&local->filter_lock);
418 netif_addr_unlock_bh(dev); 418 netif_addr_unlock_bh(dev);
419 419
@@ -486,7 +486,7 @@ static int ieee80211_stop(struct net_device *dev)
486 cancel_work_sync(&sdata->u.mgd.work); 486 cancel_work_sync(&sdata->u.mgd.work);
487 cancel_work_sync(&sdata->u.mgd.chswitch_work); 487 cancel_work_sync(&sdata->u.mgd.chswitch_work);
488 cancel_work_sync(&sdata->u.mgd.monitor_work); 488 cancel_work_sync(&sdata->u.mgd.monitor_work);
489 cancel_work_sync(&sdata->u.mgd.beacon_loss_work); 489 cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work);
490 490
491 /* 491 /*
492 * When we get here, the interface is marked down. 492 * When we get here, the interface is marked down.
@@ -596,8 +596,7 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
596 sdata->flags ^= IEEE80211_SDATA_PROMISC; 596 sdata->flags ^= IEEE80211_SDATA_PROMISC;
597 } 597 }
598 spin_lock_bh(&local->filter_lock); 598 spin_lock_bh(&local->filter_lock);
599 __dev_addr_sync(&local->mc_list, &local->mc_count, 599 __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
600 &dev->mc_list, &dev->mc_count);
601 spin_unlock_bh(&local->filter_lock); 600 spin_unlock_bh(&local->filter_lock);
602 ieee80211_queue_work(&local->hw, &local->reconfig_filter); 601 ieee80211_queue_work(&local->hw, &local->reconfig_filter);
603} 602}
@@ -815,6 +814,118 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
815 return 0; 814 return 0;
816} 815}
817 816
817static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
818 struct net_device *dev,
819 enum nl80211_iftype type)
820{
821 struct ieee80211_sub_if_data *sdata;
822 u64 mask, start, addr, val, inc;
823 u8 *m;
824 u8 tmp_addr[ETH_ALEN];
825 int i;
826
827 /* default ... something at least */
828 memcpy(dev->perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
829
830 if (is_zero_ether_addr(local->hw.wiphy->addr_mask) &&
831 local->hw.wiphy->n_addresses <= 1)
832 return;
833
834
835 mutex_lock(&local->iflist_mtx);
836
837 switch (type) {
838 case NL80211_IFTYPE_MONITOR:
839 /* doesn't matter */
840 break;
841 case NL80211_IFTYPE_WDS:
842 case NL80211_IFTYPE_AP_VLAN:
843 /* match up with an AP interface */
844 list_for_each_entry(sdata, &local->interfaces, list) {
845 if (sdata->vif.type != NL80211_IFTYPE_AP)
846 continue;
847 memcpy(dev->perm_addr, sdata->vif.addr, ETH_ALEN);
848 break;
849 }
850 /* keep default if no AP interface present */
851 break;
852 default:
853 /* assign a new address if possible -- try n_addresses first */
854 for (i = 0; i < local->hw.wiphy->n_addresses; i++) {
855 bool used = false;
856
857 list_for_each_entry(sdata, &local->interfaces, list) {
858 if (memcmp(local->hw.wiphy->addresses[i].addr,
859 sdata->vif.addr, ETH_ALEN) == 0) {
860 used = true;
861 break;
862 }
863 }
864
865 if (!used) {
866 memcpy(dev->perm_addr,
867 local->hw.wiphy->addresses[i].addr,
868 ETH_ALEN);
869 break;
870 }
871 }
872
873 /* try mask if available */
874 if (is_zero_ether_addr(local->hw.wiphy->addr_mask))
875 break;
876
877 m = local->hw.wiphy->addr_mask;
878 mask = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
879 ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
880 ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
881
882 if (__ffs64(mask) + hweight64(mask) != fls64(mask)) {
883 /* not a contiguous mask ... not handled now! */
884 printk(KERN_DEBUG "not contiguous\n");
885 break;
886 }
887
888 m = local->hw.wiphy->perm_addr;
889 start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
890 ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
891 ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
892
893 inc = 1ULL<<__ffs64(mask);
894 val = (start & mask);
895 addr = (start & ~mask) | (val & mask);
896 do {
897 bool used = false;
898
899 tmp_addr[5] = addr >> 0*8;
900 tmp_addr[4] = addr >> 1*8;
901 tmp_addr[3] = addr >> 2*8;
902 tmp_addr[2] = addr >> 3*8;
903 tmp_addr[1] = addr >> 4*8;
904 tmp_addr[0] = addr >> 5*8;
905
906 val += inc;
907
908 list_for_each_entry(sdata, &local->interfaces, list) {
909 if (memcmp(tmp_addr, sdata->vif.addr,
910 ETH_ALEN) == 0) {
911 used = true;
912 break;
913 }
914 }
915
916 if (!used) {
917 memcpy(dev->perm_addr, tmp_addr, ETH_ALEN);
918 break;
919 }
920 addr = (start & ~mask) | (val & mask);
921 } while (addr != start);
922
923 break;
924 }
925
926 mutex_unlock(&local->iflist_mtx);
927}
928
818int ieee80211_if_add(struct ieee80211_local *local, const char *name, 929int ieee80211_if_add(struct ieee80211_local *local, const char *name,
819 struct net_device **new_dev, enum nl80211_iftype type, 930 struct net_device **new_dev, enum nl80211_iftype type,
820 struct vif_params *params) 931 struct vif_params *params)
@@ -844,8 +955,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
844 if (ret < 0) 955 if (ret < 0)
845 goto fail; 956 goto fail;
846 957
847 memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); 958 ieee80211_assign_perm_addr(local, ndev, type);
848 memcpy(ndev->perm_addr, ndev->dev_addr, ETH_ALEN); 959 memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN);
849 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); 960 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
850 961
851 /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ 962 /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 8160d9c5372e..8d4b41787dcf 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -14,6 +14,7 @@
14#include <linux/list.h> 14#include <linux/list.h>
15#include <linux/rcupdate.h> 15#include <linux/rcupdate.h>
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <linux/slab.h>
17#include <net/mac80211.h> 18#include <net/mac80211.h>
18#include "ieee80211_i.h" 19#include "ieee80211_i.h"
19#include "driver-ops.h" 20#include "driver-ops.h"
@@ -139,6 +140,7 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
139 struct ieee80211_sub_if_data, 140 struct ieee80211_sub_if_data,
140 u.ap); 141 u.ap);
141 142
143 key->conf.ap_addr = sdata->dev->dev_addr;
142 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); 144 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
143 145
144 if (!ret) { 146 if (!ret) {
diff --git a/net/mac80211/led.c b/net/mac80211/led.c
index 162a643f16b6..063aad944246 100644
--- a/net/mac80211/led.c
+++ b/net/mac80211/led.c
@@ -8,6 +8,7 @@
8 8
9/* just for IFNAMSIZ */ 9/* just for IFNAMSIZ */
10#include <linux/if.h> 10#include <linux/if.h>
11#include <linux/slab.h>
11#include "led.h" 12#include "led.h"
12 13
13void ieee80211_led_rx(struct ieee80211_local *local) 14void ieee80211_led_rx(struct ieee80211_local *local)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 06c33b68d8e5..22a384dfab65 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -71,7 +71,7 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
71 spin_lock_bh(&local->filter_lock); 71 spin_lock_bh(&local->filter_lock);
72 changed_flags = local->filter_flags ^ new_flags; 72 changed_flags = local->filter_flags ^ new_flags;
73 73
74 mc = drv_prepare_multicast(local, local->mc_count, local->mc_list); 74 mc = drv_prepare_multicast(local, &local->mc_list);
75 spin_unlock_bh(&local->filter_lock); 75 spin_unlock_bh(&local->filter_lock);
76 76
77 /* be a bit nasty */ 77 /* be a bit nasty */
@@ -111,7 +111,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
111 channel_type = local->tmp_channel_type; 111 channel_type = local->tmp_channel_type;
112 } else { 112 } else {
113 chan = local->oper_channel; 113 chan = local->oper_channel;
114 channel_type = local->oper_channel_type; 114 channel_type = local->_oper_channel_type;
115 } 115 }
116 116
117 if (chan != local->hw.conf.channel || 117 if (chan != local->hw.conf.channel ||
@@ -225,11 +225,11 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
225 switch (sdata->vif.type) { 225 switch (sdata->vif.type) {
226 case NL80211_IFTYPE_AP: 226 case NL80211_IFTYPE_AP:
227 sdata->vif.bss_conf.enable_beacon = 227 sdata->vif.bss_conf.enable_beacon =
228 !!rcu_dereference(sdata->u.ap.beacon); 228 !!sdata->u.ap.beacon;
229 break; 229 break;
230 case NL80211_IFTYPE_ADHOC: 230 case NL80211_IFTYPE_ADHOC:
231 sdata->vif.bss_conf.enable_beacon = 231 sdata->vif.bss_conf.enable_beacon =
232 !!rcu_dereference(sdata->u.ibss.presp); 232 !!sdata->u.ibss.presp;
233 break; 233 break;
234 case NL80211_IFTYPE_MESH_POINT: 234 case NL80211_IFTYPE_MESH_POINT:
235 sdata->vif.bss_conf.enable_beacon = true; 235 sdata->vif.bss_conf.enable_beacon = true;
@@ -309,6 +309,8 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
309{ 309{
310 struct ieee80211_local *local = hw_to_local(hw); 310 struct ieee80211_local *local = hw_to_local(hw);
311 311
312 trace_api_restart_hw(local);
313
312 /* use this reason, __ieee80211_resume will unblock it */ 314 /* use this reason, __ieee80211_resume will unblock it */
313 ieee80211_stop_queues_by_reason(hw, 315 ieee80211_stop_queues_by_reason(hw,
314 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 316 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
@@ -388,6 +390,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
388 local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; 390 local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
389 391
390 INIT_LIST_HEAD(&local->interfaces); 392 INIT_LIST_HEAD(&local->interfaces);
393
394 __hw_addr_init(&local->mc_list);
395
391 mutex_init(&local->iflist_mtx); 396 mutex_init(&local->iflist_mtx);
392 mutex_init(&local->scan_mtx); 397 mutex_init(&local->scan_mtx);
393 398
@@ -437,7 +442,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
437 struct ieee80211_local *local = hw_to_local(hw); 442 struct ieee80211_local *local = hw_to_local(hw);
438 int result; 443 int result;
439 enum ieee80211_band band; 444 enum ieee80211_band band;
440 int channels, i, j, max_bitrates; 445 int channels, max_bitrates;
441 bool supp_ht; 446 bool supp_ht;
442 static const u32 cipher_suites[] = { 447 static const u32 cipher_suites[] = {
443 WLAN_CIPHER_SUITE_WEP40, 448 WLAN_CIPHER_SUITE_WEP40,
@@ -567,6 +572,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
567 572
568 local->hw.conf.listen_interval = local->hw.max_listen_interval; 573 local->hw.conf.listen_interval = local->hw.max_listen_interval;
569 574
575 local->hw.conf.dynamic_ps_forced_timeout = -1;
576
570 result = sta_info_start(local); 577 result = sta_info_start(local);
571 if (result < 0) 578 if (result < 0)
572 goto fail_sta_info; 579 goto fail_sta_info;
@@ -601,21 +608,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
601 608
602 ieee80211_led_init(local); 609 ieee80211_led_init(local);
603 610
604 /* alloc internal scan request */
605 i = 0;
606 local->int_scan_req->ssids = &local->scan_ssid;
607 local->int_scan_req->n_ssids = 1;
608 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
609 if (!hw->wiphy->bands[band])
610 continue;
611 for (j = 0; j < hw->wiphy->bands[band]->n_channels; j++) {
612 local->int_scan_req->channels[i] =
613 &hw->wiphy->bands[band]->channels[j];
614 i++;
615 }
616 }
617 local->int_scan_req->n_channels = i;
618
619 local->network_latency_notifier.notifier_call = 611 local->network_latency_notifier.notifier_call =
620 ieee80211_max_network_latency; 612 ieee80211_max_network_latency;
621 result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY, 613 result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 61080c5fad50..bde81031727a 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -8,6 +8,7 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#include <linux/slab.h>
11#include <asm/unaligned.h> 12#include <asm/unaligned.h>
12#include "ieee80211_i.h" 13#include "ieee80211_i.h"
13#include "mesh.h" 14#include "mesh.h"
@@ -286,8 +287,6 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
286 *pos++ |= sdata->u.mesh.accepting_plinks ? 287 *pos++ |= sdata->u.mesh.accepting_plinks ?
287 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 288 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
288 *pos++ = 0x00; 289 *pos++ = 0x00;
289
290 return;
291} 290}
292 291
293u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl) 292u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl)
@@ -600,10 +599,10 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
600 struct ieee80211_rx_status *rx_status) 599 struct ieee80211_rx_status *rx_status)
601{ 600{
602 switch (mgmt->u.action.category) { 601 switch (mgmt->u.action.category) {
603 case MESH_PLINK_CATEGORY: 602 case WLAN_CATEGORY_MESH_PLINK:
604 mesh_rx_plink_frame(sdata, mgmt, len, rx_status); 603 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
605 break; 604 break;
606 case MESH_PATH_SEL_CATEGORY: 605 case WLAN_CATEGORY_MESH_PATH_SEL:
607 mesh_rx_path_sel_frame(sdata, mgmt, len); 606 mesh_rx_path_sel_frame(sdata, mgmt, len);
608 break; 607 break;
609 } 608 }
@@ -749,9 +748,6 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
749 748
750 switch (fc & IEEE80211_FCTL_STYPE) { 749 switch (fc & IEEE80211_FCTL_STYPE) {
751 case IEEE80211_STYPE_ACTION: 750 case IEEE80211_STYPE_ACTION:
752 if (skb->len < IEEE80211_MIN_ACTION_SIZE)
753 return RX_DROP_MONITOR;
754 /* fall through */
755 case IEEE80211_STYPE_PROBE_RESP: 751 case IEEE80211_STYPE_PROBE_RESP:
756 case IEEE80211_STYPE_BEACON: 752 case IEEE80211_STYPE_BEACON:
757 skb_queue_tail(&ifmsh->skb_queue, skb); 753 skb_queue_tail(&ifmsh->skb_queue, skb);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 85562c59d7d6..c88087f1cd0f 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -209,8 +209,6 @@ struct mesh_rmc {
209#define MESH_MAX_MPATHS 1024 209#define MESH_MAX_MPATHS 1024
210 210
211/* Pending ANA approval */ 211/* Pending ANA approval */
212#define MESH_PLINK_CATEGORY 30
213#define MESH_PATH_SEL_CATEGORY 32
214#define MESH_PATH_SEL_ACTION 0 212#define MESH_PATH_SEL_ACTION 0
215 213
216/* PERR reason codes */ 214/* PERR reason codes */
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index ce84237ebad3..0705018d8d1e 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -7,6 +7,7 @@
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 */ 8 */
9 9
10#include <linux/slab.h>
10#include "mesh.h" 11#include "mesh.h"
11 12
12#ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG 13#ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG
@@ -131,7 +132,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
131 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 132 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
132 /* BSSID == SA */ 133 /* BSSID == SA */
133 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 134 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
134 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; 135 mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL;
135 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; 136 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION;
136 137
137 switch (action) { 138 switch (action) {
@@ -224,7 +225,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
224 memcpy(mgmt->da, ra, ETH_ALEN); 225 memcpy(mgmt->da, ra, ETH_ALEN);
225 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 226 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
226 /* BSSID is left zeroed, wildcard value */ 227 /* BSSID is left zeroed, wildcard value */
227 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; 228 mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL;
228 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION; 229 mgmt->u.action.u.mesh_action.action_code = MESH_PATH_SEL_ACTION;
229 ie_len = 15; 230 ie_len = 15;
230 pos = skb_put(skb, 2 + ie_len); 231 pos = skb_put(skb, 2 + ie_len);
@@ -391,7 +392,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
391 if (SN_GT(mpath->sn, orig_sn) || 392 if (SN_GT(mpath->sn, orig_sn) ||
392 (mpath->sn == orig_sn && 393 (mpath->sn == orig_sn &&
393 action == MPATH_PREQ && 394 action == MPATH_PREQ &&
394 new_metric > mpath->metric)) { 395 new_metric >= mpath->metric)) {
395 process = false; 396 process = false;
396 fresh_info = false; 397 fresh_info = false;
397 } 398 }
@@ -611,7 +612,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
611 612
612 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, 613 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
613 cpu_to_le32(orig_sn), 0, target_addr, 614 cpu_to_le32(orig_sn), 0, target_addr,
614 cpu_to_le32(target_sn), mpath->next_hop->sta.addr, hopcount, 615 cpu_to_le32(target_sn), next_hop, hopcount,
615 ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), 616 ttl, cpu_to_le32(lifetime), cpu_to_le32(metric),
616 0, sdata); 617 0, sdata);
617 rcu_read_unlock(); 618 rcu_read_unlock();
@@ -623,7 +624,6 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
623fail: 624fail:
624 rcu_read_unlock(); 625 rcu_read_unlock();
625 sdata->u.mesh.mshstats.dropped_frames_no_route++; 626 sdata->u.mesh.mshstats.dropped_frames_no_route++;
626 return;
627} 627}
628 628
629static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, 629static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 2312efe04c62..181ffd6efd81 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -10,6 +10,7 @@
10#include <linux/etherdevice.h> 10#include <linux/etherdevice.h>
11#include <linux/list.h> 11#include <linux/list.h>
12#include <linux/random.h> 12#include <linux/random.h>
13#include <linux/slab.h>
13#include <linux/spinlock.h> 14#include <linux/spinlock.h>
14#include <linux/string.h> 15#include <linux/string.h>
15#include <net/mac80211.h> 16#include <net/mac80211.h>
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 1a29c4a8139e..3cd5f7b5d693 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -6,6 +6,7 @@
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 */ 8 */
9#include <linux/gfp.h>
9#include <linux/kernel.h> 10#include <linux/kernel.h>
10#include <linux/random.h> 11#include <linux/random.h>
11#include "ieee80211_i.h" 12#include "ieee80211_i.h"
@@ -171,7 +172,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
171 memcpy(mgmt->da, da, ETH_ALEN); 172 memcpy(mgmt->da, da, ETH_ALEN);
172 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 173 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
173 /* BSSID is left zeroed, wildcard value */ 174 /* BSSID is left zeroed, wildcard value */
174 mgmt->u.action.category = MESH_PLINK_CATEGORY; 175 mgmt->u.action.category = WLAN_CATEGORY_MESH_PLINK;
175 mgmt->u.action.u.plink_action.action_code = action; 176 mgmt->u.action.u.plink_action.action_code = action;
176 177
177 if (action == PLINK_CLOSE) 178 if (action == PLINK_CLOSE)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index be5f723d643a..0839c4e8fd2e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -19,6 +19,7 @@
19#include <linux/rtnetlink.h> 19#include <linux/rtnetlink.h>
20#include <linux/pm_qos_params.h> 20#include <linux/pm_qos_params.h>
21#include <linux/crc32.h> 21#include <linux/crc32.h>
22#include <linux/slab.h>
22#include <net/mac80211.h> 23#include <net/mac80211.h>
23#include <asm/unaligned.h> 24#include <asm/unaligned.h>
24 25
@@ -46,6 +47,13 @@
46 */ 47 */
47#define IEEE80211_PROBE_WAIT (HZ / 2) 48#define IEEE80211_PROBE_WAIT (HZ / 2)
48 49
50/*
51 * Weight given to the latest Beacon frame when calculating average signal
52 * strength for Beacon frames received in the current BSS. This must be
53 * between 1 and 15.
54 */
55#define IEEE80211_SIGNAL_AVE_WEIGHT 3
56
49#define TMR_RUNNING_TIMER 0 57#define TMR_RUNNING_TIMER 0
50#define TMR_RUNNING_CHANSW 1 58#define TMR_RUNNING_CHANSW 1
51 59
@@ -129,11 +137,14 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
129 struct sta_info *sta; 137 struct sta_info *sta;
130 u32 changed = 0; 138 u32 changed = 0;
131 u16 ht_opmode; 139 u16 ht_opmode;
132 bool enable_ht = true, ht_changed; 140 bool enable_ht = true;
141 enum nl80211_channel_type prev_chantype;
133 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 142 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
134 143
135 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 144 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
136 145
146 prev_chantype = sdata->vif.bss_conf.channel_type;
147
137 /* HT is not supported */ 148 /* HT is not supported */
138 if (!sband->ht_cap.ht_supported) 149 if (!sband->ht_cap.ht_supported)
139 enable_ht = false; 150 enable_ht = false;
@@ -164,36 +175,37 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
164 } 175 }
165 } 176 }
166 177
167 ht_changed = conf_is_ht(&local->hw.conf) != enable_ht || 178 if (local->tmp_channel)
168 channel_type != local->hw.conf.channel_type; 179 local->tmp_channel_type = channel_type;
169 180
170 local->oper_channel_type = channel_type; 181 if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
182 /* can only fail due to HT40+/- mismatch */
183 channel_type = NL80211_CHAN_HT20;
184 WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
185 }
171 186
172 if (ht_changed) { 187 /* channel_type change automatically detected */
173 /* channel_type change automatically detected */ 188 ieee80211_hw_config(local, 0);
174 ieee80211_hw_config(local, 0);
175 189
190 if (prev_chantype != channel_type) {
176 rcu_read_lock(); 191 rcu_read_lock();
177 sta = sta_info_get(sdata, bssid); 192 sta = sta_info_get(sdata, bssid);
178 if (sta) 193 if (sta)
179 rate_control_rate_update(local, sband, sta, 194 rate_control_rate_update(local, sband, sta,
180 IEEE80211_RC_HT_CHANGED, 195 IEEE80211_RC_HT_CHANGED,
181 local->oper_channel_type); 196 channel_type);
182 rcu_read_unlock(); 197 rcu_read_unlock();
183 } 198 }
184
185 /* disable HT */
186 if (!enable_ht)
187 return 0;
188 199
189 ht_opmode = le16_to_cpu(hti->operation_mode); 200 ht_opmode = le16_to_cpu(hti->operation_mode);
190 201
191 /* if bss configuration changed store the new one */ 202 /* if bss configuration changed store the new one */
192 if (!sdata->ht_opmode_valid || 203 if (sdata->ht_opmode_valid != enable_ht ||
193 sdata->vif.bss_conf.ht_operation_mode != ht_opmode) { 204 sdata->vif.bss_conf.ht_operation_mode != ht_opmode ||
205 prev_chantype != channel_type) {
194 changed |= BSS_CHANGED_HT; 206 changed |= BSS_CHANGED_HT;
195 sdata->vif.bss_conf.ht_operation_mode = ht_opmode; 207 sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
196 sdata->ht_opmode_valid = true; 208 sdata->ht_opmode_valid = enable_ht;
197 } 209 }
198 210
199 return changed; 211 return changed;
@@ -203,7 +215,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
203 215
204static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, 216static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
205 const u8 *bssid, u16 stype, u16 reason, 217 const u8 *bssid, u16 stype, u16 reason,
206 void *cookie) 218 void *cookie, bool send_frame)
207{ 219{
208 struct ieee80211_local *local = sdata->local; 220 struct ieee80211_local *local = sdata->local;
209 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 221 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -240,7 +252,11 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
240 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); 252 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
241 if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) 253 if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
242 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 254 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
243 ieee80211_tx_skb(sdata, skb); 255
256 if (send_frame)
257 ieee80211_tx_skb(sdata, skb);
258 else
259 kfree_skb(skb);
244} 260}
245 261
246void ieee80211_send_pspoll(struct ieee80211_local *local, 262void ieee80211_send_pspoll(struct ieee80211_local *local,
@@ -326,7 +342,11 @@ static void ieee80211_chswitch_work(struct work_struct *work)
326 goto out; 342 goto out;
327 343
328 sdata->local->oper_channel = sdata->local->csa_channel; 344 sdata->local->oper_channel = sdata->local->csa_channel;
329 ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL); 345 if (!sdata->local->ops->channel_switch) {
346 /* call "hw_config" only if doing sw channel switch */
347 ieee80211_hw_config(sdata->local,
348 IEEE80211_CONF_CHANGE_CHANNEL);
349 }
330 350
331 /* XXX: shouldn't really modify cfg80211-owned data! */ 351 /* XXX: shouldn't really modify cfg80211-owned data! */
332 ifmgd->associated->channel = sdata->local->oper_channel; 352 ifmgd->associated->channel = sdata->local->oper_channel;
@@ -338,6 +358,29 @@ static void ieee80211_chswitch_work(struct work_struct *work)
338 mutex_unlock(&ifmgd->mtx); 358 mutex_unlock(&ifmgd->mtx);
339} 359}
340 360
361void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
362{
363 struct ieee80211_sub_if_data *sdata;
364 struct ieee80211_if_managed *ifmgd;
365
366 sdata = vif_to_sdata(vif);
367 ifmgd = &sdata->u.mgd;
368
369 trace_api_chswitch_done(sdata, success);
370 if (!success) {
371 /*
372 * If the channel switch was not successful, stay
373 * around on the old channel. We currently lack
374 * good handling of this situation, possibly we
375 * should just drop the association.
376 */
377 sdata->local->csa_channel = sdata->local->oper_channel;
378 }
379
380 ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
381}
382EXPORT_SYMBOL(ieee80211_chswitch_done);
383
341static void ieee80211_chswitch_timer(unsigned long data) 384static void ieee80211_chswitch_timer(unsigned long data)
342{ 385{
343 struct ieee80211_sub_if_data *sdata = 386 struct ieee80211_sub_if_data *sdata =
@@ -354,7 +397,8 @@ static void ieee80211_chswitch_timer(unsigned long data)
354 397
355void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, 398void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
356 struct ieee80211_channel_sw_ie *sw_elem, 399 struct ieee80211_channel_sw_ie *sw_elem,
357 struct ieee80211_bss *bss) 400 struct ieee80211_bss *bss,
401 u64 timestamp)
358{ 402{
359 struct cfg80211_bss *cbss = 403 struct cfg80211_bss *cbss =
360 container_of((void *)bss, struct cfg80211_bss, priv); 404 container_of((void *)bss, struct cfg80211_bss, priv);
@@ -382,10 +426,29 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
382 426
383 sdata->local->csa_channel = new_ch; 427 sdata->local->csa_channel = new_ch;
384 428
429 if (sdata->local->ops->channel_switch) {
430 /* use driver's channel switch callback */
431 struct ieee80211_channel_switch ch_switch;
432 memset(&ch_switch, 0, sizeof(ch_switch));
433 ch_switch.timestamp = timestamp;
434 if (sw_elem->mode) {
435 ch_switch.block_tx = true;
436 ieee80211_stop_queues_by_reason(&sdata->local->hw,
437 IEEE80211_QUEUE_STOP_REASON_CSA);
438 }
439 ch_switch.channel = new_ch;
440 ch_switch.count = sw_elem->count;
441 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
442 drv_channel_switch(sdata->local, &ch_switch);
443 return;
444 }
445
446 /* channel switch handled in software */
385 if (sw_elem->count <= 1) { 447 if (sw_elem->count <= 1) {
386 ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work); 448 ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
387 } else { 449 } else {
388 ieee80211_stop_queues_by_reason(&sdata->local->hw, 450 if (sw_elem->mode)
451 ieee80211_stop_queues_by_reason(&sdata->local->hw,
389 IEEE80211_QUEUE_STOP_REASON_CSA); 452 IEEE80211_QUEUE_STOP_REASON_CSA);
390 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; 453 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
391 mod_timer(&ifmgd->chswitch_timer, 454 mod_timer(&ifmgd->chswitch_timer,
@@ -464,6 +527,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
464{ 527{
465 struct ieee80211_sub_if_data *sdata, *found = NULL; 528 struct ieee80211_sub_if_data *sdata, *found = NULL;
466 int count = 0; 529 int count = 0;
530 int timeout;
467 531
468 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) { 532 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) {
469 local->ps_sdata = NULL; 533 local->ps_sdata = NULL;
@@ -492,11 +556,31 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
492 s32 beaconint_us; 556 s32 beaconint_us;
493 557
494 if (latency < 0) 558 if (latency < 0)
495 latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY); 559 latency = pm_qos_request(PM_QOS_NETWORK_LATENCY);
496 560
497 beaconint_us = ieee80211_tu_to_usec( 561 beaconint_us = ieee80211_tu_to_usec(
498 found->vif.bss_conf.beacon_int); 562 found->vif.bss_conf.beacon_int);
499 563
564 timeout = local->hw.conf.dynamic_ps_forced_timeout;
565 if (timeout < 0) {
566 /*
567 * The 2 second value is there for compatibility until
568 * the PM_QOS_NETWORK_LATENCY is configured with real
569 * values.
570 */
571 if (latency == 2000000000)
572 timeout = 100;
573 else if (latency <= 50000)
574 timeout = 300;
575 else if (latency <= 100000)
576 timeout = 100;
577 else if (latency <= 500000)
578 timeout = 50;
579 else
580 timeout = 0;
581 }
582 local->hw.conf.dynamic_ps_timeout = timeout;
583
500 if (beaconint_us > latency) { 584 if (beaconint_us > latency) {
501 local->ps_sdata = NULL; 585 local->ps_sdata = NULL;
502 } else { 586 } else {
@@ -589,6 +673,9 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
589 int count; 673 int count;
590 u8 *pos, uapsd_queues = 0; 674 u8 *pos, uapsd_queues = 0;
591 675
676 if (!local->ops->conf_tx)
677 return;
678
592 if (local->hw.queues < 4) 679 if (local->hw.queues < 4)
593 return; 680 return;
594 681
@@ -663,11 +750,15 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
663 params.aifs, params.cw_min, params.cw_max, params.txop, 750 params.aifs, params.cw_min, params.cw_max, params.txop,
664 params.uapsd); 751 params.uapsd);
665#endif 752#endif
666 if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx) 753 if (drv_conf_tx(local, queue, &params))
667 printk(KERN_DEBUG "%s: failed to set TX queue " 754 printk(KERN_DEBUG "%s: failed to set TX queue "
668 "parameters for queue %d\n", 755 "parameters for queue %d\n",
669 wiphy_name(local->hw.wiphy), queue); 756 wiphy_name(local->hw.wiphy), queue);
670 } 757 }
758
759 /* enable WMM or activate new settings */
760 local->hw.conf.flags |= IEEE80211_CONF_QOS;
761 drv_config(local, IEEE80211_CONF_CHANGE_QOS);
671} 762}
672 763
673static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, 764static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
@@ -728,6 +819,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
728 sdata->u.mgd.associated = cbss; 819 sdata->u.mgd.associated = cbss;
729 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN); 820 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
730 821
822 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
823
731 /* just to be sure */ 824 /* just to be sure */
732 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | 825 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
733 IEEE80211_STA_BEACON_POLL); 826 IEEE80211_STA_BEACON_POLL);
@@ -753,6 +846,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
753 /* And the BSSID changed - we're associated now */ 846 /* And the BSSID changed - we're associated now */
754 bss_info_changed |= BSS_CHANGED_BSSID; 847 bss_info_changed |= BSS_CHANGED_BSSID;
755 848
849 /* Tell the driver to monitor connection quality (if supported) */
850 if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) &&
851 sdata->vif.bss_conf.cqm_rssi_thold)
852 bss_info_changed |= BSS_CHANGED_CQM;
853
756 ieee80211_bss_info_change_notify(sdata, bss_info_changed); 854 ieee80211_bss_info_change_notify(sdata, bss_info_changed);
757 855
758 mutex_lock(&local->iflist_mtx); 856 mutex_lock(&local->iflist_mtx);
@@ -764,7 +862,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
764 netif_carrier_on(sdata->dev); 862 netif_carrier_on(sdata->dev);
765} 863}
766 864
767static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata) 865static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
866 bool remove_sta)
768{ 867{
769 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 868 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
770 struct ieee80211_local *local = sdata->local; 869 struct ieee80211_local *local = sdata->local;
@@ -816,7 +915,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
816 ieee80211_set_wmm_default(sdata); 915 ieee80211_set_wmm_default(sdata);
817 916
818 /* channel(_type) changes are handled by ieee80211_hw_config */ 917 /* channel(_type) changes are handled by ieee80211_hw_config */
819 local->oper_channel_type = NL80211_CHAN_NO_HT; 918 WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
820 919
821 /* on the next assoc, re-program HT parameters */ 920 /* on the next assoc, re-program HT parameters */
822 sdata->ht_opmode_valid = false; 921 sdata->ht_opmode_valid = false;
@@ -833,11 +932,12 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
833 932
834 ieee80211_hw_config(local, config_changed); 933 ieee80211_hw_config(local, config_changed);
835 934
836 /* And the BSSID changed -- not very interesting here */ 935 /* The BSSID (not really interesting) and HT changed */
837 changed |= BSS_CHANGED_BSSID; 936 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
838 ieee80211_bss_info_change_notify(sdata, changed); 937 ieee80211_bss_info_change_notify(sdata, changed);
839 938
840 sta_info_destroy_addr(sdata, bssid); 939 if (remove_sta)
940 sta_info_destroy_addr(sdata, bssid);
841} 941}
842 942
843void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 943void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -854,6 +954,9 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
854 if (is_multicast_ether_addr(hdr->addr1)) 954 if (is_multicast_ether_addr(hdr->addr1))
855 return; 955 return;
856 956
957 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
958 return;
959
857 mod_timer(&sdata->u.mgd.conn_mon_timer, 960 mod_timer(&sdata->u.mgd.conn_mon_timer,
858 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); 961 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
859} 962}
@@ -931,23 +1034,72 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
931 mutex_unlock(&ifmgd->mtx); 1034 mutex_unlock(&ifmgd->mtx);
932} 1035}
933 1036
934void ieee80211_beacon_loss_work(struct work_struct *work) 1037static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
1038{
1039 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1040 struct ieee80211_local *local = sdata->local;
1041 u8 bssid[ETH_ALEN];
1042
1043 mutex_lock(&ifmgd->mtx);
1044 if (!ifmgd->associated) {
1045 mutex_unlock(&ifmgd->mtx);
1046 return;
1047 }
1048
1049 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
1050
1051 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
1052
1053 ieee80211_set_disassoc(sdata, true);
1054 ieee80211_recalc_idle(local);
1055 mutex_unlock(&ifmgd->mtx);
1056 /*
1057 * must be outside lock due to cfg80211,
1058 * but that's not a problem.
1059 */
1060 ieee80211_send_deauth_disassoc(sdata, bssid,
1061 IEEE80211_STYPE_DEAUTH,
1062 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
1063 NULL, true);
1064}
1065
1066void ieee80211_beacon_connection_loss_work(struct work_struct *work)
935{ 1067{
936 struct ieee80211_sub_if_data *sdata = 1068 struct ieee80211_sub_if_data *sdata =
937 container_of(work, struct ieee80211_sub_if_data, 1069 container_of(work, struct ieee80211_sub_if_data,
938 u.mgd.beacon_loss_work); 1070 u.mgd.beacon_connection_loss_work);
939 1071
940 ieee80211_mgd_probe_ap(sdata, true); 1072 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
1073 __ieee80211_connection_loss(sdata);
1074 else
1075 ieee80211_mgd_probe_ap(sdata, true);
941} 1076}
942 1077
943void ieee80211_beacon_loss(struct ieee80211_vif *vif) 1078void ieee80211_beacon_loss(struct ieee80211_vif *vif)
944{ 1079{
945 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 1080 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1081 struct ieee80211_hw *hw = &sdata->local->hw;
1082
1083 trace_api_beacon_loss(sdata);
946 1084
947 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); 1085 WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR);
1086 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
948} 1087}
949EXPORT_SYMBOL(ieee80211_beacon_loss); 1088EXPORT_SYMBOL(ieee80211_beacon_loss);
950 1089
1090void ieee80211_connection_loss(struct ieee80211_vif *vif)
1091{
1092 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1093 struct ieee80211_hw *hw = &sdata->local->hw;
1094
1095 trace_api_connection_loss(sdata);
1096
1097 WARN_ON(!(hw->flags & IEEE80211_HW_CONNECTION_MONITOR));
1098 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
1099}
1100EXPORT_SYMBOL(ieee80211_connection_loss);
1101
1102
951static enum rx_mgmt_action __must_check 1103static enum rx_mgmt_action __must_check
952ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 1104ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
953 struct ieee80211_mgmt *mgmt, size_t len) 1105 struct ieee80211_mgmt *mgmt, size_t len)
@@ -968,7 +1120,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
968 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", 1120 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
969 sdata->name, bssid, reason_code); 1121 sdata->name, bssid, reason_code);
970 1122
971 ieee80211_set_disassoc(sdata); 1123 ieee80211_set_disassoc(sdata, true);
972 ieee80211_recalc_idle(sdata->local); 1124 ieee80211_recalc_idle(sdata->local);
973 1125
974 return RX_MGMT_CFG80211_DEAUTH; 1126 return RX_MGMT_CFG80211_DEAUTH;
@@ -998,7 +1150,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
998 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", 1150 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
999 sdata->name, mgmt->sa, reason_code); 1151 sdata->name, mgmt->sa, reason_code);
1000 1152
1001 ieee80211_set_disassoc(sdata); 1153 ieee80211_set_disassoc(sdata, true);
1002 ieee80211_recalc_idle(sdata->local); 1154 ieee80211_recalc_idle(sdata->local);
1003 return RX_MGMT_CFG80211_DISASSOC; 1155 return RX_MGMT_CFG80211_DISASSOC;
1004} 1156}
@@ -1212,7 +1364,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1212 ETH_ALEN) == 0)) { 1364 ETH_ALEN) == 0)) {
1213 struct ieee80211_channel_sw_ie *sw_elem = 1365 struct ieee80211_channel_sw_ie *sw_elem =
1214 (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem; 1366 (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem;
1215 ieee80211_sta_process_chanswitch(sdata, sw_elem, bss); 1367 ieee80211_sta_process_chanswitch(sdata, sw_elem,
1368 bss, rx_status->mactime);
1216 } 1369 }
1217} 1370}
1218 1371
@@ -1251,12 +1404,17 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1251 mutex_lock(&sdata->local->iflist_mtx); 1404 mutex_lock(&sdata->local->iflist_mtx);
1252 ieee80211_recalc_ps(sdata->local, -1); 1405 ieee80211_recalc_ps(sdata->local, -1);
1253 mutex_unlock(&sdata->local->iflist_mtx); 1406 mutex_unlock(&sdata->local->iflist_mtx);
1407
1408 if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
1409 return;
1410
1254 /* 1411 /*
1255 * We've received a probe response, but are not sure whether 1412 * We've received a probe response, but are not sure whether
1256 * we have or will be receiving any beacons or data, so let's 1413 * we have or will be receiving any beacons or data, so let's
1257 * schedule the timers again, just in case. 1414 * schedule the timers again, just in case.
1258 */ 1415 */
1259 mod_beacon_timer(sdata); 1416 mod_beacon_timer(sdata);
1417
1260 mod_timer(&ifmgd->conn_mon_timer, 1418 mod_timer(&ifmgd->conn_mon_timer,
1261 round_jiffies_up(jiffies + 1419 round_jiffies_up(jiffies +
1262 IEEE80211_CONNECTION_IDLE_TIME)); 1420 IEEE80211_CONNECTION_IDLE_TIME));
@@ -1290,6 +1448,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1290 struct ieee80211_rx_status *rx_status) 1448 struct ieee80211_rx_status *rx_status)
1291{ 1449{
1292 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1450 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1451 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
1293 size_t baselen; 1452 size_t baselen;
1294 struct ieee802_11_elems elems; 1453 struct ieee802_11_elems elems;
1295 struct ieee80211_local *local = sdata->local; 1454 struct ieee80211_local *local = sdata->local;
@@ -1325,6 +1484,41 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1325 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0) 1484 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
1326 return; 1485 return;
1327 1486
1487 /* Track average RSSI from the Beacon frames of the current AP */
1488 ifmgd->last_beacon_signal = rx_status->signal;
1489 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
1490 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
1491 ifmgd->ave_beacon_signal = rx_status->signal;
1492 ifmgd->last_cqm_event_signal = 0;
1493 } else {
1494 ifmgd->ave_beacon_signal =
1495 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
1496 (16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
1497 ifmgd->ave_beacon_signal) / 16;
1498 }
1499 if (bss_conf->cqm_rssi_thold &&
1500 !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
1501 int sig = ifmgd->ave_beacon_signal / 16;
1502 int last_event = ifmgd->last_cqm_event_signal;
1503 int thold = bss_conf->cqm_rssi_thold;
1504 int hyst = bss_conf->cqm_rssi_hyst;
1505 if (sig < thold &&
1506 (last_event == 0 || sig < last_event - hyst)) {
1507 ifmgd->last_cqm_event_signal = sig;
1508 ieee80211_cqm_rssi_notify(
1509 &sdata->vif,
1510 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
1511 GFP_KERNEL);
1512 } else if (sig > thold &&
1513 (last_event == 0 || sig > last_event + hyst)) {
1514 ifmgd->last_cqm_event_signal = sig;
1515 ieee80211_cqm_rssi_notify(
1516 &sdata->vif,
1517 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
1518 GFP_KERNEL);
1519 }
1520 }
1521
1328 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { 1522 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
1329#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1523#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1330 if (net_ratelimit()) { 1524 if (net_ratelimit()) {
@@ -1503,7 +1697,8 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1503 1697
1504 ieee80211_sta_process_chanswitch(sdata, 1698 ieee80211_sta_process_chanswitch(sdata,
1505 &mgmt->u.action.u.chan_switch.sw_elem, 1699 &mgmt->u.action.u.chan_switch.sw_elem,
1506 (void *)ifmgd->associated->priv); 1700 (void *)ifmgd->associated->priv,
1701 rx_status->mactime);
1507 break; 1702 break;
1508 } 1703 }
1509 mutex_unlock(&ifmgd->mtx); 1704 mutex_unlock(&ifmgd->mtx);
@@ -1610,7 +1805,7 @@ static void ieee80211_sta_work(struct work_struct *work)
1610 printk(KERN_DEBUG "No probe response from AP %pM" 1805 printk(KERN_DEBUG "No probe response from AP %pM"
1611 " after %dms, disconnecting.\n", 1806 " after %dms, disconnecting.\n",
1612 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 1807 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
1613 ieee80211_set_disassoc(sdata); 1808 ieee80211_set_disassoc(sdata, true);
1614 ieee80211_recalc_idle(local); 1809 ieee80211_recalc_idle(local);
1615 mutex_unlock(&ifmgd->mtx); 1810 mutex_unlock(&ifmgd->mtx);
1616 /* 1811 /*
@@ -1620,7 +1815,7 @@ static void ieee80211_sta_work(struct work_struct *work)
1620 ieee80211_send_deauth_disassoc(sdata, bssid, 1815 ieee80211_send_deauth_disassoc(sdata, bssid,
1621 IEEE80211_STYPE_DEAUTH, 1816 IEEE80211_STYPE_DEAUTH,
1622 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, 1817 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
1623 NULL); 1818 NULL, true);
1624 mutex_lock(&ifmgd->mtx); 1819 mutex_lock(&ifmgd->mtx);
1625 } 1820 }
1626 } 1821 }
@@ -1637,7 +1832,8 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data)
1637 if (local->quiescing) 1832 if (local->quiescing)
1638 return; 1833 return;
1639 1834
1640 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); 1835 ieee80211_queue_work(&sdata->local->hw,
1836 &sdata->u.mgd.beacon_connection_loss_work);
1641} 1837}
1642 1838
1643static void ieee80211_sta_conn_mon_timer(unsigned long data) 1839static void ieee80211_sta_conn_mon_timer(unsigned long data)
@@ -1689,7 +1885,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
1689 */ 1885 */
1690 1886
1691 cancel_work_sync(&ifmgd->work); 1887 cancel_work_sync(&ifmgd->work);
1692 cancel_work_sync(&ifmgd->beacon_loss_work); 1888 cancel_work_sync(&ifmgd->beacon_connection_loss_work);
1693 if (del_timer_sync(&ifmgd->timer)) 1889 if (del_timer_sync(&ifmgd->timer))
1694 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); 1890 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
1695 1891
@@ -1723,7 +1919,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1723 INIT_WORK(&ifmgd->work, ieee80211_sta_work); 1919 INIT_WORK(&ifmgd->work, ieee80211_sta_work);
1724 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); 1920 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
1725 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); 1921 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
1726 INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work); 1922 INIT_WORK(&ifmgd->beacon_connection_loss_work,
1923 ieee80211_beacon_connection_loss_work);
1727 setup_timer(&ifmgd->timer, ieee80211_sta_timer, 1924 setup_timer(&ifmgd->timer, ieee80211_sta_timer,
1728 (unsigned long) sdata); 1925 (unsigned long) sdata);
1729 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, 1926 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
@@ -1802,6 +1999,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
1802 struct ieee80211_work *wk; 1999 struct ieee80211_work *wk;
1803 u16 auth_alg; 2000 u16 auth_alg;
1804 2001
2002 if (req->local_state_change)
2003 return 0; /* no need to update mac80211 state */
2004
1805 switch (req->auth_type) { 2005 switch (req->auth_type) {
1806 case NL80211_AUTHTYPE_OPEN_SYSTEM: 2006 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1807 auth_alg = WLAN_AUTH_OPEN; 2007 auth_alg = WLAN_AUTH_OPEN;
@@ -1910,7 +2110,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
1910 } 2110 }
1911 2111
1912 /* Trying to reassociate - clear previous association state */ 2112 /* Trying to reassociate - clear previous association state */
1913 ieee80211_set_disassoc(sdata); 2113 ieee80211_set_disassoc(sdata, true);
1914 } 2114 }
1915 mutex_unlock(&ifmgd->mtx); 2115 mutex_unlock(&ifmgd->mtx);
1916 2116
@@ -2014,7 +2214,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2014 2214
2015 if (ifmgd->associated == req->bss) { 2215 if (ifmgd->associated == req->bss) {
2016 bssid = req->bss->bssid; 2216 bssid = req->bss->bssid;
2017 ieee80211_set_disassoc(sdata); 2217 ieee80211_set_disassoc(sdata, true);
2018 mutex_unlock(&ifmgd->mtx); 2218 mutex_unlock(&ifmgd->mtx);
2019 } else { 2219 } else {
2020 bool not_auth_yet = false; 2220 bool not_auth_yet = false;
@@ -2027,7 +2227,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2027 continue; 2227 continue;
2028 2228
2029 if (wk->type != IEEE80211_WORK_DIRECT_PROBE && 2229 if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
2030 wk->type != IEEE80211_WORK_AUTH) 2230 wk->type != IEEE80211_WORK_AUTH &&
2231 wk->type != IEEE80211_WORK_ASSOC)
2031 continue; 2232 continue;
2032 2233
2033 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) 2234 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
@@ -2057,9 +2258,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2057 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n", 2258 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
2058 sdata->name, bssid, req->reason_code); 2259 sdata->name, bssid, req->reason_code);
2059 2260
2060 ieee80211_send_deauth_disassoc(sdata, bssid, 2261 ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH,
2061 IEEE80211_STYPE_DEAUTH, req->reason_code, 2262 req->reason_code, cookie,
2062 cookie); 2263 !req->local_state_change);
2063 2264
2064 ieee80211_recalc_idle(sdata->local); 2265 ieee80211_recalc_idle(sdata->local);
2065 2266
@@ -2071,6 +2272,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2071 void *cookie) 2272 void *cookie)
2072{ 2273{
2073 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2274 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2275 u8 bssid[ETH_ALEN];
2074 2276
2075 mutex_lock(&ifmgd->mtx); 2277 mutex_lock(&ifmgd->mtx);
2076 2278
@@ -2088,13 +2290,15 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2088 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n", 2290 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n",
2089 sdata->name, req->bss->bssid, req->reason_code); 2291 sdata->name, req->bss->bssid, req->reason_code);
2090 2292
2091 ieee80211_set_disassoc(sdata); 2293 memcpy(bssid, req->bss->bssid, ETH_ALEN);
2294 ieee80211_set_disassoc(sdata, false);
2092 2295
2093 mutex_unlock(&ifmgd->mtx); 2296 mutex_unlock(&ifmgd->mtx);
2094 2297
2095 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, 2298 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
2096 IEEE80211_STYPE_DISASSOC, req->reason_code, 2299 IEEE80211_STYPE_DISASSOC, req->reason_code,
2097 cookie); 2300 cookie, !req->local_state_change);
2301 sta_info_destroy_addr(sdata, bssid);
2098 2302
2099 ieee80211_recalc_idle(sdata->local); 2303 ieee80211_recalc_idle(sdata->local);
2100 2304
@@ -2114,7 +2318,7 @@ int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
2114 if ((chan != local->tmp_channel || 2318 if ((chan != local->tmp_channel ||
2115 channel_type != local->tmp_channel_type) && 2319 channel_type != local->tmp_channel_type) &&
2116 (chan != local->oper_channel || 2320 (chan != local->oper_channel ||
2117 channel_type != local->oper_channel_type)) 2321 channel_type != local->_oper_channel_type))
2118 return -EBUSY; 2322 return -EBUSY;
2119 2323
2120 skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); 2324 skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
@@ -2135,3 +2339,15 @@ int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
2135 *cookie = (unsigned long) skb; 2339 *cookie = (unsigned long) skb;
2136 return 0; 2340 return 0;
2137} 2341}
2342
2343void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
2344 enum nl80211_cqm_rssi_threshold_event rssi_event,
2345 gfp_t gfp)
2346{
2347 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
2348
2349 trace_api_cqm_rssi_notify(sdata, rssi_event);
2350
2351 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp);
2352}
2353EXPORT_SYMBOL(ieee80211_cqm_rssi_notify);
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 0e64484e861c..75202b295a4e 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -46,7 +46,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
46 46
47 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { 47 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
48 list_for_each_entry_rcu(sta, &local->sta_list, list) { 48 list_for_each_entry_rcu(sta, &local->sta_list, list) {
49 set_sta_flags(sta, WLAN_STA_SUSPEND); 49 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
50 ieee80211_sta_tear_down_BA_sessions(sta); 50 ieee80211_sta_tear_down_BA_sessions(sta);
51 } 51 }
52 } 52 }
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 0b299d236fa1..6d0bd198af19 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/rtnetlink.h> 12#include <linux/rtnetlink.h>
13#include <linux/slab.h>
13#include "rate.h" 14#include "rate.h"
14#include "ieee80211_i.h" 15#include "ieee80211_i.h"
15#include "debugfs.h" 16#include "debugfs.h"
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 6e5d68b4e427..f65ce6dcc8e2 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -50,6 +50,7 @@
50#include <linux/debugfs.h> 50#include <linux/debugfs.h>
51#include <linux/random.h> 51#include <linux/random.h>
52#include <linux/ieee80211.h> 52#include <linux/ieee80211.h>
53#include <linux/slab.h>
53#include <net/mac80211.h> 54#include <net/mac80211.h>
54#include "rate.h" 55#include "rate.h"
55#include "rc80211_minstrel.h" 56#include "rc80211_minstrel.h"
@@ -541,7 +542,7 @@ minstrel_free(void *priv)
541 kfree(priv); 542 kfree(priv);
542} 543}
543 544
544static struct rate_control_ops mac80211_minstrel = { 545struct rate_control_ops mac80211_minstrel = {
545 .name = "minstrel", 546 .name = "minstrel",
546 .tx_status = minstrel_tx_status, 547 .tx_status = minstrel_tx_status,
547 .get_rate = minstrel_get_rate, 548 .get_rate = minstrel_get_rate,
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 38bf4168fc3a..0f5a83370aa6 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -80,7 +80,18 @@ struct minstrel_priv {
80 unsigned int lookaround_rate_mrr; 80 unsigned int lookaround_rate_mrr;
81}; 81};
82 82
83struct minstrel_debugfs_info {
84 size_t len;
85 char buf[];
86};
87
88extern struct rate_control_ops mac80211_minstrel;
83void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); 89void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
84void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); 90void minstrel_remove_sta_debugfs(void *priv, void *priv_sta);
85 91
92/* debugfs */
93int minstrel_stats_open(struct inode *inode, struct file *file);
94ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos);
95int minstrel_stats_release(struct inode *inode, struct file *file);
96
86#endif 97#endif
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
index a715d9454f64..241e76f3fdf2 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -49,24 +49,19 @@
49#include <linux/skbuff.h> 49#include <linux/skbuff.h>
50#include <linux/debugfs.h> 50#include <linux/debugfs.h>
51#include <linux/ieee80211.h> 51#include <linux/ieee80211.h>
52#include <linux/slab.h>
52#include <net/mac80211.h> 53#include <net/mac80211.h>
53#include "rc80211_minstrel.h" 54#include "rc80211_minstrel.h"
54 55
55struct minstrel_stats_info { 56int
56 struct minstrel_sta_info *mi;
57 char buf[4096];
58 size_t len;
59};
60
61static int
62minstrel_stats_open(struct inode *inode, struct file *file) 57minstrel_stats_open(struct inode *inode, struct file *file)
63{ 58{
64 struct minstrel_sta_info *mi = inode->i_private; 59 struct minstrel_sta_info *mi = inode->i_private;
65 struct minstrel_stats_info *ms; 60 struct minstrel_debugfs_info *ms;
66 unsigned int i, tp, prob, eprob; 61 unsigned int i, tp, prob, eprob;
67 char *p; 62 char *p;
68 63
69 ms = kmalloc(sizeof(*ms), GFP_KERNEL); 64 ms = kmalloc(sizeof(*ms) + 4096, GFP_KERNEL);
70 if (!ms) 65 if (!ms)
71 return -ENOMEM; 66 return -ENOMEM;
72 67
@@ -106,36 +101,19 @@ minstrel_stats_open(struct inode *inode, struct file *file)
106 return 0; 101 return 0;
107} 102}
108 103
109static ssize_t 104ssize_t
110minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *o) 105minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos)
111{ 106{
112 struct minstrel_stats_info *ms; 107 struct minstrel_debugfs_info *ms;
113 char *src;
114 108
115 ms = file->private_data; 109 ms = file->private_data;
116 src = ms->buf; 110 return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len);
117
118 len = min(len, ms->len);
119 if (len <= *o)
120 return 0;
121
122 src += *o;
123 len -= *o;
124 *o += len;
125
126 if (copy_to_user(buf, src, len))
127 return -EFAULT;
128
129 return len;
130} 111}
131 112
132static int 113int
133minstrel_stats_release(struct inode *inode, struct file *file) 114minstrel_stats_release(struct inode *inode, struct file *file)
134{ 115{
135 struct minstrel_stats_info *ms = file->private_data; 116 kfree(file->private_data);
136
137 kfree(ms);
138
139 return 0; 117 return 0;
140} 118}
141 119
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index 2652a374974e..aeda65466f3e 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -13,6 +13,7 @@
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/skbuff.h> 14#include <linux/skbuff.h>
15#include <linux/debugfs.h> 15#include <linux/debugfs.h>
16#include <linux/slab.h>
16#include <net/mac80211.h> 17#include <net/mac80211.h>
17#include "rate.h" 18#include "rate.h"
18#include "mesh.h" 19#include "mesh.h"
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c
index 45667054a5f3..47438b4a9af5 100644
--- a/net/mac80211/rc80211_pid_debugfs.c
+++ b/net/mac80211/rc80211_pid_debugfs.c
@@ -12,6 +12,7 @@
12#include <linux/netdevice.h> 12#include <linux/netdevice.h>
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/skbuff.h> 14#include <linux/skbuff.h>
15#include <linux/slab.h>
15 16
16#include <net/mac80211.h> 17#include <net/mac80211.h>
17#include "rate.h" 18#include "rate.h"
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b5c48de81d8b..6e2a7bcd8cb8 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/jiffies.h> 12#include <linux/jiffies.h>
13#include <linux/slab.h>
13#include <linux/kernel.h> 14#include <linux/kernel.h>
14#include <linux/skbuff.h> 15#include <linux/skbuff.h>
15#include <linux/netdevice.h> 16#include <linux/netdevice.h>
@@ -38,7 +39,7 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
38{ 39{
39 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { 40 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
40 if (likely(skb->len > FCS_LEN)) 41 if (likely(skb->len > FCS_LEN))
41 skb_trim(skb, skb->len - FCS_LEN); 42 __pskb_trim(skb, skb->len - FCS_LEN);
42 else { 43 else {
43 /* driver bug */ 44 /* driver bug */
44 WARN_ON(1); 45 WARN_ON(1);
@@ -80,8 +81,6 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local,
80 len += 8; 81 len += 8;
81 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 82 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
82 len += 1; 83 len += 1;
83 if (local->hw.flags & IEEE80211_HW_NOISE_DBM)
84 len += 1;
85 84
86 if (len & 1) /* padding for RX_FLAGS if necessary */ 85 if (len & 1) /* padding for RX_FLAGS if necessary */
87 len++; 86 len++;
@@ -178,14 +177,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
178 pos++; 177 pos++;
179 } 178 }
180 179
181 /* IEEE80211_RADIOTAP_DBM_ANTNOISE */
182 if (local->hw.flags & IEEE80211_HW_NOISE_DBM) {
183 *pos = status->noise;
184 rthdr->it_present |=
185 cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
186 pos++;
187 }
188
189 /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */ 180 /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */
190 181
191 /* IEEE80211_RADIOTAP_ANTENNA */ 182 /* IEEE80211_RADIOTAP_ANTENNA */
@@ -235,6 +226,12 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
235 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 226 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
236 present_fcs_len = FCS_LEN; 227 present_fcs_len = FCS_LEN;
237 228
229 /* make sure hdr->frame_control is on the linear part */
230 if (!pskb_may_pull(origskb, 2)) {
231 dev_kfree_skb(origskb);
232 return NULL;
233 }
234
238 if (!local->monitors) { 235 if (!local->monitors) {
239 if (should_drop_frame(origskb, present_fcs_len)) { 236 if (should_drop_frame(origskb, present_fcs_len)) {
240 dev_kfree_skb(origskb); 237 dev_kfree_skb(origskb);
@@ -492,7 +489,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
492 489
493 if (ieee80211_is_action(hdr->frame_control)) { 490 if (ieee80211_is_action(hdr->frame_control)) {
494 mgmt = (struct ieee80211_mgmt *)hdr; 491 mgmt = (struct ieee80211_mgmt *)hdr;
495 if (mgmt->u.action.category != MESH_PLINK_CATEGORY) 492 if (mgmt->u.action.category != WLAN_CATEGORY_MESH_PLINK)
496 return RX_DROP_MONITOR; 493 return RX_DROP_MONITOR;
497 return RX_CONTINUE; 494 return RX_CONTINUE;
498 } 495 }
@@ -722,14 +719,16 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
722 719
723 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 720 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
724 721
725 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) 722 spin_lock(&sta->lock);
726 goto dont_reorder; 723
724 if (!sta->ampdu_mlme.tid_active_rx[tid])
725 goto dont_reorder_unlock;
727 726
728 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; 727 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
729 728
730 /* qos null data frames are excluded */ 729 /* qos null data frames are excluded */
731 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) 730 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
732 goto dont_reorder; 731 goto dont_reorder_unlock;
733 732
734 /* new, potentially un-ordered, ampdu frame - process it */ 733 /* new, potentially un-ordered, ampdu frame - process it */
735 734
@@ -741,15 +740,20 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
741 /* if this mpdu is fragmented - terminate rx aggregation session */ 740 /* if this mpdu is fragmented - terminate rx aggregation session */
742 sc = le16_to_cpu(hdr->seq_ctrl); 741 sc = le16_to_cpu(hdr->seq_ctrl);
743 if (sc & IEEE80211_SCTL_FRAG) { 742 if (sc & IEEE80211_SCTL_FRAG) {
744 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, 743 spin_unlock(&sta->lock);
745 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP); 744 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
745 WLAN_REASON_QSTA_REQUIRE_SETUP);
746 dev_kfree_skb(skb); 746 dev_kfree_skb(skb);
747 return; 747 return;
748 } 748 }
749 749
750 if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) 750 if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) {
751 spin_unlock(&sta->lock);
751 return; 752 return;
753 }
752 754
755 dont_reorder_unlock:
756 spin_unlock(&sta->lock);
753 dont_reorder: 757 dont_reorder:
754 __skb_queue_tail(frames, skb); 758 __skb_queue_tail(frames, skb);
755} 759}
@@ -896,6 +900,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
896 rx->key = key; 900 rx->key = key;
897 return RX_CONTINUE; 901 return RX_CONTINUE;
898 } else { 902 } else {
903 u8 keyid;
899 /* 904 /*
900 * The device doesn't give us the IV so we won't be 905 * The device doesn't give us the IV so we won't be
901 * able to look up the key. That's ok though, we 906 * able to look up the key. That's ok though, we
@@ -918,7 +923,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
918 * no need to call ieee80211_wep_get_keyidx, 923 * no need to call ieee80211_wep_get_keyidx,
919 * it verifies a bunch of things we've done already 924 * it verifies a bunch of things we've done already
920 */ 925 */
921 keyidx = rx->skb->data[hdrlen + 3] >> 6; 926 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
927 keyidx = keyid >> 6;
922 928
923 rx->key = rcu_dereference(rx->sdata->keys[keyidx]); 929 rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
924 930
@@ -939,6 +945,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
939 return RX_DROP_MONITOR; 945 return RX_DROP_MONITOR;
940 } 946 }
941 947
948 if (skb_linearize(rx->skb))
949 return RX_DROP_UNUSABLE;
950
951 hdr = (struct ieee80211_hdr *)rx->skb->data;
952
942 /* Check for weak IVs if possible */ 953 /* Check for weak IVs if possible */
943 if (rx->sta && rx->key->conf.alg == ALG_WEP && 954 if (rx->sta && rx->key->conf.alg == ALG_WEP &&
944 ieee80211_is_data(hdr->frame_control) && 955 ieee80211_is_data(hdr->frame_control) &&
@@ -1077,7 +1088,6 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1077 sta->rx_fragments++; 1088 sta->rx_fragments++;
1078 sta->rx_bytes += rx->skb->len; 1089 sta->rx_bytes += rx->skb->len;
1079 sta->last_signal = status->signal; 1090 sta->last_signal = status->signal;
1080 sta->last_noise = status->noise;
1081 1091
1082 /* 1092 /*
1083 * Change STA power saving mode only at the end of a frame 1093 * Change STA power saving mode only at the end of a frame
@@ -1240,6 +1250,15 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1240 } 1250 }
1241 I802_DEBUG_INC(rx->local->rx_handlers_fragments); 1251 I802_DEBUG_INC(rx->local->rx_handlers_fragments);
1242 1252
1253 if (skb_linearize(rx->skb))
1254 return RX_DROP_UNUSABLE;
1255
1256 /*
1257 * skb_linearize() might change the skb->data and
1258 * previously cached variables (in this case, hdr) need to
1259 * be refreshed with the new data.
1260 */
1261 hdr = (struct ieee80211_hdr *)rx->skb->data;
1243 seq = (sc & IEEE80211_SCTL_SEQ) >> 4; 1262 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
1244 1263
1245 if (frag == 0) { 1264 if (frag == 0) {
@@ -1405,21 +1424,24 @@ static int
1405ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) 1424ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1406{ 1425{
1407 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1426 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1427 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1408 __le16 fc = hdr->frame_control; 1428 __le16 fc = hdr->frame_control;
1409 int res;
1410 1429
1411 res = ieee80211_drop_unencrypted(rx, fc); 1430 /*
1412 if (unlikely(res)) 1431 * Pass through unencrypted frames if the hardware has
1413 return res; 1432 * decrypted them already.
1433 */
1434 if (status->flag & RX_FLAG_DECRYPTED)
1435 return 0;
1414 1436
1415 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { 1437 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
1416 if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && 1438 if (unlikely(!ieee80211_has_protected(fc) &&
1439 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1417 rx->key)) 1440 rx->key))
1418 return -EACCES; 1441 return -EACCES;
1419 /* BIP does not use Protected field, so need to check MMIE */ 1442 /* BIP does not use Protected field, so need to check MMIE */
1420 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && 1443 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
1421 ieee80211_get_mmie_keyidx(rx->skb) < 0 && 1444 ieee80211_get_mmie_keyidx(rx->skb) < 0))
1422 rx->key))
1423 return -EACCES; 1445 return -EACCES;
1424 /* 1446 /*
1425 * When using MFP, Action frames are not allowed prior to 1447 * When using MFP, Action frames are not allowed prior to
@@ -1597,6 +1619,9 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1597 skb->dev = dev; 1619 skb->dev = dev;
1598 __skb_queue_head_init(&frame_list); 1620 __skb_queue_head_init(&frame_list);
1599 1621
1622 if (skb_linearize(skb))
1623 return RX_DROP_UNUSABLE;
1624
1600 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, 1625 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
1601 rx->sdata->vif.type, 1626 rx->sdata->vif.type,
1602 rx->local->hw.extra_tx_headroom); 1627 rx->local->hw.extra_tx_headroom);
@@ -1795,10 +1820,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
1795 if (ieee80211_is_back_req(bar->frame_control)) { 1820 if (ieee80211_is_back_req(bar->frame_control)) {
1796 if (!rx->sta) 1821 if (!rx->sta)
1797 return RX_DROP_MONITOR; 1822 return RX_DROP_MONITOR;
1823 spin_lock(&rx->sta->lock);
1798 tid = le16_to_cpu(bar->control) >> 12; 1824 tid = le16_to_cpu(bar->control) >> 12;
1799 if (rx->sta->ampdu_mlme.tid_state_rx[tid] 1825 if (!rx->sta->ampdu_mlme.tid_active_rx[tid]) {
1800 != HT_AGG_STATE_OPERATIONAL) 1826 spin_unlock(&rx->sta->lock);
1801 return RX_DROP_MONITOR; 1827 return RX_DROP_MONITOR;
1828 }
1802 tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid]; 1829 tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid];
1803 1830
1804 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; 1831 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
@@ -1812,6 +1839,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
1812 ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num, 1839 ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num,
1813 frames); 1840 frames);
1814 kfree_skb(skb); 1841 kfree_skb(skb);
1842 spin_unlock(&rx->sta->lock);
1815 return RX_QUEUED; 1843 return RX_QUEUED;
1816 } 1844 }
1817 1845
@@ -1973,6 +2001,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1973 goto handled; 2001 goto handled;
1974 } 2002 }
1975 break; 2003 break;
2004 case WLAN_CATEGORY_MESH_PLINK:
2005 case WLAN_CATEGORY_MESH_PATH_SEL:
2006 if (ieee80211_vif_is_mesh(&sdata->vif))
2007 return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
2008 break;
1976 } 2009 }
1977 2010
1978 /* 2011 /*
@@ -2366,29 +2399,42 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2366 struct ieee80211_local *local = hw_to_local(hw); 2399 struct ieee80211_local *local = hw_to_local(hw);
2367 struct ieee80211_sub_if_data *sdata; 2400 struct ieee80211_sub_if_data *sdata;
2368 struct ieee80211_hdr *hdr; 2401 struct ieee80211_hdr *hdr;
2402 __le16 fc;
2369 struct ieee80211_rx_data rx; 2403 struct ieee80211_rx_data rx;
2370 int prepares; 2404 int prepares;
2371 struct ieee80211_sub_if_data *prev = NULL; 2405 struct ieee80211_sub_if_data *prev = NULL;
2372 struct sk_buff *skb_new; 2406 struct sk_buff *skb_new;
2373 struct sta_info *sta, *tmp; 2407 struct sta_info *sta, *tmp;
2374 bool found_sta = false; 2408 bool found_sta = false;
2409 int err = 0;
2375 2410
2376 hdr = (struct ieee80211_hdr *)skb->data; 2411 fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
2377 memset(&rx, 0, sizeof(rx)); 2412 memset(&rx, 0, sizeof(rx));
2378 rx.skb = skb; 2413 rx.skb = skb;
2379 rx.local = local; 2414 rx.local = local;
2380 2415
2381 if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control)) 2416 if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
2382 local->dot11ReceivedFragmentCount++; 2417 local->dot11ReceivedFragmentCount++;
2383 2418
2384 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || 2419 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
2385 test_bit(SCAN_OFF_CHANNEL, &local->scanning))) 2420 test_bit(SCAN_OFF_CHANNEL, &local->scanning)))
2386 rx.flags |= IEEE80211_RX_IN_SCAN; 2421 rx.flags |= IEEE80211_RX_IN_SCAN;
2387 2422
2423 if (ieee80211_is_mgmt(fc))
2424 err = skb_linearize(skb);
2425 else
2426 err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
2427
2428 if (err) {
2429 dev_kfree_skb(skb);
2430 return;
2431 }
2432
2433 hdr = (struct ieee80211_hdr *)skb->data;
2388 ieee80211_parse_qos(&rx); 2434 ieee80211_parse_qos(&rx);
2389 ieee80211_verify_alignment(&rx); 2435 ieee80211_verify_alignment(&rx);
2390 2436
2391 if (ieee80211_is_data(hdr->frame_control)) { 2437 if (ieee80211_is_data(fc)) {
2392 for_each_sta_info(local, hdr->addr2, sta, tmp) { 2438 for_each_sta_info(local, hdr->addr2, sta, tmp) {
2393 rx.sta = sta; 2439 rx.sta = sta;
2394 found_sta = true; 2440 found_sta = true;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index b822dce97867..e1b0be7a57b9 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -14,6 +14,9 @@
14 14
15#include <linux/if_arp.h> 15#include <linux/if_arp.h>
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <linux/pm_qos_params.h>
18#include <net/sch_generic.h>
19#include <linux/slab.h>
17#include <net/mac80211.h> 20#include <net/mac80211.h>
18 21
19#include "ieee80211_i.h" 22#include "ieee80211_i.h"
@@ -82,7 +85,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
82{ 85{
83 struct cfg80211_bss *cbss; 86 struct cfg80211_bss *cbss;
84 struct ieee80211_bss *bss; 87 struct ieee80211_bss *bss;
85 int clen; 88 int clen, srlen;
86 s32 signal = 0; 89 s32 signal = 0;
87 90
88 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) 91 if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM)
@@ -111,23 +114,24 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
111 bss->dtim_period = tim_ie->dtim_period; 114 bss->dtim_period = tim_ie->dtim_period;
112 } 115 }
113 116
114 bss->supp_rates_len = 0; 117 /* replace old supported rates if we get new values */
118 srlen = 0;
115 if (elems->supp_rates) { 119 if (elems->supp_rates) {
116 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; 120 clen = IEEE80211_MAX_SUPP_RATES;
117 if (clen > elems->supp_rates_len) 121 if (clen > elems->supp_rates_len)
118 clen = elems->supp_rates_len; 122 clen = elems->supp_rates_len;
119 memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, 123 memcpy(bss->supp_rates, elems->supp_rates, clen);
120 clen); 124 srlen += clen;
121 bss->supp_rates_len += clen;
122 } 125 }
123 if (elems->ext_supp_rates) { 126 if (elems->ext_supp_rates) {
124 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; 127 clen = IEEE80211_MAX_SUPP_RATES - srlen;
125 if (clen > elems->ext_supp_rates_len) 128 if (clen > elems->ext_supp_rates_len)
126 clen = elems->ext_supp_rates_len; 129 clen = elems->ext_supp_rates_len;
127 memcpy(&bss->supp_rates[bss->supp_rates_len], 130 memcpy(bss->supp_rates + srlen, elems->ext_supp_rates, clen);
128 elems->ext_supp_rates, clen); 131 srlen += clen;
129 bss->supp_rates_len += clen;
130 } 132 }
133 if (srlen)
134 bss->supp_rates_len = srlen;
131 135
132 bss->wmm_used = elems->wmm_param || elems->wmm_info; 136 bss->wmm_used = elems->wmm_param || elems->wmm_info;
133 bss->uapsd_supported = is_uapsd_supported(elems); 137 bss->uapsd_supported = is_uapsd_supported(elems);
@@ -245,6 +249,8 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
245 struct ieee80211_local *local = hw_to_local(hw); 249 struct ieee80211_local *local = hw_to_local(hw);
246 bool was_hw_scan; 250 bool was_hw_scan;
247 251
252 trace_api_scan_completed(local, aborted);
253
248 mutex_lock(&local->scan_mtx); 254 mutex_lock(&local->scan_mtx);
249 255
250 /* 256 /*
@@ -321,6 +327,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
321 327
322 ieee80211_offchannel_stop_beaconing(local); 328 ieee80211_offchannel_stop_beaconing(local);
323 329
330 local->leave_oper_channel_time = 0;
324 local->next_scan_state = SCAN_DECISION; 331 local->next_scan_state = SCAN_DECISION;
325 local->scan_channel_idx = 0; 332 local->scan_channel_idx = 0;
326 333
@@ -405,7 +412,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
405 412
406 if (local->ops->hw_scan) { 413 if (local->ops->hw_scan) {
407 WARN_ON(!ieee80211_prep_hw_scan(local)); 414 WARN_ON(!ieee80211_prep_hw_scan(local));
408 rc = drv_hw_scan(local, local->hw_scan_req); 415 rc = drv_hw_scan(local, sdata, local->hw_scan_req);
409 } else 416 } else
410 rc = ieee80211_start_sw_scan(local); 417 rc = ieee80211_start_sw_scan(local);
411 418
@@ -425,11 +432,28 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
425 return rc; 432 return rc;
426} 433}
427 434
435static unsigned long
436ieee80211_scan_get_channel_time(struct ieee80211_channel *chan)
437{
438 /*
439 * TODO: channel switching also consumes quite some time,
440 * add that delay as well to get a better estimation
441 */
442 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
443 return IEEE80211_PASSIVE_CHANNEL_TIME;
444 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME;
445}
446
428static int ieee80211_scan_state_decision(struct ieee80211_local *local, 447static int ieee80211_scan_state_decision(struct ieee80211_local *local,
429 unsigned long *next_delay) 448 unsigned long *next_delay)
430{ 449{
431 bool associated = false; 450 bool associated = false;
451 bool tx_empty = true;
452 bool bad_latency;
453 bool listen_int_exceeded;
454 unsigned long min_beacon_int = 0;
432 struct ieee80211_sub_if_data *sdata; 455 struct ieee80211_sub_if_data *sdata;
456 struct ieee80211_channel *next_chan;
433 457
434 /* if no more bands/channels left, complete scan and advance to the idle state */ 458 /* if no more bands/channels left, complete scan and advance to the idle state */
435 if (local->scan_channel_idx >= local->scan_req->n_channels) { 459 if (local->scan_channel_idx >= local->scan_req->n_channels) {
@@ -437,7 +461,11 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
437 return 1; 461 return 1;
438 } 462 }
439 463
440 /* check if at least one STA interface is associated */ 464 /*
465 * check if at least one STA interface is associated,
466 * check if at least one STA interface has pending tx frames
467 * and grab the lowest used beacon interval
468 */
441 mutex_lock(&local->iflist_mtx); 469 mutex_lock(&local->iflist_mtx);
442 list_for_each_entry(sdata, &local->interfaces, list) { 470 list_for_each_entry(sdata, &local->interfaces, list) {
443 if (!ieee80211_sdata_running(sdata)) 471 if (!ieee80211_sdata_running(sdata))
@@ -446,7 +474,16 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
446 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 474 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
447 if (sdata->u.mgd.associated) { 475 if (sdata->u.mgd.associated) {
448 associated = true; 476 associated = true;
449 break; 477
478 if (sdata->vif.bss_conf.beacon_int <
479 min_beacon_int || min_beacon_int == 0)
480 min_beacon_int =
481 sdata->vif.bss_conf.beacon_int;
482
483 if (!qdisc_all_tx_empty(sdata->dev)) {
484 tx_empty = false;
485 break;
486 }
450 } 487 }
451 } 488 }
452 } 489 }
@@ -455,11 +492,34 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local,
455 if (local->scan_channel) { 492 if (local->scan_channel) {
456 /* 493 /*
457 * we're currently scanning a different channel, let's 494 * we're currently scanning a different channel, let's
458 * switch back to the operating channel now if at least 495 * see if we can scan another channel without interfering
459 * one interface is associated. Otherwise just scan the 496 * with the current traffic situation.
460 * next channel 497 *
498 * Since we don't know if the AP has pending frames for us
499 * we can only check for our tx queues and use the current
500 * pm_qos requirements for rx. Hence, if no tx traffic occurs
501 * at all we will scan as many channels in a row as the pm_qos
502 * latency allows us to. Additionally we also check for the
503 * currently negotiated listen interval to prevent losing
504 * frames unnecessarily.
505 *
506 * Otherwise switch back to the operating channel.
461 */ 507 */
462 if (associated) 508 next_chan = local->scan_req->channels[local->scan_channel_idx];
509
510 bad_latency = time_after(jiffies +
511 ieee80211_scan_get_channel_time(next_chan),
512 local->leave_oper_channel_time +
513 usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY)));
514
515 listen_int_exceeded = time_after(jiffies +
516 ieee80211_scan_get_channel_time(next_chan),
517 local->leave_oper_channel_time +
518 usecs_to_jiffies(min_beacon_int * 1024) *
519 local->hw.conf.listen_interval);
520
521 if (associated && ( !tx_empty || bad_latency ||
522 listen_int_exceeded))
463 local->next_scan_state = SCAN_ENTER_OPER_CHANNEL; 523 local->next_scan_state = SCAN_ENTER_OPER_CHANNEL;
464 else 524 else
465 local->next_scan_state = SCAN_SET_CHANNEL; 525 local->next_scan_state = SCAN_SET_CHANNEL;
@@ -491,6 +551,9 @@ static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *loca
491 else 551 else
492 *next_delay = HZ / 10; 552 *next_delay = HZ / 10;
493 553
554 /* remember when we left the operating channel */
555 local->leave_oper_channel_time = jiffies;
556
494 /* advance to the next channel to be scanned */ 557 /* advance to the next channel to be scanned */
495 local->next_scan_state = SCAN_SET_CHANNEL; 558 local->next_scan_state = SCAN_SET_CHANNEL;
496} 559}
@@ -593,7 +656,7 @@ void ieee80211_scan_work(struct work_struct *work)
593 } 656 }
594 657
595 if (local->hw_scan_req) { 658 if (local->hw_scan_req) {
596 int rc = drv_hw_scan(local, local->hw_scan_req); 659 int rc = drv_hw_scan(local, sdata, local->hw_scan_req);
597 mutex_unlock(&local->scan_mtx); 660 mutex_unlock(&local->scan_mtx);
598 if (rc) 661 if (rc)
599 ieee80211_scan_completed(&local->hw, true); 662 ieee80211_scan_completed(&local->hw, true);
@@ -666,10 +729,12 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
666} 729}
667 730
668int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, 731int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
669 const u8 *ssid, u8 ssid_len) 732 const u8 *ssid, u8 ssid_len,
733 struct ieee80211_channel *chan)
670{ 734{
671 struct ieee80211_local *local = sdata->local; 735 struct ieee80211_local *local = sdata->local;
672 int ret = -EBUSY; 736 int ret = -EBUSY;
737 enum nl80211_band band;
673 738
674 mutex_lock(&local->scan_mtx); 739 mutex_lock(&local->scan_mtx);
675 740
@@ -677,6 +742,30 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
677 if (local->scan_req) 742 if (local->scan_req)
678 goto unlock; 743 goto unlock;
679 744
745 /* fill internal scan request */
746 if (!chan) {
747 int i, nchan = 0;
748
749 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
750 if (!local->hw.wiphy->bands[band])
751 continue;
752 for (i = 0;
753 i < local->hw.wiphy->bands[band]->n_channels;
754 i++) {
755 local->int_scan_req->channels[nchan] =
756 &local->hw.wiphy->bands[band]->channels[i];
757 nchan++;
758 }
759 }
760
761 local->int_scan_req->n_channels = nchan;
762 } else {
763 local->int_scan_req->channels[0] = chan;
764 local->int_scan_req->n_channels = 1;
765 }
766
767 local->int_scan_req->ssids = &local->scan_ssid;
768 local->int_scan_req->n_ssids = 1;
680 memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN); 769 memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
681 local->int_scan_req->ssids[0].ssid_len = ssid_len; 770 local->int_scan_req->ssids[0].ssid_len = ssid_len;
682 771
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 56422d894351..730197591ab5 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -93,12 +93,18 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
93 struct ieee80211_local *local = sdata->local; 93 struct ieee80211_local *local = sdata->local;
94 struct sta_info *sta; 94 struct sta_info *sta;
95 95
96 sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); 96 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
97 rcu_read_lock_held() ||
98 lockdep_is_held(&local->sta_lock) ||
99 lockdep_is_held(&local->sta_mtx));
97 while (sta) { 100 while (sta) {
98 if (sta->sdata == sdata && 101 if (sta->sdata == sdata &&
99 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 102 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
100 break; 103 break;
101 sta = rcu_dereference(sta->hnext); 104 sta = rcu_dereference_check(sta->hnext,
105 rcu_read_lock_held() ||
106 lockdep_is_held(&local->sta_lock) ||
107 lockdep_is_held(&local->sta_mtx));
102 } 108 }
103 return sta; 109 return sta;
104} 110}
@@ -113,13 +119,19 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
113 struct ieee80211_local *local = sdata->local; 119 struct ieee80211_local *local = sdata->local;
114 struct sta_info *sta; 120 struct sta_info *sta;
115 121
116 sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); 122 sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
123 rcu_read_lock_held() ||
124 lockdep_is_held(&local->sta_lock) ||
125 lockdep_is_held(&local->sta_mtx));
117 while (sta) { 126 while (sta) {
118 if ((sta->sdata == sdata || 127 if ((sta->sdata == sdata ||
119 sta->sdata->bss == sdata->bss) && 128 sta->sdata->bss == sdata->bss) &&
120 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) 129 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
121 break; 130 break;
122 sta = rcu_dereference(sta->hnext); 131 sta = rcu_dereference_check(sta->hnext,
132 rcu_read_lock_held() ||
133 lockdep_is_held(&local->sta_lock) ||
134 lockdep_is_held(&local->sta_mtx));
123 } 135 }
124 return sta; 136 return sta;
125} 137}
@@ -238,9 +250,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
238 * enable session_timer's data differentiation. refer to 250 * enable session_timer's data differentiation. refer to
239 * sta_rx_agg_session_timer_expired for useage */ 251 * sta_rx_agg_session_timer_expired for useage */
240 sta->timer_to_tid[i] = i; 252 sta->timer_to_tid[i] = i;
241 /* rx */
242 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
243 sta->ampdu_mlme.tid_rx[i] = NULL;
244 /* tx */ 253 /* tx */
245 sta->ampdu_mlme.tid_state_tx[i] = HT_AGG_STATE_IDLE; 254 sta->ampdu_mlme.tid_state_tx[i] = HT_AGG_STATE_IDLE;
246 sta->ampdu_mlme.tid_tx[i] = NULL; 255 sta->ampdu_mlme.tid_tx[i] = NULL;
@@ -566,7 +575,7 @@ static int sta_info_buffer_expired(struct sta_info *sta,
566} 575}
567 576
568 577
569static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, 578static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
570 struct sta_info *sta) 579 struct sta_info *sta)
571{ 580{
572 unsigned long flags; 581 unsigned long flags;
@@ -574,7 +583,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
574 struct ieee80211_sub_if_data *sdata; 583 struct ieee80211_sub_if_data *sdata;
575 584
576 if (skb_queue_empty(&sta->ps_tx_buf)) 585 if (skb_queue_empty(&sta->ps_tx_buf))
577 return; 586 return false;
578 587
579 for (;;) { 588 for (;;) {
580 spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); 589 spin_lock_irqsave(&sta->ps_tx_buf.lock, flags);
@@ -599,6 +608,8 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
599 if (skb_queue_empty(&sta->ps_tx_buf)) 608 if (skb_queue_empty(&sta->ps_tx_buf))
600 sta_info_clear_tim_bit(sta); 609 sta_info_clear_tim_bit(sta);
601 } 610 }
611
612 return true;
602} 613}
603 614
604static int __must_check __sta_info_destroy(struct sta_info *sta) 615static int __must_check __sta_info_destroy(struct sta_info *sta)
@@ -607,7 +618,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
607 struct ieee80211_sub_if_data *sdata; 618 struct ieee80211_sub_if_data *sdata;
608 struct sk_buff *skb; 619 struct sk_buff *skb;
609 unsigned long flags; 620 unsigned long flags;
610 int ret, i; 621 int ret;
611 622
612 might_sleep(); 623 might_sleep();
613 624
@@ -617,6 +628,15 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
617 local = sta->local; 628 local = sta->local;
618 sdata = sta->sdata; 629 sdata = sta->sdata;
619 630
631 /*
632 * Before removing the station from the driver and
633 * rate control, it might still start new aggregation
634 * sessions -- block that to make sure the tear-down
635 * will be sufficient.
636 */
637 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
638 ieee80211_sta_tear_down_BA_sessions(sta);
639
620 spin_lock_irqsave(&local->sta_lock, flags); 640 spin_lock_irqsave(&local->sta_lock, flags);
621 ret = sta_info_hash_del(local, sta); 641 ret = sta_info_hash_del(local, sta);
622 /* this might still be the pending list ... which is fine */ 642 /* this might still be the pending list ... which is fine */
@@ -633,9 +653,6 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
633 * may mean it is removed from hardware which requires that 653 * may mean it is removed from hardware which requires that
634 * the key->sta pointer is still valid, so flush the key todo 654 * the key->sta pointer is still valid, so flush the key todo
635 * list here. 655 * list here.
636 *
637 * ieee80211_key_todo() will synchronize_rcu() so after this
638 * nothing can reference this sta struct any more.
639 */ 656 */
640 ieee80211_key_todo(); 657 ieee80211_key_todo();
641 658
@@ -667,11 +684,17 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
667 sdata = sta->sdata; 684 sdata = sta->sdata;
668 } 685 }
669 686
687 /*
688 * At this point, after we wait for an RCU grace period,
689 * neither mac80211 nor the driver can reference this
690 * sta struct any more except by still existing timers
691 * associated with this station that we clean up below.
692 */
693 synchronize_rcu();
694
670#ifdef CONFIG_MAC80211_MESH 695#ifdef CONFIG_MAC80211_MESH
671 if (ieee80211_vif_is_mesh(&sdata->vif)) { 696 if (ieee80211_vif_is_mesh(&sdata->vif))
672 mesh_accept_plinks_update(sdata); 697 mesh_accept_plinks_update(sdata);
673 del_timer(&sta->plink_timer);
674 }
675#endif 698#endif
676 699
677#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 700#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -698,50 +721,6 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
698 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) 721 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL)
699 dev_kfree_skb_any(skb); 722 dev_kfree_skb_any(skb);
700 723
701 for (i = 0; i < STA_TID_NUM; i++) {
702 struct tid_ampdu_rx *tid_rx;
703 struct tid_ampdu_tx *tid_tx;
704
705 spin_lock_bh(&sta->lock);
706 tid_rx = sta->ampdu_mlme.tid_rx[i];
707 /* Make sure timer won't free the tid_rx struct, see below */
708 if (tid_rx)
709 tid_rx->shutdown = true;
710
711 spin_unlock_bh(&sta->lock);
712
713 /*
714 * Outside spinlock - shutdown is true now so that the timer
715 * won't free tid_rx, we have to do that now. Can't let the
716 * timer do it because we have to sync the timer outside the
717 * lock that it takes itself.
718 */
719 if (tid_rx) {
720 del_timer_sync(&tid_rx->session_timer);
721 kfree(tid_rx);
722 }
723
724 /*
725 * No need to do such complications for TX agg sessions, the
726 * path leading to freeing the tid_tx struct goes via a call
727 * from the driver, and thus needs to look up the sta struct
728 * again, which cannot be found when we get here. Hence, we
729 * just need to delete the timer and free the aggregation
730 * info; we won't be telling the peer about it then but that
731 * doesn't matter if we're not talking to it again anyway.
732 */
733 tid_tx = sta->ampdu_mlme.tid_tx[i];
734 if (tid_tx) {
735 del_timer_sync(&tid_tx->addba_resp_timer);
736 /*
737 * STA removed while aggregation session being
738 * started? Bit odd, but purge frames anyway.
739 */
740 skb_queue_purge(&tid_tx->pending);
741 kfree(tid_tx);
742 }
743 }
744
745 __sta_info_free(local, sta); 724 __sta_info_free(local, sta);
746 725
747 return 0; 726 return 0;
@@ -778,15 +757,20 @@ static void sta_info_cleanup(unsigned long data)
778{ 757{
779 struct ieee80211_local *local = (struct ieee80211_local *) data; 758 struct ieee80211_local *local = (struct ieee80211_local *) data;
780 struct sta_info *sta; 759 struct sta_info *sta;
760 bool timer_needed = false;
781 761
782 rcu_read_lock(); 762 rcu_read_lock();
783 list_for_each_entry_rcu(sta, &local->sta_list, list) 763 list_for_each_entry_rcu(sta, &local->sta_list, list)
784 sta_info_cleanup_expire_buffered(local, sta); 764 if (sta_info_cleanup_expire_buffered(local, sta))
765 timer_needed = true;
785 rcu_read_unlock(); 766 rcu_read_unlock();
786 767
787 if (local->quiescing) 768 if (local->quiescing)
788 return; 769 return;
789 770
771 if (!timer_needed)
772 return;
773
790 local->sta_cleanup.expires = 774 local->sta_cleanup.expires =
791 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); 775 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL);
792 add_timer(&local->sta_cleanup); 776 add_timer(&local->sta_cleanup);
@@ -871,8 +855,12 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw,
871 struct sta_info *sta, *nxt; 855 struct sta_info *sta, *nxt;
872 856
873 /* Just return a random station ... first in list ... */ 857 /* Just return a random station ... first in list ... */
874 for_each_sta_info(hw_to_local(hw), addr, sta, nxt) 858 for_each_sta_info(hw_to_local(hw), addr, sta, nxt) {
859 if (!sta->uploaded)
860 return NULL;
875 return &sta->sta; 861 return &sta->sta;
862 }
863
876 return NULL; 864 return NULL;
877} 865}
878EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); 866EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw);
@@ -880,14 +868,19 @@ EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw);
880struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, 868struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif,
881 const u8 *addr) 869 const u8 *addr)
882{ 870{
883 struct ieee80211_sub_if_data *sdata; 871 struct sta_info *sta;
884 872
885 if (!vif) 873 if (!vif)
886 return NULL; 874 return NULL;
887 875
888 sdata = vif_to_sdata(vif); 876 sta = sta_info_get_bss(vif_to_sdata(vif), addr);
877 if (!sta)
878 return NULL;
879
880 if (!sta->uploaded)
881 return NULL;
889 882
890 return ieee80211_find_sta_by_hw(&sdata->local->hw, addr); 883 return &sta->sta;
891} 884}
892EXPORT_SYMBOL(ieee80211_find_sta); 885EXPORT_SYMBOL(ieee80211_find_sta);
893 886
@@ -980,6 +973,8 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
980{ 973{
981 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); 974 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
982 975
976 trace_api_sta_block_awake(sta->local, pubsta, block);
977
983 if (block) 978 if (block)
984 set_sta_flags(sta, WLAN_STA_PS_DRIVER); 979 set_sta_flags(sta, WLAN_STA_PS_DRIVER);
985 else 980 else
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 822d84522937..48a5e80957f0 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -35,8 +35,8 @@
35 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next 35 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
36 * frame to this station is transmitted. 36 * frame to this station is transmitted.
37 * @WLAN_STA_MFP: Management frame protection is used with this STA. 37 * @WLAN_STA_MFP: Management frame protection is used with this STA.
38 * @WLAN_STA_SUSPEND: Set/cleared during a suspend/resume cycle. 38 * @WLAN_STA_BLOCK_BA: Used to deny ADDBA requests (both TX and RX)
39 * Used to deny ADDBA requests (both TX and RX). 39 * during suspend/resume and station removal.
40 * @WLAN_STA_PS_DRIVER: driver requires keeping this station in 40 * @WLAN_STA_PS_DRIVER: driver requires keeping this station in
41 * power-save mode logically to flush frames that might still 41 * power-save mode logically to flush frames that might still
42 * be in the queues 42 * be in the queues
@@ -57,7 +57,7 @@ enum ieee80211_sta_info_flags {
57 WLAN_STA_WDS = 1<<7, 57 WLAN_STA_WDS = 1<<7,
58 WLAN_STA_CLEAR_PS_FILT = 1<<9, 58 WLAN_STA_CLEAR_PS_FILT = 1<<9,
59 WLAN_STA_MFP = 1<<10, 59 WLAN_STA_MFP = 1<<10,
60 WLAN_STA_SUSPEND = 1<<11, 60 WLAN_STA_BLOCK_BA = 1<<11,
61 WLAN_STA_PS_DRIVER = 1<<12, 61 WLAN_STA_PS_DRIVER = 1<<12,
62 WLAN_STA_PSPOLL = 1<<13, 62 WLAN_STA_PSPOLL = 1<<13,
63 WLAN_STA_DISASSOC = 1<<14, 63 WLAN_STA_DISASSOC = 1<<14,
@@ -106,7 +106,6 @@ struct tid_ampdu_tx {
106 * @buf_size: buffer size for incoming A-MPDUs 106 * @buf_size: buffer size for incoming A-MPDUs
107 * @timeout: reset timer value (in TUs). 107 * @timeout: reset timer value (in TUs).
108 * @dialog_token: dialog token for aggregation session 108 * @dialog_token: dialog token for aggregation session
109 * @shutdown: this session is being shut down due to STA removal
110 */ 109 */
111struct tid_ampdu_rx { 110struct tid_ampdu_rx {
112 struct sk_buff **reorder_buf; 111 struct sk_buff **reorder_buf;
@@ -118,7 +117,6 @@ struct tid_ampdu_rx {
118 u16 buf_size; 117 u16 buf_size;
119 u16 timeout; 118 u16 timeout;
120 u8 dialog_token; 119 u8 dialog_token;
121 bool shutdown;
122}; 120};
123 121
124/** 122/**
@@ -156,7 +154,7 @@ enum plink_state {
156 */ 154 */
157struct sta_ampdu_mlme { 155struct sta_ampdu_mlme {
158 /* rx */ 156 /* rx */
159 u8 tid_state_rx[STA_TID_NUM]; 157 bool tid_active_rx[STA_TID_NUM];
160 struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; 158 struct tid_ampdu_rx *tid_rx[STA_TID_NUM];
161 /* tx */ 159 /* tx */
162 u8 tid_state_tx[STA_TID_NUM]; 160 u8 tid_state_tx[STA_TID_NUM];
@@ -200,7 +198,6 @@ struct sta_ampdu_mlme {
200 * @rx_fragments: number of received MPDUs 198 * @rx_fragments: number of received MPDUs
201 * @rx_dropped: number of dropped MPDUs from this STA 199 * @rx_dropped: number of dropped MPDUs from this STA
202 * @last_signal: signal of last received frame from this STA 200 * @last_signal: signal of last received frame from this STA
203 * @last_noise: noise of last received frame from this STA
204 * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) 201 * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
205 * @tx_filtered_count: number of frames the hardware filtered for this STA 202 * @tx_filtered_count: number of frames the hardware filtered for this STA
206 * @tx_retry_failed: number of frames that failed retry 203 * @tx_retry_failed: number of frames that failed retry
@@ -267,7 +264,6 @@ struct sta_info {
267 unsigned long rx_fragments; 264 unsigned long rx_fragments;
268 unsigned long rx_dropped; 265 unsigned long rx_dropped;
269 int last_signal; 266 int last_signal;
270 int last_noise;
271 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; 267 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
272 268
273 /* Updated from TX status path only, no locking requirements */ 269 /* Updated from TX status path only, no locking requirements */
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 56d5b9a6ec5b..94613af009f3 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -171,13 +171,16 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
171 struct net_device *prev_dev = NULL; 171 struct net_device *prev_dev = NULL;
172 struct sta_info *sta, *tmp; 172 struct sta_info *sta, *tmp;
173 int retry_count = -1, i; 173 int retry_count = -1, i;
174 bool injected; 174 int rates_idx = -1;
175 bool send_to_cooked;
175 176
176 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 177 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
177 /* the HW cannot have attempted that rate */ 178 /* the HW cannot have attempted that rate */
178 if (i >= hw->max_rates) { 179 if (i >= hw->max_rates) {
179 info->status.rates[i].idx = -1; 180 info->status.rates[i].idx = -1;
180 info->status.rates[i].count = 0; 181 info->status.rates[i].count = 0;
182 } else if (info->status.rates[i].idx >= 0) {
183 rates_idx = i;
181 } 184 }
182 185
183 retry_count += info->status.rates[i].count; 186 retry_count += info->status.rates[i].count;
@@ -206,6 +209,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
206 return; 209 return;
207 } 210 }
208 211
212 if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) &&
213 (rates_idx != -1))
214 sta->last_tx_rate = info->status.rates[rates_idx];
215
209 if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && 216 if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) &&
210 (ieee80211_is_data_qos(fc))) { 217 (ieee80211_is_data_qos(fc))) {
211 u16 tid, ssn; 218 u16 tid, ssn;
@@ -296,11 +303,15 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
296 /* this was a transmitted frame, but now we want to reuse it */ 303 /* this was a transmitted frame, but now we want to reuse it */
297 skb_orphan(skb); 304 skb_orphan(skb);
298 305
306 /* Need to make a copy before skb->cb gets cleared */
307 send_to_cooked = !!(info->flags & IEEE80211_TX_CTL_INJECTED) ||
308 (type != IEEE80211_FTYPE_DATA);
309
299 /* 310 /*
300 * This is a bit racy but we can avoid a lot of work 311 * This is a bit racy but we can avoid a lot of work
301 * with this test... 312 * with this test...
302 */ 313 */
303 if (!local->monitors && !local->cooked_mntrs) { 314 if (!local->monitors && (!send_to_cooked || !local->cooked_mntrs)) {
304 dev_kfree_skb(skb); 315 dev_kfree_skb(skb);
305 return; 316 return;
306 } 317 }
@@ -345,9 +356,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
345 /* for now report the total retry_count */ 356 /* for now report the total retry_count */
346 rthdr->data_retries = retry_count; 357 rthdr->data_retries = retry_count;
347 358
348 /* Need to make a copy before skb->cb gets cleared */
349 injected = !!(info->flags & IEEE80211_TX_CTL_INJECTED);
350
351 /* XXX: is this sufficient for BPF? */ 359 /* XXX: is this sufficient for BPF? */
352 skb_set_mac_header(skb, 0); 360 skb_set_mac_header(skb, 0);
353 skb->ip_summed = CHECKSUM_UNNECESSARY; 361 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -362,8 +370,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
362 continue; 370 continue;
363 371
364 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) && 372 if ((sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) &&
365 !injected && 373 !send_to_cooked)
366 (type == IEEE80211_FTYPE_DATA))
367 continue; 374 continue;
368 375
369 if (prev_dev) { 376 if (prev_dev) {
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index cbe53ed4fb0b..680bcb7093db 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -429,6 +429,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
429 struct sta_info *sta = tx->sta; 429 struct sta_info *sta = tx->sta;
430 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 430 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
431 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 431 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
432 struct ieee80211_local *local = tx->local;
432 u32 staflags; 433 u32 staflags;
433 434
434 if (unlikely(!sta || 435 if (unlikely(!sta ||
@@ -476,6 +477,12 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
476 info->control.vif = &tx->sdata->vif; 477 info->control.vif = &tx->sdata->vif;
477 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 478 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
478 skb_queue_tail(&sta->ps_tx_buf, tx->skb); 479 skb_queue_tail(&sta->ps_tx_buf, tx->skb);
480
481 if (!timer_pending(&local->sta_cleanup))
482 mod_timer(&local->sta_cleanup,
483 round_jiffies(jiffies +
484 STA_INFO_CLEANUP_INTERVAL));
485
479 return TX_QUEUED; 486 return TX_QUEUED;
480 } 487 }
481#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 488#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
@@ -513,6 +520,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
513 else if (tx->sta && (key = rcu_dereference(tx->sta->key))) 520 else if (tx->sta && (key = rcu_dereference(tx->sta->key)))
514 tx->key = key; 521 tx->key = key;
515 else if (ieee80211_is_mgmt(hdr->frame_control) && 522 else if (ieee80211_is_mgmt(hdr->frame_control) &&
523 is_multicast_ether_addr(hdr->addr1) &&
524 ieee80211_is_robust_mgmt_frame(hdr) &&
516 (key = rcu_dereference(tx->sdata->default_mgmt_key))) 525 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
517 tx->key = key; 526 tx->key = key;
518 else if ((key = rcu_dereference(tx->sdata->default_key))) 527 else if ((key = rcu_dereference(tx->sdata->default_key)))
@@ -584,7 +593,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
584 struct ieee80211_hdr *hdr = (void *)tx->skb->data; 593 struct ieee80211_hdr *hdr = (void *)tx->skb->data;
585 struct ieee80211_supported_band *sband; 594 struct ieee80211_supported_band *sband;
586 struct ieee80211_rate *rate; 595 struct ieee80211_rate *rate;
587 int i, len; 596 int i;
597 u32 len;
588 bool inval = false, rts = false, short_preamble = false; 598 bool inval = false, rts = false, short_preamble = false;
589 struct ieee80211_tx_rate_control txrc; 599 struct ieee80211_tx_rate_control txrc;
590 u32 sta_flags; 600 u32 sta_flags;
@@ -593,7 +603,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
593 603
594 sband = tx->local->hw.wiphy->bands[tx->channel->band]; 604 sband = tx->local->hw.wiphy->bands[tx->channel->band];
595 605
596 len = min_t(int, tx->skb->len + FCS_LEN, 606 len = min_t(u32, tx->skb->len + FCS_LEN,
597 tx->local->hw.wiphy->frag_threshold); 607 tx->local->hw.wiphy->frag_threshold);
598 608
599 /* set up the tx rate control struct we give the RC algo */ 609 /* set up the tx rate control struct we give the RC algo */
@@ -1142,13 +1152,12 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1142 1152
1143 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && 1153 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
1144 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { 1154 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) {
1145 unsigned long flags;
1146 struct tid_ampdu_tx *tid_tx; 1155 struct tid_ampdu_tx *tid_tx;
1147 1156
1148 qc = ieee80211_get_qos_ctl(hdr); 1157 qc = ieee80211_get_qos_ctl(hdr);
1149 tid = *qc & IEEE80211_QOS_CTL_TID_MASK; 1158 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
1150 1159
1151 spin_lock_irqsave(&tx->sta->lock, flags); 1160 spin_lock(&tx->sta->lock);
1152 /* 1161 /*
1153 * XXX: This spinlock could be fairly expensive, but see the 1162 * XXX: This spinlock could be fairly expensive, but see the
1154 * comment in agg-tx.c:ieee80211_agg_tx_operational(). 1163 * comment in agg-tx.c:ieee80211_agg_tx_operational().
@@ -1173,7 +1182,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1173 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1182 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1174 __skb_queue_tail(&tid_tx->pending, skb); 1183 __skb_queue_tail(&tid_tx->pending, skb);
1175 } 1184 }
1176 spin_unlock_irqrestore(&tx->sta->lock, flags); 1185 spin_unlock(&tx->sta->lock);
1177 1186
1178 if (unlikely(queued)) 1187 if (unlikely(queued))
1179 return TX_QUEUED; 1188 return TX_QUEUED;
@@ -1991,6 +2000,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1991void ieee80211_tx_pending(unsigned long data) 2000void ieee80211_tx_pending(unsigned long data)
1992{ 2001{
1993 struct ieee80211_local *local = (struct ieee80211_local *)data; 2002 struct ieee80211_local *local = (struct ieee80211_local *)data;
2003 struct ieee80211_sub_if_data *sdata;
1994 unsigned long flags; 2004 unsigned long flags;
1995 int i; 2005 int i;
1996 bool txok; 2006 bool txok;
@@ -2010,14 +2020,12 @@ void ieee80211_tx_pending(unsigned long data)
2010 while (!skb_queue_empty(&local->pending[i])) { 2020 while (!skb_queue_empty(&local->pending[i])) {
2011 struct sk_buff *skb = __skb_dequeue(&local->pending[i]); 2021 struct sk_buff *skb = __skb_dequeue(&local->pending[i]);
2012 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2022 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2013 struct ieee80211_sub_if_data *sdata;
2014 2023
2015 if (WARN_ON(!info->control.vif)) { 2024 if (WARN_ON(!info->control.vif)) {
2016 kfree_skb(skb); 2025 kfree_skb(skb);
2017 continue; 2026 continue;
2018 } 2027 }
2019 2028
2020 sdata = vif_to_sdata(info->control.vif);
2021 spin_unlock_irqrestore(&local->queue_stop_reason_lock, 2029 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
2022 flags); 2030 flags);
2023 2031
@@ -2029,6 +2037,11 @@ void ieee80211_tx_pending(unsigned long data)
2029 if (!txok) 2037 if (!txok)
2030 break; 2038 break;
2031 } 2039 }
2040
2041 if (skb_queue_empty(&local->pending[i]))
2042 list_for_each_entry_rcu(sdata, &local->interfaces, list)
2043 netif_tx_wake_queue(
2044 netdev_get_tx_queue(sdata->dev, i));
2032 } 2045 }
2033 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 2046 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
2034 2047
@@ -2238,8 +2251,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2238 2251
2239 info->control.vif = vif; 2252 info->control.vif = vif;
2240 2253
2241 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; 2254 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT |
2242 info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; 2255 IEEE80211_TX_CTL_ASSIGN_SEQ |
2256 IEEE80211_TX_CTL_FIRST_FRAGMENT;
2243 out: 2257 out:
2244 rcu_read_unlock(); 2258 rcu_read_unlock();
2245 return skb; 2259 return skb;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index c453226f06b2..5b79d552780a 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -270,6 +270,8 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
270 struct ieee80211_local *local = hw_to_local(hw); 270 struct ieee80211_local *local = hw_to_local(hw);
271 struct ieee80211_sub_if_data *sdata; 271 struct ieee80211_sub_if_data *sdata;
272 272
273 trace_wake_queue(local, queue, reason);
274
273 if (WARN_ON(queue >= hw->queues)) 275 if (WARN_ON(queue >= hw->queues))
274 return; 276 return;
275 277
@@ -279,13 +281,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
279 /* someone still has this queue stopped */ 281 /* someone still has this queue stopped */
280 return; 282 return;
281 283
282 if (!skb_queue_empty(&local->pending[queue])) 284 if (skb_queue_empty(&local->pending[queue])) {
285 rcu_read_lock();
286 list_for_each_entry_rcu(sdata, &local->interfaces, list)
287 netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
288 rcu_read_unlock();
289 } else
283 tasklet_schedule(&local->tx_pending_tasklet); 290 tasklet_schedule(&local->tx_pending_tasklet);
284
285 rcu_read_lock();
286 list_for_each_entry_rcu(sdata, &local->interfaces, list)
287 netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
288 rcu_read_unlock();
289} 291}
290 292
291void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 293void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -312,6 +314,8 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
312 struct ieee80211_local *local = hw_to_local(hw); 314 struct ieee80211_local *local = hw_to_local(hw);
313 struct ieee80211_sub_if_data *sdata; 315 struct ieee80211_sub_if_data *sdata;
314 316
317 trace_stop_queue(local, queue, reason);
318
315 if (WARN_ON(queue >= hw->queues)) 319 if (WARN_ON(queue >= hw->queues))
316 return; 320 return;
317 321
@@ -796,6 +800,11 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
796 800
797 drv_conf_tx(local, queue, &qparam); 801 drv_conf_tx(local, queue, &qparam);
798 } 802 }
803
804 /* after reinitialize QoS TX queues setting to default,
805 * disable QoS at all */
806 local->hw.conf.flags &= ~IEEE80211_CONF_QOS;
807 drv_config(local, IEEE80211_CONF_CHANGE_QOS);
799} 808}
800 809
801void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 810void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
@@ -1097,9 +1106,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1097 */ 1106 */
1098 res = drv_start(local); 1107 res = drv_start(local);
1099 if (res) { 1108 if (res) {
1100 WARN(local->suspended, "Harware became unavailable " 1109 WARN(local->suspended, "Hardware became unavailable "
1101 "upon resume. This is could be a software issue" 1110 "upon resume. This could be a software issue "
1102 "prior to suspend or a hardware issue\n"); 1111 "prior to suspend or a hardware issue.\n");
1103 return res; 1112 return res;
1104 } 1113 }
1105 1114
@@ -1135,7 +1144,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1135 1144
1136 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { 1145 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
1137 list_for_each_entry_rcu(sta, &local->sta_list, list) { 1146 list_for_each_entry_rcu(sta, &local->sta_list, list) {
1138 clear_sta_flags(sta, WLAN_STA_SUSPEND); 1147 clear_sta_flags(sta, WLAN_STA_BLOCK_BA);
1139 } 1148 }
1140 } 1149 }
1141 1150
@@ -1151,18 +1160,33 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1151 1160
1152 /* Finally also reconfigure all the BSS information */ 1161 /* Finally also reconfigure all the BSS information */
1153 list_for_each_entry(sdata, &local->interfaces, list) { 1162 list_for_each_entry(sdata, &local->interfaces, list) {
1154 u32 changed = ~0; 1163 u32 changed;
1164
1155 if (!ieee80211_sdata_running(sdata)) 1165 if (!ieee80211_sdata_running(sdata))
1156 continue; 1166 continue;
1167
1168 /* common change flags for all interface types */
1169 changed = BSS_CHANGED_ERP_CTS_PROT |
1170 BSS_CHANGED_ERP_PREAMBLE |
1171 BSS_CHANGED_ERP_SLOT |
1172 BSS_CHANGED_HT |
1173 BSS_CHANGED_BASIC_RATES |
1174 BSS_CHANGED_BEACON_INT |
1175 BSS_CHANGED_BSSID |
1176 BSS_CHANGED_CQM;
1177
1157 switch (sdata->vif.type) { 1178 switch (sdata->vif.type) {
1158 case NL80211_IFTYPE_STATION: 1179 case NL80211_IFTYPE_STATION:
1159 /* disable beacon change bits */ 1180 changed |= BSS_CHANGED_ASSOC;
1160 changed &= ~(BSS_CHANGED_BEACON | 1181 ieee80211_bss_info_change_notify(sdata, changed);
1161 BSS_CHANGED_BEACON_ENABLED); 1182 break;
1162 /* fall through */
1163 case NL80211_IFTYPE_ADHOC: 1183 case NL80211_IFTYPE_ADHOC:
1184 changed |= BSS_CHANGED_IBSS;
1185 /* fall through */
1164 case NL80211_IFTYPE_AP: 1186 case NL80211_IFTYPE_AP:
1165 case NL80211_IFTYPE_MESH_POINT: 1187 case NL80211_IFTYPE_MESH_POINT:
1188 changed |= BSS_CHANGED_BEACON |
1189 BSS_CHANGED_BEACON_ENABLED;
1166 ieee80211_bss_info_change_notify(sdata, changed); 1190 ieee80211_bss_info_change_notify(sdata, changed);
1167 break; 1191 break;
1168 case NL80211_IFTYPE_WDS: 1192 case NL80211_IFTYPE_WDS:
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 5d745f2d7236..5f3a4113bda1 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -17,6 +17,7 @@
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/mm.h> 18#include <linux/mm.h>
19#include <linux/scatterlist.h> 19#include <linux/scatterlist.h>
20#include <linux/slab.h>
20#include <asm/unaligned.h> 21#include <asm/unaligned.h>
21 22
22#include <net/mac80211.h> 23#include <net/mac80211.h>
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 1e1ea3007b06..be3d4a698692 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -19,6 +19,7 @@
19#include <linux/if_arp.h> 19#include <linux/if_arp.h>
20#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
21#include <linux/crc32.h> 21#include <linux/crc32.h>
22#include <linux/slab.h>
22#include <net/mac80211.h> 23#include <net/mac80211.h>
23#include <asm/unaligned.h> 24#include <asm/unaligned.h>
24 25
@@ -32,6 +33,7 @@
32#define IEEE80211_MAX_PROBE_TRIES 5 33#define IEEE80211_MAX_PROBE_TRIES 5
33 34
34enum work_action { 35enum work_action {
36 WORK_ACT_MISMATCH,
35 WORK_ACT_NONE, 37 WORK_ACT_NONE,
36 WORK_ACT_TIMEOUT, 38 WORK_ACT_TIMEOUT,
37 WORK_ACT_DONE, 39 WORK_ACT_DONE,
@@ -212,15 +214,25 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
212 214
213 sband = local->hw.wiphy->bands[wk->chan->band]; 215 sband = local->hw.wiphy->bands[wk->chan->band];
214 216
215 /* 217 if (wk->assoc.supp_rates_len) {
216 * Get all rates supported by the device and the AP as 218 /*
217 * some APs don't like getting a superset of their rates 219 * Get all rates supported by the device and the AP as
218 * in the association request (e.g. D-Link DAP 1353 in 220 * some APs don't like getting a superset of their rates
219 * b-only mode)... 221 * in the association request (e.g. D-Link DAP 1353 in
220 */ 222 * b-only mode)...
221 rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates, 223 */
222 wk->assoc.supp_rates_len, 224 rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates,
223 sband, &rates); 225 wk->assoc.supp_rates_len,
226 sband, &rates);
227 } else {
228 /*
229 * In case AP not provide any supported rates information
230 * before association, we send information element(s) with
231 * all rates that we support.
232 */
233 rates = ~0;
234 rates_len = sband->n_bitrates;
235 }
224 236
225 skb = alloc_skb(local->hw.extra_tx_headroom + 237 skb = alloc_skb(local->hw.extra_tx_headroom +
226 sizeof(*mgmt) + /* bit too much but doesn't matter */ 238 sizeof(*mgmt) + /* bit too much but doesn't matter */
@@ -574,7 +586,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_work *wk,
574 u16 auth_alg, auth_transaction, status_code; 586 u16 auth_alg, auth_transaction, status_code;
575 587
576 if (wk->type != IEEE80211_WORK_AUTH) 588 if (wk->type != IEEE80211_WORK_AUTH)
577 return WORK_ACT_NONE; 589 return WORK_ACT_MISMATCH;
578 590
579 if (len < 24 + 6) 591 if (len < 24 + 6)
580 return WORK_ACT_NONE; 592 return WORK_ACT_NONE;
@@ -625,6 +637,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_work *wk,
625 struct ieee802_11_elems elems; 637 struct ieee802_11_elems elems;
626 u8 *pos; 638 u8 *pos;
627 639
640 if (wk->type != IEEE80211_WORK_ASSOC)
641 return WORK_ACT_MISMATCH;
642
628 /* 643 /*
629 * AssocResp and ReassocResp have identical structure, so process both 644 * AssocResp and ReassocResp have identical structure, so process both
630 * of them in this function. 645 * of them in this function.
@@ -680,6 +695,12 @@ ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk,
680 695
681 ASSERT_WORK_MTX(local); 696 ASSERT_WORK_MTX(local);
682 697
698 if (wk->type != IEEE80211_WORK_DIRECT_PROBE)
699 return WORK_ACT_MISMATCH;
700
701 if (len < 24 + 12)
702 return WORK_ACT_NONE;
703
683 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; 704 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
684 if (baselen > len) 705 if (baselen > len)
685 return WORK_ACT_NONE; 706 return WORK_ACT_NONE;
@@ -694,7 +715,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
694 struct ieee80211_rx_status *rx_status; 715 struct ieee80211_rx_status *rx_status;
695 struct ieee80211_mgmt *mgmt; 716 struct ieee80211_mgmt *mgmt;
696 struct ieee80211_work *wk; 717 struct ieee80211_work *wk;
697 enum work_action rma = WORK_ACT_NONE; 718 enum work_action rma;
698 u16 fc; 719 u16 fc;
699 720
700 rx_status = (struct ieee80211_rx_status *) skb->cb; 721 rx_status = (struct ieee80211_rx_status *) skb->cb;
@@ -741,7 +762,17 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
741 break; 762 break;
742 default: 763 default:
743 WARN_ON(1); 764 WARN_ON(1);
765 rma = WORK_ACT_NONE;
744 } 766 }
767
768 /*
769 * We've either received an unexpected frame, or we have
770 * multiple work items and need to match the frame to the
771 * right one.
772 */
773 if (rma == WORK_ACT_MISMATCH)
774 continue;
775
745 /* 776 /*
746 * We've processed this frame for that work, so it can't 777 * We've processed this frame for that work, so it can't
747 * belong to another work struct. 778 * belong to another work struct.
@@ -751,6 +782,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
751 } 782 }
752 783
753 switch (rma) { 784 switch (rma) {
785 case WORK_ACT_MISMATCH:
786 /* ignore this unmatched frame */
787 break;
754 case WORK_ACT_NONE: 788 case WORK_ACT_NONE:
755 break; 789 break;
756 case WORK_ACT_DONE: 790 case WORK_ACT_DONE:
@@ -919,11 +953,16 @@ static void ieee80211_work_work(struct work_struct *work)
919 run_again(local, jiffies + HZ/2); 953 run_again(local, jiffies + HZ/2);
920 } 954 }
921 955
922 if (list_empty(&local->work_list) && local->scan_req) 956 mutex_lock(&local->scan_mtx);
957
958 if (list_empty(&local->work_list) && local->scan_req &&
959 !local->scanning)
923 ieee80211_queue_delayed_work(&local->hw, 960 ieee80211_queue_delayed_work(&local->hw,
924 &local->scan_work, 961 &local->scan_work,
925 round_jiffies_relative(0)); 962 round_jiffies_relative(0));
926 963
964 mutex_unlock(&local->scan_mtx);
965
927 mutex_unlock(&local->work_mtx); 966 mutex_unlock(&local->work_mtx);
928 967
929 ieee80211_recalc_idle(local); 968 ieee80211_recalc_idle(local);
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index f4971cd45c64..0adbcc941ac9 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -9,10 +9,10 @@
9 9
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/slab.h>
13#include <linux/skbuff.h> 12#include <linux/skbuff.h>
14#include <linux/compiler.h> 13#include <linux/compiler.h>
15#include <linux/ieee80211.h> 14#include <linux/ieee80211.h>
15#include <linux/gfp.h>
16#include <asm/unaligned.h> 16#include <asm/unaligned.h>
17#include <net/mac80211.h> 17#include <net/mac80211.h>
18 18