aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-04-15 16:21:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-15 16:21:34 -0400
commit5c01d5669356e13f0fb468944c1dd4c6a7e978ad (patch)
treefa43345288d7b25fac92b3b35360a177c4947313 /net/mac80211
parentfea069152614cdeefba4b2bf80afcddb9c217fc8 (diff)
parenta5e944f1d955f3819503348426763e21e0413ba6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: Documentation/feature-removal-schedule.txt drivers/net/wireless/ath/ath5k/phy.c drivers/net/wireless/wl12xx/wl1271_main.c
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/Kconfig8
-rw-r--r--net/mac80211/agg-rx.c72
-rw-r--r--net/mac80211/agg-tx.c14
-rw-r--r--net/mac80211/cfg.c13
-rw-r--r--net/mac80211/debugfs_netdev.c12
-rw-r--r--net/mac80211/debugfs_sta.c12
-rw-r--r--net/mac80211/driver-trace.h275
-rw-r--r--net/mac80211/ht.c3
-rw-r--r--net/mac80211/ieee80211_i.h21
-rw-r--r--net/mac80211/main.c2
-rw-r--r--net/mac80211/mesh.c4
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_hwmp.c4
-rw-r--r--net/mac80211/mesh_plink.c2
-rw-r--r--net/mac80211/mlme.c106
-rw-r--r--net/mac80211/pm.c2
-rw-r--r--net/mac80211/rx.c91
-rw-r--r--net/mac80211/scan.c2
-rw-r--r--net/mac80211/sta_info.c75
-rw-r--r--net/mac80211/sta_info.h10
-rw-r--r--net/mac80211/tx.c7
-rw-r--r--net/mac80211/util.c11
-rw-r--r--net/mac80211/work.c7
23 files changed, 572 insertions, 183 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 334c359da5e8..8a91f6c0bb18 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -221,8 +221,8 @@ config MAC80211_DRIVER_API_TRACER
221 depends on EVENT_TRACING 221 depends on EVENT_TRACING
222 help 222 help
223 Say Y here to make mac80211 register with the ftrace 223 Say Y here to make mac80211 register with the ftrace
224 framework for the driver API -- you can see which 224 framework for the driver API -- you can then see which
225 driver methods it is calling then by looking at the 225 driver methods it is calling and which API functions
226 trace. 226 drivers are calling by looking at the trace.
227 227
228 If unsure, say N. 228 If unsure, say Y.
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index f9516a27e233..9598fdb4ad01 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -23,19 +23,20 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
23 u16 initiator, u16 reason) 23 u16 initiator, u16 reason)
24{ 24{
25 struct ieee80211_local *local = sta->local; 25 struct ieee80211_local *local = sta->local;
26 struct tid_ampdu_rx *tid_rx;
26 int i; 27 int i;
27 28
28 /* check if TID is in operational state */
29 spin_lock_bh(&sta->lock); 29 spin_lock_bh(&sta->lock);
30 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) { 30
31 /* check if TID is in operational state */
32 if (!sta->ampdu_mlme.tid_active_rx[tid]) {
31 spin_unlock_bh(&sta->lock); 33 spin_unlock_bh(&sta->lock);
32 return; 34 return;
33 } 35 }
34 36
35 sta->ampdu_mlme.tid_state_rx[tid] = 37 sta->ampdu_mlme.tid_active_rx[tid] = false;
36 HT_AGG_STATE_REQ_STOP_BA_MSK | 38
37 (initiator << HT_AGG_STATE_INITIATOR_SHIFT); 39 tid_rx = sta->ampdu_mlme.tid_rx[tid];
38 spin_unlock_bh(&sta->lock);
39 40
40#ifdef CONFIG_MAC80211_HT_DEBUG 41#ifdef CONFIG_MAC80211_HT_DEBUG
41 printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n", 42 printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n",
@@ -47,61 +48,35 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
47 printk(KERN_DEBUG "HW problem - can not stop rx " 48 printk(KERN_DEBUG "HW problem - can not stop rx "
48 "aggregation for tid %d\n", tid); 49 "aggregation for tid %d\n", tid);
49 50
50 /* shutdown timer has not expired */
51 if (initiator != WLAN_BACK_TIMER)
52 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
53
54 /* check if this is a self generated aggregation halt */ 51 /* check if this is a self generated aggregation halt */
55 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER) 52 if (initiator == WLAN_BACK_RECIPIENT)
56 ieee80211_send_delba(sta->sdata, sta->sta.addr, 53 ieee80211_send_delba(sta->sdata, sta->sta.addr,
57 tid, 0, reason); 54 tid, 0, reason);
58 55
59 /* free the reordering buffer */ 56 /* free the reordering buffer */
60 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) { 57 for (i = 0; i < tid_rx->buf_size; i++) {
61 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) { 58 if (tid_rx->reorder_buf[i]) {
62 /* release the reordered frames */ 59 /* release the reordered frames */
63 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]); 60 dev_kfree_skb(tid_rx->reorder_buf[i]);
64 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--; 61 tid_rx->stored_mpdu_num--;
65 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL; 62 tid_rx->reorder_buf[i] = NULL;
66 } 63 }
67 } 64 }
68 65
69 spin_lock_bh(&sta->lock);
70 /* free resources */ 66 /* free resources */
71 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf); 67 kfree(tid_rx->reorder_buf);
72 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_time); 68 kfree(tid_rx->reorder_time);
69 sta->ampdu_mlme.tid_rx[tid] = NULL;
73 70
74 if (!sta->ampdu_mlme.tid_rx[tid]->shutdown) {
75 kfree(sta->ampdu_mlme.tid_rx[tid]);
76 sta->ampdu_mlme.tid_rx[tid] = NULL;
77 }
78
79 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
80 spin_unlock_bh(&sta->lock); 71 spin_unlock_bh(&sta->lock);
81}
82
83void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
84 u16 initiator, u16 reason)
85{
86 struct sta_info *sta;
87
88 rcu_read_lock();
89
90 sta = sta_info_get(sdata, ra);
91 if (!sta) {
92 rcu_read_unlock();
93 return;
94 }
95
96 __ieee80211_stop_rx_ba_session(sta, tid, initiator, reason);
97 72
98 rcu_read_unlock(); 73 del_timer_sync(&tid_rx->session_timer);
74 kfree(tid_rx);
99} 75}
100 76
101/* 77/*
102 * After accepting the AddBA Request we activated a timer, 78 * After accepting the AddBA Request we activated a timer,
103 * resetting it after each frame that arrives from the originator. 79 * resetting it after each frame that arrives from the originator.
104 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
105 */ 80 */
106static void sta_rx_agg_session_timer_expired(unsigned long data) 81static void sta_rx_agg_session_timer_expired(unsigned long data)
107{ 82{
@@ -117,9 +92,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
117#ifdef CONFIG_MAC80211_HT_DEBUG 92#ifdef CONFIG_MAC80211_HT_DEBUG
118 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); 93 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
119#endif 94#endif
120 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, 95 __ieee80211_stop_rx_ba_session(sta, *ptid, WLAN_BACK_RECIPIENT,
121 (u16)*ptid, WLAN_BACK_TIMER, 96 WLAN_REASON_QSTA_TIMEOUT);
122 WLAN_REASON_QSTA_TIMEOUT);
123} 97}
124 98
125static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, 99static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
@@ -194,7 +168,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
194 168
195 status = WLAN_STATUS_REQUEST_DECLINED; 169 status = WLAN_STATUS_REQUEST_DECLINED;
196 170
197 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { 171 if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
198#ifdef CONFIG_MAC80211_HT_DEBUG 172#ifdef CONFIG_MAC80211_HT_DEBUG
199 printk(KERN_DEBUG "Suspend in progress. " 173 printk(KERN_DEBUG "Suspend in progress. "
200 "Denying ADDBA request\n"); 174 "Denying ADDBA request\n");
@@ -232,7 +206,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
232 /* examine state machine */ 206 /* examine state machine */
233 spin_lock_bh(&sta->lock); 207 spin_lock_bh(&sta->lock);
234 208
235 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { 209 if (sta->ampdu_mlme.tid_active_rx[tid]) {
236#ifdef CONFIG_MAC80211_HT_DEBUG 210#ifdef CONFIG_MAC80211_HT_DEBUG
237 if (net_ratelimit()) 211 if (net_ratelimit())
238 printk(KERN_DEBUG "unexpected AddBA Req from " 212 printk(KERN_DEBUG "unexpected AddBA Req from "
@@ -294,7 +268,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
294 } 268 }
295 269
296 /* change state and send addba resp */ 270 /* change state and send addba resp */
297 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL; 271 sta->ampdu_mlme.tid_active_rx[tid] = true;
298 tid_agg_rx->dialog_token = dialog_token; 272 tid_agg_rx->dialog_token = dialog_token;
299 tid_agg_rx->ssn = start_seq_num; 273 tid_agg_rx->ssn = start_seq_num;
300 tid_agg_rx->head_seq_num = start_seq_num; 274 tid_agg_rx->head_seq_num = start_seq_num;
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 96d25348aa59..608063f11797 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -215,6 +215,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
215 int ret = 0; 215 int ret = 0;
216 u16 start_seq_num; 216 u16 start_seq_num;
217 217
218 trace_api_start_tx_ba_session(pubsta, tid);
219
218 if (WARN_ON(!local->ops->ampdu_action)) 220 if (WARN_ON(!local->ops->ampdu_action))
219 return -EINVAL; 221 return -EINVAL;
220 222
@@ -246,7 +248,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
246 return -EINVAL; 248 return -EINVAL;
247 } 249 }
248 250
249 if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { 251 if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
250#ifdef CONFIG_MAC80211_HT_DEBUG 252#ifdef CONFIG_MAC80211_HT_DEBUG
251 printk(KERN_DEBUG "Suspend in progress. " 253 printk(KERN_DEBUG "Suspend in progress. "
252 "Denying BA session request\n"); 254 "Denying BA session request\n");
@@ -415,7 +417,7 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
415 struct sta_info *sta, u16 tid) 417 struct sta_info *sta, u16 tid)
416{ 418{
417#ifdef CONFIG_MAC80211_HT_DEBUG 419#ifdef CONFIG_MAC80211_HT_DEBUG
418 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); 420 printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid);
419#endif 421#endif
420 422
421 spin_lock(&local->ampdu_lock); 423 spin_lock(&local->ampdu_lock);
@@ -441,6 +443,8 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
441 struct sta_info *sta; 443 struct sta_info *sta;
442 u8 *state; 444 u8 *state;
443 445
446 trace_api_start_tx_ba_cb(sdata, ra, tid);
447
444 if (tid >= STA_TID_NUM) { 448 if (tid >= STA_TID_NUM) {
445#ifdef CONFIG_MAC80211_HT_DEBUG 449#ifdef CONFIG_MAC80211_HT_DEBUG
446 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", 450 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
@@ -542,6 +546,8 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
542 struct ieee80211_sub_if_data *sdata = sta->sdata; 546 struct ieee80211_sub_if_data *sdata = sta->sdata;
543 struct ieee80211_local *local = sdata->local; 547 struct ieee80211_local *local = sdata->local;
544 548
549 trace_api_stop_tx_ba_session(pubsta, tid, initiator);
550
545 if (!local->ops->ampdu_action) 551 if (!local->ops->ampdu_action)
546 return -EINVAL; 552 return -EINVAL;
547 553
@@ -559,6 +565,8 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
559 struct sta_info *sta; 565 struct sta_info *sta;
560 u8 *state; 566 u8 *state;
561 567
568 trace_api_stop_tx_ba_cb(sdata, ra, tid);
569
562 if (tid >= STA_TID_NUM) { 570 if (tid >= STA_TID_NUM) {
563#ifdef CONFIG_MAC80211_HT_DEBUG 571#ifdef CONFIG_MAC80211_HT_DEBUG
564 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", 572 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
@@ -675,7 +683,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
675 del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 683 del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
676 684
677#ifdef CONFIG_MAC80211_HT_DEBUG 685#ifdef CONFIG_MAC80211_HT_DEBUG
678 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); 686 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
679#endif /* CONFIG_MAC80211_HT_DEBUG */ 687#endif /* CONFIG_MAC80211_HT_DEBUG */
680 688
681 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 689 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c41aaba839fa..7dd7cda75cfa 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1137,6 +1137,10 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1137 return -EINVAL; 1137 return -EINVAL;
1138 } 1138 }
1139 1139
1140 /* enable WMM or activate new settings */
1141 local->hw.conf.flags |= IEEE80211_CONF_QOS;
1142 drv_config(local, IEEE80211_CONF_CHANGE_QOS);
1143
1140 return 0; 1144 return 0;
1141} 1145}
1142 1146
@@ -1412,9 +1416,6 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
1412 struct ieee80211_vif *vif = &sdata->vif; 1416 struct ieee80211_vif *vif = &sdata->vif;
1413 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 1417 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1414 1418
1415 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI))
1416 return -EOPNOTSUPP;
1417
1418 if (rssi_thold == bss_conf->cqm_rssi_thold && 1419 if (rssi_thold == bss_conf->cqm_rssi_thold &&
1419 rssi_hyst == bss_conf->cqm_rssi_hyst) 1420 rssi_hyst == bss_conf->cqm_rssi_hyst)
1420 return 0; 1421 return 0;
@@ -1422,6 +1423,12 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
1422 bss_conf->cqm_rssi_thold = rssi_thold; 1423 bss_conf->cqm_rssi_thold = rssi_thold;
1423 bss_conf->cqm_rssi_hyst = rssi_hyst; 1424 bss_conf->cqm_rssi_hyst = rssi_hyst;
1424 1425
1426 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
1427 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1428 return -EOPNOTSUPP;
1429 return 0;
1430 }
1431
1425 /* tell the driver upon association, unless already associated */ 1432 /* tell the driver upon association, unless already associated */
1426 if (sdata->u.mgd.associated) 1433 if (sdata->u.mgd.associated)
1427 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM); 1434 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 83d4289d954b..20b2998fa0ed 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -100,6 +100,14 @@ static ssize_t ieee80211_if_fmt_##name( \
100 return scnprintf(buf, buflen, "%pM\n", sdata->field); \ 100 return scnprintf(buf, buflen, "%pM\n", sdata->field); \
101} 101}
102 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
103#define __IEEE80211_IF_FILE(name, _write) \ 111#define __IEEE80211_IF_FILE(name, _write) \
104static ssize_t ieee80211_if_read_##name(struct file *file, \ 112static ssize_t ieee80211_if_read_##name(struct file *file, \
105 char __user *userbuf, \ 113 char __user *userbuf, \
@@ -140,6 +148,8 @@ IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
140/* STA attributes */ 148/* STA attributes */
141IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); 149IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
142IEEE80211_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);
143 153
144static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, 154static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
145 enum ieee80211_smps_mode smps_mode) 155 enum ieee80211_smps_mode smps_mode)
@@ -276,6 +286,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
276 286
277 DEBUGFS_ADD(bssid); 287 DEBUGFS_ADD(bssid);
278 DEBUGFS_ADD(aid); 288 DEBUGFS_ADD(aid);
289 DEBUGFS_ADD(last_beacon);
290 DEBUGFS_ADD(ave_beacon);
279 DEBUGFS_ADD_MODE(smps, 0600); 291 DEBUGFS_ADD_MODE(smps, 0600);
280} 292}
281 293
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 23e720034577..6bc9b07c3eda 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -119,7 +119,7 @@ STA_OPS(last_seq_ctrl);
119static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, 119static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
120 size_t count, loff_t *ppos) 120 size_t count, loff_t *ppos)
121{ 121{
122 char buf[64 + STA_TID_NUM * 40], *p = buf; 122 char buf[71 + STA_TID_NUM * 40], *p = buf;
123 int i; 123 int i;
124 struct sta_info *sta = file->private_data; 124 struct sta_info *sta = file->private_data;
125 125
@@ -127,16 +127,16 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
127 p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n", 127 p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n",
128 sta->ampdu_mlme.dialog_token_allocator + 1); 128 sta->ampdu_mlme.dialog_token_allocator + 1);
129 p += scnprintf(p, sizeof(buf) + buf - p, 129 p += scnprintf(p, sizeof(buf) + buf - p,
130 "TID\t\tRX\tDTKN\tSSN\t\tTX\tDTKN\tSSN\tpending\n"); 130 "TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tSSN\tpending\n");
131 for (i = 0; i < STA_TID_NUM; i++) { 131 for (i = 0; i < STA_TID_NUM; i++) {
132 p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i); 132 p += scnprintf(p, sizeof(buf) + buf - p, "%02d", i);
133 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", 133 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
134 sta->ampdu_mlme.tid_state_rx[i]); 134 sta->ampdu_mlme.tid_active_rx[i]);
135 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x", 135 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.2x",
136 sta->ampdu_mlme.tid_state_rx[i] ? 136 sta->ampdu_mlme.tid_active_rx[i] ?
137 sta->ampdu_mlme.tid_rx[i]->dialog_token : 0); 137 sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
138 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x", 138 p += scnprintf(p, sizeof(buf) + buf - p, "\t%#.3x",
139 sta->ampdu_mlme.tid_state_rx[i] ? 139 sta->ampdu_mlme.tid_active_rx[i] ?
140 sta->ampdu_mlme.tid_rx[i]->ssn : 0); 140 sta->ampdu_mlme.tid_rx[i]->ssn : 0);
141 141
142 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x", 142 p += scnprintf(p, sizeof(buf) + buf - p, "\t\t%x",
@@ -176,7 +176,7 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
176 if (htc->ht_supported) { 176 if (htc->ht_supported) {
177 p += scnprintf(p, sizeof(buf)+buf-p, "cap: %#.4x\n", htc->cap); 177 p += scnprintf(p, sizeof(buf)+buf-p, "cap: %#.4x\n", htc->cap);
178 178
179 PRINT_HT_CAP((htc->cap & BIT(0)), "RX LDCP"); 179 PRINT_HT_CAP((htc->cap & BIT(0)), "RX LDPC");
180 PRINT_HT_CAP((htc->cap & BIT(1)), "HT20/HT40"); 180 PRINT_HT_CAP((htc->cap & BIT(1)), "HT20/HT40");
181 PRINT_HT_CAP(!(htc->cap & BIT(1)), "HT20"); 181 PRINT_HT_CAP(!(htc->cap & BIT(1)), "HT20");
182 182
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 41baf730a5c7..e209cb82ff29 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
@@ -766,6 +770,277 @@ TRACE_EVENT(drv_flush,
766 LOCAL_PR_ARG, __entry->drop 770 LOCAL_PR_ARG, __entry->drop
767 ) 771 )
768); 772);
773
774/*
775 * Tracing for API calls that drivers call.
776 */
777
778TRACE_EVENT(api_start_tx_ba_session,
779 TP_PROTO(struct ieee80211_sta *sta, u16 tid),
780
781 TP_ARGS(sta, tid),
782
783 TP_STRUCT__entry(
784 STA_ENTRY
785 __field(u16, tid)
786 ),
787
788 TP_fast_assign(
789 STA_ASSIGN;
790 __entry->tid = tid;
791 ),
792
793 TP_printk(
794 STA_PR_FMT " tid:%d",
795 STA_PR_ARG, __entry->tid
796 )
797);
798
799TRACE_EVENT(api_start_tx_ba_cb,
800 TP_PROTO(struct ieee80211_sub_if_data *sdata, const u8 *ra, u16 tid),
801
802 TP_ARGS(sdata, ra, tid),
803
804 TP_STRUCT__entry(
805 VIF_ENTRY
806 __array(u8, ra, ETH_ALEN)
807 __field(u16, tid)
808 ),
809
810 TP_fast_assign(
811 VIF_ASSIGN;
812 memcpy(__entry->ra, ra, ETH_ALEN);
813 __entry->tid = tid;
814 ),
815
816 TP_printk(
817 VIF_PR_FMT " ra:%pM tid:%d",
818 VIF_PR_ARG, __entry->ra, __entry->tid
819 )
820);
821
822TRACE_EVENT(api_stop_tx_ba_session,
823 TP_PROTO(struct ieee80211_sta *sta, u16 tid, u16 initiator),
824
825 TP_ARGS(sta, tid, initiator),
826
827 TP_STRUCT__entry(
828 STA_ENTRY
829 __field(u16, tid)
830 __field(u16, initiator)
831 ),
832
833 TP_fast_assign(
834 STA_ASSIGN;
835 __entry->tid = tid;
836 __entry->initiator = initiator;
837 ),
838
839 TP_printk(
840 STA_PR_FMT " tid:%d initiator:%d",
841 STA_PR_ARG, __entry->tid, __entry->initiator
842 )
843);
844
845TRACE_EVENT(api_stop_tx_ba_cb,
846 TP_PROTO(struct ieee80211_sub_if_data *sdata, const u8 *ra, u16 tid),
847
848 TP_ARGS(sdata, ra, tid),
849
850 TP_STRUCT__entry(
851 VIF_ENTRY
852 __array(u8, ra, ETH_ALEN)
853 __field(u16, tid)
854 ),
855
856 TP_fast_assign(
857 VIF_ASSIGN;
858 memcpy(__entry->ra, ra, ETH_ALEN);
859 __entry->tid = tid;
860 ),
861
862 TP_printk(
863 VIF_PR_FMT " ra:%pM tid:%d",
864 VIF_PR_ARG, __entry->ra, __entry->tid
865 )
866);
867
868TRACE_EVENT(api_restart_hw,
869 TP_PROTO(struct ieee80211_local *local),
870
871 TP_ARGS(local),
872
873 TP_STRUCT__entry(
874 LOCAL_ENTRY
875 ),
876
877 TP_fast_assign(
878 LOCAL_ASSIGN;
879 ),
880
881 TP_printk(
882 LOCAL_PR_FMT,
883 LOCAL_PR_ARG
884 )
885);
886
887TRACE_EVENT(api_beacon_loss,
888 TP_PROTO(struct ieee80211_sub_if_data *sdata),
889
890 TP_ARGS(sdata),
891
892 TP_STRUCT__entry(
893 VIF_ENTRY
894 ),
895
896 TP_fast_assign(
897 VIF_ASSIGN;
898 ),
899
900 TP_printk(
901 VIF_PR_FMT,
902 VIF_PR_ARG
903 )
904);
905
906TRACE_EVENT(api_connection_loss,
907 TP_PROTO(struct ieee80211_sub_if_data *sdata),
908
909 TP_ARGS(sdata),
910
911 TP_STRUCT__entry(
912 VIF_ENTRY
913 ),
914
915 TP_fast_assign(
916 VIF_ASSIGN;
917 ),
918
919 TP_printk(
920 VIF_PR_FMT,
921 VIF_PR_ARG
922 )
923);
924
925TRACE_EVENT(api_cqm_rssi_notify,
926 TP_PROTO(struct ieee80211_sub_if_data *sdata,
927 enum nl80211_cqm_rssi_threshold_event rssi_event),
928
929 TP_ARGS(sdata, rssi_event),
930
931 TP_STRUCT__entry(
932 VIF_ENTRY
933 __field(u32, rssi_event)
934 ),
935
936 TP_fast_assign(
937 VIF_ASSIGN;
938 __entry->rssi_event = rssi_event;
939 ),
940
941 TP_printk(
942 VIF_PR_FMT " event:%d",
943 VIF_PR_ARG, __entry->rssi_event
944 )
945);
946
947TRACE_EVENT(api_scan_completed,
948 TP_PROTO(struct ieee80211_local *local, bool aborted),
949
950 TP_ARGS(local, aborted),
951
952 TP_STRUCT__entry(
953 LOCAL_ENTRY
954 __field(bool, aborted)
955 ),
956
957 TP_fast_assign(
958 LOCAL_ASSIGN;
959 __entry->aborted = aborted;
960 ),
961
962 TP_printk(
963 LOCAL_PR_FMT " aborted:%d",
964 LOCAL_PR_ARG, __entry->aborted
965 )
966);
967
968TRACE_EVENT(api_sta_block_awake,
969 TP_PROTO(struct ieee80211_local *local,
970 struct ieee80211_sta *sta, bool block),
971
972 TP_ARGS(local, sta, block),
973
974 TP_STRUCT__entry(
975 LOCAL_ENTRY
976 STA_ENTRY
977 __field(bool, block)
978 ),
979
980 TP_fast_assign(
981 LOCAL_ASSIGN;
982 STA_ASSIGN;
983 __entry->block = block;
984 ),
985
986 TP_printk(
987 LOCAL_PR_FMT STA_PR_FMT " block:%d",
988 LOCAL_PR_ARG, STA_PR_FMT, __entry->block
989 )
990);
991
992/*
993 * Tracing for internal functions
994 * (which may also be called in response to driver calls)
995 */
996
997TRACE_EVENT(wake_queue,
998 TP_PROTO(struct ieee80211_local *local, u16 queue,
999 enum queue_stop_reason reason),
1000
1001 TP_ARGS(local, queue, reason),
1002
1003 TP_STRUCT__entry(
1004 LOCAL_ENTRY
1005 __field(u16, queue)
1006 __field(u32, reason)
1007 ),
1008
1009 TP_fast_assign(
1010 LOCAL_ASSIGN;
1011 __entry->queue = queue;
1012 __entry->reason = reason;
1013 ),
1014
1015 TP_printk(
1016 LOCAL_PR_FMT " queue:%d, reason:%d",
1017 LOCAL_PR_ARG, __entry->queue, __entry->reason
1018 )
1019);
1020
1021TRACE_EVENT(stop_queue,
1022 TP_PROTO(struct ieee80211_local *local, u16 queue,
1023 enum queue_stop_reason reason),
1024
1025 TP_ARGS(local, queue, reason),
1026
1027 TP_STRUCT__entry(
1028 LOCAL_ENTRY
1029 __field(u16, queue)
1030 __field(u32, reason)
1031 ),
1032
1033 TP_fast_assign(
1034 LOCAL_ASSIGN;
1035 __entry->queue = queue;
1036 __entry->reason = reason;
1037 ),
1038
1039 TP_printk(
1040 LOCAL_PR_FMT " queue:%d, reason:%d",
1041 LOCAL_PR_ARG, __entry->queue, __entry->reason
1042 )
1043);
769#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ 1044#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
770 1045
771#undef TRACE_INCLUDE_PATH 1046#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/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 7fdacf9408b1..c9712f35e596 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 {
@@ -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 {
@@ -1078,8 +1097,6 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
1078 enum ieee80211_smps_mode smps, const u8 *da, 1097 enum ieee80211_smps_mode smps, const u8 *da,
1079 const u8 *bssid); 1098 const u8 *bssid);
1080 1099
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, 1100void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
1084 u16 initiator, u16 reason); 1101 u16 initiator, u16 reason);
1085void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); 1102void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 50c1b1ada884..011ee85bcd57 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -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);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 859ee5f3d941..7e93524459fc 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -601,10 +601,10 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
601 struct ieee80211_rx_status *rx_status) 601 struct ieee80211_rx_status *rx_status)
602{ 602{
603 switch (mgmt->u.action.category) { 603 switch (mgmt->u.action.category) {
604 case MESH_PLINK_CATEGORY: 604 case WLAN_CATEGORY_MESH_PLINK:
605 mesh_rx_plink_frame(sdata, mgmt, len, rx_status); 605 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
606 break; 606 break;
607 case MESH_PATH_SEL_CATEGORY: 607 case WLAN_CATEGORY_MESH_PATH_SEL:
608 mesh_rx_path_sel_frame(sdata, mgmt, len); 608 mesh_rx_path_sel_frame(sdata, mgmt, len);
609 break; 609 break;
610 } 610 }
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 fefc45c4b4e8..d89ed7f2592b 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -132,7 +132,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
132 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 132 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
133 /* BSSID == SA */ 133 /* BSSID == SA */
134 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); 134 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
135 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; 135 mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL;
136 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;
137 137
138 switch (action) { 138 switch (action) {
@@ -225,7 +225,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
225 memcpy(mgmt->da, ra, ETH_ALEN); 225 memcpy(mgmt->da, ra, ETH_ALEN);
226 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 226 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
227 /* BSSID is left zeroed, wildcard value */ 227 /* BSSID is left zeroed, wildcard value */
228 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; 228 mgmt->u.action.category = WLAN_CATEGORY_MESH_PATH_SEL;
229 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;
230 ie_len = 15; 230 ie_len = 15;
231 pos = skb_put(skb, 2 + ie_len); 231 pos = skb_put(skb, 2 + ie_len);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 7b7080e2b49f..3cd5f7b5d693 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -172,7 +172,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
172 memcpy(mgmt->da, da, ETH_ALEN); 172 memcpy(mgmt->da, da, ETH_ALEN);
173 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 173 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
174 /* BSSID is left zeroed, wildcard value */ 174 /* BSSID is left zeroed, wildcard value */
175 mgmt->u.action.category = MESH_PLINK_CATEGORY; 175 mgmt->u.action.category = WLAN_CATEGORY_MESH_PLINK;
176 mgmt->u.action.u.plink_action.action_code = action; 176 mgmt->u.action.u.plink_action.action_code = action;
177 177
178 if (action == PLINK_CLOSE) 178 if (action == PLINK_CLOSE)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 71ff42a0465b..35d850223a75 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -47,6 +47,13 @@
47 */ 47 */
48#define IEEE80211_PROBE_WAIT (HZ / 2) 48#define IEEE80211_PROBE_WAIT (HZ / 2)
49 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
50#define TMR_RUNNING_TIMER 0 57#define TMR_RUNNING_TIMER 0
51#define TMR_RUNNING_CHANSW 1 58#define TMR_RUNNING_CHANSW 1
52 59
@@ -204,7 +211,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
204 211
205static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, 212static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
206 const u8 *bssid, u16 stype, u16 reason, 213 const u8 *bssid, u16 stype, u16 reason,
207 void *cookie) 214 void *cookie, bool send_frame)
208{ 215{
209 struct ieee80211_local *local = sdata->local; 216 struct ieee80211_local *local = sdata->local;
210 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 217 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -241,7 +248,11 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
241 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); 248 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
242 if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) 249 if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
243 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 250 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
244 ieee80211_tx_skb(sdata, skb); 251
252 if (send_frame)
253 ieee80211_tx_skb(sdata, skb);
254 else
255 kfree_skb(skb);
245} 256}
246 257
247void ieee80211_send_pspoll(struct ieee80211_local *local, 258void ieee80211_send_pspoll(struct ieee80211_local *local,
@@ -590,6 +601,9 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
590 int count; 601 int count;
591 u8 *pos, uapsd_queues = 0; 602 u8 *pos, uapsd_queues = 0;
592 603
604 if (!local->ops->conf_tx)
605 return;
606
593 if (local->hw.queues < 4) 607 if (local->hw.queues < 4)
594 return; 608 return;
595 609
@@ -664,11 +678,15 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
664 params.aifs, params.cw_min, params.cw_max, params.txop, 678 params.aifs, params.cw_min, params.cw_max, params.txop,
665 params.uapsd); 679 params.uapsd);
666#endif 680#endif
667 if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx) 681 if (drv_conf_tx(local, queue, &params))
668 printk(KERN_DEBUG "%s: failed to set TX queue " 682 printk(KERN_DEBUG "%s: failed to set TX queue "
669 "parameters for queue %d\n", 683 "parameters for queue %d\n",
670 wiphy_name(local->hw.wiphy), queue); 684 wiphy_name(local->hw.wiphy), queue);
671 } 685 }
686
687 /* enable WMM or activate new settings */
688 local->hw.conf.flags |= IEEE80211_CONF_QOS;
689 drv_config(local, IEEE80211_CONF_CHANGE_QOS);
672} 690}
673 691
674static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, 692static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
@@ -729,6 +747,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
729 sdata->u.mgd.associated = cbss; 747 sdata->u.mgd.associated = cbss;
730 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN); 748 memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
731 749
750 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
751
732 /* just to be sure */ 752 /* just to be sure */
733 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | 753 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
734 IEEE80211_STA_BEACON_POLL); 754 IEEE80211_STA_BEACON_POLL);
@@ -770,7 +790,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
770 netif_carrier_on(sdata->dev); 790 netif_carrier_on(sdata->dev);
771} 791}
772 792
773static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata) 793static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
794 bool remove_sta)
774{ 795{
775 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 796 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
776 struct ieee80211_local *local = sdata->local; 797 struct ieee80211_local *local = sdata->local;
@@ -843,7 +864,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
843 changed |= BSS_CHANGED_BSSID; 864 changed |= BSS_CHANGED_BSSID;
844 ieee80211_bss_info_change_notify(sdata, changed); 865 ieee80211_bss_info_change_notify(sdata, changed);
845 866
846 sta_info_destroy_addr(sdata, bssid); 867 if (remove_sta)
868 sta_info_destroy_addr(sdata, bssid);
847} 869}
848 870
849void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 871void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -956,7 +978,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
956 978
957 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); 979 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
958 980
959 ieee80211_set_disassoc(sdata); 981 ieee80211_set_disassoc(sdata, true);
960 ieee80211_recalc_idle(local); 982 ieee80211_recalc_idle(local);
961 mutex_unlock(&ifmgd->mtx); 983 mutex_unlock(&ifmgd->mtx);
962 /* 984 /*
@@ -966,7 +988,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
966 ieee80211_send_deauth_disassoc(sdata, bssid, 988 ieee80211_send_deauth_disassoc(sdata, bssid,
967 IEEE80211_STYPE_DEAUTH, 989 IEEE80211_STYPE_DEAUTH,
968 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, 990 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
969 NULL); 991 NULL, true);
970} 992}
971 993
972void ieee80211_beacon_connection_loss_work(struct work_struct *work) 994void ieee80211_beacon_connection_loss_work(struct work_struct *work)
@@ -986,6 +1008,8 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif)
986 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 1008 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
987 struct ieee80211_hw *hw = &sdata->local->hw; 1009 struct ieee80211_hw *hw = &sdata->local->hw;
988 1010
1011 trace_api_beacon_loss(sdata);
1012
989 WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR); 1013 WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR);
990 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work); 1014 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
991} 1015}
@@ -996,6 +1020,8 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif)
996 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 1020 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
997 struct ieee80211_hw *hw = &sdata->local->hw; 1021 struct ieee80211_hw *hw = &sdata->local->hw;
998 1022
1023 trace_api_connection_loss(sdata);
1024
999 WARN_ON(!(hw->flags & IEEE80211_HW_CONNECTION_MONITOR)); 1025 WARN_ON(!(hw->flags & IEEE80211_HW_CONNECTION_MONITOR));
1000 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work); 1026 ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
1001} 1027}
@@ -1022,7 +1048,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1022 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", 1048 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
1023 sdata->name, bssid, reason_code); 1049 sdata->name, bssid, reason_code);
1024 1050
1025 ieee80211_set_disassoc(sdata); 1051 ieee80211_set_disassoc(sdata, true);
1026 ieee80211_recalc_idle(sdata->local); 1052 ieee80211_recalc_idle(sdata->local);
1027 1053
1028 return RX_MGMT_CFG80211_DEAUTH; 1054 return RX_MGMT_CFG80211_DEAUTH;
@@ -1052,7 +1078,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1052 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", 1078 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
1053 sdata->name, mgmt->sa, reason_code); 1079 sdata->name, mgmt->sa, reason_code);
1054 1080
1055 ieee80211_set_disassoc(sdata); 1081 ieee80211_set_disassoc(sdata, true);
1056 ieee80211_recalc_idle(sdata->local); 1082 ieee80211_recalc_idle(sdata->local);
1057 return RX_MGMT_CFG80211_DISASSOC; 1083 return RX_MGMT_CFG80211_DISASSOC;
1058} 1084}
@@ -1344,6 +1370,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1344 struct ieee80211_rx_status *rx_status) 1370 struct ieee80211_rx_status *rx_status)
1345{ 1371{
1346 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1372 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1373 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
1347 size_t baselen; 1374 size_t baselen;
1348 struct ieee802_11_elems elems; 1375 struct ieee802_11_elems elems;
1349 struct ieee80211_local *local = sdata->local; 1376 struct ieee80211_local *local = sdata->local;
@@ -1379,6 +1406,41 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1379 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0) 1406 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
1380 return; 1407 return;
1381 1408
1409 /* Track average RSSI from the Beacon frames of the current AP */
1410 ifmgd->last_beacon_signal = rx_status->signal;
1411 if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
1412 ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
1413 ifmgd->ave_beacon_signal = rx_status->signal;
1414 ifmgd->last_cqm_event_signal = 0;
1415 } else {
1416 ifmgd->ave_beacon_signal =
1417 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
1418 (16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
1419 ifmgd->ave_beacon_signal) / 16;
1420 }
1421 if (bss_conf->cqm_rssi_thold &&
1422 !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
1423 int sig = ifmgd->ave_beacon_signal / 16;
1424 int last_event = ifmgd->last_cqm_event_signal;
1425 int thold = bss_conf->cqm_rssi_thold;
1426 int hyst = bss_conf->cqm_rssi_hyst;
1427 if (sig < thold &&
1428 (last_event == 0 || sig < last_event - hyst)) {
1429 ifmgd->last_cqm_event_signal = sig;
1430 ieee80211_cqm_rssi_notify(
1431 &sdata->vif,
1432 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
1433 GFP_KERNEL);
1434 } else if (sig > thold &&
1435 (last_event == 0 || sig > last_event + hyst)) {
1436 ifmgd->last_cqm_event_signal = sig;
1437 ieee80211_cqm_rssi_notify(
1438 &sdata->vif,
1439 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
1440 GFP_KERNEL);
1441 }
1442 }
1443
1382 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { 1444 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
1383#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1445#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1384 if (net_ratelimit()) { 1446 if (net_ratelimit()) {
@@ -1664,7 +1726,7 @@ static void ieee80211_sta_work(struct work_struct *work)
1664 printk(KERN_DEBUG "No probe response from AP %pM" 1726 printk(KERN_DEBUG "No probe response from AP %pM"
1665 " after %dms, disconnecting.\n", 1727 " after %dms, disconnecting.\n",
1666 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 1728 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
1667 ieee80211_set_disassoc(sdata); 1729 ieee80211_set_disassoc(sdata, true);
1668 ieee80211_recalc_idle(local); 1730 ieee80211_recalc_idle(local);
1669 mutex_unlock(&ifmgd->mtx); 1731 mutex_unlock(&ifmgd->mtx);
1670 /* 1732 /*
@@ -1674,7 +1736,7 @@ static void ieee80211_sta_work(struct work_struct *work)
1674 ieee80211_send_deauth_disassoc(sdata, bssid, 1736 ieee80211_send_deauth_disassoc(sdata, bssid,
1675 IEEE80211_STYPE_DEAUTH, 1737 IEEE80211_STYPE_DEAUTH,
1676 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, 1738 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
1677 NULL); 1739 NULL, true);
1678 mutex_lock(&ifmgd->mtx); 1740 mutex_lock(&ifmgd->mtx);
1679 } 1741 }
1680 } 1742 }
@@ -1858,6 +1920,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
1858 struct ieee80211_work *wk; 1920 struct ieee80211_work *wk;
1859 u16 auth_alg; 1921 u16 auth_alg;
1860 1922
1923 if (req->local_state_change)
1924 return 0; /* no need to update mac80211 state */
1925
1861 switch (req->auth_type) { 1926 switch (req->auth_type) {
1862 case NL80211_AUTHTYPE_OPEN_SYSTEM: 1927 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1863 auth_alg = WLAN_AUTH_OPEN; 1928 auth_alg = WLAN_AUTH_OPEN;
@@ -1966,7 +2031,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
1966 } 2031 }
1967 2032
1968 /* Trying to reassociate - clear previous association state */ 2033 /* Trying to reassociate - clear previous association state */
1969 ieee80211_set_disassoc(sdata); 2034 ieee80211_set_disassoc(sdata, true);
1970 } 2035 }
1971 mutex_unlock(&ifmgd->mtx); 2036 mutex_unlock(&ifmgd->mtx);
1972 2037
@@ -2070,7 +2135,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2070 2135
2071 if (ifmgd->associated == req->bss) { 2136 if (ifmgd->associated == req->bss) {
2072 bssid = req->bss->bssid; 2137 bssid = req->bss->bssid;
2073 ieee80211_set_disassoc(sdata); 2138 ieee80211_set_disassoc(sdata, true);
2074 mutex_unlock(&ifmgd->mtx); 2139 mutex_unlock(&ifmgd->mtx);
2075 } else { 2140 } else {
2076 bool not_auth_yet = false; 2141 bool not_auth_yet = false;
@@ -2113,9 +2178,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2113 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n", 2178 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
2114 sdata->name, bssid, req->reason_code); 2179 sdata->name, bssid, req->reason_code);
2115 2180
2116 ieee80211_send_deauth_disassoc(sdata, bssid, 2181 ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH,
2117 IEEE80211_STYPE_DEAUTH, req->reason_code, 2182 req->reason_code, cookie,
2118 cookie); 2183 !req->local_state_change);
2119 2184
2120 ieee80211_recalc_idle(sdata->local); 2185 ieee80211_recalc_idle(sdata->local);
2121 2186
@@ -2127,6 +2192,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2127 void *cookie) 2192 void *cookie)
2128{ 2193{
2129 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2194 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2195 u8 bssid[ETH_ALEN];
2130 2196
2131 mutex_lock(&ifmgd->mtx); 2197 mutex_lock(&ifmgd->mtx);
2132 2198
@@ -2144,13 +2210,15 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2144 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n", 2210 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n",
2145 sdata->name, req->bss->bssid, req->reason_code); 2211 sdata->name, req->bss->bssid, req->reason_code);
2146 2212
2147 ieee80211_set_disassoc(sdata); 2213 memcpy(bssid, req->bss->bssid, ETH_ALEN);
2214 ieee80211_set_disassoc(sdata, false);
2148 2215
2149 mutex_unlock(&ifmgd->mtx); 2216 mutex_unlock(&ifmgd->mtx);
2150 2217
2151 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, 2218 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
2152 IEEE80211_STYPE_DISASSOC, req->reason_code, 2219 IEEE80211_STYPE_DISASSOC, req->reason_code,
2153 cookie); 2220 cookie, !req->local_state_change);
2221 sta_info_destroy_addr(sdata, bssid);
2154 2222
2155 ieee80211_recalc_idle(sdata->local); 2223 ieee80211_recalc_idle(sdata->local);
2156 2224
@@ -2198,6 +2266,8 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
2198{ 2266{
2199 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 2267 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
2200 2268
2269 trace_api_cqm_rssi_notify(sdata, rssi_event);
2270
2201 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); 2271 cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp);
2202} 2272}
2203EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); 2273EXPORT_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/rx.c b/net/mac80211/rx.c
index e0c944fb6fc9..72efbd87c1eb 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -39,7 +39,7 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
39{ 39{
40 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { 40 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
41 if (likely(skb->len > FCS_LEN)) 41 if (likely(skb->len > FCS_LEN))
42 skb_trim(skb, skb->len - FCS_LEN); 42 __pskb_trim(skb, skb->len - FCS_LEN);
43 else { 43 else {
44 /* driver bug */ 44 /* driver bug */
45 WARN_ON(1); 45 WARN_ON(1);
@@ -228,6 +228,12 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
228 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 228 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
229 present_fcs_len = FCS_LEN; 229 present_fcs_len = FCS_LEN;
230 230
231 /* make sure hdr->frame_control is on the linear part */
232 if (!pskb_may_pull(origskb, 2)) {
233 dev_kfree_skb(origskb);
234 return NULL;
235 }
236
231 if (!local->monitors) { 237 if (!local->monitors) {
232 if (should_drop_frame(origskb, present_fcs_len)) { 238 if (should_drop_frame(origskb, present_fcs_len)) {
233 dev_kfree_skb(origskb); 239 dev_kfree_skb(origskb);
@@ -485,7 +491,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
485 491
486 if (ieee80211_is_action(hdr->frame_control)) { 492 if (ieee80211_is_action(hdr->frame_control)) {
487 mgmt = (struct ieee80211_mgmt *)hdr; 493 mgmt = (struct ieee80211_mgmt *)hdr;
488 if (mgmt->u.action.category != MESH_PLINK_CATEGORY) 494 if (mgmt->u.action.category != WLAN_CATEGORY_MESH_PLINK)
489 return RX_DROP_MONITOR; 495 return RX_DROP_MONITOR;
490 return RX_CONTINUE; 496 return RX_CONTINUE;
491 } 497 }
@@ -715,14 +721,16 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
715 721
716 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 722 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
717 723
718 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) 724 spin_lock(&sta->lock);
719 goto dont_reorder; 725
726 if (!sta->ampdu_mlme.tid_active_rx[tid])
727 goto dont_reorder_unlock;
720 728
721 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; 729 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
722 730
723 /* qos null data frames are excluded */ 731 /* qos null data frames are excluded */
724 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) 732 if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
725 goto dont_reorder; 733 goto dont_reorder_unlock;
726 734
727 /* new, potentially un-ordered, ampdu frame - process it */ 735 /* new, potentially un-ordered, ampdu frame - process it */
728 736
@@ -734,15 +742,20 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx,
734 /* if this mpdu is fragmented - terminate rx aggregation session */ 742 /* if this mpdu is fragmented - terminate rx aggregation session */
735 sc = le16_to_cpu(hdr->seq_ctrl); 743 sc = le16_to_cpu(hdr->seq_ctrl);
736 if (sc & IEEE80211_SCTL_FRAG) { 744 if (sc & IEEE80211_SCTL_FRAG) {
737 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr, 745 spin_unlock(&sta->lock);
738 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP); 746 __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
747 WLAN_REASON_QSTA_REQUIRE_SETUP);
739 dev_kfree_skb(skb); 748 dev_kfree_skb(skb);
740 return; 749 return;
741 } 750 }
742 751
743 if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) 752 if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, frames)) {
753 spin_unlock(&sta->lock);
744 return; 754 return;
755 }
745 756
757 dont_reorder_unlock:
758 spin_unlock(&sta->lock);
746 dont_reorder: 759 dont_reorder:
747 __skb_queue_tail(frames, skb); 760 __skb_queue_tail(frames, skb);
748} 761}
@@ -889,6 +902,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
889 rx->key = key; 902 rx->key = key;
890 return RX_CONTINUE; 903 return RX_CONTINUE;
891 } else { 904 } else {
905 u8 keyid;
892 /* 906 /*
893 * The device doesn't give us the IV so we won't be 907 * The device doesn't give us the IV so we won't be
894 * able to look up the key. That's ok though, we 908 * able to look up the key. That's ok though, we
@@ -911,7 +925,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
911 * no need to call ieee80211_wep_get_keyidx, 925 * no need to call ieee80211_wep_get_keyidx,
912 * it verifies a bunch of things we've done already 926 * it verifies a bunch of things we've done already
913 */ 927 */
914 keyidx = rx->skb->data[hdrlen + 3] >> 6; 928 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
929 keyidx = keyid >> 6;
915 930
916 rx->key = rcu_dereference(rx->sdata->keys[keyidx]); 931 rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
917 932
@@ -932,6 +947,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
932 return RX_DROP_MONITOR; 947 return RX_DROP_MONITOR;
933 } 948 }
934 949
950 if (skb_linearize(rx->skb))
951 return RX_DROP_UNUSABLE;
952
953 hdr = (struct ieee80211_hdr *)rx->skb->data;
954
935 /* Check for weak IVs if possible */ 955 /* Check for weak IVs if possible */
936 if (rx->sta && rx->key->conf.alg == ALG_WEP && 956 if (rx->sta && rx->key->conf.alg == ALG_WEP &&
937 ieee80211_is_data(hdr->frame_control) && 957 ieee80211_is_data(hdr->frame_control) &&
@@ -1232,6 +1252,9 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1232 } 1252 }
1233 I802_DEBUG_INC(rx->local->rx_handlers_fragments); 1253 I802_DEBUG_INC(rx->local->rx_handlers_fragments);
1234 1254
1255 if (skb_linearize(rx->skb))
1256 return RX_DROP_UNUSABLE;
1257
1235 seq = (sc & IEEE80211_SCTL_SEQ) >> 4; 1258 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
1236 1259
1237 if (frag == 0) { 1260 if (frag == 0) {
@@ -1397,21 +1420,24 @@ static int
1397ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) 1420ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1398{ 1421{
1399 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 1422 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1423 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1400 __le16 fc = hdr->frame_control; 1424 __le16 fc = hdr->frame_control;
1401 int res;
1402 1425
1403 res = ieee80211_drop_unencrypted(rx, fc); 1426 /*
1404 if (unlikely(res)) 1427 * Pass through unencrypted frames if the hardware has
1405 return res; 1428 * decrypted them already.
1429 */
1430 if (status->flag & RX_FLAG_DECRYPTED)
1431 return 0;
1406 1432
1407 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { 1433 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
1408 if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && 1434 if (unlikely(!ieee80211_has_protected(fc) &&
1435 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1409 rx->key)) 1436 rx->key))
1410 return -EACCES; 1437 return -EACCES;
1411 /* BIP does not use Protected field, so need to check MMIE */ 1438 /* BIP does not use Protected field, so need to check MMIE */
1412 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && 1439 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
1413 ieee80211_get_mmie_keyidx(rx->skb) < 0 && 1440 ieee80211_get_mmie_keyidx(rx->skb) < 0))
1414 rx->key))
1415 return -EACCES; 1441 return -EACCES;
1416 /* 1442 /*
1417 * When using MFP, Action frames are not allowed prior to 1443 * When using MFP, Action frames are not allowed prior to
@@ -1589,6 +1615,9 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1589 skb->dev = dev; 1615 skb->dev = dev;
1590 __skb_queue_head_init(&frame_list); 1616 __skb_queue_head_init(&frame_list);
1591 1617
1618 if (skb_linearize(skb))
1619 return RX_DROP_UNUSABLE;
1620
1592 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, 1621 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
1593 rx->sdata->vif.type, 1622 rx->sdata->vif.type,
1594 rx->local->hw.extra_tx_headroom); 1623 rx->local->hw.extra_tx_headroom);
@@ -1787,10 +1816,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
1787 if (ieee80211_is_back_req(bar->frame_control)) { 1816 if (ieee80211_is_back_req(bar->frame_control)) {
1788 if (!rx->sta) 1817 if (!rx->sta)
1789 return RX_DROP_MONITOR; 1818 return RX_DROP_MONITOR;
1819 spin_lock(&rx->sta->lock);
1790 tid = le16_to_cpu(bar->control) >> 12; 1820 tid = le16_to_cpu(bar->control) >> 12;
1791 if (rx->sta->ampdu_mlme.tid_state_rx[tid] 1821 if (!rx->sta->ampdu_mlme.tid_active_rx[tid]) {
1792 != HT_AGG_STATE_OPERATIONAL) 1822 spin_unlock(&rx->sta->lock);
1793 return RX_DROP_MONITOR; 1823 return RX_DROP_MONITOR;
1824 }
1794 tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid]; 1825 tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid];
1795 1826
1796 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; 1827 start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
@@ -1804,6 +1835,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
1804 ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num, 1835 ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num,
1805 frames); 1836 frames);
1806 kfree_skb(skb); 1837 kfree_skb(skb);
1838 spin_unlock(&rx->sta->lock);
1807 return RX_QUEUED; 1839 return RX_QUEUED;
1808 } 1840 }
1809 1841
@@ -1965,8 +1997,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1965 goto handled; 1997 goto handled;
1966 } 1998 }
1967 break; 1999 break;
1968 case MESH_PLINK_CATEGORY: 2000 case WLAN_CATEGORY_MESH_PLINK:
1969 case MESH_PATH_SEL_CATEGORY: 2001 case WLAN_CATEGORY_MESH_PATH_SEL:
1970 if (ieee80211_vif_is_mesh(&sdata->vif)) 2002 if (ieee80211_vif_is_mesh(&sdata->vif))
1971 return ieee80211_mesh_rx_mgmt(sdata, rx->skb); 2003 return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
1972 break; 2004 break;
@@ -2363,29 +2395,42 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2363 struct ieee80211_local *local = hw_to_local(hw); 2395 struct ieee80211_local *local = hw_to_local(hw);
2364 struct ieee80211_sub_if_data *sdata; 2396 struct ieee80211_sub_if_data *sdata;
2365 struct ieee80211_hdr *hdr; 2397 struct ieee80211_hdr *hdr;
2398 __le16 fc;
2366 struct ieee80211_rx_data rx; 2399 struct ieee80211_rx_data rx;
2367 int prepares; 2400 int prepares;
2368 struct ieee80211_sub_if_data *prev = NULL; 2401 struct ieee80211_sub_if_data *prev = NULL;
2369 struct sk_buff *skb_new; 2402 struct sk_buff *skb_new;
2370 struct sta_info *sta, *tmp; 2403 struct sta_info *sta, *tmp;
2371 bool found_sta = false; 2404 bool found_sta = false;
2405 int err = 0;
2372 2406
2373 hdr = (struct ieee80211_hdr *)skb->data; 2407 fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
2374 memset(&rx, 0, sizeof(rx)); 2408 memset(&rx, 0, sizeof(rx));
2375 rx.skb = skb; 2409 rx.skb = skb;
2376 rx.local = local; 2410 rx.local = local;
2377 2411
2378 if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control)) 2412 if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
2379 local->dot11ReceivedFragmentCount++; 2413 local->dot11ReceivedFragmentCount++;
2380 2414
2381 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || 2415 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
2382 test_bit(SCAN_OFF_CHANNEL, &local->scanning))) 2416 test_bit(SCAN_OFF_CHANNEL, &local->scanning)))
2383 rx.flags |= IEEE80211_RX_IN_SCAN; 2417 rx.flags |= IEEE80211_RX_IN_SCAN;
2384 2418
2419 if (ieee80211_is_mgmt(fc))
2420 err = skb_linearize(skb);
2421 else
2422 err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
2423
2424 if (err) {
2425 dev_kfree_skb(skb);
2426 return;
2427 }
2428
2429 hdr = (struct ieee80211_hdr *)skb->data;
2385 ieee80211_parse_qos(&rx); 2430 ieee80211_parse_qos(&rx);
2386 ieee80211_verify_alignment(&rx); 2431 ieee80211_verify_alignment(&rx);
2387 2432
2388 if (ieee80211_is_data(hdr->frame_control)) { 2433 if (ieee80211_is_data(fc)) {
2389 for_each_sta_info(local, hdr->addr2, sta, tmp) { 2434 for_each_sta_info(local, hdr->addr2, sta, tmp) {
2390 rx.sta = sta; 2435 rx.sta = sta;
2391 found_sta = true; 2436 found_sta = true;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 1ce4ce8af80f..e1a3defdf581 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -248,6 +248,8 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
248 struct ieee80211_local *local = hw_to_local(hw); 248 struct ieee80211_local *local = hw_to_local(hw);
249 bool was_hw_scan; 249 bool was_hw_scan;
250 250
251 trace_api_scan_completed(local, aborted);
252
251 mutex_lock(&local->scan_mtx); 253 mutex_lock(&local->scan_mtx);
252 254
253 /* 255 /*
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index fb12cec4d333..ff0eb948917b 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -250,9 +250,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
250 * enable session_timer's data differentiation. refer to 250 * enable session_timer's data differentiation. refer to
251 * sta_rx_agg_session_timer_expired for useage */ 251 * sta_rx_agg_session_timer_expired for useage */
252 sta->timer_to_tid[i] = i; 252 sta->timer_to_tid[i] = i;
253 /* rx */
254 sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
255 sta->ampdu_mlme.tid_rx[i] = NULL;
256 /* tx */ 253 /* tx */
257 sta->ampdu_mlme.tid_state_tx[i] = HT_AGG_STATE_IDLE; 254 sta->ampdu_mlme.tid_state_tx[i] = HT_AGG_STATE_IDLE;
258 sta->ampdu_mlme.tid_tx[i] = NULL; 255 sta->ampdu_mlme.tid_tx[i] = NULL;
@@ -619,7 +616,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
619 struct ieee80211_sub_if_data *sdata; 616 struct ieee80211_sub_if_data *sdata;
620 struct sk_buff *skb; 617 struct sk_buff *skb;
621 unsigned long flags; 618 unsigned long flags;
622 int ret, i; 619 int ret;
623 620
624 might_sleep(); 621 might_sleep();
625 622
@@ -629,6 +626,15 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
629 local = sta->local; 626 local = sta->local;
630 sdata = sta->sdata; 627 sdata = sta->sdata;
631 628
629 /*
630 * Before removing the station from the driver and
631 * rate control, it might still start new aggregation
632 * sessions -- block that to make sure the tear-down
633 * will be sufficient.
634 */
635 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
636 ieee80211_sta_tear_down_BA_sessions(sta);
637
632 spin_lock_irqsave(&local->sta_lock, flags); 638 spin_lock_irqsave(&local->sta_lock, flags);
633 ret = sta_info_hash_del(local, sta); 639 ret = sta_info_hash_del(local, sta);
634 /* this might still be the pending list ... which is fine */ 640 /* this might still be the pending list ... which is fine */
@@ -645,9 +651,6 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
645 * may mean it is removed from hardware which requires that 651 * may mean it is removed from hardware which requires that
646 * the key->sta pointer is still valid, so flush the key todo 652 * the key->sta pointer is still valid, so flush the key todo
647 * list here. 653 * list here.
648 *
649 * ieee80211_key_todo() will synchronize_rcu() so after this
650 * nothing can reference this sta struct any more.
651 */ 654 */
652 ieee80211_key_todo(); 655 ieee80211_key_todo();
653 656
@@ -679,11 +682,17 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
679 sdata = sta->sdata; 682 sdata = sta->sdata;
680 } 683 }
681 684
685 /*
686 * At this point, after we wait for an RCU grace period,
687 * neither mac80211 nor the driver can reference this
688 * sta struct any more except by still existing timers
689 * associated with this station that we clean up below.
690 */
691 synchronize_rcu();
692
682#ifdef CONFIG_MAC80211_MESH 693#ifdef CONFIG_MAC80211_MESH
683 if (ieee80211_vif_is_mesh(&sdata->vif)) { 694 if (ieee80211_vif_is_mesh(&sdata->vif))
684 mesh_accept_plinks_update(sdata); 695 mesh_accept_plinks_update(sdata);
685 del_timer(&sta->plink_timer);
686 }
687#endif 696#endif
688 697
689#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 698#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -710,50 +719,6 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
710 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) 719 while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL)
711 dev_kfree_skb_any(skb); 720 dev_kfree_skb_any(skb);
712 721
713 for (i = 0; i < STA_TID_NUM; i++) {
714 struct tid_ampdu_rx *tid_rx;
715 struct tid_ampdu_tx *tid_tx;
716
717 spin_lock_bh(&sta->lock);
718 tid_rx = sta->ampdu_mlme.tid_rx[i];
719 /* Make sure timer won't free the tid_rx struct, see below */
720 if (tid_rx)
721 tid_rx->shutdown = true;
722
723 spin_unlock_bh(&sta->lock);
724
725 /*
726 * Outside spinlock - shutdown is true now so that the timer
727 * won't free tid_rx, we have to do that now. Can't let the
728 * timer do it because we have to sync the timer outside the
729 * lock that it takes itself.
730 */
731 if (tid_rx) {
732 del_timer_sync(&tid_rx->session_timer);
733 kfree(tid_rx);
734 }
735
736 /*
737 * No need to do such complications for TX agg sessions, the
738 * path leading to freeing the tid_tx struct goes via a call
739 * from the driver, and thus needs to look up the sta struct
740 * again, which cannot be found when we get here. Hence, we
741 * just need to delete the timer and free the aggregation
742 * info; we won't be telling the peer about it then but that
743 * doesn't matter if we're not talking to it again anyway.
744 */
745 tid_tx = sta->ampdu_mlme.tid_tx[i];
746 if (tid_tx) {
747 del_timer_sync(&tid_tx->addba_resp_timer);
748 /*
749 * STA removed while aggregation session being
750 * started? Bit odd, but purge frames anyway.
751 */
752 skb_queue_purge(&tid_tx->pending);
753 kfree(tid_tx);
754 }
755 }
756
757 __sta_info_free(local, sta); 722 __sta_info_free(local, sta);
758 723
759 return 0; 724 return 0;
@@ -992,6 +957,8 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
992{ 957{
993 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); 958 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
994 959
960 trace_api_sta_block_awake(sta->local, pubsta, block);
961
995 if (block) 962 if (block)
996 set_sta_flags(sta, WLAN_STA_PS_DRIVER); 963 set_sta_flags(sta, WLAN_STA_PS_DRIVER);
997 else 964 else
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 2b635909de5c..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];
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index db25fa9ef135..2cb77267f733 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -513,6 +513,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
513 else if (tx->sta && (key = rcu_dereference(tx->sta->key))) 513 else if (tx->sta && (key = rcu_dereference(tx->sta->key)))
514 tx->key = key; 514 tx->key = key;
515 else if (ieee80211_is_mgmt(hdr->frame_control) && 515 else if (ieee80211_is_mgmt(hdr->frame_control) &&
516 is_multicast_ether_addr(hdr->addr1) &&
517 ieee80211_is_robust_mgmt_frame(hdr) &&
516 (key = rcu_dereference(tx->sdata->default_mgmt_key))) 518 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
517 tx->key = key; 519 tx->key = key;
518 else if ((key = rcu_dereference(tx->sdata->default_key))) 520 else if ((key = rcu_dereference(tx->sdata->default_key)))
@@ -1142,13 +1144,12 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1142 1144
1143 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && 1145 if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
1144 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { 1146 (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) {
1145 unsigned long flags;
1146 struct tid_ampdu_tx *tid_tx; 1147 struct tid_ampdu_tx *tid_tx;
1147 1148
1148 qc = ieee80211_get_qos_ctl(hdr); 1149 qc = ieee80211_get_qos_ctl(hdr);
1149 tid = *qc & IEEE80211_QOS_CTL_TID_MASK; 1150 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
1150 1151
1151 spin_lock_irqsave(&tx->sta->lock, flags); 1152 spin_lock(&tx->sta->lock);
1152 /* 1153 /*
1153 * XXX: This spinlock could be fairly expensive, but see the 1154 * XXX: This spinlock could be fairly expensive, but see the
1154 * comment in agg-tx.c:ieee80211_agg_tx_operational(). 1155 * comment in agg-tx.c:ieee80211_agg_tx_operational().
@@ -1173,7 +1174,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1173 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1174 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1174 __skb_queue_tail(&tid_tx->pending, skb); 1175 __skb_queue_tail(&tid_tx->pending, skb);
1175 } 1176 }
1176 spin_unlock_irqrestore(&tx->sta->lock, flags); 1177 spin_unlock(&tx->sta->lock);
1177 1178
1178 if (unlikely(queued)) 1179 if (unlikely(queued))
1179 return TX_QUEUED; 1180 return TX_QUEUED;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 53af57047435..2b75b4fb68f4 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
@@ -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,
@@ -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
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 15e1ba931b87..bdb1d05b16fc 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -920,11 +920,16 @@ static void ieee80211_work_work(struct work_struct *work)
920 run_again(local, jiffies + HZ/2); 920 run_again(local, jiffies + HZ/2);
921 } 921 }
922 922
923 if (list_empty(&local->work_list) && local->scan_req) 923 mutex_lock(&local->scan_mtx);
924
925 if (list_empty(&local->work_list) && local->scan_req &&
926 !local->scanning)
924 ieee80211_queue_delayed_work(&local->hw, 927 ieee80211_queue_delayed_work(&local->hw,
925 &local->scan_work, 928 &local->scan_work,
926 round_jiffies_relative(0)); 929 round_jiffies_relative(0));
927 930
931 mutex_unlock(&local->scan_mtx);
932
928 mutex_unlock(&local->work_mtx); 933 mutex_unlock(&local->work_mtx);
929 934
930 ieee80211_recalc_idle(local); 935 ieee80211_recalc_idle(local);