iwl-debugfs.c revision d618912417fbce4f6514fe1cbef7df2e73bdb6c2
1712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/******************************************************************************
2712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
3712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * GPL LICENSE SUMMARY
4712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
5901069c71415a76d731857ccda814e18ded062f7Wey-Yi Guy * Copyright(c) 2008 - 2011 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"
42d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy#include "iwl-agn.h"
43712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
44712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* create and remove of files */
454c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_FILE(name, parent, mode) do {			\
464c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!debugfs_create_file(#name, mode, parent, priv,		\
474c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg				 &iwl_dbgfs_##name##_ops))		\
484c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;						\
49712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} while (0)
50712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
514c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_BOOL(name, parent, ptr) do {			\
524c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	struct dentry *__tmp;						\
534c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	__tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR,		\
544c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg				    parent, ptr);			\
554c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (IS_ERR(__tmp) || !__tmp)					\
564c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;						\
57712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} while (0)
58712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
594c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_X32(name, parent, ptr) do {				\
604c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	struct dentry *__tmp;						\
614c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	__tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR,		\
624c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg				   parent, ptr);			\
634c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (IS_ERR(__tmp) || !__tmp)					\
644c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;						\
65445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler} while (0)
66445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler
67712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* file operation */
68712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_FUNC(name)                                         \
69712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_##name##_read(struct file *file,               \
70712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					char __user *user_buf,          \
71712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos);
72712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
73712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_WRITE_FUNC(name)                                        \
74712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_##name##_write(struct file *file,              \
75712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					const char __user *user_buf,    \
76712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos);
77712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
78712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
79712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
80712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
81712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	file->private_data = inode->i_private;
82712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return 0;
83712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
84712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
85712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_FILE_OPS(name)                                     \
86712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	DEBUGFS_READ_FUNC(name);                                        \
87712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic const struct file_operations iwl_dbgfs_##name##_ops = {          \
88712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.read = iwl_dbgfs_##name##_read,                       		\
89712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.open = iwl_dbgfs_open_file_generic,                    	\
902b18ab36cf7e956fb5b5ee12847e94fc66d496f4Arnd Bergmann	.llseek = generic_file_llseek,					\
91712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler};
92712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
93189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer#define DEBUGFS_WRITE_FILE_OPS(name)                                    \
94189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	DEBUGFS_WRITE_FUNC(name);                                       \
95189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummerstatic const struct file_operations iwl_dbgfs_##name##_ops = {          \
96189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	.write = iwl_dbgfs_##name##_write,                              \
97189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	.open = iwl_dbgfs_open_file_generic,                    	\
982b18ab36cf7e956fb5b5ee12847e94fc66d496f4Arnd Bergmann	.llseek = generic_file_llseek,					\
99189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer};
100189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
101189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
102712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_WRITE_FILE_OPS(name)                               \
103712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	DEBUGFS_READ_FUNC(name);                                        \
104712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	DEBUGFS_WRITE_FUNC(name);                                       \
105712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic const struct file_operations iwl_dbgfs_##name##_ops = {          \
106712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.write = iwl_dbgfs_##name##_write,                              \
107712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.read = iwl_dbgfs_##name##_read,                                \
108712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.open = iwl_dbgfs_open_file_generic,                            \
1092b18ab36cf7e956fb5b5ee12847e94fc66d496f4Arnd Bergmann	.llseek = generic_file_llseek,					\
110712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler};
111712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
112712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
113712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						char __user *user_buf,
114712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						size_t count, loff_t *ppos) {
115712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
11628f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
11722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	char *buf;
118712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int pos = 0;
119712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
12022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	int cnt;
12122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ssize_t ret;
12298a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy	const size_t bufsz = 100 +
12398a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy		sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
12422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
12522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (!buf)
12622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -ENOMEM;
12722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
12822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
12922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
13098a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
13122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_mgmt_string(cnt),
13222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->tx_stats.mgmt[cnt]);
13322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
13422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
13522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
13622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
13798a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
13822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_ctrl_string(cnt),
13922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->tx_stats.ctrl[cnt]);
14022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
14122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
14222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
14322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->tx_stats.data_cnt);
14422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
14522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->tx_stats.data_bytes);
14622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
14722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	kfree(buf);
14822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	return ret;
14922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy}
15022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy
1517163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guystatic ssize_t iwl_dbgfs_clear_traffic_statistics_write(struct file *file,
15222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy					const char __user *user_buf,
15322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy					size_t count, loff_t *ppos)
15422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy{
15522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
15622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	u32 clear_flag;
15722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	char buf[8];
15822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	int buf_size;
159712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
16022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	memset(buf, 0, sizeof(buf));
16122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
16222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
16322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -EFAULT;
16422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (sscanf(buf, "%x", &clear_flag) != 1)
16522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -EFAULT;
1667163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guy	iwl_clear_traffic_stats(priv);
16722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy
16822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	return count;
169712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
170712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
171712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
172712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						char __user *user_buf,
173712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						size_t count, loff_t *ppos) {
174712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
17528f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
17622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	char *buf;
177712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int pos = 0;
17822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	int cnt;
17922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ssize_t ret;
18022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	const size_t bufsz = 100 +
18198a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy		sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
18222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
18322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (!buf)
18422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -ENOMEM;
185712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
18622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
18722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
18822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
18998a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
19022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_mgmt_string(cnt),
19122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->rx_stats.mgmt[cnt]);
19222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
19322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
19422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
19522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
19698a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
19722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_ctrl_string(cnt),
19822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->rx_stats.ctrl[cnt]);
19922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
20022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
20122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
20222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->rx_stats.data_cnt);
20322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
20422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->rx_stats.data_bytes);
205712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
20622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
20722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	kfree(buf);
20822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	return ret;
20922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy}
21022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy
211712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_sram_read(struct file *file,
212712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					char __user *user_buf,
213712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos)
214712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
21524834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	u32 val = 0;
2162943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	char *buf;
217712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ssize_t ret;
21824834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	int i = 0;
21924834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	bool device_format = false;
22024834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	int offset = 0;
22124834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	int len = 0;
222712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int pos = 0;
22324834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	int sram;
22428f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
2252943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	size_t bufsz;
226712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
2275ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	/* default is to dump the entire data segment */
2284c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
2294c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_offset = 0x800000;
230872907bb17fe2d8d01d0e9723f72f91cb4ea103fJohannes Berg		if (priv->ucode_type == IWL_UCODE_INIT)
231dbf28e21ca391110e90ccad05dda79d2e2f60e0eJohannes Berg			priv->dbgfs_sram_len = priv->ucode_init.data.len;
2325ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy		else
233dbf28e21ca391110e90ccad05dda79d2e2f60e0eJohannes Berg			priv->dbgfs_sram_len = priv->ucode_rt.data.len;
2345ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	}
23524834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	len = priv->dbgfs_sram_len;
23624834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg
23724834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	if (len == -4) {
23824834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		device_format = true;
23924834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		len = 4;
24024834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	}
24124834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg
24224834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	bufsz =  50 + len * 4;
2432943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	buf = kmalloc(bufsz, GFP_KERNEL);
2442943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	if (!buf)
2452943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy		return -ENOMEM;
24624834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg
2475ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
24824834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg			 len);
2495ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
2504c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg			priv->dbgfs_sram_offset);
25124834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg
25224834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	/* adjust sram address since reads are only on even u32 boundaries */
25324834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	offset = priv->dbgfs_sram_offset & 0x3;
25424834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	sram = priv->dbgfs_sram_offset & ~0x3;
25524834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg
25624834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	/* read the first u32 from sram */
25724834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	val = iwl_read_targ_mem(priv, sram);
25824834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg
25924834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	for (; len; len--) {
26024834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		/* put the address at the start of every line */
26124834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		if (i == 0)
26224834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg			pos += scnprintf(buf + pos, bufsz - pos,
26324834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg				"%08X: ", sram + offset);
26424834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg
26524834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		if (device_format)
26624834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg			pos += scnprintf(buf + pos, bufsz - pos,
26724834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg				"%02x", (val >> (8 * (3 - offset))) & 0xff);
26824834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		else
26924834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg			pos += scnprintf(buf + pos, bufsz - pos,
27024834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg				"%02x ", (val >> (8 * offset)) & 0xff);
27124834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg
27224834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		/* if all bytes processed, read the next u32 from sram */
27324834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		if (++offset == 4) {
27424834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg			sram += 4;
27524834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg			offset = 0;
27624834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg			val = iwl_read_targ_mem(priv, sram);
277712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		}
27824834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg
27924834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		/* put in extra spaces and split lines for human readability */
28024834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		if (++i == 16) {
28124834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg			i = 0;
2822943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos, "\n");
28324834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		} else if (!(i & 7)) {
28424834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg			pos += scnprintf(buf + pos, bufsz - pos, "   ");
28524834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		} else if (!(i & 3)) {
28624834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg			pos += scnprintf(buf + pos, bufsz - pos, " ");
28724834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		}
288712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	}
28924834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	if (i)
29024834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		pos += scnprintf(buf + pos, bufsz - pos, "\n");
291712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
292712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2932943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	kfree(buf);
294712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return ret;
295712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
296712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
297712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_sram_write(struct file *file,
298712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					const char __user *user_buf,
299712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos)
300712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
301712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	struct iwl_priv *priv = file->private_data;
302712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	char buf[64];
303712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int buf_size;
304712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	u32 offset, len;
305712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
306712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	memset(buf, 0, sizeof(buf));
307712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	buf_size = min(count, sizeof(buf) -  1);
308712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	if (copy_from_user(buf, user_buf, buf_size))
309712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		return -EFAULT;
310712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
311712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
3124c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_offset = offset;
3134c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_len = len;
31424834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg	} else if (sscanf(buf, "%x", &offset) == 1) {
31524834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		priv->dbgfs_sram_offset = offset;
31624834d2c8455a6eeee82e007d41d7e05986d134fJay Sternberg		priv->dbgfs_sram_len = -4;
317712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	} else {
3184c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_offset = 0;
3194c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_len = 0;
320712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	}
321712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
322712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return count;
323712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
324712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
325c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Bergstatic ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
326c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg					  char __user *user_buf,
327c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg					  size_t count, loff_t *ppos)
328c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg{
329c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg	struct iwl_priv *priv = file->private_data;
330c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg
331c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg	if (!priv->wowlan_sram)
332c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg		return -ENODATA;
333c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg
334c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg	return simple_read_from_buffer(user_buf, count, ppos,
335c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg				       priv->wowlan_sram,
336c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg				       priv->ucode_wowlan.data.len);
337c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg}
338712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
339712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos)
340712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
34128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
3426def9761f72501e638e79eebcd70afea12a3a93dTomas Winkler	struct iwl_station_entry *station;
343d618912417fbce4f6514fe1cbef7df2e73bdb6c2Emmanuel Grumbach	int max_sta = hw_params(priv).max_stations;
344712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	char *buf;
345712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int i, j, pos = 0;
346712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ssize_t ret;
347712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	/* Add 30 for initial string */
348712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations);
349712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
350712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	buf = kmalloc(bufsz, GFP_KERNEL);
3513ac7f14694dd38273d9d96f1c873233d71190c15Tomas Winkler	if (!buf)
352712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		return -ENOMEM;
353712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
354db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar	pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
355712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			priv->num_stations);
356712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
357712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	for (i = 0; i < max_sta; i++) {
358712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		station = &priv->stations[i];
359da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		if (!station->used)
360da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg			continue;
361da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		pos += scnprintf(buf + pos, bufsz - pos,
362da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				 "station %d - addr: %pM, flags: %#x\n",
363da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				 i, station->sta.sta.addr,
364da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				 station->sta.station_flags_msk);
365da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		pos += scnprintf(buf + pos, bufsz - pos,
366da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				"TID\tseq_num\ttxq_id\tframes\ttfds\t");
367da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		pos += scnprintf(buf + pos, bufsz - pos,
368da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				"start_idx\tbitmap\t\t\trate_n_flags\n");
369712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
370da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		for (j = 0; j < MAX_TID_COUNT; j++) {
371da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg			pos += scnprintf(buf + pos, bufsz - pos,
372da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				"%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
373da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				j, station->tid[j].seq_number,
374da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].agg.txq_id,
375da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].agg.frame_count,
376da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].tfds_in_queue,
377da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].agg.start_idx,
378da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].agg.bitmap,
379da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg				station->tid[j].agg.rate_n_flags);
380da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg
381da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg			if (station->tid[j].agg.wait_for_ba)
382db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar				pos += scnprintf(buf + pos, bufsz - pos,
383da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg						 " - waitforba");
384db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos, "\n");
385712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		}
386da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg
387da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg		pos += scnprintf(buf + pos, bufsz - pos, "\n");
388712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	}
389712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
390712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
391712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	kfree(buf);
392712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return ret;
393712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
394712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
3950848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guystatic ssize_t iwl_dbgfs_nvm_read(struct file *file,
3968dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				       char __user *user_buf,
3978dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				       size_t count,
3988dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				       loff_t *ppos)
3998dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler{
4008dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	ssize_t ret;
40128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
4028dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	int pos = 0, ofs = 0, buf_size = 0;
4038dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	const u8 *ptr;
4048dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	char *buf;
405e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy	u16 eeprom_ver;
4067cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	size_t eeprom_len = priv->cfg->base_params->eeprom_size;
4078dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	buf_size = 4 * eeprom_len + 256;
4088dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler
4098dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	if (eeprom_len % 16) {
4100848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy		IWL_ERR(priv, "NVM size is not multiple of 16.\n");
4118dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		return -ENODATA;
4128dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	}
4138dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler
414c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall	ptr = priv->eeprom;
415c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall	if (!ptr) {
416c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall		IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
417c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall		return -ENOMEM;
418c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall	}
419c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall
4208dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	/* 4 characters for byte 0xYY */
4218dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	buf = kzalloc(buf_size, GFP_KERNEL);
4228dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	if (!buf) {
42315b1687cb4f45b87ddbe4dfc7759ff5bb69497d2Winkler, Tomas		IWL_ERR(priv, "Can not allocate Buffer\n");
4248dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		return -ENOMEM;
4258dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	}
426e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
427e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy	pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, "
428e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy			"version: 0x%x\n",
4290848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy			(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
430e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy			 ? "OTP" : "EEPROM", eeprom_ver);
4318dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
4328dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
4338dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
4348dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				   buf_size - pos, 0);
4352fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre		pos += strlen(buf + pos);
4368dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		if (buf_size - pos > 0)
4378dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler			buf[pos++] = '\n';
4388dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	}
4398dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler
4408dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
4418dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	kfree(buf);
4428dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	return ret;
4438dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler}
444712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
445b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guystatic ssize_t iwl_dbgfs_log_event_read(struct file *file,
446b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy					 char __user *user_buf,
447b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy					 size_t count, loff_t *ppos)
448b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy{
449b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	struct iwl_priv *priv = file->private_data;
450b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	char *buf;
451b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	int pos = 0;
452b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	ssize_t ret = -ENOMEM;
453b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy
4543ecccbcd3c67374aeee447c08fcb9e39a99f7ee5Wey-Yi Guy	ret = pos = iwl_dump_nic_event_log(priv, true, &buf, true);
455937c397eb633b804d9a806d08c395ecfc42b1fecWey-Yi Guy	if (buf) {
456b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy		ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
457b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy		kfree(buf);
458b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	}
459b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	return ret;
460b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy}
461b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy
462189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummerstatic ssize_t iwl_dbgfs_log_event_write(struct file *file,
463189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer					const char __user *user_buf,
464189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer					size_t count, loff_t *ppos)
465189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer{
466189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	struct iwl_priv *priv = file->private_data;
467189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	u32 event_log_flag;
468189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	char buf[8];
469189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	int buf_size;
470189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
471189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	memset(buf, 0, sizeof(buf));
472189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	buf_size = min(count, sizeof(buf) -  1);
473189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	if (copy_from_user(buf, user_buf, buf_size))
474189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer		return -EFAULT;
475189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	if (sscanf(buf, "%d", &event_log_flag) != 1)
476189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer		return -EFAULT;
477189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	if (event_log_flag == 1)
4783ecccbcd3c67374aeee447c08fcb9e39a99f7ee5Wey-Yi Guy		iwl_dump_nic_event_log(priv, true, NULL, false);
479189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
480189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	return count;
481189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer}
482189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
483d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
484d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
485d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomasstatic ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
486d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas				       size_t count, loff_t *ppos)
487d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas{
48828f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
489d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	struct ieee80211_channel *channels = NULL;
490d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	const struct ieee80211_supported_band *supp_band = NULL;
491d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	int pos = 0, i, bufsz = PAGE_SIZE;
492d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	char *buf;
493d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	ssize_t ret;
494d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
495d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
496d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		return -EAGAIN;
497d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
498d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	buf = kzalloc(bufsz, GFP_KERNEL);
499d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	if (!buf) {
50015b1687cb4f45b87ddbe4dfc7759ff5bb69497d2Winkler, Tomas		IWL_ERR(priv, "Can not allocate Buffer\n");
501d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		return -ENOMEM;
502d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	}
503d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
504d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
505a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	if (supp_band) {
506a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		channels = supp_band->channels;
507d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
508d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		pos += scnprintf(buf + pos, bufsz - pos,
509a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				"Displaying %d channels in 2.4GHz band 802.11bg):\n",
510a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				supp_band->n_channels);
511d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
512a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		for (i = 0; i < supp_band->n_channels; i++)
513a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
514a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"%d: %ddBm: BSS%s%s, %s.\n",
51581e95430aaa898799421617c2db2882386bab69aShanyu Zhao					channels[i].hw_value,
516a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].max_power,
517a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags & IEEE80211_CHAN_RADAR ?
518a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					" (IEEE 802.11h required)" : "",
519a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
520a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					|| (channels[i].flags &
521a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_RADAR)) ? "" :
522a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					", IBSS",
523a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags &
524a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_PASSIVE_SCAN ?
525a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"passive only" : "active/passive");
526a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	}
527d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
528a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	if (supp_band) {
529a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		channels = supp_band->channels;
530d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
531d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		pos += scnprintf(buf + pos, bufsz - pos,
532a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				"Displaying %d channels in 5.2GHz band (802.11a)\n",
533a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				supp_band->n_channels);
534a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy
535a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		for (i = 0; i < supp_band->n_channels; i++)
536a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
537a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"%d: %ddBm: BSS%s%s, %s.\n",
53881e95430aaa898799421617c2db2882386bab69aShanyu Zhao					channels[i].hw_value,
539a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].max_power,
540a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags & IEEE80211_CHAN_RADAR ?
541a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					" (IEEE 802.11h required)" : "",
542a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
543a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					|| (channels[i].flags &
544a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_RADAR)) ? "" :
545a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					", IBSS",
546a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags &
547a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_PASSIVE_SCAN ?
548a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"passive only" : "active/passive");
549a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	}
550d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
551d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	kfree(buf);
552d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	return ret;
553d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas}
554d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
55508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guystatic ssize_t iwl_dbgfs_status_read(struct file *file,
55608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy						char __user *user_buf,
55708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy						size_t count, loff_t *ppos) {
55808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy
55928f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
56008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	char buf[512];
56108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	int pos = 0;
56208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	const size_t bufsz = sizeof(buf);
56308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy
56408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
56508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_HCMD_ACTIVE, &priv->status));
56608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
56708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_INT_ENABLED, &priv->status));
56808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
56908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_RF_KILL_HW, &priv->status));
5707812b16730ccebce71a3b2228ac08dd4f8b39469Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n",
5717812b16730ccebce71a3b2228ac08dd4f8b39469Wey-Yi Guy		test_bit(STATUS_CT_KILL, &priv->status));
57208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
57308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_INIT, &priv->status));
57408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
57508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_ALIVE, &priv->status));
57608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
57708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_READY, &priv->status));
57808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
57908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_TEMPERATURE, &priv->status));
58008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
58108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_GEO_CONFIGURED, &priv->status));
58208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
58308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_EXIT_PENDING, &priv->status));
58408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
58508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_STATISTICS, &priv->status));
58608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
58708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_SCANNING, &priv->status));
58808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
58908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_SCAN_ABORTING, &priv->status));
59008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
59108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_SCAN_HW, &priv->status));
59208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
59308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_POWER_PMI, &priv->status));
59408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
59508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_FW_ERROR, &priv->status));
59608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
59708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy}
59808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy
599a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_read(struct file *file,
600a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					char __user *user_buf,
601a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					size_t count, loff_t *ppos) {
602a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
60328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
604a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int pos = 0;
605a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int cnt = 0;
606a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	char *buf;
607a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int bufsz = 24 * 64; /* 24 items * 64 char per item */
608a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	ssize_t ret;
609a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
610a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
611a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (!buf) {
612a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
613a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		return -ENOMEM;
614a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	}
615a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
616a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
617a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy			"Interrupt Statistics Report:\n");
618a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
619a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
620a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.hw);
621a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
622a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.sw);
6236e6ebf4befa75ebdf28130d0135f3ad3aadc02f8Wey-Yi Guy	if (priv->isr_stats.sw || priv->isr_stats.hw) {
624a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
625a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy			"\tLast Restarting Code:  0x%X\n",
6266e6ebf4befa75ebdf28130d0135f3ad3aadc02f8Wey-Yi Guy			priv->isr_stats.err_code);
627a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	}
628a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#ifdef CONFIG_IWLWIFI_DEBUG
629a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
630a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.sch);
631a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
632a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.alive);
633a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#endif
634a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
635a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		"HW RF KILL switch toggled:\t %u\n",
636a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.rfkill);
637a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
638a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
639a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.ctkill);
640a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
641a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
642a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.wakeup);
643a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
644a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
645a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		"Rx command responses:\t\t %u\n",
646a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.rx);
647a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	for (cnt = 0; cnt < REPLY_MAX; cnt++) {
648a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		if (priv->isr_stats.rx_handlers[cnt] > 0)
649a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
650a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy				"\tRx handler[%36s]:\t\t %u\n",
651a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy				get_cmd_string(cnt),
652a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy				priv->isr_stats.rx_handlers[cnt]);
653a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	}
654a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
655a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
656a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.tx);
657a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
658a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
659a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.unhandled);
660a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
661a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
662a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	kfree(buf);
663a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	return ret;
664a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy}
665a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
666a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_write(struct file *file,
667a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					 const char __user *user_buf,
668a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					 size_t count, loff_t *ppos)
669a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy{
670a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
671a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	char buf[8];
672a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int buf_size;
673a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	u32 reset_flag;
674a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
675a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	memset(buf, 0, sizeof(buf));
676a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
677a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
678a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		return -EFAULT;
679a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (sscanf(buf, "%x", &reset_flag) != 1)
680a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		return -EFAULT;
681a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (reset_flag == 0)
682a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		iwl_clear_isr_stats(priv);
683a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
684a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	return count;
685a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy}
686a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
687f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guystatic ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
688f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy				       size_t count, loff_t *ppos)
689f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy{
69028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
6918dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg	struct iwl_rxon_context *ctx;
692f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy	int pos = 0, i;
6938dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg	char buf[256 * NUM_IWL_RXON_CTX];
694f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy	const size_t bufsz = sizeof(buf);
695f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy
6968dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg	for_each_context(priv, ctx) {
6978dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg		pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n",
6988dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				 ctx->ctxid);
6998dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg		for (i = 0; i < AC_NUM; i++) {
7008dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg			pos += scnprintf(buf + pos, bufsz - pos,
7018dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				"\tcw_min\tcw_max\taifsn\ttxop\n");
7028dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg			pos += scnprintf(buf + pos, bufsz - pos,
703f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy				"AC[%d]\t%u\t%u\t%u\t%u\n", i,
7048dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				ctx->qos_data.def_qos_parm.ac[i].cw_min,
7058dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				ctx->qos_data.def_qos_parm.ac[i].cw_max,
7068dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				ctx->qos_data.def_qos_parm.ac[i].aifsn,
7078dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg				ctx->qos_data.def_qos_parm.ac[i].edca_txop);
7088dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg		}
7098dfdb9d5757424f7018a643258065c4fc8e6a439Johannes Berg		pos += scnprintf(buf + pos, bufsz - pos, "\n");
710f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy	}
7114967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
712f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy}
713a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
714fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guystatic ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
715fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				char __user *user_buf,
716fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				size_t count, loff_t *ppos)
717fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy{
71828f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
7193ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
720fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	struct iwl_tt_restriction *restriction;
721fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	char buf[100];
722fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	int pos = 0;
723fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	const size_t bufsz = sizeof(buf);
724fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy
725fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
726fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy			"Thermal Throttling Mode: %s\n",
7273ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg			tt->advanced_tt ? "Advance" : "Legacy");
728fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
729fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy			"Thermal Throttling State: %d\n",
730fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy			tt->state);
7313ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg	if (tt->advanced_tt) {
732fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		restriction = tt->restriction + tt->state;
733fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
734fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				"Tx mode: %d\n",
735fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				restriction->tx_stream);
736fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
737fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				"Rx mode: %d\n",
738fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				restriction->rx_stream);
739fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
740fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				"HT mode: %d\n",
741fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				restriction->is_ht);
742fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	}
7434967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
744fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy}
745fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy
7461e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guystatic ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
7471e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 const char __user *user_buf,
7481e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 size_t count, loff_t *ppos)
7491e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy{
7501e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
7511e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	char buf[8];
7521e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	int buf_size;
7531e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	int ht40;
7541e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7551e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	memset(buf, 0, sizeof(buf));
7561e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
7571e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
7581e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		return -EFAULT;
7591e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	if (sscanf(buf, "%d", &ht40) != 1)
7601e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		return -EFAULT;
761246ed355221076884d225f9d8a4c30a048be8162Johannes Berg	if (!iwl_is_any_associated(priv))
7621e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		priv->disable_ht40 = ht40 ? true : false;
7631e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	else {
7641e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		IWL_ERR(priv, "Sta associated with AP - "
7651e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy			"Change to 40MHz channel support is not allowed\n");
7661e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		return -EINVAL;
7671e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	}
7681e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7691e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	return count;
7701e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy}
7711e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7721e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guystatic ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
7731e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 char __user *user_buf,
7741e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 size_t count, loff_t *ppos)
7751e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy{
77628f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
7771e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	char buf[100];
7781e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	int pos = 0;
7791e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	const size_t bufsz = sizeof(buf);
7801e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7811e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
7821e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy			"11n 40MHz Mode: %s\n",
7831e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy			priv->disable_ht40 ? "Disabled" : "Enabled");
7844967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
7851e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy}
7861e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
787e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
788e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    const char __user *user_buf,
789e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    size_t count, loff_t *ppos)
790e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{
791e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	struct iwl_priv *priv = file->private_data;
792e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	char buf[8];
793e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int buf_size;
794e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int value;
795e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
796e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	memset(buf, 0, sizeof(buf));
797e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	buf_size = min(count, sizeof(buf) -  1);
798e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (copy_from_user(buf, user_buf, buf_size))
799e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		return -EFAULT;
800e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
801e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (sscanf(buf, "%d", &value) != 1)
802e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		return -EINVAL;
803e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
804e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	/*
805e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 * Our users expect 0 to be "CAM", but 0 isn't actually
806e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 * valid here. However, let's not confuse them and present
807e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 * IWL_POWER_INDEX_1 as "1", not "0".
808e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 */
8091a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre	if (value == 0)
8101a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre		return -EINVAL;
8111a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre	else if (value > 0)
812e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		value -= 1;
813e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
814e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (value != -1 && (value < 0 || value >= IWL_POWER_NUM))
815e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		return -EINVAL;
816e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
8174ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy	if (!iwl_is_ready_rf(priv))
8184ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy		return -EAGAIN;
8194ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy
820e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	priv->power_data.debug_sleep_level_override = value;
821e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
822d3a571971e5af241074947fc80f6284677f6e014Reinette Chatre	mutex_lock(&priv->mutex);
8234ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy	iwl_power_update_mode(priv, true);
824d3a571971e5af241074947fc80f6284677f6e014Reinette Chatre	mutex_unlock(&priv->mutex);
825e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
826e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	return count;
827e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg}
828e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
829e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
830e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						   char __user *user_buf,
831e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						   size_t count, loff_t *ppos)
832e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{
83328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
834e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	char buf[10];
835e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int pos, value;
836e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	const size_t bufsz = sizeof(buf);
837e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
838e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	/* see the write function */
839e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	value = priv->power_data.debug_sleep_level_override;
840e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (value >= 0)
841e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		value += 1;
842e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
843e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	pos = scnprintf(buf, bufsz, "%d\n", value);
844e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
845e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg}
846e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
847e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
848e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    char __user *user_buf,
849e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    size_t count, loff_t *ppos)
850e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{
85128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
852e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	char buf[200];
853e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int pos = 0, i;
854e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	const size_t bufsz = sizeof(buf);
855e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd;
856e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
857e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	pos += scnprintf(buf + pos, bufsz - pos,
858e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 "flags: %#.2x\n", le16_to_cpu(cmd->flags));
859e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	pos += scnprintf(buf + pos, bufsz - pos,
860e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 "RX/TX timeout: %d/%d usec\n",
861e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 le32_to_cpu(cmd->rx_data_timeout),
862e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 le32_to_cpu(cmd->tx_data_timeout));
863e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
864e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		pos += scnprintf(buf + pos, bufsz - pos,
865e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg				 "sleep_interval[%d]: %d\n", i,
866e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg				 le32_to_cpu(cmd->sleep_interval[i]));
867e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
868e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
869e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg}
870e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
871712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_WRITE_FILE_OPS(sram);
872c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes BergDEBUGFS_READ_FILE_OPS(wowlan_sram);
873b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(log_event);
8740848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi GuyDEBUGFS_READ_FILE_OPS(nvm);
875712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_FILE_OPS(stations);
876d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, TomasDEBUGFS_READ_FILE_OPS(channels);
87708df05aa9b25f3079585855506022bb33a011183Wey-Yi GuyDEBUGFS_READ_FILE_OPS(status);
878a83b9141b540f96dd59409c6487828e880113a29Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(interrupt);
879f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi GuyDEBUGFS_READ_FILE_OPS(qos);
880fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi GuyDEBUGFS_READ_FILE_OPS(thermal_throttling);
8811e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
882e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes BergDEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
883e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes BergDEBUGFS_READ_FILE_OPS(current_sleep_command);
884712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
88520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guystatic ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
88620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 char __user *user_buf,
88720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 size_t count, loff_t *ppos)
88820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy{
88920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_priv *priv = file->private_data;
89020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int pos = 0, ofs = 0;
89120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int cnt = 0, entry;
89220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_tx_queue *txq;
89320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_queue *q;
89420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_rx_queue *rxq = &priv->rxq;
89520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	char *buf;
89620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
8977cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		(priv->cfg->base_params->num_of_queues * 32 * 8) + 400;
89820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	const u8 *ptr;
89920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	ssize_t ret;
90020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
90188804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	if (!priv->txq) {
90288804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		IWL_ERR(priv, "txq not ready\n");
90388804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		return -EAGAIN;
90488804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	}
90520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
90620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (!buf) {
90720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		IWL_ERR(priv, "Can not allocate buffer\n");
90820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		return -ENOMEM;
90920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
91020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
911d618912417fbce4f6514fe1cbef7df2e73bdb6c2Emmanuel Grumbach	for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) {
91220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		txq = &priv->txq[cnt];
91320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		q = &txq->q;
91420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
91520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				"q[%d]: read_ptr: %u, write_ptr: %u\n",
91620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				cnt, q->read_ptr, q->write_ptr);
91720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
9188f470ce31de1a9dfe6b53e0967eaa7e72b741714Emmanuel Grumbach	if (priv->tx_traffic &&
9198f470ce31de1a9dfe6b53e0967eaa7e72b741714Emmanuel Grumbach		(iwl_get_debug_level(priv->shrd) & IWL_DL_TX)) {
92020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		ptr = priv->tx_traffic;
92120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
92220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				"Tx Traffic idx: %u\n",	priv->tx_traffic_idx);
92320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
92420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
92520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			     entry++,  ofs += 16) {
92620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				pos += scnprintf(buf + pos, bufsz - pos,
92720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						"0x%.4x ", ofs);
92820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
92920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						   buf + pos, bufsz - pos, 0);
9302fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre				pos += strlen(buf + pos);
93120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				if (bufsz - pos > 0)
93220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					buf[pos++] = '\n';
93320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			}
93420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		}
93520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
93620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
93720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
93820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
93920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			"read: %u, write: %u\n",
94020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			 rxq->read, rxq->write);
94120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
9428f470ce31de1a9dfe6b53e0967eaa7e72b741714Emmanuel Grumbach	if (priv->rx_traffic &&
9438f470ce31de1a9dfe6b53e0967eaa7e72b741714Emmanuel Grumbach		(iwl_get_debug_level(priv->shrd) & IWL_DL_RX)) {
94420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		ptr = priv->rx_traffic;
94520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
94620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				"Rx Traffic idx: %u\n",	priv->rx_traffic_idx);
94720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
94820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
94920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			     entry++,  ofs += 16) {
95020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				pos += scnprintf(buf + pos, bufsz - pos,
95120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						"0x%.4x ", ofs);
95220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
95320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						   buf + pos, bufsz - pos, 0);
9542fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre				pos += strlen(buf + pos);
95520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				if (bufsz - pos > 0)
95620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					buf[pos++] = '\n';
95720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			}
95820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		}
95920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
96020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
96120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
96220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	kfree(buf);
96320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	return ret;
96420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy}
96520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
96620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guystatic ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
96720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 const char __user *user_buf,
96820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 size_t count, loff_t *ppos)
96920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy{
97020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_priv *priv = file->private_data;
97120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	char buf[8];
97220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int buf_size;
97320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int traffic_log;
97420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
97520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	memset(buf, 0, sizeof(buf));
97620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
97720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
97820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		return -EFAULT;
97920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (sscanf(buf, "%d", &traffic_log) != 1)
98020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		return -EFAULT;
98120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (traffic_log == 0)
98220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		iwl_reset_traffic_log(priv);
98320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
98420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	return count;
98520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy}
98620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
987141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guystatic ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
988141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						char __user *user_buf,
989141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						size_t count, loff_t *ppos) {
990141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
99128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
992141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	struct iwl_tx_queue *txq;
993141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	struct iwl_queue *q;
994141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	char *buf;
995141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int pos = 0;
996141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int cnt;
997141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int ret;
9987cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	const size_t bufsz = sizeof(char) * 64 *
9997cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy				priv->cfg->base_params->num_of_queues;
1000141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
100188804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	if (!priv->txq) {
100288804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		IWL_ERR(priv, "txq not ready\n");
100388804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		return -EAGAIN;
100488804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	}
1005141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
1006141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	if (!buf)
1007141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		return -ENOMEM;
1008141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
1009d618912417fbce4f6514fe1cbef7df2e73bdb6c2Emmanuel Grumbach	for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) {
1010141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		txq = &priv->txq[cnt];
1011141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		q = &txq->q;
1012141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
1013141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				"hwq %.2d: read=%u write=%u stop=%d"
1014141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				" swq_id=%#.2x (ac %d/hwq %d)\n",
1015141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				cnt, q->read_ptr, q->write_ptr,
1016141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				!!test_bit(cnt, priv->queue_stopped),
1017ea9b307f8e859186a6791e0d508c5993448ac900Johannes Berg				txq->swq_id, txq->swq_id & 3,
1018ea9b307f8e859186a6791e0d508c5993448ac900Johannes Berg				(txq->swq_id >> 2) & 0x1f);
1019141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		if (cnt >= 4)
1020141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy			continue;
1021141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		/* for the ACs, display the stop count too */
1022141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
1023141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				"        stop-count: %d\n",
1024141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				atomic_read(&priv->queue_stop_count[cnt]));
1025141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	}
1026141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1027141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	kfree(buf);
1028141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	return ret;
1029141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy}
1030141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
1031141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guystatic ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1032141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						char __user *user_buf,
1033141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						size_t count, loff_t *ppos) {
1034141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
103528f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1036141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	struct iwl_rx_queue *rxq = &priv->rxq;
1037141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	char buf[256];
1038141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int pos = 0;
1039141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	const size_t bufsz = sizeof(buf);
1040141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
1041141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
1042141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						rxq->read);
1043141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
1044141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						rxq->write);
1045141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
1046141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						rxq->free_count);
1047f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish	if (rxq->rb_stts) {
1048f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish		pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
1049141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy			 le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF);
1050f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish	} else {
1051f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish		pos += scnprintf(buf + pos, bufsz - pos,
1052f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish					"closed_rb_num: Not Allocated\n");
1053f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish	}
1054141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1055141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy}
1056141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
1057d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guystatic const char *fmt_value = "  %-30s %10u\n";
1058d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guystatic const char *fmt_hex   = "  %-30s       0x%02X\n";
1059d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guystatic const char *fmt_table = "  %-30s %10u  %10u  %10u  %10u\n";
1060d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guystatic const char *fmt_header =
1061d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	"%-32s    current  cumulative       delta         max\n";
1062d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1063d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guystatic int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
1064d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy{
1065d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	int p = 0;
1066d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	u32 flag;
1067d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1068d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	flag = le32_to_cpu(priv->statistics.flag);
1069d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1070d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
1071d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (flag & UCODE_STATISTICS_CLEAR_MSK)
1072d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		p += scnprintf(buf + p, bufsz - p,
1073d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		"\tStatistics have been cleared\n");
1074d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
1075d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		(flag & UCODE_STATISTICS_FREQUENCY_MSK)
1076d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		? "2.4 GHz" : "5.2 GHz");
1077d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
1078d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		(flag & UCODE_STATISTICS_NARROW_BAND_MSK)
1079d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		 ? "enabled" : "disabled");
1080d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1081d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	return p;
1082d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy}
1083d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1084e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1085e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					char __user *user_buf,
1086e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					size_t count, loff_t *ppos)
1087e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{
108828f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1089d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	int pos = 0;
1090d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	char *buf;
1091d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	int bufsz = sizeof(struct statistics_rx_phy) * 40 +
1092d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		    sizeof(struct statistics_rx_non_phy) * 40 +
1093d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		    sizeof(struct statistics_rx_ht_phy) * 40 + 400;
1094d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ssize_t ret;
1095d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
1096d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
1097d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct statistics_rx_non_phy *general, *accum_general;
1098d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct statistics_rx_non_phy *delta_general, *max_general;
1099d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
1100d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1101d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (!iwl_is_alive(priv))
1102d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -EAGAIN;
1103d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1104d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
1105d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (!buf) {
1106d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
1107d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -ENOMEM;
1108d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	}
1109d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1110d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	/*
1111d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 * the statistic information display here is based on
1112d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 * the last statistics notification from uCode
1113d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 * might not reflect the current uCode activity
1114d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 */
1115d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ofdm = &priv->statistics.rx_ofdm;
1116d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	cck = &priv->statistics.rx_cck;
1117d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	general = &priv->statistics.rx_non_phy;
1118d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ht = &priv->statistics.rx_ofdm_ht;
1119d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	accum_ofdm = &priv->accum_stats.rx_ofdm;
1120d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	accum_cck = &priv->accum_stats.rx_cck;
1121d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	accum_general = &priv->accum_stats.rx_non_phy;
1122d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	accum_ht = &priv->accum_stats.rx_ofdm_ht;
1123d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	delta_ofdm = &priv->delta_stats.rx_ofdm;
1124d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	delta_cck = &priv->delta_stats.rx_cck;
1125d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	delta_general = &priv->delta_stats.rx_non_phy;
1126d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	delta_ht = &priv->delta_stats.rx_ofdm_ht;
1127d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	max_ofdm = &priv->max_delta_stats.rx_ofdm;
1128d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	max_cck = &priv->max_delta_stats.rx_cck;
1129d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	max_general = &priv->max_delta_stats.rx_non_phy;
1130d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	max_ht = &priv->max_delta_stats.rx_ofdm_ht;
1131d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1132d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += iwl_statistics_flag(priv, buf, bufsz);
1133d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1134d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_header, "Statistics_Rx - OFDM:");
1135d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1136d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "ina_cnt:",
1137d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->ina_cnt),
1138d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->ina_cnt,
1139d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
1140d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1141d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "fina_cnt:",
1142d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
1143d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
1144d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1145d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "plcp_err:",
1146d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
1147d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->plcp_err, max_ofdm->plcp_err);
1148d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1149d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "crc32_err:",
1150d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
1151d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->crc32_err, max_ofdm->crc32_err);
1152d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1153d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "overrun_err:",
1154d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->overrun_err),
1155d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->overrun_err, delta_ofdm->overrun_err,
1156d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->overrun_err);
1157d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1158d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "early_overrun_err:",
1159d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->early_overrun_err),
1160d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->early_overrun_err,
1161d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->early_overrun_err,
1162d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->early_overrun_err);
1163d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1164d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "crc32_good:",
1165d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->crc32_good),
1166d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->crc32_good, delta_ofdm->crc32_good,
1167d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->crc32_good);
1168d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1169d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "false_alarm_cnt:",
1170d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->false_alarm_cnt),
1171d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->false_alarm_cnt,
1172d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->false_alarm_cnt,
1173d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->false_alarm_cnt);
1174d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1175d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "fina_sync_err_cnt:",
1176d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->fina_sync_err_cnt),
1177d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->fina_sync_err_cnt,
1178d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->fina_sync_err_cnt,
1179d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->fina_sync_err_cnt);
1180d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1181d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "sfd_timeout:",
1182d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->sfd_timeout),
1183d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
1184d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->sfd_timeout);
1185d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1186d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "fina_timeout:",
1187d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->fina_timeout),
1188d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
1189d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->fina_timeout);
1190d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1191d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "unresponded_rts:",
1192d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->unresponded_rts),
1193d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->unresponded_rts,
1194d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->unresponded_rts,
1195d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->unresponded_rts);
1196d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1197d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "rxe_frame_lmt_ovrun:",
1198d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
1199d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->rxe_frame_limit_overrun,
1200d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->rxe_frame_limit_overrun,
1201d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->rxe_frame_limit_overrun);
1202d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1203d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "sent_ack_cnt:",
1204d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->sent_ack_cnt),
1205d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
1206d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->sent_ack_cnt);
1207d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1208d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "sent_cts_cnt:",
1209d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->sent_cts_cnt),
1210d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
1211d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->sent_cts_cnt);
1212d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1213d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "sent_ba_rsp_cnt:",
1214d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
1215d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->sent_ba_rsp_cnt,
1216d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->sent_ba_rsp_cnt,
1217d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->sent_ba_rsp_cnt);
1218d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1219d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "dsp_self_kill:",
1220d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->dsp_self_kill),
1221d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->dsp_self_kill,
1222d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->dsp_self_kill,
1223d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->dsp_self_kill);
1224d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1225d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "mh_format_err:",
1226d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->mh_format_err),
1227d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->mh_format_err,
1228d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->mh_format_err,
1229d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->mh_format_err);
1230d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1231d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "re_acq_main_rssi_sum:",
1232d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
1233d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ofdm->re_acq_main_rssi_sum,
1234d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ofdm->re_acq_main_rssi_sum,
1235d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ofdm->re_acq_main_rssi_sum);
1236d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1237d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1238d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_header, "Statistics_Rx - CCK:");
1239d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1240d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "ina_cnt:",
1241d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
1242d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_cck->ina_cnt, max_cck->ina_cnt);
1243d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1244d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "fina_cnt:",
1245d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
1246d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_cck->fina_cnt, max_cck->fina_cnt);
1247d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1248d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "plcp_err:",
1249d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
1250d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_cck->plcp_err, max_cck->plcp_err);
1251d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1252d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "crc32_err:",
1253d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
1254d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_cck->crc32_err, max_cck->crc32_err);
1255d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1256d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "overrun_err:",
1257d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->overrun_err),
1258d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->overrun_err, delta_cck->overrun_err,
1259d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->overrun_err);
1260d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1261d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "early_overrun_err:",
1262d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->early_overrun_err),
1263d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->early_overrun_err,
1264d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_cck->early_overrun_err,
1265d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->early_overrun_err);
1266d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1267d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "crc32_good:",
1268d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
1269d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_cck->crc32_good, max_cck->crc32_good);
1270d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1271d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "false_alarm_cnt:",
1272d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->false_alarm_cnt),
1273d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->false_alarm_cnt,
1274d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
1275d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1276d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "fina_sync_err_cnt:",
1277d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->fina_sync_err_cnt),
1278d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->fina_sync_err_cnt,
1279d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_cck->fina_sync_err_cnt,
1280d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->fina_sync_err_cnt);
1281d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1282d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "sfd_timeout:",
1283d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->sfd_timeout),
1284d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->sfd_timeout, delta_cck->sfd_timeout,
1285d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->sfd_timeout);
1286d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1287d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "fina_timeout:",
1288d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->fina_timeout),
1289d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->fina_timeout, delta_cck->fina_timeout,
1290d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->fina_timeout);
1291d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1292d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "unresponded_rts:",
1293d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->unresponded_rts),
1294d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->unresponded_rts, delta_cck->unresponded_rts,
1295d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->unresponded_rts);
1296d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1297d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "rxe_frame_lmt_ovrun:",
1298d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->rxe_frame_limit_overrun),
1299d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->rxe_frame_limit_overrun,
1300d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_cck->rxe_frame_limit_overrun,
1301d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->rxe_frame_limit_overrun);
1302d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1303d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "sent_ack_cnt:",
1304d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->sent_ack_cnt),
1305d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
1306d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->sent_ack_cnt);
1307d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1308d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "sent_cts_cnt:",
1309d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->sent_cts_cnt),
1310d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
1311d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->sent_cts_cnt);
1312d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1313d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "sent_ba_rsp_cnt:",
1314d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->sent_ba_rsp_cnt),
1315d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->sent_ba_rsp_cnt,
1316d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_cck->sent_ba_rsp_cnt,
1317d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->sent_ba_rsp_cnt);
1318d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1319d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "dsp_self_kill:",
1320d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->dsp_self_kill),
1321d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
1322d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->dsp_self_kill);
1323d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1324d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "mh_format_err:",
1325d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->mh_format_err),
1326d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->mh_format_err, delta_cck->mh_format_err,
1327d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->mh_format_err);
1328d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1329d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "re_acq_main_rssi_sum:",
1330d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(cck->re_acq_main_rssi_sum),
1331d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_cck->re_acq_main_rssi_sum,
1332d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_cck->re_acq_main_rssi_sum,
1333d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_cck->re_acq_main_rssi_sum);
1334d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1335d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1336d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_header, "Statistics_Rx - GENERAL:");
1337d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1338d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "bogus_cts:",
1339d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->bogus_cts),
1340d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->bogus_cts, delta_general->bogus_cts,
1341d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->bogus_cts);
1342d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1343d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "bogus_ack:",
1344d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->bogus_ack),
1345d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->bogus_ack, delta_general->bogus_ack,
1346d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->bogus_ack);
1347d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1348d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "non_bssid_frames:",
1349d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->non_bssid_frames),
1350d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->non_bssid_frames,
1351d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->non_bssid_frames,
1352d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->non_bssid_frames);
1353d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1354d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "filtered_frames:",
1355d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->filtered_frames),
1356d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->filtered_frames,
1357d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->filtered_frames,
1358d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->filtered_frames);
1359d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1360d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "non_channel_beacons:",
1361d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->non_channel_beacons),
1362d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->non_channel_beacons,
1363d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->non_channel_beacons,
1364d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->non_channel_beacons);
1365d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1366d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "channel_beacons:",
1367d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->channel_beacons),
1368d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->channel_beacons,
1369d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->channel_beacons,
1370d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->channel_beacons);
1371d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1372d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "num_missed_bcon:",
1373d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->num_missed_bcon),
1374d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->num_missed_bcon,
1375d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->num_missed_bcon,
1376d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->num_missed_bcon);
1377d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1378d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "adc_rx_saturation_time:",
1379d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->adc_rx_saturation_time),
1380d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->adc_rx_saturation_time,
1381d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->adc_rx_saturation_time,
1382d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->adc_rx_saturation_time);
1383d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1384d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "ina_detect_search_tm:",
1385d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->ina_detection_search_time),
1386d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->ina_detection_search_time,
1387d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->ina_detection_search_time,
1388d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->ina_detection_search_time);
1389d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1390d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "beacon_silence_rssi_a:",
1391d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->beacon_silence_rssi_a),
1392d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->beacon_silence_rssi_a,
1393d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->beacon_silence_rssi_a,
1394d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->beacon_silence_rssi_a);
1395d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1396d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "beacon_silence_rssi_b:",
1397d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->beacon_silence_rssi_b),
1398d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->beacon_silence_rssi_b,
1399d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->beacon_silence_rssi_b,
1400d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->beacon_silence_rssi_b);
1401d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1402d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "beacon_silence_rssi_c:",
1403d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->beacon_silence_rssi_c),
1404d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->beacon_silence_rssi_c,
1405d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->beacon_silence_rssi_c,
1406d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->beacon_silence_rssi_c);
1407d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1408d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "interference_data_flag:",
1409d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->interference_data_flag),
1410d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->interference_data_flag,
1411d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->interference_data_flag,
1412d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->interference_data_flag);
1413d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1414d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "channel_load:",
1415d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->channel_load),
1416d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->channel_load,
1417d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->channel_load,
1418d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->channel_load);
1419d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1420d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "dsp_false_alarms:",
1421d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->dsp_false_alarms),
1422d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->dsp_false_alarms,
1423d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->dsp_false_alarms,
1424d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->dsp_false_alarms);
1425d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1426d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "beacon_rssi_a:",
1427d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->beacon_rssi_a),
1428d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->beacon_rssi_a,
1429d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->beacon_rssi_a,
1430d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->beacon_rssi_a);
1431d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1432d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "beacon_rssi_b:",
1433d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->beacon_rssi_b),
1434d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->beacon_rssi_b,
1435d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->beacon_rssi_b,
1436d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->beacon_rssi_b);
1437d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1438d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "beacon_rssi_c:",
1439d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->beacon_rssi_c),
1440d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->beacon_rssi_c,
1441d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->beacon_rssi_c,
1442d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->beacon_rssi_c);
1443d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1444d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "beacon_energy_a:",
1445d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->beacon_energy_a),
1446d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->beacon_energy_a,
1447d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->beacon_energy_a,
1448d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->beacon_energy_a);
1449d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1450d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "beacon_energy_b:",
1451d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->beacon_energy_b),
1452d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->beacon_energy_b,
1453d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->beacon_energy_b,
1454d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->beacon_energy_b);
1455d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1456d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "beacon_energy_c:",
1457d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->beacon_energy_c),
1458d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->beacon_energy_c,
1459d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->beacon_energy_c,
1460d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->beacon_energy_c);
1461d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1462d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1463d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_header, "Statistics_Rx - OFDM_HT:");
1464d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1465d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "plcp_err:",
1466d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
1467d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ht->plcp_err, max_ht->plcp_err);
1468d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1469d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "overrun_err:",
1470d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
1471d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ht->overrun_err, max_ht->overrun_err);
1472d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1473d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "early_overrun_err:",
1474d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ht->early_overrun_err),
1475d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ht->early_overrun_err,
1476d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ht->early_overrun_err,
1477d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_ht->early_overrun_err);
1478d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1479d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "crc32_good:",
1480d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
1481d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ht->crc32_good, max_ht->crc32_good);
1482d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1483d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "crc32_err:",
1484d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
1485d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ht->crc32_err, max_ht->crc32_err);
1486d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1487d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "mh_format_err:",
1488d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ht->mh_format_err),
1489d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ht->mh_format_err,
1490d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ht->mh_format_err, max_ht->mh_format_err);
1491d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1492d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg_crc32_good:",
1493d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ht->agg_crc32_good),
1494d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ht->agg_crc32_good,
1495d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
1496d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1497d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg_mpdu_cnt:",
1498d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ht->agg_mpdu_cnt),
1499d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ht->agg_mpdu_cnt,
1500d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
1501d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1502d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg_cnt:",
1503d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
1504d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ht->agg_cnt, max_ht->agg_cnt);
1505d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1506d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "unsupport_mcs:",
1507d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(ht->unsupport_mcs),
1508d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_ht->unsupport_mcs,
1509d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
1510d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1511d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1512d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	kfree(buf);
1513d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	return ret;
1514e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy}
1515e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1516e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1517e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					char __user *user_buf,
1518e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					size_t count, loff_t *ppos)
1519e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{
152028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1521d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	int pos = 0;
1522d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	char *buf;
1523d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
1524d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ssize_t ret;
1525d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
1526d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1527d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (!iwl_is_alive(priv))
1528d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -EAGAIN;
1529d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1530d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
1531d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (!buf) {
1532d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
1533d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -ENOMEM;
1534d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	}
1535d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1536d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	/* the statistic information display here is based on
1537d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 * the last statistics notification from uCode
1538d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 * might not reflect the current uCode activity
1539d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 */
1540d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	tx = &priv->statistics.tx;
1541d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	accum_tx = &priv->accum_stats.tx;
1542d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	delta_tx = &priv->delta_stats.tx;
1543d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	max_tx = &priv->max_delta_stats.tx;
1544d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1545d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += iwl_statistics_flag(priv, buf, bufsz);
1546d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1547d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_header, "Statistics_Tx:");
1548d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1549d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "preamble:",
1550d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->preamble_cnt),
1551d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->preamble_cnt,
1552d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->preamble_cnt, max_tx->preamble_cnt);
1553d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1554d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "rx_detected_cnt:",
1555d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->rx_detected_cnt),
1556d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->rx_detected_cnt,
1557d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
1558d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1559d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "bt_prio_defer_cnt:",
1560d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->bt_prio_defer_cnt),
1561d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->bt_prio_defer_cnt,
1562d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->bt_prio_defer_cnt,
1563d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->bt_prio_defer_cnt);
1564d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1565d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "bt_prio_kill_cnt:",
1566d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->bt_prio_kill_cnt),
1567d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->bt_prio_kill_cnt,
1568d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->bt_prio_kill_cnt,
1569d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->bt_prio_kill_cnt);
1570d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1571d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "few_bytes_cnt:",
1572d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->few_bytes_cnt),
1573d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->few_bytes_cnt,
1574d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
1575d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1576d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "cts_timeout:",
1577d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
1578d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->cts_timeout, max_tx->cts_timeout);
1579d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1580d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "ack_timeout:",
1581d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->ack_timeout),
1582d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->ack_timeout,
1583d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->ack_timeout, max_tx->ack_timeout);
1584d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1585d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "expected_ack_cnt:",
1586d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->expected_ack_cnt),
1587d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->expected_ack_cnt,
1588d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->expected_ack_cnt,
1589d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->expected_ack_cnt);
1590d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1591d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "actual_ack_cnt:",
1592d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->actual_ack_cnt),
1593d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->actual_ack_cnt,
1594d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->actual_ack_cnt,
1595d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->actual_ack_cnt);
1596d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1597d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "dump_msdu_cnt:",
1598d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->dump_msdu_cnt),
1599d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->dump_msdu_cnt,
1600d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->dump_msdu_cnt,
1601d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->dump_msdu_cnt);
1602d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1603d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "abort_nxt_frame_mismatch:",
1604d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
1605d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->burst_abort_next_frame_mismatch_cnt,
1606d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->burst_abort_next_frame_mismatch_cnt,
1607d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->burst_abort_next_frame_mismatch_cnt);
1608d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1609d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "abort_missing_nxt_frame:",
1610d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
1611d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->burst_abort_missing_next_frame_cnt,
1612d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->burst_abort_missing_next_frame_cnt,
1613d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->burst_abort_missing_next_frame_cnt);
1614d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1615d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "cts_timeout_collision:",
1616d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->cts_timeout_collision),
1617d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->cts_timeout_collision,
1618d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->cts_timeout_collision,
1619d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->cts_timeout_collision);
1620d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1621d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "ack_ba_timeout_collision:",
1622d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->ack_or_ba_timeout_collision),
1623d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->ack_or_ba_timeout_collision,
1624d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->ack_or_ba_timeout_collision,
1625d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->ack_or_ba_timeout_collision);
1626d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1627d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg ba_timeout:",
1628d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->agg.ba_timeout),
1629d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->agg.ba_timeout,
1630d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->agg.ba_timeout,
1631d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->agg.ba_timeout);
1632d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1633d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg ba_resched_frames:",
1634d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->agg.ba_reschedule_frames),
1635d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->agg.ba_reschedule_frames,
1636d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->agg.ba_reschedule_frames,
1637d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->agg.ba_reschedule_frames);
1638d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1639d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg scd_query_agg_frame:",
1640d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
1641d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->agg.scd_query_agg_frame_cnt,
1642d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->agg.scd_query_agg_frame_cnt,
1643d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->agg.scd_query_agg_frame_cnt);
1644d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1645d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg scd_query_no_agg:",
1646d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->agg.scd_query_no_agg),
1647d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->agg.scd_query_no_agg,
1648d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->agg.scd_query_no_agg,
1649d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->agg.scd_query_no_agg);
1650d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1651d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg scd_query_agg:",
1652d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->agg.scd_query_agg),
1653d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->agg.scd_query_agg,
1654d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->agg.scd_query_agg,
1655d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->agg.scd_query_agg);
1656d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1657d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg scd_query_mismatch:",
1658d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->agg.scd_query_mismatch),
1659d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->agg.scd_query_mismatch,
1660d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->agg.scd_query_mismatch,
1661d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->agg.scd_query_mismatch);
1662d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1663d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg frame_not_ready:",
1664d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->agg.frame_not_ready),
1665d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->agg.frame_not_ready,
1666d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->agg.frame_not_ready,
1667d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->agg.frame_not_ready);
1668d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1669d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg underrun:",
1670d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->agg.underrun),
1671d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->agg.underrun,
1672d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->agg.underrun, max_tx->agg.underrun);
1673d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1674d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg bt_prio_kill:",
1675d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->agg.bt_prio_kill),
1676d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->agg.bt_prio_kill,
1677d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->agg.bt_prio_kill,
1678d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->agg.bt_prio_kill);
1679d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1680d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "agg rx_ba_rsp_cnt:",
1681d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
1682d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_tx->agg.rx_ba_rsp_cnt,
1683d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_tx->agg.rx_ba_rsp_cnt,
1684d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_tx->agg.rx_ba_rsp_cnt);
1685d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1686d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
1687d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
1688d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			"tx power: (1/2 dB step)\n");
1689d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
1690d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
1691d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy					fmt_hex, "antenna A:",
1692d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy					tx->tx_power.ant_a);
1693d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
1694d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
1695d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy					fmt_hex, "antenna B:",
1696d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy					tx->tx_power.ant_b);
1697d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
1698d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
1699d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy					fmt_hex, "antenna C:",
1700d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy					tx->tx_power.ant_c);
1701d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	}
1702d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1703d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	kfree(buf);
1704d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	return ret;
1705e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy}
1706e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1707e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1708e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					char __user *user_buf,
1709e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					size_t count, loff_t *ppos)
1710e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{
171128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1712d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	int pos = 0;
1713d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	char *buf;
1714d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	int bufsz = sizeof(struct statistics_general) * 10 + 300;
1715d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ssize_t ret;
1716d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct statistics_general_common *general, *accum_general;
1717d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct statistics_general_common *delta_general, *max_general;
1718d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
1719d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct statistics_div *div, *accum_div, *delta_div, *max_div;
1720d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1721d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (!iwl_is_alive(priv))
1722d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -EAGAIN;
1723d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1724d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
1725d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (!buf) {
1726d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
1727d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -ENOMEM;
1728d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	}
1729d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1730d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	/* the statistic information display here is based on
1731d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 * the last statistics notification from uCode
1732d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 * might not reflect the current uCode activity
1733d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 */
1734d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	general = &priv->statistics.common;
1735d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	dbg = &priv->statistics.common.dbg;
1736d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	div = &priv->statistics.common.div;
1737d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	accum_general = &priv->accum_stats.common;
1738d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	accum_dbg = &priv->accum_stats.common.dbg;
1739d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	accum_div = &priv->accum_stats.common.div;
1740d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	delta_general = &priv->delta_stats.common;
1741d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	max_general = &priv->max_delta_stats.common;
1742d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	delta_dbg = &priv->delta_stats.common.dbg;
1743d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	max_dbg = &priv->max_delta_stats.common.dbg;
1744d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	delta_div = &priv->delta_stats.common.div;
1745d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	max_div = &priv->max_delta_stats.common.div;
1746d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1747d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += iwl_statistics_flag(priv, buf, bufsz);
1748d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1749d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_header, "Statistics_General:");
1750d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1751d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_value, "temperature:",
1752d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->temperature));
1753d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1754d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_value, "temperature_m:",
1755d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->temperature_m));
1756d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1757d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_value, "ttl_timestamp:",
1758d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->ttl_timestamp));
1759d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1760d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "burst_check:",
1761d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(dbg->burst_check),
1762d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_dbg->burst_check,
1763d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_dbg->burst_check, max_dbg->burst_check);
1764d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1765d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "burst_count:",
1766d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(dbg->burst_count),
1767d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_dbg->burst_count,
1768d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_dbg->burst_count, max_dbg->burst_count);
1769d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1770d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "wait_for_silence_timeout_count:",
1771d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(dbg->wait_for_silence_timeout_cnt),
1772d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_dbg->wait_for_silence_timeout_cnt,
1773d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_dbg->wait_for_silence_timeout_cnt,
1774d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_dbg->wait_for_silence_timeout_cnt);
1775d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1776d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "sleep_time:",
1777d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->sleep_time),
1778d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->sleep_time,
1779d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->sleep_time, max_general->sleep_time);
1780d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1781d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "slots_out:",
1782d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->slots_out),
1783d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->slots_out,
1784d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->slots_out, max_general->slots_out);
1785d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1786d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "slots_idle:",
1787d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->slots_idle),
1788d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->slots_idle,
1789d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->slots_idle, max_general->slots_idle);
1790d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1791d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "tx_on_a:",
1792d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
1793d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_div->tx_on_a, max_div->tx_on_a);
1794d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1795d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "tx_on_b:",
1796d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
1797d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_div->tx_on_b, max_div->tx_on_b);
1798d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1799d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "exec_time:",
1800d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(div->exec_time), accum_div->exec_time,
1801d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_div->exec_time, max_div->exec_time);
1802d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1803d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "probe_time:",
1804d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(div->probe_time), accum_div->probe_time,
1805d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_div->probe_time, max_div->probe_time);
1806d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1807d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "rx_enable_counter:",
1808d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->rx_enable_counter),
1809d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->rx_enable_counter,
1810d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->rx_enable_counter,
1811d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->rx_enable_counter);
1812d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1813d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 fmt_table, "num_of_sos_states:",
1814d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(general->num_of_sos_states),
1815d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_general->num_of_sos_states,
1816d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 delta_general->num_of_sos_states,
1817d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 max_general->num_of_sos_states);
1818d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1819d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	kfree(buf);
1820d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	return ret;
1821d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy}
1822d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1823d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guystatic ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
1824d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy					char __user *user_buf,
1825d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy					size_t count, loff_t *ppos)
1826d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy{
1827d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1828d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	int pos = 0;
1829d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	char *buf;
1830d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
1831d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ssize_t ret;
1832d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct statistics_bt_activity *bt, *accum_bt;
1833d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1834d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (!iwl_is_alive(priv))
1835d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -EAGAIN;
1836d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1837d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (!priv->bt_enable_flag)
1838d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -EINVAL;
1839d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1840d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	/* make request to uCode to retrieve statistics information */
1841d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	mutex_lock(&priv->mutex);
1842d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1843d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	mutex_unlock(&priv->mutex);
1844d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1845d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (ret) {
1846d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		IWL_ERR(priv,
1847d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			"Error sending statistics request: %zd\n", ret);
1848d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -EAGAIN;
1849d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	}
1850d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
1851d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (!buf) {
1852d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
1853d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -ENOMEM;
1854d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	}
1855d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1856d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	/*
1857d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 * the statistic information display here is based on
1858d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 * the last statistics notification from uCode
1859d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 * might not reflect the current uCode activity
1860d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	 */
1861d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	bt = &priv->statistics.bt_activity;
1862d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	accum_bt = &priv->accum_stats.bt_activity;
1863d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1864d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += iwl_statistics_flag(priv, buf, bufsz);
1865d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
1866d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1867d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			"\t\t\tcurrent\t\t\taccumulative\n");
1868d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1869d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
1870d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(bt->hi_priority_tx_req_cnt),
1871d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_bt->hi_priority_tx_req_cnt);
1872d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1873d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
1874d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(bt->hi_priority_tx_denied_cnt),
1875d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_bt->hi_priority_tx_denied_cnt);
1876d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1877d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
1878d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(bt->lo_priority_tx_req_cnt),
1879d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_bt->lo_priority_tx_req_cnt);
1880d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1881d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
1882d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(bt->lo_priority_tx_denied_cnt),
1883d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_bt->lo_priority_tx_denied_cnt);
1884d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1885d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
1886d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(bt->hi_priority_rx_req_cnt),
1887d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_bt->hi_priority_rx_req_cnt);
1888d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1889d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
1890d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(bt->hi_priority_rx_denied_cnt),
1891d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_bt->hi_priority_rx_denied_cnt);
1892d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1893d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
1894d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(bt->lo_priority_rx_req_cnt),
1895d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_bt->lo_priority_rx_req_cnt);
1896d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1897d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
1898d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(bt->lo_priority_rx_denied_cnt),
1899d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 accum_bt->lo_priority_rx_denied_cnt);
1900d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1901d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
1902d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
1903d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 le32_to_cpu(priv->statistics.num_bt_kills),
1904d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 priv->statistics.accum_num_bt_kills);
1905d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1906d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1907d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	kfree(buf);
1908d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	return ret;
1909d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy}
1910d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1911d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guystatic ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
1912d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy					char __user *user_buf,
1913d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy					size_t count, loff_t *ppos)
1914d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy{
1915d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1916d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	int pos = 0;
1917d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	char *buf;
1918d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) +
1919d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		(sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
1920d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ssize_t ret;
1921d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1922d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (!iwl_is_alive(priv))
1923d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -EAGAIN;
1924d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1925d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
1926d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	if (!buf) {
1927d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
1928d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy		return -ENOMEM;
1929d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	}
1930d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
1931d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
1932d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
1933d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY),
1934898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.pp_delay);
1935d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1936d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES),
1937898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.pp_few_bytes);
1938d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1939d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO),
1940898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.pp_bt_prio);
1941d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1942d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD),
1943898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.pp_quiet_period);
1944d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1945d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK),
1946898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.pp_calc_ttak);
1947d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
1948d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(
1949d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy				TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY),
1950898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.int_crossed_retry);
1951d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1952d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT),
1953898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.short_limit);
1954d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1955d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT),
1956898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.long_limit);
1957d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1958d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN),
1959898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.fifo_underrun);
1960d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1961d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW),
1962898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.drain_flow);
1963d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1964d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH),
1965898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.rfkill_flush);
1966d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1967d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE),
1968898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.life_expire);
1969d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1970d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS),
1971898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.dest_ps);
1972d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1973d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED),
1974898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.host_abort);
1975d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1976d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY),
1977898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.pp_delay);
1978d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1979d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID),
1980898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.sta_invalid);
1981d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1982d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED),
1983898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.frag_drop);
1984d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1985d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE),
1986898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.tid_disable);
1987d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1988d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED),
1989898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.fifo_flush);
1990d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
1991d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(
1992d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy				TX_STATUS_FAIL_INSUFFICIENT_CF_POLL),
1993898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.insuff_cf_poll);
1994d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1995d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX),
1996898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.fail_hw_drop);
1997d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
1998d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_tx_fail_reason(
1999d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy				TX_STATUS_FAIL_NO_BEACON_ON_RADAR),
2000898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.sta_color_mismatch);
2001d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
2002898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_tx_stats.unknown);
2003d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
2004d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
2005d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 "\nStatistics_Agg_TX_Error:\n");
2006d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
2007d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2008d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK),
2009898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.underrun);
2010d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2011d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK),
2012898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.bt_prio);
2013d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2014d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK),
2015898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.few_bytes);
2016d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2017d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK),
2018898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.abort);
2019d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
2020d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(
2021d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy				AGG_TX_STATE_LAST_SENT_TTL_MSK),
2022898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.last_sent_ttl);
2023d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
2024d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(
2025d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy				AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK),
2026898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.last_sent_try);
2027d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
2028d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(
2029d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy				AGG_TX_STATE_LAST_SENT_BT_KILL_MSK),
2030898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.last_sent_bt_kill);
2031d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2032d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK),
2033898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.scd_query);
2034d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
2035d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(
2036d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy				AGG_TX_STATE_TEST_BAD_CRC32_MSK),
2037898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.bad_crc32);
2038d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2039d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK),
2040898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.response);
2041d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2042d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK),
2043898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.dump_tx);
2044d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2045d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK),
2046898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.delay_tx);
2047d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
2048898ed67be047d0762cc7592f67bf1313dff53ca9Wey-Yi Guy			 priv->reply_agg_tx_stats.unknown);
2049d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy
2050d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2051d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	kfree(buf);
2052d6d023a1948d13652d719238f8039c09acceda8cWey-Yi Guy	return ret;
2053e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy}
2054e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
20555225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guystatic ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
20565225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					char __user *user_buf,
20575225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					size_t count, loff_t *ppos) {
20585225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
205928f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
20605225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int pos = 0;
20615225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int cnt = 0;
20625225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	char *buf;
20635225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100;
20645225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ssize_t ret;
20655225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	struct iwl_sensitivity_data *data;
20665225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
20675225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	data = &priv->sensitivity_data;
20685225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
20695225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	if (!buf) {
20705225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
20715225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		return -ENOMEM;
20725225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
20735225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
20745225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
20755225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm);
20765225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
20775225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"auto_corr_ofdm_mrc:\t\t %u\n",
20785225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm_mrc);
20795225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
20805225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm_x1);
20815225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
20825225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"auto_corr_ofdm_mrc_x1:\t\t %u\n",
20835225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm_mrc_x1);
20845225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
20855225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_cck);
20865225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
20875225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_cck_mrc);
20885225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
20895225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"last_bad_plcp_cnt_ofdm:\t\t %u\n",
20905225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_bad_plcp_cnt_ofdm);
20915225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
20925225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_fa_cnt_ofdm);
20935225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
20945225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"last_bad_plcp_cnt_cck:\t\t %u\n",
20955225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_bad_plcp_cnt_cck);
20965225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
20975225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_fa_cnt_cck);
20985225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
20995225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_curr_state);
21005225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
21015225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_prev_state);
21025225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
21035225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < 10; cnt++) {
21045225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
21055225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->nrg_value[cnt]);
21065225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
21075225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
21085225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
21095225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
21105225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
21115225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->nrg_silence_rssi[cnt]);
21125225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
21135225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
21145225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
21155225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_silence_ref);
21165225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
21175225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_energy_idx);
21185225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
21195225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_silence_idx);
21205225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
21215225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_th_cck);
21225225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
21235225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"nrg_auto_corr_silence_diff:\t %u\n",
21245225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_auto_corr_silence_diff);
21255225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
21265225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->num_in_cck_no_fa);
21275225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
21285225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_th_ofdm);
21295225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
21305225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
21315225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	kfree(buf);
21325225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	return ret;
21335225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy}
21345225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
21355225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
21365225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guystatic ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
21375225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					char __user *user_buf,
21385225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					size_t count, loff_t *ppos) {
21395225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
214028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
21415225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int pos = 0;
21425225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int cnt = 0;
21435225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	char *buf;
21445225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100;
21455225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ssize_t ret;
21465225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	struct iwl_chain_noise_data *data;
21475225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
21485225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	data = &priv->chain_noise_data;
21495225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
21505225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	if (!buf) {
21515225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
21525225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		return -ENOMEM;
21535225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
21545225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
21555225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
21565225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->active_chains);
21575225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
21585225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_noise_a);
21595225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
21605225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_noise_b);
21615225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
21625225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_noise_c);
21635225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
21645225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_signal_a);
21655225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
21665225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_signal_b);
21675225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
21685225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_signal_c);
21695225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
21705225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->beacon_count);
21715225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
21725225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
21735225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
21745225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
21755225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->disconn_array[cnt]);
21765225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
21775225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
21785225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
21795225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
21805225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
21815225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->delta_gain_code[cnt]);
21825225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
21835225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
21845225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
21855225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->radio_write);
21865225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
21875225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->state);
21885225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
21895225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
21905225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	kfree(buf);
21915225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	return ret;
21925225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy}
21935225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
2194c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guystatic ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
2195c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy						    char __user *user_buf,
2196c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy						    size_t count, loff_t *ppos)
2197c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy{
219828f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
2199c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	char buf[60];
2200c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	int pos = 0;
2201c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	const size_t bufsz = sizeof(buf);
2202c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	u32 pwrsave_status;
2203c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
2204c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) &
2205c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy			CSR_GP_REG_POWER_SAVE_STATUS_MSK;
2206c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
2207c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
2208c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
2209c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		(pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
2210c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		(pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
2211c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		(pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
2212c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		"error");
2213c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
2214c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2215c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy}
2216c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
22177163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guystatic ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
2218ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy					 const char __user *user_buf,
2219ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy					 size_t count, loff_t *ppos)
2220ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy{
2221ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
2222ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	char buf[8];
2223ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	int buf_size;
2224ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	int clear;
2225ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
2226ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	memset(buf, 0, sizeof(buf));
2227ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
2228ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
2229ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy		return -EFAULT;
2230ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	if (sscanf(buf, "%d", &clear) != 1)
2231ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy		return -EFAULT;
2232ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
2233ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	/* make request to uCode to retrieve statistics information */
2234ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	mutex_lock(&priv->mutex);
2235ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	iwl_send_statistics_request(priv, CMD_SYNC, true);
2236ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	mutex_unlock(&priv->mutex);
2237ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
2238ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	return count;
2239ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy}
2240ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
2241696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guystatic ssize_t iwl_dbgfs_csr_write(struct file *file,
2242696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy					 const char __user *user_buf,
2243696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy					 size_t count, loff_t *ppos)
2244696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy{
2245696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
2246696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	char buf[8];
2247696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	int buf_size;
2248696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	int csr;
2249696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
2250696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	memset(buf, 0, sizeof(buf));
2251696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
2252696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
2253696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy		return -EFAULT;
2254696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	if (sscanf(buf, "%d", &csr) != 1)
2255696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy		return -EFAULT;
2256696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
22573ecccbcd3c67374aeee447c08fcb9e39a99f7ee5Wey-Yi Guy	iwl_dump_csr(priv);
2258696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
2259696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	return count;
2260696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy}
2261696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
2262a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
2263a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					char __user *user_buf,
2264a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					size_t count, loff_t *ppos) {
2265a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
226657674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches	struct iwl_priv *priv = file->private_data;
2267a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	int pos = 0;
2268a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	char buf[128];
2269a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	const size_t bufsz = sizeof(buf);
2270a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
2271a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
2272a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.ucode_trace ? "On" : "Off");
2273a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n",
2274a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.non_wraps_count);
2275a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n",
2276a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.wraps_once_count);
2277a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
2278a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.wraps_more_count);
2279a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
22804967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2281a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy}
2282a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
2283a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
2284a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					 const char __user *user_buf,
2285a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					 size_t count, loff_t *ppos)
2286a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy{
2287a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	struct iwl_priv *priv = file->private_data;
2288a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	char buf[8];
2289a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	int buf_size;
2290a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	int trace;
2291a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
2292a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	memset(buf, 0, sizeof(buf));
2293a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
2294a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
2295a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		return -EFAULT;
2296a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	if (sscanf(buf, "%d", &trace) != 1)
2297a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		return -EFAULT;
2298a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
2299a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	if (trace) {
2300a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		priv->event_log.ucode_trace = true;
2301a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		/* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
2302a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		mod_timer(&priv->ucode_trace,
2303a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
2304a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	} else {
2305a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		priv->event_log.ucode_trace = false;
2306a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		del_timer_sync(&priv->ucode_trace);
2307a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	}
2308a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
2309a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	return count;
2310a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy}
2311a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
231260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Bergstatic ssize_t iwl_dbgfs_rxon_flags_read(struct file *file,
231360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg					 char __user *user_buf,
231460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg					 size_t count, loff_t *ppos) {
231560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
231657674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches	struct iwl_priv *priv = file->private_data;
231760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	int len = 0;
231860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	char buf[20];
231960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
2320246ed355221076884d225f9d8a4c30a048be8162Johannes Berg	len = sprintf(buf, "0x%04X\n",
2321246ed355221076884d225f9d8a4c30a048be8162Johannes Berg		le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags));
232260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
232360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg}
232460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
232560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Bergstatic ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file,
232660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg						char __user *user_buf,
232760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg						size_t count, loff_t *ppos) {
232860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
232957674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches	struct iwl_priv *priv = file->private_data;
233060987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	int len = 0;
233160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	char buf[20];
233260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
233360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	len = sprintf(buf, "0x%04X\n",
2334246ed355221076884d225f9d8a4c30a048be8162Johannes Berg		le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags));
233560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
233660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg}
233760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
23381b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guystatic ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
23391b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy					 char __user *user_buf,
23401b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy					 size_t count, loff_t *ppos)
23411b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy{
234257674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches	struct iwl_priv *priv = file->private_data;
23431b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	char *buf;
23441b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	int pos = 0;
23451b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	ssize_t ret = -EFAULT;
23461b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy
23473ecccbcd3c67374aeee447c08fcb9e39a99f7ee5Wey-Yi Guy	ret = pos = iwl_dump_fh(priv, &buf, true);
23483ecccbcd3c67374aeee447c08fcb9e39a99f7ee5Wey-Yi Guy	if (buf) {
23493ecccbcd3c67374aeee447c08fcb9e39a99f7ee5Wey-Yi Guy		ret = simple_read_from_buffer(user_buf,
23503ecccbcd3c67374aeee447c08fcb9e39a99f7ee5Wey-Yi Guy					      count, ppos, buf, pos);
23513ecccbcd3c67374aeee447c08fcb9e39a99f7ee5Wey-Yi Guy		kfree(buf);
23521b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	}
23531b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy
23541b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	return ret;
23551b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy}
23561b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy
2357a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guystatic ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
2358a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					char __user *user_buf,
2359a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					size_t count, loff_t *ppos) {
2360a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2361a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
2362a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	int pos = 0;
2363a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	char buf[12];
2364a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	const size_t bufsz = sizeof(buf);
2365a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2366a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
2367a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy			priv->missed_beacon_threshold);
2368a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
23694967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2370a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy}
2371a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2372a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guystatic ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
2373a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					 const char __user *user_buf,
2374a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					 size_t count, loff_t *ppos)
2375a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy{
2376a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
2377a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	char buf[8];
2378a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	int buf_size;
2379a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	int missed;
2380a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2381a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	memset(buf, 0, sizeof(buf));
2382a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
2383a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
2384a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		return -EFAULT;
2385a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	if (sscanf(buf, "%d", &missed) != 1)
2386a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		return -EINVAL;
2387a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2388a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
2389a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	    missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
2390a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		priv->missed_beacon_threshold =
2391a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy			IWL_MISSED_BEACON_THRESHOLD_DEF;
2392a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	else
2393a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		priv->missed_beacon_threshold = missed;
2394a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2395a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	return count;
2396a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy}
2397a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
23983e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyenstatic ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
23993e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					char __user *user_buf,
24003e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					size_t count, loff_t *ppos) {
24013e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
240257674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches	struct iwl_priv *priv = file->private_data;
24033e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	int pos = 0;
24043e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	char buf[12];
24053e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	const size_t bufsz = sizeof(buf);
24063e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
24073e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
24087cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy			priv->cfg->base_params->plcp_delta_threshold);
24093e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
24104967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
24113e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen}
24123e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
24133e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyenstatic ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
24143e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					const char __user *user_buf,
24153e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					size_t count, loff_t *ppos) {
24163e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
24173e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	struct iwl_priv *priv = file->private_data;
24183e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	char buf[8];
24193e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	int buf_size;
24203e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	int plcp;
24213e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
24223e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	memset(buf, 0, sizeof(buf));
24233e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	buf_size = min(count, sizeof(buf) -  1);
24243e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	if (copy_from_user(buf, user_buf, buf_size))
24253e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen		return -EFAULT;
24263e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	if (sscanf(buf, "%d", &plcp) != 1)
24273e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen		return -EINVAL;
2428680788aca3dcc24b932eb7a4219ab921ac5bf2d0Wey-Yi Guy	if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
24293e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen		(plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
24307cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		priv->cfg->base_params->plcp_delta_threshold =
2431680788aca3dcc24b932eb7a4219ab921ac5bf2d0Wey-Yi Guy			IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE;
24323e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	else
24337cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		priv->cfg->base_params->plcp_delta_threshold = plcp;
24343e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	return count;
24353e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen}
24363e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
2437528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guystatic ssize_t iwl_dbgfs_force_reset_read(struct file *file,
2438528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy					char __user *user_buf,
2439528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy					size_t count, loff_t *ppos) {
2440528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy
2441528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	struct iwl_priv *priv = file->private_data;
2442528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	int i, pos = 0;
2443528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	char buf[300];
2444528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	const size_t bufsz = sizeof(buf);
2445528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	struct iwl_force_reset *force_reset;
2446528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy
2447528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	for (i = 0; i < IWL_MAX_FORCE_RESET; i++) {
2448528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		force_reset = &priv->force_reset[i];
2449528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
2450528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"Force reset method %d\n", i);
2451528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
2452528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\tnumber of reset request: %d\n",
2453528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_request_count);
2454528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
2455528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\tnumber of reset request success: %d\n",
2456528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_success_count);
2457528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
2458528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\tnumber of reset request reject: %d\n",
2459528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_reject_count);
2460528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
2461528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\treset duration: %lu\n",
2462528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_duration);
2463528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	}
2464528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2465528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy}
2466528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy
246704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guystatic ssize_t iwl_dbgfs_force_reset_write(struct file *file,
246804cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy					const char __user *user_buf,
246904cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy					size_t count, loff_t *ppos) {
247004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy
247104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
247204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	char buf[8];
247304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	int buf_size;
247404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	int reset, ret;
247504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy
247604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	memset(buf, 0, sizeof(buf));
247704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
247804cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
247904cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		return -EFAULT;
248004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	if (sscanf(buf, "%d", &reset) != 1)
248104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		return -EINVAL;
248204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	switch (reset) {
248304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	case IWL_RF_RESET:
248404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	case IWL_FW_RESET:
2485c04f9f220300da83f71698fa7be24714152faf0dWey-Yi Guy		ret = iwl_force_reset(priv, reset, true);
248604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		break;
248704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	default:
248804cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		return -EINVAL;
248904cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	}
249004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	return ret ? ret : count;
249104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy}
249204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy
24934bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guystatic ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
24944bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy					const char __user *user_buf,
24954bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy					size_t count, loff_t *ppos) {
24964bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
24974bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	struct iwl_priv *priv = file->private_data;
24984bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	char buf[8];
24994bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	int buf_size;
25004bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	int flush;
25014bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
25024bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	memset(buf, 0, sizeof(buf));
25034bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
25044bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
25054bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy		return -EFAULT;
25064bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	if (sscanf(buf, "%d", &flush) != 1)
25074bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy		return -EINVAL;
25084bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
25094bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	if (iwl_is_rfkill(priv))
25104bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy		return -EFAULT;
25114bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
2512c68744fb935400964f7af4835017cad5014c8c88Wey-Yi Guy	iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
25134bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
25144bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy	return count;
25154bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy}
25164bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy
251722de94de7de78b8de2fb1f2df5aa85b5556cfcfdStanislaw Gruszkastatic ssize_t iwl_dbgfs_wd_timeout_write(struct file *file,
25187bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy					const char __user *user_buf,
25197bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy					size_t count, loff_t *ppos) {
25207bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy
25217bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	struct iwl_priv *priv = file->private_data;
25227bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	char buf[8];
25237bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	int buf_size;
252422de94de7de78b8de2fb1f2df5aa85b5556cfcfdStanislaw Gruszka	int timeout;
25257bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy
25267bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	memset(buf, 0, sizeof(buf));
25277bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
25287bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
25297bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy		return -EFAULT;
253022de94de7de78b8de2fb1f2df5aa85b5556cfcfdStanislaw Gruszka	if (sscanf(buf, "%d", &timeout) != 1)
25317bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy		return -EINVAL;
253222de94de7de78b8de2fb1f2df5aa85b5556cfcfdStanislaw Gruszka	if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT)
253322de94de7de78b8de2fb1f2df5aa85b5556cfcfdStanislaw Gruszka		timeout = IWL_DEF_WD_TIMEOUT;
25347bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy
253522de94de7de78b8de2fb1f2df5aa85b5556cfcfdStanislaw Gruszka	priv->cfg->base_params->wd_timeout = timeout;
253622de94de7de78b8de2fb1f2df5aa85b5556cfcfdStanislaw Gruszka	iwl_setup_watchdog(priv);
25377bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy	return count;
25387bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy}
25397bdc473c7a52497af9fe8c73e4745615a2825aaaWey-Yi Guy
2540befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guystatic ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
2541befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy					char __user *user_buf,
2542befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy					size_t count, loff_t *ppos) {
2543befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy
2544befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2545befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	int pos = 0;
2546befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	char buf[200];
2547befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	const size_t bufsz = sizeof(buf);
2548befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy
2549f21dd005df95e0fc6a578342c61b5333ce2abc2bWey-Yi Guy	if (!priv->bt_enable_flag) {
2550f21dd005df95e0fc6a578342c61b5333ce2abc2bWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n");
255108960dea6c736280a03cb947f445fdb94fdaa2eeJohannes Berg		return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2552f21dd005df95e0fc6a578342c61b5333ce2abc2bWey-Yi Guy	}
2553f21dd005df95e0fc6a578342c61b5333ce2abc2bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n",
2554f21dd005df95e0fc6a578342c61b5333ce2abc2bWey-Yi Guy		priv->bt_enable_flag);
2555befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n",
2556befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		priv->bt_full_concurrent ? "full concurrency" : "3-wire");
2557befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, "
2558befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy			 "last traffic notif: %d\n",
255966e863a527f9ed3a871797862aaf0d62b0954813Wey-Yi Guy		priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load);
2560befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, "
2561187bc4f6b2f81e1c8f6b1e9d5dee3e8e9018ebbfWey-Yi Guy			 "kill_ack_mask: %x, kill_cts_mask: %x\n",
2562187bc4f6b2f81e1c8f6b1e9d5dee3e8e9018ebbfWey-Yi Guy		priv->bt_ch_announce, priv->kill_ack_mask,
2563187bc4f6b2f81e1c8f6b1e9d5dee3e8e9018ebbfWey-Yi Guy		priv->kill_cts_mask);
2564befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy
2565befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: ");
2566befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	switch (priv->bt_traffic_load) {
2567befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
2568befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "Continuous\n");
2569befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		break;
2570befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
2571befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "High\n");
2572befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		break;
2573befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
2574befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "Low\n");
2575befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		break;
2576befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
2577befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	default:
2578befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "None\n");
2579befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		break;
2580befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy	}
2581befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy
258208960dea6c736280a03cb947f445fdb94fdaa2eeJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2583befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy}
2584befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy
2585c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guystatic ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
2586c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy					char __user *user_buf,
2587c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy					size_t count, loff_t *ppos)
2588c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy{
2589c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2590c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
2591c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	int pos = 0;
2592c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	char buf[40];
2593c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	const size_t bufsz = sizeof(buf);
2594c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
25957cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (priv->cfg->ht_params)
25967cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
25977cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy			 "use %s for aggregation\n",
25987cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy			 (priv->cfg->ht_params->use_rts_for_aggregation) ?
25997cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy				"rts/cts" : "cts-to-self");
26007cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	else
26017cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "N/A");
26027cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy
2603c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2604c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy}
2605c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
2606c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guystatic ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
2607c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy					const char __user *user_buf,
2608c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy					size_t count, loff_t *ppos) {
2609c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
2610c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	struct iwl_priv *priv = file->private_data;
2611c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	char buf[8];
2612c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	int buf_size;
2613c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	int rts;
2614c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
26157cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy	if (!priv->cfg->ht_params)
26167cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		return -EINVAL;
26177cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy
2618c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	memset(buf, 0, sizeof(buf));
2619c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
2620c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
2621c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy		return -EFAULT;
2622c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	if (sscanf(buf, "%d", &rts) != 1)
2623c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy		return -EINVAL;
2624c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	if (rts)
26257cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		priv->cfg->ht_params->use_rts_for_aggregation = true;
2626c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	else
26277cb1b0887fcc61918e3d64827fbef968bb67a57aWey-Yi Guy		priv->cfg->ht_params->use_rts_for_aggregation = false;
2628c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	return count;
2629c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy}
2630c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy
26317163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_READ_FILE_OPS(rx_statistics);
26327163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_READ_FILE_OPS(tx_statistics);
263320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
2634141b03e07a54af68fc099459bf780a182b240b45Wey-Yi GuyDEBUGFS_READ_FILE_OPS(rx_queue);
2635141b03e07a54af68fc099459bf780a182b240b45Wey-Yi GuyDEBUGFS_READ_FILE_OPS(tx_queue);
2636e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_rx_stats);
2637e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_tx_stats);
2638e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_general_stats);
26395225935b53ce1eafb222c644230d03ad6011d357Wey-Yi GuyDEBUGFS_READ_FILE_OPS(sensitivity);
26405225935b53ce1eafb222c644230d03ad6011d357Wey-Yi GuyDEBUGFS_READ_FILE_OPS(chain_noise);
2641c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi GuyDEBUGFS_READ_FILE_OPS(power_save_status);
26427163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
26437163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
2644696bdee3ba216186e21997d20a839b76158346e6Wey-Yi GuyDEBUGFS_WRITE_FILE_OPS(csr);
2645a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
26461b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi GuyDEBUGFS_READ_FILE_OPS(fh_reg);
2647a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
26483e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' NguyenDEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
2649528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(force_reset);
265060987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes BergDEBUGFS_READ_FILE_OPS(rxon_flags);
265160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes BergDEBUGFS_READ_FILE_OPS(rxon_filter_flags);
26524bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(txfifo_flush);
2653ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_bt_stats);
265422de94de7de78b8de2fb1f2df5aa85b5556cfcfdStanislaw GruszkaDEBUGFS_WRITE_FILE_OPS(wd_timeout);
2655befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi GuyDEBUGFS_READ_FILE_OPS(bt_traffic);
2656c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
265754a9aa65f749673f851ef86481940394185c1b0eWey-Yi GuyDEBUGFS_READ_FILE_OPS(reply_tx_error);
265820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
2659712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/*
2660712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Create the debugfs files and directories
2661712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
2662712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */
2663712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerint iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2664712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
266595b1a8224abf6230899856753c5506a3f737a65bZhu Yi	struct dentry *phyd = priv->hw->wiphy->debugfsdir;
26664c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
2667712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
26684c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_drv = debugfs_create_dir(name, phyd);
26694c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_drv)
26704c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		return -ENOMEM;
2671712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
26724c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	priv->debugfs_dir = dir_drv;
26734c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg
26744c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_data = debugfs_create_dir("data", dir_drv);
26754c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_data)
26764c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;
26774c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_rf = debugfs_create_dir("rf", dir_drv);
26784c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_rf)
26794c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;
26804c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_debug = debugfs_create_dir("debug", dir_drv);
26814c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_debug)
2682712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		goto err;
2683712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
26844c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
26854c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
2686c8ac61cf6e53fefb3b439fc58390fb65d2730e63Johannes Berg	DEBUGFS_ADD_FILE(wowlan_sram, dir_data, S_IRUSR);
26874c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
26884c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
26894c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
26904c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
26914c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
26924c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
269323c0fcc66b4345ea97ae588c2e01f10c994652baWey-Yi Guy	DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
269423c0fcc66b4345ea97ae588c2e01f10c994652baWey-Yi Guy	DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
26954c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
26964c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
26974c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
26984c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
26994c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
27004c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
27014c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
27024c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
27034c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
27044c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
27054c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
27064c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
27074c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
27084c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
2709528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
2710b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar	DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
2711b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar	DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
2712b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar	DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
2713c68744fb935400964f7af4835017cad5014c8c88Wey-Yi Guy	DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
2714c6abdc0dc3440b9b6ae00a59c3560ab2160c7c7dWey-Yi Guy	DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR);
2715b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar
2716703bc583cb98a24eeedd297ee59dfa12852897d1Wey-Yi Guy	DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
2717703bc583cb98a24eeedd297ee59dfa12852897d1Wey-Yi Guy	DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
2718b7af6a99690503a48c63ce5e587b4e4555f31cdbWey-Yi Guy	DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
27190da0e5bf1522d75d446f5124e17016628d0a149eJohannes Berg	DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
272054a9aa65f749673f851ef86481940394185c1b0eWey-Yi Guy	DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
272160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
272260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
272322de94de7de78b8de2fb1f2df5aa85b5556cfcfdStanislaw Gruszka	DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
272488e58fc5d940c3463c7070a2a7a8a0ce65af3fdcStanislaw Gruszka	if (iwl_advanced_bt_coexist(priv))
2725befe8c469baebe8a0fb5bd9b7cd4afd8c54ebbd5Wey-Yi Guy		DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
2726703bc583cb98a24eeedd297ee59dfa12852897d1Wey-Yi Guy	DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
2727703bc583cb98a24eeedd297ee59dfa12852897d1Wey-Yi Guy			 &priv->disable_sens_cal);
2728703bc583cb98a24eeedd297ee59dfa12852897d1Wey-Yi Guy	DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
2729703bc583cb98a24eeedd297ee59dfa12852897d1Wey-Yi Guy			 &priv->disable_chain_noise_cal);
2730712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return 0;
2731712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
2732712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklererr:
27334c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	IWL_ERR(priv, "Can't create the debugfs directory\n");
2734712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	iwl_dbgfs_unregister(priv);
27354c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	return -ENOMEM;
2736712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
2737712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
2738712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/**
2739712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Remove the debugfs files and directories
2740712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
2741712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */
2742712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklervoid iwl_dbgfs_unregister(struct iwl_priv *priv)
2743712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
27444c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!priv->debugfs_dir)
2745712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		return;
2746712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
27474c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	debugfs_remove_recursive(priv->debugfs_dir);
27484c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	priv->debugfs_dir = NULL;
2749712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
2750712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
2751712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
2752445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler
2753