cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rt2x00debug.c (19286B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
      4	<http://rt2x00.serialmonkey.com>
      5
      6 */
      7
      8/*
      9	Module: rt2x00lib
     10	Abstract: rt2x00 debugfs specific routines.
     11 */
     12
     13#include <linux/debugfs.h>
     14#include <linux/kernel.h>
     15#include <linux/module.h>
     16#include <linux/poll.h>
     17#include <linux/sched.h>
     18#include <linux/slab.h>
     19#include <linux/uaccess.h>
     20
     21#include "rt2x00.h"
     22#include "rt2x00lib.h"
     23#include "rt2x00dump.h"
     24
     25#define MAX_LINE_LENGTH 64
     26
     27struct rt2x00debug_crypto {
     28	unsigned long success;
     29	unsigned long icv_error;
     30	unsigned long mic_error;
     31	unsigned long key_error;
     32};
     33
     34struct rt2x00debug_intf {
     35	/*
     36	 * Pointer to driver structure where
     37	 * this debugfs entry belongs to.
     38	 */
     39	struct rt2x00_dev *rt2x00dev;
     40
     41	/*
     42	 * Reference to the rt2x00debug structure
     43	 * which can be used to communicate with
     44	 * the registers.
     45	 */
     46	const struct rt2x00debug *debug;
     47
     48	/*
     49	 * Debugfs entries for:
     50	 * - driver folder
     51	 *   - driver file
     52	 *   - chipset file
     53	 *   - device state flags file
     54	 *   - device capability flags file
     55	 *   - hardware restart file
     56	 *   - register folder
     57	 *     - csr offset/value files
     58	 *     - eeprom offset/value files
     59	 *     - bbp offset/value files
     60	 *     - rf offset/value files
     61	 *     - rfcsr offset/value files
     62	 *   - queue folder
     63	 *     - frame dump file
     64	 *     - queue stats file
     65	 *     - crypto stats file
     66	 */
     67	struct dentry *driver_folder;
     68
     69	/*
     70	 * The frame dump file only allows a single reader,
     71	 * so we need to store the current state here.
     72	 */
     73	unsigned long frame_dump_flags;
     74#define FRAME_DUMP_FILE_OPEN	1
     75
     76	/*
     77	 * We queue each frame before dumping it to the user,
     78	 * per read command we will pass a single skb structure
     79	 * so we should be prepared to queue multiple sk buffers
     80	 * before sending it to userspace.
     81	 */
     82	struct sk_buff_head frame_dump_skbqueue;
     83	wait_queue_head_t frame_dump_waitqueue;
     84
     85	/*
     86	 * HW crypto statistics.
     87	 * All statistics are stored separately per cipher type.
     88	 */
     89	struct rt2x00debug_crypto crypto_stats[CIPHER_MAX];
     90
     91	/*
     92	 * Driver and chipset files will use a data buffer
     93	 * that has been created in advance. This will simplify
     94	 * the code since we can use the debugfs functions.
     95	 */
     96	struct debugfs_blob_wrapper driver_blob;
     97	struct debugfs_blob_wrapper chipset_blob;
     98
     99	/*
    100	 * Requested offset for each register type.
    101	 */
    102	unsigned int offset_csr;
    103	unsigned int offset_eeprom;
    104	unsigned int offset_bbp;
    105	unsigned int offset_rf;
    106	unsigned int offset_rfcsr;
    107};
    108
    109void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
    110			       struct rxdone_entry_desc *rxdesc)
    111{
    112	struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
    113	enum cipher cipher = rxdesc->cipher;
    114	enum rx_crypto status = rxdesc->cipher_status;
    115
    116	if (cipher == CIPHER_TKIP_NO_MIC)
    117		cipher = CIPHER_TKIP;
    118	if (cipher == CIPHER_NONE || cipher >= CIPHER_MAX)
    119		return;
    120
    121	/* Remove CIPHER_NONE index */
    122	cipher--;
    123
    124	intf->crypto_stats[cipher].success += (status == RX_CRYPTO_SUCCESS);
    125	intf->crypto_stats[cipher].icv_error += (status == RX_CRYPTO_FAIL_ICV);
    126	intf->crypto_stats[cipher].mic_error += (status == RX_CRYPTO_FAIL_MIC);
    127	intf->crypto_stats[cipher].key_error += (status == RX_CRYPTO_FAIL_KEY);
    128}
    129
    130void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
    131			    enum rt2x00_dump_type type, struct queue_entry *entry)
    132{
    133	struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
    134	struct sk_buff *skb = entry->skb;
    135	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
    136	struct sk_buff *skbcopy;
    137	struct rt2x00dump_hdr *dump_hdr;
    138	struct timespec64 timestamp;
    139	u32 data_len;
    140
    141	if (likely(!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)))
    142		return;
    143
    144	ktime_get_ts64(&timestamp);
    145
    146	if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) {
    147		rt2x00_dbg(rt2x00dev, "txrx dump queue length exceeded\n");
    148		return;
    149	}
    150
    151	data_len = skb->len;
    152	if (skbdesc->flags & SKBDESC_DESC_IN_SKB)
    153		data_len -= skbdesc->desc_len;
    154
    155	skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + data_len,
    156			    GFP_ATOMIC);
    157	if (!skbcopy) {
    158		rt2x00_dbg(rt2x00dev, "Failed to copy skb for dump\n");
    159		return;
    160	}
    161
    162	dump_hdr = skb_put(skbcopy, sizeof(*dump_hdr));
    163	dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION);
    164	dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr));
    165	dump_hdr->desc_length = cpu_to_le32(skbdesc->desc_len);
    166	dump_hdr->data_length = cpu_to_le32(data_len);
    167	dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
    168	dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
    169	dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev);
    170	dump_hdr->type = cpu_to_le16(type);
    171	dump_hdr->queue_index = entry->queue->qid;
    172	dump_hdr->entry_index = entry->entry_idx;
    173	dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
    174	dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_nsec /
    175					       NSEC_PER_USEC);
    176
    177	if (!(skbdesc->flags & SKBDESC_DESC_IN_SKB))
    178		skb_put_data(skbcopy, skbdesc->desc, skbdesc->desc_len);
    179	skb_put_data(skbcopy, skb->data, skb->len);
    180
    181	skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy);
    182	wake_up_interruptible(&intf->frame_dump_waitqueue);
    183
    184	/*
    185	 * Verify that the file has not been closed while we were working.
    186	 */
    187	if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
    188		skb_queue_purge(&intf->frame_dump_skbqueue);
    189}
    190EXPORT_SYMBOL_GPL(rt2x00debug_dump_frame);
    191
    192static int rt2x00debug_file_open(struct inode *inode, struct file *file)
    193{
    194	struct rt2x00debug_intf *intf = inode->i_private;
    195
    196	file->private_data = inode->i_private;
    197
    198	if (!try_module_get(intf->debug->owner))
    199		return -EBUSY;
    200
    201	return 0;
    202}
    203
    204static int rt2x00debug_file_release(struct inode *inode, struct file *file)
    205{
    206	struct rt2x00debug_intf *intf = file->private_data;
    207
    208	module_put(intf->debug->owner);
    209
    210	return 0;
    211}
    212
    213static int rt2x00debug_open_queue_dump(struct inode *inode, struct file *file)
    214{
    215	struct rt2x00debug_intf *intf = inode->i_private;
    216	int retval;
    217
    218	retval = rt2x00debug_file_open(inode, file);
    219	if (retval)
    220		return retval;
    221
    222	if (test_and_set_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) {
    223		rt2x00debug_file_release(inode, file);
    224		return -EBUSY;
    225	}
    226
    227	return 0;
    228}
    229
    230static int rt2x00debug_release_queue_dump(struct inode *inode, struct file *file)
    231{
    232	struct rt2x00debug_intf *intf = inode->i_private;
    233
    234	skb_queue_purge(&intf->frame_dump_skbqueue);
    235
    236	clear_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags);
    237
    238	return rt2x00debug_file_release(inode, file);
    239}
    240
    241static ssize_t rt2x00debug_read_queue_dump(struct file *file,
    242					   char __user *buf,
    243					   size_t length,
    244					   loff_t *offset)
    245{
    246	struct rt2x00debug_intf *intf = file->private_data;
    247	struct sk_buff *skb;
    248	size_t status;
    249	int retval;
    250
    251	if (file->f_flags & O_NONBLOCK)
    252		return -EAGAIN;
    253
    254	retval =
    255	    wait_event_interruptible(intf->frame_dump_waitqueue,
    256				     (skb =
    257				     skb_dequeue(&intf->frame_dump_skbqueue)));
    258	if (retval)
    259		return retval;
    260
    261	status = min_t(size_t, skb->len, length);
    262	if (copy_to_user(buf, skb->data, status)) {
    263		status = -EFAULT;
    264		goto exit;
    265	}
    266
    267	*offset += status;
    268
    269exit:
    270	kfree_skb(skb);
    271
    272	return status;
    273}
    274
    275static __poll_t rt2x00debug_poll_queue_dump(struct file *file,
    276						poll_table *wait)
    277{
    278	struct rt2x00debug_intf *intf = file->private_data;
    279
    280	poll_wait(file, &intf->frame_dump_waitqueue, wait);
    281
    282	if (!skb_queue_empty(&intf->frame_dump_skbqueue))
    283		return EPOLLOUT | EPOLLWRNORM;
    284
    285	return 0;
    286}
    287
    288static const struct file_operations rt2x00debug_fop_queue_dump = {
    289	.owner		= THIS_MODULE,
    290	.read		= rt2x00debug_read_queue_dump,
    291	.poll		= rt2x00debug_poll_queue_dump,
    292	.open		= rt2x00debug_open_queue_dump,
    293	.release	= rt2x00debug_release_queue_dump,
    294	.llseek		= default_llseek,
    295};
    296
    297static ssize_t rt2x00debug_read_queue_stats(struct file *file,
    298					    char __user *buf,
    299					    size_t length,
    300					    loff_t *offset)
    301{
    302	struct rt2x00debug_intf *intf = file->private_data;
    303	struct data_queue *queue;
    304	unsigned long irqflags;
    305	unsigned int lines = 1 + intf->rt2x00dev->data_queues;
    306	size_t size;
    307	char *data;
    308	char *temp;
    309
    310	if (*offset)
    311		return 0;
    312
    313	data = kcalloc(lines, MAX_LINE_LENGTH, GFP_KERNEL);
    314	if (!data)
    315		return -ENOMEM;
    316
    317	temp = data +
    318	    sprintf(data, "qid\tflags\t\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
    319
    320	queue_for_each(intf->rt2x00dev, queue) {
    321		spin_lock_irqsave(&queue->index_lock, irqflags);
    322
    323		temp += sprintf(temp, "%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n",
    324				queue->qid, (unsigned int)queue->flags,
    325				queue->count, queue->limit, queue->length,
    326				queue->index[Q_INDEX],
    327				queue->index[Q_INDEX_DMA_DONE],
    328				queue->index[Q_INDEX_DONE]);
    329
    330		spin_unlock_irqrestore(&queue->index_lock, irqflags);
    331	}
    332
    333	size = strlen(data);
    334	size = min(size, length);
    335
    336	if (copy_to_user(buf, data, size)) {
    337		kfree(data);
    338		return -EFAULT;
    339	}
    340
    341	kfree(data);
    342
    343	*offset += size;
    344	return size;
    345}
    346
    347static const struct file_operations rt2x00debug_fop_queue_stats = {
    348	.owner		= THIS_MODULE,
    349	.read		= rt2x00debug_read_queue_stats,
    350	.open		= rt2x00debug_file_open,
    351	.release	= rt2x00debug_file_release,
    352	.llseek		= default_llseek,
    353};
    354
    355#ifdef CONFIG_RT2X00_LIB_CRYPTO
    356static ssize_t rt2x00debug_read_crypto_stats(struct file *file,
    357					     char __user *buf,
    358					     size_t length,
    359					     loff_t *offset)
    360{
    361	struct rt2x00debug_intf *intf = file->private_data;
    362	static const char * const name[] = { "WEP64", "WEP128", "TKIP", "AES" };
    363	char *data;
    364	char *temp;
    365	size_t size;
    366	unsigned int i;
    367
    368	if (*offset)
    369		return 0;
    370
    371	data = kcalloc(1 + CIPHER_MAX, MAX_LINE_LENGTH, GFP_KERNEL);
    372	if (!data)
    373		return -ENOMEM;
    374
    375	temp = data;
    376	temp += sprintf(data, "cipher\tsuccess\ticv err\tmic err\tkey err\n");
    377
    378	for (i = 0; i < CIPHER_MAX; i++) {
    379		temp += sprintf(temp, "%s\t%lu\t%lu\t%lu\t%lu\n", name[i],
    380				intf->crypto_stats[i].success,
    381				intf->crypto_stats[i].icv_error,
    382				intf->crypto_stats[i].mic_error,
    383				intf->crypto_stats[i].key_error);
    384	}
    385
    386	size = strlen(data);
    387	size = min(size, length);
    388
    389	if (copy_to_user(buf, data, size)) {
    390		kfree(data);
    391		return -EFAULT;
    392	}
    393
    394	kfree(data);
    395
    396	*offset += size;
    397	return size;
    398}
    399
    400static const struct file_operations rt2x00debug_fop_crypto_stats = {
    401	.owner		= THIS_MODULE,
    402	.read		= rt2x00debug_read_crypto_stats,
    403	.open		= rt2x00debug_file_open,
    404	.release	= rt2x00debug_file_release,
    405	.llseek		= default_llseek,
    406};
    407#endif
    408
    409#define RT2X00DEBUGFS_OPS_READ(__name, __format, __type)	\
    410static ssize_t rt2x00debug_read_##__name(struct file *file,	\
    411					 char __user *buf,	\
    412					 size_t length,		\
    413					 loff_t *offset)	\
    414{								\
    415	struct rt2x00debug_intf *intf = file->private_data;	\
    416	const struct rt2x00debug *debug = intf->debug;		\
    417	char line[16];						\
    418	size_t size;						\
    419	unsigned int index = intf->offset_##__name;		\
    420	__type value;						\
    421								\
    422	if (*offset)						\
    423		return 0;					\
    424								\
    425	if (index >= debug->__name.word_count)			\
    426		return -EINVAL;					\
    427								\
    428	index += (debug->__name.word_base /			\
    429		  debug->__name.word_size);			\
    430								\
    431	if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)		\
    432		index *= debug->__name.word_size;		\
    433								\
    434	value = debug->__name.read(intf->rt2x00dev, index);	\
    435								\
    436	size = sprintf(line, __format, value);			\
    437								\
    438	return simple_read_from_buffer(buf, length, offset, line, size); \
    439}
    440
    441#define RT2X00DEBUGFS_OPS_WRITE(__name, __type)			\
    442static ssize_t rt2x00debug_write_##__name(struct file *file,	\
    443					  const char __user *buf,\
    444					  size_t length,	\
    445					  loff_t *offset)	\
    446{								\
    447	struct rt2x00debug_intf *intf = file->private_data;	\
    448	const struct rt2x00debug *debug = intf->debug;		\
    449	char line[17];						\
    450	size_t size;						\
    451	unsigned int index = intf->offset_##__name;		\
    452	__type value;						\
    453								\
    454	if (*offset)						\
    455		return 0;					\
    456								\
    457	if (index >= debug->__name.word_count)			\
    458		return -EINVAL;					\
    459								\
    460	if (length > sizeof(line))				\
    461		return -EINVAL;					\
    462								\
    463	if (copy_from_user(line, buf, length))			\
    464		return -EFAULT;					\
    465	line[16] = 0;						\
    466						\
    467	size = strlen(line);					\
    468	value = simple_strtoul(line, NULL, 0);			\
    469								\
    470	index += (debug->__name.word_base /			\
    471		  debug->__name.word_size);			\
    472								\
    473	if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)		\
    474		index *= debug->__name.word_size;		\
    475								\
    476	debug->__name.write(intf->rt2x00dev, index, value);	\
    477								\
    478	*offset += size;					\
    479	return size;						\
    480}
    481
    482#define RT2X00DEBUGFS_OPS(__name, __format, __type)		\
    483RT2X00DEBUGFS_OPS_READ(__name, __format, __type);		\
    484RT2X00DEBUGFS_OPS_WRITE(__name, __type);			\
    485								\
    486static const struct file_operations rt2x00debug_fop_##__name = {\
    487	.owner		= THIS_MODULE,				\
    488	.read		= rt2x00debug_read_##__name,		\
    489	.write		= rt2x00debug_write_##__name,		\
    490	.open		= rt2x00debug_file_open,		\
    491	.release	= rt2x00debug_file_release,		\
    492	.llseek		= generic_file_llseek,			\
    493};
    494
    495RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32);
    496RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16);
    497RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8);
    498RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32);
    499RT2X00DEBUGFS_OPS(rfcsr, "0x%.2x\n", u8);
    500
    501static ssize_t rt2x00debug_read_dev_flags(struct file *file,
    502					  char __user *buf,
    503					  size_t length,
    504					  loff_t *offset)
    505{
    506	struct rt2x00debug_intf *intf =	file->private_data;
    507	char line[16];
    508	size_t size;
    509
    510	if (*offset)
    511		return 0;
    512
    513	size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags);
    514
    515	return simple_read_from_buffer(buf, length, offset, line, size);
    516}
    517
    518static const struct file_operations rt2x00debug_fop_dev_flags = {
    519	.owner		= THIS_MODULE,
    520	.read		= rt2x00debug_read_dev_flags,
    521	.open		= rt2x00debug_file_open,
    522	.release	= rt2x00debug_file_release,
    523	.llseek		= default_llseek,
    524};
    525
    526static ssize_t rt2x00debug_read_cap_flags(struct file *file,
    527					  char __user *buf,
    528					  size_t length,
    529					  loff_t *offset)
    530{
    531	struct rt2x00debug_intf *intf =	file->private_data;
    532	char line[16];
    533	size_t size;
    534
    535	if (*offset)
    536		return 0;
    537
    538	size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags);
    539
    540	return simple_read_from_buffer(buf, length, offset, line, size);
    541}
    542
    543static const struct file_operations rt2x00debug_fop_cap_flags = {
    544	.owner		= THIS_MODULE,
    545	.read		= rt2x00debug_read_cap_flags,
    546	.open		= rt2x00debug_file_open,
    547	.release	= rt2x00debug_file_release,
    548	.llseek		= default_llseek,
    549};
    550
    551static ssize_t rt2x00debug_write_restart_hw(struct file *file,
    552					    const char __user *buf,
    553					    size_t length,
    554					    loff_t *offset)
    555{
    556	struct rt2x00debug_intf *intf =	file->private_data;
    557	struct rt2x00_dev *rt2x00dev = intf->rt2x00dev;
    558	static unsigned long last_reset = INITIAL_JIFFIES;
    559
    560	if (!rt2x00_has_cap_restart_hw(rt2x00dev))
    561		return -EOPNOTSUPP;
    562
    563	if (time_before(jiffies, last_reset + msecs_to_jiffies(2000)))
    564		return -EBUSY;
    565
    566	last_reset = jiffies;
    567
    568	ieee80211_restart_hw(rt2x00dev->hw);
    569	return length;
    570}
    571
    572static const struct file_operations rt2x00debug_restart_hw = {
    573	.owner = THIS_MODULE,
    574	.write = rt2x00debug_write_restart_hw,
    575	.open = simple_open,
    576	.llseek = generic_file_llseek,
    577};
    578
    579static void rt2x00debug_create_file_driver(const char *name,
    580					   struct rt2x00debug_intf *intf,
    581					   struct debugfs_blob_wrapper *blob)
    582{
    583	char *data;
    584
    585	data = kzalloc(3 * MAX_LINE_LENGTH, GFP_KERNEL);
    586	if (!data)
    587		return;
    588
    589	blob->data = data;
    590	data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
    591	data += sprintf(data, "version:\t%s\n", DRV_VERSION);
    592	blob->size = strlen(blob->data);
    593
    594	debugfs_create_blob(name, 0400, intf->driver_folder, blob);
    595}
    596
    597static void rt2x00debug_create_file_chipset(const char *name,
    598					    struct rt2x00debug_intf *intf,
    599					    struct debugfs_blob_wrapper *blob)
    600{
    601	const struct rt2x00debug *debug = intf->debug;
    602	char *data;
    603
    604	data = kzalloc(9 * MAX_LINE_LENGTH, GFP_KERNEL);
    605	if (!data)
    606		return;
    607
    608	blob->data = data;
    609	data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt);
    610	data += sprintf(data, "rf chip:\t%04x\n", intf->rt2x00dev->chip.rf);
    611	data += sprintf(data, "revision:\t%04x\n", intf->rt2x00dev->chip.rev);
    612	data += sprintf(data, "\n");
    613	data += sprintf(data, "register\tbase\twords\twordsize\n");
    614#define RT2X00DEBUGFS_SPRINTF_REGISTER(__name)			\
    615{								\
    616	if (debug->__name.read)					\
    617		data += sprintf(data, __stringify(__name)	\
    618				"\t%d\t%d\t%d\n",		\
    619				debug->__name.word_base,	\
    620				debug->__name.word_count,	\
    621				debug->__name.word_size);	\
    622}
    623	RT2X00DEBUGFS_SPRINTF_REGISTER(csr);
    624	RT2X00DEBUGFS_SPRINTF_REGISTER(eeprom);
    625	RT2X00DEBUGFS_SPRINTF_REGISTER(bbp);
    626	RT2X00DEBUGFS_SPRINTF_REGISTER(rf);
    627	RT2X00DEBUGFS_SPRINTF_REGISTER(rfcsr);
    628#undef RT2X00DEBUGFS_SPRINTF_REGISTER
    629
    630	blob->size = strlen(blob->data);
    631
    632	debugfs_create_blob(name, 0400, intf->driver_folder, blob);
    633}
    634
    635void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
    636{
    637	const struct rt2x00debug *debug = rt2x00dev->ops->debugfs;
    638	struct rt2x00debug_intf *intf;
    639	struct dentry *queue_folder;
    640	struct dentry *register_folder;
    641
    642	intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL);
    643	if (!intf) {
    644		rt2x00_err(rt2x00dev, "Failed to allocate debug handler\n");
    645		return;
    646	}
    647
    648	intf->debug = debug;
    649	intf->rt2x00dev = rt2x00dev;
    650	rt2x00dev->debugfs_intf = intf;
    651
    652	intf->driver_folder =
    653	    debugfs_create_dir(intf->rt2x00dev->ops->name,
    654			       rt2x00dev->hw->wiphy->debugfsdir);
    655
    656	rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob);
    657	rt2x00debug_create_file_chipset("chipset", intf, &intf->chipset_blob);
    658	debugfs_create_file("dev_flags", 0400, intf->driver_folder, intf,
    659			    &rt2x00debug_fop_dev_flags);
    660	debugfs_create_file("cap_flags", 0400, intf->driver_folder, intf,
    661			    &rt2x00debug_fop_cap_flags);
    662	debugfs_create_file("restart_hw", 0200, intf->driver_folder, intf,
    663			    &rt2x00debug_restart_hw);
    664
    665	register_folder = debugfs_create_dir("register", intf->driver_folder);
    666
    667#define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name)		\
    668({									\
    669	if (debug->__name.read) {					\
    670		debugfs_create_u32(__stringify(__name) "_offset", 0600,	\
    671				   register_folder,			\
    672				   &(__intf)->offset_##__name);		\
    673									\
    674		debugfs_create_file(__stringify(__name) "_value", 0600,	\
    675				    register_folder, (__intf),		\
    676				    &rt2x00debug_fop_##__name);		\
    677	}								\
    678})
    679
    680	RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr);
    681	RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, eeprom);
    682	RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, bbp);
    683	RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rf);
    684	RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rfcsr);
    685
    686#undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY
    687
    688	queue_folder = debugfs_create_dir("queue", intf->driver_folder);
    689
    690	debugfs_create_file("dump", 0400, queue_folder, intf,
    691			    &rt2x00debug_fop_queue_dump);
    692
    693	skb_queue_head_init(&intf->frame_dump_skbqueue);
    694	init_waitqueue_head(&intf->frame_dump_waitqueue);
    695
    696	debugfs_create_file("queue", 0400, queue_folder, intf,
    697			    &rt2x00debug_fop_queue_stats);
    698
    699#ifdef CONFIG_RT2X00_LIB_CRYPTO
    700	if (rt2x00_has_cap_hw_crypto(rt2x00dev))
    701		debugfs_create_file("crypto", 0444, queue_folder, intf,
    702				    &rt2x00debug_fop_crypto_stats);
    703#endif
    704
    705	return;
    706}
    707
    708void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
    709{
    710	struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
    711
    712	if (unlikely(!intf))
    713		return;
    714
    715	skb_queue_purge(&intf->frame_dump_skbqueue);
    716
    717	debugfs_remove_recursive(intf->driver_folder);
    718	kfree(intf->chipset_blob.data);
    719	kfree(intf->driver_blob.data);
    720	kfree(intf);
    721
    722	rt2x00dev->debugfs_intf = NULL;
    723}