aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-08-04 10:37:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-22 16:29:58 -0400
commit2bb057d07a0bc17475a7bf897fc41667ab08b73f (patch)
tree55461e52caa34a45a67aaf9e3f1c608f96c77d59 /drivers/net/wireless/rt2x00
parent8e7cdbb6333ef7654e708bd60e50a123688dcd7b (diff)
rt2x00: Implement HW encryption
Various rt2x00 devices support hardware encryption. Most of them require the IV/EIV to be generated by mac80211, but require it to be provided seperately instead of within the frame itself. This means that rt2x00lib should extract the data from the frame and place it in the frame descriptor. During RX the IV/EIV is provided in the descriptor by the hardware which means that it should be inserted into the frame by rt2x00lib. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig4
-rw-r--r--drivers/net/wireless/rt2x00/Makefile1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h39
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c215
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c97
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c30
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h47
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c110
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c81
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h73
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h19
11 files changed, 686 insertions, 30 deletions
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index d485a86bba75..2f60e175f039 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -33,6 +33,10 @@ config RT2X00_LIB_FIRMWARE
33 depends on RT2X00_LIB 33 depends on RT2X00_LIB
34 select FW_LOADER 34 select FW_LOADER
35 35
36config RT2X00_LIB_CRYPTO
37 boolean
38 depends on RT2X00_LIB
39
36config RT2X00_LIB_RFKILL 40config RT2X00_LIB_RFKILL
37 boolean 41 boolean
38 depends on RT2X00_LIB 42 depends on RT2X00_LIB
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index 1087dbcf1a04..917cb4f3b038 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -3,6 +3,7 @@ rt2x00lib-y += rt2x00mac.o
3rt2x00lib-y += rt2x00config.o 3rt2x00lib-y += rt2x00config.o
4rt2x00lib-y += rt2x00queue.o 4rt2x00lib-y += rt2x00queue.o
5rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o 5rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o
6rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
6rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o 7rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o
7rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o 8rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
8rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o 9rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 82c28dcc471d..0ffd972bb856 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -452,6 +452,23 @@ struct rt2x00lib_erp {
452}; 452};
453 453
454/* 454/*
455 * Configuration structure for hardware encryption.
456 */
457struct rt2x00lib_crypto {
458 enum cipher cipher;
459
460 enum set_key_cmd cmd;
461 const u8 *address;
462
463 u32 bssidx;
464 u32 aid;
465
466 u8 key[16];
467 u8 tx_mic[8];
468 u8 rx_mic[8];
469};
470
471/*
455 * Configuration structure wrapper around the 472 * Configuration structure wrapper around the
456 * rt2x00 interface configuration handler. 473 * rt2x00 interface configuration handler.
457 */ 474 */
@@ -547,6 +564,12 @@ struct rt2x00lib_ops {
547 /* 564 /*
548 * Configuration handlers. 565 * Configuration handlers.
549 */ 566 */
567 int (*config_shared_key) (struct rt2x00_dev *rt2x00dev,
568 struct rt2x00lib_crypto *crypto,
569 struct ieee80211_key_conf *key);
570 int (*config_pairwise_key) (struct rt2x00_dev *rt2x00dev,
571 struct rt2x00lib_crypto *crypto,
572 struct ieee80211_key_conf *key);
550 void (*config_filter) (struct rt2x00_dev *rt2x00dev, 573 void (*config_filter) (struct rt2x00_dev *rt2x00dev,
551 const unsigned int filter_flags); 574 const unsigned int filter_flags);
552 void (*config_intf) (struct rt2x00_dev *rt2x00dev, 575 void (*config_intf) (struct rt2x00_dev *rt2x00dev,
@@ -609,7 +632,7 @@ enum rt2x00_flags {
609 DEVICE_DIRTY_CONFIG, 632 DEVICE_DIRTY_CONFIG,
610 633
611 /* 634 /*
612 * Driver features 635 * Driver requirements
613 */ 636 */
614 DRIVER_REQUIRE_FIRMWARE, 637 DRIVER_REQUIRE_FIRMWARE,
615 DRIVER_REQUIRE_BEACON_GUARD, 638 DRIVER_REQUIRE_BEACON_GUARD,
@@ -618,9 +641,14 @@ enum rt2x00_flags {
618 DRIVER_REQUIRE_DMA, 641 DRIVER_REQUIRE_DMA,
619 642
620 /* 643 /*
621 * Driver configuration 644 * Driver features
622 */ 645 */
623 CONFIG_SUPPORT_HW_BUTTON, 646 CONFIG_SUPPORT_HW_BUTTON,
647 CONFIG_SUPPORT_HW_CRYPTO,
648
649 /*
650 * Driver configuration
651 */
624 CONFIG_FRAME_TYPE, 652 CONFIG_FRAME_TYPE,
625 CONFIG_RF_SEQUENCE, 653 CONFIG_RF_SEQUENCE,
626 CONFIG_EXTERNAL_LNA_A, 654 CONFIG_EXTERNAL_LNA_A,
@@ -966,6 +994,13 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
966 unsigned int changed_flags, 994 unsigned int changed_flags,
967 unsigned int *total_flags, 995 unsigned int *total_flags,
968 int mc_count, struct dev_addr_list *mc_list); 996 int mc_count, struct dev_addr_list *mc_list);
997#ifdef CONFIG_RT2X00_LIB_CRYPTO
998int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
999 const u8 *local_address, const u8 *address,
1000 struct ieee80211_key_conf *key);
1001#else
1002#define rt2x00mac_set_key NULL
1003#endif /* CONFIG_RT2X00_LIB_CRYPTO */
969int rt2x00mac_get_stats(struct ieee80211_hw *hw, 1004int rt2x00mac_get_stats(struct ieee80211_hw *hw,
970 struct ieee80211_low_level_stats *stats); 1005 struct ieee80211_low_level_stats *stats);
971int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, 1006int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
new file mode 100644
index 000000000000..e1448cfa9444
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -0,0 +1,215 @@
1/*
2 Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
3 <http://rt2x00.serialmonkey.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21/*
22 Module: rt2x00lib
23 Abstract: rt2x00 crypto specific routines.
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28
29#include "rt2x00.h"
30#include "rt2x00lib.h"
31
32enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key)
33{
34 switch (key->alg) {
35 case ALG_WEP:
36 if (key->keylen == LEN_WEP40)
37 return CIPHER_WEP64;
38 else
39 return CIPHER_WEP128;
40 case ALG_TKIP:
41 return CIPHER_TKIP;
42 case ALG_CCMP:
43 return CIPHER_AES;
44 default:
45 return CIPHER_NONE;
46 }
47}
48
49unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info)
50{
51 struct ieee80211_key_conf *key = tx_info->control.hw_key;
52 unsigned int overhead = 0;
53
54 /*
55 * Extend frame length to include IV/EIV/ICV/MMIC,
56 * note that these lengths should only be added when
57 * mac80211 does not generate it.
58 */
59 overhead += tx_info->control.icv_len;
60
61 if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
62 overhead += tx_info->control.iv_len;
63
64 if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
65 if (key->alg == ALG_TKIP)
66 overhead += 8;
67 }
68
69 return overhead;
70}
71
72void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len)
73{
74 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
75 unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
76
77 if (unlikely(!iv_len))
78 return;
79
80 /* Copy IV/EIV data */
81 if (iv_len >= 4)
82 memcpy(&skbdesc->iv, skb->data + header_length, 4);
83 if (iv_len >= 8)
84 memcpy(&skbdesc->eiv, skb->data + header_length + 4, 4);
85
86 /* Move ieee80211 header */
87 memmove(skb->data + iv_len, skb->data, header_length);
88
89 /* Pull buffer to correct size */
90 skb_pull(skb, iv_len);
91
92 /* IV/EIV data has officially be stripped */
93 skbdesc->flags |= FRAME_DESC_IV_STRIPPED;
94}
95
96void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
97{
98 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
99 unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
100 const unsigned int iv_len =
101 ((!!(skbdesc->iv)) * 4) + ((!!(skbdesc->eiv)) * 4);
102
103 if (!(skbdesc->flags & FRAME_DESC_IV_STRIPPED))
104 return;
105
106 skb_push(skb, iv_len);
107
108 /* Move ieee80211 header */
109 memmove(skb->data, skb->data + iv_len, header_length);
110
111 /* Copy IV/EIV data */
112 if (iv_len >= 4)
113 memcpy(skb->data + header_length, &skbdesc->iv, 4);
114 if (iv_len >= 8)
115 memcpy(skb->data + header_length + 4, &skbdesc->eiv, 4);
116
117 /* IV/EIV data has returned into the frame */
118 skbdesc->flags &= ~FRAME_DESC_IV_STRIPPED;
119}
120
121void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
122 unsigned int header_length,
123 struct rxdone_entry_desc *rxdesc)
124{
125 unsigned int payload_len = rxdesc->size - header_length;
126 unsigned int iv_len;
127 unsigned int icv_len;
128 unsigned int transfer = 0;
129
130 /*
131 * WEP64/WEP128: Provides IV & ICV
132 * TKIP: Provides IV/EIV & ICV
133 * AES: Provies IV/EIV & ICV
134 */
135 switch (rxdesc->cipher) {
136 case CIPHER_WEP64:
137 case CIPHER_WEP128:
138 iv_len = 4;
139 icv_len = 4;
140 break;
141 case CIPHER_TKIP:
142 iv_len = 8;
143 icv_len = 4;
144 break;
145 case CIPHER_AES:
146 iv_len = 8;
147 icv_len = 8;
148 break;
149 default:
150 /* Unsupport type */
151 return;
152 }
153
154 /*
155 * Make room for new data, note that we increase both
156 * headsize and tailsize when required. The tailsize is
157 * only needed when ICV data needs to be inserted and
158 * the padding is smaller then the ICV data.
159 * When alignment requirements is greater then the
160 * ICV data we must trim the skb to the correct size
161 * because we need to remove the extra bytes.
162 */
163 skb_push(skb, iv_len + align);
164 if (align < icv_len)
165 skb_put(skb, icv_len - align);
166 else if (align > icv_len)
167 skb_trim(skb, rxdesc->size + iv_len + icv_len);
168
169 /* Move ieee80211 header */
170 memmove(skb->data + transfer,
171 skb->data + transfer + iv_len + align,
172 header_length);
173 transfer += header_length;
174
175 /* Copy IV data */
176 if (iv_len >= 4) {
177 memcpy(skb->data + transfer, &rxdesc->iv, 4);
178 transfer += 4;
179 }
180
181 /* Copy EIV data */
182 if (iv_len >= 8) {
183 memcpy(skb->data + transfer, &rxdesc->eiv, 4);
184 transfer += 4;
185 }
186
187 /* Move payload */
188 if (align) {
189 memmove(skb->data + transfer,
190 skb->data + transfer + align,
191 payload_len);
192 }
193
194 /*
195 * NOTE: Always count the payload as transfered,
196 * even when alignment was set to zero. This is required
197 * for determining the correct offset for the ICV data.
198 */
199 transfer += payload_len;
200
201 /* Copy ICV data */
202 if (icv_len >= 4) {
203 memcpy(skb->data + transfer, &rxdesc->icv, 4);
204 /*
205 * AES appends 8 bytes, we can't fill the upper
206 * 4 bytes, but mac80211 doesn't care about what
207 * we provide here anyway and strips it immediately.
208 */
209 transfer += icv_len;
210 }
211
212 /* IV/EIV/ICV has been inserted into frame */
213 rxdesc->size = transfer;
214 rxdesc->flags &= ~RX_FLAG_IV_STRIPPED;
215}
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 6bee1d611bbf..5cf4c859e39d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -35,6 +35,13 @@
35 35
36#define MAX_LINE_LENGTH 64 36#define MAX_LINE_LENGTH 64
37 37
38struct rt2x00debug_crypto {
39 unsigned long success;
40 unsigned long icv_error;
41 unsigned long mic_error;
42 unsigned long key_error;
43};
44
38struct rt2x00debug_intf { 45struct rt2x00debug_intf {
39 /* 46 /*
40 * Pointer to driver structure where 47 * Pointer to driver structure where
@@ -63,6 +70,7 @@ struct rt2x00debug_intf {
63 * - queue folder 70 * - queue folder
64 * - frame dump file 71 * - frame dump file
65 * - queue stats file 72 * - queue stats file
73 * - crypto stats file
66 */ 74 */
67 struct dentry *driver_folder; 75 struct dentry *driver_folder;
68 struct dentry *driver_entry; 76 struct dentry *driver_entry;
@@ -80,6 +88,7 @@ struct rt2x00debug_intf {
80 struct dentry *queue_folder; 88 struct dentry *queue_folder;
81 struct dentry *queue_frame_dump_entry; 89 struct dentry *queue_frame_dump_entry;
82 struct dentry *queue_stats_entry; 90 struct dentry *queue_stats_entry;
91 struct dentry *crypto_stats_entry;
83 92
84 /* 93 /*
85 * The frame dump file only allows a single reader, 94 * The frame dump file only allows a single reader,
@@ -98,6 +107,12 @@ struct rt2x00debug_intf {
98 wait_queue_head_t frame_dump_waitqueue; 107 wait_queue_head_t frame_dump_waitqueue;
99 108
100 /* 109 /*
110 * HW crypto statistics.
111 * All statistics are stored seperately per cipher type.
112 */
113 struct rt2x00debug_crypto crypto_stats[CIPHER_MAX];
114
115 /*
101 * Driver and chipset files will use a data buffer 116 * Driver and chipset files will use a data buffer
102 * that has been created in advance. This will simplify 117 * that has been created in advance. This will simplify
103 * the code since we can use the debugfs functions. 118 * the code since we can use the debugfs functions.
@@ -114,6 +129,25 @@ struct rt2x00debug_intf {
114 unsigned int offset_rf; 129 unsigned int offset_rf;
115}; 130};
116 131
132void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
133 enum cipher cipher, enum rx_crypto status)
134{
135 struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
136
137 if (cipher == CIPHER_TKIP_NO_MIC)
138 cipher = CIPHER_TKIP;
139 if (cipher == CIPHER_NONE || cipher > CIPHER_MAX)
140 return;
141
142 /* Remove CIPHER_NONE index */
143 cipher--;
144
145 intf->crypto_stats[cipher].success += (status == RX_CRYPTO_SUCCESS);
146 intf->crypto_stats[cipher].icv_error += (status == RX_CRYPTO_FAIL_ICV);
147 intf->crypto_stats[cipher].mic_error += (status == RX_CRYPTO_FAIL_MIC);
148 intf->crypto_stats[cipher].key_error += (status == RX_CRYPTO_FAIL_KEY);
149}
150
117void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, 151void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
118 enum rt2x00_dump_type type, struct sk_buff *skb) 152 enum rt2x00_dump_type type, struct sk_buff *skb)
119{ 153{
@@ -327,6 +361,59 @@ static const struct file_operations rt2x00debug_fop_queue_stats = {
327 .release = rt2x00debug_file_release, 361 .release = rt2x00debug_file_release,
328}; 362};
329 363
364#ifdef CONFIG_RT2X00_LIB_CRYPTO
365static ssize_t rt2x00debug_read_crypto_stats(struct file *file,
366 char __user *buf,
367 size_t length,
368 loff_t *offset)
369{
370 struct rt2x00debug_intf *intf = file->private_data;
371 char *name[] = { "WEP64", "WEP128", "TKIP", "AES" };
372 char *data;
373 char *temp;
374 size_t size;
375 unsigned int i;
376
377 if (*offset)
378 return 0;
379
380 data = kzalloc((1 + CIPHER_MAX)* MAX_LINE_LENGTH, GFP_KERNEL);
381 if (!data)
382 return -ENOMEM;
383
384 temp = data;
385 temp += sprintf(data, "cipher\tsuccess\ticv err\tmic err\tkey err\n");
386
387 for (i = 0; i < CIPHER_MAX; i++) {
388 temp += sprintf(temp, "%s\t%lu\t%lu\t%lu\t%lu\n", name[i],
389 intf->crypto_stats[i].success,
390 intf->crypto_stats[i].icv_error,
391 intf->crypto_stats[i].mic_error,
392 intf->crypto_stats[i].key_error);
393 }
394
395 size = strlen(data);
396 size = min(size, length);
397
398 if (copy_to_user(buf, data, size)) {
399 kfree(data);
400 return -EFAULT;
401 }
402
403 kfree(data);
404
405 *offset += size;
406 return size;
407}
408
409static const struct file_operations rt2x00debug_fop_crypto_stats = {
410 .owner = THIS_MODULE,
411 .read = rt2x00debug_read_crypto_stats,
412 .open = rt2x00debug_file_open,
413 .release = rt2x00debug_file_release,
414};
415#endif
416
330#define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ 417#define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \
331static ssize_t rt2x00debug_read_##__name(struct file *file, \ 418static ssize_t rt2x00debug_read_##__name(struct file *file, \
332 char __user *buf, \ 419 char __user *buf, \
@@ -569,6 +656,13 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
569 debugfs_create_file("queue", S_IRUSR, intf->queue_folder, 656 debugfs_create_file("queue", S_IRUSR, intf->queue_folder,
570 intf, &rt2x00debug_fop_queue_stats); 657 intf, &rt2x00debug_fop_queue_stats);
571 658
659#ifdef CONFIG_RT2X00_LIB_CRYPTO
660 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
661 intf->crypto_stats_entry =
662 debugfs_create_file("crypto", S_IRUGO, intf->queue_folder,
663 intf, &rt2x00debug_fop_crypto_stats);
664#endif
665
572 return; 666 return;
573 667
574exit: 668exit:
@@ -587,6 +681,9 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
587 681
588 skb_queue_purge(&intf->frame_dump_skbqueue); 682 skb_queue_purge(&intf->frame_dump_skbqueue);
589 683
684#ifdef CONFIG_RT2X00_LIB_CRYPTO
685 debugfs_remove(intf->crypto_stats_entry);
686#endif
590 debugfs_remove(intf->queue_stats_entry); 687 debugfs_remove(intf->queue_stats_entry);
591 debugfs_remove(intf->queue_frame_dump_entry); 688 debugfs_remove(intf->queue_frame_dump_entry);
592 debugfs_remove(intf->queue_folder); 689 debugfs_remove(intf->queue_folder);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index f42283ad7b02..182952249a19 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -508,6 +508,15 @@ void rt2x00lib_txdone(struct queue_entry *entry,
508 rt2x00queue_unmap_skb(rt2x00dev, entry->skb); 508 rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
509 509
510 /* 510 /*
511 * If the IV/EIV data was stripped from the frame before it was
512 * passed to the hardware, we should now reinsert it again because
513 * mac80211 will expect the the same data to be present it the
514 * frame as it was passed to us.
515 */
516 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
517 rt2x00crypto_tx_insert_iv(entry->skb);
518
519 /*
511 * Send frame to debugfs immediately, after this call is completed 520 * Send frame to debugfs immediately, after this call is completed
512 * we are going to overwrite the skb->cb array. 521 * we are going to overwrite the skb->cb array.
513 */ 522 */
@@ -585,7 +594,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
585 struct ieee80211_supported_band *sband; 594 struct ieee80211_supported_band *sband;
586 struct ieee80211_hdr *hdr; 595 struct ieee80211_hdr *hdr;
587 const struct rt2x00_rate *rate; 596 const struct rt2x00_rate *rate;
588 unsigned int header_size; 597 unsigned int header_length;
589 unsigned int align; 598 unsigned int align;
590 unsigned int i; 599 unsigned int i;
591 int idx = -1; 600 int idx = -1;
@@ -613,10 +622,19 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
613 * The data behind the ieee80211 header must be 622 * The data behind the ieee80211 header must be
614 * aligned on a 4 byte boundary. 623 * aligned on a 4 byte boundary.
615 */ 624 */
616 header_size = ieee80211_get_hdrlen_from_skb(entry->skb); 625 header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
617 align = ((unsigned long)(entry->skb->data + header_size)) & 3; 626 align = ((unsigned long)(entry->skb->data + header_length)) & 3;
618 627
619 if (align) { 628 /*
629 * Hardware might have stripped the IV/EIV/ICV data,
630 * in that case it is possible that the data was
631 * provided seperately (through hardware descriptor)
632 * in which case we should reinsert the data into the frame.
633 */
634 if ((rxdesc.flags & RX_FLAG_IV_STRIPPED)) {
635 rt2x00crypto_rx_insert_iv(entry->skb, align,
636 header_length, &rxdesc);
637 } else if (align) {
620 skb_push(entry->skb, align); 638 skb_push(entry->skb, align);
621 /* Move entire frame in 1 command */ 639 /* Move entire frame in 1 command */
622 memmove(entry->skb->data, entry->skb->data + align, 640 memmove(entry->skb->data, entry->skb->data + align,
@@ -657,6 +675,10 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
657 (rxdesc.dev_flags & RXDONE_MY_BSS)) 675 (rxdesc.dev_flags & RXDONE_MY_BSS))
658 rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi); 676 rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi);
659 677
678 rt2x00debug_update_crypto(rt2x00dev,
679 rxdesc.cipher,
680 rxdesc.cipher_status);
681
660 rt2x00dev->link.qual.rx_success++; 682 rt2x00dev->link.qual.rx_success++;
661 683
662 rx_status->mactime = rxdesc.timestamp; 684 rx_status->mactime = rxdesc.timestamp;
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index c5fb3a72cf37..7bbc16b1b6c6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -181,6 +181,8 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev);
181void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev); 181void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev);
182void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, 182void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
183 enum rt2x00_dump_type type, struct sk_buff *skb); 183 enum rt2x00_dump_type type, struct sk_buff *skb);
184void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
185 enum cipher cipher, enum rx_crypto status);
184#else 186#else
185static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) 187static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
186{ 188{
@@ -195,9 +197,54 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
195 struct sk_buff *skb) 197 struct sk_buff *skb)
196{ 198{
197} 199}
200
201static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
202 enum cipher cipher,
203 enum rx_crypto status)
204{
205}
198#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 206#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
199 207
200/* 208/*
209 * Crypto handlers.
210 */
211#ifdef CONFIG_RT2X00_LIB_CRYPTO
212enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key);
213unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info);
214void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len);
215void rt2x00crypto_tx_insert_iv(struct sk_buff *skb);
216void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
217 unsigned int header_length,
218 struct rxdone_entry_desc *rxdesc);
219#else
220static inline enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key)
221{
222 return CIPHER_NONE;
223}
224
225static inline unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info)
226{
227 return 0;
228}
229
230static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
231 unsigned int iv_len)
232{
233}
234
235static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
236{
237}
238
239static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
240 unsigned int align,
241 unsigned int header_length,
242 struct rxdone_entry_desc *rxdesc)
243{
244}
245#endif
246
247/*
201 * RFkill handlers. 248 * RFkill handlers.
202 */ 249 */
203#ifdef CONFIG_RT2X00_LIB_RFKILL 250#ifdef CONFIG_RT2X00_LIB_RFKILL
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 4b9fde903cd6..3af427339417 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -36,22 +36,22 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
36 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb); 36 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb);
37 struct ieee80211_tx_info *rts_info; 37 struct ieee80211_tx_info *rts_info;
38 struct sk_buff *skb; 38 struct sk_buff *skb;
39 int size; 39 unsigned int data_length;
40 int retval = 0; 40 int retval = 0;
41 41
42 if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) 42 if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
43 size = sizeof(struct ieee80211_cts); 43 data_length = sizeof(struct ieee80211_cts);
44 else 44 else
45 size = sizeof(struct ieee80211_rts); 45 data_length = sizeof(struct ieee80211_rts);
46 46
47 skb = dev_alloc_skb(size + rt2x00dev->hw->extra_tx_headroom); 47 skb = dev_alloc_skb(data_length + rt2x00dev->hw->extra_tx_headroom);
48 if (unlikely(!skb)) { 48 if (unlikely(!skb)) {
49 WARNING(rt2x00dev, "Failed to create RTS/CTS frame.\n"); 49 WARNING(rt2x00dev, "Failed to create RTS/CTS frame.\n");
50 return -ENOMEM; 50 return -ENOMEM;
51 } 51 }
52 52
53 skb_reserve(skb, rt2x00dev->hw->extra_tx_headroom); 53 skb_reserve(skb, rt2x00dev->hw->extra_tx_headroom);
54 skb_put(skb, size); 54 skb_put(skb, data_length);
55 55
56 /* 56 /*
57 * Copy TX information over from original frame to 57 * Copy TX information over from original frame to
@@ -64,7 +64,6 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
64 */ 64 */
65 memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); 65 memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));
66 rts_info = IEEE80211_SKB_CB(skb); 66 rts_info = IEEE80211_SKB_CB(skb);
67 rts_info->control.hw_key = NULL;
68 rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS; 67 rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS;
69 rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT; 68 rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;
70 rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; 69 rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
@@ -74,13 +73,24 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
74 else 73 else
75 rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK; 74 rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
76 75
76 skb->do_not_encrypt = 1;
77
78 /*
79 * RTS/CTS frame should use the length of the frame plus any
80 * encryption overhead that will be added by the hardware.
81 */
82#ifdef CONFIG_RT2X00_LIB_CRYPTO
83 if (!frag_skb->do_not_encrypt)
84 data_length += rt2x00crypto_tx_overhead(tx_info);
85#endif /* CONFIG_RT2X00_LIB_CRYPTO */
86
77 if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) 87 if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
78 ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, 88 ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
79 frag_skb->data, size, tx_info, 89 frag_skb->data, data_length, tx_info,
80 (struct ieee80211_cts *)(skb->data)); 90 (struct ieee80211_cts *)(skb->data));
81 else 91 else
82 ieee80211_rts_get(rt2x00dev->hw, tx_info->control.vif, 92 ieee80211_rts_get(rt2x00dev->hw, tx_info->control.vif,
83 frag_skb->data, size, tx_info, 93 frag_skb->data, data_length, tx_info,
84 (struct ieee80211_rts *)(skb->data)); 94 (struct ieee80211_rts *)(skb->data));
85 95
86 retval = rt2x00queue_write_tx_frame(queue, skb); 96 retval = rt2x00queue_write_tx_frame(queue, skb);
@@ -464,6 +474,90 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
464} 474}
465EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); 475EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
466 476
477#ifdef CONFIG_RT2X00_LIB_CRYPTO
478int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
479 const u8 *local_address, const u8 *address,
480 struct ieee80211_key_conf *key)
481{
482 struct rt2x00_dev *rt2x00dev = hw->priv;
483 int (*set_key) (struct rt2x00_dev *rt2x00dev,
484 struct rt2x00lib_crypto *crypto,
485 struct ieee80211_key_conf *key);
486 struct rt2x00lib_crypto crypto;
487
488 if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
489 return -EOPNOTSUPP;
490 else if (key->keylen > 32)
491 return -ENOSPC;
492
493 memset(&crypto, 0, sizeof(crypto));
494
495 /*
496 * When in STA mode, bssidx is always 0 otherwise local_address[5]
497 * contains the bss number, see BSS_ID_MASK comments for details.
498 */
499 if (rt2x00dev->intf_sta_count)
500 crypto.bssidx = 0;
501 else
502 crypto.bssidx =
503 local_address[5] & (rt2x00dev->ops->max_ap_intf - 1);
504
505 crypto.cipher = rt2x00crypto_key_to_cipher(key);
506 if (crypto.cipher == CIPHER_NONE)
507 return -EOPNOTSUPP;
508
509 crypto.cmd = cmd;
510 crypto.address = address;
511
512 if (crypto.cipher == CIPHER_TKIP) {
513 if (key->keylen > NL80211_TKIP_DATA_OFFSET_ENCR_KEY)
514 memcpy(&crypto.key,
515 &key->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
516 sizeof(crypto.key));
517
518 if (key->keylen > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
519 memcpy(&crypto.tx_mic,
520 &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
521 sizeof(crypto.tx_mic));
522
523 if (key->keylen > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
524 memcpy(&crypto.rx_mic,
525 &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
526 sizeof(crypto.rx_mic));
527 } else
528 memcpy(&crypto.key, &key->key[0], key->keylen);
529
530 /*
531 * Each BSS has a maximum of 4 shared keys.
532 * Shared key index values:
533 * 0) BSS0 key0
534 * 1) BSS0 key1
535 * ...
536 * 4) BSS1 key0
537 * ...
538 * 8) BSS2 key0
539 * ...
540 * Both pairwise as shared key indeces are determined by
541 * driver. This is required because the hardware requires
542 * keys to be assigned in correct order (When key 1 is
543 * provided but key 0 is not, then the key is not found
544 * by the hardware during RX).
545 */
546 key->hw_key_idx = 0;
547
548 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
549 set_key = rt2x00dev->ops->lib->config_pairwise_key;
550 else
551 set_key = rt2x00dev->ops->lib->config_shared_key;
552
553 if (!set_key)
554 return -EOPNOTSUPP;
555
556 return set_key(rt2x00dev, &crypto, key);
557}
558EXPORT_SYMBOL_GPL(rt2x00mac_set_key);
559#endif /* CONFIG_RT2X00_LIB_CRYPTO */
560
467int rt2x00mac_get_stats(struct ieee80211_hw *hw, 561int rt2x00mac_get_stats(struct ieee80211_hw *hw,
468 struct ieee80211_low_level_stats *stats) 562 struct ieee80211_low_level_stats *stats)
469{ 563{
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 898cdd7f57d9..c0f97c53e5ce 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -33,10 +33,11 @@
33struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, 33struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
34 struct queue_entry *entry) 34 struct queue_entry *entry)
35{ 35{
36 unsigned int frame_size;
37 unsigned int reserved_size;
38 struct sk_buff *skb; 36 struct sk_buff *skb;
39 struct skb_frame_desc *skbdesc; 37 struct skb_frame_desc *skbdesc;
38 unsigned int frame_size;
39 unsigned int head_size = 0;
40 unsigned int tail_size = 0;
40 41
41 /* 42 /*
42 * The frame size includes descriptor size, because the 43 * The frame size includes descriptor size, because the
@@ -49,16 +50,32 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
49 * this means we need at least 3 bytes for moving the frame 50 * this means we need at least 3 bytes for moving the frame
50 * into the correct offset. 51 * into the correct offset.
51 */ 52 */
52 reserved_size = 4; 53 head_size = 4;
54
55 /*
56 * For IV/EIV/ICV assembly we must make sure there is
57 * at least 8 bytes bytes available in headroom for IV/EIV
58 * and 4 bytes for ICV data as tailroon.
59 */
60#ifdef CONFIG_RT2X00_LIB_CRYPTO
61 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
62 head_size += 8;
63 tail_size += 4;
64 }
65#endif /* CONFIG_RT2X00_LIB_CRYPTO */
53 66
54 /* 67 /*
55 * Allocate skbuffer. 68 * Allocate skbuffer.
56 */ 69 */
57 skb = dev_alloc_skb(frame_size + reserved_size); 70 skb = dev_alloc_skb(frame_size + head_size + tail_size);
58 if (!skb) 71 if (!skb)
59 return NULL; 72 return NULL;
60 73
61 skb_reserve(skb, reserved_size); 74 /*
75 * Make sure we not have a frame with the requested bytes
76 * available in the head and tail.
77 */
78 skb_reserve(skb, head_size);
62 skb_put(skb, frame_size); 79 skb_put(skb, frame_size);
63 80
64 /* 81 /*
@@ -140,7 +157,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
140 txdesc->cw_max = entry->queue->cw_max; 157 txdesc->cw_max = entry->queue->cw_max;
141 txdesc->aifs = entry->queue->aifs; 158 txdesc->aifs = entry->queue->aifs;
142 159
143 /* Data length should be extended with 4 bytes for CRC */ 160 /* Data length + CRC + IV/EIV/ICV/MMIC (when using encryption) */
144 data_length = entry->skb->len + 4; 161 data_length = entry->skb->len + 4;
145 162
146 /* 163 /*
@@ -149,6 +166,35 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
149 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) 166 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
150 __set_bit(ENTRY_TXD_ACK, &txdesc->flags); 167 __set_bit(ENTRY_TXD_ACK, &txdesc->flags);
151 168
169#ifdef CONFIG_RT2X00_LIB_CRYPTO
170 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) &&
171 !entry->skb->do_not_encrypt) {
172 struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
173
174 __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags);
175
176 txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key);
177
178 if (hw_key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
179 __set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags);
180
181 txdesc->key_idx = hw_key->hw_key_idx;
182 txdesc->iv_offset = ieee80211_get_hdrlen_from_skb(entry->skb);
183
184 /*
185 * Extend frame length to include all encryption overhead
186 * that will be added by the hardware.
187 */
188 data_length += rt2x00crypto_tx_overhead(tx_info);
189
190 if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
191 __set_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags);
192
193 if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC))
194 __set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags);
195 }
196#endif /* CONFIG_RT2X00_LIB_CRYPTO */
197
152 /* 198 /*
153 * Check if this is a RTS/CTS frame 199 * Check if this is a RTS/CTS frame
154 */ 200 */
@@ -305,6 +351,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
305 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); 351 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
306 struct txentry_desc txdesc; 352 struct txentry_desc txdesc;
307 struct skb_frame_desc *skbdesc; 353 struct skb_frame_desc *skbdesc;
354 unsigned int iv_len = IEEE80211_SKB_CB(skb)->control.iv_len;
308 355
309 if (unlikely(rt2x00queue_full(queue))) 356 if (unlikely(rt2x00queue_full(queue)))
310 return -EINVAL; 357 return -EINVAL;
@@ -326,15 +373,33 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
326 rt2x00queue_create_tx_descriptor(entry, &txdesc); 373 rt2x00queue_create_tx_descriptor(entry, &txdesc);
327 374
328 /* 375 /*
329 * skb->cb array is now ours and we are free to use it. 376 * All information is retreived from the skb->cb array,
377 * now we should claim ownership of the driver part of that
378 * array.
330 */ 379 */
331 skbdesc = get_skb_frame_desc(entry->skb); 380 skbdesc = get_skb_frame_desc(entry->skb);
332 memset(skbdesc, 0, sizeof(*skbdesc)); 381 memset(skbdesc, 0, sizeof(*skbdesc));
333 skbdesc->entry = entry; 382 skbdesc->entry = entry;
334 383
384 /*
385 * When hardware encryption is supported, and this frame
386 * is to be encrypted, we should strip the IV/EIV data from
387 * the frame so we can provide it to the driver seperately.
388 */
389 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
390 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags))
391 rt2x00crypto_tx_remove_iv(skb, iv_len);
392
393 /*
394 * It could be possible that the queue was corrupted and this
395 * call failed. Just drop the frame, we cannot rollback and pass
396 * the frame to mac80211 because the skb->cb has now been tainted.
397 */
335 if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) { 398 if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) {
336 __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 399 __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
337 return -EIO; 400 dev_kfree_skb_any(entry->skb);
401 entry->skb = NULL;
402 return 0;
338 } 403 }
339 404
340 if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags)) 405 if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index ff78e52ce43c..37f3f98d58a2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -87,10 +87,13 @@ enum data_queue_qid {
87 * 87 *
88 * @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX 88 * @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX
89 * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX 89 * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX
90 * @FRAME_DESC_IV_STRIPPED: Frame contained a IV/EIV provided by
91 * mac80211 but was stripped for processing by the driver.
90 */ 92 */
91enum skb_frame_desc_flags { 93enum skb_frame_desc_flags {
92 SKBDESC_DMA_MAPPED_RX = (1 << 0), 94 SKBDESC_DMA_MAPPED_RX = 1 << 0,
93 SKBDESC_DMA_MAPPED_TX = (1 << 1), 95 SKBDESC_DMA_MAPPED_TX = 1 << 1,
96 FRAME_DESC_IV_STRIPPED = 1 << 2,
94}; 97};
95 98
96/** 99/**
@@ -104,6 +107,8 @@ enum skb_frame_desc_flags {
104 * @desc: Pointer to descriptor part of the frame. 107 * @desc: Pointer to descriptor part of the frame.
105 * Note that this pointer could point to something outside 108 * Note that this pointer could point to something outside
106 * of the scope of the skb->data pointer. 109 * of the scope of the skb->data pointer.
110 * @iv: IV data used during encryption/decryption.
111 * @eiv: EIV data used during encryption/decryption.
107 * @skb_dma: (PCI-only) the DMA address associated with the sk buffer. 112 * @skb_dma: (PCI-only) the DMA address associated with the sk buffer.
108 * @entry: The entry to which this sk buffer belongs. 113 * @entry: The entry to which this sk buffer belongs.
109 */ 114 */
@@ -113,6 +118,9 @@ struct skb_frame_desc {
113 unsigned int desc_len; 118 unsigned int desc_len;
114 void *desc; 119 void *desc;
115 120
121 __le32 iv;
122 __le32 eiv;
123
116 dma_addr_t skb_dma; 124 dma_addr_t skb_dma;
117 125
118 struct queue_entry *entry; 126 struct queue_entry *entry;
@@ -152,7 +160,11 @@ enum rxdone_entry_desc_flags {
152 * @size: Data size of the received frame. 160 * @size: Data size of the received frame.
153 * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). 161 * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags).
154 * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). 162 * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags).
155 163 * @cipher: Cipher type used during decryption.
164 * @cipher_status: Decryption status.
165 * @iv: IV data used during decryption.
166 * @eiv: EIV data used during decryption.
167 * @icv: ICV data used during decryption.
156 */ 168 */
157struct rxdone_entry_desc { 169struct rxdone_entry_desc {
158 u64 timestamp; 170 u64 timestamp;
@@ -161,6 +173,12 @@ struct rxdone_entry_desc {
161 int size; 173 int size;
162 int flags; 174 int flags;
163 int dev_flags; 175 int dev_flags;
176 u8 cipher;
177 u8 cipher_status;
178
179 __le32 iv;
180 __le32 eiv;
181 __le32 icv;
164}; 182};
165 183
166/** 184/**
@@ -206,6 +224,10 @@ struct txdone_entry_desc {
206 * @ENTRY_TXD_BURST: This frame belongs to the same burst event. 224 * @ENTRY_TXD_BURST: This frame belongs to the same burst event.
207 * @ENTRY_TXD_ACK: An ACK is required for this frame. 225 * @ENTRY_TXD_ACK: An ACK is required for this frame.
208 * @ENTRY_TXD_RETRY_MODE: When set, the long retry count is used. 226 * @ENTRY_TXD_RETRY_MODE: When set, the long retry count is used.
227 * @ENTRY_TXD_ENCRYPT: This frame should be encrypted.
228 * @ENTRY_TXD_ENCRYPT_PAIRWISE: Use pairwise key table (instead of shared).
229 * @ENTRY_TXD_ENCRYPT_IV: Generate IV/EIV in hardware.
230 * @ENTRY_TXD_ENCRYPT_MMIC: Generate MIC in hardware.
209 */ 231 */
210enum txentry_desc_flags { 232enum txentry_desc_flags {
211 ENTRY_TXD_RTS_FRAME, 233 ENTRY_TXD_RTS_FRAME,
@@ -218,6 +240,10 @@ enum txentry_desc_flags {
218 ENTRY_TXD_BURST, 240 ENTRY_TXD_BURST,
219 ENTRY_TXD_ACK, 241 ENTRY_TXD_ACK,
220 ENTRY_TXD_RETRY_MODE, 242 ENTRY_TXD_RETRY_MODE,
243 ENTRY_TXD_ENCRYPT,
244 ENTRY_TXD_ENCRYPT_PAIRWISE,
245 ENTRY_TXD_ENCRYPT_IV,
246 ENTRY_TXD_ENCRYPT_MMIC,
221}; 247};
222 248
223/** 249/**
@@ -236,6 +262,9 @@ enum txentry_desc_flags {
236 * @ifs: IFS value. 262 * @ifs: IFS value.
237 * @cw_min: cwmin value. 263 * @cw_min: cwmin value.
238 * @cw_max: cwmax value. 264 * @cw_max: cwmax value.
265 * @cipher: Cipher type used for encryption.
266 * @key_idx: Key index used for encryption.
267 * @iv_offset: Position where IV should be inserted by hardware.
239 */ 268 */
240struct txentry_desc { 269struct txentry_desc {
241 unsigned long flags; 270 unsigned long flags;
@@ -252,6 +281,10 @@ struct txentry_desc {
252 short ifs; 281 short ifs;
253 short cw_min; 282 short cw_min;
254 short cw_max; 283 short cw_max;
284
285 enum cipher cipher;
286 u16 key_idx;
287 u16 iv_offset;
255}; 288};
256 289
257/** 290/**
@@ -484,25 +517,51 @@ static inline int rt2x00queue_threshold(struct data_queue *queue)
484} 517}
485 518
486/** 519/**
487 * rt2x00_desc_read - Read a word from the hardware descriptor. 520 * _rt2x00_desc_read - Read a word from the hardware descriptor.
521 * @desc: Base descriptor address
522 * @word: Word index from where the descriptor should be read.
523 * @value: Address where the descriptor value should be written into.
524 */
525static inline void _rt2x00_desc_read(__le32 *desc, const u8 word, __le32 *value)
526{
527 *value = desc[word];
528}
529
530/**
531 * rt2x00_desc_read - Read a word from the hardware descriptor, this
532 * function will take care of the byte ordering.
488 * @desc: Base descriptor address 533 * @desc: Base descriptor address
489 * @word: Word index from where the descriptor should be read. 534 * @word: Word index from where the descriptor should be read.
490 * @value: Address where the descriptor value should be written into. 535 * @value: Address where the descriptor value should be written into.
491 */ 536 */
492static inline void rt2x00_desc_read(__le32 *desc, const u8 word, u32 *value) 537static inline void rt2x00_desc_read(__le32 *desc, const u8 word, u32 *value)
493{ 538{
494 *value = le32_to_cpu(desc[word]); 539 __le32 tmp;
540 _rt2x00_desc_read(desc, word, &tmp);
541 *value = le32_to_cpu(tmp);
542}
543
544/**
545 * rt2x00_desc_write - write a word to the hardware descriptor, this
546 * function will take care of the byte ordering.
547 * @desc: Base descriptor address
548 * @word: Word index from where the descriptor should be written.
549 * @value: Value that should be written into the descriptor.
550 */
551static inline void _rt2x00_desc_write(__le32 *desc, const u8 word, __le32 value)
552{
553 desc[word] = value;
495} 554}
496 555
497/** 556/**
498 * rt2x00_desc_write - wrote a word to the hardware descriptor. 557 * rt2x00_desc_write - write a word to the hardware descriptor.
499 * @desc: Base descriptor address 558 * @desc: Base descriptor address
500 * @word: Word index from where the descriptor should be written. 559 * @word: Word index from where the descriptor should be written.
501 * @value: Value that should be written into the descriptor. 560 * @value: Value that should be written into the descriptor.
502 */ 561 */
503static inline void rt2x00_desc_write(__le32 *desc, const u8 word, u32 value) 562static inline void rt2x00_desc_write(__le32 *desc, const u8 word, u32 value)
504{ 563{
505 desc[word] = cpu_to_le32(value); 564 _rt2x00_desc_write(desc, word, cpu_to_le32(value));
506} 565}
507 566
508#endif /* RT2X00QUEUE_H */ 567#endif /* RT2X00QUEUE_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index 7e88ce5651b9..6d5acf99a1c5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -27,6 +27,16 @@
27#define RT2X00REG_H 27#define RT2X00REG_H
28 28
29/* 29/*
30 * RX crypto status
31 */
32enum rx_crypto {
33 RX_CRYPTO_SUCCESS = 0,
34 RX_CRYPTO_FAIL_ICV = 1,
35 RX_CRYPTO_FAIL_MIC = 2,
36 RX_CRYPTO_FAIL_KEY = 3,
37};
38
39/*
30 * Antenna values 40 * Antenna values
31 */ 41 */
32enum antenna { 42enum antenna {
@@ -104,7 +114,14 @@ enum cipher {
104 */ 114 */
105 CIPHER_CKIP64 = 5, 115 CIPHER_CKIP64 = 5,
106 CIPHER_CKIP128 = 6, 116 CIPHER_CKIP128 = 6,
107 CIPHER_TKIP_NO_MIC = 7, 117 CIPHER_TKIP_NO_MIC = 7, /* Don't send to device */
118
119/*
120 * Max cipher type.
121 * Note that CIPHER_NONE isn't counted, and CKIP64 and CKIP128
122 * are excluded due to limitations in mac80211.
123 */
124 CIPHER_MAX = 4,
108}; 125};
109 126
110/* 127/*