iwl-debugfs.c revision 66e863a527f9ed3a871797862aaf0d62b0954813
1712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/******************************************************************************
2712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
3712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * GPL LICENSE SUMMARY
4712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
51f44780827c6bbbcd1f12d5c6b6ce84f49a96bc0Reinette Chatre * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
7712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * This program is free software; you can redistribute it and/or modify
8712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * it under the terms of version 2 of the GNU General Public License as
9712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * published by the Free Software Foundation.
10712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
11712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * This program is distributed in the hope that it will be useful, but
12712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * WITHOUT ANY WARRANTY; without even the implied warranty of
13712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * General Public License for more details.
15712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
16712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * You should have received a copy of the GNU General Public License
17712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * along with this program; if not, write to the Free Software
18712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * USA
20712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
21712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * The full GNU General Public License is included in this distribution
22712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * in the file called LICENSE.GPL.
23712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
24712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Contact Information:
25759ef89fb096c4a6ef078d3cfd5682ac037bd789Winkler, Tomas *  Intel Linux Wireless <ilw@linux.intel.com>
26712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *****************************************************************************/
28712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
295a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
30712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/kernel.h>
31712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/module.h>
32712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/debugfs.h>
33712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
34712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/ieee80211.h>
35712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <net/mac80211.h>
36712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
37712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
383e0d4cb12f6fd97193a455b49125398b2231c87cTomas Winkler#include "iwl-dev.h"
39712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include "iwl-debug.h"
40fee1247a30e5b3d48fe985b4a935eb6818f3b464Tomas Winkler#include "iwl-core.h"
413395f6e9cf48469d7ee05703cad1502002741c16Tomas Winkler#include "iwl-io.h"
42712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
43712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* create and remove of files */
444c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_FILE(name, parent, mode) do {			\
454c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!debugfs_create_file(#name, mode, parent, priv,		\
464c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg				 &iwl_dbgfs_##name##_ops))		\
474c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;						\
48712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} while (0)
49712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
504c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_BOOL(name, parent, ptr) do {			\
514c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	struct dentry *__tmp;						\
524c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	__tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR,		\
534c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg				    parent, ptr);			\
544c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (IS_ERR(__tmp) || !__tmp)					\
554c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;						\
56712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} while (0)
57712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
584c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_X32(name, parent, ptr) do {				\
594c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	struct dentry *__tmp;						\
604c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	__tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR,		\
614c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg				   parent, ptr);			\
624c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (IS_ERR(__tmp) || !__tmp)					\
634c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;						\
64445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler} while (0)
65445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler
66712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* file operation */
67712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_FUNC(name)                                         \
68712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_##name##_read(struct file *file,               \
69712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					char __user *user_buf,          \
70712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos);
71712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
72712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_WRITE_FUNC(name)                                        \
73712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_##name##_write(struct file *file,              \
74712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					const char __user *user_buf,    \
75712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos);
76712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
77712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
78712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
79712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
80712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	file->private_data = inode->i_private;
81712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return 0;
82712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
83712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
84712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_FILE_OPS(name)                                     \
85712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	DEBUGFS_READ_FUNC(name);                                        \
86712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic const struct file_operations iwl_dbgfs_##name##_ops = {          \
87712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.read = iwl_dbgfs_##name##_read,                       		\
88712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.open = iwl_dbgfs_open_file_generic,                    	\
892b18ab36cf7e956fb5b5ee12847e94fc66d496f4Arnd Bergmann	.llseek = generic_file_llseek,					\
90712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler};
91712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
92189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer#define DEBUGFS_WRITE_FILE_OPS(name)                                    \
93189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	DEBUGFS_WRITE_FUNC(name);                                       \
94189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummerstatic const struct file_operations iwl_dbgfs_##name##_ops = {          \
95189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	.write = iwl_dbgfs_##name##_write,                              \
96189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	.open = iwl_dbgfs_open_file_generic,                    	\
972b18ab36cf7e956fb5b5ee12847e94fc66d496f4Arnd Bergmann	.llseek = generic_file_llseek,					\
98189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer};
99189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
100189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
101712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_WRITE_FILE_OPS(name)                               \
102712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	DEBUGFS_READ_FUNC(name);                                        \
103712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	DEBUGFS_WRITE_FUNC(name);                                       \
104712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic const struct file_operations iwl_dbgfs_##name##_ops = {          \
105712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.write = iwl_dbgfs_##name##_write,                              \
106712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.read = iwl_dbgfs_##name##_read,                                \
107712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.open = iwl_dbgfs_open_file_generic,                            \
1082b18ab36cf7e956fb5b5ee12847e94fc66d496f4Arnd Bergmann	.llseek = generic_file_llseek,					\
109712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler};
110712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
111712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
112712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						char __user *user_buf,
113712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						size_t count, loff_t *ppos) {
114712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
11528f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
11622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	char *buf;
117712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int pos = 0;
118712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
11922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	int cnt;
12022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ssize_t ret;
12198a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy	const size_t bufsz = 100 +
12298a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy		sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
12322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
12422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (!buf)
12522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -ENOMEM;
12622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
12722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
12822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
12998a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
13022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_mgmt_string(cnt),
13122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->tx_stats.mgmt[cnt]);
13222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
13322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
13422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
13522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
13698a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
13722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_ctrl_string(cnt),
13822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->tx_stats.ctrl[cnt]);
13922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
14022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
14122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
14222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->tx_stats.data_cnt);
14322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
14422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->tx_stats.data_bytes);
14522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
14622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	kfree(buf);
14722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	return ret;
14822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy}
14922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy
1507163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guystatic ssize_t iwl_dbgfs_clear_traffic_statistics_write(struct file *file,
15122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy					const char __user *user_buf,
15222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy					size_t count, loff_t *ppos)
15322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy{
15422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
15522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	u32 clear_flag;
15622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	char buf[8];
15722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	int buf_size;
158712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
15922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	memset(buf, 0, sizeof(buf));
16022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
16122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
16222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -EFAULT;
16322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (sscanf(buf, "%x", &clear_flag) != 1)
16422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -EFAULT;
1657163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guy	iwl_clear_traffic_stats(priv);
16622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy
16722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	return count;
168712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
169712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
170712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
171712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						char __user *user_buf,
172712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						size_t count, loff_t *ppos) {
173712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
17428f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
17522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	char *buf;
176712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int pos = 0;
17722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	int cnt;
17822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ssize_t ret;
17922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	const size_t bufsz = 100 +
18098a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy		sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
18122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
18222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (!buf)
18322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -ENOMEM;
184712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
18522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
18622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
18722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
18898a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
18922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_mgmt_string(cnt),
19022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->rx_stats.mgmt[cnt]);
19122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
19222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
19322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
19422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
19598a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
19622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_ctrl_string(cnt),
19722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->rx_stats.ctrl[cnt]);
19822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
19922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
20022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
20122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->rx_stats.data_cnt);
20222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
20322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->rx_stats.data_bytes);
204712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
20522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
20622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	kfree(buf);
20722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	return ret;
20822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy}
20922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy
210712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE1_MASK 0x000000ff;
211712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE2_MASK 0x0000ffff;
212712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE3_MASK 0x00ffffff;
213712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_sram_read(struct file *file,
214712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					char __user *user_buf,
215712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos)
216712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
217712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	u32 val;
2182943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	char *buf;
219712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ssize_t ret;
220712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int i;
221712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int pos = 0;
22228f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
2232943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	size_t bufsz;
224712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
2255ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	/* default is to dump the entire data segment */
2264c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
2274c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_offset = 0x800000;
2285ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy		if (priv->ucode_type == UCODE_INIT)
2294c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg			priv->dbgfs_sram_len = priv->ucode_init_data.len;
2305ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy		else
2314c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg			priv->dbgfs_sram_len = priv->ucode_data.len;
2325ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	}
2334c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	bufsz =  30 + priv->dbgfs_sram_len * sizeof(char) * 10;
2342943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	buf = kmalloc(bufsz, GFP_KERNEL);
2352943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	if (!buf)
2362943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy		return -ENOMEM;
2375ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
2384c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg			priv->dbgfs_sram_len);
2395ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
2404c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg			priv->dbgfs_sram_offset);
2414c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	for (i = priv->dbgfs_sram_len; i > 0; i -= 4) {
2424c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		val = iwl_read_targ_mem(priv, priv->dbgfs_sram_offset + \
2434c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg					priv->dbgfs_sram_len - i);
244712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		if (i < 4) {
245712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			switch (i) {
246712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			case 1:
247712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				val &= BYTE1_MASK;
248712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				break;
249712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			case 2:
250712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				val &= BYTE2_MASK;
251712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				break;
252712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			case 3:
253712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				val &= BYTE3_MASK;
254712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				break;
255712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			}
256712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		}
2572943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy		if (!(i % 16))
2582943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos, "\n");
259db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar		pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
260712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	}
261db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar	pos += scnprintf(buf + pos, bufsz - pos, "\n");
262712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
263712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2642943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	kfree(buf);
265712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return ret;
266712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
267712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
268712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_sram_write(struct file *file,
269712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					const char __user *user_buf,
270712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos)
271712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
272712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	struct iwl_priv *priv = file->private_data;
273712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	char buf[64];
274712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int buf_size;
275712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	u32 offset, len;
276712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
277712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	memset(buf, 0, sizeof(buf));
278712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	buf_size = min(count, sizeof(buf) -  1);
279712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	if (copy_from_user(buf, user_buf, buf_size))
280712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		return -EFAULT;
281712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
282712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
2834c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_offset = offset;
2844c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_len = len;
285712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	} else {
2864c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_offset = 0;
2874c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_len = 0;
288712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	}
289712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
290712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return count;
291712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
292712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
293712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
294712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos)
295712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
29628f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
2976def9761f72501e638e79eebcd70afea12a3a93dTomas Winkler	struct iwl_station_entry *station;
2985425e490471d521bae2fce16d22995803b41d90fTomas Winkler	int max_sta = priv->hw_params.max_stations;
299712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	char *buf;
300712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int i, j, pos = 0;
301712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ssize_t ret;
302712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	/* Add 30 for initial string */
303712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations);
304712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
305712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	buf = kmalloc(bufsz, GFP_KERNEL);
3063ac7f14694dd38273d9d96f1c873233d71190c15Tomas Winkler	if (!buf)
307712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		return -ENOMEM;
308712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
309db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar	pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
310712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			priv->num_stations);
311712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
312712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	for (i = 0; i < max_sta; i++) {
313712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		station = &priv->stations[i];
314da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		if (!station->used)
315da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg			continue;
316da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		pos += scnprintf(buf + pos, bufsz - pos,
317da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				 "station %d - addr: %pM, flags: %#x\n",
318da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				 i, station->sta.sta.addr,
319da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				 station->sta.station_flags_msk);
320da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		pos += scnprintf(buf + pos, bufsz - pos,
321da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				"TID\tseq_num\ttxq_id\tframes\ttfds\t");
322da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		pos += scnprintf(buf + pos, bufsz - pos,
323da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				"start_idx\tbitmap\t\t\trate_n_flags\n");
324712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
325da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		for (j = 0; j < MAX_TID_COUNT; j++) {
326da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg			pos += scnprintf(buf + pos, bufsz - pos,
327da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				"%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
328da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				j, station->tid[j].seq_number,
329da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].agg.txq_id,
330da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].agg.frame_count,
331da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].tfds_in_queue,
332da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].agg.start_idx,
333da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].agg.bitmap,
334da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].agg.rate_n_flags);
335da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg
336da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg			if (station->tid[j].agg.wait_for_ba)
337db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar				pos += scnprintf(buf + pos, bufsz - pos,
338da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg						 " - waitforba");
339db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos, "\n");
340712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		}
341da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg
342da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		pos += scnprintf(buf + pos, bufsz - pos, "\n");
343712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	}
344712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
345712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
346712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	kfree(buf);
347712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return ret;
348712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
349712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
3500848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guystatic ssize_t iwl_dbgfs_nvm_read(struct file *file,
3518dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				       char __user *user_buf,
3528dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				       size_t count,
3538dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				       loff_t *ppos)
3548dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler{
3558dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	ssize_t ret;
35628f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
3578dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	int pos = 0, ofs = 0, buf_size = 0;
3588dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	const u8 *ptr;
3598dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	char *buf;
360e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy	u16 eeprom_ver;
3617cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	size_t eeprom_len = priv->cfg->base_params->eeprom_size;
3628dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	buf_size = 4 * eeprom_len + 256;
3638dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler
3648dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	if (eeprom_len % 16) {
3650848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy		IWL_ERR(priv, "NVM size is not multiple of 16.\n");
3668dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		return -ENODATA;
3678dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	}
3688dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler
369c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall	ptr = priv->eeprom;
370c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall	if (!ptr) {
371c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall		IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
372c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall		return -ENOMEM;
373c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall	}
374c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall
3758dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	/* 4 characters for byte 0xYY */
3768dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	buf = kzalloc(buf_size, GFP_KERNEL);
3778dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	if (!buf) {
37815b1687cb4f45b87ddbe4dfc7759ff5bb69497d2Winkler, Tomas		IWL_ERR(priv, "Can not allocate Buffer\n");
3798dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		return -ENOMEM;
3808dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	}
381e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
382e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy	pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, "
383e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy			"version: 0x%x\n",
3840848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy			(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
385e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy			 ? "OTP" : "EEPROM", eeprom_ver);
3868dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
3878dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
3888dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
3898dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				   buf_size - pos, 0);
3902fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre		pos += strlen(buf + pos);
3918dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		if (buf_size - pos > 0)
3928dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler			buf[pos++] = '\n';
3938dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	}
3948dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler
3958dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
3968dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	kfree(buf);
3978dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	return ret;
3988dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler}
399712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
400b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guystatic ssize_t iwl_dbgfs_log_event_read(struct file *file,
401b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy					 char __user *user_buf,
402b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy					 size_t count, loff_t *ppos)
403b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy{
404b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	struct iwl_priv *priv = file->private_data;
405b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	char *buf;
406b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	int pos = 0;
407b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	ssize_t ret = -ENOMEM;
408b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy
409937c397eb633b804d9a806d08c395ecfc42b1fecWey-Yi Guy	ret = pos = priv->cfg->ops->lib->dump_nic_event_log(
410937c397eb633b804d9a806d08c395ecfc42b1fecWey-Yi Guy					priv, true, &buf, true);
411937c397eb633b804d9a806d08c395ecfc42b1fecWey-Yi Guy	if (buf) {
412b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy		ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
413b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy		kfree(buf);
414b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	}
415b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	return ret;
416b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy}
417b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy
418189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummerstatic ssize_t iwl_dbgfs_log_event_write(struct file *file,
419189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer					const char __user *user_buf,
420189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer					size_t count, loff_t *ppos)
421189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer{
422189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	struct iwl_priv *priv = file->private_data;
423189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	u32 event_log_flag;
424189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	char buf[8];
425189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	int buf_size;
426189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
427189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	memset(buf, 0, sizeof(buf));
428189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	buf_size = min(count, sizeof(buf) -  1);
429189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	if (copy_from_user(buf, user_buf, buf_size))
430189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer		return -EFAULT;
431189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	if (sscanf(buf, "%d", &event_log_flag) != 1)
432189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer		return -EFAULT;
433189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	if (event_log_flag == 1)
434b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy		priv->cfg->ops->lib->dump_nic_event_log(priv, true,
435b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy							NULL, false);
436189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
437189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	return count;
438189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer}
439189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
440d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
441d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
442d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomasstatic ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
443d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas				       size_t count, loff_t *ppos)
444d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas{
44528f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
446d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	struct ieee80211_channel *channels = NULL;
447d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	const struct ieee80211_supported_band *supp_band = NULL;
448d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	int pos = 0, i, bufsz = PAGE_SIZE;
449d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	char *buf;
450d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	ssize_t ret;
451d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
452d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
453d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		return -EAGAIN;
454d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
455d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	buf = kzalloc(bufsz, GFP_KERNEL);
456d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	if (!buf) {
45715b1687cb4f45b87ddbe4dfc7759ff5bb69497d2Winkler, Tomas		IWL_ERR(priv, "Can not allocate Buffer\n");
458d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		return -ENOMEM;
459d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	}
460d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
461d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
462a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	if (supp_band) {
463a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		channels = supp_band->channels;
464d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
465d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		pos += scnprintf(buf + pos, bufsz - pos,
466a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				"Displaying %d channels in 2.4GHz band 802.11bg):\n",
467a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				supp_band->n_channels);
468d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
469a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		for (i = 0; i < supp_band->n_channels; i++)
470a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
471a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"%d: %ddBm: BSS%s%s, %s.\n",
47281e95430aaa898799421617c2db2882386bab69aShanyu Zhao					channels[i].hw_value,
473a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].max_power,
474a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags & IEEE80211_CHAN_RADAR ?
475a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					" (IEEE 802.11h required)" : "",
476a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
477a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					|| (channels[i].flags &
478a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_RADAR)) ? "" :
479a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					", IBSS",
480a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags &
481a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_PASSIVE_SCAN ?
482a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"passive only" : "active/passive");
483a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	}
484d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
485a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	if (supp_band) {
486a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		channels = supp_band->channels;
487d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
488d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		pos += scnprintf(buf + pos, bufsz - pos,
489a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				"Displaying %d channels in 5.2GHz band (802.11a)\n",
490a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				supp_band->n_channels);
491a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy
492a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		for (i = 0; i < supp_band->n_channels; i++)
493a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
494a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"%d: %ddBm: BSS%s%s, %s.\n",
49581e95430aaa898799421617c2db2882386bab69aShanyu Zhao					channels[i].hw_value,
496a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].max_power,
497a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags & IEEE80211_CHAN_RADAR ?
498a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					" (IEEE 802.11h required)" : "",
499a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
500a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					|| (channels[i].flags &
501a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_RADAR)) ? "" :
502a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					", IBSS",
503a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags &
504a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_PASSIVE_SCAN ?
505a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"passive only" : "active/passive");
506a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	}
507d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
508d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	kfree(buf);
509d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	return ret;
510d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas}
511d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
51208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guystatic ssize_t iwl_dbgfs_status_read(struct file *file,
51308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy						char __user *user_buf,
51408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy						size_t count, loff_t *ppos) {
51508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy
51628f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
51708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	char buf[512];
51808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	int pos = 0;
51908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	const size_t bufsz = sizeof(buf);
52008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy
52108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
52208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_HCMD_ACTIVE, &priv->status));
52308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
52408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_INT_ENABLED, &priv->status));
52508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
52608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_RF_KILL_HW, &priv->status));
5277812b16730ccebce71a3b2228ac08dd4f8b39469Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n",
5287812b16730ccebce71a3b2228ac08dd4f8b39469Wey-Yi Guy		test_bit(STATUS_CT_KILL, &priv->status));
52908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
53008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_INIT, &priv->status));
53108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
53208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_ALIVE, &priv->status));
53308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
53408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_READY, &priv->status));
53508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
53608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_TEMPERATURE, &priv->status));
53708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
53808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_GEO_CONFIGURED, &priv->status));
53908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
54008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_EXIT_PENDING, &priv->status));
54108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
54208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_STATISTICS, &priv->status));
54308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
54408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_SCANNING, &priv->status));
54508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
54608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_SCAN_ABORTING, &priv->status));
54708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
54808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_SCAN_HW, &priv->status));
54908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
55008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_POWER_PMI, &priv->status));
55108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
55208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_FW_ERROR, &priv->status));
55308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
55408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy}
55508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy
556a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_read(struct file *file,
557a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					char __user *user_buf,
558a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					size_t count, loff_t *ppos) {
559a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
56028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
561a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int pos = 0;
562a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int cnt = 0;
563a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	char *buf;
564a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int bufsz = 24 * 64; /* 24 items * 64 char per item */
565a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	ssize_t ret;
566a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
567a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
568a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (!buf) {
569a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
570a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		return -ENOMEM;
571a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	}
572a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
573a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
574a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy			"Interrupt Statistics Report:\n");
575a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
576a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
577a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.hw);
578a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
579a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.sw);
5806e6ebf4befa75ebdf28130d0135f3ad3aadc02f8Wey-Yi Guy	if (priv->isr_stats.sw || priv->isr_stats.hw) {
581a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
582a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy			"\tLast Restarting Code:  0x%X\n",
5836e6ebf4befa75ebdf28130d0135f3ad3aadc02f8Wey-Yi Guy			priv->isr_stats.err_code);
584a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	}
585a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#ifdef CONFIG_IWLWIFI_DEBUG
586a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
587a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.sch);
588a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
589a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.alive);
590a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#endif
591a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
592a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		"HW RF KILL switch toggled:\t %u\n",
593a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.rfkill);
594a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
595a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
596a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.ctkill);
597a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
598a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
599a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.wakeup);
600a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
601a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
602a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		"Rx command responses:\t\t %u\n",
603a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.rx);
604a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	for (cnt = 0; cnt < REPLY_MAX; cnt++) {
605a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		if (priv->isr_stats.rx_handlers[cnt] > 0)
606a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
607a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy				"\tRx handler[%36s]:\t\t %u\n",
608a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy				get_cmd_string(cnt),
609a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy				priv->isr_stats.rx_handlers[cnt]);
610a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	}
611a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
612a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
613a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.tx);
614a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
615a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
616a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.unhandled);
617a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
618a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
619a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	kfree(buf);
620a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	return ret;
621a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy}
622a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
623a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_write(struct file *file,
624a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					 const char __user *user_buf,
625a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					 size_t count, loff_t *ppos)
626a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy{
627a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
628a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	char buf[8];
629a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int buf_size;
630a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	u32 reset_flag;
631a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
632a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	memset(buf, 0, sizeof(buf));
633a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
634a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
635a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		return -EFAULT;
636a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (sscanf(buf, "%x", &reset_flag) != 1)
637a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		return -EFAULT;
638a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (reset_flag == 0)
639a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		iwl_clear_isr_stats(priv);
640a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
641a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	return count;
642a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy}
643a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
644f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guystatic ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
645f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy				       size_t count, loff_t *ppos)
646f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy{
64728f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
6488dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg	struct iwl_rxon_context *ctx;
649f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy	int pos = 0, i;
6508dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg	char buf[256 * NUM_IWL_RXON_CTX];
651f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy	const size_t bufsz = sizeof(buf);
652f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy
6538dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg	for_each_context(priv, ctx) {
6548dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg		pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n",
6558dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				 ctx->ctxid);
6568dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg		for (i = 0; i < AC_NUM; i++) {
6578dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg			pos += scnprintf(buf + pos, bufsz - pos,
6588dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				"\tcw_min\tcw_max\taifsn\ttxop\n");
6598dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg			pos += scnprintf(buf + pos, bufsz - pos,
660f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy				"AC[%d]\t%u\t%u\t%u\t%u\n", i,
6618dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				ctx->qos_data.def_qos_parm.ac[i].cw_min,
6628dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				ctx->qos_data.def_qos_parm.ac[i].cw_max,
6638dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				ctx->qos_data.def_qos_parm.ac[i].aifsn,
6648dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				ctx->qos_data.def_qos_parm.ac[i].edca_txop);
6658dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg		}
6668dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg		pos += scnprintf(buf + pos, bufsz - pos, "\n");
667f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy	}
6684967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
669f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy}
670a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
671a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guystatic ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
672a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy				  size_t count, loff_t *ppos)
673a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy{
67428f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
675a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	int pos = 0;
676a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	char buf[256];
677a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	const size_t bufsz = sizeof(buf);
678a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy
679a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
680a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy			 "allow blinking: %s\n",
681a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy			 (priv->allow_blinking) ? "True" : "False");
682a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	if (priv->allow_blinking) {
683a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
684a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy				 "Led blinking rate: %u\n",
685a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy				 priv->last_blink_rate);
686a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
687a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy				 "Last blink time: %lu\n",
688a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy				 priv->last_blink_time);
689a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	}
690a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy
6914967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
692a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy}
693a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy
694fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guystatic ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
695fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				char __user *user_buf,
696fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				size_t count, loff_t *ppos)
697fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy{
69828f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
6993ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
700fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	struct iwl_tt_restriction *restriction;
701fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	char buf[100];
702fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	int pos = 0;
703fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	const size_t bufsz = sizeof(buf);
704fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy
705fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
706fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy			"Thermal Throttling Mode: %s\n",
7073ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg			tt->advanced_tt ? "Advance" : "Legacy");
708fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
709fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy			"Thermal Throttling State: %d\n",
710fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy			tt->state);
7113ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg	if (tt->advanced_tt) {
712fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		restriction = tt->restriction + tt->state;
713fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
714fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				"Tx mode: %d\n",
715fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				restriction->tx_stream);
716fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
717fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				"Rx mode: %d\n",
718fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				restriction->rx_stream);
719fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
720fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				"HT mode: %d\n",
721fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				restriction->is_ht);
722fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	}
7234967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
724fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy}
725fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy
7261e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guystatic ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
7271e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 const char __user *user_buf,
7281e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 size_t count, loff_t *ppos)
7291e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy{
7301e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
7311e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	char buf[8];
7321e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	int buf_size;
7331e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	int ht40;
7341e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7351e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	memset(buf, 0, sizeof(buf));
7361e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
7371e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
7381e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		return -EFAULT;
7391e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	if (sscanf(buf, "%d", &ht40) != 1)
7401e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		return -EFAULT;
741246ed355221076884d225f9d8a4c30a048be8162Johannes Berg	if (!iwl_is_any_associated(priv))
7421e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		priv->disable_ht40 = ht40 ? true : false;
7431e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	else {
7441e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		IWL_ERR(priv, "Sta associated with AP - "
7451e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy			"Change to 40MHz channel support is not allowed\n");
7461e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		return -EINVAL;
7471e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	}
7481e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7491e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	return count;
7501e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy}
7511e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7521e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guystatic ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
7531e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 char __user *user_buf,
7541e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 size_t count, loff_t *ppos)
7551e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy{
75628f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
7571e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	char buf[100];
7581e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	int pos = 0;
7591e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	const size_t bufsz = sizeof(buf);
7601e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7611e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
7621e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy			"11n 40MHz Mode: %s\n",
7631e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy			priv->disable_ht40 ? "Disabled" : "Enabled");
7644967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
7651e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy}
7661e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
767e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
768e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    const char __user *user_buf,
769e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    size_t count, loff_t *ppos)
770e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{
771e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	struct iwl_priv *priv = file->private_data;
772e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	char buf[8];
773e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int buf_size;
774e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int value;
775e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
776e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	memset(buf, 0, sizeof(buf));
777e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	buf_size = min(count, sizeof(buf) -  1);
778e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (copy_from_user(buf, user_buf, buf_size))
779e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		return -EFAULT;
780e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
781e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (sscanf(buf, "%d", &value) != 1)
782e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		return -EINVAL;
783e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
784e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	/*
785e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 * Our users expect 0 to be "CAM", but 0 isn't actually
786e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 * valid here. However, let's not confuse them and present
787e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 * IWL_POWER_INDEX_1 as "1", not "0".
788e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 */
7891a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre	if (value == 0)
7901a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre		return -EINVAL;
7911a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre	else if (value > 0)
792e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		value -= 1;
793e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
794e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (value != -1 && (value < 0 || value >= IWL_POWER_NUM))
795e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		return -EINVAL;
796e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
7974ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy	if (!iwl_is_ready_rf(priv))
7984ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy		return -EAGAIN;
7994ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy
800e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	priv->power_data.debug_sleep_level_override = value;
801e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
802d3a571971e5af241074947fc80f6284677f6e014Reinette Chatre	mutex_lock(&priv->mutex);
8034ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy	iwl_power_update_mode(priv, true);
804d3a571971e5af241074947fc80f6284677f6e014Reinette Chatre	mutex_unlock(&priv->mutex);
805e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
806e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	return count;
807e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg}
808e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
809e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
810e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						   char __user *user_buf,
811e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						   size_t count, loff_t *ppos)
812e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{
81328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
814e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	char buf[10];
815e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int pos, value;
816e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	const size_t bufsz = sizeof(buf);
817e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
818e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	/* see the write function */
819e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	value = priv->power_data.debug_sleep_level_override;
820e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (value >= 0)
821e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		value += 1;
822e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
823e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	pos = scnprintf(buf, bufsz, "%d\n", value);
824e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
825e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg}
826e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
827e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
828e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    char __user *user_buf,
829e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    size_t count, loff_t *ppos)
830e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{
83128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
832e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	char buf[200];
833e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int pos = 0, i;
834e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	const size_t bufsz = sizeof(buf);
835e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd;
836e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
837e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	pos += scnprintf(buf + pos, bufsz - pos,
838e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 "flags: %#.2x\n", le16_to_cpu(cmd->flags));
839e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	pos += scnprintf(buf + pos, bufsz - pos,
840e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 "RX/TX timeout: %d/%d usec\n",
841e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 le32_to_cpu(cmd->rx_data_timeout),
842e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 le32_to_cpu(cmd->tx_data_timeout));
843e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
844e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		pos += scnprintf(buf + pos, bufsz - pos,
845e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg				 "sleep_interval[%d]: %d\n", i,
846e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg				 le32_to_cpu(cmd->sleep_interval[i]));
847e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
848e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
849e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg}
850e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
851712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_WRITE_FILE_OPS(sram);
852b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(log_event);
8530848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi GuyDEBUGFS_READ_FILE_OPS(nvm);
854712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_FILE_OPS(stations);
855d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, TomasDEBUGFS_READ_FILE_OPS(channels);
85608df05aa9b25f3079585855506022bb33a011183Wey-Yi GuyDEBUGFS_READ_FILE_OPS(status);
857a83b9141b540f96dd59409c6487828e880113a29Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(interrupt);
858f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi GuyDEBUGFS_READ_FILE_OPS(qos);
859a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi GuyDEBUGFS_READ_FILE_OPS(led);
860fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi GuyDEBUGFS_READ_FILE_OPS(thermal_throttling);
8611e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
862e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes BergDEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
863e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes BergDEBUGFS_READ_FILE_OPS(current_sleep_command);
864712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
86520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guystatic ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
86620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 char __user *user_buf,
86720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 size_t count, loff_t *ppos)
86820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy{
86920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_priv *priv = file->private_data;
87020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int pos = 0, ofs = 0;
87120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int cnt = 0, entry;
87220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_tx_queue *txq;
87320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_queue *q;
87420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_rx_queue *rxq = &priv->rxq;
87520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	char *buf;
87620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
8777cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		(priv->cfg->base_params->num_of_queues * 32 * 8) + 400;
87820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	const u8 *ptr;
87920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	ssize_t ret;
88020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
88188804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	if (!priv->txq) {
88288804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		IWL_ERR(priv, "txq not ready\n");
88388804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		return -EAGAIN;
88488804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	}
88520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
88620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (!buf) {
88720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		IWL_ERR(priv, "Can not allocate buffer\n");
88820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		return -ENOMEM;
88920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
89020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
89120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
89220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		txq = &priv->txq[cnt];
89320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		q = &txq->q;
89420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
89520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				"q[%d]: read_ptr: %u, write_ptr: %u\n",
89620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				cnt, q->read_ptr, q->write_ptr);
89720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
89820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) {
89920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		ptr = priv->tx_traffic;
90020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
90120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				"Tx Traffic idx: %u\n",	priv->tx_traffic_idx);
90220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
90320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
90420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			     entry++,  ofs += 16) {
90520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				pos += scnprintf(buf + pos, bufsz - pos,
90620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						"0x%.4x ", ofs);
90720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
90820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						   buf + pos, bufsz - pos, 0);
9092fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre				pos += strlen(buf + pos);
91020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				if (bufsz - pos > 0)
91120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					buf[pos++] = '\n';
91220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			}
91320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		}
91420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
91520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
91620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
91720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
91820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			"read: %u, write: %u\n",
91920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			 rxq->read, rxq->write);
92020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
92120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) {
92220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		ptr = priv->rx_traffic;
92320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
92420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				"Rx Traffic idx: %u\n",	priv->rx_traffic_idx);
92520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
92620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
92720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			     entry++,  ofs += 16) {
92820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				pos += scnprintf(buf + pos, bufsz - pos,
92920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						"0x%.4x ", ofs);
93020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
93120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						   buf + pos, bufsz - pos, 0);
9322fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre				pos += strlen(buf + pos);
93320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				if (bufsz - pos > 0)
93420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					buf[pos++] = '\n';
93520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			}
93620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		}
93720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
93820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
93920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
94020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	kfree(buf);
94120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	return ret;
94220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy}
94320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
94420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guystatic ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
94520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 const char __user *user_buf,
94620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 size_t count, loff_t *ppos)
94720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy{
94820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_priv *priv = file->private_data;
94920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	char buf[8];
95020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int buf_size;
95120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int traffic_log;
95220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
95320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	memset(buf, 0, sizeof(buf));
95420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
95520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
95620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		return -EFAULT;
95720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (sscanf(buf, "%d", &traffic_log) != 1)
95820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		return -EFAULT;
95920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (traffic_log == 0)
96020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		iwl_reset_traffic_log(priv);
96120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
96220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	return count;
96320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy}
96420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
965141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guystatic ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
966141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						char __user *user_buf,
967141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						size_t count, loff_t *ppos) {
968141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
96928f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
970141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	struct iwl_tx_queue *txq;
971141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	struct iwl_queue *q;
972141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	char *buf;
973141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int pos = 0;
974141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int cnt;
975141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int ret;
9767cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	const size_t bufsz = sizeof(char) * 64 *
9777cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy				priv->cfg->base_params->num_of_queues;
978141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
97988804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	if (!priv->txq) {
98088804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		IWL_ERR(priv, "txq not ready\n");
98188804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		return -EAGAIN;
98288804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	}
983141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
984141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	if (!buf)
985141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		return -ENOMEM;
986141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
987141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
988141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		txq = &priv->txq[cnt];
989141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		q = &txq->q;
990141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
991141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				"hwq %.2d: read=%u write=%u stop=%d"
992141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				" swq_id=%#.2x (ac %d/hwq %d)\n",
993141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				cnt, q->read_ptr, q->write_ptr,
994141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				!!test_bit(cnt, priv->queue_stopped),
995141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				txq->swq_id,
996141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				txq->swq_id & 0x80 ? txq->swq_id & 3 :
997141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				txq->swq_id,
998141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				txq->swq_id & 0x80 ? (txq->swq_id >> 2) &
999141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				0x1f : txq->swq_id);
1000141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		if (cnt >= 4)
1001141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy			continue;
1002141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		/* for the ACs, display the stop count too */
1003141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
1004141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				"        stop-count: %d\n",
1005141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				atomic_read(&priv->queue_stop_count[cnt]));
1006141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	}
1007141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1008141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	kfree(buf);
1009141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	return ret;
1010141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy}
1011141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
1012141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guystatic ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1013141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						char __user *user_buf,
1014141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						size_t count, loff_t *ppos) {
1015141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
101628f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1017141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	struct iwl_rx_queue *rxq = &priv->rxq;
1018141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	char buf[256];
1019141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int pos = 0;
1020141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	const size_t bufsz = sizeof(buf);
1021141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
1022141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
1023141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						rxq->read);
1024141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
1025141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						rxq->write);
1026141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
1027141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						rxq->free_count);
1028f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish	if (rxq->rb_stts) {
1029f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish		pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
1030141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy			 le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF);
1031f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish	} else {
1032f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish		pos += scnprintf(buf + pos, bufsz - pos,
1033f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish					"closed_rb_num: Not Allocated\n");
1034f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish	}
1035141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1036141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy}
1037141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
1038e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1039e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					char __user *user_buf,
1040e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					size_t count, loff_t *ppos)
1041e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{
104228f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
104317f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar	return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
104417f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar			user_buf, count, ppos);
1045e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy}
1046e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1047e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1048e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					char __user *user_buf,
1049e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					size_t count, loff_t *ppos)
1050e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{
105128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
105217f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar	return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
105317f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar			user_buf, count, ppos);
1054e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy}
1055e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1056e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1057e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					char __user *user_buf,
1058e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					size_t count, loff_t *ppos)
1059e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{
106028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
106117f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar	return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
106217f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar			user_buf, count, ppos);
1063e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy}
1064e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
10655225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guystatic ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
10665225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					char __user *user_buf,
10675225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					size_t count, loff_t *ppos) {
10685225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
106928f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
10705225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int pos = 0;
10715225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int cnt = 0;
10725225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	char *buf;
10735225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100;
10745225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ssize_t ret;
10755225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	struct iwl_sensitivity_data *data;
10765225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
10775225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	data = &priv->sensitivity_data;
10785225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
10795225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	if (!buf) {
10805225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
10815225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		return -ENOMEM;
10825225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
10835225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
10845225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
10855225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm);
10865225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
10875225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"auto_corr_ofdm_mrc:\t\t %u\n",
10885225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm_mrc);
10895225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
10905225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm_x1);
10915225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
10925225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"auto_corr_ofdm_mrc_x1:\t\t %u\n",
10935225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm_mrc_x1);
10945225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
10955225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_cck);
10965225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
10975225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_cck_mrc);
10985225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
10995225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"last_bad_plcp_cnt_ofdm:\t\t %u\n",
11005225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_bad_plcp_cnt_ofdm);
11015225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
11025225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_fa_cnt_ofdm);
11035225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
11045225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"last_bad_plcp_cnt_cck:\t\t %u\n",
11055225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_bad_plcp_cnt_cck);
11065225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
11075225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_fa_cnt_cck);
11085225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
11095225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_curr_state);
11105225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
11115225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_prev_state);
11125225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
11135225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < 10; cnt++) {
11145225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
11155225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->nrg_value[cnt]);
11165225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
11175225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
11185225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
11195225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
11205225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
11215225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->nrg_silence_rssi[cnt]);
11225225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
11235225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
11245225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
11255225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_silence_ref);
11265225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
11275225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_energy_idx);
11285225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
11295225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_silence_idx);
11305225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
11315225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_th_cck);
11325225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
11335225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"nrg_auto_corr_silence_diff:\t %u\n",
11345225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_auto_corr_silence_diff);
11355225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
11365225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->num_in_cck_no_fa);
11375225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
11385225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_th_ofdm);
11395225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
11405225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
11415225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	kfree(buf);
11425225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	return ret;
11435225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy}
11445225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
11455225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
11465225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guystatic ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
11475225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					char __user *user_buf,
11485225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					size_t count, loff_t *ppos) {
11495225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
115028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
11515225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int pos = 0;
11525225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int cnt = 0;
11535225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	char *buf;
11545225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100;
11555225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ssize_t ret;
11565225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	struct iwl_chain_noise_data *data;
11575225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
11585225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	data = &priv->chain_noise_data;
11595225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
11605225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	if (!buf) {
11615225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
11625225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		return -ENOMEM;
11635225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
11645225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
11655225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
11665225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->active_chains);
11675225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
11685225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_noise_a);
11695225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
11705225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_noise_b);
11715225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
11725225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_noise_c);
11735225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
11745225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_signal_a);
11755225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
11765225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_signal_b);
11775225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
11785225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_signal_c);
11795225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
11805225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->beacon_count);
11815225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
11825225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
11835225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
11845225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
11855225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->disconn_array[cnt]);
11865225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
11875225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
11885225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
11895225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
11905225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
11915225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->delta_gain_code[cnt]);
11925225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
11935225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
11945225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
11955225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->radio_write);
11965225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
11975225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->state);
11985225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
11995225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
12005225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	kfree(buf);
12015225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	return ret;
12025225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy}
12035225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
1204c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guystatic ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
1205c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy						    char __user *user_buf,
1206c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy						    size_t count, loff_t *ppos)
1207c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy{
120828f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1209c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	char buf[60];
1210c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	int pos = 0;
1211c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	const size_t bufsz = sizeof(buf);
1212c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	u32 pwrsave_status;
1213c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
1214c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) &
1215c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy			CSR_GP_REG_POWER_SAVE_STATUS_MSK;
1216c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
1217c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
1218c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
1219c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		(pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1220c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		(pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1221c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		(pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1222c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		"error");
1223c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
1224c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1225c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy}
1226c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
12277163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guystatic ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
1228ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy					 const char __user *user_buf,
1229ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy					 size_t count, loff_t *ppos)
1230ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy{
1231ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
1232ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	char buf[8];
1233ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	int buf_size;
1234ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	int clear;
1235ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
1236ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	memset(buf, 0, sizeof(buf));
1237ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
1238ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
1239ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy		return -EFAULT;
1240ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	if (sscanf(buf, "%d", &clear) != 1)
1241ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy		return -EFAULT;
1242ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
1243ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	/* make request to uCode to retrieve statistics information */
1244ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	mutex_lock(&priv->mutex);
1245ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	iwl_send_statistics_request(priv, CMD_SYNC, true);
1246ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	mutex_unlock(&priv->mutex);
1247ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
1248ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	return count;
1249ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy}
1250ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
1251696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guystatic ssize_t iwl_dbgfs_csr_write(struct file *file,
1252696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy					 const char __user *user_buf,
1253696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy					 size_t count, loff_t *ppos)
1254696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy{
1255696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
1256696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	char buf[8];
1257696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	int buf_size;
1258696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	int csr;
1259696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
1260696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	memset(buf, 0, sizeof(buf));
1261696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
1262696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
1263696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy		return -EFAULT;
1264696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	if (sscanf(buf, "%d", &csr) != 1)
1265696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy		return -EFAULT;
1266696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
1267696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	if (priv->cfg->ops->lib->dump_csr)
1268696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy		priv->cfg->ops->lib->dump_csr(priv);
1269696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
1270696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	return count;
1271696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy}
1272696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
1273a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
1274a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					char __user *user_buf,
1275a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					size_t count, loff_t *ppos) {
1276a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
127757674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches	struct iwl_priv *priv = file->private_data;
1278a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	int pos = 0;
1279a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	char buf[128];
1280a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	const size_t bufsz = sizeof(buf);
1281a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
1282a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
1283a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.ucode_trace ? "On" : "Off");
1284a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n",
1285a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.non_wraps_count);
1286a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n",
1287a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.wraps_once_count);
1288a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
1289a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.wraps_more_count);
1290a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
12914967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1292a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy}
1293a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
1294a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
1295a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					 const char __user *user_buf,
1296a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					 size_t count, loff_t *ppos)
1297a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy{
1298a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	struct iwl_priv *priv = file->private_data;
1299a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	char buf[8];
1300a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	int buf_size;
1301a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	int trace;
1302a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
1303a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	memset(buf, 0, sizeof(buf));
1304a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
1305a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
1306a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		return -EFAULT;
1307a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	if (sscanf(buf, "%d", &trace) != 1)
1308a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		return -EFAULT;
1309a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
1310a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	if (trace) {
1311a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		priv->event_log.ucode_trace = true;
1312a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		/* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
1313a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		mod_timer(&priv->ucode_trace,
1314a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
1315a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	} else {
1316a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		priv->event_log.ucode_trace = false;
1317a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		del_timer_sync(&priv->ucode_trace);
1318a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	}
1319a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
1320a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	return count;
1321a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy}
1322a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
132360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Bergstatic ssize_t iwl_dbgfs_rxon_flags_read(struct file *file,
132460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg					 char __user *user_buf,
132560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg					 size_t count, loff_t *ppos) {
132660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
132757674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches	struct iwl_priv *priv = file->private_data;
132860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	int len = 0;
132960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	char buf[20];
133060987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
1331246ed355221076884d225f9d8a4c30a048be8162Johannes Berg	len = sprintf(buf, "0x%04X\n",
1332246ed355221076884d225f9d8a4c30a048be8162Johannes Berg		le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags));
133360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
133460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg}
133560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
133660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Bergstatic ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file,
133760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg						char __user *user_buf,
133860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg						size_t count, loff_t *ppos) {
133960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
134057674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches	struct iwl_priv *priv = file->private_data;
134160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	int len = 0;
134260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	char buf[20];
134360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
134460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	len = sprintf(buf, "0x%04X\n",
1345246ed355221076884d225f9d8a4c30a048be8162Johannes Berg		le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags));
134660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
134760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg}
134860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
13491b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guystatic ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
13501b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy					 char __user *user_buf,
13511b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy					 size_t count, loff_t *ppos)
13521b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy{
135357674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches	struct iwl_priv *priv = file->private_data;
13541b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	char *buf;
13551b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	int pos = 0;
13561b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	ssize_t ret = -EFAULT;
13571b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy
13581b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	if (priv->cfg->ops->lib->dump_fh) {
13591b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy		ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true);
13601b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy		if (buf) {
13611b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy			ret = simple_read_from_buffer(user_buf,
13621b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy						      count, ppos, buf, pos);
13631b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy			kfree(buf);
13641b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy		}
13651b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	}
13661b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy
13671b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	return ret;
13681b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy}
13691b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy
1370a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guystatic ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
1371a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					char __user *user_buf,
1372a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					size_t count, loff_t *ppos) {
1373a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
1374a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
1375a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	int pos = 0;
1376a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	char buf[12];
1377a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	const size_t bufsz = sizeof(buf);
1378a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
1379a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
1380a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy			priv->missed_beacon_threshold);
1381a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
13824967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1383a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy}
1384a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
1385a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guystatic ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
1386a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					 const char __user *user_buf,
1387a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					 size_t count, loff_t *ppos)
1388a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy{
1389a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
1390a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	char buf[8];
1391a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	int buf_size;
1392a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	int missed;
1393a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
1394a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	memset(buf, 0, sizeof(buf));
1395a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
1396a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
1397a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		return -EFAULT;
1398a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	if (sscanf(buf, "%d", &missed) != 1)
1399a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		return -EINVAL;
1400a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
1401a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
1402a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	    missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
1403a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		priv->missed_beacon_threshold =
1404a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy			IWL_MISSED_BEACON_THRESHOLD_DEF;
1405a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	else
1406a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		priv->missed_beacon_threshold = missed;
1407a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
1408a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	return count;
1409a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy}
1410a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
14113e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyenstatic ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
14123e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					char __user *user_buf,
14133e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					size_t count, loff_t *ppos) {
14143e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
141557674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches	struct iwl_priv *priv = file->private_data;
14163e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	int pos = 0;
14173e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	char buf[12];
14183e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	const size_t bufsz = sizeof(buf);
14193e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
14203e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
14217cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy			priv->cfg->base_params->plcp_delta_threshold);
14223e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
14234967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
14243e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen}
14253e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
14263e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyenstatic ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
14273e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					const char __user *user_buf,
14283e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					size_t count, loff_t *ppos) {
14293e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
14303e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	struct iwl_priv *priv = file->private_data;
14313e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	char buf[8];
14323e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	int buf_size;
14333e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	int plcp;
14343e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
14353e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	memset(buf, 0, sizeof(buf));
14363e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	buf_size = min(count, sizeof(buf) -  1);
14373e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	if (copy_from_user(buf, user_buf, buf_size))
14383e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen		return -EFAULT;
14393e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	if (sscanf(buf, "%d", &plcp) != 1)
14403e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen		return -EINVAL;
1441680788aca3dcc24b932eb7a4219ab921ac5bf2d0Wey-Yi Guy	if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
14423e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen		(plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
14437cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		priv->cfg->base_params->plcp_delta_threshold =
1444680788aca3dcc24b932eb7a4219ab921ac5bf2d0Wey-Yi Guy			IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE;
14453e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	else
14467cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		priv->cfg->base_params->plcp_delta_threshold = plcp;
14473e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	return count;
14483e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen}
14493e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
1450528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guystatic ssize_t iwl_dbgfs_force_reset_read(struct file *file,
1451528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy					char __user *user_buf,
1452528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy					size_t count, loff_t *ppos) {
1453528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy
1454528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	struct iwl_priv *priv = file->private_data;
1455528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	int i, pos = 0;
1456528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	char buf[300];
1457528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	const size_t bufsz = sizeof(buf);
1458528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	struct iwl_force_reset *force_reset;
1459528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy
1460528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	for (i = 0; i < IWL_MAX_FORCE_RESET; i++) {
1461528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		force_reset = &priv->force_reset[i];
1462528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
1463528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"Force reset method %d\n", i);
1464528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
1465528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\tnumber of reset request: %d\n",
1466528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_request_count);
1467528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
1468528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\tnumber of reset request success: %d\n",
1469528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_success_count);
1470528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
1471528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\tnumber of reset request reject: %d\n",
1472528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_reject_count);
1473528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
1474528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\treset duration: %lu\n",
1475528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_duration);
1476528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	}
1477528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1478528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy}
1479528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy
148004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guystatic ssize_t iwl_dbgfs_force_reset_write(struct file *file,
148104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy					const char __user *user_buf,
148204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy					size_t count, loff_t *ppos) {
148304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy
148404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
148504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	char buf[8];
148604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	int buf_size;
148704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	int reset, ret;
148804cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy
148904cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	memset(buf, 0, sizeof(buf));
149004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
149104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
149204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		return -EFAULT;
149304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	if (sscanf(buf, "%d", &reset) != 1)
149404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		return -EINVAL;
149504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	switch (reset) {
149604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	case IWL_RF_RESET:
149704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	case IWL_FW_RESET:
1498c04f9f220300da83f71698fa7be24714152faf0dWey-Yi Guy		ret = iwl_force_reset(priv, reset, true);
149904cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		break;
150004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	default:
150104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		return -EINVAL;
150204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	}
150304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	return ret ? ret : count;
150404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy}
150504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy
15064bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guystatic ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
15074bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy					const char __user *user_buf,
15084bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy					size_t count, loff_t *ppos) {
15094bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
15104bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	struct iwl_priv *priv = file->private_data;
15114bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	char buf[8];
15124bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	int buf_size;
15134bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	int flush;
15144bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
15154bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	memset(buf, 0, sizeof(buf));
15164bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
15174bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
15184bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy		return -EFAULT;
15194bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	if (sscanf(buf, "%d", &flush) != 1)
15204bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy		return -EINVAL;
15214bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
15224bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	if (iwl_is_rfkill(priv))
15234bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy		return -EFAULT;
15244bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
15254bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL);
15264bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
15274bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	return count;
15284bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy}
15294bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
1530ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
1531ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy					char __user *user_buf,
1532ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy					size_t count, loff_t *ppos)
1533ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy{
1534ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1535ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy
1536ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy	return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file,
1537ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy			user_buf, count, ppos);
1538ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy}
1539ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy
15407bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guystatic ssize_t iwl_dbgfs_monitor_period_write(struct file *file,
15417bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy					const char __user *user_buf,
15427bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy					size_t count, loff_t *ppos) {
15437bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy
15447bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	struct iwl_priv *priv = file->private_data;
15457bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	char buf[8];
15467bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	int buf_size;
15477bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	int period;
15487bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy
15497bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	memset(buf, 0, sizeof(buf));
15507bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
15517bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
15527bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy		return -EFAULT;
15537bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	if (sscanf(buf, "%d", &period) != 1)
15547bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy		return -EINVAL;
15557bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	if (period < 0 || period > IWL_MAX_MONITORING_PERIOD)
15567cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		priv->cfg->base_params->monitor_recover_period =
15577cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy			IWL_DEF_MONITORING_PERIOD;
15587bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	else
15597cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		priv->cfg->base_params->monitor_recover_period = period;
15607bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy
15617cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (priv->cfg->base_params->monitor_recover_period)
15627bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy		mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies(
15637cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy			  priv->cfg->base_params->monitor_recover_period));
15647bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	else
15657bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy		del_timer_sync(&priv->monitor_recover);
15667bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	return count;
15677bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy}
15687bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy
1569befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guystatic ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
1570befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy					char __user *user_buf,
1571befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy					size_t count, loff_t *ppos) {
1572befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy
1573befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1574befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	int pos = 0;
1575befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	char buf[200];
1576befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	const size_t bufsz = sizeof(buf);
1577befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	ssize_t ret;
1578befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy
1579befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n",
1580befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		priv->bt_full_concurrent ? "full concurrency" : "3-wire");
1581befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, "
1582befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy			 "last traffic notif: %d\n",
158366e863a527f9ed3a871797862aaf0d62b0954813Wey-Yi Guy		priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load);
1584befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, "
1585befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy			 "sco_active: %d, kill_ack_mask: %x, "
1586befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy			 "kill_cts_mask: %x\n",
1587befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		priv->bt_ch_announce, priv->bt_sco_active,
1588befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		priv->kill_ack_mask, priv->kill_cts_mask);
1589befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy
1590befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: ");
1591befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	switch (priv->bt_traffic_load) {
1592befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1593befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "Continuous\n");
1594befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		break;
1595befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1596befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "High\n");
1597befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		break;
1598befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1599befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "Low\n");
1600befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		break;
1601befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1602befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	default:
1603befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "None\n");
1604befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		break;
1605befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	}
1606befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy
1607befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1608befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	return ret;
1609befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy}
1610befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy
1611c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guystatic ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
1612c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy					char __user *user_buf,
1613c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy					size_t count, loff_t *ppos)
1614c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy{
1615c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1616c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
1617c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	int pos = 0;
1618c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	char buf[40];
1619c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	const size_t bufsz = sizeof(buf);
1620c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
16217cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (priv->cfg->ht_params)
16227cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
16237cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy			 "use %s for aggregation\n",
16247cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy			 (priv->cfg->ht_params->use_rts_for_aggregation) ?
16257cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy				"rts/cts" : "cts-to-self");
16267cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	else
16277cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "N/A");
16287cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy
1629c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1630c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy}
1631c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
1632c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guystatic ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
1633c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy					const char __user *user_buf,
1634c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy					size_t count, loff_t *ppos) {
1635c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
1636c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	struct iwl_priv *priv = file->private_data;
1637c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	char buf[8];
1638c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	int buf_size;
1639c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	int rts;
1640c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
16417cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (!priv->cfg->ht_params)
16427cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		return -EINVAL;
16437cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy
1644c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	memset(buf, 0, sizeof(buf));
1645c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
1646c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
1647c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy		return -EFAULT;
1648c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	if (sscanf(buf, "%d", &rts) != 1)
1649c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy		return -EINVAL;
1650c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	if (rts)
16517cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		priv->cfg->ht_params->use_rts_for_aggregation = true;
1652c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	else
16537cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		priv->cfg->ht_params->use_rts_for_aggregation = false;
1654c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	return count;
1655c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy}
1656c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
165754a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guystatic ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
165854a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy					char __user *user_buf,
165954a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy					size_t count, loff_t *ppos)
166054a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy{
166154a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy	struct iwl_priv *priv = file->private_data;
166254a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy
166354a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy	if (priv->cfg->ops->lib->debugfs_ops.reply_tx_error)
166454a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy		return priv->cfg->ops->lib->debugfs_ops.reply_tx_error(
166554a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy			file, user_buf, count, ppos);
166654a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy	else
166754a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy		return -ENODATA;
166854a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy}
16697163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_READ_FILE_OPS(rx_statistics);
16707163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_READ_FILE_OPS(tx_statistics);
167120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
1672141b03e07a54af68fc099459bf780a182b240b45Wey-Yi GuyDEBUGFS_READ_FILE_OPS(rx_queue);
1673141b03e07a54af68fc099459bf780a182b240b45Wey-Yi GuyDEBUGFS_READ_FILE_OPS(tx_queue);
1674e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1675e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1676e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_general_stats);
16775225935b53ce1eafb222c644230d03ad6011d357Wey-Yi GuyDEBUGFS_READ_FILE_OPS(sensitivity);
16785225935b53ce1eafb222c644230d03ad6011d357Wey-Yi GuyDEBUGFS_READ_FILE_OPS(chain_noise);
1679c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi GuyDEBUGFS_READ_FILE_OPS(power_save_status);
16807163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
16817163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
1682696bdee3ba216186e21997d20a839b76158346e6Wey-Yi GuyDEBUGFS_WRITE_FILE_OPS(csr);
1683a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
16841b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi GuyDEBUGFS_READ_FILE_OPS(fh_reg);
1685a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
16863e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' NguyenDEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
1687528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(force_reset);
168860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes BergDEBUGFS_READ_FILE_OPS(rxon_flags);
168960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes BergDEBUGFS_READ_FILE_OPS(rxon_filter_flags);
16904bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(txfifo_flush);
1691ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_bt_stats);
16927bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(monitor_period);
1693befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi GuyDEBUGFS_READ_FILE_OPS(bt_traffic);
1694c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
169554a9aa65f749673f851ef86481940394185c1b0eWey-Yi GuyDEBUGFS_READ_FILE_OPS(reply_tx_error);
169620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
1697712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/*
1698712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Create the debugfs files and directories
1699712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
1700712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */
1701712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerint iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1702712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
170395b1a8224abf6230899856753c5506a3f737a65bZhu Yi	struct dentry *phyd = priv->hw->wiphy->debugfsdir;
17044c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1705712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
17064c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_drv = debugfs_create_dir(name, phyd);
17074c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_drv)
17084c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		return -ENOMEM;
1709712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
17104c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	priv->debugfs_dir = dir_drv;
17114c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg
17124c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_data = debugfs_create_dir("data", dir_drv);
17134c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_data)
17144c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;
17154c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_rf = debugfs_create_dir("rf", dir_drv);
17164c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_rf)
17174c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;
17184c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_debug = debugfs_create_dir("debug", dir_drv);
17194c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_debug)
1720712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		goto err;
1721712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
17224c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
17234c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
17244c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
17254c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
17264c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
17274c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
17284c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
17294c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
17304c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
17317cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (!priv->cfg->base_params->broken_powersave) {
1732381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy		DEBUGFS_ADD_FILE(sleep_level_override, dir_data,
1733381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy				 S_IWUSR | S_IRUSR);
1734381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy		DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
1735381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy	}
17364c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
17374c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
17384c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
17394c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
17404c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
17414c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
17424c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
17434c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
17444c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
17454c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
17464c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
17474c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
17484c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
17494c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
1750528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
1751b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar	DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1752b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar	DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1753b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar	DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
17544bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	if (priv->cfg->ops->lib->dev_txfifo_flush)
17554bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy		DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
1756c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR);
1757b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar
17587cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (priv->cfg->base_params->sensitivity_calib_by_driver)
17594c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
17607cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (priv->cfg->base_params->chain_noise_calib_by_driver)
17614c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
17627cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (priv->cfg->base_params->ucode_tracing)
17634c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
17647cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics)
1765ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy		DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
176654a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy	DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
176760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
176860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
17697bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR);
17707cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
1771befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
17727cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (priv->cfg->base_params->sensitivity_calib_by_driver)
177365d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy		DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
177465d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy				 &priv->disable_sens_cal);
17757cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (priv->cfg->base_params->chain_noise_calib_by_driver)
177665d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy		DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
177765d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy				 &priv->disable_chain_noise_cal);
17787cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (priv->cfg->base_params->tx_power_by_driver)
17794c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
1780030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy				&priv->disable_tx_power_cal);
1781712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return 0;
1782712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
1783712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklererr:
17844c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	IWL_ERR(priv, "Can't create the debugfs directory\n");
1785712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	iwl_dbgfs_unregister(priv);
17864c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	return -ENOMEM;
1787712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
1788712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerEXPORT_SYMBOL(iwl_dbgfs_register);
1789712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
1790712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/**
1791712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Remove the debugfs files and directories
1792712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
1793712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */
1794712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklervoid iwl_dbgfs_unregister(struct iwl_priv *priv)
1795712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
17964c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!priv->debugfs_dir)
1797712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		return;
1798712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
17994c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	debugfs_remove_recursive(priv->debugfs_dir);
18004c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	priv->debugfs_dir = NULL;
1801712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
1802712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerEXPORT_SYMBOL(iwl_dbgfs_unregister);
1803712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
1804712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
1805445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler
1806