iwl-debugfs.c revision 4967c31677cf3c6c49aadf205f1a31d15d7610da
1712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/******************************************************************************
2712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
3712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * GPL LICENSE SUMMARY
4712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
51f44780827c6bbbcd1f12d5c6b6ce84f49a96bc0Reinette Chatre * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
6712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
7712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * This program is free software; you can redistribute it and/or modify
8712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * it under the terms of version 2 of the GNU General Public License as
9712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * published by the Free Software Foundation.
10712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
11712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * This program is distributed in the hope that it will be useful, but
12712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * WITHOUT ANY WARRANTY; without even the implied warranty of
13712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * General Public License for more details.
15712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
16712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * You should have received a copy of the GNU General Public License
17712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * along with this program; if not, write to the Free Software
18712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * USA
20712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
21712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * The full GNU General Public License is included in this distribution
22712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * in the file called LICENSE.GPL.
23712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
24712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Contact Information:
25759ef89fb096c4a6ef078d3cfd5682ac037bd789Winkler, Tomas *  Intel Linux Wireless <ilw@linux.intel.com>
26712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *****************************************************************************/
28712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
29712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/kernel.h>
30712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/module.h>
31712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/debugfs.h>
32712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
33712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/ieee80211.h>
34712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <net/mac80211.h>
35712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
36712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
373e0d4cb12f6fd97193a455b49125398b2231c87cTomas Winkler#include "iwl-dev.h"
38712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include "iwl-debug.h"
39fee1247a30e5b3d48fe985b4a935eb6818f3b464Tomas Winkler#include "iwl-core.h"
403395f6e9cf48469d7ee05703cad1502002741c16Tomas Winkler#include "iwl-io.h"
415225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy#include "iwl-calib.h"
42712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
43712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* create and remove of files */
444c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_FILE(name, parent, mode) do {			\
454c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!debugfs_create_file(#name, mode, parent, priv,		\
464c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg				 &iwl_dbgfs_##name##_ops))		\
474c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;						\
48712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} while (0)
49712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
504c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_BOOL(name, parent, ptr) do {			\
514c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	struct dentry *__tmp;						\
524c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	__tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR,		\
534c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg				    parent, ptr);			\
544c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (IS_ERR(__tmp) || !__tmp)					\
554c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;						\
56712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} while (0)
57712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
584c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_X32(name, parent, ptr) do {				\
594c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	struct dentry *__tmp;						\
604c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	__tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR,		\
614c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg				   parent, ptr);			\
624c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (IS_ERR(__tmp) || !__tmp)					\
634c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;						\
64445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler} while (0)
65445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler
66712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* file operation */
67712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_FUNC(name)                                         \
68712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_##name##_read(struct file *file,               \
69712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					char __user *user_buf,          \
70712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos);
71712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
72712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_WRITE_FUNC(name)                                        \
73712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_##name##_write(struct file *file,              \
74712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					const char __user *user_buf,    \
75712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos);
76712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
77712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
78712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
79712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
80712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	file->private_data = inode->i_private;
81712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return 0;
82712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
83712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
84712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_FILE_OPS(name)                                     \
85712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	DEBUGFS_READ_FUNC(name);                                        \
86712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic const struct file_operations iwl_dbgfs_##name##_ops = {          \
87712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.read = iwl_dbgfs_##name##_read,                       		\
88712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.open = iwl_dbgfs_open_file_generic,                    	\
89712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler};
90712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
91189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer#define DEBUGFS_WRITE_FILE_OPS(name)                                    \
92189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	DEBUGFS_WRITE_FUNC(name);                                       \
93189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummerstatic const struct file_operations iwl_dbgfs_##name##_ops = {          \
94189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	.write = iwl_dbgfs_##name##_write,                              \
95189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	.open = iwl_dbgfs_open_file_generic,                    	\
96189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer};
97189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
98189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
99712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_WRITE_FILE_OPS(name)                               \
100712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	DEBUGFS_READ_FUNC(name);                                        \
101712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	DEBUGFS_WRITE_FUNC(name);                                       \
102712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic const struct file_operations iwl_dbgfs_##name##_ops = {          \
103712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.write = iwl_dbgfs_##name##_write,                              \
104712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.read = iwl_dbgfs_##name##_read,                                \
105712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	.open = iwl_dbgfs_open_file_generic,                            \
106712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler};
107712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
108712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
109712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
110712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						char __user *user_buf,
111712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						size_t count, loff_t *ppos) {
112712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
11328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
11422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	char *buf;
115712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int pos = 0;
116712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
11722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	int cnt;
11822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ssize_t ret;
11998a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy	const size_t bufsz = 100 +
12098a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy		sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
12122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
12222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (!buf)
12322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -ENOMEM;
12422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
12522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
12622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
12798a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
12822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_mgmt_string(cnt),
12922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->tx_stats.mgmt[cnt]);
13022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
13122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
13222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
13322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
13498a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
13522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_ctrl_string(cnt),
13622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->tx_stats.ctrl[cnt]);
13722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
13822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
13922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
14022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->tx_stats.data_cnt);
14122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
14222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->tx_stats.data_bytes);
14322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
14422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	kfree(buf);
14522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	return ret;
14622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy}
14722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy
1487163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guystatic ssize_t iwl_dbgfs_clear_traffic_statistics_write(struct file *file,
14922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy					const char __user *user_buf,
15022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy					size_t count, loff_t *ppos)
15122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy{
15222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
15322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	u32 clear_flag;
15422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	char buf[8];
15522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	int buf_size;
156712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
15722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	memset(buf, 0, sizeof(buf));
15822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
15922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
16022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -EFAULT;
16122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (sscanf(buf, "%x", &clear_flag) != 1)
16222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -EFAULT;
1637163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guy	iwl_clear_traffic_stats(priv);
16422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy
16522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	return count;
166712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
167712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
168712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
169712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						char __user *user_buf,
170712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						size_t count, loff_t *ppos) {
171712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
17228f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
17322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	char *buf;
174712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int pos = 0;
17522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	int cnt;
17622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ssize_t ret;
17722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	const size_t bufsz = 100 +
17898a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy		sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
17922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
18022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	if (!buf)
18122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		return -ENOMEM;
182712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
18322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
18422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
18522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
18698a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
18722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_mgmt_string(cnt),
18822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->rx_stats.mgmt[cnt]);
18922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
19022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
19122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
19222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
19398a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy				 "\t%25s\t\t: %u\n",
19422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 get_ctrl_string(cnt),
19522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy				 priv->rx_stats.ctrl[cnt]);
19622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	}
19722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
19822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
19922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->rx_stats.data_cnt);
20022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
20122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy			 priv->rx_stats.data_bytes);
202712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
20322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
20422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	kfree(buf);
20522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy	return ret;
20622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy}
20722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy
208712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE1_MASK 0x000000ff;
209712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE2_MASK 0x0000ffff;
210712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE3_MASK 0x00ffffff;
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{
215712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	u32 val;
2162943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	char *buf;
217712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ssize_t ret;
218712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int i;
219712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int pos = 0;
22028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
2212943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	size_t bufsz;
222712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
2235ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	/* default is to dump the entire data segment */
2244c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
2254c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_offset = 0x800000;
2265ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy		if (priv->ucode_type == UCODE_INIT)
2274c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg			priv->dbgfs_sram_len = priv->ucode_init_data.len;
2285ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy		else
2294c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg			priv->dbgfs_sram_len = priv->ucode_data.len;
2305ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	}
2314c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	bufsz =  30 + priv->dbgfs_sram_len * sizeof(char) * 10;
2322943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	buf = kmalloc(bufsz, GFP_KERNEL);
2332943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	if (!buf)
2342943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy		return -ENOMEM;
2355ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
2364c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg			priv->dbgfs_sram_len);
2375ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
2384c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg			priv->dbgfs_sram_offset);
2394c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	for (i = priv->dbgfs_sram_len; i > 0; i -= 4) {
2404c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		val = iwl_read_targ_mem(priv, priv->dbgfs_sram_offset + \
2414c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg					priv->dbgfs_sram_len - i);
242712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		if (i < 4) {
243712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			switch (i) {
244712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			case 1:
245712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				val &= BYTE1_MASK;
246712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				break;
247712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			case 2:
248712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				val &= BYTE2_MASK;
249712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				break;
250712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			case 3:
251712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				val &= BYTE3_MASK;
252712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler				break;
253712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			}
254712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		}
2552943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy		if (!(i % 16))
2562943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos, "\n");
257db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar		pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
258712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	}
259db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar	pos += scnprintf(buf + pos, bufsz - pos, "\n");
260712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
261712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2622943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy	kfree(buf);
263712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return ret;
264712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
265712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
266712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_sram_write(struct file *file,
267712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					const char __user *user_buf,
268712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos)
269712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
270712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	struct iwl_priv *priv = file->private_data;
271712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	char buf[64];
272712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int buf_size;
273712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	u32 offset, len;
274712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
275712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	memset(buf, 0, sizeof(buf));
276712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	buf_size = min(count, sizeof(buf) -  1);
277712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	if (copy_from_user(buf, user_buf, buf_size))
278712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		return -EFAULT;
279712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
280712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
2814c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_offset = offset;
2824c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_len = len;
283712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	} else {
2844c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_offset = 0;
2854c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		priv->dbgfs_sram_len = 0;
286712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	}
287712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
288712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return count;
289712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
290712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
291712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
292712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					size_t count, loff_t *ppos)
293712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
29428f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
2956def9761f72501e638e79eebcd70afea12a3a93dTomas Winkler	struct iwl_station_entry *station;
2965425e490471d521bae2fce16d22995803b41d90fTomas Winkler	int max_sta = priv->hw_params.max_stations;
297712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	char *buf;
298712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	int i, j, pos = 0;
299712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ssize_t ret;
300712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	/* Add 30 for initial string */
301712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations);
302712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
303712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	buf = kmalloc(bufsz, GFP_KERNEL);
3043ac7f14694dd38273d9d96f1c873233d71190c15Tomas Winkler	if (!buf)
305712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		return -ENOMEM;
306712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
307db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar	pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
308712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			priv->num_stations);
309712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
310712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	for (i = 0; i < max_sta; i++) {
311712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		station = &priv->stations[i];
312712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		if (station->used) {
313db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos,
314db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar					"station %d:\ngeneral data:\n", i+1);
315db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n",
316712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					station->sta.sta.sta_id);
317db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n",
318712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					station->sta.mode);
319db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos,
320db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar					"flags: 0x%x\n",
321712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler					station->sta.station_flags_msk);
322db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n");
323db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos,
324344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller					"seq_num\t\ttxq_id");
325db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos,
326344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller					"\tframe_count\twait_for_ba\t");
327db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos,
328db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar					"start_idx\tbitmap0\t");
329db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos,
330344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller					"bitmap1\trate_n_flags");
331344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller			pos += scnprintf(buf + pos, bufsz - pos, "\n");
332712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
333712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			for (j = 0; j < MAX_TID_COUNT; j++) {
334db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar				pos += scnprintf(buf + pos, bufsz - pos,
335344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller						"[%d]:\t\t%u", j,
336db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar						station->tid[j].seq_number);
337db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar				pos += scnprintf(buf + pos, bufsz - pos,
338344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller						"\t%u\t\t%u\t\t%u\t\t",
339712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						station->tid[j].agg.txq_id,
340712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						station->tid[j].agg.frame_count,
341712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						station->tid[j].agg.wait_for_ba);
342db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar				pos += scnprintf(buf + pos, bufsz - pos,
343344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller						"%u\t%llu\t%u",
344712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						station->tid[j].agg.start_idx,
34516788599a9601cbba6ad7b58b3b52227ea59c013John W. Linville						(unsigned long long)station->tid[j].agg.bitmap,
346712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler						station->tid[j].agg.rate_n_flags);
347344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller				pos += scnprintf(buf + pos, bufsz - pos, "\n");
348712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler			}
349db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar			pos += scnprintf(buf + pos, bufsz - pos, "\n");
350712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		}
351712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	}
352712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
353712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
354712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	kfree(buf);
355712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return ret;
356712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
357712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
3580848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guystatic ssize_t iwl_dbgfs_nvm_read(struct file *file,
3598dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				       char __user *user_buf,
3608dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				       size_t count,
3618dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				       loff_t *ppos)
3628dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler{
3638dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	ssize_t ret;
36428f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
3658dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	int pos = 0, ofs = 0, buf_size = 0;
3668dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	const u8 *ptr;
3678dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	char *buf;
368e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy	u16 eeprom_ver;
3698dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	size_t eeprom_len = priv->cfg->eeprom_size;
3708dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	buf_size = 4 * eeprom_len + 256;
3718dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler
3728dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	if (eeprom_len % 16) {
3730848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy		IWL_ERR(priv, "NVM size is not multiple of 16.\n");
3748dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		return -ENODATA;
3758dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	}
3768dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler
377c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall	ptr = priv->eeprom;
378c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall	if (!ptr) {
379c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall		IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
380c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall		return -ENOMEM;
381c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall	}
382c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall
3838dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	/* 4 characters for byte 0xYY */
3848dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	buf = kzalloc(buf_size, GFP_KERNEL);
3858dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	if (!buf) {
38615b1687cb4f45b87ddbe4dfc7759ff5bb69497d2Winkler, Tomas		IWL_ERR(priv, "Can not allocate Buffer\n");
3878dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		return -ENOMEM;
3888dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	}
389e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
390e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy	pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, "
391e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy			"version: 0x%x\n",
3920848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy			(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
393e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy			 ? "OTP" : "EEPROM", eeprom_ver);
3948dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
3958dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
3968dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
3978dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler				   buf_size - pos, 0);
3982fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre		pos += strlen(buf + pos);
3998dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler		if (buf_size - pos > 0)
4008dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler			buf[pos++] = '\n';
4018dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	}
4028dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler
4038dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
4048dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	kfree(buf);
4058dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler	return ret;
4068dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler}
407712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
408b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guystatic ssize_t iwl_dbgfs_log_event_read(struct file *file,
409b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy					 char __user *user_buf,
410b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy					 size_t count, loff_t *ppos)
411b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy{
412b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	struct iwl_priv *priv = file->private_data;
413b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	char *buf;
414b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	int pos = 0;
415b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	ssize_t ret = -ENOMEM;
416b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy
417937c397eb633b804d9a806d08c395ecfc42b1fecWey-Yi Guy	ret = pos = priv->cfg->ops->lib->dump_nic_event_log(
418937c397eb633b804d9a806d08c395ecfc42b1fecWey-Yi Guy					priv, true, &buf, true);
419937c397eb633b804d9a806d08c395ecfc42b1fecWey-Yi Guy	if (buf) {
420b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy		ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
421b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy		kfree(buf);
422b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	}
423b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy	return ret;
424b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy}
425b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy
426189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummerstatic ssize_t iwl_dbgfs_log_event_write(struct file *file,
427189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer					const char __user *user_buf,
428189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer					size_t count, loff_t *ppos)
429189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer{
430189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	struct iwl_priv *priv = file->private_data;
431189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	u32 event_log_flag;
432189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	char buf[8];
433189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	int buf_size;
434189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
435189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	memset(buf, 0, sizeof(buf));
436189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	buf_size = min(count, sizeof(buf) -  1);
437189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	if (copy_from_user(buf, user_buf, buf_size))
438189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer		return -EFAULT;
439189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	if (sscanf(buf, "%d", &event_log_flag) != 1)
440189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer		return -EFAULT;
441189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	if (event_log_flag == 1)
442b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy		priv->cfg->ops->lib->dump_nic_event_log(priv, true,
443b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy							NULL, false);
444189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
445189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer	return count;
446189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer}
447189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer
448d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
449d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
450d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomasstatic ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
451d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas				       size_t count, loff_t *ppos)
452d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas{
45328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
454d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	struct ieee80211_channel *channels = NULL;
455d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	const struct ieee80211_supported_band *supp_band = NULL;
456d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	int pos = 0, i, bufsz = PAGE_SIZE;
457d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	char *buf;
458d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	ssize_t ret;
459d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
460d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
461d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		return -EAGAIN;
462d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
463d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	buf = kzalloc(bufsz, GFP_KERNEL);
464d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	if (!buf) {
46515b1687cb4f45b87ddbe4dfc7759ff5bb69497d2Winkler, Tomas		IWL_ERR(priv, "Can not allocate Buffer\n");
466d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		return -ENOMEM;
467d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	}
468d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
469d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
470a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	if (supp_band) {
471a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		channels = supp_band->channels;
472d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
473d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		pos += scnprintf(buf + pos, bufsz - pos,
474a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				"Displaying %d channels in 2.4GHz band 802.11bg):\n",
475a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				supp_band->n_channels);
476d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
477a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		for (i = 0; i < supp_band->n_channels; i++)
478a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
479a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"%d: %ddBm: BSS%s%s, %s.\n",
480a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					ieee80211_frequency_to_channel(
481a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].center_freq),
482a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].max_power,
483a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags & IEEE80211_CHAN_RADAR ?
484a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					" (IEEE 802.11h required)" : "",
485a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
486a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					|| (channels[i].flags &
487a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_RADAR)) ? "" :
488a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					", IBSS",
489a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags &
490a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_PASSIVE_SCAN ?
491a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"passive only" : "active/passive");
492a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	}
493d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
494a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	if (supp_band) {
495a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		channels = supp_band->channels;
496d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
497d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas		pos += scnprintf(buf + pos, bufsz - pos,
498a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				"Displaying %d channels in 5.2GHz band (802.11a)\n",
499a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy				supp_band->n_channels);
500a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy
501a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy		for (i = 0; i < supp_band->n_channels; i++)
502a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
503a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"%d: %ddBm: BSS%s%s, %s.\n",
504a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					ieee80211_frequency_to_channel(
505a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].center_freq),
506a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].max_power,
507a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags & IEEE80211_CHAN_RADAR ?
508a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					" (IEEE 802.11h required)" : "",
509a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
510a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					|| (channels[i].flags &
511a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_RADAR)) ? "" :
512a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					", IBSS",
513a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					channels[i].flags &
514a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					IEEE80211_CHAN_PASSIVE_SCAN ?
515a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy					"passive only" : "active/passive");
516a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy	}
517d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
518d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	kfree(buf);
519d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas	return ret;
520d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas}
521d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas
52208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guystatic ssize_t iwl_dbgfs_status_read(struct file *file,
52308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy						char __user *user_buf,
52408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy						size_t count, loff_t *ppos) {
52508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy
52628f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
52708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	char buf[512];
52808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	int pos = 0;
52908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	const size_t bufsz = sizeof(buf);
53008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy
53108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
53208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_HCMD_ACTIVE, &priv->status));
53308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
53408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_INT_ENABLED, &priv->status));
53508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
53608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_RF_KILL_HW, &priv->status));
5377812b16730ccebce71a3b2228ac08dd4f8b39469Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n",
5387812b16730ccebce71a3b2228ac08dd4f8b39469Wey-Yi Guy		test_bit(STATUS_CT_KILL, &priv->status));
53908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
54008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_INIT, &priv->status));
54108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
54208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_ALIVE, &priv->status));
54308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
54408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_READY, &priv->status));
54508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
54608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_TEMPERATURE, &priv->status));
54708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
54808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_GEO_CONFIGURED, &priv->status));
54908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
55008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_EXIT_PENDING, &priv->status));
55108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
55208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_STATISTICS, &priv->status));
55308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
55408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_SCANNING, &priv->status));
55508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
55608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_SCAN_ABORTING, &priv->status));
55708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
55808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_SCAN_HW, &priv->status));
55908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
56008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_POWER_PMI, &priv->status));
56108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
56208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy		test_bit(STATUS_FW_ERROR, &priv->status));
56308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
56408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy}
56508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy
566a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_read(struct file *file,
567a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					char __user *user_buf,
568a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					size_t count, loff_t *ppos) {
569a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
57028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
571a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int pos = 0;
572a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int cnt = 0;
573a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	char *buf;
574a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int bufsz = 24 * 64; /* 24 items * 64 char per item */
575a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	ssize_t ret;
576a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
577a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
578a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (!buf) {
579a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
580a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		return -ENOMEM;
581a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	}
582a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
583a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
584a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy			"Interrupt Statistics Report:\n");
585a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
586a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
587a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.hw);
588a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
589a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.sw);
590a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (priv->isr_stats.sw > 0) {
591a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
592a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy			"\tLast Restarting Code:  0x%X\n",
593a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy			priv->isr_stats.sw_err);
594a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	}
595a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#ifdef CONFIG_IWLWIFI_DEBUG
596a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
597a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.sch);
598a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
599a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.alive);
600a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#endif
601a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
602a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		"HW RF KILL switch toggled:\t %u\n",
603a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.rfkill);
604a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
605a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
606a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.ctkill);
607a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
608a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
609a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.wakeup);
610a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
611a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
612a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		"Rx command responses:\t\t %u\n",
613a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.rx);
614a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	for (cnt = 0; cnt < REPLY_MAX; cnt++) {
615a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		if (priv->isr_stats.rx_handlers[cnt] > 0)
616a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
617a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy				"\tRx handler[%36s]:\t\t %u\n",
618a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy				get_cmd_string(cnt),
619a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy				priv->isr_stats.rx_handlers[cnt]);
620a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	}
621a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
622a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
623a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.tx);
624a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
625a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
626a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		priv->isr_stats.unhandled);
627a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
628a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
629a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	kfree(buf);
630a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	return ret;
631a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy}
632a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
633a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_write(struct file *file,
634a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					 const char __user *user_buf,
635a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy					 size_t count, loff_t *ppos)
636a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy{
637a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
638a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	char buf[8];
639a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	int buf_size;
640a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	u32 reset_flag;
641a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
642a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	memset(buf, 0, sizeof(buf));
643a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
644a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
645a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		return -EFAULT;
646a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (sscanf(buf, "%x", &reset_flag) != 1)
647a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		return -EFAULT;
648a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	if (reset_flag == 0)
649a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy		iwl_clear_isr_stats(priv);
650a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
651a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy	return count;
652a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy}
653a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
654f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guystatic ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
655f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy				       size_t count, loff_t *ppos)
656f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy{
65728f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
658f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy	int pos = 0, i;
659f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy	char buf[256];
660f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy	const size_t bufsz = sizeof(buf);
661f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy
662f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy	for (i = 0; i < AC_NUM; i++) {
663f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
664f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy			"\tcw_min\tcw_max\taifsn\ttxop\n");
665f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
666f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy				"AC[%d]\t%u\t%u\t%u\t%u\n", i,
667f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy				priv->qos_data.def_qos_parm.ac[i].cw_min,
668f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy				priv->qos_data.def_qos_parm.ac[i].cw_max,
669f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy				priv->qos_data.def_qos_parm.ac[i].aifsn,
670f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy				priv->qos_data.def_qos_parm.ac[i].edca_txop);
671f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy	}
6724967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
673f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy}
674a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy
675a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guystatic ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
676a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy				  size_t count, loff_t *ppos)
677a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy{
67828f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
679a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	int pos = 0;
680a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	char buf[256];
681a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	const size_t bufsz = sizeof(buf);
682a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy
683a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
684a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy			 "allow blinking: %s\n",
685a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy			 (priv->allow_blinking) ? "True" : "False");
686a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	if (priv->allow_blinking) {
687a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
688a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy				 "Led blinking rate: %u\n",
689a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy				 priv->last_blink_rate);
690a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
691a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy				 "Last blink time: %lu\n",
692a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy				 priv->last_blink_time);
693a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy	}
694a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy
6954967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
696a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy}
697a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy
698fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guystatic ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
699fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				char __user *user_buf,
700fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				size_t count, loff_t *ppos)
701fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy{
70228f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
7033ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
704fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	struct iwl_tt_restriction *restriction;
705fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	char buf[100];
706fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	int pos = 0;
707fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	const size_t bufsz = sizeof(buf);
708fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy
709fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
710fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy			"Thermal Throttling Mode: %s\n",
7113ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg			tt->advanced_tt ? "Advance" : "Legacy");
712fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
713fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy			"Thermal Throttling State: %d\n",
714fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy			tt->state);
7153ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg	if (tt->advanced_tt) {
716fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		restriction = tt->restriction + tt->state;
717fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
718fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				"Tx mode: %d\n",
719fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				restriction->tx_stream);
720fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
721fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				"Rx mode: %d\n",
722fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				restriction->rx_stream);
723fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
724fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				"HT mode: %d\n",
725fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy				restriction->is_ht);
726fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy	}
7274967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
728fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy}
729fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy
7301e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guystatic ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
7311e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 const char __user *user_buf,
7321e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 size_t count, loff_t *ppos)
7331e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy{
7341e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
7351e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	char buf[8];
7361e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	int buf_size;
7371e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	int ht40;
7381e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7391e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	memset(buf, 0, sizeof(buf));
7401e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
7411e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
7421e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		return -EFAULT;
7431e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	if (sscanf(buf, "%d", &ht40) != 1)
7441e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		return -EFAULT;
7451e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	if (!iwl_is_associated(priv))
7461e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		priv->disable_ht40 = ht40 ? true : false;
7471e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	else {
7481e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		IWL_ERR(priv, "Sta associated with AP - "
7491e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy			"Change to 40MHz channel support is not allowed\n");
7501e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy		return -EINVAL;
7511e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	}
7521e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7531e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	return count;
7541e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy}
7551e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7561e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guystatic ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
7571e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 char __user *user_buf,
7581e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy					 size_t count, loff_t *ppos)
7591e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy{
76028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
7611e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	char buf[100];
7621e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	int pos = 0;
7631e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	const size_t bufsz = sizeof(buf);
7641e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
7651e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
7661e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy			"11n 40MHz Mode: %s\n",
7671e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy			priv->disable_ht40 ? "Disabled" : "Enabled");
7684967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
7691e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy}
7701e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy
771e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
772e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    const char __user *user_buf,
773e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    size_t count, loff_t *ppos)
774e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{
775e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	struct iwl_priv *priv = file->private_data;
776e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	char buf[8];
777e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int buf_size;
778e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int value;
779e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
780e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	memset(buf, 0, sizeof(buf));
781e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	buf_size = min(count, sizeof(buf) -  1);
782e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (copy_from_user(buf, user_buf, buf_size))
783e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		return -EFAULT;
784e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
785e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (sscanf(buf, "%d", &value) != 1)
786e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		return -EINVAL;
787e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
788e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	/*
789e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 * Our users expect 0 to be "CAM", but 0 isn't actually
790e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 * valid here. However, let's not confuse them and present
791e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 * IWL_POWER_INDEX_1 as "1", not "0".
792e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	 */
7931a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre	if (value == 0)
7941a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre		return -EINVAL;
7951a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre	else if (value > 0)
796e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		value -= 1;
797e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
798e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (value != -1 && (value < 0 || value >= IWL_POWER_NUM))
799e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		return -EINVAL;
800e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
8014ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy	if (!iwl_is_ready_rf(priv))
8024ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy		return -EAGAIN;
8034ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy
804e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	priv->power_data.debug_sleep_level_override = value;
805e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
806d3a571971e5af241074947fc80f6284677f6e014Reinette Chatre	mutex_lock(&priv->mutex);
8074ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy	iwl_power_update_mode(priv, true);
808d3a571971e5af241074947fc80f6284677f6e014Reinette Chatre	mutex_unlock(&priv->mutex);
809e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
810e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	return count;
811e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg}
812e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
813e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
814e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						   char __user *user_buf,
815e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						   size_t count, loff_t *ppos)
816e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{
81728f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
818e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	char buf[10];
819e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int pos, value;
820e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	const size_t bufsz = sizeof(buf);
821e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
822e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	/* see the write function */
823e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	value = priv->power_data.debug_sleep_level_override;
824e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	if (value >= 0)
825e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		value += 1;
826e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
827e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	pos = scnprintf(buf, bufsz, "%d\n", value);
828e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
829e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg}
830e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
831e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
832e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    char __user *user_buf,
833e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg						    size_t count, loff_t *ppos)
834e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{
83528f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
836e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	char buf[200];
837e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	int pos = 0, i;
838e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	const size_t bufsz = sizeof(buf);
839e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd;
840e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
841e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	pos += scnprintf(buf + pos, bufsz - pos,
842e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 "flags: %#.2x\n", le16_to_cpu(cmd->flags));
843e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	pos += scnprintf(buf + pos, bufsz - pos,
844e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 "RX/TX timeout: %d/%d usec\n",
845e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 le32_to_cpu(cmd->rx_data_timeout),
846e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg			 le32_to_cpu(cmd->tx_data_timeout));
847e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
848e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg		pos += scnprintf(buf + pos, bufsz - pos,
849e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg				 "sleep_interval[%d]: %d\n", i,
850e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg				 le32_to_cpu(cmd->sleep_interval[i]));
851e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
852e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
853e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg}
854e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg
855712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_WRITE_FILE_OPS(sram);
856b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(log_event);
8570848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi GuyDEBUGFS_READ_FILE_OPS(nvm);
858712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_FILE_OPS(stations);
859d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, TomasDEBUGFS_READ_FILE_OPS(channels);
86008df05aa9b25f3079585855506022bb33a011183Wey-Yi GuyDEBUGFS_READ_FILE_OPS(status);
861a83b9141b540f96dd59409c6487828e880113a29Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(interrupt);
862f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi GuyDEBUGFS_READ_FILE_OPS(qos);
863a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi GuyDEBUGFS_READ_FILE_OPS(led);
864fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi GuyDEBUGFS_READ_FILE_OPS(thermal_throttling);
8651e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
866e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes BergDEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
867e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes BergDEBUGFS_READ_FILE_OPS(current_sleep_command);
868712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
86920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guystatic ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
87020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 char __user *user_buf,
87120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 size_t count, loff_t *ppos)
87220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy{
87320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_priv *priv = file->private_data;
87420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int pos = 0, ofs = 0;
87520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int cnt = 0, entry;
87620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_tx_queue *txq;
87720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_queue *q;
87820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_rx_queue *rxq = &priv->rxq;
87920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	char *buf;
88020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
88188804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		(priv->cfg->num_of_queues * 32 * 8) + 400;
88220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	const u8 *ptr;
88320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	ssize_t ret;
88420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
88588804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	if (!priv->txq) {
88688804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		IWL_ERR(priv, "txq not ready\n");
88788804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		return -EAGAIN;
88888804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	}
88920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
89020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (!buf) {
89120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		IWL_ERR(priv, "Can not allocate buffer\n");
89220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		return -ENOMEM;
89320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
89420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
89520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
89620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		txq = &priv->txq[cnt];
89720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		q = &txq->q;
89820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
89920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				"q[%d]: read_ptr: %u, write_ptr: %u\n",
90020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				cnt, q->read_ptr, q->write_ptr);
90120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
90220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) {
90320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		ptr = priv->tx_traffic;
90420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
90520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				"Tx Traffic idx: %u\n",	priv->tx_traffic_idx);
90620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
90720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
90820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			     entry++,  ofs += 16) {
90920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				pos += scnprintf(buf + pos, bufsz - pos,
91020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						"0x%.4x ", ofs);
91120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
91220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						   buf + pos, bufsz - pos, 0);
9132fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre				pos += strlen(buf + pos);
91420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				if (bufsz - pos > 0)
91520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					buf[pos++] = '\n';
91620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			}
91720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		}
91820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
91920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
92020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
92120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
92220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			"read: %u, write: %u\n",
92320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			 rxq->read, rxq->write);
92420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
92520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) {
92620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		ptr = priv->rx_traffic;
92720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
92820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				"Rx Traffic idx: %u\n",	priv->rx_traffic_idx);
92920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
93020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
93120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			     entry++,  ofs += 16) {
93220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				pos += scnprintf(buf + pos, bufsz - pos,
93320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						"0x%.4x ", ofs);
93420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
93520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy						   buf + pos, bufsz - pos, 0);
9362fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre				pos += strlen(buf + pos);
93720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy				if (bufsz - pos > 0)
93820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					buf[pos++] = '\n';
93920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy			}
94020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		}
94120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	}
94220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
94320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
94420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	kfree(buf);
94520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	return ret;
94620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy}
94720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
94820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guystatic ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
94920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 const char __user *user_buf,
95020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy					 size_t count, loff_t *ppos)
95120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy{
95220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	struct iwl_priv *priv = file->private_data;
95320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	char buf[8];
95420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int buf_size;
95520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	int traffic_log;
95620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
95720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	memset(buf, 0, sizeof(buf));
95820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
95920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
96020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		return -EFAULT;
96120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (sscanf(buf, "%d", &traffic_log) != 1)
96220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		return -EFAULT;
96320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	if (traffic_log == 0)
96420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy		iwl_reset_traffic_log(priv);
96520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
96620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy	return count;
96720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy}
96820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
969141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guystatic ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
970141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						char __user *user_buf,
971141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						size_t count, loff_t *ppos) {
972141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
97328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
974141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	struct iwl_tx_queue *txq;
975141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	struct iwl_queue *q;
976141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	char *buf;
977141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int pos = 0;
978141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int cnt;
979141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int ret;
980d23db556819c00d297c0f447bdd75b282d563122Wey-Yi Guy	const size_t bufsz = sizeof(char) * 64 * priv->cfg->num_of_queues;
981141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
98288804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	if (!priv->txq) {
98388804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		IWL_ERR(priv, "txq not ready\n");
98488804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy		return -EAGAIN;
98588804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy	}
986141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
987141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	if (!buf)
988141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		return -ENOMEM;
989141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
990141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
991141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		txq = &priv->txq[cnt];
992141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		q = &txq->q;
993141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
994141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				"hwq %.2d: read=%u write=%u stop=%d"
995141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				" swq_id=%#.2x (ac %d/hwq %d)\n",
996141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				cnt, q->read_ptr, q->write_ptr,
997141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				!!test_bit(cnt, priv->queue_stopped),
998141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				txq->swq_id,
999141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				txq->swq_id & 0x80 ? txq->swq_id & 3 :
1000141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				txq->swq_id,
1001141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				txq->swq_id & 0x80 ? (txq->swq_id >> 2) &
1002141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				0x1f : txq->swq_id);
1003141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		if (cnt >= 4)
1004141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy			continue;
1005141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		/* for the ACs, display the stop count too */
1006141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
1007141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				"        stop-count: %d\n",
1008141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy				atomic_read(&priv->queue_stop_count[cnt]));
1009141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	}
1010141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1011141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	kfree(buf);
1012141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	return ret;
1013141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy}
1014141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
1015141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guystatic ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1016141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						char __user *user_buf,
1017141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						size_t count, loff_t *ppos) {
1018141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
101928f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1020141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	struct iwl_rx_queue *rxq = &priv->rxq;
1021141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	char buf[256];
1022141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	int pos = 0;
1023141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	const size_t bufsz = sizeof(buf);
1024141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
1025141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
1026141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						rxq->read);
1027141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
1028141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						rxq->write);
1029141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
1030141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy						rxq->free_count);
1031141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
1032141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy			 le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF);
1033141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1034141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy}
1035141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy
1036e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
1037e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy				     int bufsz)
1038e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{
1039e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	int p = 0;
1040e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1041e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	p += scnprintf(buf + p, bufsz - p,
1042e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		"Statistics Flag(0x%X):\n",
1043e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		le32_to_cpu(priv->statistics.flag));
1044e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
1045e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		p += scnprintf(buf + p, bufsz - p,
1046e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		"\tStatistics have been cleared\n");
1047e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	p += scnprintf(buf + p, bufsz - p,
1048e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		"\tOperational Frequency: %s\n",
1049e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		(le32_to_cpu(priv->statistics.flag) &
1050e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		UCODE_STATISTICS_FREQUENCY_MSK)
1051e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		 ? "2.4 GHz" : "5.2 GHz");
1052e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	p += scnprintf(buf + p, bufsz - p,
1053e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		"\tTGj Narrow Band: %s\n",
1054e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		(le32_to_cpu(priv->statistics.flag) &
1055e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		UCODE_STATISTICS_NARROW_BAND_MSK)
1056e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		 ? "enabled" : "disabled");
1057e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	return p;
1058e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy}
1059e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1060e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guystatic const char ucode_stats_header[] =
1061e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	"%-32s     current  acumulative       delta         max\n";
1062e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guystatic const char ucode_stats_short_format[] =
1063e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	"  %-30s %10u\n";
1064e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guystatic const char ucode_stats_format[] =
1065e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	"  %-30s %10u  %10u  %10u  %10u\n";
1066e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1067e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1068e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					char __user *user_buf,
1069e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					size_t count, loff_t *ppos)
1070e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{
107128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1072e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	int pos = 0;
1073e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	char *buf;
1074e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	int bufsz = sizeof(struct statistics_rx_phy) * 40 +
1075e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy		sizeof(struct statistics_rx_non_phy) * 40 +
1076e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy		sizeof(struct statistics_rx_ht_phy) * 40 + 400;
1077e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	ssize_t ret;
1078e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
1079e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
108092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy	struct statistics_rx_non_phy *general, *accum_general;
1081e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	struct statistics_rx_non_phy *delta_general, *max_general;
1082e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
1083e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1084e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	if (!iwl_is_alive(priv))
1085e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		return -EAGAIN;
1086e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1087e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
1088e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	if (!buf) {
1089e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
1090e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		return -ENOMEM;
1091e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	}
1092e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1093e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	/* the statistic information display here is based on
1094e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	 * the last statistics notification from uCode
1095e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	 * might not reflect the current uCode activity
1096e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	 */
1097e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	ofdm = &priv->statistics.rx.ofdm;
1098e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	cck = &priv->statistics.rx.cck;
1099e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	general = &priv->statistics.rx.general;
1100e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	ht = &priv->statistics.rx.ofdm_ht;
110192a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy	accum_ofdm = &priv->accum_statistics.rx.ofdm;
110292a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy	accum_cck = &priv->accum_statistics.rx.cck;
110392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy	accum_general = &priv->accum_statistics.rx.general;
110492a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy	accum_ht = &priv->accum_statistics.rx.ofdm_ht;
1105e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	delta_ofdm = &priv->delta_statistics.rx.ofdm;
1106e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	delta_cck = &priv->delta_statistics.rx.cck;
1107e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	delta_general = &priv->delta_statistics.rx.general;
1108e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	delta_ht = &priv->delta_statistics.rx.ofdm_ht;
1109e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	max_ofdm = &priv->max_delta.rx.ofdm;
1110e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	max_cck = &priv->max_delta.rx.cck;
1111e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	max_general = &priv->max_delta.rx.general;
1112e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	max_ht = &priv->max_delta.rx.ofdm_ht;
1113e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy
1114e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1115e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1116e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "Statistics_Rx - OFDM:");
1117e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1118e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "ina_cnt:", le32_to_cpu(ofdm->ina_cnt),
1119e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->ina_cnt,
1120e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
1121e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1122e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "fina_cnt:",
1123e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
1124e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
1125e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1126e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "plcp_err:",
1127e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
1128e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->plcp_err, max_ofdm->plcp_err);
1129e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1130e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "crc32_err:",
1131e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
1132e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->crc32_err, max_ofdm->crc32_err);
1133e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1134e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "overrun_err:",
113592a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->overrun_err),
1136e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->overrun_err,
1137e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->overrun_err, max_ofdm->overrun_err);
1138e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1139e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "early_overrun_err:",
114092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->early_overrun_err),
1141e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->early_overrun_err,
1142e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->early_overrun_err,
1143e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ofdm->early_overrun_err);
1144e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1145e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "crc32_good:",
114692a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->crc32_good),
1147e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->crc32_good,
1148e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->crc32_good, max_ofdm->crc32_good);
1149e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1150e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "false_alarm_cnt:",
115192a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->false_alarm_cnt),
1152e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->false_alarm_cnt,
1153e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->false_alarm_cnt,
1154e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ofdm->false_alarm_cnt);
1155e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1156e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "fina_sync_err_cnt:",
115792a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->fina_sync_err_cnt),
1158e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->fina_sync_err_cnt,
1159e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->fina_sync_err_cnt,
1160e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ofdm->fina_sync_err_cnt);
1161e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1162e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "sfd_timeout:",
116392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->sfd_timeout),
1164e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->sfd_timeout,
1165e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->sfd_timeout,
1166e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ofdm->sfd_timeout);
1167e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1168e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "fina_timeout:",
116992a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->fina_timeout),
1170e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->fina_timeout,
1171e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->fina_timeout,
1172e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ofdm->fina_timeout);
1173e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1174e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "unresponded_rts:",
117592a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->unresponded_rts),
1176e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->unresponded_rts,
1177e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->unresponded_rts,
1178e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ofdm->unresponded_rts);
1179e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1180e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"rxe_frame_lmt_ovrun:",
118192a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
1182e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->rxe_frame_limit_overrun,
1183e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->rxe_frame_limit_overrun,
1184e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ofdm->rxe_frame_limit_overrun);
1185e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1186e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "sent_ack_cnt:",
118792a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->sent_ack_cnt),
1188e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->sent_ack_cnt,
1189e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->sent_ack_cnt,
1190e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ofdm->sent_ack_cnt);
1191e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1192e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "sent_cts_cnt:",
119392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->sent_cts_cnt),
1194e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->sent_cts_cnt,
1195e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt);
1196e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1197e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "sent_ba_rsp_cnt:",
119892a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
1199e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->sent_ba_rsp_cnt,
1200e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->sent_ba_rsp_cnt,
1201e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ofdm->sent_ba_rsp_cnt);
1202e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1203e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "dsp_self_kill:",
120492a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->dsp_self_kill),
1205e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->dsp_self_kill,
1206e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->dsp_self_kill,
1207e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ofdm->dsp_self_kill);
1208e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1209e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "mh_format_err:",
121092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->mh_format_err),
1211e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->mh_format_err,
1212e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->mh_format_err,
1213e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ofdm->mh_format_err);
1214e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1215e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "re_acq_main_rssi_sum:",
121692a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ofdm->re_acq_main_rssi_sum),
1217e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ofdm->re_acq_main_rssi_sum,
1218e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ofdm->re_acq_main_rssi_sum,
1219e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			max_ofdm->re_acq_main_rssi_sum);
1220e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy
1221e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1222e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "Statistics_Rx - CCK:");
1223e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1224e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "ina_cnt:",
1225e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
1226e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->ina_cnt, max_cck->ina_cnt);
1227e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1228e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "fina_cnt:",
1229e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
1230e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->fina_cnt, max_cck->fina_cnt);
1231e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1232e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "plcp_err:",
1233e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
1234e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->plcp_err, max_cck->plcp_err);
1235e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1236e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "crc32_err:",
1237e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
1238e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->crc32_err, max_cck->crc32_err);
1239e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1240e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "overrun_err:",
124192a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->overrun_err),
1242e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->overrun_err,
1243e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->overrun_err, max_cck->overrun_err);
1244e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1245e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "early_overrun_err:",
124692a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->early_overrun_err),
1247e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->early_overrun_err,
1248e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->early_overrun_err,
1249e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_cck->early_overrun_err);
1250e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1251e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "crc32_good:",
1252e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
1253e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->crc32_good,
1254e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_cck->crc32_good);
1255e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1256e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "false_alarm_cnt:",
125792a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->false_alarm_cnt),
1258e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->false_alarm_cnt,
1259e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
1260e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1261e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "fina_sync_err_cnt:",
126292a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->fina_sync_err_cnt),
1263e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->fina_sync_err_cnt,
1264e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->fina_sync_err_cnt,
1265e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_cck->fina_sync_err_cnt);
1266e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1267e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "sfd_timeout:",
126892a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->sfd_timeout),
1269e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->sfd_timeout,
1270e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->sfd_timeout, max_cck->sfd_timeout);
1271e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1272e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "fina_timeout:",
127392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->fina_timeout),
1274e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->fina_timeout,
1275e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->fina_timeout, max_cck->fina_timeout);
1276e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1277e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "unresponded_rts:",
127892a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->unresponded_rts),
1279e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->unresponded_rts,
1280e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->unresponded_rts,
1281e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_cck->unresponded_rts);
1282e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1283e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"rxe_frame_lmt_ovrun:",
128492a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->rxe_frame_limit_overrun),
1285e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->rxe_frame_limit_overrun,
1286e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->rxe_frame_limit_overrun,
1287e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_cck->rxe_frame_limit_overrun);
1288e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1289e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "sent_ack_cnt:",
129092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->sent_ack_cnt),
1291e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->sent_ack_cnt,
1292e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->sent_ack_cnt,
1293e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_cck->sent_ack_cnt);
1294e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1295e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "sent_cts_cnt:",
129692a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->sent_cts_cnt),
1297e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->sent_cts_cnt,
1298e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->sent_cts_cnt,
1299e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_cck->sent_cts_cnt);
1300e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1301e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "sent_ba_rsp_cnt:",
130292a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->sent_ba_rsp_cnt),
1303e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->sent_ba_rsp_cnt,
1304e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->sent_ba_rsp_cnt,
1305e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_cck->sent_ba_rsp_cnt);
1306e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1307e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "dsp_self_kill:",
130892a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->dsp_self_kill),
1309e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->dsp_self_kill,
1310e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->dsp_self_kill,
1311e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_cck->dsp_self_kill);
1312e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1313e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "mh_format_err:",
131492a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->mh_format_err),
1315e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->mh_format_err,
1316e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->mh_format_err, max_cck->mh_format_err);
1317e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1318e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "re_acq_main_rssi_sum:",
131992a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(cck->re_acq_main_rssi_sum),
1320e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_cck->re_acq_main_rssi_sum,
1321e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_cck->re_acq_main_rssi_sum,
1322e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_cck->re_acq_main_rssi_sum);
1323e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy
1324e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1325e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"Statistics_Rx - GENERAL:");
1326e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1327e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "bogus_cts:",
132892a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->bogus_cts),
1329e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->bogus_cts,
1330e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->bogus_cts, max_general->bogus_cts);
1331e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1332e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "bogus_ack:",
133392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->bogus_ack),
1334e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->bogus_ack,
1335e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->bogus_ack, max_general->bogus_ack);
1336e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1337e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "non_bssid_frames:",
133892a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->non_bssid_frames),
1339e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->non_bssid_frames,
1340e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->non_bssid_frames,
1341e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->non_bssid_frames);
1342e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1343e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "filtered_frames:",
134492a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->filtered_frames),
1345e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->filtered_frames,
1346e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->filtered_frames,
1347e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->filtered_frames);
1348e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1349e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "non_channel_beacons:",
135092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->non_channel_beacons),
1351e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->non_channel_beacons,
1352e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->non_channel_beacons,
1353e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->non_channel_beacons);
1354e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1355e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "channel_beacons:",
135692a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->channel_beacons),
1357e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->channel_beacons,
1358e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->channel_beacons,
1359e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->channel_beacons);
1360e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1361e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "num_missed_bcon:",
136292a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->num_missed_bcon),
1363e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->num_missed_bcon,
1364e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->num_missed_bcon,
1365e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->num_missed_bcon);
1366e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1367e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"adc_rx_saturation_time:",
136892a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->adc_rx_saturation_time),
1369e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->adc_rx_saturation_time,
1370e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->adc_rx_saturation_time,
1371e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->adc_rx_saturation_time);
1372e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1373e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"ina_detect_search_tm:",
137492a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->ina_detection_search_time),
1375e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->ina_detection_search_time,
1376e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->ina_detection_search_time,
1377e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->ina_detection_search_time);
1378e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1379e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "beacon_silence_rssi_a:",
138092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->beacon_silence_rssi_a),
1381e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->beacon_silence_rssi_a,
1382e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->beacon_silence_rssi_a,
1383e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->beacon_silence_rssi_a);
1384e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1385e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "beacon_silence_rssi_b:",
138692a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->beacon_silence_rssi_b),
1387e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->beacon_silence_rssi_b,
1388e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->beacon_silence_rssi_b,
1389e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->beacon_silence_rssi_b);
1390e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1391e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "beacon_silence_rssi_c:",
139292a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->beacon_silence_rssi_c),
1393e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->beacon_silence_rssi_c,
1394e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->beacon_silence_rssi_c,
1395e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->beacon_silence_rssi_c);
1396e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1397e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"interference_data_flag:",
139892a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->interference_data_flag),
1399e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->interference_data_flag,
1400e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->interference_data_flag,
1401e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->interference_data_flag);
1402e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1403e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "channel_load:",
140492a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->channel_load),
1405e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->channel_load,
1406e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->channel_load,
1407e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->channel_load);
1408e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1409e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "dsp_false_alarms:",
141092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->dsp_false_alarms),
1411e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->dsp_false_alarms,
1412e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->dsp_false_alarms,
1413e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->dsp_false_alarms);
1414e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1415e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "beacon_rssi_a:",
141692a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->beacon_rssi_a),
1417e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->beacon_rssi_a,
1418e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->beacon_rssi_a,
1419e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->beacon_rssi_a);
1420e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1421e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "beacon_rssi_b:",
142292a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->beacon_rssi_b),
1423e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->beacon_rssi_b,
1424e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->beacon_rssi_b,
1425e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->beacon_rssi_b);
1426e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1427e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "beacon_rssi_c:",
142892a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->beacon_rssi_c),
1429e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->beacon_rssi_c,
1430e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->beacon_rssi_c,
1431e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->beacon_rssi_c);
1432e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1433e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "beacon_energy_a:",
143492a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->beacon_energy_a),
1435e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->beacon_energy_a,
1436e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->beacon_energy_a,
1437e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->beacon_energy_a);
1438e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1439e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "beacon_energy_b:",
144092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->beacon_energy_b),
1441e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->beacon_energy_b,
1442e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->beacon_energy_b,
1443e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->beacon_energy_b);
1444e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1445e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "beacon_energy_c:",
144692a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->beacon_energy_c),
1447e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->beacon_energy_c,
1448e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->beacon_energy_c,
1449e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->beacon_energy_c);
1450e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1451e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
1452e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1453e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"Statistics_Rx - OFDM_HT:");
1454e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1455e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "plcp_err:",
1456e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
1457e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ht->plcp_err, max_ht->plcp_err);
1458e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1459e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "overrun_err:",
1460e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
1461e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ht->overrun_err, max_ht->overrun_err);
1462e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1463e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "early_overrun_err:",
146492a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ht->early_overrun_err),
1465e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ht->early_overrun_err,
1466e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ht->early_overrun_err,
1467e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_ht->early_overrun_err);
1468e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1469e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "crc32_good:",
1470e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
1471e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ht->crc32_good, max_ht->crc32_good);
1472e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1473e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "crc32_err:",
1474e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
1475e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ht->crc32_err, max_ht->crc32_err);
1476e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1477e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "mh_format_err:",
147892a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ht->mh_format_err),
1479e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ht->mh_format_err,
1480e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ht->mh_format_err, max_ht->mh_format_err);
1481e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1482e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "agg_crc32_good:",
148392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ht->agg_crc32_good),
1484e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ht->agg_crc32_good,
1485e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
1486e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1487e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "agg_mpdu_cnt:",
148892a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(ht->agg_mpdu_cnt),
1489e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ht->agg_mpdu_cnt,
1490e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
1491e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1492e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "agg_cnt:",
1493e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
1494e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ht->agg_cnt, max_ht->agg_cnt);
1495e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1496e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "unsupport_mcs:",
1497f0118a4575d45ce3074c830660de938bc6e17bdaWey-Yi Guy			 le32_to_cpu(ht->unsupport_mcs),
1498e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_ht->unsupport_mcs,
1499e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
1500e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1501e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1502e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	kfree(buf);
1503e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	return ret;
1504e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy}
1505e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1506e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1507e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					char __user *user_buf,
1508e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					size_t count, loff_t *ppos)
1509e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{
151028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1511e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	int pos = 0;
1512e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	char *buf;
1513e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
1514e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	ssize_t ret;
1515e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
1516e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1517e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	if (!iwl_is_alive(priv))
1518e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		return -EAGAIN;
1519e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1520e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
1521e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	if (!buf) {
1522e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
1523e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		return -ENOMEM;
1524e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	}
1525e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1526e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	/* the statistic information display here is based on
1527e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	 * the last statistics notification from uCode
1528e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	 * might not reflect the current uCode activity
1529e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	 */
1530e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	tx = &priv->statistics.tx;
153192a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy	accum_tx = &priv->accum_statistics.tx;
1532e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	delta_tx = &priv->delta_statistics.tx;
1533e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	max_tx = &priv->max_delta.tx;
1534e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1535e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,  ucode_stats_header,
1536e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"Statistics_Tx:");
1537e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1538e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "preamble:",
153992a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->preamble_cnt),
1540e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->preamble_cnt,
1541e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->preamble_cnt, max_tx->preamble_cnt);
1542e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1543e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "rx_detected_cnt:",
154492a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->rx_detected_cnt),
1545e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->rx_detected_cnt,
1546e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
1547e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1548e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "bt_prio_defer_cnt:",
154992a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->bt_prio_defer_cnt),
1550e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->bt_prio_defer_cnt,
1551e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->bt_prio_defer_cnt,
1552e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->bt_prio_defer_cnt);
1553e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1554e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "bt_prio_kill_cnt:",
155592a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->bt_prio_kill_cnt),
1556e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->bt_prio_kill_cnt,
1557e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->bt_prio_kill_cnt,
1558e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->bt_prio_kill_cnt);
1559e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1560e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "few_bytes_cnt:",
156192a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->few_bytes_cnt),
1562e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->few_bytes_cnt,
1563e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
1564e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1565e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "cts_timeout:",
1566e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
1567e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->cts_timeout, max_tx->cts_timeout);
1568e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1569e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "ack_timeout:",
157092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->ack_timeout),
1571e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->ack_timeout,
1572e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->ack_timeout, max_tx->ack_timeout);
1573e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1574e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "expected_ack_cnt:",
157592a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->expected_ack_cnt),
1576e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->expected_ack_cnt,
1577e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->expected_ack_cnt,
1578e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->expected_ack_cnt);
1579e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1580e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "actual_ack_cnt:",
158192a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->actual_ack_cnt),
1582e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->actual_ack_cnt,
1583e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->actual_ack_cnt,
1584e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->actual_ack_cnt);
1585e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1586e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "dump_msdu_cnt:",
158792a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->dump_msdu_cnt),
1588e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->dump_msdu_cnt,
1589e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->dump_msdu_cnt,
1590e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->dump_msdu_cnt);
1591e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1592e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "abort_nxt_frame_mismatch:",
159392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
1594e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->burst_abort_next_frame_mismatch_cnt,
1595e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->burst_abort_next_frame_mismatch_cnt,
1596e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->burst_abort_next_frame_mismatch_cnt);
1597e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1598e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "abort_missing_nxt_frame:",
159992a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
1600e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->burst_abort_missing_next_frame_cnt,
1601e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->burst_abort_missing_next_frame_cnt,
1602e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->burst_abort_missing_next_frame_cnt);
1603e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1604e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "cts_timeout_collision:",
160592a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->cts_timeout_collision),
1606e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->cts_timeout_collision,
1607e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->cts_timeout_collision,
1608e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->cts_timeout_collision);
1609e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1610e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"ack_ba_timeout_collision:",
161192a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->ack_or_ba_timeout_collision),
1612e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->ack_or_ba_timeout_collision,
1613e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->ack_or_ba_timeout_collision,
1614e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->ack_or_ba_timeout_collision);
1615e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1616e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "agg ba_timeout:",
161792a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->agg.ba_timeout),
1618e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->agg.ba_timeout,
1619e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->agg.ba_timeout,
1620e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->agg.ba_timeout);
1621e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1622e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"agg ba_resched_frames:",
162392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->agg.ba_reschedule_frames),
1624e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->agg.ba_reschedule_frames,
1625e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->agg.ba_reschedule_frames,
1626e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->agg.ba_reschedule_frames);
1627e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1628e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"agg scd_query_agg_frame:",
162992a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
1630e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->agg.scd_query_agg_frame_cnt,
1631e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->agg.scd_query_agg_frame_cnt,
1632e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->agg.scd_query_agg_frame_cnt);
1633e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1634e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "agg scd_query_no_agg:",
163592a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->agg.scd_query_no_agg),
1636e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->agg.scd_query_no_agg,
1637e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->agg.scd_query_no_agg,
1638e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->agg.scd_query_no_agg);
1639e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1640e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "agg scd_query_agg:",
164192a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->agg.scd_query_agg),
1642e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->agg.scd_query_agg,
1643e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->agg.scd_query_agg,
1644e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->agg.scd_query_agg);
1645e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1646e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"agg scd_query_mismatch:",
164792a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->agg.scd_query_mismatch),
1648e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->agg.scd_query_mismatch,
1649e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->agg.scd_query_mismatch,
1650e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->agg.scd_query_mismatch);
1651e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1652e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "agg frame_not_ready:",
165392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->agg.frame_not_ready),
1654e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->agg.frame_not_ready,
1655e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->agg.frame_not_ready,
1656e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->agg.frame_not_ready);
1657e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1658e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "agg underrun:",
165992a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->agg.underrun),
1660e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->agg.underrun,
1661e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->agg.underrun, max_tx->agg.underrun);
1662e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1663e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "agg bt_prio_kill:",
166492a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->agg.bt_prio_kill),
1665e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->agg.bt_prio_kill,
1666e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->agg.bt_prio_kill,
1667e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->agg.bt_prio_kill);
1668e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1669e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "agg rx_ba_rsp_cnt:",
167092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
1671e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_tx->agg.rx_ba_rsp_cnt,
1672e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_tx->agg.rx_ba_rsp_cnt,
1673e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_tx->agg.rx_ba_rsp_cnt);
1674e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1675e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1676e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	kfree(buf);
1677e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	return ret;
1678e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy}
1679e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1680e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1681e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					char __user *user_buf,
1682e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy					size_t count, loff_t *ppos)
1683e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{
168428f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1685e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	int pos = 0;
1686e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	char *buf;
168711fc524941248dc717f1af5dfa844eceb7c0217fWey-Yi Guy	int bufsz = sizeof(struct statistics_general) * 10 + 300;
1688e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	ssize_t ret;
168992a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy	struct statistics_general *general, *accum_general;
1690e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	struct statistics_general *delta_general, *max_general;
1691e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
1692e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	struct statistics_div *div, *accum_div, *delta_div, *max_div;
1693e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1694e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	if (!iwl_is_alive(priv))
1695e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		return -EAGAIN;
1696e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1697e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
1698e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	if (!buf) {
1699e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
1700e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy		return -ENOMEM;
1701e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	}
1702e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
1703e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	/* the statistic information display here is based on
1704e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	 * the last statistics notification from uCode
1705e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	 * might not reflect the current uCode activity
1706e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	 */
1707e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	general = &priv->statistics.general;
1708e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	dbg = &priv->statistics.general.dbg;
1709e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	div = &priv->statistics.general.div;
171092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy	accum_general = &priv->accum_statistics.general;
1711e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	delta_general = &priv->delta_statistics.general;
1712e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	max_general = &priv->max_delta.general;
171392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy	accum_dbg = &priv->accum_statistics.general.dbg;
1714e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	delta_dbg = &priv->delta_statistics.general.dbg;
1715e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	max_dbg = &priv->max_delta.general.dbg;
171692a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy	accum_div = &priv->accum_statistics.general.div;
1717e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	delta_div = &priv->delta_statistics.general.div;
1718e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	max_div = &priv->max_delta.general.div;
1719e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
1720e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header,
1721e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			"Statistics_General:");
1722e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1723e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "temperature:",
1724e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy			 le32_to_cpu(general->temperature));
1725e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format,
1726e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "temperature_m:",
1727e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy			 le32_to_cpu(general->temperature_m));
1728e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1729e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "burst_check:",
173092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(dbg->burst_check),
1731e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_dbg->burst_check,
1732e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_dbg->burst_check, max_dbg->burst_check);
1733e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1734e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "burst_count:",
173592a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(dbg->burst_count),
1736e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_dbg->burst_count,
1737e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_dbg->burst_count, max_dbg->burst_count);
1738e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1739e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "sleep_time:",
174092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->sleep_time),
1741e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->sleep_time,
1742e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->sleep_time, max_general->sleep_time);
1743e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1744e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "slots_out:",
174592a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->slots_out),
1746e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->slots_out,
1747e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->slots_out, max_general->slots_out);
1748e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1749e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "slots_idle:",
175092a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->slots_idle),
1751e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->slots_idle,
1752e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->slots_idle, max_general->slots_idle);
175392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n",
1754e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy			 le32_to_cpu(general->ttl_timestamp));
1755e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1756e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "tx_on_a:",
1757e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
1758e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_div->tx_on_a, max_div->tx_on_a);
1759e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1760e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "tx_on_b:",
1761e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
1762e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_div->tx_on_b, max_div->tx_on_b);
1763e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1764e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "exec_time:",
1765e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(div->exec_time), accum_div->exec_time,
1766e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_div->exec_time, max_div->exec_time);
1767e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1768e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "probe_time:",
1769e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 le32_to_cpu(div->probe_time), accum_div->probe_time,
1770e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_div->probe_time, max_div->probe_time);
1771e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
1772e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 "rx_enable_counter:",
177392a35bda792cf9295b1d399f7c937d4560292b1eWey-Yi Guy			 le32_to_cpu(general->rx_enable_counter),
1774e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 accum_general->rx_enable_counter,
1775e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 delta_general->rx_enable_counter,
1776e3ef2164386a13a37714ec033e30811d052c7999Wey-Yi Guy			 max_general->rx_enable_counter);
177711fc524941248dc717f1af5dfa844eceb7c0217fWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format,
177811fc524941248dc717f1af5dfa844eceb7c0217fWey-Yi Guy			 "num_of_sos_states:",
177911fc524941248dc717f1af5dfa844eceb7c0217fWey-Yi Guy			 le32_to_cpu(general->num_of_sos_states),
178011fc524941248dc717f1af5dfa844eceb7c0217fWey-Yi Guy			 accum_general->num_of_sos_states,
178111fc524941248dc717f1af5dfa844eceb7c0217fWey-Yi Guy			 delta_general->num_of_sos_states,
178211fc524941248dc717f1af5dfa844eceb7c0217fWey-Yi Guy			 max_general->num_of_sos_states);
1783e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1784e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	kfree(buf);
1785e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	return ret;
1786e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy}
1787e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy
17885225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guystatic ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
17895225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					char __user *user_buf,
17905225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					size_t count, loff_t *ppos) {
17915225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
179228f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
17935225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int pos = 0;
17945225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int cnt = 0;
17955225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	char *buf;
17965225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100;
17975225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ssize_t ret;
17985225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	struct iwl_sensitivity_data *data;
17995225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
18005225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	data = &priv->sensitivity_data;
18015225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
18025225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	if (!buf) {
18035225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
18045225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		return -ENOMEM;
18055225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
18065225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
18075225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
18085225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm);
18095225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
18105225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"auto_corr_ofdm_mrc:\t\t %u\n",
18115225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm_mrc);
18125225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
18135225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm_x1);
18145225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
18155225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"auto_corr_ofdm_mrc_x1:\t\t %u\n",
18165225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_ofdm_mrc_x1);
18175225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
18185225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_cck);
18195225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
18205225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->auto_corr_cck_mrc);
18215225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
18225225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"last_bad_plcp_cnt_ofdm:\t\t %u\n",
18235225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_bad_plcp_cnt_ofdm);
18245225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
18255225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_fa_cnt_ofdm);
18265225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
18275225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"last_bad_plcp_cnt_cck:\t\t %u\n",
18285225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_bad_plcp_cnt_cck);
18295225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
18305225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->last_fa_cnt_cck);
18315225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
18325225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_curr_state);
18335225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
18345225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_prev_state);
18355225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
18365225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < 10; cnt++) {
18375225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
18385225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->nrg_value[cnt]);
18395225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
18405225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
18415225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
18425225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
18435225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
18445225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->nrg_silence_rssi[cnt]);
18455225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
18465225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
18475225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
18485225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_silence_ref);
18495225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
18505225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_energy_idx);
18515225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
18525225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_silence_idx);
18535225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
18545225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_th_cck);
18555225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos,
18565225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			"nrg_auto_corr_silence_diff:\t %u\n",
18575225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_auto_corr_silence_diff);
18585225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
18595225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->num_in_cck_no_fa);
18605225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
18615225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->nrg_th_ofdm);
18625225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
18635225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
18645225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	kfree(buf);
18655225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	return ret;
18665225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy}
18675225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
18685225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
18695225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guystatic ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
18705225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					char __user *user_buf,
18715225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy					size_t count, loff_t *ppos) {
18725225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
187328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
18745225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int pos = 0;
18755225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int cnt = 0;
18765225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	char *buf;
18775225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100;
18785225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ssize_t ret;
18795225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	struct iwl_chain_noise_data *data;
18805225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
18815225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	data = &priv->chain_noise_data;
18825225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	buf = kzalloc(bufsz, GFP_KERNEL);
18835225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	if (!buf) {
18845225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		IWL_ERR(priv, "Can not allocate Buffer\n");
18855225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		return -ENOMEM;
18865225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
18875225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
18885225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
18895225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->active_chains);
18905225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
18915225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_noise_a);
18925225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
18935225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_noise_b);
18945225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
18955225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_noise_c);
18965225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
18975225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_signal_a);
18985225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
18995225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_signal_b);
19005225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
19015225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->chain_signal_c);
19025225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
19035225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->beacon_count);
19045225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
19055225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
19065225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
19075225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
19085225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->disconn_array[cnt]);
19095225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
19105225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
19115225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
19125225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
19135225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, " %u",
19145225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy				data->delta_gain_code[cnt]);
19155225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	}
19165225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "\n");
19175225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
19185225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->radio_write);
19195225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
19205225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy			data->state);
19215225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
19225225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
19235225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	kfree(buf);
19245225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy	return ret;
19255225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy}
19265225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy
1927f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guystatic ssize_t iwl_dbgfs_tx_power_read(struct file *file,
1928f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy					char __user *user_buf,
1929f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy					size_t count, loff_t *ppos) {
1930f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy
193128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1932f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy	char buf[128];
1933f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy	int pos = 0;
1934f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy	const size_t bufsz = sizeof(buf);
1935f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy	struct statistics_tx *tx;
1936f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy
1937f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy	if (!iwl_is_alive(priv))
1938f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1939f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy	else {
1940f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy		tx = &priv->statistics.tx;
1941f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy		if (tx->tx_power.ant_a ||
1942f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy		    tx->tx_power.ant_b ||
1943f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy		    tx->tx_power.ant_c) {
1944f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos,
1945f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy				"tx power: (1/2 dB step)\n");
1946f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy			if ((priv->cfg->valid_tx_ant & ANT_A) &&
1947f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy			    tx->tx_power.ant_a)
1948f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy				pos += scnprintf(buf + pos, bufsz - pos,
1949f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy						"\tantenna A: 0x%X\n",
1950f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy						tx->tx_power.ant_a);
1951f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy			if ((priv->cfg->valid_tx_ant & ANT_B) &&
1952f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy			    tx->tx_power.ant_b)
1953f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy				pos += scnprintf(buf + pos, bufsz - pos,
1954f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy						"\tantenna B: 0x%X\n",
1955f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy						tx->tx_power.ant_b);
1956f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy			if ((priv->cfg->valid_tx_ant & ANT_C) &&
1957f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy			    tx->tx_power.ant_c)
1958f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy				pos += scnprintf(buf + pos, bufsz - pos,
1959f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy						"\tantenna C: 0x%X\n",
1960f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy						tx->tx_power.ant_c);
1961f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy		} else
1962f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy			pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
1963f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy	}
1964f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1965f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy}
1966f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi Guy
1967c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guystatic ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
1968c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy						    char __user *user_buf,
1969c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy						    size_t count, loff_t *ppos)
1970c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy{
197128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten	struct iwl_priv *priv = file->private_data;
1972c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	char buf[60];
1973c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	int pos = 0;
1974c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	const size_t bufsz = sizeof(buf);
1975c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	u32 pwrsave_status;
1976c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
1977c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) &
1978c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy			CSR_GP_REG_POWER_SAVE_STATUS_MSK;
1979c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
1980c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
1981c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
1982c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		(pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1983c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		(pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1984c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		(pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1985c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy		"error");
1986c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
1987c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1988c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy}
1989c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy
19907163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guystatic ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
1991ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy					 const char __user *user_buf,
1992ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy					 size_t count, loff_t *ppos)
1993ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy{
1994ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
1995ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	char buf[8];
1996ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	int buf_size;
1997ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	int clear;
1998ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
1999ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	memset(buf, 0, sizeof(buf));
2000ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
2001ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
2002ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy		return -EFAULT;
2003ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	if (sscanf(buf, "%d", &clear) != 1)
2004ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy		return -EFAULT;
2005ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
2006ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	/* make request to uCode to retrieve statistics information */
2007ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	mutex_lock(&priv->mutex);
2008ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	iwl_send_statistics_request(priv, CMD_SYNC, true);
2009ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	mutex_unlock(&priv->mutex);
2010ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
2011ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy	return count;
2012ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy}
2013ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy
2014696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guystatic ssize_t iwl_dbgfs_csr_write(struct file *file,
2015696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy					 const char __user *user_buf,
2016696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy					 size_t count, loff_t *ppos)
2017696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy{
2018696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
2019696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	char buf[8];
2020696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	int buf_size;
2021696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	int csr;
2022696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
2023696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	memset(buf, 0, sizeof(buf));
2024696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
2025696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
2026696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy		return -EFAULT;
2027696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	if (sscanf(buf, "%d", &csr) != 1)
2028696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy		return -EFAULT;
2029696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
2030696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	if (priv->cfg->ops->lib->dump_csr)
2031696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy		priv->cfg->ops->lib->dump_csr(priv);
2032696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
2033696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy	return count;
2034696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy}
2035696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy
2036a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
2037a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					char __user *user_buf,
2038a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					size_t count, loff_t *ppos) {
2039a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
2040a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2041a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	int pos = 0;
2042a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	char buf[128];
2043a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	const size_t bufsz = sizeof(buf);
2044a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
2045a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
2046a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.ucode_trace ? "On" : "Off");
2047a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n",
2048a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.non_wraps_count);
2049a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n",
2050a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.wraps_once_count);
2051a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
2052a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			priv->event_log.wraps_more_count);
2053a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
20544967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2055a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy}
2056a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
2057a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
2058a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					 const char __user *user_buf,
2059a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy					 size_t count, loff_t *ppos)
2060a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy{
2061a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	struct iwl_priv *priv = file->private_data;
2062a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	char buf[8];
2063a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	int buf_size;
2064a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	int trace;
2065a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
2066a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	memset(buf, 0, sizeof(buf));
2067a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
2068a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
2069a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		return -EFAULT;
2070a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	if (sscanf(buf, "%d", &trace) != 1)
2071a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		return -EFAULT;
2072a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
2073a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	if (trace) {
2074a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		priv->event_log.ucode_trace = true;
2075a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		/* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
2076a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		mod_timer(&priv->ucode_trace,
2077a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy			jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
2078a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	} else {
2079a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		priv->event_log.ucode_trace = false;
2080a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy		del_timer_sync(&priv->ucode_trace);
2081a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	}
2082a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
2083a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy	return count;
2084a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy}
2085a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy
208660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Bergstatic ssize_t iwl_dbgfs_rxon_flags_read(struct file *file,
208760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg					 char __user *user_buf,
208860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg					 size_t count, loff_t *ppos) {
208960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
209060987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
209160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	int len = 0;
209260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	char buf[20];
209360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
209460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags));
209560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
209660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg}
209760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
209860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Bergstatic ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file,
209960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg						char __user *user_buf,
210060987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg						size_t count, loff_t *ppos) {
210160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
210260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
210360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	int len = 0;
210460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	char buf[20];
210560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
210660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	len = sprintf(buf, "0x%04X\n",
210760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg		      le32_to_cpu(priv->active_rxon.filter_flags));
210860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
210960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg}
211060987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg
21111b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guystatic ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
21121b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy					 char __user *user_buf,
21131b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy					 size_t count, loff_t *ppos)
21141b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy{
21151b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
21161b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	char *buf;
21171b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	int pos = 0;
21181b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	ssize_t ret = -EFAULT;
21191b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy
21201b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	if (priv->cfg->ops->lib->dump_fh) {
21211b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy		ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true);
21221b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy		if (buf) {
21231b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy			ret = simple_read_from_buffer(user_buf,
21241b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy						      count, ppos, buf, pos);
21251b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy			kfree(buf);
21261b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy		}
21271b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	}
21281b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy
21291b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy	return ret;
21301b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy}
21311b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy
2132a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guystatic ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
2133a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					char __user *user_buf,
2134a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					size_t count, loff_t *ppos) {
2135a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2136a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
2137a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	int pos = 0;
2138a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	char buf[12];
2139a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	const size_t bufsz = sizeof(buf);
2140a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2141a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
2142a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy			priv->missed_beacon_threshold);
2143a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
21444967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2145a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy}
2146a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2147a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guystatic ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
2148a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					 const char __user *user_buf,
2149a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy					 size_t count, loff_t *ppos)
2150a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy{
2151a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
2152a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	char buf[8];
2153a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	int buf_size;
2154a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	int missed;
2155a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2156a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	memset(buf, 0, sizeof(buf));
2157a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
2158a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
2159a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		return -EFAULT;
2160a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	if (sscanf(buf, "%d", &missed) != 1)
2161a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		return -EINVAL;
2162a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2163a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
2164a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	    missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
2165a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		priv->missed_beacon_threshold =
2166a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy			IWL_MISSED_BEACON_THRESHOLD_DEF;
2167a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	else
2168a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy		priv->missed_beacon_threshold = missed;
2169a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2170a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy	return count;
2171a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy}
2172a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy
2173afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guystatic ssize_t iwl_dbgfs_internal_scan_write(struct file *file,
2174afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy					 const char __user *user_buf,
2175afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy					 size_t count, loff_t *ppos)
2176afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy{
2177afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy	struct iwl_priv *priv = file->private_data;
2178afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy	char buf[8];
2179afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy	int buf_size;
2180afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy	int scan;
2181afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy
2182afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy	memset(buf, 0, sizeof(buf));
2183afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
2184afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
2185afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy		return -EFAULT;
2186afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy	if (sscanf(buf, "%d", &scan) != 1)
2187afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy		return -EINVAL;
2188afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy
2189afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy	iwl_internal_short_hw_scan(priv);
2190afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy
2191afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy	return count;
2192afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy}
2193afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi Guy
21943e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyenstatic ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
21953e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					char __user *user_buf,
21963e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					size_t count, loff_t *ppos) {
21973e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
21983e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
21993e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	int pos = 0;
22003e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	char buf[12];
22013e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	const size_t bufsz = sizeof(buf);
22023e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
22033e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
22043e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen			priv->cfg->plcp_delta_threshold);
22053e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
22064967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
22073e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen}
22083e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
22093e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyenstatic ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
22103e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					const char __user *user_buf,
22113e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen					size_t count, loff_t *ppos) {
22123e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
22133e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	struct iwl_priv *priv = file->private_data;
22143e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	char buf[8];
22153e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	int buf_size;
22163e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	int plcp;
22173e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
22183e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	memset(buf, 0, sizeof(buf));
22193e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	buf_size = min(count, sizeof(buf) -  1);
22203e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	if (copy_from_user(buf, user_buf, buf_size))
22213e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen		return -EFAULT;
22223e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	if (sscanf(buf, "%d", &plcp) != 1)
22233e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen		return -EINVAL;
22243e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	if ((plcp <= IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
22253e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen		(plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
22263e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen		priv->cfg->plcp_delta_threshold =
22273e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen			IWL_MAX_PLCP_ERR_THRESHOLD_DEF;
22283e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	else
22293e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen		priv->cfg->plcp_delta_threshold = plcp;
22303e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen	return count;
22313e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen}
22323e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen
2233528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guystatic ssize_t iwl_dbgfs_force_reset_read(struct file *file,
2234528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy					char __user *user_buf,
2235528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy					size_t count, loff_t *ppos) {
2236528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy
2237528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	struct iwl_priv *priv = file->private_data;
2238528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	int i, pos = 0;
2239528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	char buf[300];
2240528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	const size_t bufsz = sizeof(buf);
2241528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	struct iwl_force_reset *force_reset;
2242528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy
2243528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	for (i = 0; i < IWL_MAX_FORCE_RESET; i++) {
2244528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		force_reset = &priv->force_reset[i];
2245528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
2246528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"Force reset method %d\n", i);
2247528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
2248528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\tnumber of reset request: %d\n",
2249528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_request_count);
2250528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
2251528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\tnumber of reset request success: %d\n",
2252528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_success_count);
2253528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
2254528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\tnumber of reset request reject: %d\n",
2255528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_reject_count);
2256528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy		pos += scnprintf(buf + pos, bufsz - pos,
2257528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				"\treset duration: %lu\n",
2258528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy				force_reset->reset_duration);
2259528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	}
2260528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2261528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy}
2262528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy
226304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guystatic ssize_t iwl_dbgfs_force_reset_write(struct file *file,
226404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy					const char __user *user_buf,
226504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy					size_t count, loff_t *ppos) {
226604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy
226704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	struct iwl_priv *priv = file->private_data;
226804cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	char buf[8];
226904cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	int buf_size;
227004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	int reset, ret;
227104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy
227204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	memset(buf, 0, sizeof(buf));
227304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	buf_size = min(count, sizeof(buf) -  1);
227404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	if (copy_from_user(buf, user_buf, buf_size))
227504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		return -EFAULT;
227604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	if (sscanf(buf, "%d", &reset) != 1)
227704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		return -EINVAL;
227804cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	switch (reset) {
227904cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	case IWL_RF_RESET:
228004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	case IWL_FW_RESET:
228104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		ret = iwl_force_reset(priv, reset);
228204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		break;
228304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	default:
228404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy		return -EINVAL;
228504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	}
228604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy	return ret ? ret : count;
228704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy}
228804cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy
22897163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_READ_FILE_OPS(rx_statistics);
22907163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_READ_FILE_OPS(tx_statistics);
229120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
2292141b03e07a54af68fc099459bf780a182b240b45Wey-Yi GuyDEBUGFS_READ_FILE_OPS(rx_queue);
2293141b03e07a54af68fc099459bf780a182b240b45Wey-Yi GuyDEBUGFS_READ_FILE_OPS(tx_queue);
2294e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_rx_stats);
2295e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_tx_stats);
2296e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_general_stats);
22975225935b53ce1eafb222c644230d03ad6011d357Wey-Yi GuyDEBUGFS_READ_FILE_OPS(sensitivity);
22985225935b53ce1eafb222c644230d03ad6011d357Wey-Yi GuyDEBUGFS_READ_FILE_OPS(chain_noise);
2299f204b2487e5503ca4a9f3e69dcd63f6af979aaacWey-Yi GuyDEBUGFS_READ_FILE_OPS(tx_power);
2300c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi GuyDEBUGFS_READ_FILE_OPS(power_save_status);
23017163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
23027163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
2303696bdee3ba216186e21997d20a839b76158346e6Wey-Yi GuyDEBUGFS_WRITE_FILE_OPS(csr);
2304a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
23051b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi GuyDEBUGFS_READ_FILE_OPS(fh_reg);
2306a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
2307afbdd69af0e6a0c40676d4d4b94a0a4414708eaaWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(internal_scan);
23083e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' NguyenDEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
2309528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(force_reset);
231060987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes BergDEBUGFS_READ_FILE_OPS(rxon_flags);
231160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes BergDEBUGFS_READ_FILE_OPS(rxon_filter_flags);
231220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy
2313712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/*
2314712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Create the debugfs files and directories
2315712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
2316712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */
2317712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerint iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2318712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
231995b1a8224abf6230899856753c5506a3f737a65bZhu Yi	struct dentry *phyd = priv->hw->wiphy->debugfsdir;
23204c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
2321712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
23224c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_drv = debugfs_create_dir(name, phyd);
23234c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_drv)
23244c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		return -ENOMEM;
2325712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
23264c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	priv->debugfs_dir = dir_drv;
23274c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg
23284c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_data = debugfs_create_dir("data", dir_drv);
23294c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_data)
23304c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;
23314c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_rf = debugfs_create_dir("rf", dir_drv);
23324c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_rf)
23334c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		goto err;
23344c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	dir_debug = debugfs_create_dir("debug", dir_drv);
23354c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!dir_debug)
2336712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		goto err;
2337712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
23384c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
23394c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
23404c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
23414c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
23424c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
23434c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
23444c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
23454c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
23464c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
23474c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
23484c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
23494c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
23504c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
23514c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
23524c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
23534c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
23544c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
23554c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
23564c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(tx_power, dir_debug, S_IRUSR);
23574c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
23584c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
23594c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
23604c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
23614c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
23624c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
23634c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR);
23644c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
2365528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy	DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
2366e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
23674c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
23684c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
23694c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
23704c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
23714c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
23724c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
2373e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy	}
237460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
237560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg	DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
23764c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal);
23774c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
2378445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler			 &priv->disable_chain_noise_cal);
2379030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy	if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
2380030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy	    ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
23814c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg		DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
2382030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy				&priv->disable_tx_power_cal);
2383712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	return 0;
2384712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
2385712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklererr:
23864c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	IWL_ERR(priv, "Can't create the debugfs directory\n");
2387712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler	iwl_dbgfs_unregister(priv);
23884c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	return -ENOMEM;
2389712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
2390712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerEXPORT_SYMBOL(iwl_dbgfs_register);
2391712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
2392712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/**
2393712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Remove the debugfs files and directories
2394712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *
2395712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */
2396712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklervoid iwl_dbgfs_unregister(struct iwl_priv *priv)
2397712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{
23984c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	if (!priv->debugfs_dir)
2399712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler		return;
2400712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
24014c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	debugfs_remove_recursive(priv->debugfs_dir);
24024c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg	priv->debugfs_dir = NULL;
2403712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}
2404712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerEXPORT_SYMBOL(iwl_dbgfs_unregister);
2405712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
2406712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler
2407445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler
2408