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