aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00debug.c
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/rt2x00debug.c
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/rt2x00debug.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c97
1 files changed, 97 insertions, 0 deletions
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);