iwl-debugfs.c revision c09430abed4159e5c56aaea257d040f7452daba6
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	priv->power_data.debug_sleep_level_override = value;
813
814	iwl_power_update_mode(priv, false);
815
816	return count;
817}
818
819static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
820						   char __user *user_buf,
821						   size_t count, loff_t *ppos)
822{
823	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
824	char buf[10];
825	int pos, value;
826	const size_t bufsz = sizeof(buf);
827
828	/* see the write function */
829	value = priv->power_data.debug_sleep_level_override;
830	if (value >= 0)
831		value += 1;
832
833	pos = scnprintf(buf, bufsz, "%d\n", value);
834	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
835}
836
837static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
838						    char __user *user_buf,
839						    size_t count, loff_t *ppos)
840{
841	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
842	char buf[200];
843	int pos = 0, i;
844	const size_t bufsz = sizeof(buf);
845	struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd;
846
847	pos += scnprintf(buf + pos, bufsz - pos,
848			 "flags: %#.2x\n", le16_to_cpu(cmd->flags));
849	pos += scnprintf(buf + pos, bufsz - pos,
850			 "RX/TX timeout: %d/%d usec\n",
851			 le32_to_cpu(cmd->rx_data_timeout),
852			 le32_to_cpu(cmd->tx_data_timeout));
853	for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
854		pos += scnprintf(buf + pos, bufsz - pos,
855				 "sleep_interval[%d]: %d\n", i,
856				 le32_to_cpu(cmd->sleep_interval[i]));
857
858	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
859}
860
861DEBUGFS_READ_WRITE_FILE_OPS(sram);
862DEBUGFS_WRITE_FILE_OPS(log_event);
863DEBUGFS_READ_FILE_OPS(nvm);
864DEBUGFS_READ_FILE_OPS(stations);
865DEBUGFS_READ_FILE_OPS(channels);
866DEBUGFS_READ_FILE_OPS(status);
867DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
868DEBUGFS_READ_FILE_OPS(qos);
869DEBUGFS_READ_FILE_OPS(led);
870DEBUGFS_READ_FILE_OPS(thermal_throttling);
871DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
872DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
873DEBUGFS_READ_FILE_OPS(current_sleep_command);
874
875static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
876					 char __user *user_buf,
877					 size_t count, loff_t *ppos)
878{
879	struct iwl_priv *priv = file->private_data;
880	int pos = 0, ofs = 0;
881	int cnt = 0, entry;
882	struct iwl_tx_queue *txq;
883	struct iwl_queue *q;
884	struct iwl_rx_queue *rxq = &priv->rxq;
885	char *buf;
886	int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
887		(priv->cfg->num_of_queues * 32 * 8) + 400;
888	const u8 *ptr;
889	ssize_t ret;
890
891	if (!priv->txq) {
892		IWL_ERR(priv, "txq not ready\n");
893		return -EAGAIN;
894	}
895	buf = kzalloc(bufsz, GFP_KERNEL);
896	if (!buf) {
897		IWL_ERR(priv, "Can not allocate buffer\n");
898		return -ENOMEM;
899	}
900	pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
901	for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
902		txq = &priv->txq[cnt];
903		q = &txq->q;
904		pos += scnprintf(buf + pos, bufsz - pos,
905				"q[%d]: read_ptr: %u, write_ptr: %u\n",
906				cnt, q->read_ptr, q->write_ptr);
907	}
908	if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) {
909		ptr = priv->tx_traffic;
910		pos += scnprintf(buf + pos, bufsz - pos,
911				"Tx Traffic idx: %u\n",	priv->tx_traffic_idx);
912		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
913			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
914			     entry++,  ofs += 16) {
915				pos += scnprintf(buf + pos, bufsz - pos,
916						"0x%.4x ", ofs);
917				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
918						   buf + pos, bufsz - pos, 0);
919				pos += strlen(buf + pos);
920				if (bufsz - pos > 0)
921					buf[pos++] = '\n';
922			}
923		}
924	}
925
926	pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
927	pos += scnprintf(buf + pos, bufsz - pos,
928			"read: %u, write: %u\n",
929			 rxq->read, rxq->write);
930
931	if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) {
932		ptr = priv->rx_traffic;
933		pos += scnprintf(buf + pos, bufsz - pos,
934				"Rx Traffic idx: %u\n",	priv->rx_traffic_idx);
935		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
936			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
937			     entry++,  ofs += 16) {
938				pos += scnprintf(buf + pos, bufsz - pos,
939						"0x%.4x ", ofs);
940				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
941						   buf + pos, bufsz - pos, 0);
942				pos += strlen(buf + pos);
943				if (bufsz - pos > 0)
944					buf[pos++] = '\n';
945			}
946		}
947	}
948
949	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
950	kfree(buf);
951	return ret;
952}
953
954static ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
955					 const char __user *user_buf,
956					 size_t count, loff_t *ppos)
957{
958	struct iwl_priv *priv = file->private_data;
959	char buf[8];
960	int buf_size;
961	int traffic_log;
962
963	memset(buf, 0, sizeof(buf));
964	buf_size = min(count, sizeof(buf) -  1);
965	if (copy_from_user(buf, user_buf, buf_size))
966		return -EFAULT;
967	if (sscanf(buf, "%d", &traffic_log) != 1)
968		return -EFAULT;
969	if (traffic_log == 0)
970		iwl_reset_traffic_log(priv);
971
972	return count;
973}
974
975static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
976						char __user *user_buf,
977						size_t count, loff_t *ppos) {
978
979	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
980	struct iwl_tx_queue *txq;
981	struct iwl_queue *q;
982	char *buf;
983	int pos = 0;
984	int cnt;
985	int ret;
986	const size_t bufsz = sizeof(char) * 60 * priv->cfg->num_of_queues;
987
988	if (!priv->txq) {
989		IWL_ERR(priv, "txq not ready\n");
990		return -EAGAIN;
991	}
992	buf = kzalloc(bufsz, GFP_KERNEL);
993	if (!buf)
994		return -ENOMEM;
995
996	for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
997		txq = &priv->txq[cnt];
998		q = &txq->q;
999		pos += scnprintf(buf + pos, bufsz - pos,
1000				"hwq %.2d: read=%u write=%u stop=%d"
1001				" swq_id=%#.2x (ac %d/hwq %d)\n",
1002				cnt, q->read_ptr, q->write_ptr,
1003				!!test_bit(cnt, priv->queue_stopped),
1004				txq->swq_id,
1005				txq->swq_id & 0x80 ? txq->swq_id & 3 :
1006				txq->swq_id,
1007				txq->swq_id & 0x80 ? (txq->swq_id >> 2) &
1008				0x1f : txq->swq_id);
1009		if (cnt >= 4)
1010			continue;
1011		/* for the ACs, display the stop count too */
1012		pos += scnprintf(buf + pos, bufsz - pos,
1013				"        stop-count: %d\n",
1014				atomic_read(&priv->queue_stop_count[cnt]));
1015	}
1016	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1017	kfree(buf);
1018	return ret;
1019}
1020
1021static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1022						char __user *user_buf,
1023						size_t count, loff_t *ppos) {
1024
1025	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1026	struct iwl_rx_queue *rxq = &priv->rxq;
1027	char buf[256];
1028	int pos = 0;
1029	const size_t bufsz = sizeof(buf);
1030
1031	pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
1032						rxq->read);
1033	pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
1034						rxq->write);
1035	pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
1036						rxq->free_count);
1037	pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
1038			 le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF);
1039	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1040}
1041
1042#define UCODE_STATISTICS_CLEAR_MSK		(0x1 << 0)
1043#define UCODE_STATISTICS_FREQUENCY_MSK		(0x1 << 1)
1044#define UCODE_STATISTICS_NARROW_BAND_MSK	(0x1 << 2)
1045
1046static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
1047				     int bufsz)
1048{
1049	int p = 0;
1050
1051	p += scnprintf(buf + p, bufsz - p,
1052		"Statistics Flag(0x%X):\n",
1053		le32_to_cpu(priv->statistics.flag));
1054	if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
1055		p += scnprintf(buf + p, bufsz - p,
1056		"\tStatistics have been cleared\n");
1057	p += scnprintf(buf + p, bufsz - p,
1058		"\tOperational Frequency: %s\n",
1059		(le32_to_cpu(priv->statistics.flag) &
1060		UCODE_STATISTICS_FREQUENCY_MSK)
1061		 ? "2.4 GHz" : "5.2 GHz");
1062	p += scnprintf(buf + p, bufsz - p,
1063		"\tTGj Narrow Band: %s\n",
1064		(le32_to_cpu(priv->statistics.flag) &
1065		UCODE_STATISTICS_NARROW_BAND_MSK)
1066		 ? "enabled" : "disabled");
1067	return p;
1068}
1069
1070
1071static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1072					char __user *user_buf,
1073					size_t count, loff_t *ppos)
1074{
1075	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1076	int pos = 0;
1077	char *buf;
1078	int bufsz = sizeof(struct statistics_rx_phy) * 20 +
1079		sizeof(struct statistics_rx_non_phy) * 20 +
1080		sizeof(struct statistics_rx_ht_phy) * 20 + 400;
1081	ssize_t ret;
1082	struct statistics_rx_phy *ofdm, *accum_ofdm;
1083	struct statistics_rx_phy *cck, *accum_cck;
1084	struct statistics_rx_non_phy *general, *accum_general;
1085	struct statistics_rx_ht_phy *ht, *accum_ht;
1086
1087	if (!iwl_is_alive(priv))
1088		return -EAGAIN;
1089
1090	/* make request to uCode to retrieve statistics information */
1091	mutex_lock(&priv->mutex);
1092	ret = iwl_send_statistics_request(priv, 0);
1093	mutex_unlock(&priv->mutex);
1094
1095	if (ret) {
1096		IWL_ERR(priv,
1097			"Error sending statistics request: %zd\n", ret);
1098		return -EAGAIN;
1099	}
1100	buf = kzalloc(bufsz, GFP_KERNEL);
1101	if (!buf) {
1102		IWL_ERR(priv, "Can not allocate Buffer\n");
1103		return -ENOMEM;
1104	}
1105
1106	/* the statistic information display here is based on
1107	 * the last statistics notification from uCode
1108	 * might not reflect the current uCode activity
1109	 */
1110	ofdm = &priv->statistics.rx.ofdm;
1111	cck = &priv->statistics.rx.cck;
1112	general = &priv->statistics.rx.general;
1113	ht = &priv->statistics.rx.ofdm_ht;
1114	accum_ofdm = &priv->accum_statistics.rx.ofdm;
1115	accum_cck = &priv->accum_statistics.rx.cck;
1116	accum_general = &priv->accum_statistics.rx.general;
1117	accum_ht = &priv->accum_statistics.rx.ofdm_ht;
1118	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1119	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n");
1120	pos += scnprintf(buf + pos, bufsz - pos,
1121			"\t\t\tcurrent\t\t\taccumulative\n");
1122	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n",
1123			 le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt);
1124	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n",
1125			 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt);
1126	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
1127			 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err);
1128	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
1129			 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err);
1130	pos += scnprintf(buf + pos, bufsz - pos,
1131			 "overrun_err:\t\t%u\t\t\t%u\n",
1132			 le32_to_cpu(ofdm->overrun_err),
1133			 accum_ofdm->overrun_err);
1134	pos += scnprintf(buf + pos, bufsz - pos,
1135			 "early_overrun_err:\t%u\t\t\t%u\n",
1136			 le32_to_cpu(ofdm->early_overrun_err),
1137			 accum_ofdm->early_overrun_err);
1138	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
1139			 le32_to_cpu(ofdm->crc32_good),
1140			 accum_ofdm->crc32_good);
1141	pos += scnprintf(buf + pos, bufsz - pos,
1142			 "false_alarm_cnt:\t%u\t\t\t%u\n",
1143			 le32_to_cpu(ofdm->false_alarm_cnt),
1144			 accum_ofdm->false_alarm_cnt);
1145	pos += scnprintf(buf + pos, bufsz - pos,
1146			 "fina_sync_err_cnt:\t%u\t\t\t%u\n",
1147			 le32_to_cpu(ofdm->fina_sync_err_cnt),
1148			 accum_ofdm->fina_sync_err_cnt);
1149	pos += scnprintf(buf + pos, bufsz - pos,
1150			 "sfd_timeout:\t\t%u\t\t\t%u\n",
1151			 le32_to_cpu(ofdm->sfd_timeout),
1152			 accum_ofdm->sfd_timeout);
1153	pos += scnprintf(buf + pos, bufsz - pos,
1154			 "fina_timeout:\t\t%u\t\t\t%u\n",
1155			 le32_to_cpu(ofdm->fina_timeout),
1156			 accum_ofdm->fina_timeout);
1157	pos += scnprintf(buf + pos, bufsz - pos,
1158			 "unresponded_rts:\t%u\t\t\t%u\n",
1159			 le32_to_cpu(ofdm->unresponded_rts),
1160			 accum_ofdm->unresponded_rts);
1161	pos += scnprintf(buf + pos, bufsz - pos,
1162			"rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n",
1163			 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
1164			 accum_ofdm->rxe_frame_limit_overrun);
1165	pos += scnprintf(buf + pos, bufsz - pos,
1166			 "sent_ack_cnt:\t\t%u\t\t\t%u\n",
1167			 le32_to_cpu(ofdm->sent_ack_cnt),
1168			 accum_ofdm->sent_ack_cnt);
1169	pos += scnprintf(buf + pos, bufsz - pos,
1170			 "sent_cts_cnt:\t\t%u\t\t\t%u\n",
1171			 le32_to_cpu(ofdm->sent_cts_cnt),
1172			 accum_ofdm->sent_cts_cnt);
1173	pos += scnprintf(buf + pos, bufsz - pos,
1174			 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n",
1175			 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
1176			 accum_ofdm->sent_ba_rsp_cnt);
1177	pos += scnprintf(buf + pos, bufsz - pos,
1178			 "dsp_self_kill:\t\t%u\t\t\t%u\n",
1179			 le32_to_cpu(ofdm->dsp_self_kill),
1180			 accum_ofdm->dsp_self_kill);
1181	pos += scnprintf(buf + pos, bufsz - pos,
1182			 "mh_format_err:\t\t%u\t\t\t%u\n",
1183			 le32_to_cpu(ofdm->mh_format_err),
1184			 accum_ofdm->mh_format_err);
1185	pos += scnprintf(buf + pos, bufsz - pos,
1186			 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n",
1187			 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
1188			 accum_ofdm->re_acq_main_rssi_sum);
1189
1190	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n");
1191	pos += scnprintf(buf + pos, bufsz - pos,
1192			"\t\t\tcurrent\t\t\taccumulative\n");
1193	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n",
1194			 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt);
1195	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n",
1196			 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt);
1197	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
1198			 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err);
1199	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
1200			 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err);
1201	pos += scnprintf(buf + pos, bufsz - pos,
1202			 "overrun_err:\t\t%u\t\t\t%u\n",
1203			 le32_to_cpu(cck->overrun_err),
1204			 accum_cck->overrun_err);
1205	pos += scnprintf(buf + pos, bufsz - pos,
1206			 "early_overrun_err:\t%u\t\t\t%u\n",
1207			 le32_to_cpu(cck->early_overrun_err),
1208			 accum_cck->early_overrun_err);
1209	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
1210			 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good);
1211	pos += scnprintf(buf + pos, bufsz - pos,
1212			 "false_alarm_cnt:\t%u\t\t\t%u\n",
1213			 le32_to_cpu(cck->false_alarm_cnt),
1214			 accum_cck->false_alarm_cnt);
1215	pos += scnprintf(buf + pos, bufsz - pos,
1216			 "fina_sync_err_cnt:\t%u\t\t\t%u\n",
1217			 le32_to_cpu(cck->fina_sync_err_cnt),
1218			 accum_cck->fina_sync_err_cnt);
1219	pos += scnprintf(buf + pos, bufsz - pos,
1220			 "sfd_timeout:\t\t%u\t\t\t%u\n",
1221			 le32_to_cpu(cck->sfd_timeout),
1222			 accum_cck->sfd_timeout);
1223	pos += scnprintf(buf + pos, bufsz - pos,
1224			 "fina_timeout:\t\t%u\t\t\t%u\n",
1225			 le32_to_cpu(cck->fina_timeout),
1226			 accum_cck->fina_timeout);
1227	pos += scnprintf(buf + pos, bufsz - pos,
1228			 "unresponded_rts:\t%u\t\t\t%u\n",
1229			 le32_to_cpu(cck->unresponded_rts),
1230			 accum_cck->unresponded_rts);
1231	pos += scnprintf(buf + pos, bufsz - pos,
1232			"rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n",
1233			 le32_to_cpu(cck->rxe_frame_limit_overrun),
1234			 accum_cck->rxe_frame_limit_overrun);
1235	pos += scnprintf(buf + pos, bufsz - pos,
1236			 "sent_ack_cnt:\t\t%u\t\t\t%u\n",
1237			 le32_to_cpu(cck->sent_ack_cnt),
1238			 accum_cck->sent_ack_cnt);
1239	pos += scnprintf(buf + pos, bufsz - pos,
1240			 "sent_cts_cnt:\t\t%u\t\t\t%u\n",
1241			 le32_to_cpu(cck->sent_cts_cnt),
1242			 accum_cck->sent_cts_cnt);
1243	pos += scnprintf(buf + pos, bufsz - pos,
1244			 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n",
1245			 le32_to_cpu(cck->sent_ba_rsp_cnt),
1246			 accum_cck->sent_ba_rsp_cnt);
1247	pos += scnprintf(buf + pos, bufsz - pos,
1248			 "dsp_self_kill:\t\t%u\t\t\t%u\n",
1249			 le32_to_cpu(cck->dsp_self_kill),
1250			 accum_cck->dsp_self_kill);
1251	pos += scnprintf(buf + pos, bufsz - pos,
1252			 "mh_format_err:\t\t%u\t\t\t%u\n",
1253			 le32_to_cpu(cck->mh_format_err),
1254			 accum_cck->mh_format_err);
1255	pos += scnprintf(buf + pos, bufsz - pos,
1256			 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n",
1257			 le32_to_cpu(cck->re_acq_main_rssi_sum),
1258			 accum_cck->re_acq_main_rssi_sum);
1259
1260	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n");
1261	pos += scnprintf(buf + pos, bufsz - pos,
1262			"\t\t\tcurrent\t\t\taccumulative\n");
1263	pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts:\t\t%u\t\t\t%u\n",
1264			 le32_to_cpu(general->bogus_cts),
1265			 accum_general->bogus_cts);
1266	pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack:\t\t%u\t\t\t%u\n",
1267			 le32_to_cpu(general->bogus_ack),
1268			 accum_general->bogus_ack);
1269	pos += scnprintf(buf + pos, bufsz - pos,
1270			 "non_bssid_frames:\t%u\t\t\t%u\n",
1271			 le32_to_cpu(general->non_bssid_frames),
1272			 accum_general->non_bssid_frames);
1273	pos += scnprintf(buf + pos, bufsz - pos,
1274			 "filtered_frames:\t%u\t\t\t%u\n",
1275			 le32_to_cpu(general->filtered_frames),
1276			 accum_general->filtered_frames);
1277	pos += scnprintf(buf + pos, bufsz - pos,
1278			 "non_channel_beacons:\t%u\t\t\t%u\n",
1279			 le32_to_cpu(general->non_channel_beacons),
1280			 accum_general->non_channel_beacons);
1281	pos += scnprintf(buf + pos, bufsz - pos,
1282			 "channel_beacons:\t%u\t\t\t%u\n",
1283			 le32_to_cpu(general->channel_beacons),
1284			 accum_general->channel_beacons);
1285	pos += scnprintf(buf + pos, bufsz - pos,
1286			 "num_missed_bcon:\t%u\t\t\t%u\n",
1287			 le32_to_cpu(general->num_missed_bcon),
1288			 accum_general->num_missed_bcon);
1289	pos += scnprintf(buf + pos, bufsz - pos,
1290			"adc_rx_saturation_time:\t%u\t\t\t%u\n",
1291			 le32_to_cpu(general->adc_rx_saturation_time),
1292			 accum_general->adc_rx_saturation_time);
1293	pos += scnprintf(buf + pos, bufsz - pos,
1294			"ina_detect_search_tm:\t%u\t\t\t%u\n",
1295			 le32_to_cpu(general->ina_detection_search_time),
1296			 accum_general->ina_detection_search_time);
1297	pos += scnprintf(buf + pos, bufsz - pos,
1298			 "beacon_silence_rssi_a:\t%u\t\t\t%u\n",
1299			 le32_to_cpu(general->beacon_silence_rssi_a),
1300			 accum_general->beacon_silence_rssi_a);
1301	pos += scnprintf(buf + pos, bufsz - pos,
1302			 "beacon_silence_rssi_b:\t%u\t\t\t%u\n",
1303			 le32_to_cpu(general->beacon_silence_rssi_b),
1304			 accum_general->beacon_silence_rssi_b);
1305	pos += scnprintf(buf + pos, bufsz - pos,
1306			 "beacon_silence_rssi_c:\t%u\t\t\t%u\n",
1307			 le32_to_cpu(general->beacon_silence_rssi_c),
1308			 accum_general->beacon_silence_rssi_c);
1309	pos += scnprintf(buf + pos, bufsz - pos,
1310			"interference_data_flag:\t%u\t\t\t%u\n",
1311			 le32_to_cpu(general->interference_data_flag),
1312			 accum_general->interference_data_flag);
1313	pos += scnprintf(buf + pos, bufsz - pos,
1314			 "channel_load:\t\t%u\t\t\t%u\n",
1315			 le32_to_cpu(general->channel_load),
1316			 accum_general->channel_load);
1317	pos += scnprintf(buf + pos, bufsz - pos,
1318			 "dsp_false_alarms:\t%u\t\t\t%u\n",
1319			 le32_to_cpu(general->dsp_false_alarms),
1320			 accum_general->dsp_false_alarms);
1321	pos += scnprintf(buf + pos, bufsz - pos,
1322			 "beacon_rssi_a:\t\t%u\t\t\t%u\n",
1323			 le32_to_cpu(general->beacon_rssi_a),
1324			 accum_general->beacon_rssi_a);
1325	pos += scnprintf(buf + pos, bufsz - pos,
1326			 "beacon_rssi_b:\t\t%u\t\t\t%u\n",
1327			 le32_to_cpu(general->beacon_rssi_b),
1328			 accum_general->beacon_rssi_b);
1329	pos += scnprintf(buf + pos, bufsz - pos,
1330			 "beacon_rssi_c:\t\t%u\t\t\t%u\n",
1331			 le32_to_cpu(general->beacon_rssi_c),
1332			 accum_general->beacon_rssi_c);
1333	pos += scnprintf(buf + pos, bufsz - pos,
1334			 "beacon_energy_a:\t%u\t\t\t%u\n",
1335			 le32_to_cpu(general->beacon_energy_a),
1336			 accum_general->beacon_energy_a);
1337	pos += scnprintf(buf + pos, bufsz - pos,
1338			 "beacon_energy_b:\t%u\t\t\t%u\n",
1339			 le32_to_cpu(general->beacon_energy_b),
1340			 accum_general->beacon_energy_b);
1341	pos += scnprintf(buf + pos, bufsz - pos,
1342			 "beacon_energy_c:\t%u\t\t\t%u\n",
1343			 le32_to_cpu(general->beacon_energy_c),
1344			 accum_general->beacon_energy_c);
1345
1346	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
1347	pos += scnprintf(buf + pos, bufsz - pos,
1348			"\t\t\tcurrent\t\t\taccumulative\n");
1349	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n",
1350			 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err);
1351	pos += scnprintf(buf + pos, bufsz - pos,
1352			 "overrun_err:\t\t%u\t\t\t%u\n",
1353			 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err);
1354	pos += scnprintf(buf + pos, bufsz - pos,
1355			 "early_overrun_err:\t%u\t\t\t%u\n",
1356			 le32_to_cpu(ht->early_overrun_err),
1357			 accum_ht->early_overrun_err);
1358	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n",
1359			 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good);
1360	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n",
1361			 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err);
1362	pos += scnprintf(buf + pos, bufsz - pos,
1363			 "mh_format_err:\t\t%u\t\t\t%u\n",
1364			 le32_to_cpu(ht->mh_format_err),
1365			 accum_ht->mh_format_err);
1366	pos += scnprintf(buf + pos, bufsz - pos,
1367			 "agg_crc32_good:\t\t%u\t\t\t%u\n",
1368			 le32_to_cpu(ht->agg_crc32_good),
1369			 accum_ht->agg_crc32_good);
1370	pos += scnprintf(buf + pos, bufsz - pos,
1371			 "agg_mpdu_cnt:\t\t%u\t\t\t%u\n",
1372			 le32_to_cpu(ht->agg_mpdu_cnt),
1373			 accum_ht->agg_mpdu_cnt);
1374	pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n",
1375			 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt);
1376
1377	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1378	kfree(buf);
1379	return ret;
1380}
1381
1382static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1383					char __user *user_buf,
1384					size_t count, loff_t *ppos)
1385{
1386	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1387	int pos = 0;
1388	char *buf;
1389	int bufsz = (sizeof(struct statistics_tx) * 24) + 250;
1390	ssize_t ret;
1391	struct statistics_tx *tx, *accum_tx;
1392
1393	if (!iwl_is_alive(priv))
1394		return -EAGAIN;
1395
1396	/* make request to uCode to retrieve statistics information */
1397	mutex_lock(&priv->mutex);
1398	ret = iwl_send_statistics_request(priv, 0);
1399	mutex_unlock(&priv->mutex);
1400
1401	if (ret) {
1402		IWL_ERR(priv,
1403			"Error sending statistics request: %zd\n", ret);
1404		return -EAGAIN;
1405	}
1406	buf = kzalloc(bufsz, GFP_KERNEL);
1407	if (!buf) {
1408		IWL_ERR(priv, "Can not allocate Buffer\n");
1409		return -ENOMEM;
1410	}
1411
1412	/* the statistic information display here is based on
1413	 * the last statistics notification from uCode
1414	 * might not reflect the current uCode activity
1415	 */
1416	tx = &priv->statistics.tx;
1417	accum_tx = &priv->accum_statistics.tx;
1418	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1419	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n");
1420	pos += scnprintf(buf + pos, bufsz - pos,
1421			"\t\t\tcurrent\t\t\taccumulative\n");
1422	pos += scnprintf(buf + pos, bufsz - pos, "preamble:\t\t\t%u\t\t\t%u\n",
1423			 le32_to_cpu(tx->preamble_cnt),
1424			 accum_tx->preamble_cnt);
1425	pos += scnprintf(buf + pos, bufsz - pos,
1426			 "rx_detected_cnt:\t\t%u\t\t\t%u\n",
1427			 le32_to_cpu(tx->rx_detected_cnt),
1428			 accum_tx->rx_detected_cnt);
1429	pos += scnprintf(buf + pos, bufsz - pos,
1430			 "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n",
1431			 le32_to_cpu(tx->bt_prio_defer_cnt),
1432			 accum_tx->bt_prio_defer_cnt);
1433	pos += scnprintf(buf + pos, bufsz - pos,
1434			 "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n",
1435			 le32_to_cpu(tx->bt_prio_kill_cnt),
1436			 accum_tx->bt_prio_kill_cnt);
1437	pos += scnprintf(buf + pos, bufsz - pos,
1438			 "few_bytes_cnt:\t\t\t%u\t\t\t%u\n",
1439			 le32_to_cpu(tx->few_bytes_cnt),
1440			 accum_tx->few_bytes_cnt);
1441	pos += scnprintf(buf + pos, bufsz - pos,
1442			 "cts_timeout:\t\t\t%u\t\t\t%u\n",
1443			 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout);
1444	pos += scnprintf(buf + pos, bufsz - pos,
1445			 "ack_timeout:\t\t\t%u\t\t\t%u\n",
1446			 le32_to_cpu(tx->ack_timeout),
1447			 accum_tx->ack_timeout);
1448	pos += scnprintf(buf + pos, bufsz - pos,
1449			 "expected_ack_cnt:\t\t%u\t\t\t%u\n",
1450			 le32_to_cpu(tx->expected_ack_cnt),
1451			 accum_tx->expected_ack_cnt);
1452	pos += scnprintf(buf + pos, bufsz - pos,
1453			 "actual_ack_cnt:\t\t\t%u\t\t\t%u\n",
1454			 le32_to_cpu(tx->actual_ack_cnt),
1455			 accum_tx->actual_ack_cnt);
1456	pos += scnprintf(buf + pos, bufsz - pos,
1457			 "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n",
1458			 le32_to_cpu(tx->dump_msdu_cnt),
1459			 accum_tx->dump_msdu_cnt);
1460	pos += scnprintf(buf + pos, bufsz - pos,
1461			 "abort_nxt_frame_mismatch:"
1462			 "\t%u\t\t\t%u\n",
1463			 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
1464			 accum_tx->burst_abort_next_frame_mismatch_cnt);
1465	pos += scnprintf(buf + pos, bufsz - pos,
1466			 "abort_missing_nxt_frame:"
1467			 "\t%u\t\t\t%u\n",
1468			 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
1469			 accum_tx->burst_abort_missing_next_frame_cnt);
1470	pos += scnprintf(buf + pos, bufsz - pos,
1471			 "cts_timeout_collision:\t\t%u\t\t\t%u\n",
1472			 le32_to_cpu(tx->cts_timeout_collision),
1473			 accum_tx->cts_timeout_collision);
1474	pos += scnprintf(buf + pos, bufsz - pos,
1475			"ack_ba_timeout_collision:\t%u\t\t\t%u\n",
1476			 le32_to_cpu(tx->ack_or_ba_timeout_collision),
1477			 accum_tx->ack_or_ba_timeout_collision);
1478	pos += scnprintf(buf + pos, bufsz - pos,
1479			 "agg ba_timeout:\t\t\t%u\t\t\t%u\n",
1480			 le32_to_cpu(tx->agg.ba_timeout),
1481			 accum_tx->agg.ba_timeout);
1482	pos += scnprintf(buf + pos, bufsz - pos,
1483			"agg ba_resched_frames:\t\t%u\t\t\t%u\n",
1484			 le32_to_cpu(tx->agg.ba_reschedule_frames),
1485			 accum_tx->agg.ba_reschedule_frames);
1486	pos += scnprintf(buf + pos, bufsz - pos,
1487			"agg scd_query_agg_frame:\t%u\t\t\t%u\n",
1488			 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
1489			 accum_tx->agg.scd_query_agg_frame_cnt);
1490	pos += scnprintf(buf + pos, bufsz - pos,
1491			 "agg scd_query_no_agg:\t\t%u\t\t\t%u\n",
1492			 le32_to_cpu(tx->agg.scd_query_no_agg),
1493			 accum_tx->agg.scd_query_no_agg);
1494	pos += scnprintf(buf + pos, bufsz - pos,
1495			 "agg scd_query_agg:\t\t%u\t\t\t%u\n",
1496			 le32_to_cpu(tx->agg.scd_query_agg),
1497			 accum_tx->agg.scd_query_agg);
1498	pos += scnprintf(buf + pos, bufsz - pos,
1499			"agg scd_query_mismatch:\t\t%u\t\t\t%u\n",
1500			 le32_to_cpu(tx->agg.scd_query_mismatch),
1501			 accum_tx->agg.scd_query_mismatch);
1502	pos += scnprintf(buf + pos, bufsz - pos,
1503			 "agg frame_not_ready:\t\t%u\t\t\t%u\n",
1504			 le32_to_cpu(tx->agg.frame_not_ready),
1505			 accum_tx->agg.frame_not_ready);
1506	pos += scnprintf(buf + pos, bufsz - pos,
1507			 "agg underrun:\t\t\t%u\t\t\t%u\n",
1508			 le32_to_cpu(tx->agg.underrun),
1509			 accum_tx->agg.underrun);
1510	pos += scnprintf(buf + pos, bufsz - pos,
1511			 "agg bt_prio_kill:\t\t%u\t\t\t%u\n",
1512			 le32_to_cpu(tx->agg.bt_prio_kill),
1513			 accum_tx->agg.bt_prio_kill);
1514	pos += scnprintf(buf + pos, bufsz - pos,
1515			 "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n",
1516			 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
1517			 accum_tx->agg.rx_ba_rsp_cnt);
1518
1519	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1520	kfree(buf);
1521	return ret;
1522}
1523
1524static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1525					char __user *user_buf,
1526					size_t count, loff_t *ppos)
1527{
1528	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1529	int pos = 0;
1530	char *buf;
1531	int bufsz = sizeof(struct statistics_general) * 4 + 250;
1532	ssize_t ret;
1533	struct statistics_general *general, *accum_general;
1534	struct statistics_dbg *dbg, *accum_dbg;
1535	struct statistics_div *div, *accum_div;
1536
1537	if (!iwl_is_alive(priv))
1538		return -EAGAIN;
1539
1540	/* make request to uCode to retrieve statistics information */
1541	mutex_lock(&priv->mutex);
1542	ret = iwl_send_statistics_request(priv, 0);
1543	mutex_unlock(&priv->mutex);
1544
1545	if (ret) {
1546		IWL_ERR(priv,
1547			"Error sending statistics request: %zd\n", ret);
1548		return -EAGAIN;
1549	}
1550	buf = kzalloc(bufsz, GFP_KERNEL);
1551	if (!buf) {
1552		IWL_ERR(priv, "Can not allocate Buffer\n");
1553		return -ENOMEM;
1554	}
1555
1556	/* the statistic information display here is based on
1557	 * the last statistics notification from uCode
1558	 * might not reflect the current uCode activity
1559	 */
1560	general = &priv->statistics.general;
1561	dbg = &priv->statistics.general.dbg;
1562	div = &priv->statistics.general.div;
1563	accum_general = &priv->accum_statistics.general;
1564	accum_dbg = &priv->accum_statistics.general.dbg;
1565	accum_div = &priv->accum_statistics.general.div;
1566	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1567	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n");
1568	pos += scnprintf(buf + pos, bufsz - pos,
1569			"\t\t\tcurrent\t\t\taccumulative\n");
1570	pos += scnprintf(buf + pos, bufsz - pos, "temperature:\t\t\t%u\n",
1571			 le32_to_cpu(general->temperature));
1572	pos += scnprintf(buf + pos, bufsz - pos, "temperature_m:\t\t\t%u\n",
1573			 le32_to_cpu(general->temperature_m));
1574	pos += scnprintf(buf + pos, bufsz - pos,
1575			 "burst_check:\t\t\t%u\t\t\t%u\n",
1576			 le32_to_cpu(dbg->burst_check),
1577			 accum_dbg->burst_check);
1578	pos += scnprintf(buf + pos, bufsz - pos,
1579			 "burst_count:\t\t\t%u\t\t\t%u\n",
1580			 le32_to_cpu(dbg->burst_count),
1581			 accum_dbg->burst_count);
1582	pos += scnprintf(buf + pos, bufsz - pos,
1583			 "sleep_time:\t\t\t%u\t\t\t%u\n",
1584			 le32_to_cpu(general->sleep_time),
1585			 accum_general->sleep_time);
1586	pos += scnprintf(buf + pos, bufsz - pos,
1587			 "slots_out:\t\t\t%u\t\t\t%u\n",
1588			 le32_to_cpu(general->slots_out),
1589			 accum_general->slots_out);
1590	pos += scnprintf(buf + pos, bufsz - pos,
1591			 "slots_idle:\t\t\t%u\t\t\t%u\n",
1592			 le32_to_cpu(general->slots_idle),
1593			 accum_general->slots_idle);
1594	pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
1595			 le32_to_cpu(general->ttl_timestamp));
1596	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a:\t\t\t%u\t\t\t%u\n",
1597			 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a);
1598	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b:\t\t\t%u\t\t\t%u\n",
1599			 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b);
1600	pos += scnprintf(buf + pos, bufsz - pos,
1601			 "exec_time:\t\t\t%u\t\t\t%u\n",
1602			 le32_to_cpu(div->exec_time), accum_div->exec_time);
1603	pos += scnprintf(buf + pos, bufsz - pos,
1604			 "probe_time:\t\t\t%u\t\t\t%u\n",
1605			 le32_to_cpu(div->probe_time), accum_div->probe_time);
1606	pos += scnprintf(buf + pos, bufsz - pos,
1607			 "rx_enable_counter:\t\t%u\t\t\t%u\n",
1608			 le32_to_cpu(general->rx_enable_counter),
1609			 accum_general->rx_enable_counter);
1610	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1611	kfree(buf);
1612	return ret;
1613}
1614
1615static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
1616					char __user *user_buf,
1617					size_t count, loff_t *ppos) {
1618
1619	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1620	int pos = 0;
1621	int cnt = 0;
1622	char *buf;
1623	int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100;
1624	ssize_t ret;
1625	struct iwl_sensitivity_data *data;
1626
1627	data = &priv->sensitivity_data;
1628	buf = kzalloc(bufsz, GFP_KERNEL);
1629	if (!buf) {
1630		IWL_ERR(priv, "Can not allocate Buffer\n");
1631		return -ENOMEM;
1632	}
1633
1634	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
1635			data->auto_corr_ofdm);
1636	pos += scnprintf(buf + pos, bufsz - pos,
1637			"auto_corr_ofdm_mrc:\t\t %u\n",
1638			data->auto_corr_ofdm_mrc);
1639	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
1640			data->auto_corr_ofdm_x1);
1641	pos += scnprintf(buf + pos, bufsz - pos,
1642			"auto_corr_ofdm_mrc_x1:\t\t %u\n",
1643			data->auto_corr_ofdm_mrc_x1);
1644	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
1645			data->auto_corr_cck);
1646	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
1647			data->auto_corr_cck_mrc);
1648	pos += scnprintf(buf + pos, bufsz - pos,
1649			"last_bad_plcp_cnt_ofdm:\t\t %u\n",
1650			data->last_bad_plcp_cnt_ofdm);
1651	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
1652			data->last_fa_cnt_ofdm);
1653	pos += scnprintf(buf + pos, bufsz - pos,
1654			"last_bad_plcp_cnt_cck:\t\t %u\n",
1655			data->last_bad_plcp_cnt_cck);
1656	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
1657			data->last_fa_cnt_cck);
1658	pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
1659			data->nrg_curr_state);
1660	pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
1661			data->nrg_prev_state);
1662	pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
1663	for (cnt = 0; cnt < 10; cnt++) {
1664		pos += scnprintf(buf + pos, bufsz - pos, " %u",
1665				data->nrg_value[cnt]);
1666	}
1667	pos += scnprintf(buf + pos, bufsz - pos, "\n");
1668	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
1669	for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
1670		pos += scnprintf(buf + pos, bufsz - pos, " %u",
1671				data->nrg_silence_rssi[cnt]);
1672	}
1673	pos += scnprintf(buf + pos, bufsz - pos, "\n");
1674	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
1675			data->nrg_silence_ref);
1676	pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
1677			data->nrg_energy_idx);
1678	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
1679			data->nrg_silence_idx);
1680	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
1681			data->nrg_th_cck);
1682	pos += scnprintf(buf + pos, bufsz - pos,
1683			"nrg_auto_corr_silence_diff:\t %u\n",
1684			data->nrg_auto_corr_silence_diff);
1685	pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
1686			data->num_in_cck_no_fa);
1687	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
1688			data->nrg_th_ofdm);
1689
1690	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1691	kfree(buf);
1692	return ret;
1693}
1694
1695
1696static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
1697					char __user *user_buf,
1698					size_t count, loff_t *ppos) {
1699
1700	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1701	int pos = 0;
1702	int cnt = 0;
1703	char *buf;
1704	int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100;
1705	ssize_t ret;
1706	struct iwl_chain_noise_data *data;
1707
1708	data = &priv->chain_noise_data;
1709	buf = kzalloc(bufsz, GFP_KERNEL);
1710	if (!buf) {
1711		IWL_ERR(priv, "Can not allocate Buffer\n");
1712		return -ENOMEM;
1713	}
1714
1715	pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
1716			data->active_chains);
1717	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
1718			data->chain_noise_a);
1719	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
1720			data->chain_noise_b);
1721	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
1722			data->chain_noise_c);
1723	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
1724			data->chain_signal_a);
1725	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
1726			data->chain_signal_b);
1727	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
1728			data->chain_signal_c);
1729	pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
1730			data->beacon_count);
1731
1732	pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
1733	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
1734		pos += scnprintf(buf + pos, bufsz - pos, " %u",
1735				data->disconn_array[cnt]);
1736	}
1737	pos += scnprintf(buf + pos, bufsz - pos, "\n");
1738	pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
1739	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
1740		pos += scnprintf(buf + pos, bufsz - pos, " %u",
1741				data->delta_gain_code[cnt]);
1742	}
1743	pos += scnprintf(buf + pos, bufsz - pos, "\n");
1744	pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
1745			data->radio_write);
1746	pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
1747			data->state);
1748
1749	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1750	kfree(buf);
1751	return ret;
1752}
1753
1754static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
1755					char __user *user_buf,
1756					size_t count, loff_t *ppos) {
1757
1758	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1759	char buf[128];
1760	int pos = 0;
1761	ssize_t ret;
1762	const size_t bufsz = sizeof(buf);
1763	struct statistics_tx *tx;
1764
1765	if (!iwl_is_alive(priv))
1766		pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1767	else {
1768		/* make request to uCode to retrieve statistics information */
1769		mutex_lock(&priv->mutex);
1770		ret = iwl_send_statistics_request(priv, 0);
1771		mutex_unlock(&priv->mutex);
1772
1773		if (ret) {
1774			IWL_ERR(priv, "Error sending statistics request: %zd\n",
1775				ret);
1776			return -EAGAIN;
1777		}
1778		tx = &priv->statistics.tx;
1779		if (tx->tx_power.ant_a ||
1780		    tx->tx_power.ant_b ||
1781		    tx->tx_power.ant_c) {
1782			pos += scnprintf(buf + pos, bufsz - pos,
1783				"tx power: (1/2 dB step)\n");
1784			if ((priv->cfg->valid_tx_ant & ANT_A) &&
1785			    tx->tx_power.ant_a)
1786				pos += scnprintf(buf + pos, bufsz - pos,
1787						"\tantenna A: 0x%X\n",
1788						tx->tx_power.ant_a);
1789			if ((priv->cfg->valid_tx_ant & ANT_B) &&
1790			    tx->tx_power.ant_b)
1791				pos += scnprintf(buf + pos, bufsz - pos,
1792						"\tantenna B: 0x%X\n",
1793						tx->tx_power.ant_b);
1794			if ((priv->cfg->valid_tx_ant & ANT_C) &&
1795			    tx->tx_power.ant_c)
1796				pos += scnprintf(buf + pos, bufsz - pos,
1797						"\tantenna C: 0x%X\n",
1798						tx->tx_power.ant_c);
1799		} else
1800			pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1801	}
1802	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1803}
1804
1805static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
1806						    char __user *user_buf,
1807						    size_t count, loff_t *ppos)
1808{
1809	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1810	char buf[60];
1811	int pos = 0;
1812	const size_t bufsz = sizeof(buf);
1813	u32 pwrsave_status;
1814
1815	pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) &
1816			CSR_GP_REG_POWER_SAVE_STATUS_MSK;
1817
1818	pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
1819	pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
1820		(pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1821		(pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1822		(pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1823		"error");
1824
1825	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1826}
1827
1828DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics);
1829DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics);
1830DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
1831DEBUGFS_READ_FILE_OPS(rx_queue);
1832DEBUGFS_READ_FILE_OPS(tx_queue);
1833DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1834DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1835DEBUGFS_READ_FILE_OPS(ucode_general_stats);
1836DEBUGFS_READ_FILE_OPS(sensitivity);
1837DEBUGFS_READ_FILE_OPS(chain_noise);
1838DEBUGFS_READ_FILE_OPS(tx_power);
1839DEBUGFS_READ_FILE_OPS(power_save_status);
1840
1841/*
1842 * Create the debugfs files and directories
1843 *
1844 */
1845int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1846{
1847	struct iwl_debugfs *dbgfs;
1848	struct dentry *phyd = priv->hw->wiphy->debugfsdir;
1849	int ret = 0;
1850
1851	dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL);
1852	if (!dbgfs) {
1853		ret = -ENOMEM;
1854		goto err;
1855	}
1856
1857	priv->dbgfs = dbgfs;
1858	dbgfs->name = name;
1859	dbgfs->dir_drv = debugfs_create_dir(name, phyd);
1860	if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) {
1861		ret = -ENOENT;
1862		goto err;
1863	}
1864
1865	DEBUGFS_ADD_DIR(data, dbgfs->dir_drv);
1866	DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv);
1867	DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv);
1868	DEBUGFS_ADD_FILE(nvm, data);
1869	DEBUGFS_ADD_FILE(sram, data);
1870	DEBUGFS_ADD_FILE(log_event, data);
1871	DEBUGFS_ADD_FILE(stations, data);
1872	DEBUGFS_ADD_FILE(channels, data);
1873	DEBUGFS_ADD_FILE(status, data);
1874	DEBUGFS_ADD_FILE(interrupt, data);
1875	DEBUGFS_ADD_FILE(qos, data);
1876	DEBUGFS_ADD_FILE(led, data);
1877	DEBUGFS_ADD_FILE(sleep_level_override, data);
1878	DEBUGFS_ADD_FILE(current_sleep_command, data);
1879	DEBUGFS_ADD_FILE(thermal_throttling, data);
1880	DEBUGFS_ADD_FILE(disable_ht40, data);
1881	DEBUGFS_ADD_FILE(rx_statistics, debug);
1882	DEBUGFS_ADD_FILE(tx_statistics, debug);
1883	DEBUGFS_ADD_FILE(traffic_log, debug);
1884	DEBUGFS_ADD_FILE(rx_queue, debug);
1885	DEBUGFS_ADD_FILE(tx_queue, debug);
1886	DEBUGFS_ADD_FILE(tx_power, debug);
1887	DEBUGFS_ADD_FILE(power_save_status, debug);
1888	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1889		DEBUGFS_ADD_FILE(ucode_rx_stats, debug);
1890		DEBUGFS_ADD_FILE(ucode_tx_stats, debug);
1891		DEBUGFS_ADD_FILE(ucode_general_stats, debug);
1892		DEBUGFS_ADD_FILE(sensitivity, debug);
1893		DEBUGFS_ADD_FILE(chain_noise, debug);
1894	}
1895	DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
1896	DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
1897			 &priv->disable_chain_noise_cal);
1898	if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
1899	    ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
1900		DEBUGFS_ADD_BOOL(disable_tx_power, rf,
1901				&priv->disable_tx_power_cal);
1902	return 0;
1903
1904err:
1905	IWL_ERR(priv, "Can't open the debugfs directory\n");
1906	iwl_dbgfs_unregister(priv);
1907	return ret;
1908}
1909EXPORT_SYMBOL(iwl_dbgfs_register);
1910
1911/**
1912 * Remove the debugfs files and directories
1913 *
1914 */
1915void iwl_dbgfs_unregister(struct iwl_priv *priv)
1916{
1917	if (!priv->dbgfs)
1918		return;
1919
1920	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sleep_level_override);
1921	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_current_sleep_command);
1922	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
1923	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
1924	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
1925	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
1926	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
1927	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
1928	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
1929	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos);
1930	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
1931	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
1932	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
1933	DEBUGFS_REMOVE(priv->dbgfs->dir_data);
1934	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_statistics);
1935	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_statistics);
1936	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log);
1937	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue);
1938	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue);
1939	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power);
1940	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status);
1941	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1942		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1943			file_ucode_rx_stats);
1944		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1945			file_ucode_tx_stats);
1946		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1947			file_ucode_general_stats);
1948		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1949			file_sensitivity);
1950		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1951			file_chain_noise);
1952	}
1953	DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
1954	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
1955	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
1956	if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
1957	    ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
1958		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
1959	DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
1960	DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
1961	kfree(priv->dbgfs);
1962	priv->dbgfs = NULL;
1963}
1964EXPORT_SYMBOL(iwl_dbgfs_unregister);
1965
1966
1967
1968