iwl-debugfs.c revision 4ad177b5c860dc0b1083eccc55957daf4a116b90
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 *  Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
28
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/debugfs.h>
32
33#include <linux/ieee80211.h>
34#include <net/mac80211.h>
35
36
37#include "iwl-dev.h"
38#include "iwl-debug.h"
39#include "iwl-core.h"
40#include "iwl-io.h"
41#include "iwl-calib.h"
42
43/* create and remove of files */
44#define DEBUGFS_ADD_DIR(name, parent) do {                              \
45	dbgfs->dir_##name = debugfs_create_dir(#name, parent);          \
46	if (!(dbgfs->dir_##name))                                       \
47		goto err; 						\
48} while (0)
49
50#define DEBUGFS_ADD_FILE(name, parent) do {                             \
51	dbgfs->dbgfs_##parent##_files.file_##name =                     \
52	debugfs_create_file(#name, S_IWUSR | S_IRUSR,                   \
53				dbgfs->dir_##parent, priv,              \
54				&iwl_dbgfs_##name##_ops);               \
55	if (!(dbgfs->dbgfs_##parent##_files.file_##name))               \
56		goto err;                                               \
57} while (0)
58
59#define DEBUGFS_ADD_BOOL(name, parent, ptr) do {                        \
60	dbgfs->dbgfs_##parent##_files.file_##name =                     \
61	debugfs_create_bool(#name, S_IWUSR | S_IRUSR,                   \
62			    dbgfs->dir_##parent, ptr);                  \
63	if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name)		\
64			|| !dbgfs->dbgfs_##parent##_files.file_##name)	\
65		goto err;                                               \
66} while (0)
67
68#define DEBUGFS_ADD_X32(name, parent, ptr) do {                        \
69	dbgfs->dbgfs_##parent##_files.file_##name =                     \
70	debugfs_create_x32(#name, S_IRUSR, dbgfs->dir_##parent, ptr);   \
71	if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name)		\
72			|| !dbgfs->dbgfs_##parent##_files.file_##name)	\
73		goto err;                                               \
74} while (0)
75
76#define DEBUGFS_REMOVE(name)  do {              \
77	debugfs_remove(name);                   \
78	name = NULL;                            \
79} while (0);
80
81/* file operation */
82#define DEBUGFS_READ_FUNC(name)                                         \
83static ssize_t iwl_dbgfs_##name##_read(struct file *file,               \
84					char __user *user_buf,          \
85					size_t count, loff_t *ppos);
86
87#define DEBUGFS_WRITE_FUNC(name)                                        \
88static ssize_t iwl_dbgfs_##name##_write(struct file *file,              \
89					const char __user *user_buf,    \
90					size_t count, loff_t *ppos);
91
92
93static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
94{
95	file->private_data = inode->i_private;
96	return 0;
97}
98
99#define DEBUGFS_READ_FILE_OPS(name)                                     \
100	DEBUGFS_READ_FUNC(name);                                        \
101static const struct file_operations iwl_dbgfs_##name##_ops = {          \
102	.read = iwl_dbgfs_##name##_read,                       		\
103	.open = iwl_dbgfs_open_file_generic,                    	\
104};
105
106#define DEBUGFS_WRITE_FILE_OPS(name)                                    \
107	DEBUGFS_WRITE_FUNC(name);                                       \
108static const struct file_operations iwl_dbgfs_##name##_ops = {          \
109	.write = iwl_dbgfs_##name##_write,                              \
110	.open = iwl_dbgfs_open_file_generic,                    	\
111};
112
113
114#define DEBUGFS_READ_WRITE_FILE_OPS(name)                               \
115	DEBUGFS_READ_FUNC(name);                                        \
116	DEBUGFS_WRITE_FUNC(name);                                       \
117static const struct file_operations iwl_dbgfs_##name##_ops = {          \
118	.write = iwl_dbgfs_##name##_write,                              \
119	.read = iwl_dbgfs_##name##_read,                                \
120	.open = iwl_dbgfs_open_file_generic,                            \
121};
122
123
124static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
125						char __user *user_buf,
126						size_t count, loff_t *ppos) {
127
128	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
129	char *buf;
130	int pos = 0;
131
132	int cnt;
133	ssize_t ret;
134	const size_t bufsz = 100 + sizeof(char) * 24 * (MANAGEMENT_MAX + CONTROL_MAX);
135	buf = kzalloc(bufsz, GFP_KERNEL);
136	if (!buf)
137		return -ENOMEM;
138	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
139	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
140		pos += scnprintf(buf + pos, bufsz - pos,
141				 "\t%s\t\t: %u\n",
142				 get_mgmt_string(cnt),
143				 priv->tx_stats.mgmt[cnt]);
144	}
145	pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
146	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
147		pos += scnprintf(buf + pos, bufsz - pos,
148				 "\t%s\t\t: %u\n",
149				 get_ctrl_string(cnt),
150				 priv->tx_stats.ctrl[cnt]);
151	}
152	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
153	pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
154			 priv->tx_stats.data_cnt);
155	pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
156			 priv->tx_stats.data_bytes);
157	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
158	kfree(buf);
159	return ret;
160}
161
162static ssize_t iwl_dbgfs_tx_statistics_write(struct file *file,
163					const char __user *user_buf,
164					size_t count, loff_t *ppos)
165{
166	struct iwl_priv *priv = file->private_data;
167	u32 clear_flag;
168	char buf[8];
169	int buf_size;
170
171	memset(buf, 0, sizeof(buf));
172	buf_size = min(count, sizeof(buf) -  1);
173	if (copy_from_user(buf, user_buf, buf_size))
174		return -EFAULT;
175	if (sscanf(buf, "%x", &clear_flag) != 1)
176		return -EFAULT;
177	if (clear_flag == 1)
178		iwl_clear_tx_stats(priv);
179
180	return count;
181}
182
183static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
184						char __user *user_buf,
185						size_t count, loff_t *ppos) {
186
187	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
188	char *buf;
189	int pos = 0;
190	int cnt;
191	ssize_t ret;
192	const size_t bufsz = 100 +
193		sizeof(char) * 24 * (MANAGEMENT_MAX + CONTROL_MAX);
194	buf = kzalloc(bufsz, GFP_KERNEL);
195	if (!buf)
196		return -ENOMEM;
197
198	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
199	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
200		pos += scnprintf(buf + pos, bufsz - pos,
201				 "\t%s\t\t: %u\n",
202				 get_mgmt_string(cnt),
203				 priv->rx_stats.mgmt[cnt]);
204	}
205	pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
206	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
207		pos += scnprintf(buf + pos, bufsz - pos,
208				 "\t%s\t\t: %u\n",
209				 get_ctrl_string(cnt),
210				 priv->rx_stats.ctrl[cnt]);
211	}
212	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
213	pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
214			 priv->rx_stats.data_cnt);
215	pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
216			 priv->rx_stats.data_bytes);
217
218	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
219	kfree(buf);
220	return ret;
221}
222
223static ssize_t iwl_dbgfs_rx_statistics_write(struct file *file,
224					const char __user *user_buf,
225					size_t count, loff_t *ppos)
226{
227	struct iwl_priv *priv = file->private_data;
228	u32 clear_flag;
229	char buf[8];
230	int buf_size;
231
232	memset(buf, 0, sizeof(buf));
233	buf_size = min(count, sizeof(buf) -  1);
234	if (copy_from_user(buf, user_buf, buf_size))
235		return -EFAULT;
236	if (sscanf(buf, "%x", &clear_flag) != 1)
237		return -EFAULT;
238	if (clear_flag == 1)
239		iwl_clear_rx_stats(priv);
240	return count;
241}
242
243#define BYTE1_MASK 0x000000ff;
244#define BYTE2_MASK 0x0000ffff;
245#define BYTE3_MASK 0x00ffffff;
246static ssize_t iwl_dbgfs_sram_read(struct file *file,
247					char __user *user_buf,
248					size_t count, loff_t *ppos)
249{
250	u32 val;
251	char buf[1024];
252	ssize_t ret;
253	int i;
254	int pos = 0;
255	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
256	const size_t bufsz = sizeof(buf);
257
258	for (i = priv->dbgfs->sram_len; i > 0; i -= 4) {
259		val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \
260					priv->dbgfs->sram_len - i);
261		if (i < 4) {
262			switch (i) {
263			case 1:
264				val &= BYTE1_MASK;
265				break;
266			case 2:
267				val &= BYTE2_MASK;
268				break;
269			case 3:
270				val &= BYTE3_MASK;
271				break;
272			}
273		}
274		pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
275	}
276	pos += scnprintf(buf + pos, bufsz - pos, "\n");
277
278	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
279	return ret;
280}
281
282static ssize_t iwl_dbgfs_sram_write(struct file *file,
283					const char __user *user_buf,
284					size_t count, loff_t *ppos)
285{
286	struct iwl_priv *priv = file->private_data;
287	char buf[64];
288	int buf_size;
289	u32 offset, len;
290
291	memset(buf, 0, sizeof(buf));
292	buf_size = min(count, sizeof(buf) -  1);
293	if (copy_from_user(buf, user_buf, buf_size))
294		return -EFAULT;
295
296	if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
297		priv->dbgfs->sram_offset = offset;
298		priv->dbgfs->sram_len = len;
299	} else {
300		priv->dbgfs->sram_offset = 0;
301		priv->dbgfs->sram_len = 0;
302	}
303
304	return count;
305}
306
307static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
308					size_t count, loff_t *ppos)
309{
310	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
311	struct iwl_station_entry *station;
312	int max_sta = priv->hw_params.max_stations;
313	char *buf;
314	int i, j, pos = 0;
315	ssize_t ret;
316	/* Add 30 for initial string */
317	const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations);
318
319	buf = kmalloc(bufsz, GFP_KERNEL);
320	if (!buf)
321		return -ENOMEM;
322
323	pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
324			priv->num_stations);
325
326	for (i = 0; i < max_sta; i++) {
327		station = &priv->stations[i];
328		if (station->used) {
329			pos += scnprintf(buf + pos, bufsz - pos,
330					"station %d:\ngeneral data:\n", i+1);
331			pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n",
332					station->sta.sta.sta_id);
333			pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n",
334					station->sta.mode);
335			pos += scnprintf(buf + pos, bufsz - pos,
336					"flags: 0x%x\n",
337					station->sta.station_flags_msk);
338			pos += scnprintf(buf + pos, bufsz - pos,
339					"ps_status: %u\n", station->ps_status);
340			pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n");
341			pos += scnprintf(buf + pos, bufsz - pos,
342					"seq_num\t\ttxq_id");
343			pos += scnprintf(buf + pos, bufsz - pos,
344					"\tframe_count\twait_for_ba\t");
345			pos += scnprintf(buf + pos, bufsz - pos,
346					"start_idx\tbitmap0\t");
347			pos += scnprintf(buf + pos, bufsz - pos,
348					"bitmap1\trate_n_flags");
349			pos += scnprintf(buf + pos, bufsz - pos, "\n");
350
351			for (j = 0; j < MAX_TID_COUNT; j++) {
352				pos += scnprintf(buf + pos, bufsz - pos,
353						"[%d]:\t\t%u", j,
354						station->tid[j].seq_number);
355				pos += scnprintf(buf + pos, bufsz - pos,
356						"\t%u\t\t%u\t\t%u\t\t",
357						station->tid[j].agg.txq_id,
358						station->tid[j].agg.frame_count,
359						station->tid[j].agg.wait_for_ba);
360				pos += scnprintf(buf + pos, bufsz - pos,
361						"%u\t%llu\t%u",
362						station->tid[j].agg.start_idx,
363						(unsigned long long)station->tid[j].agg.bitmap,
364						station->tid[j].agg.rate_n_flags);
365				pos += scnprintf(buf + pos, bufsz - pos, "\n");
366			}
367			pos += scnprintf(buf + pos, bufsz - pos, "\n");
368		}
369	}
370
371	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
372	kfree(buf);
373	return ret;
374}
375
376static ssize_t iwl_dbgfs_nvm_read(struct file *file,
377				       char __user *user_buf,
378				       size_t count,
379				       loff_t *ppos)
380{
381	ssize_t ret;
382	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
383	int pos = 0, ofs = 0, buf_size = 0;
384	const u8 *ptr;
385	char *buf;
386	u16 eeprom_ver;
387	size_t eeprom_len = priv->cfg->eeprom_size;
388	buf_size = 4 * eeprom_len + 256;
389
390	if (eeprom_len % 16) {
391		IWL_ERR(priv, "NVM size is not multiple of 16.\n");
392		return -ENODATA;
393	}
394
395	ptr = priv->eeprom;
396	if (!ptr) {
397		IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
398		return -ENOMEM;
399	}
400
401	/* 4 characters for byte 0xYY */
402	buf = kzalloc(buf_size, GFP_KERNEL);
403	if (!buf) {
404		IWL_ERR(priv, "Can not allocate Buffer\n");
405		return -ENOMEM;
406	}
407	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
408	pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, "
409			"version: 0x%x\n",
410			(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
411			 ? "OTP" : "EEPROM", eeprom_ver);
412	for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
413		pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
414		hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
415				   buf_size - pos, 0);
416		pos += strlen(buf + pos);
417		if (buf_size - pos > 0)
418			buf[pos++] = '\n';
419	}
420
421	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
422	kfree(buf);
423	return ret;
424}
425
426static ssize_t iwl_dbgfs_log_event_write(struct file *file,
427					const char __user *user_buf,
428					size_t count, loff_t *ppos)
429{
430	struct iwl_priv *priv = file->private_data;
431	u32 event_log_flag;
432	char buf[8];
433	int buf_size;
434
435	memset(buf, 0, sizeof(buf));
436	buf_size = min(count, sizeof(buf) -  1);
437	if (copy_from_user(buf, user_buf, buf_size))
438		return -EFAULT;
439	if (sscanf(buf, "%d", &event_log_flag) != 1)
440		return -EFAULT;
441	if (event_log_flag == 1)
442		priv->cfg->ops->lib->dump_nic_event_log(priv);
443
444	return count;
445}
446
447
448
449static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
450				       size_t count, loff_t *ppos)
451{
452	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
453	struct ieee80211_channel *channels = NULL;
454	const struct ieee80211_supported_band *supp_band = NULL;
455	int pos = 0, i, bufsz = PAGE_SIZE;
456	char *buf;
457	ssize_t ret;
458
459	if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
460		return -EAGAIN;
461
462	buf = kzalloc(bufsz, GFP_KERNEL);
463	if (!buf) {
464		IWL_ERR(priv, "Can not allocate Buffer\n");
465		return -ENOMEM;
466	}
467
468	supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
469	if (supp_band) {
470		channels = supp_band->channels;
471
472		pos += scnprintf(buf + pos, bufsz - pos,
473				"Displaying %d channels in 2.4GHz band 802.11bg):\n",
474				supp_band->n_channels);
475
476		for (i = 0; i < supp_band->n_channels; i++)
477			pos += scnprintf(buf + pos, bufsz - pos,
478					"%d: %ddBm: BSS%s%s, %s.\n",
479					ieee80211_frequency_to_channel(
480					channels[i].center_freq),
481					channels[i].max_power,
482					channels[i].flags & IEEE80211_CHAN_RADAR ?
483					" (IEEE 802.11h required)" : "",
484					((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
485					|| (channels[i].flags &
486					IEEE80211_CHAN_RADAR)) ? "" :
487					", IBSS",
488					channels[i].flags &
489					IEEE80211_CHAN_PASSIVE_SCAN ?
490					"passive only" : "active/passive");
491	}
492	supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
493	if (supp_band) {
494		channels = supp_band->channels;
495
496		pos += scnprintf(buf + pos, bufsz - pos,
497				"Displaying %d channels in 5.2GHz band (802.11a)\n",
498				supp_band->n_channels);
499
500		for (i = 0; i < supp_band->n_channels; i++)
501			pos += scnprintf(buf + pos, bufsz - pos,
502					"%d: %ddBm: BSS%s%s, %s.\n",
503					ieee80211_frequency_to_channel(
504					channels[i].center_freq),
505					channels[i].max_power,
506					channels[i].flags & IEEE80211_CHAN_RADAR ?
507					" (IEEE 802.11h required)" : "",
508					((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
509					|| (channels[i].flags &
510					IEEE80211_CHAN_RADAR)) ? "" :
511					", IBSS",
512					channels[i].flags &
513					IEEE80211_CHAN_PASSIVE_SCAN ?
514					"passive only" : "active/passive");
515	}
516	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
517	kfree(buf);
518	return ret;
519}
520
521static ssize_t iwl_dbgfs_status_read(struct file *file,
522						char __user *user_buf,
523						size_t count, loff_t *ppos) {
524
525	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
526	char buf[512];
527	int pos = 0;
528	const size_t bufsz = sizeof(buf);
529
530	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
531		test_bit(STATUS_HCMD_ACTIVE, &priv->status));
532	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n",
533		test_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status));
534	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
535		test_bit(STATUS_INT_ENABLED, &priv->status));
536	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
537		test_bit(STATUS_RF_KILL_HW, &priv->status));
538	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n",
539		test_bit(STATUS_CT_KILL, &priv->status));
540	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
541		test_bit(STATUS_INIT, &priv->status));
542	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
543		test_bit(STATUS_ALIVE, &priv->status));
544	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
545		test_bit(STATUS_READY, &priv->status));
546	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
547		test_bit(STATUS_TEMPERATURE, &priv->status));
548	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
549		test_bit(STATUS_GEO_CONFIGURED, &priv->status));
550	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
551		test_bit(STATUS_EXIT_PENDING, &priv->status));
552	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
553		test_bit(STATUS_STATISTICS, &priv->status));
554	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
555		test_bit(STATUS_SCANNING, &priv->status));
556	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
557		test_bit(STATUS_SCAN_ABORTING, &priv->status));
558	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
559		test_bit(STATUS_SCAN_HW, &priv->status));
560	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
561		test_bit(STATUS_POWER_PMI, &priv->status));
562	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
563		test_bit(STATUS_FW_ERROR, &priv->status));
564	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_MODE_PENDING:\t %d\n",
565		test_bit(STATUS_MODE_PENDING, &priv->status));
566	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
567}
568
569static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
570					char __user *user_buf,
571					size_t count, loff_t *ppos) {
572
573	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
574	int pos = 0;
575	int cnt = 0;
576	char *buf;
577	int bufsz = 24 * 64; /* 24 items * 64 char per item */
578	ssize_t ret;
579
580	buf = kzalloc(bufsz, GFP_KERNEL);
581	if (!buf) {
582		IWL_ERR(priv, "Can not allocate Buffer\n");
583		return -ENOMEM;
584	}
585
586	pos += scnprintf(buf + pos, bufsz - pos,
587			"Interrupt Statistics Report:\n");
588
589	pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
590		priv->isr_stats.hw);
591	pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
592		priv->isr_stats.sw);
593	if (priv->isr_stats.sw > 0) {
594		pos += scnprintf(buf + pos, bufsz - pos,
595			"\tLast Restarting Code:  0x%X\n",
596			priv->isr_stats.sw_err);
597	}
598#ifdef CONFIG_IWLWIFI_DEBUG
599	pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
600		priv->isr_stats.sch);
601	pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
602		priv->isr_stats.alive);
603#endif
604	pos += scnprintf(buf + pos, bufsz - pos,
605		"HW RF KILL switch toggled:\t %u\n",
606		priv->isr_stats.rfkill);
607
608	pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
609		priv->isr_stats.ctkill);
610
611	pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
612		priv->isr_stats.wakeup);
613
614	pos += scnprintf(buf + pos, bufsz - pos,
615		"Rx command responses:\t\t %u\n",
616		priv->isr_stats.rx);
617	for (cnt = 0; cnt < REPLY_MAX; cnt++) {
618		if (priv->isr_stats.rx_handlers[cnt] > 0)
619			pos += scnprintf(buf + pos, bufsz - pos,
620				"\tRx handler[%36s]:\t\t %u\n",
621				get_cmd_string(cnt),
622				priv->isr_stats.rx_handlers[cnt]);
623	}
624
625	pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
626		priv->isr_stats.tx);
627
628	pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
629		priv->isr_stats.unhandled);
630
631	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
632	kfree(buf);
633	return ret;
634}
635
636static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
637					 const char __user *user_buf,
638					 size_t count, loff_t *ppos)
639{
640	struct iwl_priv *priv = file->private_data;
641	char buf[8];
642	int buf_size;
643	u32 reset_flag;
644
645	memset(buf, 0, sizeof(buf));
646	buf_size = min(count, sizeof(buf) -  1);
647	if (copy_from_user(buf, user_buf, buf_size))
648		return -EFAULT;
649	if (sscanf(buf, "%x", &reset_flag) != 1)
650		return -EFAULT;
651	if (reset_flag == 0)
652		iwl_clear_isr_stats(priv);
653
654	return count;
655}
656
657static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
658				       size_t count, loff_t *ppos)
659{
660	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
661	int pos = 0, i;
662	char buf[256];
663	const size_t bufsz = sizeof(buf);
664	ssize_t ret;
665
666	for (i = 0; i < AC_NUM; i++) {
667		pos += scnprintf(buf + pos, bufsz - pos,
668			"\tcw_min\tcw_max\taifsn\ttxop\n");
669		pos += scnprintf(buf + pos, bufsz - pos,
670				"AC[%d]\t%u\t%u\t%u\t%u\n", i,
671				priv->qos_data.def_qos_parm.ac[i].cw_min,
672				priv->qos_data.def_qos_parm.ac[i].cw_max,
673				priv->qos_data.def_qos_parm.ac[i].aifsn,
674				priv->qos_data.def_qos_parm.ac[i].edca_txop);
675	}
676	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
677	return ret;
678}
679
680static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
681				  size_t count, loff_t *ppos)
682{
683	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
684	int pos = 0;
685	char buf[256];
686	const size_t bufsz = sizeof(buf);
687	ssize_t ret;
688
689	pos += scnprintf(buf + pos, bufsz - pos,
690			 "allow blinking: %s\n",
691			 (priv->allow_blinking) ? "True" : "False");
692	if (priv->allow_blinking) {
693		pos += scnprintf(buf + pos, bufsz - pos,
694				 "Led blinking rate: %u\n",
695				 priv->last_blink_rate);
696		pos += scnprintf(buf + pos, bufsz - pos,
697				 "Last blink time: %lu\n",
698				 priv->last_blink_time);
699	}
700
701	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
702	return ret;
703}
704
705static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
706				char __user *user_buf,
707				size_t count, loff_t *ppos)
708{
709	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
710	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
711	struct iwl_tt_restriction *restriction;
712	char buf[100];
713	int pos = 0;
714	const size_t bufsz = sizeof(buf);
715	ssize_t ret;
716
717	pos += scnprintf(buf + pos, bufsz - pos,
718			"Thermal Throttling Mode: %s\n",
719			tt->advanced_tt ? "Advance" : "Legacy");
720	pos += scnprintf(buf + pos, bufsz - pos,
721			"Thermal Throttling State: %d\n",
722			tt->state);
723	if (tt->advanced_tt) {
724		restriction = tt->restriction + tt->state;
725		pos += scnprintf(buf + pos, bufsz - pos,
726				"Tx mode: %d\n",
727				restriction->tx_stream);
728		pos += scnprintf(buf + pos, bufsz - pos,
729				"Rx mode: %d\n",
730				restriction->rx_stream);
731		pos += scnprintf(buf + pos, bufsz - pos,
732				"HT mode: %d\n",
733				restriction->is_ht);
734	}
735	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
736	return ret;
737}
738
739static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
740					 const char __user *user_buf,
741					 size_t count, loff_t *ppos)
742{
743	struct iwl_priv *priv = file->private_data;
744	char buf[8];
745	int buf_size;
746	int ht40;
747
748	memset(buf, 0, sizeof(buf));
749	buf_size = min(count, sizeof(buf) -  1);
750	if (copy_from_user(buf, user_buf, buf_size))
751		return -EFAULT;
752	if (sscanf(buf, "%d", &ht40) != 1)
753		return -EFAULT;
754	if (!iwl_is_associated(priv))
755		priv->disable_ht40 = ht40 ? true : false;
756	else {
757		IWL_ERR(priv, "Sta associated with AP - "
758			"Change to 40MHz channel support is not allowed\n");
759		return -EINVAL;
760	}
761
762	return count;
763}
764
765static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
766					 char __user *user_buf,
767					 size_t count, loff_t *ppos)
768{
769	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
770	char buf[100];
771	int pos = 0;
772	const size_t bufsz = sizeof(buf);
773	ssize_t ret;
774
775	pos += scnprintf(buf + pos, bufsz - pos,
776			"11n 40MHz Mode: %s\n",
777			priv->disable_ht40 ? "Disabled" : "Enabled");
778	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
779	return ret;
780}
781
782static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
783						    const char __user *user_buf,
784						    size_t count, loff_t *ppos)
785{
786	struct iwl_priv *priv = file->private_data;
787	char buf[8];
788	int buf_size;
789	int value;
790
791	memset(buf, 0, sizeof(buf));
792	buf_size = min(count, sizeof(buf) -  1);
793	if (copy_from_user(buf, user_buf, buf_size))
794		return -EFAULT;
795
796	if (sscanf(buf, "%d", &value) != 1)
797		return -EINVAL;
798
799	/*
800	 * Our users expect 0 to be "CAM", but 0 isn't actually
801	 * valid here. However, let's not confuse them and present
802	 * IWL_POWER_INDEX_1 as "1", not "0".
803	 */
804	if (value == 0)
805		return -EINVAL;
806	else if (value > 0)
807		value -= 1;
808
809	if (value != -1 && (value < 0 || value >= IWL_POWER_NUM))
810		return -EINVAL;
811
812	if (!iwl_is_ready_rf(priv))
813		return -EAGAIN;
814
815	priv->power_data.debug_sleep_level_override = value;
816
817	iwl_power_update_mode(priv, true);
818
819	return count;
820}
821
822static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
823						   char __user *user_buf,
824						   size_t count, loff_t *ppos)
825{
826	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
827	char buf[10];
828	int pos, value;
829	const size_t bufsz = sizeof(buf);
830
831	/* see the write function */
832	value = priv->power_data.debug_sleep_level_override;
833	if (value >= 0)
834		value += 1;
835
836	pos = scnprintf(buf, bufsz, "%d\n", value);
837	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
838}
839
840static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
841						    char __user *user_buf,
842						    size_t count, loff_t *ppos)
843{
844	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
845	char buf[200];
846	int pos = 0, i;
847	const size_t bufsz = sizeof(buf);
848	struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd;
849
850	pos += scnprintf(buf + pos, bufsz - pos,
851			 "flags: %#.2x\n", le16_to_cpu(cmd->flags));
852	pos += scnprintf(buf + pos, bufsz - pos,
853			 "RX/TX timeout: %d/%d usec\n",
854			 le32_to_cpu(cmd->rx_data_timeout),
855			 le32_to_cpu(cmd->tx_data_timeout));
856	for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
857		pos += scnprintf(buf + pos, bufsz - pos,
858				 "sleep_interval[%d]: %d\n", i,
859				 le32_to_cpu(cmd->sleep_interval[i]));
860
861	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
862}
863
864DEBUGFS_READ_WRITE_FILE_OPS(sram);
865DEBUGFS_WRITE_FILE_OPS(log_event);
866DEBUGFS_READ_FILE_OPS(nvm);
867DEBUGFS_READ_FILE_OPS(stations);
868DEBUGFS_READ_FILE_OPS(channels);
869DEBUGFS_READ_FILE_OPS(status);
870DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
871DEBUGFS_READ_FILE_OPS(qos);
872DEBUGFS_READ_FILE_OPS(led);
873DEBUGFS_READ_FILE_OPS(thermal_throttling);
874DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
875DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
876DEBUGFS_READ_FILE_OPS(current_sleep_command);
877
878static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
879					 char __user *user_buf,
880					 size_t count, loff_t *ppos)
881{
882	struct iwl_priv *priv = file->private_data;
883	int pos = 0, ofs = 0;
884	int cnt = 0, entry;
885	struct iwl_tx_queue *txq;
886	struct iwl_queue *q;
887	struct iwl_rx_queue *rxq = &priv->rxq;
888	char *buf;
889	int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
890		(priv->cfg->num_of_queues * 32 * 8) + 400;
891	const u8 *ptr;
892	ssize_t ret;
893
894	if (!priv->txq) {
895		IWL_ERR(priv, "txq not ready\n");
896		return -EAGAIN;
897	}
898	buf = kzalloc(bufsz, GFP_KERNEL);
899	if (!buf) {
900		IWL_ERR(priv, "Can not allocate buffer\n");
901		return -ENOMEM;
902	}
903	pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
904	for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
905		txq = &priv->txq[cnt];
906		q = &txq->q;
907		pos += scnprintf(buf + pos, bufsz - pos,
908				"q[%d]: read_ptr: %u, write_ptr: %u\n",
909				cnt, q->read_ptr, q->write_ptr);
910	}
911	if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) {
912		ptr = priv->tx_traffic;
913		pos += scnprintf(buf + pos, bufsz - pos,
914				"Tx Traffic idx: %u\n",	priv->tx_traffic_idx);
915		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
916			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
917			     entry++,  ofs += 16) {
918				pos += scnprintf(buf + pos, bufsz - pos,
919						"0x%.4x ", ofs);
920				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
921						   buf + pos, bufsz - pos, 0);
922				pos += strlen(buf + pos);
923				if (bufsz - pos > 0)
924					buf[pos++] = '\n';
925			}
926		}
927	}
928
929	pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
930	pos += scnprintf(buf + pos, bufsz - pos,
931			"read: %u, write: %u\n",
932			 rxq->read, rxq->write);
933
934	if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) {
935		ptr = priv->rx_traffic;
936		pos += scnprintf(buf + pos, bufsz - pos,
937				"Rx Traffic idx: %u\n",	priv->rx_traffic_idx);
938		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
939			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
940			     entry++,  ofs += 16) {
941				pos += scnprintf(buf + pos, bufsz - pos,
942						"0x%.4x ", ofs);
943				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
944						   buf + pos, bufsz - pos, 0);
945				pos += strlen(buf + pos);
946				if (bufsz - pos > 0)
947					buf[pos++] = '\n';
948			}
949		}
950	}
951
952	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
953	kfree(buf);
954	return ret;
955}
956
957static ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
958					 const char __user *user_buf,
959					 size_t count, loff_t *ppos)
960{
961	struct iwl_priv *priv = file->private_data;
962	char buf[8];
963	int buf_size;
964	int traffic_log;
965
966	memset(buf, 0, sizeof(buf));
967	buf_size = min(count, sizeof(buf) -  1);
968	if (copy_from_user(buf, user_buf, buf_size))
969		return -EFAULT;
970	if (sscanf(buf, "%d", &traffic_log) != 1)
971		return -EFAULT;
972	if (traffic_log == 0)
973		iwl_reset_traffic_log(priv);
974
975	return count;
976}
977
978static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
979						char __user *user_buf,
980						size_t count, loff_t *ppos) {
981
982	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
983	struct iwl_tx_queue *txq;
984	struct iwl_queue *q;
985	char *buf;
986	int pos = 0;
987	int cnt;
988	int ret;
989	const size_t bufsz = sizeof(char) * 60 * priv->cfg->num_of_queues;
990
991	if (!priv->txq) {
992		IWL_ERR(priv, "txq not ready\n");
993		return -EAGAIN;
994	}
995	buf = kzalloc(bufsz, GFP_KERNEL);
996	if (!buf)
997		return -ENOMEM;
998
999	for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
1000		txq = &priv->txq[cnt];
1001		q = &txq->q;
1002		pos += scnprintf(buf + pos, bufsz - pos,
1003				"hwq %.2d: read=%u write=%u stop=%d"
1004				" swq_id=%#.2x (ac %d/hwq %d)\n",
1005				cnt, q->read_ptr, q->write_ptr,
1006				!!test_bit(cnt, priv->queue_stopped),
1007				txq->swq_id,
1008				txq->swq_id & 0x80 ? txq->swq_id & 3 :
1009				txq->swq_id,
1010				txq->swq_id & 0x80 ? (txq->swq_id >> 2) &
1011				0x1f : txq->swq_id);
1012		if (cnt >= 4)
1013			continue;
1014		/* for the ACs, display the stop count too */
1015		pos += scnprintf(buf + pos, bufsz - pos,
1016				"        stop-count: %d\n",
1017				atomic_read(&priv->queue_stop_count[cnt]));
1018	}
1019	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1020	kfree(buf);
1021	return ret;
1022}
1023
1024static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1025						char __user *user_buf,
1026						size_t count, loff_t *ppos) {
1027
1028	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1029	struct iwl_rx_queue *rxq = &priv->rxq;
1030	char buf[256];
1031	int pos = 0;
1032	const size_t bufsz = sizeof(buf);
1033
1034	pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
1035						rxq->read);
1036	pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
1037						rxq->write);
1038	pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
1039						rxq->free_count);
1040	pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
1041			 le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF);
1042	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1043}
1044
1045#define UCODE_STATISTICS_CLEAR_MSK		(0x1 << 0)
1046#define UCODE_STATISTICS_FREQUENCY_MSK		(0x1 << 1)
1047#define UCODE_STATISTICS_NARROW_BAND_MSK	(0x1 << 2)
1048
1049static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
1050				     int bufsz)
1051{
1052	int p = 0;
1053
1054	p += scnprintf(buf + p, bufsz - p,
1055		"Statistics Flag(0x%X):\n",
1056		le32_to_cpu(priv->statistics.flag));
1057	if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
1058		p += scnprintf(buf + p, bufsz - p,
1059		"\tStatistics have been cleared\n");
1060	p += scnprintf(buf + p, bufsz - p,
1061		"\tOperational Frequency: %s\n",
1062		(le32_to_cpu(priv->statistics.flag) &
1063		UCODE_STATISTICS_FREQUENCY_MSK)
1064		 ? "2.4 GHz" : "5.2 GHz");
1065	p += scnprintf(buf + p, bufsz - p,
1066		"\tTGj Narrow Band: %s\n",
1067		(le32_to_cpu(priv->statistics.flag) &
1068		UCODE_STATISTICS_NARROW_BAND_MSK)
1069		 ? "enabled" : "disabled");
1070	return p;
1071}
1072
1073
1074static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1075					char __user *user_buf,
1076					size_t count, loff_t *ppos)
1077{
1078	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1079	int pos = 0;
1080	char *buf;
1081	int bufsz = sizeof(struct statistics_rx_phy) * 20 +
1082		sizeof(struct statistics_rx_non_phy) * 20 +
1083		sizeof(struct statistics_rx_ht_phy) * 20 + 400;
1084	ssize_t ret;
1085	struct statistics_rx_phy *ofdm, *accum_ofdm;
1086	struct statistics_rx_phy *cck, *accum_cck;
1087	struct statistics_rx_non_phy *general, *accum_general;
1088	struct statistics_rx_ht_phy *ht, *accum_ht;
1089
1090	if (!iwl_is_alive(priv))
1091		return -EAGAIN;
1092
1093	/* make request to uCode to retrieve statistics information */
1094	mutex_lock(&priv->mutex);
1095	ret = iwl_send_statistics_request(priv, 0);
1096	mutex_unlock(&priv->mutex);
1097
1098	if (ret) {
1099		IWL_ERR(priv,
1100			"Error sending statistics request: %zd\n", ret);
1101		return -EAGAIN;
1102	}
1103	buf = kzalloc(bufsz, GFP_KERNEL);
1104	if (!buf) {
1105		IWL_ERR(priv, "Can not allocate Buffer\n");
1106		return -ENOMEM;
1107	}
1108
1109	/* the statistic information display here is based on
1110	 * the last statistics notification from uCode
1111	 * might not reflect the current uCode activity
1112	 */
1113	ofdm = &priv->statistics.rx.ofdm;
1114	cck = &priv->statistics.rx.cck;
1115	general = &priv->statistics.rx.general;
1116	ht = &priv->statistics.rx.ofdm_ht;
1117	accum_ofdm = &priv->accum_statistics.rx.ofdm;
1118	accum_cck = &priv->accum_statistics.rx.cck;
1119	accum_general = &priv->accum_statistics.rx.general;
1120	accum_ht = &priv->accum_statistics.rx.ofdm_ht;
1121	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1122	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n");
1123	pos += scnprintf(buf + pos, bufsz - pos,
1124			"\t\t\tcurrent\t\t\taccumulative\n");
1125	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n",
1126			 le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt);
1127	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n",
1128			 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt);
1129	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
1130			 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err);
1131	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
1132			 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err);
1133	pos += scnprintf(buf + pos, bufsz - pos,
1134			 "overrun_err:\t\t%u\t\t\t%u\n",
1135			 le32_to_cpu(ofdm->overrun_err),
1136			 accum_ofdm->overrun_err);
1137	pos += scnprintf(buf + pos, bufsz - pos,
1138			 "early_overrun_err:\t%u\t\t\t%u\n",
1139			 le32_to_cpu(ofdm->early_overrun_err),
1140			 accum_ofdm->early_overrun_err);
1141	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
1142			 le32_to_cpu(ofdm->crc32_good),
1143			 accum_ofdm->crc32_good);
1144	pos += scnprintf(buf + pos, bufsz - pos,
1145			 "false_alarm_cnt:\t%u\t\t\t%u\n",
1146			 le32_to_cpu(ofdm->false_alarm_cnt),
1147			 accum_ofdm->false_alarm_cnt);
1148	pos += scnprintf(buf + pos, bufsz - pos,
1149			 "fina_sync_err_cnt:\t%u\t\t\t%u\n",
1150			 le32_to_cpu(ofdm->fina_sync_err_cnt),
1151			 accum_ofdm->fina_sync_err_cnt);
1152	pos += scnprintf(buf + pos, bufsz - pos,
1153			 "sfd_timeout:\t\t%u\t\t\t%u\n",
1154			 le32_to_cpu(ofdm->sfd_timeout),
1155			 accum_ofdm->sfd_timeout);
1156	pos += scnprintf(buf + pos, bufsz - pos,
1157			 "fina_timeout:\t\t%u\t\t\t%u\n",
1158			 le32_to_cpu(ofdm->fina_timeout),
1159			 accum_ofdm->fina_timeout);
1160	pos += scnprintf(buf + pos, bufsz - pos,
1161			 "unresponded_rts:\t%u\t\t\t%u\n",
1162			 le32_to_cpu(ofdm->unresponded_rts),
1163			 accum_ofdm->unresponded_rts);
1164	pos += scnprintf(buf + pos, bufsz - pos,
1165			"rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n",
1166			 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
1167			 accum_ofdm->rxe_frame_limit_overrun);
1168	pos += scnprintf(buf + pos, bufsz - pos,
1169			 "sent_ack_cnt:\t\t%u\t\t\t%u\n",
1170			 le32_to_cpu(ofdm->sent_ack_cnt),
1171			 accum_ofdm->sent_ack_cnt);
1172	pos += scnprintf(buf + pos, bufsz - pos,
1173			 "sent_cts_cnt:\t\t%u\t\t\t%u\n",
1174			 le32_to_cpu(ofdm->sent_cts_cnt),
1175			 accum_ofdm->sent_cts_cnt);
1176	pos += scnprintf(buf + pos, bufsz - pos,
1177			 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n",
1178			 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
1179			 accum_ofdm->sent_ba_rsp_cnt);
1180	pos += scnprintf(buf + pos, bufsz - pos,
1181			 "dsp_self_kill:\t\t%u\t\t\t%u\n",
1182			 le32_to_cpu(ofdm->dsp_self_kill),
1183			 accum_ofdm->dsp_self_kill);
1184	pos += scnprintf(buf + pos, bufsz - pos,
1185			 "mh_format_err:\t\t%u\t\t\t%u\n",
1186			 le32_to_cpu(ofdm->mh_format_err),
1187			 accum_ofdm->mh_format_err);
1188	pos += scnprintf(buf + pos, bufsz - pos,
1189			 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n",
1190			 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
1191			 accum_ofdm->re_acq_main_rssi_sum);
1192
1193	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n");
1194	pos += scnprintf(buf + pos, bufsz - pos,
1195			"\t\t\tcurrent\t\t\taccumulative\n");
1196	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n",
1197			 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt);
1198	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n",
1199			 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt);
1200	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
1201			 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err);
1202	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
1203			 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err);
1204	pos += scnprintf(buf + pos, bufsz - pos,
1205			 "overrun_err:\t\t%u\t\t\t%u\n",
1206			 le32_to_cpu(cck->overrun_err),
1207			 accum_cck->overrun_err);
1208	pos += scnprintf(buf + pos, bufsz - pos,
1209			 "early_overrun_err:\t%u\t\t\t%u\n",
1210			 le32_to_cpu(cck->early_overrun_err),
1211			 accum_cck->early_overrun_err);
1212	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
1213			 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good);
1214	pos += scnprintf(buf + pos, bufsz - pos,
1215			 "false_alarm_cnt:\t%u\t\t\t%u\n",
1216			 le32_to_cpu(cck->false_alarm_cnt),
1217			 accum_cck->false_alarm_cnt);
1218	pos += scnprintf(buf + pos, bufsz - pos,
1219			 "fina_sync_err_cnt:\t%u\t\t\t%u\n",
1220			 le32_to_cpu(cck->fina_sync_err_cnt),
1221			 accum_cck->fina_sync_err_cnt);
1222	pos += scnprintf(buf + pos, bufsz - pos,
1223			 "sfd_timeout:\t\t%u\t\t\t%u\n",
1224			 le32_to_cpu(cck->sfd_timeout),
1225			 accum_cck->sfd_timeout);
1226	pos += scnprintf(buf + pos, bufsz - pos,
1227			 "fina_timeout:\t\t%u\t\t\t%u\n",
1228			 le32_to_cpu(cck->fina_timeout),
1229			 accum_cck->fina_timeout);
1230	pos += scnprintf(buf + pos, bufsz - pos,
1231			 "unresponded_rts:\t%u\t\t\t%u\n",
1232			 le32_to_cpu(cck->unresponded_rts),
1233			 accum_cck->unresponded_rts);
1234	pos += scnprintf(buf + pos, bufsz - pos,
1235			"rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n",
1236			 le32_to_cpu(cck->rxe_frame_limit_overrun),
1237			 accum_cck->rxe_frame_limit_overrun);
1238	pos += scnprintf(buf + pos, bufsz - pos,
1239			 "sent_ack_cnt:\t\t%u\t\t\t%u\n",
1240			 le32_to_cpu(cck->sent_ack_cnt),
1241			 accum_cck->sent_ack_cnt);
1242	pos += scnprintf(buf + pos, bufsz - pos,
1243			 "sent_cts_cnt:\t\t%u\t\t\t%u\n",
1244			 le32_to_cpu(cck->sent_cts_cnt),
1245			 accum_cck->sent_cts_cnt);
1246	pos += scnprintf(buf + pos, bufsz - pos,
1247			 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n",
1248			 le32_to_cpu(cck->sent_ba_rsp_cnt),
1249			 accum_cck->sent_ba_rsp_cnt);
1250	pos += scnprintf(buf + pos, bufsz - pos,
1251			 "dsp_self_kill:\t\t%u\t\t\t%u\n",
1252			 le32_to_cpu(cck->dsp_self_kill),
1253			 accum_cck->dsp_self_kill);
1254	pos += scnprintf(buf + pos, bufsz - pos,
1255			 "mh_format_err:\t\t%u\t\t\t%u\n",
1256			 le32_to_cpu(cck->mh_format_err),
1257			 accum_cck->mh_format_err);
1258	pos += scnprintf(buf + pos, bufsz - pos,
1259			 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n",
1260			 le32_to_cpu(cck->re_acq_main_rssi_sum),
1261			 accum_cck->re_acq_main_rssi_sum);
1262
1263	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n");
1264	pos += scnprintf(buf + pos, bufsz - pos,
1265			"\t\t\tcurrent\t\t\taccumulative\n");
1266	pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts:\t\t%u\t\t\t%u\n",
1267			 le32_to_cpu(general->bogus_cts),
1268			 accum_general->bogus_cts);
1269	pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack:\t\t%u\t\t\t%u\n",
1270			 le32_to_cpu(general->bogus_ack),
1271			 accum_general->bogus_ack);
1272	pos += scnprintf(buf + pos, bufsz - pos,
1273			 "non_bssid_frames:\t%u\t\t\t%u\n",
1274			 le32_to_cpu(general->non_bssid_frames),
1275			 accum_general->non_bssid_frames);
1276	pos += scnprintf(buf + pos, bufsz - pos,
1277			 "filtered_frames:\t%u\t\t\t%u\n",
1278			 le32_to_cpu(general->filtered_frames),
1279			 accum_general->filtered_frames);
1280	pos += scnprintf(buf + pos, bufsz - pos,
1281			 "non_channel_beacons:\t%u\t\t\t%u\n",
1282			 le32_to_cpu(general->non_channel_beacons),
1283			 accum_general->non_channel_beacons);
1284	pos += scnprintf(buf + pos, bufsz - pos,
1285			 "channel_beacons:\t%u\t\t\t%u\n",
1286			 le32_to_cpu(general->channel_beacons),
1287			 accum_general->channel_beacons);
1288	pos += scnprintf(buf + pos, bufsz - pos,
1289			 "num_missed_bcon:\t%u\t\t\t%u\n",
1290			 le32_to_cpu(general->num_missed_bcon),
1291			 accum_general->num_missed_bcon);
1292	pos += scnprintf(buf + pos, bufsz - pos,
1293			"adc_rx_saturation_time:\t%u\t\t\t%u\n",
1294			 le32_to_cpu(general->adc_rx_saturation_time),
1295			 accum_general->adc_rx_saturation_time);
1296	pos += scnprintf(buf + pos, bufsz - pos,
1297			"ina_detect_search_tm:\t%u\t\t\t%u\n",
1298			 le32_to_cpu(general->ina_detection_search_time),
1299			 accum_general->ina_detection_search_time);
1300	pos += scnprintf(buf + pos, bufsz - pos,
1301			 "beacon_silence_rssi_a:\t%u\t\t\t%u\n",
1302			 le32_to_cpu(general->beacon_silence_rssi_a),
1303			 accum_general->beacon_silence_rssi_a);
1304	pos += scnprintf(buf + pos, bufsz - pos,
1305			 "beacon_silence_rssi_b:\t%u\t\t\t%u\n",
1306			 le32_to_cpu(general->beacon_silence_rssi_b),
1307			 accum_general->beacon_silence_rssi_b);
1308	pos += scnprintf(buf + pos, bufsz - pos,
1309			 "beacon_silence_rssi_c:\t%u\t\t\t%u\n",
1310			 le32_to_cpu(general->beacon_silence_rssi_c),
1311			 accum_general->beacon_silence_rssi_c);
1312	pos += scnprintf(buf + pos, bufsz - pos,
1313			"interference_data_flag:\t%u\t\t\t%u\n",
1314			 le32_to_cpu(general->interference_data_flag),
1315			 accum_general->interference_data_flag);
1316	pos += scnprintf(buf + pos, bufsz - pos,
1317			 "channel_load:\t\t%u\t\t\t%u\n",
1318			 le32_to_cpu(general->channel_load),
1319			 accum_general->channel_load);
1320	pos += scnprintf(buf + pos, bufsz - pos,
1321			 "dsp_false_alarms:\t%u\t\t\t%u\n",
1322			 le32_to_cpu(general->dsp_false_alarms),
1323			 accum_general->dsp_false_alarms);
1324	pos += scnprintf(buf + pos, bufsz - pos,
1325			 "beacon_rssi_a:\t\t%u\t\t\t%u\n",
1326			 le32_to_cpu(general->beacon_rssi_a),
1327			 accum_general->beacon_rssi_a);
1328	pos += scnprintf(buf + pos, bufsz - pos,
1329			 "beacon_rssi_b:\t\t%u\t\t\t%u\n",
1330			 le32_to_cpu(general->beacon_rssi_b),
1331			 accum_general->beacon_rssi_b);
1332	pos += scnprintf(buf + pos, bufsz - pos,
1333			 "beacon_rssi_c:\t\t%u\t\t\t%u\n",
1334			 le32_to_cpu(general->beacon_rssi_c),
1335			 accum_general->beacon_rssi_c);
1336	pos += scnprintf(buf + pos, bufsz - pos,
1337			 "beacon_energy_a:\t%u\t\t\t%u\n",
1338			 le32_to_cpu(general->beacon_energy_a),
1339			 accum_general->beacon_energy_a);
1340	pos += scnprintf(buf + pos, bufsz - pos,
1341			 "beacon_energy_b:\t%u\t\t\t%u\n",
1342			 le32_to_cpu(general->beacon_energy_b),
1343			 accum_general->beacon_energy_b);
1344	pos += scnprintf(buf + pos, bufsz - pos,
1345			 "beacon_energy_c:\t%u\t\t\t%u\n",
1346			 le32_to_cpu(general->beacon_energy_c),
1347			 accum_general->beacon_energy_c);
1348
1349	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
1350	pos += scnprintf(buf + pos, bufsz - pos,
1351			"\t\t\tcurrent\t\t\taccumulative\n");
1352	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
1353			 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err);
1354	pos += scnprintf(buf + pos, bufsz - pos,
1355			 "overrun_err:\t\t%u\t\t\t%u\n",
1356			 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err);
1357	pos += scnprintf(buf + pos, bufsz - pos,
1358			 "early_overrun_err:\t%u\t\t\t%u\n",
1359			 le32_to_cpu(ht->early_overrun_err),
1360			 accum_ht->early_overrun_err);
1361	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
1362			 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good);
1363	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
1364			 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err);
1365	pos += scnprintf(buf + pos, bufsz - pos,
1366			 "mh_format_err:\t\t%u\t\t\t%u\n",
1367			 le32_to_cpu(ht->mh_format_err),
1368			 accum_ht->mh_format_err);
1369	pos += scnprintf(buf + pos, bufsz - pos,
1370			 "agg_crc32_good:\t\t%u\t\t\t%u\n",
1371			 le32_to_cpu(ht->agg_crc32_good),
1372			 accum_ht->agg_crc32_good);
1373	pos += scnprintf(buf + pos, bufsz - pos,
1374			 "agg_mpdu_cnt:\t\t%u\t\t\t%u\n",
1375			 le32_to_cpu(ht->agg_mpdu_cnt),
1376			 accum_ht->agg_mpdu_cnt);
1377	pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n",
1378			 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt);
1379
1380	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1381	kfree(buf);
1382	return ret;
1383}
1384
1385static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1386					char __user *user_buf,
1387					size_t count, loff_t *ppos)
1388{
1389	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1390	int pos = 0;
1391	char *buf;
1392	int bufsz = (sizeof(struct statistics_tx) * 24) + 250;
1393	ssize_t ret;
1394	struct statistics_tx *tx, *accum_tx;
1395
1396	if (!iwl_is_alive(priv))
1397		return -EAGAIN;
1398
1399	/* make request to uCode to retrieve statistics information */
1400	mutex_lock(&priv->mutex);
1401	ret = iwl_send_statistics_request(priv, 0);
1402	mutex_unlock(&priv->mutex);
1403
1404	if (ret) {
1405		IWL_ERR(priv,
1406			"Error sending statistics request: %zd\n", ret);
1407		return -EAGAIN;
1408	}
1409	buf = kzalloc(bufsz, GFP_KERNEL);
1410	if (!buf) {
1411		IWL_ERR(priv, "Can not allocate Buffer\n");
1412		return -ENOMEM;
1413	}
1414
1415	/* the statistic information display here is based on
1416	 * the last statistics notification from uCode
1417	 * might not reflect the current uCode activity
1418	 */
1419	tx = &priv->statistics.tx;
1420	accum_tx = &priv->accum_statistics.tx;
1421	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1422	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n");
1423	pos += scnprintf(buf + pos, bufsz - pos,
1424			"\t\t\tcurrent\t\t\taccumulative\n");
1425	pos += scnprintf(buf + pos, bufsz - pos, "preamble:\t\t\t%u\t\t\t%u\n",
1426			 le32_to_cpu(tx->preamble_cnt),
1427			 accum_tx->preamble_cnt);
1428	pos += scnprintf(buf + pos, bufsz - pos,
1429			 "rx_detected_cnt:\t\t%u\t\t\t%u\n",
1430			 le32_to_cpu(tx->rx_detected_cnt),
1431			 accum_tx->rx_detected_cnt);
1432	pos += scnprintf(buf + pos, bufsz - pos,
1433			 "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n",
1434			 le32_to_cpu(tx->bt_prio_defer_cnt),
1435			 accum_tx->bt_prio_defer_cnt);
1436	pos += scnprintf(buf + pos, bufsz - pos,
1437			 "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n",
1438			 le32_to_cpu(tx->bt_prio_kill_cnt),
1439			 accum_tx->bt_prio_kill_cnt);
1440	pos += scnprintf(buf + pos, bufsz - pos,
1441			 "few_bytes_cnt:\t\t\t%u\t\t\t%u\n",
1442			 le32_to_cpu(tx->few_bytes_cnt),
1443			 accum_tx->few_bytes_cnt);
1444	pos += scnprintf(buf + pos, bufsz - pos,
1445			 "cts_timeout:\t\t\t%u\t\t\t%u\n",
1446			 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout);
1447	pos += scnprintf(buf + pos, bufsz - pos,
1448			 "ack_timeout:\t\t\t%u\t\t\t%u\n",
1449			 le32_to_cpu(tx->ack_timeout),
1450			 accum_tx->ack_timeout);
1451	pos += scnprintf(buf + pos, bufsz - pos,
1452			 "expected_ack_cnt:\t\t%u\t\t\t%u\n",
1453			 le32_to_cpu(tx->expected_ack_cnt),
1454			 accum_tx->expected_ack_cnt);
1455	pos += scnprintf(buf + pos, bufsz - pos,
1456			 "actual_ack_cnt:\t\t\t%u\t\t\t%u\n",
1457			 le32_to_cpu(tx->actual_ack_cnt),
1458			 accum_tx->actual_ack_cnt);
1459	pos += scnprintf(buf + pos, bufsz - pos,
1460			 "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n",
1461			 le32_to_cpu(tx->dump_msdu_cnt),
1462			 accum_tx->dump_msdu_cnt);
1463	pos += scnprintf(buf + pos, bufsz - pos,
1464			 "abort_nxt_frame_mismatch:"
1465			 "\t%u\t\t\t%u\n",
1466			 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
1467			 accum_tx->burst_abort_next_frame_mismatch_cnt);
1468	pos += scnprintf(buf + pos, bufsz - pos,
1469			 "abort_missing_nxt_frame:"
1470			 "\t%u\t\t\t%u\n",
1471			 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
1472			 accum_tx->burst_abort_missing_next_frame_cnt);
1473	pos += scnprintf(buf + pos, bufsz - pos,
1474			 "cts_timeout_collision:\t\t%u\t\t\t%u\n",
1475			 le32_to_cpu(tx->cts_timeout_collision),
1476			 accum_tx->cts_timeout_collision);
1477	pos += scnprintf(buf + pos, bufsz - pos,
1478			"ack_ba_timeout_collision:\t%u\t\t\t%u\n",
1479			 le32_to_cpu(tx->ack_or_ba_timeout_collision),
1480			 accum_tx->ack_or_ba_timeout_collision);
1481	pos += scnprintf(buf + pos, bufsz - pos,
1482			 "agg ba_timeout:\t\t\t%u\t\t\t%u\n",
1483			 le32_to_cpu(tx->agg.ba_timeout),
1484			 accum_tx->agg.ba_timeout);
1485	pos += scnprintf(buf + pos, bufsz - pos,
1486			"agg ba_resched_frames:\t\t%u\t\t\t%u\n",
1487			 le32_to_cpu(tx->agg.ba_reschedule_frames),
1488			 accum_tx->agg.ba_reschedule_frames);
1489	pos += scnprintf(buf + pos, bufsz - pos,
1490			"agg scd_query_agg_frame:\t%u\t\t\t%u\n",
1491			 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
1492			 accum_tx->agg.scd_query_agg_frame_cnt);
1493	pos += scnprintf(buf + pos, bufsz - pos,
1494			 "agg scd_query_no_agg:\t\t%u\t\t\t%u\n",
1495			 le32_to_cpu(tx->agg.scd_query_no_agg),
1496			 accum_tx->agg.scd_query_no_agg);
1497	pos += scnprintf(buf + pos, bufsz - pos,
1498			 "agg scd_query_agg:\t\t%u\t\t\t%u\n",
1499			 le32_to_cpu(tx->agg.scd_query_agg),
1500			 accum_tx->agg.scd_query_agg);
1501	pos += scnprintf(buf + pos, bufsz - pos,
1502			"agg scd_query_mismatch:\t\t%u\t\t\t%u\n",
1503			 le32_to_cpu(tx->agg.scd_query_mismatch),
1504			 accum_tx->agg.scd_query_mismatch);
1505	pos += scnprintf(buf + pos, bufsz - pos,
1506			 "agg frame_not_ready:\t\t%u\t\t\t%u\n",
1507			 le32_to_cpu(tx->agg.frame_not_ready),
1508			 accum_tx->agg.frame_not_ready);
1509	pos += scnprintf(buf + pos, bufsz - pos,
1510			 "agg underrun:\t\t\t%u\t\t\t%u\n",
1511			 le32_to_cpu(tx->agg.underrun),
1512			 accum_tx->agg.underrun);
1513	pos += scnprintf(buf + pos, bufsz - pos,
1514			 "agg bt_prio_kill:\t\t%u\t\t\t%u\n",
1515			 le32_to_cpu(tx->agg.bt_prio_kill),
1516			 accum_tx->agg.bt_prio_kill);
1517	pos += scnprintf(buf + pos, bufsz - pos,
1518			 "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n",
1519			 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
1520			 accum_tx->agg.rx_ba_rsp_cnt);
1521
1522	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1523	kfree(buf);
1524	return ret;
1525}
1526
1527static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1528					char __user *user_buf,
1529					size_t count, loff_t *ppos)
1530{
1531	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1532	int pos = 0;
1533	char *buf;
1534	int bufsz = sizeof(struct statistics_general) * 4 + 250;
1535	ssize_t ret;
1536	struct statistics_general *general, *accum_general;
1537	struct statistics_dbg *dbg, *accum_dbg;
1538	struct statistics_div *div, *accum_div;
1539
1540	if (!iwl_is_alive(priv))
1541		return -EAGAIN;
1542
1543	/* make request to uCode to retrieve statistics information */
1544	mutex_lock(&priv->mutex);
1545	ret = iwl_send_statistics_request(priv, 0);
1546	mutex_unlock(&priv->mutex);
1547
1548	if (ret) {
1549		IWL_ERR(priv,
1550			"Error sending statistics request: %zd\n", ret);
1551		return -EAGAIN;
1552	}
1553	buf = kzalloc(bufsz, GFP_KERNEL);
1554	if (!buf) {
1555		IWL_ERR(priv, "Can not allocate Buffer\n");
1556		return -ENOMEM;
1557	}
1558
1559	/* the statistic information display here is based on
1560	 * the last statistics notification from uCode
1561	 * might not reflect the current uCode activity
1562	 */
1563	general = &priv->statistics.general;
1564	dbg = &priv->statistics.general.dbg;
1565	div = &priv->statistics.general.div;
1566	accum_general = &priv->accum_statistics.general;
1567	accum_dbg = &priv->accum_statistics.general.dbg;
1568	accum_div = &priv->accum_statistics.general.div;
1569	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1570	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n");
1571	pos += scnprintf(buf + pos, bufsz - pos,
1572			"\t\t\tcurrent\t\t\taccumulative\n");
1573	pos += scnprintf(buf + pos, bufsz - pos, "temperature:\t\t\t%u\n",
1574			 le32_to_cpu(general->temperature));
1575	pos += scnprintf(buf + pos, bufsz - pos, "temperature_m:\t\t\t%u\n",
1576			 le32_to_cpu(general->temperature_m));
1577	pos += scnprintf(buf + pos, bufsz - pos,
1578			 "burst_check:\t\t\t%u\t\t\t%u\n",
1579			 le32_to_cpu(dbg->burst_check),
1580			 accum_dbg->burst_check);
1581	pos += scnprintf(buf + pos, bufsz - pos,
1582			 "burst_count:\t\t\t%u\t\t\t%u\n",
1583			 le32_to_cpu(dbg->burst_count),
1584			 accum_dbg->burst_count);
1585	pos += scnprintf(buf + pos, bufsz - pos,
1586			 "sleep_time:\t\t\t%u\t\t\t%u\n",
1587			 le32_to_cpu(general->sleep_time),
1588			 accum_general->sleep_time);
1589	pos += scnprintf(buf + pos, bufsz - pos,
1590			 "slots_out:\t\t\t%u\t\t\t%u\n",
1591			 le32_to_cpu(general->slots_out),
1592			 accum_general->slots_out);
1593	pos += scnprintf(buf + pos, bufsz - pos,
1594			 "slots_idle:\t\t\t%u\t\t\t%u\n",
1595			 le32_to_cpu(general->slots_idle),
1596			 accum_general->slots_idle);
1597	pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
1598			 le32_to_cpu(general->ttl_timestamp));
1599	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a:\t\t\t%u\t\t\t%u\n",
1600			 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a);
1601	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b:\t\t\t%u\t\t\t%u\n",
1602			 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b);
1603	pos += scnprintf(buf + pos, bufsz - pos,
1604			 "exec_time:\t\t\t%u\t\t\t%u\n",
1605			 le32_to_cpu(div->exec_time), accum_div->exec_time);
1606	pos += scnprintf(buf + pos, bufsz - pos,
1607			 "probe_time:\t\t\t%u\t\t\t%u\n",
1608			 le32_to_cpu(div->probe_time), accum_div->probe_time);
1609	pos += scnprintf(buf + pos, bufsz - pos,
1610			 "rx_enable_counter:\t\t%u\t\t\t%u\n",
1611			 le32_to_cpu(general->rx_enable_counter),
1612			 accum_general->rx_enable_counter);
1613	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1614	kfree(buf);
1615	return ret;
1616}
1617
1618static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
1619					char __user *user_buf,
1620					size_t count, loff_t *ppos) {
1621
1622	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1623	int pos = 0;
1624	int cnt = 0;
1625	char *buf;
1626	int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100;
1627	ssize_t ret;
1628	struct iwl_sensitivity_data *data;
1629
1630	data = &priv->sensitivity_data;
1631	buf = kzalloc(bufsz, GFP_KERNEL);
1632	if (!buf) {
1633		IWL_ERR(priv, "Can not allocate Buffer\n");
1634		return -ENOMEM;
1635	}
1636
1637	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
1638			data->auto_corr_ofdm);
1639	pos += scnprintf(buf + pos, bufsz - pos,
1640			"auto_corr_ofdm_mrc:\t\t %u\n",
1641			data->auto_corr_ofdm_mrc);
1642	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
1643			data->auto_corr_ofdm_x1);
1644	pos += scnprintf(buf + pos, bufsz - pos,
1645			"auto_corr_ofdm_mrc_x1:\t\t %u\n",
1646			data->auto_corr_ofdm_mrc_x1);
1647	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
1648			data->auto_corr_cck);
1649	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
1650			data->auto_corr_cck_mrc);
1651	pos += scnprintf(buf + pos, bufsz - pos,
1652			"last_bad_plcp_cnt_ofdm:\t\t %u\n",
1653			data->last_bad_plcp_cnt_ofdm);
1654	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
1655			data->last_fa_cnt_ofdm);
1656	pos += scnprintf(buf + pos, bufsz - pos,
1657			"last_bad_plcp_cnt_cck:\t\t %u\n",
1658			data->last_bad_plcp_cnt_cck);
1659	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
1660			data->last_fa_cnt_cck);
1661	pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
1662			data->nrg_curr_state);
1663	pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
1664			data->nrg_prev_state);
1665	pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
1666	for (cnt = 0; cnt < 10; cnt++) {
1667		pos += scnprintf(buf + pos, bufsz - pos, " %u",
1668				data->nrg_value[cnt]);
1669	}
1670	pos += scnprintf(buf + pos, bufsz - pos, "\n");
1671	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
1672	for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
1673		pos += scnprintf(buf + pos, bufsz - pos, " %u",
1674				data->nrg_silence_rssi[cnt]);
1675	}
1676	pos += scnprintf(buf + pos, bufsz - pos, "\n");
1677	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
1678			data->nrg_silence_ref);
1679	pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
1680			data->nrg_energy_idx);
1681	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
1682			data->nrg_silence_idx);
1683	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
1684			data->nrg_th_cck);
1685	pos += scnprintf(buf + pos, bufsz - pos,
1686			"nrg_auto_corr_silence_diff:\t %u\n",
1687			data->nrg_auto_corr_silence_diff);
1688	pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
1689			data->num_in_cck_no_fa);
1690	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
1691			data->nrg_th_ofdm);
1692
1693	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1694	kfree(buf);
1695	return ret;
1696}
1697
1698
1699static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
1700					char __user *user_buf,
1701					size_t count, loff_t *ppos) {
1702
1703	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1704	int pos = 0;
1705	int cnt = 0;
1706	char *buf;
1707	int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100;
1708	ssize_t ret;
1709	struct iwl_chain_noise_data *data;
1710
1711	data = &priv->chain_noise_data;
1712	buf = kzalloc(bufsz, GFP_KERNEL);
1713	if (!buf) {
1714		IWL_ERR(priv, "Can not allocate Buffer\n");
1715		return -ENOMEM;
1716	}
1717
1718	pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
1719			data->active_chains);
1720	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
1721			data->chain_noise_a);
1722	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
1723			data->chain_noise_b);
1724	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
1725			data->chain_noise_c);
1726	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
1727			data->chain_signal_a);
1728	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
1729			data->chain_signal_b);
1730	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
1731			data->chain_signal_c);
1732	pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
1733			data->beacon_count);
1734
1735	pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
1736	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
1737		pos += scnprintf(buf + pos, bufsz - pos, " %u",
1738				data->disconn_array[cnt]);
1739	}
1740	pos += scnprintf(buf + pos, bufsz - pos, "\n");
1741	pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
1742	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
1743		pos += scnprintf(buf + pos, bufsz - pos, " %u",
1744				data->delta_gain_code[cnt]);
1745	}
1746	pos += scnprintf(buf + pos, bufsz - pos, "\n");
1747	pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
1748			data->radio_write);
1749	pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
1750			data->state);
1751
1752	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1753	kfree(buf);
1754	return ret;
1755}
1756
1757static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
1758					char __user *user_buf,
1759					size_t count, loff_t *ppos) {
1760
1761	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1762	char buf[128];
1763	int pos = 0;
1764	ssize_t ret;
1765	const size_t bufsz = sizeof(buf);
1766	struct statistics_tx *tx;
1767
1768	if (!iwl_is_alive(priv))
1769		pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1770	else {
1771		/* make request to uCode to retrieve statistics information */
1772		mutex_lock(&priv->mutex);
1773		ret = iwl_send_statistics_request(priv, 0);
1774		mutex_unlock(&priv->mutex);
1775
1776		if (ret) {
1777			IWL_ERR(priv, "Error sending statistics request: %zd\n",
1778				ret);
1779			return -EAGAIN;
1780		}
1781		tx = &priv->statistics.tx;
1782		if (tx->tx_power.ant_a ||
1783		    tx->tx_power.ant_b ||
1784		    tx->tx_power.ant_c) {
1785			pos += scnprintf(buf + pos, bufsz - pos,
1786				"tx power: (1/2 dB step)\n");
1787			if ((priv->cfg->valid_tx_ant & ANT_A) &&
1788			    tx->tx_power.ant_a)
1789				pos += scnprintf(buf + pos, bufsz - pos,
1790						"\tantenna A: 0x%X\n",
1791						tx->tx_power.ant_a);
1792			if ((priv->cfg->valid_tx_ant & ANT_B) &&
1793			    tx->tx_power.ant_b)
1794				pos += scnprintf(buf + pos, bufsz - pos,
1795						"\tantenna B: 0x%X\n",
1796						tx->tx_power.ant_b);
1797			if ((priv->cfg->valid_tx_ant & ANT_C) &&
1798			    tx->tx_power.ant_c)
1799				pos += scnprintf(buf + pos, bufsz - pos,
1800						"\tantenna C: 0x%X\n",
1801						tx->tx_power.ant_c);
1802		} else
1803			pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1804	}
1805	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1806}
1807
1808static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
1809						    char __user *user_buf,
1810						    size_t count, loff_t *ppos)
1811{
1812	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1813	char buf[60];
1814	int pos = 0;
1815	const size_t bufsz = sizeof(buf);
1816	u32 pwrsave_status;
1817
1818	pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) &
1819			CSR_GP_REG_POWER_SAVE_STATUS_MSK;
1820
1821	pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
1822	pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
1823		(pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1824		(pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1825		(pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1826		"error");
1827
1828	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1829}
1830
1831DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics);
1832DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics);
1833DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
1834DEBUGFS_READ_FILE_OPS(rx_queue);
1835DEBUGFS_READ_FILE_OPS(tx_queue);
1836DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1837DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1838DEBUGFS_READ_FILE_OPS(ucode_general_stats);
1839DEBUGFS_READ_FILE_OPS(sensitivity);
1840DEBUGFS_READ_FILE_OPS(chain_noise);
1841DEBUGFS_READ_FILE_OPS(tx_power);
1842DEBUGFS_READ_FILE_OPS(power_save_status);
1843
1844/*
1845 * Create the debugfs files and directories
1846 *
1847 */
1848int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1849{
1850	struct iwl_debugfs *dbgfs;
1851	struct dentry *phyd = priv->hw->wiphy->debugfsdir;
1852	int ret = 0;
1853
1854	dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL);
1855	if (!dbgfs) {
1856		ret = -ENOMEM;
1857		goto err;
1858	}
1859
1860	priv->dbgfs = dbgfs;
1861	dbgfs->name = name;
1862	dbgfs->dir_drv = debugfs_create_dir(name, phyd);
1863	if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) {
1864		ret = -ENOENT;
1865		goto err;
1866	}
1867
1868	DEBUGFS_ADD_DIR(data, dbgfs->dir_drv);
1869	DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv);
1870	DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv);
1871	DEBUGFS_ADD_FILE(nvm, data);
1872	DEBUGFS_ADD_FILE(sram, data);
1873	DEBUGFS_ADD_FILE(log_event, data);
1874	DEBUGFS_ADD_FILE(stations, data);
1875	DEBUGFS_ADD_FILE(channels, data);
1876	DEBUGFS_ADD_FILE(status, data);
1877	DEBUGFS_ADD_FILE(interrupt, data);
1878	DEBUGFS_ADD_FILE(qos, data);
1879	DEBUGFS_ADD_FILE(led, data);
1880	DEBUGFS_ADD_FILE(sleep_level_override, data);
1881	DEBUGFS_ADD_FILE(current_sleep_command, data);
1882	DEBUGFS_ADD_FILE(thermal_throttling, data);
1883	DEBUGFS_ADD_FILE(disable_ht40, data);
1884	DEBUGFS_ADD_FILE(rx_statistics, debug);
1885	DEBUGFS_ADD_FILE(tx_statistics, debug);
1886	DEBUGFS_ADD_FILE(traffic_log, debug);
1887	DEBUGFS_ADD_FILE(rx_queue, debug);
1888	DEBUGFS_ADD_FILE(tx_queue, debug);
1889	DEBUGFS_ADD_FILE(tx_power, debug);
1890	DEBUGFS_ADD_FILE(power_save_status, debug);
1891	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1892		DEBUGFS_ADD_FILE(ucode_rx_stats, debug);
1893		DEBUGFS_ADD_FILE(ucode_tx_stats, debug);
1894		DEBUGFS_ADD_FILE(ucode_general_stats, debug);
1895		DEBUGFS_ADD_FILE(sensitivity, debug);
1896		DEBUGFS_ADD_FILE(chain_noise, debug);
1897	}
1898	DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
1899	DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
1900			 &priv->disable_chain_noise_cal);
1901	if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
1902	    ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
1903		DEBUGFS_ADD_BOOL(disable_tx_power, rf,
1904				&priv->disable_tx_power_cal);
1905	return 0;
1906
1907err:
1908	IWL_ERR(priv, "Can't open the debugfs directory\n");
1909	iwl_dbgfs_unregister(priv);
1910	return ret;
1911}
1912EXPORT_SYMBOL(iwl_dbgfs_register);
1913
1914/**
1915 * Remove the debugfs files and directories
1916 *
1917 */
1918void iwl_dbgfs_unregister(struct iwl_priv *priv)
1919{
1920	if (!priv->dbgfs)
1921		return;
1922
1923	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sleep_level_override);
1924	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_current_sleep_command);
1925	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
1926	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
1927	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
1928	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
1929	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
1930	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
1931	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
1932	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos);
1933	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
1934	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
1935	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
1936	DEBUGFS_REMOVE(priv->dbgfs->dir_data);
1937	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_statistics);
1938	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_statistics);
1939	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log);
1940	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue);
1941	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue);
1942	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power);
1943	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status);
1944	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1945		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1946			file_ucode_rx_stats);
1947		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1948			file_ucode_tx_stats);
1949		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1950			file_ucode_general_stats);
1951		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1952			file_sensitivity);
1953		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1954			file_chain_noise);
1955	}
1956	DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
1957	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
1958	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
1959	if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
1960	    ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
1961		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
1962	DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
1963	DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
1964	kfree(priv->dbgfs);
1965	priv->dbgfs = NULL;
1966}
1967EXPORT_SYMBOL(iwl_dbgfs_unregister);
1968
1969
1970
1971