iwl-debugfs.c revision 57674308d00b5ebb639ce53d388e61728e0c7f72
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", 470a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ieee80211_frequency_to_channel( 471a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].center_freq), 472a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].max_power, 473a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & IEEE80211_CHAN_RADAR ? 474a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy " (IEEE 802.11h required)" : "", 475a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 476a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy || (channels[i].flags & 477a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_RADAR)) ? "" : 478a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ", IBSS", 479a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & 480a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_PASSIVE_SCAN ? 481a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "passive only" : "active/passive"); 482a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy } 483d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); 484a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy if (supp_band) { 485a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels = supp_band->channels; 486d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 487d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas pos += scnprintf(buf + pos, bufsz - pos, 488a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "Displaying %d channels in 5.2GHz band (802.11a)\n", 489a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy supp_band->n_channels); 490a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy 491a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy for (i = 0; i < supp_band->n_channels; i++) 492a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 493a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "%d: %ddBm: BSS%s%s, %s.\n", 494a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ieee80211_frequency_to_channel( 495a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].center_freq), 496a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].max_power, 497a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & IEEE80211_CHAN_RADAR ? 498a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy " (IEEE 802.11h required)" : "", 499a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 500a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy || (channels[i].flags & 501a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_RADAR)) ? "" : 502a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ", IBSS", 503a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & 504a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_PASSIVE_SCAN ? 505a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "passive only" : "active/passive"); 506a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy } 507d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 508d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas kfree(buf); 509d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas return ret; 510d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas} 511d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 51208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guystatic ssize_t iwl_dbgfs_status_read(struct file *file, 51308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy char __user *user_buf, 51408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy size_t count, loff_t *ppos) { 51508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy 51628f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 51708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy char buf[512]; 51808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy int pos = 0; 51908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy const size_t bufsz = sizeof(buf); 52008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy 52108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", 52208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_HCMD_ACTIVE, &priv->status)); 52308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", 52408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_INT_ENABLED, &priv->status)); 52508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", 52608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_RF_KILL_HW, &priv->status)); 5277812b16730ccebce71a3b2228ac08dd4f8b39469Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", 5287812b16730ccebce71a3b2228ac08dd4f8b39469Wey-Yi Guy test_bit(STATUS_CT_KILL, &priv->status)); 52908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", 53008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_INIT, &priv->status)); 53108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", 53208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_ALIVE, &priv->status)); 53308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", 53408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_READY, &priv->status)); 53508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n", 53608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_TEMPERATURE, &priv->status)); 53708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", 53808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_GEO_CONFIGURED, &priv->status)); 53908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", 54008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_EXIT_PENDING, &priv->status)); 54108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", 54208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_STATISTICS, &priv->status)); 54308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", 54408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_SCANNING, &priv->status)); 54508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", 54608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_SCAN_ABORTING, &priv->status)); 54708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", 54808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_SCAN_HW, &priv->status)); 54908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", 55008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_POWER_PMI, &priv->status)); 55108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", 55208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_FW_ERROR, &priv->status)); 55308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 55408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy} 55508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy 556a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_read(struct file *file, 557a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy char __user *user_buf, 558a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy size_t count, loff_t *ppos) { 559a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 56028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 561a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int pos = 0; 562a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int cnt = 0; 563a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy char *buf; 564a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int bufsz = 24 * 64; /* 24 items * 64 char per item */ 565a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy ssize_t ret; 566a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 567a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 568a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (!buf) { 569a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy IWL_ERR(priv, "Can not allocate Buffer\n"); 570a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return -ENOMEM; 571a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy } 572a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 573a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 574a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "Interrupt Statistics Report:\n"); 575a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 576a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n", 577a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.hw); 578a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", 579a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.sw); 580a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (priv->isr_stats.sw > 0) { 581a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 582a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "\tLast Restarting Code: 0x%X\n", 583a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.sw_err); 584a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy } 585a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#ifdef CONFIG_IWLWIFI_DEBUG 586a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", 587a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.sch); 588a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n", 589a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.alive); 590a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#endif 591a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 592a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "HW RF KILL switch toggled:\t %u\n", 593a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.rfkill); 594a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 595a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n", 596a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.ctkill); 597a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 598a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n", 599a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.wakeup); 600a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 601a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 602a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "Rx command responses:\t\t %u\n", 603a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.rx); 604a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy for (cnt = 0; cnt < REPLY_MAX; cnt++) { 605a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (priv->isr_stats.rx_handlers[cnt] > 0) 606a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 607a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "\tRx handler[%36s]:\t\t %u\n", 608a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy get_cmd_string(cnt), 609a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.rx_handlers[cnt]); 610a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy } 611a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 612a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n", 613a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.tx); 614a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 615a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n", 616a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.unhandled); 617a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 618a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 619a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy kfree(buf); 620a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return ret; 621a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy} 622a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 623a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_write(struct file *file, 624a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy const char __user *user_buf, 625a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy size_t count, loff_t *ppos) 626a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy{ 627a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy struct iwl_priv *priv = file->private_data; 628a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy char buf[8]; 629a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int buf_size; 630a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy u32 reset_flag; 631a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 632a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy memset(buf, 0, sizeof(buf)); 633a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 634a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 635a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return -EFAULT; 636a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (sscanf(buf, "%x", &reset_flag) != 1) 637a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return -EFAULT; 638a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (reset_flag == 0) 639a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy iwl_clear_isr_stats(priv); 640a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 641a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return count; 642a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy} 643a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 644f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guystatic ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, 645f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy size_t count, loff_t *ppos) 646f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy{ 64728f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 648f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy int pos = 0, i; 649f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy char buf[256]; 650f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy const size_t bufsz = sizeof(buf); 651f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy 652f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy for (i = 0; i < AC_NUM; i++) { 653f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 654f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy "\tcw_min\tcw_max\taifsn\ttxop\n"); 655f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 656f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy "AC[%d]\t%u\t%u\t%u\t%u\n", i, 657f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].cw_min, 658f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].cw_max, 659f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].aifsn, 660f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].edca_txop); 661f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy } 6624967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 663f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy} 664a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 665a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guystatic ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, 666a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy size_t count, loff_t *ppos) 667a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy{ 66828f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 669a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy int pos = 0; 670a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy char buf[256]; 671a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy const size_t bufsz = sizeof(buf); 672a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy 673a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 674a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy "allow blinking: %s\n", 675a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy (priv->allow_blinking) ? "True" : "False"); 676a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy if (priv->allow_blinking) { 677a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 678a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy "Led blinking rate: %u\n", 679a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy priv->last_blink_rate); 680a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 681a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy "Last blink time: %lu\n", 682a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy priv->last_blink_time); 683a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy } 684a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy 6854967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 686a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy} 687a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy 688fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guystatic ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, 689fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy char __user *user_buf, 690fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy size_t count, loff_t *ppos) 691fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy{ 69228f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 6933ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 694fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy struct iwl_tt_restriction *restriction; 695fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy char buf[100]; 696fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy int pos = 0; 697fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy const size_t bufsz = sizeof(buf); 698fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy 699fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 700fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Thermal Throttling Mode: %s\n", 7013ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg tt->advanced_tt ? "Advance" : "Legacy"); 702fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 703fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Thermal Throttling State: %d\n", 704fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy tt->state); 7053ad3b92a5517c043ef30e4b95c4c39a35bbc36beJohannes Berg if (tt->advanced_tt) { 706fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction = tt->restriction + tt->state; 707fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 708fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Tx mode: %d\n", 709fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction->tx_stream); 710fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 711fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Rx mode: %d\n", 712fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction->rx_stream); 713fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 714fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "HT mode: %d\n", 715fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction->is_ht); 716fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy } 7174967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 718fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy} 719fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy 7201e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guystatic ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, 7211e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy const char __user *user_buf, 7221e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy size_t count, loff_t *ppos) 7231e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy{ 7241e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy struct iwl_priv *priv = file->private_data; 7251e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy char buf[8]; 7261e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy int buf_size; 7271e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy int ht40; 7281e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy 7291e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy memset(buf, 0, sizeof(buf)); 7301e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 7311e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 7321e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy return -EFAULT; 7331e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy if (sscanf(buf, "%d", &ht40) != 1) 7341e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy return -EFAULT; 7351e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy if (!iwl_is_associated(priv)) 7361e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy priv->disable_ht40 = ht40 ? true : false; 7371e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy else { 7381e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy IWL_ERR(priv, "Sta associated with AP - " 7391e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy "Change to 40MHz channel support is not allowed\n"); 7401e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy return -EINVAL; 7411e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy } 7421e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy 7431e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy return count; 7441e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy} 7451e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy 7461e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guystatic ssize_t iwl_dbgfs_disable_ht40_read(struct file *file, 7471e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy char __user *user_buf, 7481e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy size_t count, loff_t *ppos) 7491e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy{ 75028f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 7511e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy char buf[100]; 7521e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy int pos = 0; 7531e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy const size_t bufsz = sizeof(buf); 7541e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy 7551e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 7561e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy "11n 40MHz Mode: %s\n", 7571e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy priv->disable_ht40 ? "Disabled" : "Enabled"); 7584967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 7591e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy} 7601e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi Guy 761e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, 762e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg const char __user *user_buf, 763e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg size_t count, loff_t *ppos) 764e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{ 765e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg struct iwl_priv *priv = file->private_data; 766e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg char buf[8]; 767e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg int buf_size; 768e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg int value; 769e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 770e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg memset(buf, 0, sizeof(buf)); 771e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg buf_size = min(count, sizeof(buf) - 1); 772e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg if (copy_from_user(buf, user_buf, buf_size)) 773e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return -EFAULT; 774e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 775e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg if (sscanf(buf, "%d", &value) != 1) 776e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return -EINVAL; 777e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 778e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg /* 779e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg * Our users expect 0 to be "CAM", but 0 isn't actually 780e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg * valid here. However, let's not confuse them and present 781e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg * IWL_POWER_INDEX_1 as "1", not "0". 782e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg */ 7831a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre if (value == 0) 7841a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre return -EINVAL; 7851a34c043802a213e719420ece395cf25c85cc7c5Reinette Chatre else if (value > 0) 786e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg value -= 1; 787e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 788e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) 789e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return -EINVAL; 790e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 7914ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy if (!iwl_is_ready_rf(priv)) 7924ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy return -EAGAIN; 7934ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy 794e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg priv->power_data.debug_sleep_level_override = value; 795e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 796d3a571971e5af241074947fc80f6284677f6e014Reinette Chatre mutex_lock(&priv->mutex); 7974ad177b5c860dc0b1083eccc55957daf4a116b90Wey-Yi Guy iwl_power_update_mode(priv, true); 798d3a571971e5af241074947fc80f6284677f6e014Reinette Chatre mutex_unlock(&priv->mutex); 799e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 800e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return count; 801e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg} 802e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 803e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file, 804e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg char __user *user_buf, 805e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg size_t count, loff_t *ppos) 806e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{ 80728f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 808e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg char buf[10]; 809e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg int pos, value; 810e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg const size_t bufsz = sizeof(buf); 811e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 812e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg /* see the write function */ 813e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg value = priv->power_data.debug_sleep_level_override; 814e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg if (value >= 0) 815e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg value += 1; 816e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 817e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg pos = scnprintf(buf, bufsz, "%d\n", value); 818e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 819e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg} 820e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 821e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Bergstatic ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file, 822e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg char __user *user_buf, 823e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg size_t count, loff_t *ppos) 824e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg{ 82528f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 826e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg char buf[200]; 827e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg int pos = 0, i; 828e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg const size_t bufsz = sizeof(buf); 829e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd; 830e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 831e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg pos += scnprintf(buf + pos, bufsz - pos, 832e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg "flags: %#.2x\n", le16_to_cpu(cmd->flags)); 833e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg pos += scnprintf(buf + pos, bufsz - pos, 834e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg "RX/TX timeout: %d/%d usec\n", 835e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg le32_to_cpu(cmd->rx_data_timeout), 836e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg le32_to_cpu(cmd->tx_data_timeout)); 837e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg for (i = 0; i < IWL_POWER_VEC_SIZE; i++) 838e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg pos += scnprintf(buf + pos, bufsz - pos, 839e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg "sleep_interval[%d]: %d\n", i, 840e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg le32_to_cpu(cmd->sleep_interval[i])); 841e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 842e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 843e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg} 844e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes Berg 845712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_WRITE_FILE_OPS(sram); 846b03d7d0fd3d23b7cf130fa702f4ae3b1bc827d4bWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(log_event); 8470848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi GuyDEBUGFS_READ_FILE_OPS(nvm); 848712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_FILE_OPS(stations); 849d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, TomasDEBUGFS_READ_FILE_OPS(channels); 85008df05aa9b25f3079585855506022bb33a011183Wey-Yi GuyDEBUGFS_READ_FILE_OPS(status); 851a83b9141b540f96dd59409c6487828e880113a29Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(interrupt); 852f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi GuyDEBUGFS_READ_FILE_OPS(qos); 853a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi GuyDEBUGFS_READ_FILE_OPS(led); 854fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi GuyDEBUGFS_READ_FILE_OPS(thermal_throttling); 8551e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); 856e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes BergDEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); 857e312c24cf8229f9b6e76dbfd5d99eefe21f4ac0aJohannes BergDEBUGFS_READ_FILE_OPS(current_sleep_command); 858712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 85920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guystatic ssize_t iwl_dbgfs_traffic_log_read(struct file *file, 86020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy char __user *user_buf, 86120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy size_t count, loff_t *ppos) 86220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy{ 86320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy struct iwl_priv *priv = file->private_data; 86420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy int pos = 0, ofs = 0; 86520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy int cnt = 0, entry; 86620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy struct iwl_tx_queue *txq; 86720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy struct iwl_queue *q; 86820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy struct iwl_rx_queue *rxq = &priv->rxq; 86920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy char *buf; 87020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + 87188804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy (priv->cfg->num_of_queues * 32 * 8) + 400; 87220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy const u8 *ptr; 87320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy ssize_t ret; 87420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 87588804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy if (!priv->txq) { 87688804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy IWL_ERR(priv, "txq not ready\n"); 87788804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy return -EAGAIN; 87888804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy } 87920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 88020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (!buf) { 88120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy IWL_ERR(priv, "Can not allocate buffer\n"); 88220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy return -ENOMEM; 88320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 88420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n"); 88520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { 88620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy txq = &priv->txq[cnt]; 88720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy q = &txq->q; 88820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 88920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "q[%d]: read_ptr: %u, write_ptr: %u\n", 89020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy cnt, q->read_ptr, q->write_ptr); 89120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 89220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) { 89320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy ptr = priv->tx_traffic; 89420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 89520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "Tx Traffic idx: %u\n", priv->tx_traffic_idx); 89620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { 89720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; 89820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy entry++, ofs += 16) { 89920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 90020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "0x%.4x ", ofs); 90120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy hex_dump_to_buffer(ptr + ofs, 16, 16, 2, 90220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf + pos, bufsz - pos, 0); 9032fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre pos += strlen(buf + pos); 90420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (bufsz - pos > 0) 90520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf[pos++] = '\n'; 90620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 90720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 90820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 90920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 91020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n"); 91120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 91220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "read: %u, write: %u\n", 91320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy rxq->read, rxq->write); 91420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 91520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) { 91620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy ptr = priv->rx_traffic; 91720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 91820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "Rx Traffic idx: %u\n", priv->rx_traffic_idx); 91920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { 92020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; 92120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy entry++, ofs += 16) { 92220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 92320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy "0x%.4x ", ofs); 92420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy hex_dump_to_buffer(ptr + ofs, 16, 16, 2, 92520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf + pos, bufsz - pos, 0); 9262fac9717a05fc4b4824422d2c439c1260807c110Reinette Chatre pos += strlen(buf + pos); 92720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (bufsz - pos > 0) 92820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf[pos++] = '\n'; 92920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 93020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 93120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy } 93220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 93320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 93420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy kfree(buf); 93520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy return ret; 93620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy} 93720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 93820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guystatic ssize_t iwl_dbgfs_traffic_log_write(struct file *file, 93920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy const char __user *user_buf, 94020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy size_t count, loff_t *ppos) 94120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy{ 94220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy struct iwl_priv *priv = file->private_data; 94320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy char buf[8]; 94420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy int buf_size; 94520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy int traffic_log; 94620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 94720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy memset(buf, 0, sizeof(buf)); 94820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 94920594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 95020594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy return -EFAULT; 95120594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (sscanf(buf, "%d", &traffic_log) != 1) 95220594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy return -EFAULT; 95320594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy if (traffic_log == 0) 95420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy iwl_reset_traffic_log(priv); 95520594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 95620594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy return count; 95720594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy} 95820594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 959141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guystatic ssize_t iwl_dbgfs_tx_queue_read(struct file *file, 960141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy char __user *user_buf, 961141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy size_t count, loff_t *ppos) { 962141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 96328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 964141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy struct iwl_tx_queue *txq; 965141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy struct iwl_queue *q; 966141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy char *buf; 967141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy int pos = 0; 968141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy int cnt; 969141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy int ret; 970d23db556819c00d297c0f447bdd75b282d563122Wey-Yi Guy const size_t bufsz = sizeof(char) * 64 * priv->cfg->num_of_queues; 971141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 97288804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy if (!priv->txq) { 97388804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy IWL_ERR(priv, "txq not ready\n"); 97488804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy return -EAGAIN; 97588804e2b33b6ab3974ff2330cd045ca53d6750c5Wey-Yi Guy } 976141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 977141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy if (!buf) 978141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy return -ENOMEM; 979141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 980141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { 981141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy txq = &priv->txq[cnt]; 982141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy q = &txq->q; 983141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 984141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy "hwq %.2d: read=%u write=%u stop=%d" 985141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy " swq_id=%#.2x (ac %d/hwq %d)\n", 986141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy cnt, q->read_ptr, q->write_ptr, 987141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy !!test_bit(cnt, priv->queue_stopped), 988141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy txq->swq_id, 989141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy txq->swq_id & 0x80 ? txq->swq_id & 3 : 990141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy txq->swq_id, 991141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy txq->swq_id & 0x80 ? (txq->swq_id >> 2) & 992141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 0x1f : txq->swq_id); 993141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy if (cnt >= 4) 994141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy continue; 995141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy /* for the ACs, display the stop count too */ 996141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 997141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy " stop-count: %d\n", 998141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy atomic_read(&priv->queue_stop_count[cnt])); 999141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy } 1000141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1001141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy kfree(buf); 1002141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy return ret; 1003141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy} 1004141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 1005141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guystatic ssize_t iwl_dbgfs_rx_queue_read(struct file *file, 1006141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy char __user *user_buf, 1007141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy size_t count, loff_t *ppos) { 1008141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 100928f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 1010141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy struct iwl_rx_queue *rxq = &priv->rxq; 1011141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy char buf[256]; 1012141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy int pos = 0; 1013141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy const size_t bufsz = sizeof(buf); 1014141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 1015141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n", 1016141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy rxq->read); 1017141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", 1018141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy rxq->write); 1019141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n", 1020141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy rxq->free_count); 1021f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish if (rxq->rb_stts) { 1022f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n", 1023141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF); 1024f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish } else { 1025f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish pos += scnprintf(buf + pos, bufsz - pos, 1026f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish "closed_rb_num: Not Allocated\n"); 1027f5cc6a224d9f41d963fa4cee35d3db2559e8015dDor Shaish } 1028141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1029141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy} 1030141b03e07a54af68fc099459bf780a182b240b45Wey-Yi Guy 1031e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, 1032e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy char __user *user_buf, 1033e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy size_t count, loff_t *ppos) 1034e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{ 103528f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 103617f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file, 103717f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar user_buf, count, ppos); 1038e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy} 1039e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy 1040e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, 1041e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy char __user *user_buf, 1042e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy size_t count, loff_t *ppos) 1043e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{ 104428f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 104517f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file, 104617f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar user_buf, count, ppos); 1047e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy} 1048e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy 1049e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guystatic ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, 1050e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy char __user *user_buf, 1051e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy size_t count, loff_t *ppos) 1052e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy{ 105328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 105417f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file, 105517f36fc6ef3d1ab15f9d2160a9daa107db0887caAbhijeet Kolekar user_buf, count, ppos); 1056e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy} 1057e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi Guy 10585225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guystatic ssize_t iwl_dbgfs_sensitivity_read(struct file *file, 10595225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy char __user *user_buf, 10605225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy size_t count, loff_t *ppos) { 10615225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 106228f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 10635225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int pos = 0; 10645225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int cnt = 0; 10655225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy char *buf; 10665225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100; 10675225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy ssize_t ret; 10685225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy struct iwl_sensitivity_data *data; 10695225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 10705225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data = &priv->sensitivity_data; 10715225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 10725225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy if (!buf) { 10735225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy IWL_ERR(priv, "Can not allocate Buffer\n"); 10745225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy return -ENOMEM; 10755225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 10765225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 10775225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n", 10785225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_ofdm); 10795225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 10805225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy "auto_corr_ofdm_mrc:\t\t %u\n", 10815225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_ofdm_mrc); 10825225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n", 10835225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_ofdm_x1); 10845225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 10855225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy "auto_corr_ofdm_mrc_x1:\t\t %u\n", 10865225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_ofdm_mrc_x1); 10875225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n", 10885225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_cck); 10895225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n", 10905225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->auto_corr_cck_mrc); 10915225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 10925225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy "last_bad_plcp_cnt_ofdm:\t\t %u\n", 10935225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->last_bad_plcp_cnt_ofdm); 10945225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n", 10955225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->last_fa_cnt_ofdm); 10965225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 10975225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy "last_bad_plcp_cnt_cck:\t\t %u\n", 10985225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->last_bad_plcp_cnt_cck); 10995225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n", 11005225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->last_fa_cnt_cck); 11015225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n", 11025225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_curr_state); 11035225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n", 11045225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_prev_state); 11055225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t"); 11065225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy for (cnt = 0; cnt < 10; cnt++) { 11075225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, " %u", 11085225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_value[cnt]); 11095225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 11105225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\n"); 11115225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t"); 11125225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) { 11135225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, " %u", 11145225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_silence_rssi[cnt]); 11155225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 11165225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\n"); 11175225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n", 11185225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_silence_ref); 11195225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n", 11205225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_energy_idx); 11215225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n", 11225225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_silence_idx); 11235225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n", 11245225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_th_cck); 11255225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 11265225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy "nrg_auto_corr_silence_diff:\t %u\n", 11275225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_auto_corr_silence_diff); 11285225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n", 11295225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->num_in_cck_no_fa); 11305225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n", 11315225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->nrg_th_ofdm); 11325225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11335225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 11345225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy kfree(buf); 11355225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy return ret; 11365225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy} 11375225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11385225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11395225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guystatic ssize_t iwl_dbgfs_chain_noise_read(struct file *file, 11405225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy char __user *user_buf, 11415225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy size_t count, loff_t *ppos) { 11425225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 114328f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 11445225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int pos = 0; 11455225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int cnt = 0; 11465225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy char *buf; 11475225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100; 11485225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy ssize_t ret; 11495225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy struct iwl_chain_noise_data *data; 11505225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11515225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data = &priv->chain_noise_data; 11525225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 11535225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy if (!buf) { 11545225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy IWL_ERR(priv, "Can not allocate Buffer\n"); 11555225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy return -ENOMEM; 11565225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 11575225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11585225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n", 11595225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->active_chains); 11605225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n", 11615225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_noise_a); 11625225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n", 11635225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_noise_b); 11645225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n", 11655225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_noise_c); 11665225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n", 11675225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_signal_a); 11685225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n", 11695225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_signal_b); 11705225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n", 11715225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->chain_signal_c); 11725225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n", 11735225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->beacon_count); 11745225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11755225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t"); 11765225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 11775225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, " %u", 11785225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->disconn_array[cnt]); 11795225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 11805225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\n"); 11815225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t"); 11825225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 11835225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, " %u", 11845225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->delta_gain_code[cnt]); 11855225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy } 11865225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "\n"); 11875225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n", 11885225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->radio_write); 11895225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n", 11905225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy data->state); 11915225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 11925225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 11935225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy kfree(buf); 11945225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy return ret; 11955225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy} 11965225935b53ce1eafb222c644230d03ad6011d357Wey-Yi Guy 1197c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guystatic ssize_t iwl_dbgfs_power_save_status_read(struct file *file, 1198c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy char __user *user_buf, 1199c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy size_t count, loff_t *ppos) 1200c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy{ 120128f63a4bb744ea81030219aba2337fddb10b380bH Hartley Sweeten struct iwl_priv *priv = file->private_data; 1202c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy char buf[60]; 1203c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy int pos = 0; 1204c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy const size_t bufsz = sizeof(buf); 1205c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy u32 pwrsave_status; 1206c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy 1207c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) & 1208c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy CSR_GP_REG_POWER_SAVE_STATUS_MSK; 1209c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy 1210c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); 1211c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "%s\n", 1212c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" : 1213c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" : 1214c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" : 1215c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy "error"); 1216c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy 1217c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1218c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy} 1219c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi Guy 12207163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi Guystatic ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file, 1221ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy const char __user *user_buf, 1222ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy size_t count, loff_t *ppos) 1223ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy{ 1224ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy struct iwl_priv *priv = file->private_data; 1225ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy char buf[8]; 1226ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy int buf_size; 1227ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy int clear; 1228ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy 1229ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy memset(buf, 0, sizeof(buf)); 1230ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 1231ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 1232ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy return -EFAULT; 1233ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy if (sscanf(buf, "%d", &clear) != 1) 1234ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy return -EFAULT; 1235ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy 1236ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy /* make request to uCode to retrieve statistics information */ 1237ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy mutex_lock(&priv->mutex); 1238ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy iwl_send_statistics_request(priv, CMD_SYNC, true); 1239ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy mutex_unlock(&priv->mutex); 1240ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy 1241ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy return count; 1242ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy} 1243ef8d5529b015d4c5db7fad1adfc91edfd5abad56Wey-Yi Guy 1244696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guystatic ssize_t iwl_dbgfs_csr_write(struct file *file, 1245696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy const char __user *user_buf, 1246696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy size_t count, loff_t *ppos) 1247696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy{ 1248696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy struct iwl_priv *priv = file->private_data; 1249696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy char buf[8]; 1250696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy int buf_size; 1251696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy int csr; 1252696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy 1253696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy memset(buf, 0, sizeof(buf)); 1254696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 1255696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 1256696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy return -EFAULT; 1257696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy if (sscanf(buf, "%d", &csr) != 1) 1258696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy return -EFAULT; 1259696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy 1260696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy if (priv->cfg->ops->lib->dump_csr) 1261696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy priv->cfg->ops->lib->dump_csr(priv); 1262696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy 1263696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy return count; 1264696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy} 1265696bdee3ba216186e21997d20a839b76158346e6Wey-Yi Guy 1266a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file, 1267a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy char __user *user_buf, 1268a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy size_t count, loff_t *ppos) { 1269a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 127057674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches struct iwl_priv *priv = file->private_data; 1271a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy int pos = 0; 1272a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy char buf[128]; 1273a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy const size_t bufsz = sizeof(buf); 1274a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 1275a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", 1276a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.ucode_trace ? "On" : "Off"); 1277a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n", 1278a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.non_wraps_count); 1279a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n", 1280a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.wraps_once_count); 1281a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", 1282a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.wraps_more_count); 1283a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 12844967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1285a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy} 1286a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 1287a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guystatic ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, 1288a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy const char __user *user_buf, 1289a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy size_t count, loff_t *ppos) 1290a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy{ 1291a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy struct iwl_priv *priv = file->private_data; 1292a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy char buf[8]; 1293a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy int buf_size; 1294a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy int trace; 1295a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 1296a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy memset(buf, 0, sizeof(buf)); 1297a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 1298a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 1299a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy return -EFAULT; 1300a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy if (sscanf(buf, "%d", &trace) != 1) 1301a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy return -EFAULT; 1302a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 1303a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy if (trace) { 1304a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.ucode_trace = true; 1305a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */ 1306a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy mod_timer(&priv->ucode_trace, 1307a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); 1308a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy } else { 1309a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy priv->event_log.ucode_trace = false; 1310a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy del_timer_sync(&priv->ucode_trace); 1311a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy } 1312a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 1313a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy return count; 1314a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy} 1315a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi Guy 131660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Bergstatic ssize_t iwl_dbgfs_rxon_flags_read(struct file *file, 131760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg char __user *user_buf, 131860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg size_t count, loff_t *ppos) { 131960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 132057674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches struct iwl_priv *priv = file->private_data; 132160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg int len = 0; 132260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg char buf[20]; 132360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 132460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags)); 132560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg return simple_read_from_buffer(user_buf, count, ppos, buf, len); 132660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg} 132760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 132860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Bergstatic ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file, 132960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg char __user *user_buf, 133060987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg size_t count, loff_t *ppos) { 133160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 133257674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches struct iwl_priv *priv = file->private_data; 133360987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg int len = 0; 133460987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg char buf[20]; 133560987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 133660987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg len = sprintf(buf, "0x%04X\n", 133760987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg le32_to_cpu(priv->active_rxon.filter_flags)); 133860987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg return simple_read_from_buffer(user_buf, count, ppos, buf, len); 133960987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg} 134060987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg 13411b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guystatic ssize_t iwl_dbgfs_fh_reg_read(struct file *file, 13421b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy char __user *user_buf, 13431b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy size_t count, loff_t *ppos) 13441b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy{ 134557674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches struct iwl_priv *priv = file->private_data; 13461b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy char *buf; 13471b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy int pos = 0; 13481b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy ssize_t ret = -EFAULT; 13491b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy 13501b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy if (priv->cfg->ops->lib->dump_fh) { 13511b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true); 13521b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy if (buf) { 13531b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy ret = simple_read_from_buffer(user_buf, 13541b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy count, ppos, buf, pos); 13551b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy kfree(buf); 13561b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy } 13571b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy } 13581b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy 13591b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy return ret; 13601b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy} 13611b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi Guy 1362a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guystatic ssize_t iwl_dbgfs_missed_beacon_read(struct file *file, 1363a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy char __user *user_buf, 1364a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy size_t count, loff_t *ppos) { 1365a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1366a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy struct iwl_priv *priv = file->private_data; 1367a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy int pos = 0; 1368a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy char buf[12]; 1369a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy const size_t bufsz = sizeof(buf); 1370a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1371a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "%d\n", 1372a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy priv->missed_beacon_threshold); 1373a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 13744967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1375a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy} 1376a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1377a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guystatic ssize_t iwl_dbgfs_missed_beacon_write(struct file *file, 1378a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy const char __user *user_buf, 1379a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy size_t count, loff_t *ppos) 1380a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy{ 1381a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy struct iwl_priv *priv = file->private_data; 1382a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy char buf[8]; 1383a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy int buf_size; 1384a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy int missed; 1385a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1386a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy memset(buf, 0, sizeof(buf)); 1387a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 1388a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 1389a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy return -EFAULT; 1390a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy if (sscanf(buf, "%d", &missed) != 1) 1391a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy return -EINVAL; 1392a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1393a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN || 1394a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy missed > IWL_MISSED_BEACON_THRESHOLD_MAX) 1395a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy priv->missed_beacon_threshold = 1396a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy IWL_MISSED_BEACON_THRESHOLD_DEF; 1397a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy else 1398a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy priv->missed_beacon_threshold = missed; 1399a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 1400a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy return count; 1401a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy} 1402a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi Guy 14033e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyenstatic ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, 14043e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen char __user *user_buf, 14053e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen size_t count, loff_t *ppos) { 14063e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 140757674308d00b5ebb639ce53d388e61728e0c7f72Joe Perches struct iwl_priv *priv = file->private_data; 14083e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen int pos = 0; 14093e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen char buf[12]; 14103e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen const size_t bufsz = sizeof(buf); 14113e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 14123e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen pos += scnprintf(buf + pos, bufsz - pos, "%u\n", 14133e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen priv->cfg->plcp_delta_threshold); 14143e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 14154967c31677cf3c6c49aadf205f1a31d15d7610daWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 14163e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen} 14173e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 14183e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyenstatic ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, 14193e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen const char __user *user_buf, 14203e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen size_t count, loff_t *ppos) { 14213e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 14223e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen struct iwl_priv *priv = file->private_data; 14233e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen char buf[8]; 14243e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen int buf_size; 14253e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen int plcp; 14263e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 14273e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen memset(buf, 0, sizeof(buf)); 14283e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen buf_size = min(count, sizeof(buf) - 1); 14293e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen if (copy_from_user(buf, user_buf, buf_size)) 14303e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen return -EFAULT; 14313e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen if (sscanf(buf, "%d", &plcp) != 1) 14323e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen return -EINVAL; 1433680788aca3dcc24b932eb7a4219ab921ac5bf2d0Wey-Yi Guy if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || 14343e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) 14353e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen priv->cfg->plcp_delta_threshold = 1436680788aca3dcc24b932eb7a4219ab921ac5bf2d0Wey-Yi Guy IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; 14373e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen else 14383e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen priv->cfg->plcp_delta_threshold = plcp; 14393e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen return count; 14403e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen} 14413e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' Nguyen 1442528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guystatic ssize_t iwl_dbgfs_force_reset_read(struct file *file, 1443528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy char __user *user_buf, 1444528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy size_t count, loff_t *ppos) { 1445528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy 1446528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy struct iwl_priv *priv = file->private_data; 1447528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy int i, pos = 0; 1448528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy char buf[300]; 1449528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy const size_t bufsz = sizeof(buf); 1450528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy struct iwl_force_reset *force_reset; 1451528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy 1452528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy for (i = 0; i < IWL_MAX_FORCE_RESET; i++) { 1453528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy force_reset = &priv->force_reset[i]; 1454528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 1455528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy "Force reset method %d\n", i); 1456528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 1457528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy "\tnumber of reset request: %d\n", 1458528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy force_reset->reset_request_count); 1459528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 1460528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy "\tnumber of reset request success: %d\n", 1461528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy force_reset->reset_success_count); 1462528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 1463528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy "\tnumber of reset request reject: %d\n", 1464528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy force_reset->reset_reject_count); 1465528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 1466528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy "\treset duration: %lu\n", 1467528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy force_reset->reset_duration); 1468528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy } 1469528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1470528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy} 1471528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy 147204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guystatic ssize_t iwl_dbgfs_force_reset_write(struct file *file, 147304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy const char __user *user_buf, 147404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy size_t count, loff_t *ppos) { 147504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy 147604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy struct iwl_priv *priv = file->private_data; 147704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy char buf[8]; 147804cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy int buf_size; 147904cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy int reset, ret; 148004cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy 148104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy memset(buf, 0, sizeof(buf)); 148204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 148304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 148404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy return -EFAULT; 148504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy if (sscanf(buf, "%d", &reset) != 1) 148604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy return -EINVAL; 148704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy switch (reset) { 148804cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy case IWL_RF_RESET: 148904cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy case IWL_FW_RESET: 1490c04f9f220300da83f71698fa7be24714152faf0dWey-Yi Guy ret = iwl_force_reset(priv, reset, true); 149104cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy break; 149204cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy default: 149304cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy return -EINVAL; 149404cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy } 149504cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy return ret ? ret : count; 149604cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy} 149704cafd7fa74d5f70efc93bef36f118177057ff74Wey-Yi Guy 14984bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guystatic ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, 14994bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy const char __user *user_buf, 15004bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy size_t count, loff_t *ppos) { 15014bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 15024bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy struct iwl_priv *priv = file->private_data; 15034bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy char buf[8]; 15044bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy int buf_size; 15054bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy int flush; 15064bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 15074bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy memset(buf, 0, sizeof(buf)); 15084bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 15094bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 15104bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy return -EFAULT; 15114bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy if (sscanf(buf, "%d", &flush) != 1) 15124bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy return -EINVAL; 15134bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 15144bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy if (iwl_is_rfkill(priv)) 15154bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy return -EFAULT; 15164bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 15174bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL); 15184bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 15194bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy return count; 15204bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy} 15214bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy 15227163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_READ_FILE_OPS(rx_statistics); 15237163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_READ_FILE_OPS(tx_statistics); 152420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 1525141b03e07a54af68fc099459bf780a182b240b45Wey-Yi GuyDEBUGFS_READ_FILE_OPS(rx_queue); 1526141b03e07a54af68fc099459bf780a182b240b45Wey-Yi GuyDEBUGFS_READ_FILE_OPS(tx_queue); 1527e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_rx_stats); 1528e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_tx_stats); 1529e8fe59aecb9020b06305be4f8c67d73cbf49cbd2Wey-Yi GuyDEBUGFS_READ_FILE_OPS(ucode_general_stats); 15305225935b53ce1eafb222c644230d03ad6011d357Wey-Yi GuyDEBUGFS_READ_FILE_OPS(sensitivity); 15315225935b53ce1eafb222c644230d03ad6011d357Wey-Yi GuyDEBUGFS_READ_FILE_OPS(chain_noise); 1532c09430abed4159e5c56aaea257d040f7452daba6Wey-Yi GuyDEBUGFS_READ_FILE_OPS(power_save_status); 15337163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); 15347163b8a4ec995dabda3e92c6fed7b8600060618cWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); 1535696bdee3ba216186e21997d20a839b76158346e6Wey-Yi GuyDEBUGFS_WRITE_FILE_OPS(csr); 1536a9e1cb6a78ea8a74c49bf76726a2942f636a833bWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); 15371b3eb8236ad9369ae519216b61a3d22806370115Wey-Yi GuyDEBUGFS_READ_FILE_OPS(fh_reg); 1538a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); 15393e4fb5faefb57824f2e42305b3d5907845af978cTrieu 'Andrew' NguyenDEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); 1540528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(force_reset); 154160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes BergDEBUGFS_READ_FILE_OPS(rxon_flags); 154260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes BergDEBUGFS_READ_FILE_OPS(rxon_filter_flags); 15434bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi GuyDEBUGFS_WRITE_FILE_OPS(txfifo_flush); 154420594eb0daa67f7a0cc19d74a1bafceb1bb09f4aWey-Yi Guy 1545712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* 1546712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Create the debugfs files and directories 1547712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 1548712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */ 1549712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerint iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 1550712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 155195b1a8224abf6230899856753c5506a3f737a65bZhu Yi struct dentry *phyd = priv->hw->wiphy->debugfsdir; 15524c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug; 1553712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 15544c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg dir_drv = debugfs_create_dir(name, phyd); 15554c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!dir_drv) 15564c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg return -ENOMEM; 1557712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 15584c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->debugfs_dir = dir_drv; 15594c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg 15604c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg dir_data = debugfs_create_dir("data", dir_drv); 15614c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!dir_data) 15624c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg goto err; 15634c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg dir_rf = debugfs_create_dir("rf", dir_drv); 15644c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!dir_rf) 15654c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg goto err; 15664c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg dir_debug = debugfs_create_dir("debug", dir_drv); 15674c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!dir_debug) 1568712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler goto err; 1569712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 15704c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); 15714c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); 15724c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR); 15734c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); 15744c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); 15754c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); 15764c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); 15774c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); 15784c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR); 1579381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy if (!priv->cfg->broken_powersave) { 1580381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy DEBUGFS_ADD_FILE(sleep_level_override, dir_data, 1581381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy S_IWUSR | S_IRUSR); 1582381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); 1583381733cc53ce7abf3d8498f8ccf7586546c0b264Wey-Yi Guy } 15844c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR); 15854c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); 15864c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); 15874c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR); 15884c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR); 15894c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR); 15904c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR); 15914c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); 15924c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR); 15934c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); 15944c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR); 15954c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); 15964c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); 15974c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); 1598528c3126a98e75f47fc9fa11b243c82a59271d0dWey-Yi Guy DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); 1599b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); 1600b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); 1601b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); 16024bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy if (priv->cfg->ops->lib->dev_txfifo_flush) 16034bf49a90bc0bda131ef353cca631025849f36b4eWey-Yi Guy DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); 1604b8c76267cfb9a025afdd122bc2a8942dbf493dd1Abhijeet Kolekar 160565d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy if (priv->cfg->sensitivity_calib_by_driver) 16064c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); 160765d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy if (priv->cfg->chain_noise_calib_by_driver) 16084c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); 16096e5c800e75fad95f2a12d45d9b548b23834a13ffWey-Yi Guy if (priv->cfg->ucode_tracing) 16104c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); 161160987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); 161260987206cba0dbb547bce2d23c3a3338c5aaf5acJohannes Berg DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); 161365d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy if (priv->cfg->sensitivity_calib_by_driver) 161465d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, 161565d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy &priv->disable_sens_cal); 161665d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy if (priv->cfg->chain_noise_calib_by_driver) 161765d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, 161865d1f89682acf4d61dec7a8b771ed34afb7c17d9Wey-Yi Guy &priv->disable_chain_noise_cal); 16194e7033ef491a8447247e77b20626cbc197a2eb83Wey-Yi Guy if (priv->cfg->tx_power_by_driver) 16204c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, 1621030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy &priv->disable_tx_power_cal); 1622712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return 0; 1623712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 1624712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklererr: 16254c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg IWL_ERR(priv, "Can't create the debugfs directory\n"); 1626712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler iwl_dbgfs_unregister(priv); 16274c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg return -ENOMEM; 1628712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 1629712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerEXPORT_SYMBOL(iwl_dbgfs_register); 1630712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 1631712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/** 1632712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Remove the debugfs files and directories 1633712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 1634712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */ 1635712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklervoid iwl_dbgfs_unregister(struct iwl_priv *priv) 1636712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 16374c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg if (!priv->debugfs_dir) 1638712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return; 1639712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 16404c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg debugfs_remove_recursive(priv->debugfs_dir); 16414c84a8f1679f754d6080e49892f5cae2c88c91a8Johannes Berg priv->debugfs_dir = NULL; 1642712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 1643712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerEXPORT_SYMBOL(iwl_dbgfs_unregister); 1644712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 1645712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 1646445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler 1647