aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-07-08 18:39:41 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-08 18:39:41 -0400
commit54dceb008ffcbe003bea9017cad1227a83b6fc3f (patch)
treed4e3345ead16da19efe38dbf97ade38309f8b4f7 /net
parent11a100f844f6096787ab20e19f17d72abc957a8f (diff)
parentb46372710ab536c0967f76be5dc41341583d4a54 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/Kconfig3
-rw-r--r--net/mac80211/aes_ccm.c51
-rw-r--r--net/mac80211/aes_ccm.h4
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/main.c33
-rw-r--r--net/mac80211/michael.c20
-rw-r--r--net/mac80211/michael.h2
-rw-r--r--net/mac80211/mlme.c34
-rw-r--r--net/mac80211/rx.c135
-rw-r--r--net/mac80211/sta_info.c1
-rw-r--r--net/mac80211/sta_info.h81
-rw-r--r--net/mac80211/wext.c2
-rw-r--r--net/mac80211/wme.c5
-rw-r--r--net/mac80211/wme.h8
-rw-r--r--net/mac80211/wpa.c183
-rw-r--r--net/rfkill/rfkill.c22
-rw-r--r--net/wireless/nl80211.c6
17 files changed, 325 insertions, 268 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 11a1e7fa195d..40f1add17753 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -207,7 +207,6 @@ config MAC80211_LOWTX_FRAME_DUMP
207 207
208config MAC80211_DEBUG_COUNTERS 208config MAC80211_DEBUG_COUNTERS
209 bool "Extra statistics for TX/RX debugging" 209 bool "Extra statistics for TX/RX debugging"
210 depends on MAC80211_DEBUG
211 depends on MAC80211_DEBUG_MENU 210 depends on MAC80211_DEBUG_MENU
212 depends on MAC80211_DEBUGFS 211 depends on MAC80211_DEBUGFS
213 ---help--- 212 ---help---
@@ -219,7 +218,7 @@ config MAC80211_DEBUG_COUNTERS
219 218
220config MAC80211_VERBOSE_SPECT_MGMT_DEBUG 219config MAC80211_VERBOSE_SPECT_MGMT_DEBUG
221 bool "Verbose Spectrum Management (IEEE 802.11h)debugging" 220 bool "Verbose Spectrum Management (IEEE 802.11h)debugging"
222 depends on MAC80211_DEBUG 221 depends on MAC80211_DEBUG_MENU
223 ---help--- 222 ---help---
224 Say Y here to print out verbose Spectrum Management (IEEE 802.11h) 223 Say Y here to print out verbose Spectrum Management (IEEE 802.11h)
225 debug messages. 224 debug messages.
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
index 4d4c2dfcf9a0..a87cb3ba2df6 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -16,31 +16,28 @@
16#include "key.h" 16#include "key.h"
17#include "aes_ccm.h" 17#include "aes_ccm.h"
18 18
19 19static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a)
20static void ieee80211_aes_encrypt(struct crypto_cipher *tfm,
21 const u8 pt[16], u8 ct[16])
22{
23 crypto_cipher_encrypt_one(tfm, ct, pt);
24}
25
26
27static inline void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
28 u8 *b, u8 *s_0, u8 *a)
29{ 20{
30 int i; 21 int i;
22 u8 *b_0, *aad, *b, *s_0;
31 23
32 ieee80211_aes_encrypt(tfm, b_0, b); 24 b_0 = scratch + 3 * AES_BLOCK_LEN;
25 aad = scratch + 4 * AES_BLOCK_LEN;
26 b = scratch;
27 s_0 = scratch + AES_BLOCK_LEN;
28
29 crypto_cipher_encrypt_one(tfm, b, b_0);
33 30
34 /* Extra Authenticate-only data (always two AES blocks) */ 31 /* Extra Authenticate-only data (always two AES blocks) */
35 for (i = 0; i < AES_BLOCK_LEN; i++) 32 for (i = 0; i < AES_BLOCK_LEN; i++)
36 aad[i] ^= b[i]; 33 aad[i] ^= b[i];
37 ieee80211_aes_encrypt(tfm, aad, b); 34 crypto_cipher_encrypt_one(tfm, b, aad);
38 35
39 aad += AES_BLOCK_LEN; 36 aad += AES_BLOCK_LEN;
40 37
41 for (i = 0; i < AES_BLOCK_LEN; i++) 38 for (i = 0; i < AES_BLOCK_LEN; i++)
42 aad[i] ^= b[i]; 39 aad[i] ^= b[i];
43 ieee80211_aes_encrypt(tfm, aad, a); 40 crypto_cipher_encrypt_one(tfm, a, aad);
44 41
45 /* Mask out bits from auth-only-b_0 */ 42 /* Mask out bits from auth-only-b_0 */
46 b_0[0] &= 0x07; 43 b_0[0] &= 0x07;
@@ -48,24 +45,26 @@ static inline void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
48 /* S_0 is used to encrypt T (= MIC) */ 45 /* S_0 is used to encrypt T (= MIC) */
49 b_0[14] = 0; 46 b_0[14] = 0;
50 b_0[15] = 0; 47 b_0[15] = 0;
51 ieee80211_aes_encrypt(tfm, b_0, s_0); 48 crypto_cipher_encrypt_one(tfm, s_0, b_0);
52} 49}
53 50
54 51
55void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, 52void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
56 u8 *b_0, u8 *aad, u8 *data, size_t data_len, 53 u8 *data, size_t data_len,
57 u8 *cdata, u8 *mic) 54 u8 *cdata, u8 *mic)
58{ 55{
59 int i, j, last_len, num_blocks; 56 int i, j, last_len, num_blocks;
60 u8 *pos, *cpos, *b, *s_0, *e; 57 u8 *pos, *cpos, *b, *s_0, *e, *b_0, *aad;
61 58
62 b = scratch; 59 b = scratch;
63 s_0 = scratch + AES_BLOCK_LEN; 60 s_0 = scratch + AES_BLOCK_LEN;
64 e = scratch + 2 * AES_BLOCK_LEN; 61 e = scratch + 2 * AES_BLOCK_LEN;
62 b_0 = scratch + 3 * AES_BLOCK_LEN;
63 aad = scratch + 4 * AES_BLOCK_LEN;
65 64
66 num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); 65 num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
67 last_len = data_len % AES_BLOCK_LEN; 66 last_len = data_len % AES_BLOCK_LEN;
68 aes_ccm_prepare(tfm, b_0, aad, b, s_0, b); 67 aes_ccm_prepare(tfm, scratch, b);
69 68
70 /* Process payload blocks */ 69 /* Process payload blocks */
71 pos = data; 70 pos = data;
@@ -77,11 +76,11 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
77 /* Authentication followed by encryption */ 76 /* Authentication followed by encryption */
78 for (i = 0; i < blen; i++) 77 for (i = 0; i < blen; i++)
79 b[i] ^= pos[i]; 78 b[i] ^= pos[i];
80 ieee80211_aes_encrypt(tfm, b, b); 79 crypto_cipher_encrypt_one(tfm, b, b);
81 80
82 b_0[14] = (j >> 8) & 0xff; 81 b_0[14] = (j >> 8) & 0xff;
83 b_0[15] = j & 0xff; 82 b_0[15] = j & 0xff;
84 ieee80211_aes_encrypt(tfm, b_0, e); 83 crypto_cipher_encrypt_one(tfm, e, b_0);
85 for (i = 0; i < blen; i++) 84 for (i = 0; i < blen; i++)
86 *cpos++ = *pos++ ^ e[i]; 85 *cpos++ = *pos++ ^ e[i];
87 } 86 }
@@ -92,19 +91,20 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
92 91
93 92
94int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, 93int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
95 u8 *b_0, u8 *aad, u8 *cdata, size_t data_len, 94 u8 *cdata, size_t data_len, u8 *mic, u8 *data)
96 u8 *mic, u8 *data)
97{ 95{
98 int i, j, last_len, num_blocks; 96 int i, j, last_len, num_blocks;
99 u8 *pos, *cpos, *b, *s_0, *a; 97 u8 *pos, *cpos, *b, *s_0, *a, *b_0, *aad;
100 98
101 b = scratch; 99 b = scratch;
102 s_0 = scratch + AES_BLOCK_LEN; 100 s_0 = scratch + AES_BLOCK_LEN;
103 a = scratch + 2 * AES_BLOCK_LEN; 101 a = scratch + 2 * AES_BLOCK_LEN;
102 b_0 = scratch + 3 * AES_BLOCK_LEN;
103 aad = scratch + 4 * AES_BLOCK_LEN;
104 104
105 num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); 105 num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
106 last_len = data_len % AES_BLOCK_LEN; 106 last_len = data_len % AES_BLOCK_LEN;
107 aes_ccm_prepare(tfm, b_0, aad, b, s_0, a); 107 aes_ccm_prepare(tfm, scratch, a);
108 108
109 /* Process payload blocks */ 109 /* Process payload blocks */
110 cpos = cdata; 110 cpos = cdata;
@@ -116,13 +116,12 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
116 /* Decryption followed by authentication */ 116 /* Decryption followed by authentication */
117 b_0[14] = (j >> 8) & 0xff; 117 b_0[14] = (j >> 8) & 0xff;
118 b_0[15] = j & 0xff; 118 b_0[15] = j & 0xff;
119 ieee80211_aes_encrypt(tfm, b_0, b); 119 crypto_cipher_encrypt_one(tfm, b, b_0);
120 for (i = 0; i < blen; i++) { 120 for (i = 0; i < blen; i++) {
121 *pos = *cpos++ ^ b[i]; 121 *pos = *cpos++ ^ b[i];
122 a[i] ^= *pos++; 122 a[i] ^= *pos++;
123 } 123 }
124 124 crypto_cipher_encrypt_one(tfm, a, a);
125 ieee80211_aes_encrypt(tfm, a, a);
126 } 125 }
127 126
128 for (i = 0; i < CCMP_MIC_LEN; i++) { 127 for (i = 0; i < CCMP_MIC_LEN; i++) {
diff --git a/net/mac80211/aes_ccm.h b/net/mac80211/aes_ccm.h
index 8cd0f14aab4d..6e7820ef3448 100644
--- a/net/mac80211/aes_ccm.h
+++ b/net/mac80211/aes_ccm.h
@@ -16,10 +16,10 @@
16 16
17struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]); 17struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]);
18void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, 18void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
19 u8 *b_0, u8 *aad, u8 *data, size_t data_len, 19 u8 *data, size_t data_len,
20 u8 *cdata, u8 *mic); 20 u8 *cdata, u8 *mic);
21int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, 21int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
22 u8 *b_0, u8 *aad, u8 *cdata, size_t data_len, 22 u8 *cdata, size_t data_len,
23 u8 *mic, u8 *data); 23 u8 *mic, u8 *data);
24void ieee80211_aes_key_free(struct crypto_cipher *tfm); 24void ieee80211_aes_key_free(struct crypto_cipher *tfm);
25 25
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f90da1bbec49..02a8753a4eca 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -893,7 +893,7 @@ int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason);
893int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); 893int ieee80211_sta_disassociate(struct net_device *dev, u16 reason);
894void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, 894void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
895 u32 changed); 895 u32 changed);
896void ieee80211_reset_erp_info(struct net_device *dev); 896u32 ieee80211_reset_erp_info(struct net_device *dev);
897int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, 897int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
898 struct ieee80211_ht_info *ht_info); 898 struct ieee80211_ht_info *ht_info);
899int ieee80211_ht_addt_info_ie_to_ht_bss_info( 899int ieee80211_ht_addt_info_ie_to_ht_bss_info(
@@ -904,6 +904,7 @@ void ieee80211_send_addba_request(struct net_device *dev, const u8 *da,
904 u16 agg_size, u16 timeout); 904 u16 agg_size, u16 timeout);
905void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, 905void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid,
906 u16 initiator, u16 reason_code); 906 u16 initiator, u16 reason_code);
907void ieee80211_send_bar(struct net_device *dev, u8 *ra, u16 tid, u16 ssn);
907 908
908void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da, 909void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da,
909 u16 tid, u16 initiator, u16 reason); 910 u16 tid, u16 initiator, u16 reason);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index f18cfd727872..cc756e93e6c8 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -182,10 +182,11 @@ static int ieee80211_open(struct net_device *dev)
182{ 182{
183 struct ieee80211_sub_if_data *sdata, *nsdata; 183 struct ieee80211_sub_if_data *sdata, *nsdata;
184 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 184 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
185 struct sta_info *sta;
185 struct ieee80211_if_init_conf conf; 186 struct ieee80211_if_init_conf conf;
187 u32 changed = 0;
186 int res; 188 int res;
187 bool need_hw_reconfig = 0; 189 bool need_hw_reconfig = 0;
188 struct sta_info *sta;
189 190
190 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 191 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
191 192
@@ -329,7 +330,8 @@ static int ieee80211_open(struct net_device *dev)
329 goto err_stop; 330 goto err_stop;
330 331
331 ieee80211_if_config(dev); 332 ieee80211_if_config(dev);
332 ieee80211_reset_erp_info(dev); 333 changed |= ieee80211_reset_erp_info(dev);
334 ieee80211_bss_info_change_notify(sdata, changed);
333 ieee80211_enable_keys(sdata); 335 ieee80211_enable_keys(sdata);
334 336
335 if (sdata->vif.type == IEEE80211_IF_TYPE_STA && 337 if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
@@ -1190,15 +1192,13 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
1190 changed); 1192 changed);
1191} 1193}
1192 1194
1193void ieee80211_reset_erp_info(struct net_device *dev) 1195u32 ieee80211_reset_erp_info(struct net_device *dev)
1194{ 1196{
1195 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1197 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1196 1198
1197 sdata->bss_conf.use_cts_prot = 0; 1199 sdata->bss_conf.use_cts_prot = 0;
1198 sdata->bss_conf.use_short_preamble = 0; 1200 sdata->bss_conf.use_short_preamble = 0;
1199 ieee80211_bss_info_change_notify(sdata, 1201 return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE;
1200 BSS_CHANGED_ERP_CTS_PROT |
1201 BSS_CHANGED_ERP_PREAMBLE);
1202} 1202}
1203 1203
1204void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, 1204void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
@@ -1404,14 +1404,15 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
1404 struct ieee80211_local *local = hw_to_local(hw); 1404 struct ieee80211_local *local = hw_to_local(hw);
1405 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1405 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1406 u16 frag, type; 1406 u16 frag, type;
1407 __le16 fc;
1407 struct ieee80211_tx_status_rtap_hdr *rthdr; 1408 struct ieee80211_tx_status_rtap_hdr *rthdr;
1408 struct ieee80211_sub_if_data *sdata; 1409 struct ieee80211_sub_if_data *sdata;
1409 struct net_device *prev_dev = NULL; 1410 struct net_device *prev_dev = NULL;
1411 struct sta_info *sta;
1410 1412
1411 rcu_read_lock(); 1413 rcu_read_lock();
1412 1414
1413 if (info->status.excessive_retries) { 1415 if (info->status.excessive_retries) {
1414 struct sta_info *sta;
1415 sta = sta_info_get(local, hdr->addr1); 1416 sta = sta_info_get(local, hdr->addr1);
1416 if (sta) { 1417 if (sta) {
1417 if (test_sta_flags(sta, WLAN_STA_PS)) { 1418 if (test_sta_flags(sta, WLAN_STA_PS)) {
@@ -1426,8 +1427,24 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
1426 } 1427 }
1427 } 1428 }
1428 1429
1430 fc = hdr->frame_control;
1431
1432 if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) &&
1433 (ieee80211_is_data_qos(fc))) {
1434 u16 tid, ssn;
1435 u8 *qc;
1436 sta = sta_info_get(local, hdr->addr1);
1437 if (sta) {
1438 qc = ieee80211_get_qos_ctl(hdr);
1439 tid = qc[0] & 0xf;
1440 ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10)
1441 & IEEE80211_SCTL_SEQ);
1442 ieee80211_send_bar(sta->sdata->dev, hdr->addr1,
1443 tid, ssn);
1444 }
1445 }
1446
1429 if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { 1447 if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
1430 struct sta_info *sta;
1431 sta = sta_info_get(local, hdr->addr1); 1448 sta = sta_info_get(local, hdr->addr1);
1432 if (sta) { 1449 if (sta) {
1433 ieee80211_handle_filtered_frame(local, sta, skb); 1450 ieee80211_handle_filtered_frame(local, sta, skb);
diff --git a/net/mac80211/michael.c b/net/mac80211/michael.c
index 1fcdf38cf60c..408649bd4702 100644
--- a/net/mac80211/michael.c
+++ b/net/mac80211/michael.c
@@ -8,6 +8,7 @@
8 */ 8 */
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/bitops.h> 10#include <linux/bitops.h>
11#include <linux/ieee80211.h>
11#include <asm/unaligned.h> 12#include <asm/unaligned.h>
12 13
13#include "michael.h" 14#include "michael.h"
@@ -26,9 +27,18 @@ static void michael_block(struct michael_mic_ctx *mctx, u32 val)
26 mctx->l += mctx->r; 27 mctx->l += mctx->r;
27} 28}
28 29
29static void michael_mic_hdr(struct michael_mic_ctx *mctx, 30static void michael_mic_hdr(struct michael_mic_ctx *mctx, const u8 *key,
30 const u8 *key, const u8 *da, const u8 *sa, u8 priority) 31 struct ieee80211_hdr *hdr)
31{ 32{
33 u8 *da, *sa, tid;
34
35 da = ieee80211_get_DA(hdr);
36 sa = ieee80211_get_SA(hdr);
37 if (ieee80211_is_data_qos(hdr->frame_control))
38 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
39 else
40 tid = 0;
41
32 mctx->l = get_unaligned_le32(key); 42 mctx->l = get_unaligned_le32(key);
33 mctx->r = get_unaligned_le32(key + 4); 43 mctx->r = get_unaligned_le32(key + 4);
34 44
@@ -40,17 +50,17 @@ static void michael_mic_hdr(struct michael_mic_ctx *mctx,
40 michael_block(mctx, get_unaligned_le16(&da[4]) | 50 michael_block(mctx, get_unaligned_le16(&da[4]) |
41 (get_unaligned_le16(sa) << 16)); 51 (get_unaligned_le16(sa) << 16));
42 michael_block(mctx, get_unaligned_le32(&sa[2])); 52 michael_block(mctx, get_unaligned_le32(&sa[2]));
43 michael_block(mctx, priority); 53 michael_block(mctx, tid);
44} 54}
45 55
46void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority, 56void michael_mic(const u8 *key, struct ieee80211_hdr *hdr,
47 const u8 *data, size_t data_len, u8 *mic) 57 const u8 *data, size_t data_len, u8 *mic)
48{ 58{
49 u32 val; 59 u32 val;
50 size_t block, blocks, left; 60 size_t block, blocks, left;
51 struct michael_mic_ctx mctx; 61 struct michael_mic_ctx mctx;
52 62
53 michael_mic_hdr(&mctx, key, da, sa, priority); 63 michael_mic_hdr(&mctx, key, hdr);
54 64
55 /* Real data */ 65 /* Real data */
56 blocks = data_len / 4; 66 blocks = data_len / 4;
diff --git a/net/mac80211/michael.h b/net/mac80211/michael.h
index 69b4501f13ba..3b848dad9587 100644
--- a/net/mac80211/michael.h
+++ b/net/mac80211/michael.h
@@ -18,7 +18,7 @@ struct michael_mic_ctx {
18 u32 l, r; 18 u32 l, r;
19}; 19};
20 20
21void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority, 21void michael_mic(const u8 *key, struct ieee80211_hdr *hdr,
22 const u8 *data, size_t data_len, u8 *mic); 22 const u8 *data, size_t data_len, u8 *mic);
23 23
24#endif /* MICHAEL_H */ 24#endif /* MICHAEL_H */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4a3bddd206d8..37ea04f5bab9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -366,8 +366,10 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
366 bool use_short_preamble) 366 bool use_short_preamble)
367{ 367{
368 struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; 368 struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
369#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
369 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 370 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
370 DECLARE_MAC_BUF(mac); 371 DECLARE_MAC_BUF(mac);
372#endif
371 u32 changed = 0; 373 u32 changed = 0;
372 374
373 if (use_protection != bss_conf->use_cts_prot) { 375 if (use_protection != bss_conf->use_cts_prot) {
@@ -571,7 +573,7 @@ static void ieee80211_set_associated(struct net_device *dev,
571 ieee80211_sta_tear_down_BA_sessions(dev, ifsta->bssid); 573 ieee80211_sta_tear_down_BA_sessions(dev, ifsta->bssid);
572 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; 574 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
573 netif_carrier_off(dev); 575 netif_carrier_off(dev);
574 ieee80211_reset_erp_info(dev); 576 changed |= ieee80211_reset_erp_info(dev);
575 577
576 sdata->bss_conf.assoc_ht = 0; 578 sdata->bss_conf.assoc_ht = 0;
577 sdata->bss_conf.ht_conf = NULL; 579 sdata->bss_conf.ht_conf = NULL;
@@ -1536,6 +1538,35 @@ void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid,
1536 ieee80211_sta_tx(dev, skb, 0); 1538 ieee80211_sta_tx(dev, skb, 0);
1537} 1539}
1538 1540
1541void ieee80211_send_bar(struct net_device *dev, u8 *ra, u16 tid, u16 ssn)
1542{
1543 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1544 struct sk_buff *skb;
1545 struct ieee80211_bar *bar;
1546 u16 bar_control = 0;
1547
1548 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
1549 if (!skb) {
1550 printk(KERN_ERR "%s: failed to allocate buffer for "
1551 "bar frame\n", dev->name);
1552 return;
1553 }
1554 skb_reserve(skb, local->hw.extra_tx_headroom);
1555 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
1556 memset(bar, 0, sizeof(*bar));
1557 bar->frame_control = IEEE80211_FC(IEEE80211_FTYPE_CTL,
1558 IEEE80211_STYPE_BACK_REQ);
1559 memcpy(bar->ra, ra, ETH_ALEN);
1560 memcpy(bar->ta, dev->dev_addr, ETH_ALEN);
1561 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
1562 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
1563 bar_control |= (u16)(tid << 12);
1564 bar->control = cpu_to_le16(bar_control);
1565 bar->start_seq_num = cpu_to_le16(ssn);
1566
1567 ieee80211_sta_tx(dev, skb, 0);
1568}
1569
1539void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, 1570void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
1540 u16 initiator, u16 reason) 1571 u16 initiator, u16 reason)
1541{ 1572{
@@ -2481,6 +2512,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2481 control->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; 2512 control->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
2482 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; 2513 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
2483 control->flags |= IEEE80211_TX_CTL_NO_ACK; 2514 control->flags |= IEEE80211_TX_CTL_NO_ACK;
2515 control->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
2484 control->control.retry_limit = 1; 2516 control->control.retry_limit = 1;
2485 2517
2486 ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); 2518 ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6a88e8f9bff0..fab443d717eb 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -321,20 +321,20 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
321 321
322static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) 322static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
323{ 323{
324 u8 *data = rx->skb->data; 324 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
325 int tid; 325 int tid;
326 326
327 /* does the frame have a qos control field? */ 327 /* does the frame have a qos control field? */
328 if (WLAN_FC_IS_QOS_DATA(rx->fc)) { 328 if (ieee80211_is_data_qos(hdr->frame_control)) {
329 u8 *qc = data + ieee80211_get_hdrlen(rx->fc) - QOS_CONTROL_LEN; 329 u8 *qc = ieee80211_get_qos_ctl(hdr);
330 /* frame has qos control */ 330 /* frame has qos control */
331 tid = qc[0] & QOS_CONTROL_TID_MASK; 331 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
332 if (qc[0] & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) 332 if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
333 rx->flags |= IEEE80211_RX_AMSDU; 333 rx->flags |= IEEE80211_RX_AMSDU;
334 else 334 else
335 rx->flags &= ~IEEE80211_RX_AMSDU; 335 rx->flags &= ~IEEE80211_RX_AMSDU;
336 } else { 336 } else {
337 if (unlikely((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)) { 337 if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
338 /* Separate TID for management frames */ 338 /* Separate TID for management frames */
339 tid = NUM_RX_DATA_QUEUES - 1; 339 tid = NUM_RX_DATA_QUEUES - 1;
340 } else { 340 } else {
@@ -352,9 +352,10 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
352static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx) 352static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx)
353{ 353{
354#ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT 354#ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT
355 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
355 int hdrlen; 356 int hdrlen;
356 357
357 if (!WLAN_FC_DATA_PRESENT(rx->fc)) 358 if (!ieee80211_is_data_present(hdr->frame_control))
358 return; 359 return;
359 360
360 /* 361 /*
@@ -376,7 +377,7 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx)
376 * header and the payload is not supported, the driver is required 377 * header and the payload is not supported, the driver is required
377 * to move the 802.11 header further back in that case. 378 * to move the 802.11 header further back in that case.
378 */ 379 */
379 hdrlen = ieee80211_get_hdrlen(rx->fc); 380 hdrlen = ieee80211_hdrlen(hdr->frame_control);
380 if (rx->flags & IEEE80211_RX_AMSDU) 381 if (rx->flags & IEEE80211_RX_AMSDU)
381 hdrlen += ETH_HLEN; 382 hdrlen += ETH_HLEN;
382 WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3); 383 WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3);
@@ -415,14 +416,11 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
415static ieee80211_rx_result 416static ieee80211_rx_result
416ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) 417ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
417{ 418{
418 int hdrlen = ieee80211_get_hdrlen(rx->fc); 419 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
419 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; 420 unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control);
420 421
421#define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l)) 422 if (ieee80211_is_data(hdr->frame_control)) {
422 423 if (!ieee80211_has_a4(hdr->frame_control))
423 if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
424 if (!((rx->fc & IEEE80211_FCTL_FROMDS) &&
425 (rx->fc & IEEE80211_FCTL_TODS)))
426 return RX_DROP_MONITOR; 424 return RX_DROP_MONITOR;
427 if (memcmp(hdr->addr4, rx->dev->dev_addr, ETH_ALEN) == 0) 425 if (memcmp(hdr->addr4, rx->dev->dev_addr, ETH_ALEN) == 0)
428 return RX_DROP_MONITOR; 426 return RX_DROP_MONITOR;
@@ -435,27 +433,30 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
435 if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) { 433 if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) {
436 struct ieee80211_mgmt *mgmt; 434 struct ieee80211_mgmt *mgmt;
437 435
438 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) 436 if (!ieee80211_is_mgmt(hdr->frame_control))
439 return RX_DROP_MONITOR; 437 return RX_DROP_MONITOR;
440 438
441 switch (rx->fc & IEEE80211_FCTL_STYPE) { 439 if (ieee80211_is_action(hdr->frame_control)) {
442 case IEEE80211_STYPE_ACTION:
443 mgmt = (struct ieee80211_mgmt *)hdr; 440 mgmt = (struct ieee80211_mgmt *)hdr;
444 if (mgmt->u.action.category != PLINK_CATEGORY) 441 if (mgmt->u.action.category != PLINK_CATEGORY)
445 return RX_DROP_MONITOR; 442 return RX_DROP_MONITOR;
446 /* fall through on else */
447 case IEEE80211_STYPE_PROBE_REQ:
448 case IEEE80211_STYPE_PROBE_RESP:
449 case IEEE80211_STYPE_BEACON:
450 return RX_CONTINUE; 443 return RX_CONTINUE;
451 break;
452 default:
453 return RX_DROP_MONITOR;
454 } 444 }
455 445
456 } else if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && 446 if (ieee80211_is_probe_req(hdr->frame_control) ||
457 is_multicast_ether_addr(hdr->addr1) && 447 ieee80211_is_probe_resp(hdr->frame_control) ||
458 mesh_rmc_check(hdr->addr4, msh_h_get(hdr, hdrlen), rx->dev)) 448 ieee80211_is_beacon(hdr->frame_control))
449 return RX_CONTINUE;
450
451 return RX_DROP_MONITOR;
452
453 }
454
455#define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l))
456
457 if (ieee80211_is_data(hdr->frame_control) &&
458 is_multicast_ether_addr(hdr->addr1) &&
459 mesh_rmc_check(hdr->addr4, msh_h_get(hdr, hdrlen), rx->dev))
459 return RX_DROP_MONITOR; 460 return RX_DROP_MONITOR;
460#undef msh_h_get 461#undef msh_h_get
461 462
@@ -466,13 +467,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
466static ieee80211_rx_result debug_noinline 467static ieee80211_rx_result debug_noinline
467ieee80211_rx_h_check(struct ieee80211_rx_data *rx) 468ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
468{ 469{
469 struct ieee80211_hdr *hdr; 470 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
470
471 hdr = (struct ieee80211_hdr *) rx->skb->data;
472 471
473 /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ 472 /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
474 if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { 473 if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) {
475 if (unlikely(rx->fc & IEEE80211_FCTL_RETRY && 474 if (unlikely(ieee80211_has_retry(hdr->frame_control) &&
476 rx->sta->last_seq_ctrl[rx->queue] == 475 rx->sta->last_seq_ctrl[rx->queue] ==
477 hdr->seq_ctrl)) { 476 hdr->seq_ctrl)) {
478 if (rx->flags & IEEE80211_RX_RA_MATCH) { 477 if (rx->flags & IEEE80211_RX_RA_MATCH) {
@@ -501,15 +500,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
501 if (ieee80211_vif_is_mesh(&rx->sdata->vif)) 500 if (ieee80211_vif_is_mesh(&rx->sdata->vif))
502 return ieee80211_rx_mesh_check(rx); 501 return ieee80211_rx_mesh_check(rx);
503 502
504 if (unlikely(((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || 503 if (unlikely((ieee80211_is_data(hdr->frame_control) ||
505 ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && 504 ieee80211_is_pspoll(hdr->frame_control)) &&
506 (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) &&
507 rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 505 rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
508 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { 506 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
509 if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && 507 if ((!ieee80211_has_fromds(hdr->frame_control) &&
510 !(rx->fc & IEEE80211_FCTL_TODS) && 508 !ieee80211_has_tods(hdr->frame_control) &&
511 (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) 509 ieee80211_is_data(hdr->frame_control)) ||
512 || !(rx->flags & IEEE80211_RX_RA_MATCH)) { 510 !(rx->flags & IEEE80211_RX_RA_MATCH)) {
513 /* Drop IBSS frames and frames for other hosts 511 /* Drop IBSS frames and frames for other hosts
514 * silently. */ 512 * silently. */
515 return RX_DROP_MONITOR; 513 return RX_DROP_MONITOR;
@@ -525,7 +523,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
525static ieee80211_rx_result debug_noinline 523static ieee80211_rx_result debug_noinline
526ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) 524ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
527{ 525{
528 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; 526 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
529 int keyidx; 527 int keyidx;
530 int hdrlen; 528 int hdrlen;
531 ieee80211_rx_result result = RX_DROP_UNUSABLE; 529 ieee80211_rx_result result = RX_DROP_UNUSABLE;
@@ -557,7 +555,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
557 * possible. 555 * possible.
558 */ 556 */
559 557
560 if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) 558 if (!ieee80211_has_protected(hdr->frame_control))
561 return RX_CONTINUE; 559 return RX_CONTINUE;
562 560
563 /* 561 /*
@@ -586,7 +584,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
586 (rx->status->flag & RX_FLAG_IV_STRIPPED)) 584 (rx->status->flag & RX_FLAG_IV_STRIPPED))
587 return RX_CONTINUE; 585 return RX_CONTINUE;
588 586
589 hdrlen = ieee80211_get_hdrlen(rx->fc); 587 hdrlen = ieee80211_hdrlen(hdr->frame_control);
590 588
591 if (rx->skb->len < 8 + hdrlen) 589 if (rx->skb->len < 8 + hdrlen)
592 return RX_DROP_UNUSABLE; /* TODO: count this? */ 590 return RX_DROP_UNUSABLE; /* TODO: count this? */
@@ -618,7 +616,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
618 616
619 /* Check for weak IVs if possible */ 617 /* Check for weak IVs if possible */
620 if (rx->sta && rx->key->conf.alg == ALG_WEP && 618 if (rx->sta && rx->key->conf.alg == ALG_WEP &&
621 ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && 619 ieee80211_is_data(hdr->frame_control) &&
622 (!(rx->status->flag & RX_FLAG_IV_STRIPPED) || 620 (!(rx->status->flag & RX_FLAG_IV_STRIPPED) ||
623 !(rx->status->flag & RX_FLAG_DECRYPTED)) && 621 !(rx->status->flag & RX_FLAG_DECRYPTED)) &&
624 ieee80211_wep_is_weak_iv(rx->skb, rx->key)) 622 ieee80211_wep_is_weak_iv(rx->skb, rx->key))
@@ -710,7 +708,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
710{ 708{
711 struct sta_info *sta = rx->sta; 709 struct sta_info *sta = rx->sta;
712 struct net_device *dev = rx->dev; 710 struct net_device *dev = rx->dev;
713 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; 711 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
714 712
715 if (!sta) 713 if (!sta)
716 return RX_CONTINUE; 714 return RX_CONTINUE;
@@ -744,21 +742,20 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
744 sta->last_qual = rx->status->qual; 742 sta->last_qual = rx->status->qual;
745 sta->last_noise = rx->status->noise; 743 sta->last_noise = rx->status->noise;
746 744
747 if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { 745 if (!ieee80211_has_morefrags(hdr->frame_control)) {
748 /* Change STA power saving mode only in the end of a frame 746 /* Change STA power saving mode only in the end of a frame
749 * exchange sequence */ 747 * exchange sequence */
750 if (test_sta_flags(sta, WLAN_STA_PS) && 748 if (test_sta_flags(sta, WLAN_STA_PS) &&
751 !(rx->fc & IEEE80211_FCTL_PM)) 749 !ieee80211_has_pm(hdr->frame_control))
752 rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); 750 rx->sent_ps_buffered += ap_sta_ps_end(dev, sta);
753 else if (!test_sta_flags(sta, WLAN_STA_PS) && 751 else if (!test_sta_flags(sta, WLAN_STA_PS) &&
754 (rx->fc & IEEE80211_FCTL_PM)) 752 ieee80211_has_pm(hdr->frame_control))
755 ap_sta_ps_start(dev, sta); 753 ap_sta_ps_start(dev, sta);
756 } 754 }
757 755
758 /* Drop data::nullfunc frames silently, since they are used only to 756 /* Drop data::nullfunc frames silently, since they are used only to
759 * control station power saving mode. */ 757 * control station power saving mode. */
760 if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && 758 if (ieee80211_is_nullfunc(hdr->frame_control)) {
761 (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_NULLFUNC) {
762 I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc); 759 I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc);
763 /* Update counter and free packet here to avoid counting this 760 /* Update counter and free packet here to avoid counting this
764 * as a dropped packed. */ 761 * as a dropped packed. */
@@ -1037,19 +1034,19 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
1037static ieee80211_rx_result debug_noinline 1034static ieee80211_rx_result debug_noinline
1038ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) 1035ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx)
1039{ 1036{
1040 u16 fc = rx->fc;
1041 u8 *data = rx->skb->data; 1037 u8 *data = rx->skb->data;
1042 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) data; 1038 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)data;
1043 1039
1044 if (!WLAN_FC_IS_QOS_DATA(fc)) 1040 if (!ieee80211_is_data_qos(hdr->frame_control))
1045 return RX_CONTINUE; 1041 return RX_CONTINUE;
1046 1042
1047 /* remove the qos control field, update frame type and meta-data */ 1043 /* remove the qos control field, update frame type and meta-data */
1048 memmove(data + 2, data, ieee80211_get_hdrlen(fc) - 2); 1044 memmove(data + IEEE80211_QOS_CTL_LEN, data,
1049 hdr = (struct ieee80211_hdr *) skb_pull(rx->skb, 2); 1045 ieee80211_hdrlen(hdr->frame_control) - IEEE80211_QOS_CTL_LEN);
1046 hdr = (struct ieee80211_hdr *)skb_pull(rx->skb, IEEE80211_QOS_CTL_LEN);
1050 /* change frame type to non QOS */ 1047 /* change frame type to non QOS */
1051 rx->fc = fc &= ~IEEE80211_STYPE_QOS_DATA; 1048 rx->fc &= ~IEEE80211_STYPE_QOS_DATA;
1052 hdr->frame_control = cpu_to_le16(fc); 1049 hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
1053 1050
1054 return RX_CONTINUE; 1051 return RX_CONTINUE;
1055} 1052}
@@ -1465,15 +1462,15 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
1465 struct ieee80211_local *local = rx->local; 1462 struct ieee80211_local *local = rx->local;
1466 struct ieee80211_hw *hw = &local->hw; 1463 struct ieee80211_hw *hw = &local->hw;
1467 struct sk_buff *skb = rx->skb; 1464 struct sk_buff *skb = rx->skb;
1468 struct ieee80211_bar *bar = (struct ieee80211_bar *) skb->data; 1465 struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data;
1469 struct tid_ampdu_rx *tid_agg_rx; 1466 struct tid_ampdu_rx *tid_agg_rx;
1470 u16 start_seq_num; 1467 u16 start_seq_num;
1471 u16 tid; 1468 u16 tid;
1472 1469
1473 if (likely((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL)) 1470 if (likely(!ieee80211_is_ctl(bar->frame_control)))
1474 return RX_CONTINUE; 1471 return RX_CONTINUE;
1475 1472
1476 if ((rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ) { 1473 if (ieee80211_is_back_req(bar->frame_control)) {
1477 if (!rx->sta) 1474 if (!rx->sta)
1478 return RX_CONTINUE; 1475 return RX_CONTINUE;
1479 tid = le16_to_cpu(bar->control) >> 12; 1476 tid = le16_to_cpu(bar->control) >> 12;
@@ -1527,11 +1524,12 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
1527 struct ieee80211_hdr *hdr, 1524 struct ieee80211_hdr *hdr,
1528 struct ieee80211_rx_data *rx) 1525 struct ieee80211_rx_data *rx)
1529{ 1526{
1530 int keyidx, hdrlen; 1527 int keyidx;
1528 unsigned int hdrlen;
1531 DECLARE_MAC_BUF(mac); 1529 DECLARE_MAC_BUF(mac);
1532 DECLARE_MAC_BUF(mac2); 1530 DECLARE_MAC_BUF(mac2);
1533 1531
1534 hdrlen = ieee80211_get_hdrlen_from_skb(rx->skb); 1532 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1535 if (rx->skb->len >= hdrlen + 4) 1533 if (rx->skb->len >= hdrlen + 4)
1536 keyidx = rx->skb->data[hdrlen + 3] >> 6; 1534 keyidx = rx->skb->data[hdrlen + 3] >> 6;
1537 else 1535 else
@@ -1545,7 +1543,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
1545 goto ignore; 1543 goto ignore;
1546 } 1544 }
1547 1545
1548 if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) 1546 if (!ieee80211_has_protected(hdr->frame_control))
1549 goto ignore; 1547 goto ignore;
1550 1548
1551 if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) { 1549 if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) {
@@ -1558,9 +1556,8 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
1558 goto ignore; 1556 goto ignore;
1559 } 1557 }
1560 1558
1561 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && 1559 if (!ieee80211_is_data(hdr->frame_control) &&
1562 ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || 1560 !ieee80211_is_auth(hdr->frame_control))
1563 (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH))
1564 goto ignore; 1561 goto ignore;
1565 1562
1566 mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); 1563 mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr);
@@ -1731,8 +1728,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1731 case IEEE80211_IF_TYPE_IBSS: 1728 case IEEE80211_IF_TYPE_IBSS:
1732 if (!bssid) 1729 if (!bssid)
1733 return 0; 1730 return 0;
1734 if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && 1731 if (ieee80211_is_beacon(hdr->frame_control)) {
1735 (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) {
1736 if (!rx->sta) 1732 if (!rx->sta)
1737 rx->sta = ieee80211_ibss_add_sta(sdata->dev, 1733 rx->sta = ieee80211_ibss_add_sta(sdata->dev,
1738 rx->skb, bssid, hdr->addr2, 1734 rx->skb, bssid, hdr->addr2,
@@ -1783,8 +1779,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1783 return 0; 1779 return 0;
1784 break; 1780 break;
1785 case IEEE80211_IF_TYPE_WDS: 1781 case IEEE80211_IF_TYPE_WDS:
1786 if (bssid || 1782 if (bssid || !ieee80211_is_data(hdr->frame_control))
1787 (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
1788 return 0; 1783 return 0;
1789 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) 1784 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
1790 return 0; 1785 return 0;
@@ -2044,7 +2039,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2044 if (!ieee80211_is_data_qos(hdr->frame_control)) 2039 if (!ieee80211_is_data_qos(hdr->frame_control))
2045 goto end_reorder; 2040 goto end_reorder;
2046 2041
2047 tid = *ieee80211_get_qos_ctl(hdr) & QOS_CONTROL_TID_MASK; 2042 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
2048 2043
2049 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) 2044 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL)
2050 goto end_reorder; 2045 goto end_reorder;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index d8a16b7f6a6b..47d2c1bbfcaa 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -135,6 +135,7 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx,
135/** 135/**
136 * __sta_info_free - internal STA free helper 136 * __sta_info_free - internal STA free helper
137 * 137 *
138 * @local: pointer to the global information
138 * @sta: STA info to free 139 * @sta: STA info to free
139 * 140 *
140 * This function must undo everything done by sta_info_alloc() 141 * This function must undo everything done by sta_info_alloc()
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index fd228c198e31..94311dcfe043 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -160,11 +160,21 @@ struct sta_ampdu_mlme {
160 * @list: global linked list entry 160 * @list: global linked list entry
161 * @hnext: hash table linked list pointer 161 * @hnext: hash table linked list pointer
162 * @local: pointer to the global information 162 * @local: pointer to the global information
163 * @sdata: TBD
164 * @key: TBD
165 * @rate_ctrl: TBD
166 * @rate_ctrl_priv: TBD
167 * @lock: used for locking all fields that require locking, see comments
168 * in the header file.
169 * @flaglock: spinlock for flags accesses
170 * @ht_info: HT capabilities of this STA
171 * @supp_rates: Bitmap of supported rates (per band)
163 * @addr: MAC address of this STA 172 * @addr: MAC address of this STA
164 * @aid: STA's unique AID (1..2007, 0 = not assigned yet), 173 * @aid: STA's unique AID (1..2007, 0 = not assigned yet),
165 * only used in AP (and IBSS?) mode 174 * only used in AP (and IBSS?) mode
175 * @listen_interval: TBD
176 * @pin_status: TBD
166 * @flags: STA flags, see &enum ieee80211_sta_info_flags 177 * @flags: STA flags, see &enum ieee80211_sta_info_flags
167 * @flaglock: spinlock for flags accesses
168 * @ps_tx_buf: buffer of frames to transmit to this station 178 * @ps_tx_buf: buffer of frames to transmit to this station
169 * when it leaves power saving state 179 * when it leaves power saving state
170 * @tx_filtered: buffer of frames we already tried to transmit 180 * @tx_filtered: buffer of frames we already tried to transmit
@@ -172,10 +182,41 @@ struct sta_ampdu_mlme {
172 * power saving state 182 * power saving state
173 * @rx_packets: Number of MSDUs received from this STA 183 * @rx_packets: Number of MSDUs received from this STA
174 * @rx_bytes: Number of bytes received from this STA 184 * @rx_bytes: Number of bytes received from this STA
175 * @supp_rates: Bitmap of supported rates (per band) 185 * @wep_weak_iv_count: TBD
176 * @ht_info: HT capabilities of this STA 186 * @last_rx: TBD
177 * @lock: used for locking all fields that require locking, see comments 187 * @num_duplicates: number of duplicate frames received from this STA
178 * in the header file. 188 * @rx_fragments: number of received MPDUs
189 * @rx_dropped: number of dropped MPDUs from this STA
190 * @last_signal: signal of last received frame from this STA
191 * @last_qual: qual of last received frame from this STA
192 * @last_noise: noise of last received frame from this STA
193 * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
194 * @wme_rx_queue: TBD
195 * @tx_filtered_count: TBD
196 * @tx_retry_failed: TBD
197 * @tx_retry_count: TBD
198 * @tx_num_consecutive_failures: TBD
199 * @tx_num_mpdu_ok: TBD
200 * @tx_num_mpdu_fail: TBD
201 * @fail_avg: moving percentage of failed MSDUs
202 * @tx_packets: number of RX/TX MSDUs
203 * @tx_bytes: TBD
204 * @tx_fragments: number of transmitted MPDUs
205 * @txrate_idx: TBD
206 * @last_txrate_idx: TBD
207 * @wme_tx_queue: TBD
208 * @ampdu_mlme: TBD
209 * @timer_to_tid: identity mapping to ID timers
210 * @tid_to_tx_q: map tid to tx queue
211 * @llid: Local link ID
212 * @plid: Peer link ID
213 * @reason: Cancel reason on PLINK_HOLDING state
214 * @plink_retries: Retries in establishment
215 * @ignore_plink_timer: TBD
216 * @plink_state plink_state: TBD
217 * @plink_timeout: TBD
218 * @plink_timer: TBD
219 * @debugfs: debug filesystem info
179 */ 220 */
180struct sta_info { 221struct sta_info {
181 /* General information, mostly static */ 222 /* General information, mostly static */
@@ -217,14 +258,12 @@ struct sta_info {
217 unsigned long rx_packets, rx_bytes; 258 unsigned long rx_packets, rx_bytes;
218 unsigned long wep_weak_iv_count; 259 unsigned long wep_weak_iv_count;
219 unsigned long last_rx; 260 unsigned long last_rx;
220 unsigned long num_duplicates; /* number of duplicate frames received 261 unsigned long num_duplicates;
221 * from this STA */ 262 unsigned long rx_fragments;
222 unsigned long rx_fragments; /* number of received MPDUs */ 263 unsigned long rx_dropped;
223 unsigned long rx_dropped; /* number of dropped MPDUs from this STA */ 264 int last_signal;
224 int last_signal; /* signal of last received frame from this STA */ 265 int last_qual;
225 int last_qual; /* qual of last received frame from this STA */ 266 int last_noise;
226 int last_noise; /* noise of last received frame from this STA */
227 /* last received seq/frag number from this STA (per RX queue) */
228 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; 267 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
229#ifdef CONFIG_MAC80211_DEBUG_COUNTERS 268#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
230 unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES]; 269 unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES];
@@ -241,9 +280,9 @@ struct sta_info {
241 unsigned int fail_avg; 280 unsigned int fail_avg;
242 281
243 /* Updated from TX path only, no locking requirements */ 282 /* Updated from TX path only, no locking requirements */
244 unsigned long tx_packets; /* number of RX/TX MSDUs */ 283 unsigned long tx_packets;
245 unsigned long tx_bytes; 284 unsigned long tx_bytes;
246 unsigned long tx_fragments; /* number of transmitted MPDUs */ 285 unsigned long tx_fragments;
247 int txrate_idx; 286 int txrate_idx;
248 int last_txrate_idx; 287 int last_txrate_idx;
249#ifdef CONFIG_MAC80211_DEBUG_COUNTERS 288#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
@@ -254,18 +293,18 @@ struct sta_info {
254 * Aggregation information, locked with lock. 293 * Aggregation information, locked with lock.
255 */ 294 */
256 struct sta_ampdu_mlme ampdu_mlme; 295 struct sta_ampdu_mlme ampdu_mlme;
257 u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */ 296 u8 timer_to_tid[STA_TID_NUM];
258 u8 tid_to_tx_q[STA_TID_NUM]; /* map tid to tx queue */ 297 u8 tid_to_tx_q[STA_TID_NUM];
259 298
260#ifdef CONFIG_MAC80211_MESH 299#ifdef CONFIG_MAC80211_MESH
261 /* 300 /*
262 * Mesh peer link attributes 301 * Mesh peer link attributes
263 * TODO: move to a sub-structure that is referenced with pointer? 302 * TODO: move to a sub-structure that is referenced with pointer?
264 */ 303 */
265 __le16 llid; /* Local link ID */ 304 __le16 llid;
266 __le16 plid; /* Peer link ID */ 305 __le16 plid;
267 __le16 reason; /* Cancel reason on PLINK_HOLDING state */ 306 __le16 reason;
268 u8 plink_retries; /* Retries in establishment */ 307 u8 plink_retries;
269 bool ignore_plink_timer; 308 bool ignore_plink_timer;
270 enum plink_state plink_state; 309 enum plink_state plink_state;
271 u32 plink_timeout; 310 u32 plink_timeout;
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 1babb979fe00..736c32e340f2 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -800,6 +800,8 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
800 800
801 if (frag->disabled) 801 if (frag->disabled)
802 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; 802 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
803 else if (!frag->fixed)
804 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
803 else if (frag->value < 256 || 805 else if (frag->value < 256 ||
804 frag->value > IEEE80211_MAX_FRAG_THRESHOLD) 806 frag->value > IEEE80211_MAX_FRAG_THRESHOLD)
805 return -EINVAL; 807 return -EINVAL;
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index ffe1af82fa4d..5c666f7eda8f 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -154,7 +154,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
154 queue = skb_get_queue_mapping(skb); 154 queue = skb_get_queue_mapping(skb);
155 rcu_read_lock(); 155 rcu_read_lock();
156 sta = sta_info_get(local, hdr->addr1); 156 sta = sta_info_get(local, hdr->addr1);
157 tid = skb->priority & QOS_CONTROL_TAG1D_MASK; 157 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
158 if (sta) { 158 if (sta) {
159 int ampdu_queue = sta->tid_to_tx_q[tid]; 159 int ampdu_queue = sta->tid_to_tx_q[tid];
160 if ((ampdu_queue < QD_NUM(hw)) && 160 if ((ampdu_queue < QD_NUM(hw)) &&
@@ -181,7 +181,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
181 if (ieee80211_is_data_qos(hdr->frame_control)) { 181 if (ieee80211_is_data_qos(hdr->frame_control)) {
182 u8 *p = ieee80211_get_qos_ctl(hdr); 182 u8 *p = ieee80211_get_qos_ctl(hdr);
183 u8 ack_policy = 0; 183 u8 ack_policy = 0;
184 tid = skb->priority & QOS_CONTROL_TAG1D_MASK; 184 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
185 if (local->wifi_wme_noack_test) 185 if (local->wifi_wme_noack_test)
186 ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << 186 ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK <<
187 QOS_CONTROL_ACK_POLICY_SHIFT; 187 QOS_CONTROL_ACK_POLICY_SHIFT;
@@ -210,7 +210,6 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
210 kfree_skb(skb); 210 kfree_skb(skb);
211 err = NET_XMIT_DROP; 211 err = NET_XMIT_DROP;
212 } else { 212 } else {
213 tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
214 skb_set_queue_mapping(skb, queue); 213 skb_set_queue_mapping(skb, queue);
215 qdisc = q->queues[queue]; 214 qdisc = q->queues[queue];
216 err = qdisc->enqueue(skb, qdisc); 215 err = qdisc->enqueue(skb, qdisc);
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index bbdb53344817..1aca609eccfc 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -19,18 +19,10 @@
19#define QOS_CONTROL_ACK_POLICY_NORMAL 0 19#define QOS_CONTROL_ACK_POLICY_NORMAL 0
20#define QOS_CONTROL_ACK_POLICY_NOACK 1 20#define QOS_CONTROL_ACK_POLICY_NOACK 1
21 21
22#define QOS_CONTROL_TID_MASK 0x0f
23#define QOS_CONTROL_ACK_POLICY_SHIFT 5 22#define QOS_CONTROL_ACK_POLICY_SHIFT 5
24 23
25#define QOS_CONTROL_TAG1D_MASK 0x07
26
27extern const int ieee802_1d_to_ac[8]; 24extern const int ieee802_1d_to_ac[8];
28 25
29static inline int WLAN_FC_IS_QOS_DATA(u16 fc)
30{
31 return (fc & 0x8C) == 0x88;
32}
33
34#ifdef CONFIG_MAC80211_QOS 26#ifdef CONFIG_MAC80211_QOS
35void ieee80211_install_qdisc(struct net_device *dev); 27void ieee80211_install_qdisc(struct net_device *dev);
36int ieee80211_qdisc_installed(struct net_device *dev); 28int ieee80211_qdisc_installed(struct net_device *dev);
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index b414d5d92f38..2f33df0dcccf 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -11,6 +11,8 @@
11#include <linux/slab.h> 11#include <linux/slab.h>
12#include <linux/skbuff.h> 12#include <linux/skbuff.h>
13#include <linux/compiler.h> 13#include <linux/compiler.h>
14#include <linux/ieee80211.h>
15#include <asm/unaligned.h>
14#include <net/mac80211.h> 16#include <net/mac80211.h>
15 17
16#include "ieee80211_i.h" 18#include "ieee80211_i.h"
@@ -19,53 +21,30 @@
19#include "aes_ccm.h" 21#include "aes_ccm.h"
20#include "wpa.h" 22#include "wpa.h"
21 23
22static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da,
23 u8 *qos_tid, u8 **data, size_t *data_len)
24{
25 struct ieee80211_hdr *hdr;
26 size_t hdrlen;
27 __le16 fc;
28
29 hdr = (struct ieee80211_hdr *)skb->data;
30 fc = hdr->frame_control;
31
32 hdrlen = ieee80211_hdrlen(fc);
33
34 *sa = ieee80211_get_SA(hdr);
35 *da = ieee80211_get_DA(hdr);
36
37 *data = skb->data + hdrlen;
38 *data_len = skb->len - hdrlen;
39
40 if (ieee80211_is_data_qos(fc))
41 *qos_tid = (*ieee80211_get_qos_ctl(hdr) & 0x0f) | 0x80;
42 else
43 *qos_tid = 0;
44
45 return skb->len < hdrlen ? -1 : 0;
46}
47
48
49ieee80211_tx_result 24ieee80211_tx_result
50ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) 25ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
51{ 26{
52 u8 *data, *sa, *da, *key, *mic, qos_tid, key_offset; 27 u8 *data, *key, *mic, key_offset;
53 size_t data_len; 28 size_t data_len;
54 u16 fc; 29 unsigned int hdrlen;
30 struct ieee80211_hdr *hdr;
55 struct sk_buff *skb = tx->skb; 31 struct sk_buff *skb = tx->skb;
56 int authenticator; 32 int authenticator;
57 int wpa_test = 0; 33 int wpa_test = 0;
58 int tail; 34 int tail;
59 35
60 fc = tx->fc; 36 hdr = (struct ieee80211_hdr *)skb->data;
61
62 if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 || 37 if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 ||
63 !WLAN_FC_DATA_PRESENT(fc)) 38 !ieee80211_is_data_present(hdr->frame_control))
64 return TX_CONTINUE; 39 return TX_CONTINUE;
65 40
66 if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)) 41 hdrlen = ieee80211_hdrlen(hdr->frame_control);
42 if (skb->len < hdrlen)
67 return TX_DROP; 43 return TX_DROP;
68 44
45 data = skb->data + hdrlen;
46 data_len = skb->len - hdrlen;
47
69 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 48 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
70 !(tx->flags & IEEE80211_TX_FRAGMENTED) && 49 !(tx->flags & IEEE80211_TX_FRAGMENTED) &&
71 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && 50 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) &&
@@ -95,7 +74,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
95 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; 74 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
96 key = &tx->key->conf.key[key_offset]; 75 key = &tx->key->conf.key[key_offset];
97 mic = skb_put(skb, MICHAEL_MIC_LEN); 76 mic = skb_put(skb, MICHAEL_MIC_LEN);
98 michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); 77 michael_mic(key, hdr, data, data_len, mic);
99 78
100 return TX_CONTINUE; 79 return TX_CONTINUE;
101} 80}
@@ -104,31 +83,33 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
104ieee80211_rx_result 83ieee80211_rx_result
105ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) 84ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
106{ 85{
107 u8 *data, *sa, *da, *key = NULL, qos_tid, key_offset; 86 u8 *data, *key = NULL, key_offset;
108 size_t data_len; 87 size_t data_len;
109 u16 fc; 88 unsigned int hdrlen;
89 struct ieee80211_hdr *hdr;
110 u8 mic[MICHAEL_MIC_LEN]; 90 u8 mic[MICHAEL_MIC_LEN];
111 struct sk_buff *skb = rx->skb; 91 struct sk_buff *skb = rx->skb;
112 int authenticator = 1, wpa_test = 0; 92 int authenticator = 1, wpa_test = 0;
113 DECLARE_MAC_BUF(mac); 93 DECLARE_MAC_BUF(mac);
114 94
115 fc = rx->fc;
116
117 /* 95 /*
118 * No way to verify the MIC if the hardware stripped it 96 * No way to verify the MIC if the hardware stripped it
119 */ 97 */
120 if (rx->status->flag & RX_FLAG_MMIC_STRIPPED) 98 if (rx->status->flag & RX_FLAG_MMIC_STRIPPED)
121 return RX_CONTINUE; 99 return RX_CONTINUE;
122 100
101 hdr = (struct ieee80211_hdr *)skb->data;
123 if (!rx->key || rx->key->conf.alg != ALG_TKIP || 102 if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
124 !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc)) 103 !ieee80211_has_protected(hdr->frame_control) ||
104 !ieee80211_is_data_present(hdr->frame_control))
125 return RX_CONTINUE; 105 return RX_CONTINUE;
126 106
127 if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len) 107 hdrlen = ieee80211_hdrlen(hdr->frame_control);
128 || data_len < MICHAEL_MIC_LEN) 108 if (skb->len < hdrlen + MICHAEL_MIC_LEN)
129 return RX_DROP_UNUSABLE; 109 return RX_DROP_UNUSABLE;
130 110
131 data_len -= MICHAEL_MIC_LEN; 111 data = skb->data + hdrlen;
112 data_len = skb->len - hdrlen - MICHAEL_MIC_LEN;
132 113
133#if 0 114#if 0
134 authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */ 115 authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */
@@ -141,7 +122,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
141 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY : 122 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY :
142 NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; 123 NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
143 key = &rx->key->conf.key[key_offset]; 124 key = &rx->key->conf.key[key_offset];
144 michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); 125 michael_mic(key, hdr, data, data_len, mic);
145 if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { 126 if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) {
146 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 127 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
147 return RX_DROP_UNUSABLE; 128 return RX_DROP_UNUSABLE;
@@ -253,7 +234,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
253 234
254 hdrlen = ieee80211_hdrlen(hdr->frame_control); 235 hdrlen = ieee80211_hdrlen(hdr->frame_control);
255 236
256 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) 237 if (!ieee80211_is_data(hdr->frame_control))
257 return RX_CONTINUE; 238 return RX_CONTINUE;
258 239
259 if (!rx->sta || skb->len - hdrlen < 12) 240 if (!rx->sta || skb->len - hdrlen < 12)
@@ -293,70 +274,68 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
293} 274}
294 275
295 276
296static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, 277static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
297 int encrypted) 278 int encrypted)
298{ 279{
299 u16 fc; 280 __le16 mask_fc;
300 int a4_included, qos_included; 281 int a4_included;
301 u8 qos_tid, *fc_pos, *data, *sa, *da; 282 u8 qos_tid;
302 int len_a; 283 u8 *b_0, *aad;
303 size_t data_len; 284 u16 data_len, len_a;
304 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 285 unsigned int hdrlen;
286 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
305 287
306 fc_pos = (u8 *) &hdr->frame_control; 288 b_0 = scratch + 3 * AES_BLOCK_LEN;
307 fc = fc_pos[0] ^ (fc_pos[1] << 8); 289 aad = scratch + 4 * AES_BLOCK_LEN;
308 a4_included = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == 290
309 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); 291 /*
310 292 * Mask FC: zero subtype b4 b5 b6
311 ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len); 293 * Retry, PwrMgt, MoreData; set Protected
312 data_len -= CCMP_HDR_LEN + (encrypted ? CCMP_MIC_LEN : 0); 294 */
313 if (qos_tid & 0x80) { 295 mask_fc = hdr->frame_control;
314 qos_included = 1; 296 mask_fc &= ~cpu_to_le16(0x0070 | IEEE80211_FCTL_RETRY |
315 qos_tid &= 0x0f; 297 IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA);
316 } else 298 mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
317 qos_included = 0; 299
318 /* First block, b_0 */ 300 hdrlen = ieee80211_hdrlen(hdr->frame_control);
301 len_a = hdrlen - 2;
302 a4_included = ieee80211_has_a4(hdr->frame_control);
303
304 if (ieee80211_is_data_qos(hdr->frame_control))
305 qos_tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
306 else
307 qos_tid = 0;
319 308
309 data_len = skb->len - hdrlen - CCMP_HDR_LEN;
310 if (encrypted)
311 data_len -= CCMP_MIC_LEN;
312
313 /* First block, b_0 */
320 b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ 314 b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
321 /* Nonce: QoS Priority | A2 | PN */ 315 /* Nonce: QoS Priority | A2 | PN */
322 b_0[1] = qos_tid; 316 b_0[1] = qos_tid;
323 memcpy(&b_0[2], hdr->addr2, 6); 317 memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
324 memcpy(&b_0[8], pn, CCMP_PN_LEN); 318 memcpy(&b_0[8], pn, CCMP_PN_LEN);
325 /* l(m) */ 319 /* l(m) */
326 b_0[14] = (data_len >> 8) & 0xff; 320 put_unaligned_be16(data_len, &b_0[14]);
327 b_0[15] = data_len & 0xff;
328
329 321
330 /* AAD (extra authenticate-only data) / masked 802.11 header 322 /* AAD (extra authenticate-only data) / masked 802.11 header
331 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ 323 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
332 324 put_unaligned_be16(len_a, &aad[0]);
333 len_a = a4_included ? 28 : 22; 325 put_unaligned(mask_fc, (__le16 *)&aad[2]);
334 if (qos_included) 326 memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN);
335 len_a += 2;
336
337 aad[0] = 0; /* (len_a >> 8) & 0xff; */
338 aad[1] = len_a & 0xff;
339 /* Mask FC: zero subtype b4 b5 b6 */
340 aad[2] = fc_pos[0] & ~(BIT(4) | BIT(5) | BIT(6));
341 /* Retry, PwrMgt, MoreData; set Protected */
342 aad[3] = (fc_pos[1] & ~(BIT(3) | BIT(4) | BIT(5))) | BIT(6);
343 memcpy(&aad[4], &hdr->addr1, 18);
344 327
345 /* Mask Seq#, leave Frag# */ 328 /* Mask Seq#, leave Frag# */
346 aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f; 329 aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f;
347 aad[23] = 0; 330 aad[23] = 0;
331
348 if (a4_included) { 332 if (a4_included) {
349 memcpy(&aad[24], hdr->addr4, 6); 333 memcpy(&aad[24], hdr->addr4, ETH_ALEN);
350 aad[30] = 0; 334 aad[30] = qos_tid;
351 aad[31] = 0; 335 aad[31] = 0;
352 } else 336 } else {
353 memset(&aad[24], 0, 8); 337 memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN);
354 if (qos_included) { 338 aad[24] = qos_tid;
355 u8 *dpos = &aad[a4_included ? 30 : 24];
356
357 /* Mask QoS Control field */
358 dpos[0] = qos_tid;
359 dpos[1] = 0;
360 } 339 }
361} 340}
362 341
@@ -392,7 +371,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
392 struct ieee80211_key *key = tx->key; 371 struct ieee80211_key *key = tx->key;
393 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 372 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
394 int hdrlen, len, tail; 373 int hdrlen, len, tail;
395 u8 *pos, *pn, *b_0, *aad, *scratch; 374 u8 *pos, *pn;
396 int i; 375 int i;
397 376
398 info->control.icv_len = CCMP_MIC_LEN; 377 info->control.icv_len = CCMP_MIC_LEN;
@@ -406,10 +385,6 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
406 return 0; 385 return 0;
407 } 386 }
408 387
409 scratch = key->u.ccmp.tx_crypto_buf;
410 b_0 = scratch + 3 * AES_BLOCK_LEN;
411 aad = scratch + 4 * AES_BLOCK_LEN;
412
413 hdrlen = ieee80211_hdrlen(hdr->frame_control); 388 hdrlen = ieee80211_hdrlen(hdr->frame_control);
414 len = skb->len - hdrlen; 389 len = skb->len - hdrlen;
415 390
@@ -445,8 +420,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
445 } 420 }
446 421
447 pos += CCMP_HDR_LEN; 422 pos += CCMP_HDR_LEN;
448 ccmp_special_blocks(skb, pn, b_0, aad, 0); 423 ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0);
449 ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, b_0, aad, pos, len, 424 ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, key->u.ccmp.tx_crypto_buf, pos, len,
450 pos, skb_put(skb, CCMP_MIC_LEN)); 425 pos, skb_put(skb, CCMP_MIC_LEN));
451 426
452 return 0; 427 return 0;
@@ -478,7 +453,7 @@ ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
478ieee80211_rx_result 453ieee80211_rx_result
479ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) 454ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
480{ 455{
481 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; 456 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
482 int hdrlen; 457 int hdrlen;
483 struct ieee80211_key *key = rx->key; 458 struct ieee80211_key *key = rx->key;
484 struct sk_buff *skb = rx->skb; 459 struct sk_buff *skb = rx->skb;
@@ -488,7 +463,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
488 463
489 hdrlen = ieee80211_hdrlen(hdr->frame_control); 464 hdrlen = ieee80211_hdrlen(hdr->frame_control);
490 465
491 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) 466 if (!ieee80211_is_data(hdr->frame_control))
492 return RX_CONTINUE; 467 return RX_CONTINUE;
493 468
494 data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN; 469 data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN;
@@ -508,16 +483,10 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
508 483
509 if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { 484 if (!(rx->status->flag & RX_FLAG_DECRYPTED)) {
510 /* hardware didn't decrypt/verify MIC */ 485 /* hardware didn't decrypt/verify MIC */
511 u8 *scratch, *b_0, *aad; 486 ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1);
512
513 scratch = key->u.ccmp.rx_crypto_buf;
514 b_0 = scratch + 3 * AES_BLOCK_LEN;
515 aad = scratch + 4 * AES_BLOCK_LEN;
516
517 ccmp_special_blocks(skb, pn, b_0, aad, 1);
518 487
519 if (ieee80211_aes_ccm_decrypt( 488 if (ieee80211_aes_ccm_decrypt(
520 key->u.ccmp.tfm, scratch, b_0, aad, 489 key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf,
521 skb->data + hdrlen + CCMP_HDR_LEN, data_len, 490 skb->data + hdrlen + CCMP_HDR_LEN, data_len,
522 skb->data + skb->len - CCMP_MIC_LEN, 491 skb->data + skb->len - CCMP_MIC_LEN,
523 skb->data + hdrlen + CCMP_HDR_LEN)) { 492 skb->data + hdrlen + CCMP_HDR_LEN)) {
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index ce0e23148cdd..7a560b785097 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -130,17 +130,19 @@ static void update_rfkill_state(struct rfkill *rfkill)
130 130
131/** 131/**
132 * rfkill_toggle_radio - wrapper for toggle_radio hook 132 * rfkill_toggle_radio - wrapper for toggle_radio hook
133 * calls toggle_radio taking into account a lot of "small" 133 *
134 * details.
135 * @rfkill: the rfkill struct to use 134 * @rfkill: the rfkill struct to use
136 * @force: calls toggle_radio even if cache says it is not needed, 135 * @force: calls toggle_radio even if cache says it is not needed,
137 * and also makes sure notifications of the state will be 136 * and also makes sure notifications of the state will be
138 * sent even if it didn't change 137 * sent even if it didn't change
139 * @state: the new state to call toggle_radio() with 138 * @state: the new state to call toggle_radio() with
140 * 139 *
141 * This wrappen protects and enforces the API for toggle_radio 140 * Calls rfkill->toggle_radio, enforcing the API for toggle_radio
142 * calls. Note that @force cannot override a (possibly cached) 141 * calls and handling all the red tape such as issuing notifications
143 * state of RFKILL_STATE_HARD_BLOCKED. Any device making use of 142 * if the call is successful.
143 *
144 * Note that @force cannot override a (possibly cached) state of
145 * RFKILL_STATE_HARD_BLOCKED. Any device making use of
144 * RFKILL_STATE_HARD_BLOCKED implements either get_state() or 146 * RFKILL_STATE_HARD_BLOCKED implements either get_state() or
145 * rfkill_force_state(), so the cache either is bypassed or valid. 147 * rfkill_force_state(), so the cache either is bypassed or valid.
146 * 148 *
@@ -499,17 +501,15 @@ static struct class rfkill_class = {
499 501
500static int rfkill_add_switch(struct rfkill *rfkill) 502static int rfkill_add_switch(struct rfkill *rfkill)
501{ 503{
502 int error;
503
504 mutex_lock(&rfkill_mutex); 504 mutex_lock(&rfkill_mutex);
505 505
506 error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type], 0); 506 rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type], 0);
507 if (!error) 507
508 list_add_tail(&rfkill->node, &rfkill_list); 508 list_add_tail(&rfkill->node, &rfkill_list);
509 509
510 mutex_unlock(&rfkill_mutex); 510 mutex_unlock(&rfkill_mutex);
511 511
512 return error; 512 return 0;
513} 513}
514 514
515static void rfkill_remove_switch(struct rfkill *rfkill) 515static void rfkill_remove_switch(struct rfkill *rfkill)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index fb75f265b39c..b7fefffd2d0d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -199,12 +199,14 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
199 199
200 mutex_lock(&cfg80211_drv_mutex); 200 mutex_lock(&cfg80211_drv_mutex);
201 list_for_each_entry(dev, &cfg80211_drv_list, list) { 201 list_for_each_entry(dev, &cfg80211_drv_list, list) {
202 if (++idx < start) 202 if (++idx <= start)
203 continue; 203 continue;
204 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid, 204 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
205 cb->nlh->nlmsg_seq, NLM_F_MULTI, 205 cb->nlh->nlmsg_seq, NLM_F_MULTI,
206 dev) < 0) 206 dev) < 0) {
207 idx--;
207 break; 208 break;
209 }
208 } 210 }
209 mutex_unlock(&cfg80211_drv_mutex); 211 mutex_unlock(&cfg80211_drv_mutex);
210 212