iwl-debugfs.c revision 81e95430aaa898799421617c2db2882386bab69a
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" 425225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy#include "iwl-calib.h" 43712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 44712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* create and remove of files */ 454c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ 464c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!debugfs_create_file(#name, mode, parent, priv, \ 474c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg &iwl_dbgfs_##name##_ops)) \ 484c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg goto err; \ 49712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} while (0) 50712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 514c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ 524c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg struct dentry *__tmp; \ 534c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ 544c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg parent, ptr); \ 554c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (IS_ERR(__tmp) || !__tmp) \ 564c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg goto err; \ 57712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} while (0) 58712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 594c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ 604c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg struct dentry *__tmp; \ 614c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \ 624c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg parent, ptr); \ 634c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (IS_ERR(__tmp) || !__tmp) \ 644c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg goto err; \ 65445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler} while (0) 66445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler 67712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* file operation */ 68712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_FUNC(name) \ 69712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_##name##_read(struct file *file, \ 70712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char __user *user_buf, \ 71712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos); 72712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 73712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_WRITE_FUNC(name) \ 74712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_##name##_write(struct file *file, \ 75712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler const char __user *user_buf, \ 76712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos); 77712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 78712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 79712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file) 80712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 81712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler file->private_data = inode->i_private; 82712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return 0; 83712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 84712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 85712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_FILE_OPS(name) \ 86712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_READ_FUNC(name); \ 87712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic const struct file_operations iwl_dbgfs_##name##_ops = { \ 88712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler .read = iwl_dbgfs_##name##_read, \ 89712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler .open = iwl_dbgfs_open_file_generic, \ 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, \ 97189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer}; 98189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer 99189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer 100712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_WRITE_FILE_OPS(name) \ 101712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_READ_FUNC(name); \ 102712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_WRITE_FUNC(name); \ 103712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic const struct file_operations iwl_dbgfs_##name##_ops = { \ 104712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler .write = iwl_dbgfs_##name##_write, \ 105712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler .read = iwl_dbgfs_##name##_read, \ 106712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler .open = iwl_dbgfs_open_file_generic, \ 107712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}; 108712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 109712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, 110712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char __user *user_buf, 111712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos) { 112712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 11328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 11422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy char *buf; 115712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int pos = 0; 116712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 11722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy int cnt; 11822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy ssize_t ret; 11998a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy const size_t bufsz = 100 + 12098a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); 12122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 12222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy if (!buf) 12322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy return -ENOMEM; 12422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); 12522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { 12622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 12798a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy "\t%25s\t\t: %u\n", 12822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy get_mgmt_string(cnt), 12922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy priv->tx_stats.mgmt[cnt]); 13022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy } 13122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Control\n"); 13222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy for (cnt = 0; cnt < CONTROL_MAX; cnt++) { 13322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 13498a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy "\t%25s\t\t: %u\n", 13522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy get_ctrl_string(cnt), 13622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy priv->tx_stats.ctrl[cnt]); 13722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy } 13822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); 13922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", 14022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy priv->tx_stats.data_cnt); 14122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", 14222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy priv->tx_stats.data_bytes); 14322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 14422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy kfree(buf); 14522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy return ret; 14622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy} 14722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy 1487163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guystatic ssize_t iwl_dbgfs_clear_traffic_statistics_write(struct file *file, 14922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy const char __user *user_buf, 15022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy size_t count, loff_t *ppos) 15122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy{ 15222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy struct iwl_priv *priv = file->private_data; 15322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy u32 clear_flag; 15422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy char buf[8]; 15522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy int buf_size; 156712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 15722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy memset(buf, 0, sizeof(buf)); 15822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 15922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 16022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy return -EFAULT; 16122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy if (sscanf(buf, "%x", &clear_flag) != 1) 16222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy return -EFAULT; 1637163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guy iwl_clear_traffic_stats(priv); 16422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy 16522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy return count; 166712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 167712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 168712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, 169712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char __user *user_buf, 170712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos) { 171712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 17228f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 17322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy char *buf; 174712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int pos = 0; 17522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy int cnt; 17622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy ssize_t ret; 17722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy const size_t bufsz = 100 + 17898a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); 17922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 18022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy if (!buf) 18122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy return -ENOMEM; 182712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 18322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); 18422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { 18522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 18698a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy "\t%25s\t\t: %u\n", 18722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy get_mgmt_string(cnt), 18822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy priv->rx_stats.mgmt[cnt]); 18922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy } 19022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Control:\n"); 19122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy for (cnt = 0; cnt < CONTROL_MAX; cnt++) { 19222fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 19398a7b43be19faa7b92576c62614c45e38517331cWey-Yi Guy "\t%25s\t\t: %u\n", 19422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy get_ctrl_string(cnt), 19522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy priv->rx_stats.ctrl[cnt]); 19622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy } 19722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); 19822fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", 19922fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy priv->rx_stats.data_cnt); 20022fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", 20122fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy priv->rx_stats.data_bytes); 202712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 20322fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 20422fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy kfree(buf); 20522fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy return ret; 20622fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy} 20722fdf3c9e19dce6d66bcfdbed547a5aa52b89933Wey-Yi Guy 208712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE1_MASK 0x000000ff; 209712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE2_MASK 0x0000ffff; 210712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE3_MASK 0x00ffffff; 211712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_sram_read(struct file *file, 212712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char __user *user_buf, 213712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos) 214712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 215712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler u32 val; 2162943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy char *buf; 217712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler ssize_t ret; 218712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int i; 219712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int pos = 0; 22028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 2212943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy size_t bufsz; 222712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 2235ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy /* default is to dump the entire data segment */ 2244c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { 2254c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->dbgfs_sram_offset = 0x800000; 2265ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy if (priv->ucode_type == UCODE_INIT) 2274c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->dbgfs_sram_len = priv->ucode_init_data.len; 2285ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy else 2294c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->dbgfs_sram_len = priv->ucode_data.len; 2305ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy } 2314c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg bufsz = 30 + priv->dbgfs_sram_len * sizeof(char) * 10; 2322943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy buf = kmalloc(bufsz, GFP_KERNEL); 2332943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy if (!buf) 2342943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy return -ENOMEM; 2355ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", 2364c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->dbgfs_sram_len); 2375ade1e4dd1df436c3a441d17321c24aac8497306Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", 2384c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->dbgfs_sram_offset); 2394c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg for (i = priv->dbgfs_sram_len; i > 0; i -= 4) { 2404c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg val = iwl_read_targ_mem(priv, priv->dbgfs_sram_offset + \ 2414c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->dbgfs_sram_len - i); 242712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler if (i < 4) { 243712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler switch (i) { 244712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler case 1: 245712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler val &= BYTE1_MASK; 246712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler break; 247712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler case 2: 248712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler val &= BYTE2_MASK; 249712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler break; 250712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler case 3: 251712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler val &= BYTE3_MASK; 252712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler break; 253712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 254712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 2552943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy if (!(i % 16)) 2562943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\n"); 257db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); 258712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 259db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "\n"); 260712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 261712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2622943f136ffe29adb08162197b129bf8106e8191cWey-Yi Guy kfree(buf); 263712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return ret; 264712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 265712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 266712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_sram_write(struct file *file, 267712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler const char __user *user_buf, 268712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos) 269712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 270712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler struct iwl_priv *priv = file->private_data; 271712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char buf[64]; 272712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int buf_size; 273712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler u32 offset, len; 274712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 275712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler memset(buf, 0, sizeof(buf)); 276712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler buf_size = min(count, sizeof(buf) - 1); 277712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler if (copy_from_user(buf, user_buf, buf_size)) 278712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return -EFAULT; 279712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 280712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 2814c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->dbgfs_sram_offset = offset; 2824c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->dbgfs_sram_len = len; 283712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } else { 2844c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->dbgfs_sram_offset = 0; 2854c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->dbgfs_sram_len = 0; 286712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 287712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 288712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return count; 289712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 290712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 291712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 292712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos) 293712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 29428f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 2956def9761f72501e638e79eebcd70afea12a3a93dTomas Winkler struct iwl_station_entry *station; 2965425e490471d521bae2fce16d22995803b41d90fTomas Winkler int max_sta = priv->hw_params.max_stations; 297712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char *buf; 298712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int i, j, pos = 0; 299712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler ssize_t ret; 300712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler /* Add 30 for initial string */ 301712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations); 302712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 303712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler buf = kmalloc(bufsz, GFP_KERNEL); 3043ac7f14694dd38273d9d96f1c873233d71190c15Tomas Winkler if (!buf) 305712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return -ENOMEM; 306712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 307db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", 308712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler priv->num_stations); 309712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 310712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler for (i = 0; i < max_sta; i++) { 311712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler station = &priv->stations[i]; 312da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg if (!station->used) 313da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg continue; 314da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg pos += scnprintf(buf + pos, bufsz - pos, 315da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg "station %d - addr: %pM, flags: %#x\n", 316da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg i, station->sta.sta.addr, 317da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg station->sta.station_flags_msk); 318da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg pos += scnprintf(buf + pos, bufsz - pos, 319da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg "TID\tseq_num\ttxq_id\tframes\ttfds\t"); 320da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg pos += scnprintf(buf + pos, bufsz - pos, 321da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg "start_idx\tbitmap\t\t\trate_n_flags\n"); 322712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 323da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg for (j = 0; j < MAX_TID_COUNT; j++) { 324da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg pos += scnprintf(buf + pos, bufsz - pos, 325da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x", 326da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg j, station->tid[j].seq_number, 327da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg station->tid[j].agg.txq_id, 328da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg station->tid[j].agg.frame_count, 329da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg station->tid[j].tfds_in_queue, 330da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg station->tid[j].agg.start_idx, 331da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg station->tid[j].agg.bitmap, 332da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg station->tid[j].agg.rate_n_flags); 333da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg 334da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg if (station->tid[j].agg.wait_for_ba) 335db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, 336da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg " - waitforba"); 337db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "\n"); 338712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 339da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg 340da73511d4316c4e3efe903e123286c5b55a1999fJohannes Berg pos += scnprintf(buf + pos, bufsz - pos, "\n"); 341712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 342712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 343712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 344712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler kfree(buf); 345712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return ret; 346712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 347712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 3480848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guystatic ssize_t iwl_dbgfs_nvm_read(struct file *file, 3498dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler char __user *user_buf, 3508dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler size_t count, 3518dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler loff_t *ppos) 3528dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler{ 3538dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler ssize_t ret; 35428f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 3558dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler int pos = 0, ofs = 0, buf_size = 0; 3568dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler const u8 *ptr; 3578dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler char *buf; 358e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy u16 eeprom_ver; 3598dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler size_t eeprom_len = priv->cfg->eeprom_size; 3608dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler buf_size = 4 * eeprom_len + 256; 3618dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler 3628dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler if (eeprom_len % 16) { 3630848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy IWL_ERR(priv, "NVM size is not multiple of 16.\n"); 3648dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler return -ENODATA; 3658dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler } 3668dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler 367c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall ptr = priv->eeprom; 368c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall if (!ptr) { 369c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall IWL_ERR(priv, "Invalid EEPROM/OTP memory\n"); 370c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall return -ENOMEM; 371c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall } 372c37457e69ffd7d3c94cbfcc1c39be9a45dd7ad21Julia Lawall 3738dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler /* 4 characters for byte 0xYY */ 3748dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler buf = kzalloc(buf_size, GFP_KERNEL); 3758dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler if (!buf) { 37615b1687cb4f45b87ddbe4dfc7759ff5bb69497d2Winkler, Tomas IWL_ERR(priv, "Can not allocate Buffer\n"); 3778dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler return -ENOMEM; 3788dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler } 379e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); 380e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " 381e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy "version: 0x%x\n", 3820848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) 383e307ddce394ee7bcec41fb74330ac89eafaea1d9Wey-Yi Guy ? "OTP" : "EEPROM", eeprom_ver); 3848dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { 3858dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); 3868dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, 3878dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler buf_size - pos, 0); 3882fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre pos += strlen(buf + pos); 3898dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler if (buf_size - pos > 0) 3908dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler buf[pos++] = '\n'; 3918dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler } 3928dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler 3938dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 3948dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler kfree(buf); 3958dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler return ret; 3968dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler} 397712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 398b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guystatic ssize_t iwl_dbgfs_log_event_read(struct file *file, 399b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy char __user *user_buf, 400b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy size_t count, loff_t *ppos) 401b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy{ 402b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy struct iwl_priv *priv = file->private_data; 403b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy char *buf; 404b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy int pos = 0; 405b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy ssize_t ret = -ENOMEM; 406b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy 407937c397eb633b804d9a806d08c395ecfc42b1fecWey-Yi Guy ret = pos = priv->cfg->ops->lib->dump_nic_event_log( 408937c397eb633b804d9a806d08c395ecfc42b1fecWey-Yi Guy priv, true, &buf, true); 409937c397eb633b804d9a806d08c395ecfc42b1fecWey-Yi Guy if (buf) { 410b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 411b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy kfree(buf); 412b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy } 413b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy return ret; 414b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy} 415b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy 416189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummerstatic ssize_t iwl_dbgfs_log_event_write(struct file *file, 417189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer const char __user *user_buf, 418189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer size_t count, loff_t *ppos) 419189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer{ 420189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer struct iwl_priv *priv = file->private_data; 421189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer u32 event_log_flag; 422189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer char buf[8]; 423189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer int buf_size; 424189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer 425189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer memset(buf, 0, sizeof(buf)); 426189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer buf_size = min(count, sizeof(buf) - 1); 427189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer if (copy_from_user(buf, user_buf, buf_size)) 428189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer return -EFAULT; 429189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer if (sscanf(buf, "%d", &event_log_flag) != 1) 430189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer return -EFAULT; 431189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer if (event_log_flag == 1) 432b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy priv->cfg->ops->lib->dump_nic_event_log(priv, true, 433b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi Guy NULL, false); 434189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer 435189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer return count; 436189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer} 437189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer 438d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 439d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 440d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomasstatic ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, 441d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas size_t count, loff_t *ppos) 442d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas{ 44328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 444d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas struct ieee80211_channel *channels = NULL; 445d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas const struct ieee80211_supported_band *supp_band = NULL; 446d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas int pos = 0, i, bufsz = PAGE_SIZE; 447d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas char *buf; 448d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas ssize_t ret; 449d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 450d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) 451d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas return -EAGAIN; 452d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 453d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas buf = kzalloc(bufsz, GFP_KERNEL); 454d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas if (!buf) { 45515b1687cb4f45b87ddbe4dfc7759ff5bb69497d2Winkler, Tomas IWL_ERR(priv, "Can not allocate Buffer\n"); 456d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas return -ENOMEM; 457d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas } 458d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 459d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); 460a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy if (supp_band) { 461a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels = supp_band->channels; 462d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 463d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas pos += scnprintf(buf + pos, bufsz - pos, 464a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "Displaying %d channels in 2.4GHz band 802.11bg):\n", 465a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy supp_band->n_channels); 466d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 467a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy for (i = 0; i < supp_band->n_channels; i++) 468a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 469a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "%d: %ddBm: BSS%s%s, %s.\n", 47081e95430aaa898799421617c2db2882386bab69aShanyu Zhao channels[i].hw_value, 471a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].max_power, 472a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & IEEE80211_CHAN_RADAR ? 473a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy " (IEEE 802.11h required)" : "", 474a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 475a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy || (channels[i].flags & 476a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_RADAR)) ? "" : 477a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ", IBSS", 478a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & 479a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_PASSIVE_SCAN ? 480a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "passive only" : "active/passive"); 481a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy } 482d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); 483a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy if (supp_band) { 484a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels = supp_band->channels; 485d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 486d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas pos += scnprintf(buf + pos, bufsz - pos, 487a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "Displaying %d channels in 5.2GHz band (802.11a)\n", 488a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy supp_band->n_channels); 489a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy 490a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy for (i = 0; i < supp_band->n_channels; i++) 491a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 492a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "%d: %ddBm: BSS%s%s, %s.\n", 49381e95430aaa898799421617c2db2882386bab69aShanyu Zhao channels[i].hw_value, 494a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].max_power, 495a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & IEEE80211_CHAN_RADAR ? 496a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy " (IEEE 802.11h required)" : "", 497a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 498a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy || (channels[i].flags & 499a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_RADAR)) ? "" : 500a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ", IBSS", 501a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & 502a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_PASSIVE_SCAN ? 503a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "passive only" : "active/passive"); 504a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy } 505d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 506d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas kfree(buf); 507d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas return ret; 508d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas} 509d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 51008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guystatic ssize_t iwl_dbgfs_status_read(struct file *file, 51108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy char __user *user_buf, 51208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy size_t count, loff_t *ppos) { 51308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy 51428f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 51508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy char buf[512]; 51608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy int pos = 0; 51708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy const size_t bufsz = sizeof(buf); 51808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy 51908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", 52008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_HCMD_ACTIVE, &priv->status)); 52108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", 52208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_INT_ENABLED, &priv->status)); 52308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", 52408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_RF_KILL_HW, &priv->status)); 5257812b16730ccebce71a3b2228ac08dd4f8b39469Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", 5267812b16730ccebce71a3b2228ac08dd4f8b39469Wey-Yi Guy test_bit(STATUS_CT_KILL, &priv->status)); 52708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", 52808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_INIT, &priv->status)); 52908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", 53008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_ALIVE, &priv->status)); 53108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", 53208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_READY, &priv->status)); 53308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n", 53408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_TEMPERATURE, &priv->status)); 53508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", 53608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_GEO_CONFIGURED, &priv->status)); 53708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", 53808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_EXIT_PENDING, &priv->status)); 53908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", 54008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_STATISTICS, &priv->status)); 54108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", 54208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_SCANNING, &priv->status)); 54308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", 54408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_SCAN_ABORTING, &priv->status)); 54508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", 54608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_SCAN_HW, &priv->status)); 54708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", 54808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_POWER_PMI, &priv->status)); 54908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", 55008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_FW_ERROR, &priv->status)); 55108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 55208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy} 55308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy 554a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_read(struct file *file, 555a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy char __user *user_buf, 556a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy size_t count, loff_t *ppos) { 557a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 55828f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 559a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int pos = 0; 560a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int cnt = 0; 561a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy char *buf; 562a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int bufsz = 24 * 64; /* 24 items * 64 char per item */ 563a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy ssize_t ret; 564a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 565a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 566a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (!buf) { 567a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy IWL_ERR(priv, "Can not allocate Buffer\n"); 568a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return -ENOMEM; 569a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy } 570a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 571a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 572a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "Interrupt Statistics Report:\n"); 573a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 574a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n", 575a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.hw); 576a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", 577a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.sw); 578a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (priv->isr_stats.sw > 0) { 579a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 580a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "\tLast Restarting Code: 0x%X\n", 581a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.sw_err); 582a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy } 583a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#ifdef CONFIG_IWLWIFI_DEBUG 584a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", 585a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.sch); 586a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n", 587a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.alive); 588a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#endif 589a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 590a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "HW RF KILL switch toggled:\t %u\n", 591a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.rfkill); 592a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 593a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n", 594a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.ctkill); 595a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 596a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n", 597a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.wakeup); 598a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 599a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 600a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "Rx command responses:\t\t %u\n", 601a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.rx); 602a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy for (cnt = 0; cnt < REPLY_MAX; cnt++) { 603a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (priv->isr_stats.rx_handlers[cnt] > 0) 604a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 605a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "\tRx handler[%36s]:\t\t %u\n", 606a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy get_cmd_string(cnt), 607a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.rx_handlers[cnt]); 608a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy } 609a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 610a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n", 611a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.tx); 612a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 613a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n", 614a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.unhandled); 615a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 616a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 617a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy kfree(buf); 618a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return ret; 619a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy} 620a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 621a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_write(struct file *file, 622a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy const char __user *user_buf, 623a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy size_t count, loff_t *ppos) 624a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy{ 625a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy struct iwl_priv *priv = file->private_data; 626a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy char buf[8]; 627a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int buf_size; 628a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy u32 reset_flag; 629a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 630a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy memset(buf, 0, sizeof(buf)); 631a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 632a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 633a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return -EFAULT; 634a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (sscanf(buf, "%x", &reset_flag) != 1) 635a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return -EFAULT; 636a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (reset_flag == 0) 637a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy iwl_clear_isr_stats(priv); 638a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 639a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return count; 640a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy} 641a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 642f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guystatic ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, 643f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy size_t count, loff_t *ppos) 644f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy{ 64528f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 646f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy int pos = 0, i; 647f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy char buf[256]; 648f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy const size_t bufsz = sizeof(buf); 649f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy 650f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy for (i = 0; i < AC_NUM; i++) { 651f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 652f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy "\tcw_min\tcw_max\taifsn\ttxop\n"); 653f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 654f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy "AC[%d]\t%u\t%u\t%u\t%u\n", i, 655f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].cw_min, 656f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].cw_max, 657f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].aifsn, 658f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].edca_txop); 659f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy } 6604967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 661f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy} 662a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 663a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guystatic ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, 664a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy size_t count, loff_t *ppos) 665a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy{ 66628f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 667a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy int pos = 0; 668a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy char buf[256]; 669a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy const size_t bufsz = sizeof(buf); 670a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy 671a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 672a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy "allow blinking: %s\n", 673a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy (priv->allow_blinking) ? "True" : "False"); 674a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy if (priv->allow_blinking) { 675a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 676a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy "Led blinking rate: %u\n", 677a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy priv->last_blink_rate); 678a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 679a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy "Last blink time: %lu\n", 680a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy priv->last_blink_time); 681a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy } 682a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy 6834967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 684a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy} 685a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy 686fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guystatic ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, 687fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy char __user *user_buf, 688fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy size_t count, loff_t *ppos) 689fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy{ 69028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 6913ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 692fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy struct iwl_tt_restriction *restriction; 693fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy char buf[100]; 694fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy int pos = 0; 695fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy const size_t bufsz = sizeof(buf); 696fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy 697fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 698fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Thermal Throttling Mode: %s\n", 6993ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg tt->advanced_tt ? "Advance" : "Legacy"); 700fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 701fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Thermal Throttling State: %d\n", 702fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy tt->state); 7033ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg if (tt->advanced_tt) { 704fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction = tt->restriction + tt->state; 705fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 706fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Tx mode: %d\n", 707fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction->tx_stream); 708fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 709fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Rx mode: %d\n", 710fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction->rx_stream); 711fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 712fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "HT mode: %d\n", 713fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction->is_ht); 714fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy } 7154967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 716fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy} 717fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy 7181e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guystatic ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, 7191e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy const char __user *user_buf, 7201e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy size_t count, loff_t *ppos) 7211e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy{ 7221e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy struct iwl_priv *priv = file->private_data; 7231e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy char buf[8]; 7241e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy int buf_size; 7251e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy int ht40; 7261e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy 7271e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy memset(buf, 0, sizeof(buf)); 7281e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 7291e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 7301e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy return -EFAULT; 7311e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy if (sscanf(buf, "%d", &ht40) != 1) 7321e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy return -EFAULT; 7331e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy if (!iwl_is_associated(priv)) 7341e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy priv->disable_ht40 = ht40 ? true : false; 7351e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy else { 7361e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy IWL_ERR(priv, "Sta associated with AP - " 7371e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy "Change to 40MHz channel support is not allowed\n"); 7381e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy return -EINVAL; 7391e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy } 7401e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy 7411e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy return count; 7421e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy} 7431e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy 7441e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guystatic ssize_t iwl_dbgfs_disable_ht40_read(struct file *file, 7451e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy char __user *user_buf, 7461e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy size_t count, loff_t *ppos) 7471e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy{ 74828f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 7491e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy char buf[100]; 7501e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy int pos = 0; 7511e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy const size_t bufsz = sizeof(buf); 7521e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy 7531e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 7541e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy "11n 40MHz Mode: %s\n", 7551e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy priv->disable_ht40 ? "Disabled" : "Enabled"); 7564967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 7571e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy} 7581e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy 759e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, 760e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg const char __user *user_buf, 761e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg size_t count, loff_t *ppos) 762e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{ 763e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg struct iwl_priv *priv = file->private_data; 764e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg char buf[8]; 765e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg int buf_size; 766e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg int value; 767e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 768e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg memset(buf, 0, sizeof(buf)); 769e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg buf_size = min(count, sizeof(buf) - 1); 770e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg if (copy_from_user(buf, user_buf, buf_size)) 771e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return -EFAULT; 772e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 773e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg if (sscanf(buf, "%d", &value) != 1) 774e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return -EINVAL; 775e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 776e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg /* 777e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg * Our users expect 0 to be "CAM", but 0 isn't actually 778e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg * valid here. However, let's not confuse them and present 779e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg * IWL_POWER_INDEX_1 as "1", not "0". 780e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg */ 7811a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre if (value == 0) 7821a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre return -EINVAL; 7831a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre else if (value > 0) 784e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg value -= 1; 785e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 786e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) 787e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return -EINVAL; 788e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 7894ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy if (!iwl_is_ready_rf(priv)) 7904ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy return -EAGAIN; 7914ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy 792e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg priv->power_data.debug_sleep_level_override = value; 793e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 794d3a571971e5af241074947fc80f6284677f6e014Reinette Chatre mutex_lock(&priv->mutex); 7954ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy iwl_power_update_mode(priv, true); 796d3a571971e5af241074947fc80f6284677f6e014Reinette Chatre mutex_unlock(&priv->mutex); 797e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 798e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return count; 799e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg} 800e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 801e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file, 802e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg char __user *user_buf, 803e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg size_t count, loff_t *ppos) 804e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{ 80528f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 806e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg char buf[10]; 807e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg int pos, value; 808e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg const size_t bufsz = sizeof(buf); 809e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 810e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg /* see the write function */ 811e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg value = priv->power_data.debug_sleep_level_override; 812e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg if (value >= 0) 813e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg value += 1; 814e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 815e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg pos = scnprintf(buf, bufsz, "%d\n", value); 816e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 817e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg} 818e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 819e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file, 820e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg char __user *user_buf, 821e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg size_t count, loff_t *ppos) 822e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{ 82328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 824e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg char buf[200]; 825e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg int pos = 0, i; 826e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg const size_t bufsz = sizeof(buf); 827e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd; 828e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 829e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg pos += scnprintf(buf + pos, bufsz - pos, 830e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg "flags: %#.2x\n", le16_to_cpu(cmd->flags)); 831e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg pos += scnprintf(buf + pos, bufsz - pos, 832e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg "RX/TX timeout: %d/%d usec\n", 833e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg le32_to_cpu(cmd->rx_data_timeout), 834e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg le32_to_cpu(cmd->tx_data_timeout)); 835e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg for (i = 0; i < IWL_POWER_VEC_SIZE; i++) 836e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg pos += scnprintf(buf + pos, bufsz - pos, 837e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg "sleep_interval[%d]: %d\n", i, 838e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg le32_to_cpu(cmd->sleep_interval[i])); 839e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 840e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 841e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg} 842e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 843712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_WRITE_FILE_OPS(sram); 844b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(log_event); 8450848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi GuyDEBUGFS_READ_FILE_OPS(nvm); 846712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_FILE_OPS(stations); 847d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, TomasDEBUGFS_READ_FILE_OPS(channels); 84808df05aa9b25f3079585855506022bb33a011183Wey-Yi GuyDEBUGFS_READ_FILE_OPS(status); 849a83b9141b540f96dd59409c6487828e880113a29Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(interrupt); 850f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi GuyDEBUGFS_READ_FILE_OPS(qos); 851a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi GuyDEBUGFS_READ_FILE_OPS(led); 852fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi GuyDEBUGFS_READ_FILE_OPS(thermal_throttling); 8531e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); 854e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes BergDEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); 855e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes BergDEBUGFS_READ_FILE_OPS(current_sleep_command); 856712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 85720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guystatic ssize_t iwl_dbgfs_traffic_log_read(struct file *file, 85820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy char __user *user_buf, 85920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy size_t count, loff_t *ppos) 86020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy{ 86120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy struct iwl_priv *priv = file->private_data; 86220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy int pos = 0, ofs = 0; 86320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy int cnt = 0, entry; 86420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy struct iwl_tx_queue *txq; 86520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy struct iwl_queue *q; 86620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy struct iwl_rx_queue *rxq = &priv->rxq; 86720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy char *buf; 86820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + 86988804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy (priv->cfg->num_of_queues * 32 * 8) + 400; 87020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy const u8 *ptr; 87120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy ssize_t ret; 87220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 87388804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy if (!priv->txq) { 87488804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy IWL_ERR(priv, "txq not ready\n"); 87588804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy return -EAGAIN; 87688804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy } 87720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 87820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (!buf) { 87920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy IWL_ERR(priv, "Can not allocate buffer\n"); 88020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy return -ENOMEM; 88120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 88220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n"); 88320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { 88420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy txq = &priv->txq[cnt]; 88520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy q = &txq->q; 88620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 88720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "q[%d]: read_ptr: %u, write_ptr: %u\n", 88820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy cnt, q->read_ptr, q->write_ptr); 88920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 89020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) { 89120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy ptr = priv->tx_traffic; 89220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 89320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "Tx Traffic idx: %u\n", priv->tx_traffic_idx); 89420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { 89520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; 89620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy entry++, ofs += 16) { 89720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 89820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "0x%.4x ", ofs); 89920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy hex_dump_to_buffer(ptr + ofs, 16, 16, 2, 90020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf + pos, bufsz - pos, 0); 9012fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre pos += strlen(buf + pos); 90220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (bufsz - pos > 0) 90320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf[pos++] = '\n'; 90420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 90520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 90620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 90720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 90820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n"); 90920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 91020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "read: %u, write: %u\n", 91120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy rxq->read, rxq->write); 91220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 91320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) { 91420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy ptr = priv->rx_traffic; 91520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 91620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "Rx Traffic idx: %u\n", priv->rx_traffic_idx); 91720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { 91820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; 91920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy entry++, ofs += 16) { 92020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 92120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "0x%.4x ", ofs); 92220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy hex_dump_to_buffer(ptr + ofs, 16, 16, 2, 92320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf + pos, bufsz - pos, 0); 9242fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre pos += strlen(buf + pos); 92520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (bufsz - pos > 0) 92620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf[pos++] = '\n'; 92720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 92820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 92920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 93020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 93120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 93220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy kfree(buf); 93320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy return ret; 93420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy} 93520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 93620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guystatic ssize_t iwl_dbgfs_traffic_log_write(struct file *file, 93720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy const char __user *user_buf, 93820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy size_t count, loff_t *ppos) 93920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy{ 94020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy struct iwl_priv *priv = file->private_data; 94120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy char buf[8]; 94220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy int buf_size; 94320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy int traffic_log; 94420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 94520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy memset(buf, 0, sizeof(buf)); 94620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 94720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 94820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy return -EFAULT; 94920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (sscanf(buf, "%d", &traffic_log) != 1) 95020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy return -EFAULT; 95120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (traffic_log == 0) 95220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy iwl_reset_traffic_log(priv); 95320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 95420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy return count; 95520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy} 95620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 957141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guystatic ssize_t iwl_dbgfs_tx_queue_read(struct file *file, 958141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy char __user *user_buf, 959141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy size_t count, loff_t *ppos) { 960141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 96128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 962141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy struct iwl_tx_queue *txq; 963141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy struct iwl_queue *q; 964141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy char *buf; 965141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy int pos = 0; 966141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy int cnt; 967141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy int ret; 968d23db556819c00d297c0f447bdd75b282d563122Wey-Yi Guy const size_t bufsz = sizeof(char) * 64 * priv->cfg->num_of_queues; 969141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 97088804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy if (!priv->txq) { 97188804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy IWL_ERR(priv, "txq not ready\n"); 97288804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy return -EAGAIN; 97388804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy } 974141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 975141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy if (!buf) 976141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy return -ENOMEM; 977141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 978141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { 979141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy txq = &priv->txq[cnt]; 980141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy q = &txq->q; 981141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 982141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy "hwq %.2d: read=%u write=%u stop=%d" 983141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy " swq_id=%#.2x (ac %d/hwq %d)\n", 984141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy cnt, q->read_ptr, q->write_ptr, 985141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy !!test_bit(cnt, priv->queue_stopped), 986141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy txq->swq_id, 987141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy txq->swq_id & 0x80 ? txq->swq_id & 3 : 988141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy txq->swq_id, 989141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy txq->swq_id & 0x80 ? (txq->swq_id >> 2) & 990141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 0x1f : txq->swq_id); 991141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy if (cnt >= 4) 992141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy continue; 993141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy /* for the ACs, display the stop count too */ 994141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 995141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy " stop-count: %d\n", 996141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy atomic_read(&priv->queue_stop_count[cnt])); 997141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy } 998141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 999141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy kfree(buf); 1000141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy return ret; 1001141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy} 1002141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 1003141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guystatic ssize_t iwl_dbgfs_rx_queue_read(struct file *file, 1004141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy char __user *user_buf, 1005141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy size_t count, loff_t *ppos) { 1006141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 100728f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 1008141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy struct iwl_rx_queue *rxq = &priv->rxq; 1009141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy char buf[256]; 1010141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy int pos = 0; 1011141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy const size_t bufsz = sizeof(buf); 1012141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 1013141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n", 1014141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy rxq->read); 1015141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", 1016141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy rxq->write); 1017141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n", 1018141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy rxq->free_count); 1019f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish if (rxq->rb_stts) { 1020f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n", 1021141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF); 1022f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish } else { 1023f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish pos += scnprintf(buf + pos, bufsz - pos, 1024f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish "closed_rb_num: Not Allocated\n"); 1025f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish } 1026141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1027141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy} 1028141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 1029e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, 1030e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy char __user *user_buf, 1031e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy size_t count, loff_t *ppos) 1032e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{ 103328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 103417f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file, 103517f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar user_buf, count, ppos); 1036e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy} 1037e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy 1038e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tx_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.tx_stats_read(file, 104417f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar user_buf, count, ppos); 1045e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy} 1046e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy 1047e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_general_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.general_stats_read(file, 105317f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar user_buf, count, ppos); 1054e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy} 1055e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy 10565225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guystatic ssize_t iwl_dbgfs_sensitivity_read(struct file *file, 10575225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy char __user *user_buf, 10585225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy size_t count, loff_t *ppos) { 10595225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 106028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 10615225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int pos = 0; 10625225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int cnt = 0; 10635225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy char *buf; 10645225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100; 10655225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy ssize_t ret; 10665225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy struct iwl_sensitivity_data *data; 10675225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 10685225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data = &priv->sensitivity_data; 10695225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 10705225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy if (!buf) { 10715225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy IWL_ERR(priv, "Can not allocate Buffer\n"); 10725225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy return -ENOMEM; 10735225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 10745225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 10755225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n", 10765225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_ofdm); 10775225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 10785225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy "auto_corr_ofdm_mrc:\t\t %u\n", 10795225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_ofdm_mrc); 10805225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n", 10815225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_ofdm_x1); 10825225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 10835225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy "auto_corr_ofdm_mrc_x1:\t\t %u\n", 10845225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_ofdm_mrc_x1); 10855225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n", 10865225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_cck); 10875225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n", 10885225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_cck_mrc); 10895225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 10905225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy "last_bad_plcp_cnt_ofdm:\t\t %u\n", 10915225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->last_bad_plcp_cnt_ofdm); 10925225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n", 10935225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->last_fa_cnt_ofdm); 10945225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 10955225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy "last_bad_plcp_cnt_cck:\t\t %u\n", 10965225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->last_bad_plcp_cnt_cck); 10975225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n", 10985225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->last_fa_cnt_cck); 10995225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n", 11005225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_curr_state); 11015225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n", 11025225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_prev_state); 11035225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t"); 11045225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy for (cnt = 0; cnt < 10; cnt++) { 11055225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, " %u", 11065225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_value[cnt]); 11075225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 11085225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\n"); 11095225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t"); 11105225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) { 11115225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, " %u", 11125225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_silence_rssi[cnt]); 11135225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 11145225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\n"); 11155225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n", 11165225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_silence_ref); 11175225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n", 11185225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_energy_idx); 11195225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n", 11205225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_silence_idx); 11215225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n", 11225225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_th_cck); 11235225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 11245225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy "nrg_auto_corr_silence_diff:\t %u\n", 11255225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_auto_corr_silence_diff); 11265225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n", 11275225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->num_in_cck_no_fa); 11285225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n", 11295225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_th_ofdm); 11305225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11315225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 11325225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy kfree(buf); 11335225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy return ret; 11345225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy} 11355225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11365225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11375225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guystatic ssize_t iwl_dbgfs_chain_noise_read(struct file *file, 11385225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy char __user *user_buf, 11395225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy size_t count, loff_t *ppos) { 11405225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 114128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 11425225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int pos = 0; 11435225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int cnt = 0; 11445225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy char *buf; 11455225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100; 11465225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy ssize_t ret; 11475225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy struct iwl_chain_noise_data *data; 11485225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11495225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data = &priv->chain_noise_data; 11505225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 11515225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy if (!buf) { 11525225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy IWL_ERR(priv, "Can not allocate Buffer\n"); 11535225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy return -ENOMEM; 11545225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 11555225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11565225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n", 11575225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->active_chains); 11585225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n", 11595225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_noise_a); 11605225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n", 11615225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_noise_b); 11625225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n", 11635225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_noise_c); 11645225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n", 11655225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_signal_a); 11665225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n", 11675225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_signal_b); 11685225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n", 11695225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_signal_c); 11705225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n", 11715225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->beacon_count); 11725225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11735225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t"); 11745225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 11755225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, " %u", 11765225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->disconn_array[cnt]); 11775225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 11785225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\n"); 11795225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t"); 11805225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 11815225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, " %u", 11825225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->delta_gain_code[cnt]); 11835225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 11845225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\n"); 11855225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n", 11865225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->radio_write); 11875225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n", 11885225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->state); 11895225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11905225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 11915225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy kfree(buf); 11925225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy return ret; 11935225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy} 11945225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 1195c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guystatic ssize_t iwl_dbgfs_power_save_status_read(struct file *file, 1196c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy char __user *user_buf, 1197c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy size_t count, loff_t *ppos) 1198c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy{ 119928f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 1200c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy char buf[60]; 1201c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy int pos = 0; 1202c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy const size_t bufsz = sizeof(buf); 1203c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy u32 pwrsave_status; 1204c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy 1205c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) & 1206c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy CSR_GP_REG_POWER_SAVE_STATUS_MSK; 1207c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy 1208c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); 1209c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "%s\n", 1210c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" : 1211c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" : 1212c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" : 1213c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy "error"); 1214c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy 1215c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1216c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy} 1217c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy 12187163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guystatic ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file, 1219ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy const char __user *user_buf, 1220ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy size_t count, loff_t *ppos) 1221ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy{ 1222ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy struct iwl_priv *priv = file->private_data; 1223ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy char buf[8]; 1224ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy int buf_size; 1225ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy int clear; 1226ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy 1227ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy memset(buf, 0, sizeof(buf)); 1228ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 1229ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 1230ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy return -EFAULT; 1231ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy if (sscanf(buf, "%d", &clear) != 1) 1232ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy return -EFAULT; 1233ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy 1234ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy /* make request to uCode to retrieve statistics information */ 1235ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy mutex_lock(&priv->mutex); 1236ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy iwl_send_statistics_request(priv, CMD_SYNC, true); 1237ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy mutex_unlock(&priv->mutex); 1238ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy 1239ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy return count; 1240ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy} 1241ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy 1242696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guystatic ssize_t iwl_dbgfs_csr_write(struct file *file, 1243696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy const char __user *user_buf, 1244696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy size_t count, loff_t *ppos) 1245696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy{ 1246696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy struct iwl_priv *priv = file->private_data; 1247696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy char buf[8]; 1248696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy int buf_size; 1249696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy int csr; 1250696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy 1251696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy memset(buf, 0, sizeof(buf)); 1252696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 1253696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 1254696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy return -EFAULT; 1255696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy if (sscanf(buf, "%d", &csr) != 1) 1256696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy return -EFAULT; 1257696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy 1258696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy if (priv->cfg->ops->lib->dump_csr) 1259696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy priv->cfg->ops->lib->dump_csr(priv); 1260696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy 1261696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy return count; 1262696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy} 1263696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy 1264a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file, 1265a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy char __user *user_buf, 1266a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy size_t count, loff_t *ppos) { 1267a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 126857674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches struct iwl_priv *priv = file->private_data; 1269a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy int pos = 0; 1270a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy char buf[128]; 1271a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy const size_t bufsz = sizeof(buf); 1272a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 1273a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", 1274a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.ucode_trace ? "On" : "Off"); 1275a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n", 1276a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.non_wraps_count); 1277a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n", 1278a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.wraps_once_count); 1279a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", 1280a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.wraps_more_count); 1281a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 12824967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1283a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy} 1284a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 1285a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, 1286a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy const char __user *user_buf, 1287a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy size_t count, loff_t *ppos) 1288a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy{ 1289a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy struct iwl_priv *priv = file->private_data; 1290a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy char buf[8]; 1291a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy int buf_size; 1292a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy int trace; 1293a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 1294a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy memset(buf, 0, sizeof(buf)); 1295a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 1296a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 1297a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy return -EFAULT; 1298a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy if (sscanf(buf, "%d", &trace) != 1) 1299a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy return -EFAULT; 1300a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 1301a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy if (trace) { 1302a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.ucode_trace = true; 1303a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */ 1304a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy mod_timer(&priv->ucode_trace, 1305a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); 1306a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy } else { 1307a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.ucode_trace = false; 1308a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy del_timer_sync(&priv->ucode_trace); 1309a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy } 1310a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 1311a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy return count; 1312a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy} 1313a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 131460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Bergstatic ssize_t iwl_dbgfs_rxon_flags_read(struct file *file, 131560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg char __user *user_buf, 131660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg size_t count, loff_t *ppos) { 131760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 131857674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches struct iwl_priv *priv = file->private_data; 131960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg int len = 0; 132060987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg char buf[20]; 132160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 132260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags)); 132360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg return simple_read_from_buffer(user_buf, count, ppos, buf, len); 132460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg} 132560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 132660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Bergstatic ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file, 132760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg char __user *user_buf, 132860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg size_t count, loff_t *ppos) { 132960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 133057674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches struct iwl_priv *priv = file->private_data; 133160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg int len = 0; 133260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg char buf[20]; 133360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 133460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg len = sprintf(buf, "0x%04X\n", 133560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg le32_to_cpu(priv->active_rxon.filter_flags)); 133660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg return simple_read_from_buffer(user_buf, count, ppos, buf, len); 133760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg} 133860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 13391b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guystatic ssize_t iwl_dbgfs_fh_reg_read(struct file *file, 13401b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy char __user *user_buf, 13411b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy size_t count, loff_t *ppos) 13421b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy{ 134357674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches struct iwl_priv *priv = file->private_data; 13441b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy char *buf; 13451b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy int pos = 0; 13461b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy ssize_t ret = -EFAULT; 13471b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy 13481b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy if (priv->cfg->ops->lib->dump_fh) { 13491b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true); 13501b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy if (buf) { 13511b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy ret = simple_read_from_buffer(user_buf, 13521b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy count, ppos, buf, pos); 13531b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy kfree(buf); 13541b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy } 13551b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy } 13561b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy 13571b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy return ret; 13581b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy} 13591b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy 1360a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guystatic ssize_t iwl_dbgfs_missed_beacon_read(struct file *file, 1361a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy char __user *user_buf, 1362a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy size_t count, loff_t *ppos) { 1363a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1364a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy struct iwl_priv *priv = file->private_data; 1365a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy int pos = 0; 1366a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy char buf[12]; 1367a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy const size_t bufsz = sizeof(buf); 1368a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1369a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "%d\n", 1370a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy priv->missed_beacon_threshold); 1371a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 13724967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1373a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy} 1374a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1375a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guystatic ssize_t iwl_dbgfs_missed_beacon_write(struct file *file, 1376a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy const char __user *user_buf, 1377a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy size_t count, loff_t *ppos) 1378a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy{ 1379a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy struct iwl_priv *priv = file->private_data; 1380a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy char buf[8]; 1381a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy int buf_size; 1382a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy int missed; 1383a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1384a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy memset(buf, 0, sizeof(buf)); 1385a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 1386a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 1387a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy return -EFAULT; 1388a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy if (sscanf(buf, "%d", &missed) != 1) 1389a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy return -EINVAL; 1390a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1391a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN || 1392a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy missed > IWL_MISSED_BEACON_THRESHOLD_MAX) 1393a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy priv->missed_beacon_threshold = 1394a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy IWL_MISSED_BEACON_THRESHOLD_DEF; 1395a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy else 1396a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy priv->missed_beacon_threshold = missed; 1397a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1398a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy return count; 1399a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy} 1400a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 14013e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyenstatic ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, 14023e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen char __user *user_buf, 14033e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen size_t count, loff_t *ppos) { 14043e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 140557674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches struct iwl_priv *priv = file->private_data; 14063e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen int pos = 0; 14073e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen char buf[12]; 14083e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen const size_t bufsz = sizeof(buf); 14093e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 14103e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen pos += scnprintf(buf + pos, bufsz - pos, "%u\n", 14113e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen priv->cfg->plcp_delta_threshold); 14123e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 14134967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 14143e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen} 14153e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 14163e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyenstatic ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, 14173e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen const char __user *user_buf, 14183e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen size_t count, loff_t *ppos) { 14193e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 14203e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen struct iwl_priv *priv = file->private_data; 14213e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen char buf[8]; 14223e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen int buf_size; 14233e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen int plcp; 14243e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 14253e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen memset(buf, 0, sizeof(buf)); 14263e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen buf_size = min(count, sizeof(buf) - 1); 14273e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen if (copy_from_user(buf, user_buf, buf_size)) 14283e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen return -EFAULT; 14293e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen if (sscanf(buf, "%d", &plcp) != 1) 14303e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen return -EINVAL; 1431680788aca3dcc24b932eb7a4219ab921ac5bf2d0Wey-Yi Guy if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || 14323e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) 14333e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen priv->cfg->plcp_delta_threshold = 1434680788aca3dcc24b932eb7a4219ab921ac5bf2d0Wey-Yi Guy IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; 14353e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen else 14363e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen priv->cfg->plcp_delta_threshold = plcp; 14373e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen return count; 14383e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen} 14393e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 1440528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guystatic ssize_t iwl_dbgfs_force_reset_read(struct file *file, 1441528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy char __user *user_buf, 1442528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy size_t count, loff_t *ppos) { 1443528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy 1444528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy struct iwl_priv *priv = file->private_data; 1445528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy int i, pos = 0; 1446528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy char buf[300]; 1447528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy const size_t bufsz = sizeof(buf); 1448528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy struct iwl_force_reset *force_reset; 1449528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy 1450528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy for (i = 0; i < IWL_MAX_FORCE_RESET; i++) { 1451528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy force_reset = &priv->force_reset[i]; 1452528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 1453528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy "Force reset method %d\n", i); 1454528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 1455528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy "\tnumber of reset request: %d\n", 1456528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy force_reset->reset_request_count); 1457528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 1458528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy "\tnumber of reset request success: %d\n", 1459528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy force_reset->reset_success_count); 1460528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 1461528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy "\tnumber of reset request reject: %d\n", 1462528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy force_reset->reset_reject_count); 1463528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 1464528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy "\treset duration: %lu\n", 1465528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy force_reset->reset_duration); 1466528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy } 1467528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1468528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy} 1469528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy 147004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guystatic ssize_t iwl_dbgfs_force_reset_write(struct file *file, 147104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy const char __user *user_buf, 147204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy size_t count, loff_t *ppos) { 147304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy 147404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy struct iwl_priv *priv = file->private_data; 147504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy char buf[8]; 147604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy int buf_size; 147704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy int reset, ret; 147804cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy 147904cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy memset(buf, 0, sizeof(buf)); 148004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 148104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 148204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy return -EFAULT; 148304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy if (sscanf(buf, "%d", &reset) != 1) 148404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy return -EINVAL; 148504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy switch (reset) { 148604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy case IWL_RF_RESET: 148704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy case IWL_FW_RESET: 1488c04f9f220300da83f71698fa7be24714152faf0dWey-Yi Guy ret = iwl_force_reset(priv, reset, true); 148904cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy break; 149004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy default: 149104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy return -EINVAL; 149204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy } 149304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy return ret ? ret : count; 149404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy} 149504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy 14964bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guystatic ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, 14974bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy const char __user *user_buf, 14984bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy size_t count, loff_t *ppos) { 14994bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 15004bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy struct iwl_priv *priv = file->private_data; 15014bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy char buf[8]; 15024bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy int buf_size; 15034bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy int flush; 15044bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 15054bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy memset(buf, 0, sizeof(buf)); 15064bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 15074bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 15084bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy return -EFAULT; 15094bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy if (sscanf(buf, "%d", &flush) != 1) 15104bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy return -EINVAL; 15114bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 15124bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy if (iwl_is_rfkill(priv)) 15134bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy return -EFAULT; 15144bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 15154bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL); 15164bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 15174bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy return count; 15184bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy} 15194bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 1520ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, 1521ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy char __user *user_buf, 1522ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy size_t count, loff_t *ppos) 1523ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy{ 1524ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1525ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy 1526ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file, 1527ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy user_buf, count, ppos); 1528ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy} 1529ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy 15307163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_READ_FILE_OPS(rx_statistics); 15317163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_READ_FILE_OPS(tx_statistics); 153220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 1533141b03e07a54af68fc099459bf780a182b240b45Wey-Yi GuyDEBUGFS_READ_FILE_OPS(rx_queue); 1534141b03e07a54af68fc099459bf780a182b240b45Wey-Yi GuyDEBUGFS_READ_FILE_OPS(tx_queue); 1535e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_rx_stats); 1536e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_tx_stats); 1537e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_general_stats); 15385225935b53ce1eafb222c644230d03ad6011d357Wey-Yi GuyDEBUGFS_READ_FILE_OPS(sensitivity); 15395225935b53ce1eafb222c644230d03ad6011d357Wey-Yi GuyDEBUGFS_READ_FILE_OPS(chain_noise); 1540c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi GuyDEBUGFS_READ_FILE_OPS(power_save_status); 15417163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); 15427163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); 1543696bdee3ba216186e21997d20a839b76158346e6Wey-Yi GuyDEBUGFS_WRITE_FILE_OPS(csr); 1544a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); 15451b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi GuyDEBUGFS_READ_FILE_OPS(fh_reg); 1546a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); 15473e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' NguyenDEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); 1548528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(force_reset); 154960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes BergDEBUGFS_READ_FILE_OPS(rxon_flags); 155060987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes BergDEBUGFS_READ_FILE_OPS(rxon_filter_flags); 15514bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(txfifo_flush); 1552ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_bt_stats); 155320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 1554712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* 1555712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Create the debugfs files and directories 1556712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 1557712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */ 1558712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerint iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 1559712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 156095b1a8224abf6230899856753c5506a3f737a65bZhu Yi struct dentry *phyd = priv->hw->wiphy->debugfsdir; 15614c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug; 1562712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 15634c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg dir_drv = debugfs_create_dir(name, phyd); 15644c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!dir_drv) 15654c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg return -ENOMEM; 1566712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 15674c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->debugfs_dir = dir_drv; 15684c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg 15694c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg dir_data = debugfs_create_dir("data", dir_drv); 15704c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!dir_data) 15714c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg goto err; 15724c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg dir_rf = debugfs_create_dir("rf", dir_drv); 15734c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!dir_rf) 15744c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg goto err; 15754c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg dir_debug = debugfs_create_dir("debug", dir_drv); 15764c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!dir_debug) 1577712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler goto err; 1578712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 15794c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); 15804c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); 15814c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR); 15824c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); 15834c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); 15844c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); 15854c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); 15864c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); 15874c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR); 1588381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy if (!priv->cfg->broken_powersave) { 1589381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy DEBUGFS_ADD_FILE(sleep_level_override, dir_data, 1590381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy S_IWUSR | S_IRUSR); 1591381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); 1592381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy } 15934c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR); 15944c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); 15954c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); 15964c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR); 15974c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR); 15984c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR); 15994c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR); 16004c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); 16014c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR); 16024c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); 16034c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR); 16044c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); 16054c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); 16064c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); 1607528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); 1608b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); 1609b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); 1610b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); 16114bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy if (priv->cfg->ops->lib->dev_txfifo_flush) 16124bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); 1613b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar 161465d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy if (priv->cfg->sensitivity_calib_by_driver) 16154c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); 161665d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy if (priv->cfg->chain_noise_calib_by_driver) 16174c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); 16186e5c800e75fad95f2a12d45d9b548b23834a13ffWey-Yi Guy if (priv->cfg->ucode_tracing) 16194c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); 1620ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy if (priv->cfg->bt_statistics) 1621ffb7d896b3bc21e09d77fed45b52b2ff4ce213e5Wey-Yi Guy DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); 162260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); 162360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); 162465d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy if (priv->cfg->sensitivity_calib_by_driver) 162565d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, 162665d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy &priv->disable_sens_cal); 162765d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy if (priv->cfg->chain_noise_calib_by_driver) 162865d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, 162965d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy &priv->disable_chain_noise_cal); 16304e7033ef491a8447247e77b20626cbc197a2eb83Wey-Yi Guy if (priv->cfg->tx_power_by_driver) 16314c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, 1632030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy &priv->disable_tx_power_cal); 1633712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return 0; 1634712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 1635712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklererr: 16364c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg IWL_ERR(priv, "Can't create the debugfs directory\n"); 1637712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler iwl_dbgfs_unregister(priv); 16384c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg return -ENOMEM; 1639712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 1640712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerEXPORT_SYMBOL(iwl_dbgfs_register); 1641712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 1642712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/** 1643712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Remove the debugfs files and directories 1644712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 1645712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */ 1646712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklervoid iwl_dbgfs_unregister(struct iwl_priv *priv) 1647712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 16484c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!priv->debugfs_dir) 1649712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return; 1650712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 16514c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg debugfs_remove_recursive(priv->debugfs_dir); 16524c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->debugfs_dir = NULL; 1653712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 1654712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerEXPORT_SYMBOL(iwl_dbgfs_unregister); 1655712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 1656712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 1657445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler 1658