aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-03-16 13:45:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-03-16 13:45:25 -0400
commit01a282980937f9ca55a3cb06b9c6ff1cc49ea396 (patch)
tree07a043edc861e245a7a9764751af0898a1f1199a /net
parentd5ddb4a59ed43b4c569b4efa8b508d50ef140cc6 (diff)
parent377526578f2c343ea281a918b18ece1fca65005c (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/ath/ath9k/hw.c
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/chan.c27
-rw-r--r--net/mac80211/debugfs.c81
-rw-r--r--net/mac80211/debugfs_netdev.c71
-rw-r--r--net/mac80211/driver-ops.h35
-rw-r--r--net/mac80211/driver-trace.h45
-rw-r--r--net/mac80211/ieee80211_i.h34
-rw-r--r--net/mac80211/main.c2
-rw-r--r--net/mac80211/mlme.c382
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c16
-rw-r--r--net/mac80211/rx.c21
-rw-r--r--net/mac80211/tx.c10
-rw-r--r--net/mac80211/wep.c21
-rw-r--r--net/mac80211/wep.h1
-rw-r--r--net/mac80211/wpa.c22
-rw-r--r--net/wireless/nl80211.c8
-rw-r--r--net/wireless/scan.c7
-rw-r--r--net/wireless/wext-sme.c3
17 files changed, 355 insertions, 431 deletions
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index d1f7abddb182..e00ce8c3e28e 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -3,6 +3,7 @@
3 */ 3 */
4 4
5#include <linux/nl80211.h> 5#include <linux/nl80211.h>
6#include <net/cfg80211.h>
6#include "ieee80211_i.h" 7#include "ieee80211_i.h"
7 8
8static enum ieee80211_chan_mode 9static enum ieee80211_chan_mode
@@ -134,3 +135,29 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
134 135
135 return result; 136 return result;
136} 137}
138
139/*
140 * ieee80211_get_tx_channel_type returns the channel type we should
141 * use for packet transmission, given the channel capability and
142 * whatever regulatory flags we have been given.
143 */
144enum nl80211_channel_type ieee80211_get_tx_channel_type(
145 struct ieee80211_local *local,
146 enum nl80211_channel_type channel_type)
147{
148 switch (channel_type) {
149 case NL80211_CHAN_HT40PLUS:
150 if (local->hw.conf.channel->flags &
151 IEEE80211_CHAN_NO_HT40PLUS)
152 return NL80211_CHAN_HT20;
153 break;
154 case NL80211_CHAN_HT40MINUS:
155 if (local->hw.conf.channel->flags &
156 IEEE80211_CHAN_NO_HT40MINUS)
157 return NL80211_CHAN_HT20;
158 break;
159 default:
160 break;
161 }
162 return channel_type;
163}
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 483e96ed95c1..cc5b7a6e7e0b 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -97,85 +97,6 @@ static const struct file_operations reset_ops = {
97 .llseek = noop_llseek, 97 .llseek = noop_llseek,
98}; 98};
99 99
100static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf,
101 size_t count, loff_t *ppos)
102{
103 struct ieee80211_local *local = file->private_data;
104 return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n",
105 local->uapsd_queues);
106}
107
108static ssize_t uapsd_queues_write(struct file *file,
109 const char __user *user_buf,
110 size_t count, loff_t *ppos)
111{
112 struct ieee80211_local *local = file->private_data;
113 u8 val;
114 int ret;
115
116 ret = kstrtou8_from_user(user_buf, count, 0, &val);
117 if (ret)
118 return ret;
119
120 if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
121 return -ERANGE;
122
123 local->uapsd_queues = val;
124
125 return count;
126}
127
128static const struct file_operations uapsd_queues_ops = {
129 .read = uapsd_queues_read,
130 .write = uapsd_queues_write,
131 .open = mac80211_open_file_generic,
132 .llseek = default_llseek,
133};
134
135static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf,
136 size_t count, loff_t *ppos)
137{
138 struct ieee80211_local *local = file->private_data;
139
140 return mac80211_format_buffer(user_buf, count, ppos, "0x%x\n",
141 local->uapsd_max_sp_len);
142}
143
144static ssize_t uapsd_max_sp_len_write(struct file *file,
145 const char __user *user_buf,
146 size_t count, loff_t *ppos)
147{
148 struct ieee80211_local *local = file->private_data;
149 unsigned long val;
150 char buf[10];
151 size_t len;
152 int ret;
153
154 len = min(count, sizeof(buf) - 1);
155 if (copy_from_user(buf, user_buf, len))
156 return -EFAULT;
157 buf[len] = '\0';
158
159 ret = kstrtoul(buf, 0, &val);
160
161 if (ret)
162 return -EINVAL;
163
164 if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
165 return -ERANGE;
166
167 local->uapsd_max_sp_len = val;
168
169 return count;
170}
171
172static const struct file_operations uapsd_max_sp_len_ops = {
173 .read = uapsd_max_sp_len_read,
174 .write = uapsd_max_sp_len_write,
175 .open = mac80211_open_file_generic,
176 .llseek = default_llseek,
177};
178
179static ssize_t channel_type_read(struct file *file, char __user *user_buf, 100static ssize_t channel_type_read(struct file *file, char __user *user_buf,
180 size_t count, loff_t *ppos) 101 size_t count, loff_t *ppos)
181{ 102{
@@ -362,8 +283,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
362 DEBUGFS_ADD(wep_iv); 283 DEBUGFS_ADD(wep_iv);
363 DEBUGFS_ADD(queues); 284 DEBUGFS_ADD(queues);
364 DEBUGFS_ADD_MODE(reset, 0200); 285 DEBUGFS_ADD_MODE(reset, 0200);
365 DEBUGFS_ADD(uapsd_queues);
366 DEBUGFS_ADD(uapsd_max_sp_len);
367 DEBUGFS_ADD(channel_type); 286 DEBUGFS_ADD(channel_type);
368 DEBUGFS_ADD(hwflags); 287 DEBUGFS_ADD(hwflags);
369 DEBUGFS_ADD(user_power); 288 DEBUGFS_ADD(user_power);
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index f6de8a65f402..a32eeda04aa3 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -49,16 +49,15 @@ static ssize_t ieee80211_if_write(
49 size_t count, loff_t *ppos, 49 size_t count, loff_t *ppos,
50 ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int)) 50 ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int))
51{ 51{
52 u8 *buf; 52 char buf[64];
53 ssize_t ret; 53 ssize_t ret;
54 54
55 buf = kmalloc(count, GFP_KERNEL); 55 if (count >= sizeof(buf))
56 if (!buf) 56 return -E2BIG;
57 return -ENOMEM;
58 57
59 ret = -EFAULT;
60 if (copy_from_user(buf, userbuf, count)) 58 if (copy_from_user(buf, userbuf, count))
61 goto freebuf; 59 return -EFAULT;
60 buf[count] = '\0';
62 61
63 ret = -ENODEV; 62 ret = -ENODEV;
64 rtnl_lock(); 63 rtnl_lock();
@@ -66,8 +65,6 @@ static ssize_t ieee80211_if_write(
66 ret = (*write)(sdata, buf, count); 65 ret = (*write)(sdata, buf, count);
67 rtnl_unlock(); 66 rtnl_unlock();
68 67
69freebuf:
70 kfree(buf);
71 return ret; 68 return ret;
72} 69}
73 70
@@ -340,6 +337,62 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
340 337
341__IEEE80211_IF_FILE_W(tkip_mic_test); 338__IEEE80211_IF_FILE_W(tkip_mic_test);
342 339
340static ssize_t ieee80211_if_fmt_uapsd_queues(
341 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
342{
343 const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
344
345 return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_queues);
346}
347
348static ssize_t ieee80211_if_parse_uapsd_queues(
349 struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
350{
351 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
352 u8 val;
353 int ret;
354
355 ret = kstrtou8(buf, 0, &val);
356 if (ret)
357 return ret;
358
359 if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
360 return -ERANGE;
361
362 ifmgd->uapsd_queues = val;
363
364 return buflen;
365}
366__IEEE80211_IF_FILE_W(uapsd_queues);
367
368static ssize_t ieee80211_if_fmt_uapsd_max_sp_len(
369 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
370{
371 const struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
372
373 return snprintf(buf, buflen, "0x%x\n", ifmgd->uapsd_max_sp_len);
374}
375
376static ssize_t ieee80211_if_parse_uapsd_max_sp_len(
377 struct ieee80211_sub_if_data *sdata, const char *buf, int buflen)
378{
379 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
380 unsigned long val;
381 int ret;
382
383 ret = kstrtoul(buf, 0, &val);
384 if (ret)
385 return -EINVAL;
386
387 if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
388 return -ERANGE;
389
390 ifmgd->uapsd_max_sp_len = val;
391
392 return buflen;
393}
394__IEEE80211_IF_FILE_W(uapsd_max_sp_len);
395
343/* AP attributes */ 396/* AP attributes */
344IEEE80211_IF_FILE(num_sta_authorized, u.ap.num_sta_authorized, ATOMIC); 397IEEE80211_IF_FILE(num_sta_authorized, u.ap.num_sta_authorized, ATOMIC);
345IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); 398IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
@@ -472,6 +525,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
472 DEBUGFS_ADD(ave_beacon); 525 DEBUGFS_ADD(ave_beacon);
473 DEBUGFS_ADD_MODE(smps, 0600); 526 DEBUGFS_ADD_MODE(smps, 0600);
474 DEBUGFS_ADD_MODE(tkip_mic_test, 0200); 527 DEBUGFS_ADD_MODE(tkip_mic_test, 0200);
528 DEBUGFS_ADD_MODE(uapsd_queues, 0600);
529 DEBUGFS_ADD_MODE(uapsd_max_sp_len, 0600);
475} 530}
476 531
477static void add_ap_files(struct ieee80211_sub_if_data *sdata) 532static void add_ap_files(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 70dfb6415c20..af4691fed645 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -168,41 +168,6 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
168 trace_drv_return_void(local); 168 trace_drv_return_void(local);
169} 169}
170 170
171static inline int drv_tx_sync(struct ieee80211_local *local,
172 struct ieee80211_sub_if_data *sdata,
173 const u8 *bssid,
174 enum ieee80211_tx_sync_type type)
175{
176 int ret = 0;
177
178 might_sleep();
179
180 check_sdata_in_driver(sdata);
181
182 trace_drv_tx_sync(local, sdata, bssid, type);
183 if (local->ops->tx_sync)
184 ret = local->ops->tx_sync(&local->hw, &sdata->vif,
185 bssid, type);
186 trace_drv_return_int(local, ret);
187 return ret;
188}
189
190static inline void drv_finish_tx_sync(struct ieee80211_local *local,
191 struct ieee80211_sub_if_data *sdata,
192 const u8 *bssid,
193 enum ieee80211_tx_sync_type type)
194{
195 might_sleep();
196
197 check_sdata_in_driver(sdata);
198
199 trace_drv_finish_tx_sync(local, sdata, bssid, type);
200 if (local->ops->finish_tx_sync)
201 local->ops->finish_tx_sync(&local->hw, &sdata->vif,
202 bssid, type);
203 trace_drv_return_void(local);
204}
205
206static inline u64 drv_prepare_multicast(struct ieee80211_local *local, 171static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
207 struct netdev_hw_addr_list *mc_list) 172 struct netdev_hw_addr_list *mc_list)
208{ 173{
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 384e2f08c187..21d6f5290a1c 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -296,7 +296,7 @@ TRACE_EVENT(drv_bss_info_changed,
296 __entry->dtimper = info->dtim_period; 296 __entry->dtimper = info->dtim_period;
297 __entry->bcnint = info->beacon_int; 297 __entry->bcnint = info->beacon_int;
298 __entry->assoc_cap = info->assoc_capability; 298 __entry->assoc_cap = info->assoc_capability;
299 __entry->timestamp = info->timestamp; 299 __entry->timestamp = info->last_tsf;
300 __entry->basic_rates = info->basic_rates; 300 __entry->basic_rates = info->basic_rates;
301 __entry->enable_beacon = info->enable_beacon; 301 __entry->enable_beacon = info->enable_beacon;
302 __entry->ht_operation_mode = info->ht_operation_mode; 302 __entry->ht_operation_mode = info->ht_operation_mode;
@@ -308,49 +308,6 @@ TRACE_EVENT(drv_bss_info_changed,
308 ) 308 )
309); 309);
310 310
311DECLARE_EVENT_CLASS(tx_sync_evt,
312 TP_PROTO(struct ieee80211_local *local,
313 struct ieee80211_sub_if_data *sdata,
314 const u8 *bssid,
315 enum ieee80211_tx_sync_type type),
316 TP_ARGS(local, sdata, bssid, type),
317
318 TP_STRUCT__entry(
319 LOCAL_ENTRY
320 VIF_ENTRY
321 __array(char, bssid, ETH_ALEN)
322 __field(u32, sync_type)
323 ),
324
325 TP_fast_assign(
326 LOCAL_ASSIGN;
327 VIF_ASSIGN;
328 memcpy(__entry->bssid, bssid, ETH_ALEN);
329 __entry->sync_type = type;
330 ),
331
332 TP_printk(
333 LOCAL_PR_FMT VIF_PR_FMT " bssid:%pM type:%d",
334 LOCAL_PR_ARG, VIF_PR_ARG, __entry->bssid, __entry->sync_type
335 )
336);
337
338DEFINE_EVENT(tx_sync_evt, drv_tx_sync,
339 TP_PROTO(struct ieee80211_local *local,
340 struct ieee80211_sub_if_data *sdata,
341 const u8 *bssid,
342 enum ieee80211_tx_sync_type type),
343 TP_ARGS(local, sdata, bssid, type)
344);
345
346DEFINE_EVENT(tx_sync_evt, drv_finish_tx_sync,
347 TP_PROTO(struct ieee80211_local *local,
348 struct ieee80211_sub_if_data *sdata,
349 const u8 *bssid,
350 enum ieee80211_tx_sync_type type),
351 TP_ARGS(local, sdata, bssid, type)
352);
353
354TRACE_EVENT(drv_prepare_multicast, 311TRACE_EVENT(drv_prepare_multicast,
355 TP_PROTO(struct ieee80211_local *local, int mc_count), 312 TP_PROTO(struct ieee80211_local *local, int mc_count),
356 313
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 796b13bfc953..d9798a307f20 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -388,7 +388,6 @@ struct ieee80211_mgd_auth_data {
388 388
389 u8 key[WLAN_KEY_LEN_WEP104]; 389 u8 key[WLAN_KEY_LEN_WEP104];
390 u8 key_len, key_idx; 390 u8 key_len, key_idx;
391 bool synced;
392 bool done; 391 bool done;
393 392
394 size_t ie_len; 393 size_t ie_len;
@@ -408,7 +407,7 @@ struct ieee80211_mgd_assoc_data {
408 u8 ssid[IEEE80211_MAX_SSID_LEN]; 407 u8 ssid[IEEE80211_MAX_SSID_LEN];
409 u8 ssid_len; 408 u8 ssid_len;
410 u8 supp_rates_len; 409 u8 supp_rates_len;
411 bool wmm_used, uapsd_used; 410 bool wmm, uapsd;
412 bool have_beacon; 411 bool have_beacon;
413 bool sent_assoc; 412 bool sent_assoc;
414 bool synced; 413 bool synced;
@@ -460,6 +459,20 @@ struct ieee80211_if_managed {
460 IEEE80211_MFP_REQUIRED 459 IEEE80211_MFP_REQUIRED
461 } mfp; /* management frame protection */ 460 } mfp; /* management frame protection */
462 461
462 /*
463 * Bitmask of enabled u-apsd queues,
464 * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association
465 * to take effect.
466 */
467 unsigned int uapsd_queues;
468
469 /*
470 * Maximum number of buffered frames AP can deliver during a
471 * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar.
472 * Needs a new association to take effect.
473 */
474 unsigned int uapsd_max_sp_len;
475
463 int wmm_last_param_set; 476 int wmm_last_param_set;
464 477
465 u8 use_4addr; 478 u8 use_4addr;
@@ -1018,20 +1031,6 @@ struct ieee80211_local {
1018 */ 1031 */
1019 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ 1032 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
1020 1033
1021 /*
1022 * Bitmask of enabled u-apsd queues,
1023 * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association
1024 * to take effect.
1025 */
1026 unsigned int uapsd_queues;
1027
1028 /*
1029 * Maximum number of buffered frames AP can deliver during a
1030 * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar.
1031 * Needs a new association to take effect.
1032 */
1033 unsigned int uapsd_max_sp_len;
1034
1035 bool pspolling; 1034 bool pspolling;
1036 bool offchannel_ps_enabled; 1035 bool offchannel_ps_enabled;
1037 /* 1036 /*
@@ -1503,6 +1502,9 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
1503 enum nl80211_channel_type chantype); 1502 enum nl80211_channel_type chantype);
1504enum nl80211_channel_type 1503enum nl80211_channel_type
1505ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info); 1504ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info);
1505enum nl80211_channel_type ieee80211_get_tx_channel_type(
1506 struct ieee80211_local *local,
1507 enum nl80211_channel_type channel_type);
1506 1508
1507#ifdef CONFIG_MAC80211_NOINLINE 1509#ifdef CONFIG_MAC80211_NOINLINE
1508#define debug_noinline noinline 1510#define debug_noinline noinline
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 36fa8051296c..b581a24fa15c 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -595,8 +595,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
595 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; 595 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
596 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; 596 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
597 local->user_power_level = -1; 597 local->user_power_level = -1;
598 local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
599 local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
600 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; 598 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
601 599
602 INIT_LIST_HEAD(&local->interfaces); 600 INIT_LIST_HEAD(&local->interfaces);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c08924aeac00..576fb25456dd 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -189,40 +189,35 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
189 u16 ht_opmode; 189 u16 ht_opmode;
190 bool enable_ht = true; 190 bool enable_ht = true;
191 enum nl80211_channel_type prev_chantype; 191 enum nl80211_channel_type prev_chantype;
192 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 192 enum nl80211_channel_type rx_channel_type = NL80211_CHAN_NO_HT;
193 enum nl80211_channel_type tx_channel_type;
193 194
194 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 195 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
195
196 prev_chantype = sdata->vif.bss_conf.channel_type; 196 prev_chantype = sdata->vif.bss_conf.channel_type;
197 197
198 /* HT is not supported */
199 if (!sband->ht_cap.ht_supported)
200 enable_ht = false;
201 198
202 if (enable_ht) { 199 hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan,
203 hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan, 200 sband->band);
204 sband->band); 201 /* check that channel matches the right operating channel */
205 /* check that channel matches the right operating channel */ 202 if (local->hw.conf.channel->center_freq != hti_cfreq) {
206 if (local->hw.conf.channel->center_freq != hti_cfreq) { 203 /* Some APs mess this up, evidently.
207 /* Some APs mess this up, evidently. 204 * Netgear WNDR3700 sometimes reports 4 higher than
208 * Netgear WNDR3700 sometimes reports 4 higher than 205 * the actual channel, for instance.
209 * the actual channel, for instance. 206 */
210 */ 207 printk(KERN_DEBUG
211 printk(KERN_DEBUG 208 "%s: Wrong control channel in association"
212 "%s: Wrong control channel in association" 209 " response: configured center-freq: %d"
213 " response: configured center-freq: %d" 210 " hti-cfreq: %d hti->control_chan: %d"
214 " hti-cfreq: %d hti->control_chan: %d" 211 " band: %d. Disabling HT.\n",
215 " band: %d. Disabling HT.\n", 212 sdata->name,
216 sdata->name, 213 local->hw.conf.channel->center_freq,
217 local->hw.conf.channel->center_freq, 214 hti_cfreq, hti->control_chan,
218 hti_cfreq, hti->control_chan, 215 sband->band);
219 sband->band); 216 enable_ht = false;
220 enable_ht = false;
221 }
222 } 217 }
223 218
224 if (enable_ht) { 219 if (enable_ht) {
225 channel_type = NL80211_CHAN_HT20; 220 rx_channel_type = NL80211_CHAN_HT20;
226 221
227 if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && 222 if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
228 !ieee80111_cfg_override_disables_ht40(sdata) && 223 !ieee80111_cfg_override_disables_ht40(sdata) &&
@@ -230,29 +225,28 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
230 (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { 225 (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
231 switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { 226 switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
232 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: 227 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
233 if (!(local->hw.conf.channel->flags & 228 rx_channel_type = NL80211_CHAN_HT40PLUS;
234 IEEE80211_CHAN_NO_HT40PLUS))
235 channel_type = NL80211_CHAN_HT40PLUS;
236 break; 229 break;
237 case IEEE80211_HT_PARAM_CHA_SEC_BELOW: 230 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
238 if (!(local->hw.conf.channel->flags & 231 rx_channel_type = NL80211_CHAN_HT40MINUS;
239 IEEE80211_CHAN_NO_HT40MINUS))
240 channel_type = NL80211_CHAN_HT40MINUS;
241 break; 232 break;
242 } 233 }
243 } 234 }
244 } 235 }
245 236
237 tx_channel_type = ieee80211_get_tx_channel_type(local, rx_channel_type);
238
246 if (local->tmp_channel) 239 if (local->tmp_channel)
247 local->tmp_channel_type = channel_type; 240 local->tmp_channel_type = rx_channel_type;
248 241
249 if (!ieee80211_set_channel_type(local, sdata, channel_type)) { 242 if (!ieee80211_set_channel_type(local, sdata, rx_channel_type)) {
250 /* can only fail due to HT40+/- mismatch */ 243 /* can only fail due to HT40+/- mismatch */
251 channel_type = NL80211_CHAN_HT20; 244 rx_channel_type = NL80211_CHAN_HT20;
252 WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); 245 WARN_ON(!ieee80211_set_channel_type(local, sdata,
246 rx_channel_type));
253 } 247 }
254 248
255 if (beacon_htcap_ie && (prev_chantype != channel_type)) { 249 if (beacon_htcap_ie && (prev_chantype != rx_channel_type)) {
256 /* 250 /*
257 * Whenever the AP announces the HT mode change that can be 251 * Whenever the AP announces the HT mode change that can be
258 * 40MHz intolerant or etc., it would be safer to stop tx 252 * 40MHz intolerant or etc., it would be safer to stop tx
@@ -270,13 +264,13 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
270 /* channel_type change automatically detected */ 264 /* channel_type change automatically detected */
271 ieee80211_hw_config(local, 0); 265 ieee80211_hw_config(local, 0);
272 266
273 if (prev_chantype != channel_type) { 267 if (prev_chantype != tx_channel_type) {
274 rcu_read_lock(); 268 rcu_read_lock();
275 sta = sta_info_get(sdata, bssid); 269 sta = sta_info_get(sdata, bssid);
276 if (sta) 270 if (sta)
277 rate_control_rate_update(local, sband, sta, 271 rate_control_rate_update(local, sband, sta,
278 IEEE80211_RC_HT_CHANGED, 272 IEEE80211_RC_HT_CHANGED,
279 channel_type); 273 tx_channel_type);
280 rcu_read_unlock(); 274 rcu_read_unlock();
281 275
282 if (beacon_htcap_ie) 276 if (beacon_htcap_ie)
@@ -289,7 +283,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
289 /* if bss configuration changed store the new one */ 283 /* if bss configuration changed store the new one */
290 if (sdata->ht_opmode_valid != enable_ht || 284 if (sdata->ht_opmode_valid != enable_ht ||
291 sdata->vif.bss_conf.ht_operation_mode != ht_opmode || 285 sdata->vif.bss_conf.ht_operation_mode != ht_opmode ||
292 prev_chantype != channel_type) { 286 prev_chantype != rx_channel_type) {
293 changed |= BSS_CHANGED_HT; 287 changed |= BSS_CHANGED_HT;
294 sdata->vif.bss_conf.ht_operation_mode = ht_opmode; 288 sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
295 sdata->ht_opmode_valid = enable_ht; 289 sdata->ht_opmode_valid = enable_ht;
@@ -335,9 +329,6 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
335 329
336 BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap)); 330 BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
337 331
338 if (!sband->ht_cap.ht_supported)
339 return;
340
341 if (!ht_info_ie) 332 if (!ht_info_ie)
342 return; 333 return;
343 334
@@ -405,7 +396,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
405 u16 capab; 396 u16 capab;
406 struct ieee80211_supported_band *sband; 397 struct ieee80211_supported_band *sband;
407 u32 rates = 0; 398 u32 rates = 0;
408 struct ieee80211_bss *bss = (void *)assoc_data->bss->priv;
409 399
410 lockdep_assert_held(&ifmgd->mtx); 400 lockdep_assert_held(&ifmgd->mtx);
411 401
@@ -566,8 +556,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
566 offset = noffset; 556 offset = noffset;
567 } 557 }
568 558
569 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N) && 559 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
570 bss->wmm_used && local->hw.queues >= 4)
571 ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie, 560 ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie,
572 sband, local->oper_channel, ifmgd->ap_smps); 561 sband, local->oper_channel, ifmgd->ap_smps);
573 562
@@ -581,10 +570,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
581 offset = noffset; 570 offset = noffset;
582 } 571 }
583 572
584 if (assoc_data->wmm_used && local->hw.queues >= 4) { 573 if (assoc_data->wmm) {
585 if (assoc_data->uapsd_used) { 574 if (assoc_data->uapsd) {
586 qos_info = local->uapsd_queues; 575 qos_info = ifmgd->uapsd_queues;
587 qos_info |= (local->uapsd_max_sp_len << 576 qos_info |= (ifmgd->uapsd_max_sp_len <<
588 IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT); 577 IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
589 } else { 578 } else {
590 qos_info = 0; 579 qos_info = 0;
@@ -1203,7 +1192,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
1203 return; 1192 return;
1204 1193
1205 if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) 1194 if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
1206 uapsd_queues = local->uapsd_queues; 1195 uapsd_queues = ifmgd->uapsd_queues;
1207 1196
1208 count = wmm_param[6] & 0x0f; 1197 count = wmm_param[6] & 0x0f;
1209 if (count == ifmgd->wmm_last_param_set) 1198 if (count == ifmgd->wmm_last_param_set)
@@ -1329,7 +1318,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1329 bss_info_changed |= BSS_CHANGED_ASSOC; 1318 bss_info_changed |= BSS_CHANGED_ASSOC;
1330 /* set timing information */ 1319 /* set timing information */
1331 bss_conf->beacon_int = cbss->beacon_interval; 1320 bss_conf->beacon_int = cbss->beacon_interval;
1332 bss_conf->timestamp = cbss->tsf; 1321 bss_conf->last_tsf = cbss->tsf;
1333 1322
1334 bss_info_changed |= BSS_CHANGED_BEACON_INT; 1323 bss_info_changed |= BSS_CHANGED_BEACON_INT;
1335 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 1324 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
@@ -1355,15 +1344,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1355 bss_conf->dtim_period = 0; 1344 bss_conf->dtim_period = 0;
1356 1345
1357 bss_conf->assoc = 1; 1346 bss_conf->assoc = 1;
1358 /*
1359 * For now just always ask the driver to update the basic rateset
1360 * when we have associated, we aren't checking whether it actually
1361 * changed or not.
1362 */
1363 bss_info_changed |= BSS_CHANGED_BASIC_RATES;
1364
1365 /* And the BSSID changed - we're associated now */
1366 bss_info_changed |= BSS_CHANGED_BSSID;
1367 1347
1368 /* Tell the driver to monitor connection quality (if supported) */ 1348 /* Tell the driver to monitor connection quality (if supported) */
1369 if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI && 1349 if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI &&
@@ -1394,7 +1374,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1394 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1374 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1395 struct ieee80211_local *local = sdata->local; 1375 struct ieee80211_local *local = sdata->local;
1396 struct sta_info *sta; 1376 struct sta_info *sta;
1397 u32 changed = 0, config_changed = 0; 1377 u32 changed = 0;
1398 u8 bssid[ETH_ALEN]; 1378 u8 bssid[ETH_ALEN];
1399 1379
1400 ASSERT_MGD_MTX(ifmgd); 1380 ASSERT_MGD_MTX(ifmgd);
@@ -1454,9 +1434,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1454 changed |= BSS_CHANGED_ASSOC; 1434 changed |= BSS_CHANGED_ASSOC;
1455 sdata->vif.bss_conf.assoc = false; 1435 sdata->vif.bss_conf.assoc = false;
1456 1436
1457 /* channel(_type) changes are handled by ieee80211_hw_config */
1458 WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
1459
1460 /* on the next assoc, re-program HT parameters */ 1437 /* on the next assoc, re-program HT parameters */
1461 sdata->ht_opmode_valid = false; 1438 sdata->ht_opmode_valid = false;
1462 memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa)); 1439 memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
@@ -1469,12 +1446,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1469 1446
1470 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 1447 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
1471 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 1448 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
1472 config_changed |= IEEE80211_CONF_CHANGE_PS; 1449 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
1473 } 1450 }
1474 local->ps_sdata = NULL; 1451 local->ps_sdata = NULL;
1475 1452
1476 ieee80211_hw_config(local, config_changed);
1477
1478 /* Disable ARP filtering */ 1453 /* Disable ARP filtering */
1479 if (sdata->vif.bss_conf.arp_filter_enabled) { 1454 if (sdata->vif.bss_conf.arp_filter_enabled) {
1480 sdata->vif.bss_conf.arp_filter_enabled = false; 1455 sdata->vif.bss_conf.arp_filter_enabled = false;
@@ -1488,6 +1463,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1488 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; 1463 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
1489 ieee80211_bss_info_change_notify(sdata, changed); 1464 ieee80211_bss_info_change_notify(sdata, changed);
1490 1465
1466 /* channel(_type) changes are handled by ieee80211_hw_config */
1467 WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
1468 ieee80211_hw_config(local, 0);
1469
1491 /* disassociated - set to defaults now */ 1470 /* disassociated - set to defaults now */
1492 ieee80211_set_wmm_default(sdata, false); 1471 ieee80211_set_wmm_default(sdata, false);
1493 1472
@@ -1770,11 +1749,6 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
1770 1749
1771 lockdep_assert_held(&sdata->u.mgd.mtx); 1750 lockdep_assert_held(&sdata->u.mgd.mtx);
1772 1751
1773 if (auth_data->synced)
1774 drv_finish_tx_sync(sdata->local, sdata,
1775 auth_data->bss->bssid,
1776 IEEE80211_TX_SYNC_AUTH);
1777
1778 if (!assoc) { 1752 if (!assoc) {
1779 sta_info_destroy_addr(sdata, auth_data->bss->bssid); 1753 sta_info_destroy_addr(sdata, auth_data->bss->bssid);
1780 1754
@@ -1862,10 +1836,6 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1862 1836
1863 printk(KERN_DEBUG "%s: authenticated\n", sdata->name); 1837 printk(KERN_DEBUG "%s: authenticated\n", sdata->name);
1864 out: 1838 out:
1865 if (ifmgd->auth_data->synced)
1866 drv_finish_tx_sync(sdata->local, sdata, bssid,
1867 IEEE80211_TX_SYNC_AUTH);
1868 ifmgd->auth_data->synced = false;
1869 ifmgd->auth_data->done = true; 1839 ifmgd->auth_data->done = true;
1870 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; 1840 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
1871 run_again(ifmgd, ifmgd->auth_data->timeout); 1841 run_again(ifmgd, ifmgd->auth_data->timeout);
@@ -2005,11 +1975,6 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
2005 1975
2006 lockdep_assert_held(&sdata->u.mgd.mtx); 1976 lockdep_assert_held(&sdata->u.mgd.mtx);
2007 1977
2008 if (assoc_data->synced)
2009 drv_finish_tx_sync(sdata->local, sdata,
2010 assoc_data->bss->bssid,
2011 IEEE80211_TX_SYNC_ASSOC);
2012
2013 if (!assoc) { 1978 if (!assoc) {
2014 sta_info_destroy_addr(sdata, assoc_data->bss->bssid); 1979 sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
2015 1980
@@ -2030,15 +1995,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2030 struct ieee80211_supported_band *sband; 1995 struct ieee80211_supported_band *sband;
2031 struct sta_info *sta; 1996 struct sta_info *sta;
2032 u8 *pos; 1997 u8 *pos;
2033 u32 rates, basic_rates;
2034 u16 capab_info, aid; 1998 u16 capab_info, aid;
2035 struct ieee802_11_elems elems; 1999 struct ieee802_11_elems elems;
2036 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 2000 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
2037 u32 changed = 0; 2001 u32 changed = 0;
2038 int err; 2002 int err;
2039 bool have_higher_than_11mbit = false;
2040 u16 ap_ht_cap_flags; 2003 u16 ap_ht_cap_flags;
2041 int min_rate = INT_MAX, min_rate_index = -1;
2042 2004
2043 /* AssocResp and ReassocResp have identical structure */ 2005 /* AssocResp and ReassocResp have identical structure */
2044 2006
@@ -2083,39 +2045,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2083 return false; 2045 return false;
2084 } 2046 }
2085 2047
2086 rates = 0;
2087 basic_rates = 0;
2088 sband = local->hw.wiphy->bands[local->oper_channel->band]; 2048 sband = local->hw.wiphy->bands[local->oper_channel->band];
2089 2049
2090 ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len,
2091 &rates, &basic_rates, &have_higher_than_11mbit,
2092 &min_rate, &min_rate_index);
2093
2094 ieee80211_get_rates(sband, elems.ext_supp_rates,
2095 elems.ext_supp_rates_len, &rates, &basic_rates,
2096 &have_higher_than_11mbit,
2097 &min_rate, &min_rate_index);
2098
2099 /*
2100 * some buggy APs don't advertise basic_rates. use the lowest
2101 * supported rate instead.
2102 */
2103 if (unlikely(!basic_rates) && min_rate_index >= 0) {
2104 printk(KERN_DEBUG "%s: No basic rates in AssocResp. "
2105 "Using min supported rate instead.\n", sdata->name);
2106 basic_rates = BIT(min_rate_index);
2107 }
2108
2109 sta->sta.supp_rates[local->oper_channel->band] = rates;
2110 sdata->vif.bss_conf.basic_rates = basic_rates;
2111
2112 /* cf. IEEE 802.11 9.2.12 */
2113 if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
2114 have_higher_than_11mbit)
2115 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
2116 else
2117 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
2118
2119 if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2050 if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
2120 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 2051 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
2121 elems.ht_cap_elem, &sta->sta.ht_cap); 2052 elems.ht_cap_elem, &sta->sta.ht_cap);
@@ -2162,7 +2093,6 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2162 changed |= BSS_CHANGED_QOS; 2093 changed |= BSS_CHANGED_QOS;
2163 2094
2164 if (elems.ht_info_elem && elems.wmm_param && 2095 if (elems.ht_info_elem && elems.wmm_param &&
2165 (sdata->local->hw.queues >= 4) &&
2166 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2096 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
2167 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, 2097 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
2168 cbss->bssid, ap_ht_cap_flags, 2098 cbss->bssid, ap_ht_cap_flags,
@@ -2255,14 +2185,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2255 } else { 2185 } else {
2256 printk(KERN_DEBUG "%s: associated\n", sdata->name); 2186 printk(KERN_DEBUG "%s: associated\n", sdata->name);
2257 2187
2258 /* tell driver about sync done first */
2259 if (assoc_data->synced) {
2260 drv_finish_tx_sync(sdata->local, sdata,
2261 assoc_data->bss->bssid,
2262 IEEE80211_TX_SYNC_ASSOC);
2263 assoc_data->synced = false;
2264 }
2265
2266 if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { 2188 if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) {
2267 /* oops -- internal error -- send timeout for now */ 2189 /* oops -- internal error -- send timeout for now */
2268 ieee80211_destroy_assoc_data(sdata, true); 2190 ieee80211_destroy_assoc_data(sdata, true);
@@ -2747,14 +2669,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
2747 if (WARN_ON_ONCE(!auth_data)) 2669 if (WARN_ON_ONCE(!auth_data))
2748 return -EINVAL; 2670 return -EINVAL;
2749 2671
2750 if (!auth_data->synced) {
2751 int ret = drv_tx_sync(local, sdata, auth_data->bss->bssid,
2752 IEEE80211_TX_SYNC_AUTH);
2753 if (ret)
2754 return ret;
2755 }
2756 auth_data->synced = true;
2757
2758 auth_data->tries++; 2672 auth_data->tries++;
2759 2673
2760 if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { 2674 if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
@@ -2811,14 +2725,6 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
2811 2725
2812 lockdep_assert_held(&sdata->u.mgd.mtx); 2726 lockdep_assert_held(&sdata->u.mgd.mtx);
2813 2727
2814 if (!assoc_data->synced) {
2815 int ret = drv_tx_sync(local, sdata, assoc_data->bss->bssid,
2816 IEEE80211_TX_SYNC_ASSOC);
2817 if (ret)
2818 return ret;
2819 }
2820 assoc_data->synced = true;
2821
2822 assoc_data->tries++; 2728 assoc_data->tries++;
2823 if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { 2729 if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) {
2824 printk(KERN_DEBUG "%s: association with %pM timed out\n", 2730 printk(KERN_DEBUG "%s: association with %pM timed out\n",
@@ -3107,6 +3013,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
3107 3013
3108 ifmgd->flags = 0; 3014 ifmgd->flags = 0;
3109 ifmgd->powersave = sdata->wdev.ps; 3015 ifmgd->powersave = sdata->wdev.ps;
3016 ifmgd->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
3017 ifmgd->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
3110 3018
3111 mutex_init(&ifmgd->mtx); 3019 mutex_init(&ifmgd->mtx);
3112 3020
@@ -3143,6 +3051,101 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
3143 return 0; 3051 return 0;
3144} 3052}
3145 3053
3054static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3055 struct cfg80211_bss *cbss, bool assoc)
3056{
3057 struct ieee80211_local *local = sdata->local;
3058 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3059 struct ieee80211_bss *bss = (void *)cbss->priv;
3060 struct sta_info *sta;
3061 bool have_sta = false;
3062 int err;
3063
3064 if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data))
3065 return -EINVAL;
3066
3067 if (assoc) {
3068 rcu_read_lock();
3069 have_sta = sta_info_get(sdata, cbss->bssid);
3070 rcu_read_unlock();
3071 }
3072
3073 if (!have_sta) {
3074 sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL);
3075 if (!sta)
3076 return -ENOMEM;
3077 }
3078
3079 mutex_lock(&local->mtx);
3080 ieee80211_recalc_idle(sdata->local);
3081 mutex_unlock(&local->mtx);
3082
3083 /* switch to the right channel */
3084 local->oper_channel = cbss->channel;
3085 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
3086
3087 if (!have_sta) {
3088 struct ieee80211_supported_band *sband;
3089 u32 rates = 0, basic_rates = 0;
3090 bool have_higher_than_11mbit;
3091 int min_rate = INT_MAX, min_rate_index = -1;
3092
3093 sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
3094
3095 ieee80211_get_rates(sband, bss->supp_rates,
3096 bss->supp_rates_len,
3097 &rates, &basic_rates,
3098 &have_higher_than_11mbit,
3099 &min_rate, &min_rate_index);
3100
3101 /*
3102 * This used to be a workaround for basic rates missing
3103 * in the association response frame. Now that we no
3104 * longer use the basic rates from there, it probably
3105 * doesn't happen any more, but keep the workaround so
3106 * in case some *other* APs are buggy in different ways
3107 * we can connect -- with a warning.
3108 */
3109 if (!basic_rates && min_rate_index >= 0) {
3110 printk(KERN_DEBUG
3111 "%s: No basic rates, using min rate instead.\n",
3112 sdata->name);
3113 basic_rates = BIT(min_rate_index);
3114 }
3115
3116 sta->sta.supp_rates[cbss->channel->band] = rates;
3117 sdata->vif.bss_conf.basic_rates = basic_rates;
3118
3119 /* cf. IEEE 802.11 9.2.12 */
3120 if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
3121 have_higher_than_11mbit)
3122 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
3123 else
3124 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
3125
3126 memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN);
3127
3128 /* tell driver about BSSID and basic rates */
3129 ieee80211_bss_info_change_notify(sdata,
3130 BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES);
3131
3132 if (assoc)
3133 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
3134
3135 err = sta_info_insert(sta);
3136 sta = NULL;
3137 if (err) {
3138 printk(KERN_DEBUG
3139 "%s: failed to insert STA entry for the AP (error %d)\n",
3140 sdata->name, err);
3141 return err;
3142 }
3143 } else
3144 WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, cbss->bssid));
3145
3146 return 0;
3147}
3148
3146/* config hooks */ 3149/* config hooks */
3147int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, 3150int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3148 struct cfg80211_auth_request *req) 3151 struct cfg80211_auth_request *req)
@@ -3150,7 +3153,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3150 struct ieee80211_local *local = sdata->local; 3153 struct ieee80211_local *local = sdata->local;
3151 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3154 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3152 struct ieee80211_mgd_auth_data *auth_data; 3155 struct ieee80211_mgd_auth_data *auth_data;
3153 struct sta_info *sta;
3154 u16 auth_alg; 3156 u16 auth_alg;
3155 int err; 3157 int err;
3156 3158
@@ -3216,38 +3218,12 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3216 printk(KERN_DEBUG "%s: authenticate with %pM\n", 3218 printk(KERN_DEBUG "%s: authenticate with %pM\n",
3217 sdata->name, req->bss->bssid); 3219 sdata->name, req->bss->bssid);
3218 3220
3219 mutex_lock(&local->mtx); 3221 err = ieee80211_prep_connection(sdata, req->bss, false);
3220 ieee80211_recalc_idle(sdata->local); 3222 if (err)
3221 mutex_unlock(&local->mtx);
3222
3223 /* switch to the right channel */
3224 local->oper_channel = req->bss->channel;
3225 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
3226
3227 /* set BSSID */
3228 memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
3229 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
3230
3231 /* add station entry */
3232 sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
3233 if (!sta) {
3234 err = -ENOMEM;
3235 goto err_clear; 3223 goto err_clear;
3236 }
3237
3238 err = sta_info_insert(sta);
3239 if (err) {
3240 printk(KERN_DEBUG
3241 "%s: failed to insert STA entry for the AP %pM (error %d)\n",
3242 sdata->name, req->bss->bssid, err);
3243 goto err_clear;
3244 }
3245 3224
3246 err = ieee80211_probe_auth(sdata); 3225 err = ieee80211_probe_auth(sdata);
3247 if (err) { 3226 if (err) {
3248 if (auth_data->synced)
3249 drv_finish_tx_sync(local, sdata, req->bss->bssid,
3250 IEEE80211_TX_SYNC_AUTH);
3251 sta_info_destroy_addr(sdata, req->bss->bssid); 3227 sta_info_destroy_addr(sdata, req->bss->bssid);
3252 goto err_clear; 3228 goto err_clear;
3253 } 3229 }
@@ -3274,7 +3250,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3274 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3250 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3275 struct ieee80211_bss *bss = (void *)req->bss->priv; 3251 struct ieee80211_bss *bss = (void *)req->bss->priv;
3276 struct ieee80211_mgd_assoc_data *assoc_data; 3252 struct ieee80211_mgd_assoc_data *assoc_data;
3277 struct sta_info *sta; 3253 struct ieee80211_supported_band *sband;
3278 const u8 *ssidie; 3254 const u8 *ssidie;
3279 int i, err; 3255 int i, err;
3280 3256
@@ -3316,6 +3292,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3316 3292
3317 ifmgd->beacon_crc_valid = false; 3293 ifmgd->beacon_crc_valid = false;
3318 3294
3295 /*
3296 * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
3297 * We still associate in non-HT mode (11a/b/g) if any one of these
3298 * ciphers is configured as pairwise.
3299 * We can set this to true for non-11n hardware, that'll be checked
3300 * separately along with the peer capabilities.
3301 */
3319 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) 3302 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
3320 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || 3303 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
3321 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || 3304 req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
@@ -3325,6 +3308,12 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3325 if (req->flags & ASSOC_REQ_DISABLE_HT) 3308 if (req->flags & ASSOC_REQ_DISABLE_HT)
3326 ifmgd->flags |= IEEE80211_STA_DISABLE_11N; 3309 ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
3327 3310
3311 /* Also disable HT if we don't support it or the AP doesn't use WMM */
3312 sband = local->hw.wiphy->bands[req->bss->channel->band];
3313 if (!sband->ht_cap.ht_supported ||
3314 local->hw.queues < 4 || !bss->wmm_used)
3315 ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
3316
3328 memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); 3317 memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
3329 memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, 3318 memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask,
3330 sizeof(ifmgd->ht_capa_mask)); 3319 sizeof(ifmgd->ht_capa_mask));
@@ -3344,15 +3333,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3344 } else 3333 } else
3345 ifmgd->ap_smps = ifmgd->req_smps; 3334 ifmgd->ap_smps = ifmgd->req_smps;
3346 3335
3347 /*
3348 * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
3349 * We still associate in non-HT mode (11a/b/g) if any one of these
3350 * ciphers is configured as pairwise.
3351 * We can set this to true for non-11n hardware, that'll be checked
3352 * separately along with the peer capabilities.
3353 */
3354 assoc_data->capability = req->bss->capability; 3336 assoc_data->capability = req->bss->capability;
3355 assoc_data->wmm_used = bss->wmm_used; 3337 assoc_data->wmm = bss->wmm_used && (local->hw.queues >= 4);
3356 assoc_data->supp_rates = bss->supp_rates; 3338 assoc_data->supp_rates = bss->supp_rates;
3357 assoc_data->supp_rates_len = bss->supp_rates_len; 3339 assoc_data->supp_rates_len = bss->supp_rates_len;
3358 assoc_data->ht_information_ie = 3340 assoc_data->ht_information_ie =
@@ -3360,10 +3342,10 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3360 3342
3361 if (bss->wmm_used && bss->uapsd_supported && 3343 if (bss->wmm_used && bss->uapsd_supported &&
3362 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { 3344 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
3363 assoc_data->uapsd_used = true; 3345 assoc_data->uapsd = true;
3364 ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; 3346 ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
3365 } else { 3347 } else {
3366 assoc_data->uapsd_used = false; 3348 assoc_data->uapsd = false;
3367 ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED; 3349 ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
3368 } 3350 }
3369 3351
@@ -3393,41 +3375,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3393 3375
3394 ifmgd->assoc_data = assoc_data; 3376 ifmgd->assoc_data = assoc_data;
3395 3377
3396 mutex_lock(&local->mtx); 3378 err = ieee80211_prep_connection(sdata, req->bss, true);
3397 ieee80211_recalc_idle(sdata->local); 3379 if (err)
3398 mutex_unlock(&local->mtx); 3380 goto err_clear;
3399
3400 /* switch to the right channel */
3401 local->oper_channel = req->bss->channel;
3402 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
3403
3404 rcu_read_lock();
3405 sta = sta_info_get(sdata, req->bss->bssid);
3406 rcu_read_unlock();
3407
3408 if (!sta) {
3409 /* set BSSID */
3410 memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
3411 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
3412
3413 sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
3414 if (!sta) {
3415 err = -ENOMEM;
3416 goto err_clear;
3417 }
3418
3419 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
3420
3421 err = sta_info_insert(sta);
3422 sta = NULL;
3423 if (err) {
3424 printk(KERN_DEBUG
3425 "%s: failed to insert STA entry for the AP (error %d)\n",
3426 sdata->name, err);
3427 goto err_clear;
3428 }
3429 } else
3430 WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, req->bss->bssid));
3431 3381
3432 if (!bss->dtim_period && 3382 if (!bss->dtim_period &&
3433 sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { 3383 sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) {
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index ff5f7b84e825..16e0b277b9a8 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -568,6 +568,13 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
568 minstrel_next_sample_idx(mi); 568 minstrel_next_sample_idx(mi);
569 569
570 /* 570 /*
571 * Sampling might add some overhead (RTS, no aggregation)
572 * to the frame. Hence, don't use sampling for the currently
573 * used max TP rate.
574 */
575 if (sample_idx == mi->max_tp_rate)
576 return -1;
577 /*
571 * When not using MRR, do not sample if the probability is already 578 * When not using MRR, do not sample if the probability is already
572 * higher than 95% to avoid wasting airtime 579 * higher than 95% to avoid wasting airtime
573 */ 580 */
@@ -692,6 +699,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
692 int ack_dur; 699 int ack_dur;
693 int stbc; 700 int stbc;
694 int i; 701 int i;
702 unsigned int smps;
695 703
696 /* fall back to the old minstrel for legacy stations */ 704 /* fall back to the old minstrel for legacy stations */
697 if (!sta->ht_cap.ht_supported) 705 if (!sta->ht_cap.ht_supported)
@@ -731,6 +739,9 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
731 oper_chan_type != NL80211_CHAN_HT40PLUS) 739 oper_chan_type != NL80211_CHAN_HT40PLUS)
732 sta_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; 740 sta_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
733 741
742 smps = (sta_cap & IEEE80211_HT_CAP_SM_PS) >>
743 IEEE80211_HT_CAP_SM_PS_SHIFT;
744
734 for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { 745 for (i = 0; i < ARRAY_SIZE(mi->groups); i++) {
735 u16 req = 0; 746 u16 req = 0;
736 747
@@ -748,6 +759,11 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
748 if ((sta_cap & req) != req) 759 if ((sta_cap & req) != req)
749 continue; 760 continue;
750 761
762 /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */
763 if (smps == WLAN_HT_CAP_SM_PS_STATIC &&
764 minstrel_mcs_groups[i].streams > 1)
765 continue;
766
751 mi->groups[i].supported = 767 mi->groups[i].supported =
752 mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; 768 mcs->rx_mask[minstrel_mcs_groups[i].streams - 1];
753 769
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5f6e32ca0858..bcfe8c77c839 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1063,20 +1063,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1063 return RX_DROP_MONITOR; 1063 return RX_DROP_MONITOR;
1064 } 1064 }
1065 1065
1066 if (skb_linearize(rx->skb))
1067 return RX_DROP_UNUSABLE;
1068 /* the hdr variable is invalid now! */
1069
1070 switch (rx->key->conf.cipher) { 1066 switch (rx->key->conf.cipher) {
1071 case WLAN_CIPHER_SUITE_WEP40: 1067 case WLAN_CIPHER_SUITE_WEP40:
1072 case WLAN_CIPHER_SUITE_WEP104: 1068 case WLAN_CIPHER_SUITE_WEP104:
1073 /* Check for weak IVs if possible */
1074 if (rx->sta && ieee80211_is_data(fc) &&
1075 (!(status->flag & RX_FLAG_IV_STRIPPED) ||
1076 !(status->flag & RX_FLAG_DECRYPTED)) &&
1077 ieee80211_wep_is_weak_iv(rx->skb, rx->key))
1078 rx->sta->wep_weak_iv_count++;
1079
1080 result = ieee80211_crypto_wep_decrypt(rx); 1069 result = ieee80211_crypto_wep_decrypt(rx);
1081 break; 1070 break;
1082 case WLAN_CIPHER_SUITE_TKIP: 1071 case WLAN_CIPHER_SUITE_TKIP:
@@ -1096,6 +1085,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1096 return RX_DROP_UNUSABLE; 1085 return RX_DROP_UNUSABLE;
1097 } 1086 }
1098 1087
1088 /* the hdr variable is invalid after the decrypt handlers */
1089
1099 /* either the frame has been decrypted or will be dropped */ 1090 /* either the frame has been decrypted or will be dropped */
1100 status->flag |= RX_FLAG_DECRYPTED; 1091 status->flag |= RX_FLAG_DECRYPTED;
1101 1092
@@ -2278,9 +2269,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2278 2269
2279 sband = rx->local->hw.wiphy->bands[status->band]; 2270 sband = rx->local->hw.wiphy->bands[status->band];
2280 2271
2281 rate_control_rate_update(local, sband, rx->sta, 2272 rate_control_rate_update(
2282 IEEE80211_RC_SMPS_CHANGED, 2273 local, sband, rx->sta,
2283 local->_oper_channel_type); 2274 IEEE80211_RC_SMPS_CHANGED,
2275 ieee80211_get_tx_channel_type(
2276 local, local->_oper_channel_type));
2284 goto handled; 2277 goto handled;
2285 } 2278 }
2286 default: 2279 default:
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 570737df2d22..782a60198df4 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -226,12 +226,12 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
226 * have correct qos tag for some reason, due the network or the 226 * have correct qos tag for some reason, due the network or the
227 * peer application. 227 * peer application.
228 * 228 *
229 * Note: local->uapsd_queues access is racy here. If the value is 229 * Note: ifmgd->uapsd_queues access is racy here. If the value is
230 * changed via debugfs, user needs to reassociate manually to have 230 * changed via debugfs, user needs to reassociate manually to have
231 * everything in sync. 231 * everything in sync.
232 */ 232 */
233 if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) 233 if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
234 && (local->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) 234 && (ifmgd->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
235 && skb_get_queue_mapping(tx->skb) == 0) 235 && skb_get_queue_mapping(tx->skb) == 0)
236 return TX_CONTINUE; 236 return TX_CONTINUE;
237 237
@@ -1065,6 +1065,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
1065{ 1065{
1066 bool queued = false; 1066 bool queued = false;
1067 bool reset_agg_timer = false; 1067 bool reset_agg_timer = false;
1068 struct sk_buff *purge_skb = NULL;
1068 1069
1069 if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { 1070 if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
1070 info->flags |= IEEE80211_TX_CTL_AMPDU; 1071 info->flags |= IEEE80211_TX_CTL_AMPDU;
@@ -1106,8 +1107,13 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
1106 info->control.vif = &tx->sdata->vif; 1107 info->control.vif = &tx->sdata->vif;
1107 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1108 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1108 __skb_queue_tail(&tid_tx->pending, skb); 1109 __skb_queue_tail(&tid_tx->pending, skb);
1110 if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER)
1111 purge_skb = __skb_dequeue(&tid_tx->pending);
1109 } 1112 }
1110 spin_unlock(&tx->sta->lock); 1113 spin_unlock(&tx->sta->lock);
1114
1115 if (purge_skb)
1116 dev_kfree_skb(purge_skb);
1111 } 1117 }
1112 1118
1113 /* reset session timer */ 1119 /* reset session timer */
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 68ad351479df..7aa31bbfaa3b 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -263,16 +263,14 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
263} 263}
264 264
265 265
266bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) 266static bool ieee80211_wep_is_weak_iv(struct sk_buff *skb,
267 struct ieee80211_key *key)
267{ 268{
268 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 269 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
269 unsigned int hdrlen; 270 unsigned int hdrlen;
270 u8 *ivpos; 271 u8 *ivpos;
271 u32 iv; 272 u32 iv;
272 273
273 if (!ieee80211_has_protected(hdr->frame_control))
274 return false;
275
276 hdrlen = ieee80211_hdrlen(hdr->frame_control); 274 hdrlen = ieee80211_hdrlen(hdr->frame_control);
277 ivpos = skb->data + hdrlen; 275 ivpos = skb->data + hdrlen;
278 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; 276 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
@@ -286,18 +284,27 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
286 struct sk_buff *skb = rx->skb; 284 struct sk_buff *skb = rx->skb;
287 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 285 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
288 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 286 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
287 __le16 fc = hdr->frame_control;
289 288
290 if (!ieee80211_is_data(hdr->frame_control) && 289 if (!ieee80211_is_data(fc) && !ieee80211_is_auth(fc))
291 !ieee80211_is_auth(hdr->frame_control))
292 return RX_CONTINUE; 290 return RX_CONTINUE;
293 291
294 if (!(status->flag & RX_FLAG_DECRYPTED)) { 292 if (!(status->flag & RX_FLAG_DECRYPTED)) {
293 if (skb_linearize(rx->skb))
294 return RX_DROP_UNUSABLE;
295 if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
296 rx->sta->wep_weak_iv_count++;
295 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) 297 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key))
296 return RX_DROP_UNUSABLE; 298 return RX_DROP_UNUSABLE;
297 } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { 299 } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
300 if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + WEP_IV_LEN))
301 return RX_DROP_UNUSABLE;
302 if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
303 rx->sta->wep_weak_iv_count++;
298 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); 304 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
299 /* remove ICV */ 305 /* remove ICV */
300 skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN); 306 if (pskb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN))
307 return RX_DROP_UNUSABLE;
301 } 308 }
302 309
303 return RX_CONTINUE; 310 return RX_CONTINUE;
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h
index 01e54840a628..9615749d1f65 100644
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
@@ -25,7 +25,6 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
25 const u8 *key, int keylen, int keyidx); 25 const u8 *key, int keylen, int keyidx);
26int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, 26int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
27 size_t klen, u8 *data, size_t data_len); 27 size_t klen, u8 *data, size_t data_len);
28bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
29 28
30ieee80211_rx_result 29ieee80211_rx_result
31ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); 30ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx);
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index b758350919ff..0ae23c60968c 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -138,6 +138,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
138 if (skb->len < hdrlen + MICHAEL_MIC_LEN) 138 if (skb->len < hdrlen + MICHAEL_MIC_LEN)
139 return RX_DROP_UNUSABLE; 139 return RX_DROP_UNUSABLE;
140 140
141 if (skb_linearize(rx->skb))
142 return RX_DROP_UNUSABLE;
143 hdr = (void *)skb->data;
144
141 data = skb->data + hdrlen; 145 data = skb->data + hdrlen;
142 data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; 146 data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
143 key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]; 147 key = &rx->key->conf.key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
@@ -253,6 +257,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
253 if (!rx->sta || skb->len - hdrlen < 12) 257 if (!rx->sta || skb->len - hdrlen < 12)
254 return RX_DROP_UNUSABLE; 258 return RX_DROP_UNUSABLE;
255 259
260 /* it may be possible to optimize this a bit more */
261 if (skb_linearize(rx->skb))
262 return RX_DROP_UNUSABLE;
263 hdr = (void *)skb->data;
264
256 /* 265 /*
257 * Let TKIP code verify IV, but skip decryption. 266 * Let TKIP code verify IV, but skip decryption.
258 * In the case where hardware checks the IV as well, 267 * In the case where hardware checks the IV as well,
@@ -484,6 +493,14 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
484 if (!rx->sta || data_len < 0) 493 if (!rx->sta || data_len < 0)
485 return RX_DROP_UNUSABLE; 494 return RX_DROP_UNUSABLE;
486 495
496 if (status->flag & RX_FLAG_DECRYPTED) {
497 if (!pskb_may_pull(rx->skb, hdrlen + CCMP_HDR_LEN))
498 return RX_DROP_UNUSABLE;
499 } else {
500 if (skb_linearize(rx->skb))
501 return RX_DROP_UNUSABLE;
502 }
503
487 ccmp_hdr2pn(pn, skb->data + hdrlen); 504 ccmp_hdr2pn(pn, skb->data + hdrlen);
488 505
489 queue = rx->security_idx; 506 queue = rx->security_idx;
@@ -509,7 +526,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
509 memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN); 526 memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN);
510 527
511 /* Remove CCMP header and MIC */ 528 /* Remove CCMP header and MIC */
512 skb_trim(skb, skb->len - CCMP_MIC_LEN); 529 if (pskb_trim(skb, skb->len - CCMP_MIC_LEN))
530 return RX_DROP_UNUSABLE;
513 memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); 531 memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen);
514 skb_pull(skb, CCMP_HDR_LEN); 532 skb_pull(skb, CCMP_HDR_LEN);
515 533
@@ -609,6 +627,8 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
609 if (!ieee80211_is_mgmt(hdr->frame_control)) 627 if (!ieee80211_is_mgmt(hdr->frame_control))
610 return RX_CONTINUE; 628 return RX_CONTINUE;
611 629
630 /* management frames are already linear */
631
612 if (skb->len < 24 + sizeof(*mmie)) 632 if (skb->len < 24 + sizeof(*mmie))
613 return RX_DROP_UNUSABLE; 633 return RX_DROP_UNUSABLE;
614 634
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 39dbdf2adb12..4c1eb9472ddb 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -205,6 +205,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
205 }, 205 },
206 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, 206 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
207 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, 207 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
208 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
208}; 209};
209 210
210/* policy for the key attributes */ 211/* policy for the key attributes */
@@ -5116,6 +5117,13 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
5116 5117
5117 wiphy = &rdev->wiphy; 5118 wiphy = &rdev->wiphy;
5118 5119
5120 connect.bg_scan_period = -1;
5121 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
5122 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
5123 connect.bg_scan_period =
5124 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
5125 }
5126
5119 if (info->attrs[NL80211_ATTR_MAC]) 5127 if (info->attrs[NL80211_ATTR_MAC])
5120 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 5128 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
5121 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); 5129 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index afde7e5f0010..70faadf16a32 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -734,9 +734,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
734struct cfg80211_bss* 734struct cfg80211_bss*
735cfg80211_inform_bss(struct wiphy *wiphy, 735cfg80211_inform_bss(struct wiphy *wiphy,
736 struct ieee80211_channel *channel, 736 struct ieee80211_channel *channel,
737 const u8 *bssid, 737 const u8 *bssid, u64 tsf, u16 capability,
738 u64 timestamp, u16 capability, u16 beacon_interval, 738 u16 beacon_interval, const u8 *ie, size_t ielen,
739 const u8 *ie, size_t ielen,
740 s32 signal, gfp_t gfp) 739 s32 signal, gfp_t gfp)
741{ 740{
742 struct cfg80211_internal_bss *res; 741 struct cfg80211_internal_bss *res;
@@ -758,7 +757,7 @@ cfg80211_inform_bss(struct wiphy *wiphy,
758 memcpy(res->pub.bssid, bssid, ETH_ALEN); 757 memcpy(res->pub.bssid, bssid, ETH_ALEN);
759 res->pub.channel = channel; 758 res->pub.channel = channel;
760 res->pub.signal = signal; 759 res->pub.signal = signal;
761 res->pub.tsf = timestamp; 760 res->pub.tsf = tsf;
762 res->pub.beacon_interval = beacon_interval; 761 res->pub.beacon_interval = beacon_interval;
763 res->pub.capability = capability; 762 res->pub.capability = capability;
764 /* 763 /*
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 326750b99151..7c01c2f3b6cf 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -30,6 +30,9 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
30 wdev->wext.connect.ie = wdev->wext.ie; 30 wdev->wext.connect.ie = wdev->wext.ie;
31 wdev->wext.connect.ie_len = wdev->wext.ie_len; 31 wdev->wext.connect.ie_len = wdev->wext.ie_len;
32 32
33 /* Use default background scan period */
34 wdev->wext.connect.bg_scan_period = -1;
35
33 if (wdev->wext.keys) { 36 if (wdev->wext.keys) {
34 wdev->wext.keys->def = wdev->wext.default_key; 37 wdev->wext.keys->def = wdev->wext.default_key;
35 wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key; 38 wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key;