iwl-debugfs.c revision fbf3a2af3834e8e93e9c2876de62c5b49988e352
1712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/****************************************************************************** 2712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 3712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * GPL LICENSE SUMMARY 4712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 501f8162a854df7f9c259c839ad3c1168ac13b7b8Reinette Chatre * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. 6712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 7712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * This program is free software; you can redistribute it and/or modify 8712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * it under the terms of version 2 of the GNU General Public License as 9712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * published by the Free Software Foundation. 10712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 11712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * This program is distributed in the hope that it will be useful, but 12712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * WITHOUT ANY WARRANTY; without even the implied warranty of 13712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * General Public License for more details. 15712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 16712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * You should have received a copy of the GNU General Public License 17712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * along with this program; if not, write to the Free Software 18712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, 19712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * USA 20712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 21712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * The full GNU General Public License is included in this distribution 22712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * in the file called LICENSE.GPL. 23712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 24712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Contact Information: 25759ef89fb096c4a6ef078d3cfd5682ac037bd789Winkler, Tomas * Intel Linux Wireless <ilw@linux.intel.com> 26712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 27712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler *****************************************************************************/ 28712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 29712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/kernel.h> 30712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/module.h> 31712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/debugfs.h> 32712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 33712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <linux/ieee80211.h> 34712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include <net/mac80211.h> 35712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 36712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 373e0d4cb12f6fd97193a455b49125398b2231c87cTomas Winkler#include "iwl-dev.h" 38712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#include "iwl-debug.h" 39fee1247a30e5b3d48fe985b4a935eb6818f3b464Tomas Winkler#include "iwl-core.h" 403395f6e9cf48469d7ee05703cad1502002741c16Tomas Winkler#include "iwl-io.h" 41712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 42712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 43712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* create and remove of files */ 44712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_ADD_DIR(name, parent) do { \ 45712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler dbgfs->dir_##name = debugfs_create_dir(#name, parent); \ 46712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler if (!(dbgfs->dir_##name)) \ 47712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler goto err; \ 48712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} while (0) 49712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 50712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_ADD_FILE(name, parent) do { \ 51712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler dbgfs->dbgfs_##parent##_files.file_##name = \ 52fcf89d05404dafcde581d44dfa89bd8c8def27f9Reinette Chatre debugfs_create_file(#name, S_IWUSR | S_IRUSR, \ 53fcf89d05404dafcde581d44dfa89bd8c8def27f9Reinette Chatre dbgfs->dir_##parent, priv, \ 54712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler &iwl_dbgfs_##name##_ops); \ 55712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \ 56712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler goto err; \ 57712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} while (0) 58712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 59445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ 60445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler dbgfs->dbgfs_##parent##_files.file_##name = \ 61fcf89d05404dafcde581d44dfa89bd8c8def27f9Reinette Chatre debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ 62fcf89d05404dafcde581d44dfa89bd8c8def27f9Reinette Chatre dbgfs->dir_##parent, ptr); \ 639b24001db145cf1da76a479918373c18aa10bb4bZhaolei if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ 649b24001db145cf1da76a479918373c18aa10bb4bZhaolei || !dbgfs->dbgfs_##parent##_files.file_##name) \ 65445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler goto err; \ 66445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler} while (0) 67445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler 682ddfa129bbf3dca708ffb0eb29d08de32cacd547Winkler, Tomas#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ 692ddfa129bbf3dca708ffb0eb29d08de32cacd547Winkler, Tomas dbgfs->dbgfs_##parent##_files.file_##name = \ 70fcf89d05404dafcde581d44dfa89bd8c8def27f9Reinette Chatre debugfs_create_x32(#name, S_IRUSR, dbgfs->dir_##parent, ptr); \ 712ddfa129bbf3dca708ffb0eb29d08de32cacd547Winkler, Tomas if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ 722ddfa129bbf3dca708ffb0eb29d08de32cacd547Winkler, Tomas || !dbgfs->dbgfs_##parent##_files.file_##name) \ 732ddfa129bbf3dca708ffb0eb29d08de32cacd547Winkler, Tomas goto err; \ 742ddfa129bbf3dca708ffb0eb29d08de32cacd547Winkler, Tomas} while (0) 752ddfa129bbf3dca708ffb0eb29d08de32cacd547Winkler, Tomas 76712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_REMOVE(name) do { \ 77712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler debugfs_remove(name); \ 78712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler name = NULL; \ 79712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} while (0); 80712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 81712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* file operation */ 82712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_FUNC(name) \ 83712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_##name##_read(struct file *file, \ 84712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char __user *user_buf, \ 85712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos); 86712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 87712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_WRITE_FUNC(name) \ 88712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_##name##_write(struct file *file, \ 89712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler const char __user *user_buf, \ 90712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos); 91712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 92712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 93712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file) 94712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 95712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler file->private_data = inode->i_private; 96712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return 0; 97712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 98712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 99712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_FILE_OPS(name) \ 100712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_READ_FUNC(name); \ 101712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic const struct file_operations iwl_dbgfs_##name##_ops = { \ 102712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler .read = iwl_dbgfs_##name##_read, \ 103712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler .open = iwl_dbgfs_open_file_generic, \ 104712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}; 105712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 106189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer#define DEBUGFS_WRITE_FILE_OPS(name) \ 107189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer DEBUGFS_WRITE_FUNC(name); \ 108189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummerstatic const struct file_operations iwl_dbgfs_##name##_ops = { \ 109189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer .write = iwl_dbgfs_##name##_write, \ 110189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer .open = iwl_dbgfs_open_file_generic, \ 111189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer}; 112189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer 113189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer 114712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define DEBUGFS_READ_WRITE_FILE_OPS(name) \ 115712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_READ_FUNC(name); \ 116712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_WRITE_FUNC(name); \ 117712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic const struct file_operations iwl_dbgfs_##name##_ops = { \ 118712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler .write = iwl_dbgfs_##name##_write, \ 119712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler .read = iwl_dbgfs_##name##_read, \ 120712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler .open = iwl_dbgfs_open_file_generic, \ 121712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler}; 122712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 123712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 124712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, 125712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char __user *user_buf, 126712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos) { 127712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 128712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 129712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char buf[256]; 130712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int pos = 0; 131db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar const size_t bufsz = sizeof(buf); 132712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 133db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n", 134db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar priv->tx_stats[0].cnt); 135db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n", 136db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar priv->tx_stats[1].cnt); 137db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n", 138db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar priv->tx_stats[2].cnt); 139712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 140712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 141712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 142712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 143712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, 144712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char __user *user_buf, 145712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos) { 146712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 147712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 148712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char buf[256]; 149712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int pos = 0; 150db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar const size_t bufsz = sizeof(buf); 151712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 152db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n", 153db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar priv->rx_stats[0].cnt); 154db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n", 155db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar priv->rx_stats[1].cnt); 156db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n", 157db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar priv->rx_stats[2].cnt); 158712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 159712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 160712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 161712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 162712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE1_MASK 0x000000ff; 163712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE2_MASK 0x0000ffff; 164712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler#define BYTE3_MASK 0x00ffffff; 165712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_sram_read(struct file *file, 166712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char __user *user_buf, 167712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos) 168712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 169712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler u32 val; 170712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char buf[1024]; 171712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler ssize_t ret; 172712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int i; 173712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int pos = 0; 174712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 175db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar const size_t bufsz = sizeof(buf); 176712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 177712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { 1783395f6e9cf48469d7ee05703cad1502002741c16Tomas Winkler val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ 179712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler priv->dbgfs->sram_len - i); 180712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler if (i < 4) { 181712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler switch (i) { 182712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler case 1: 183712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler val &= BYTE1_MASK; 184712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler break; 185712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler case 2: 186712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler val &= BYTE2_MASK; 187712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler break; 188712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler case 3: 189712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler val &= BYTE3_MASK; 190712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler break; 191712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 192712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 193db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); 194712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 195db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "\n"); 196712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 197712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 198712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return ret; 199712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 200712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 201712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_sram_write(struct file *file, 202712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler const char __user *user_buf, 203712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos) 204712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 205712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler struct iwl_priv *priv = file->private_data; 206712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char buf[64]; 207712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int buf_size; 208712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler u32 offset, len; 209712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 210712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler memset(buf, 0, sizeof(buf)); 211712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler buf_size = min(count, sizeof(buf) - 1); 212712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler if (copy_from_user(buf, user_buf, buf_size)) 213712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return -EFAULT; 214712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 215712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 216712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler priv->dbgfs->sram_offset = offset; 217712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler priv->dbgfs->sram_len = len; 218712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } else { 219712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler priv->dbgfs->sram_offset = 0; 220712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler priv->dbgfs->sram_len = 0; 221712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 222712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 223712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return count; 224712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 225712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 226712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerstatic ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 227712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler size_t count, loff_t *ppos) 228712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 229712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 2306def9761f72501e638e79eebcd70afea12a3a93dTomas Winkler struct iwl_station_entry *station; 2315425e490471d521bae2fce16d22995803b41d90fTomas Winkler int max_sta = priv->hw_params.max_stations; 232712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler char *buf; 233712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler int i, j, pos = 0; 234712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler ssize_t ret; 235712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler /* Add 30 for initial string */ 236712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations); 237712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 238712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler buf = kmalloc(bufsz, GFP_KERNEL); 2393ac7f14694dd38273d9d96f1c873233d71190c15Tomas Winkler if (!buf) 240712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return -ENOMEM; 241712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 242db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", 243712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler priv->num_stations); 244712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 245712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler for (i = 0; i < max_sta; i++) { 246712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler station = &priv->stations[i]; 247712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler if (station->used) { 248db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, 249db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar "station %d:\ngeneral data:\n", i+1); 250db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n", 251712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler station->sta.sta.sta_id); 252db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n", 253712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler station->sta.mode); 254db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, 255db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar "flags: 0x%x\n", 256712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler station->sta.station_flags_msk); 257db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, 258db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar "ps_status: %u\n", station->ps_status); 259db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); 260db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, 261344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller "seq_num\t\ttxq_id"); 262db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, 263344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller "\tframe_count\twait_for_ba\t"); 264db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, 265db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar "start_idx\tbitmap0\t"); 266db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, 267344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller "bitmap1\trate_n_flags"); 268344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller pos += scnprintf(buf + pos, bufsz - pos, "\n"); 269712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 270712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler for (j = 0; j < MAX_TID_COUNT; j++) { 271db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, 272344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller "[%d]:\t\t%u", j, 273db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar station->tid[j].seq_number); 274db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, 275344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller "\t%u\t\t%u\t\t%u\t\t", 276712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler station->tid[j].agg.txq_id, 277712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler station->tid[j].agg.frame_count, 278712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler station->tid[j].agg.wait_for_ba); 279db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, 280344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller "%u\t%llu\t%u", 281712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler station->tid[j].agg.start_idx, 28216788599a9601cbba6ad7b58b3b52227ea59c013John W. Linville (unsigned long long)station->tid[j].agg.bitmap, 283712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler station->tid[j].agg.rate_n_flags); 284344234de54891ed15bf8127e4640ff9238076d6cDavid S. Miller pos += scnprintf(buf + pos, bufsz - pos, "\n"); 285712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 286db0589f3b9443f2b57ea6daaec09c1ab0ac99cb0Abhijeet Kolekar pos += scnprintf(buf + pos, bufsz - pos, "\n"); 287712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 288712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 289712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 290712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 291712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler kfree(buf); 292712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return ret; 293712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 294712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 2950848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guystatic ssize_t iwl_dbgfs_nvm_read(struct file *file, 2968dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler char __user *user_buf, 2978dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler size_t count, 2988dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler loff_t *ppos) 2998dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler{ 3008dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler ssize_t ret; 3018dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 3028dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler int pos = 0, ofs = 0, buf_size = 0; 3038dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler const u8 *ptr; 3048dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler char *buf; 3058dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler size_t eeprom_len = priv->cfg->eeprom_size; 3068dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler buf_size = 4 * eeprom_len + 256; 3078dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler 3088dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler if (eeprom_len % 16) { 3090848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy IWL_ERR(priv, "NVM size is not multiple of 16.\n"); 3108dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler return -ENODATA; 3118dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler } 3128dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler 3138dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler /* 4 characters for byte 0xYY */ 3148dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler buf = kzalloc(buf_size, GFP_KERNEL); 3158dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler if (!buf) { 31615b1687cb4f45b87ddbe4dfc7759ff5bb69497d2Winkler, Tomas IWL_ERR(priv, "Can not allocate Buffer\n"); 3178dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler return -ENOMEM; 3188dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler } 3198dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler 3208dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler ptr = priv->eeprom; 3210848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy if (!ptr) { 3220848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy IWL_ERR(priv, "Invalid EEPROM/OTP memory\n"); 3230848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy return -ENOMEM; 3240848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy } 3250848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s\n", 3260848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) 3270848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy ? "OTP" : "EEPROM"); 3288dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { 3298dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); 3308dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, 3318dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler buf_size - pos, 0); 3328dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler pos += strlen(buf); 3338dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler if (buf_size - pos > 0) 3348dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler buf[pos++] = '\n'; 3358dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler } 3368dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler 3378dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 3388dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler kfree(buf); 3398dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler return ret; 3408dd266ef4eb51d034fa1c5f9307a9ff07547d8e6Tomas Winkler} 341712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 342189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummerstatic ssize_t iwl_dbgfs_log_event_write(struct file *file, 343189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer const char __user *user_buf, 344189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer size_t count, loff_t *ppos) 345189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer{ 346189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer struct iwl_priv *priv = file->private_data; 347189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer u32 event_log_flag; 348189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer char buf[8]; 349189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer int buf_size; 350189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer 351189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer memset(buf, 0, sizeof(buf)); 352189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer buf_size = min(count, sizeof(buf) - 1); 353189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer if (copy_from_user(buf, user_buf, buf_size)) 354189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer return -EFAULT; 355189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer if (sscanf(buf, "%d", &event_log_flag) != 1) 356189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer return -EFAULT; 357189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer if (event_log_flag == 1) 358189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer iwl_dump_nic_event_log(priv); 359189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer 360189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer return count; 361189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer} 362189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer 363d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 364d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 365d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomasstatic ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, 366d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas size_t count, loff_t *ppos) 367d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas{ 368d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 369d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas struct ieee80211_channel *channels = NULL; 370d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas const struct ieee80211_supported_band *supp_band = NULL; 371d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas int pos = 0, i, bufsz = PAGE_SIZE; 372d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas char *buf; 373d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas ssize_t ret; 374d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 375d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) 376d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas return -EAGAIN; 377d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 378d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas buf = kzalloc(bufsz, GFP_KERNEL); 379d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas if (!buf) { 38015b1687cb4f45b87ddbe4dfc7759ff5bb69497d2Winkler, Tomas IWL_ERR(priv, "Can not allocate Buffer\n"); 381d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas return -ENOMEM; 382d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas } 383d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 384d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); 385a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy if (supp_band) { 386a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels = supp_band->channels; 387d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 388d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas pos += scnprintf(buf + pos, bufsz - pos, 389a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "Displaying %d channels in 2.4GHz band 802.11bg):\n", 390a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy supp_band->n_channels); 391d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 392a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy for (i = 0; i < supp_band->n_channels; i++) 393a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 394a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "%d: %ddBm: BSS%s%s, %s.\n", 395a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ieee80211_frequency_to_channel( 396a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].center_freq), 397a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].max_power, 398a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & IEEE80211_CHAN_RADAR ? 399a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy " (IEEE 802.11h required)" : "", 400a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 401a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy || (channels[i].flags & 402a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_RADAR)) ? "" : 403a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ", IBSS", 404a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & 405a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_PASSIVE_SCAN ? 406a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "passive only" : "active/passive"); 407a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy } 408d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); 409a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy if (supp_band) { 410a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels = supp_band->channels; 411d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 412d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas pos += scnprintf(buf + pos, bufsz - pos, 413a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "Displaying %d channels in 5.2GHz band (802.11a)\n", 414a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy supp_band->n_channels); 415a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy 416a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy for (i = 0; i < supp_band->n_channels; i++) 417a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 418a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "%d: %ddBm: BSS%s%s, %s.\n", 419a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ieee80211_frequency_to_channel( 420a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].center_freq), 421a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].max_power, 422a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & IEEE80211_CHAN_RADAR ? 423a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy " (IEEE 802.11h required)" : "", 424a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 425a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy || (channels[i].flags & 426a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_RADAR)) ? "" : 427a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy ", IBSS", 428a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy channels[i].flags & 429a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy IEEE80211_CHAN_PASSIVE_SCAN ? 430a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy "passive only" : "active/passive"); 431a2e2322d83df82a57ba456cfa604c8b8f7b04670Wey-Yi Guy } 432d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 433d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas kfree(buf); 434d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas return ret; 435d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas} 436d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas 43708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guystatic ssize_t iwl_dbgfs_status_read(struct file *file, 43808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy char __user *user_buf, 43908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy size_t count, loff_t *ppos) { 44008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy 44108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 44208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy char buf[512]; 44308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy int pos = 0; 44408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy const size_t bufsz = sizeof(buf); 44508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy 44608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", 44708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_HCMD_ACTIVE, &priv->status)); 44808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n", 44908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)); 45008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", 45108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_INT_ENABLED, &priv->status)); 45208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", 45308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_RF_KILL_HW, &priv->status)); 45408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", 45508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_INIT, &priv->status)); 45608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", 45708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_ALIVE, &priv->status)); 45808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", 45908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_READY, &priv->status)); 46008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n", 46108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_TEMPERATURE, &priv->status)); 46208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", 46308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_GEO_CONFIGURED, &priv->status)); 46408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", 46508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_EXIT_PENDING, &priv->status)); 46608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", 46708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_STATISTICS, &priv->status)); 46808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", 46908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_SCANNING, &priv->status)); 47008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", 47108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_SCAN_ABORTING, &priv->status)); 47208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", 47308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_SCAN_HW, &priv->status)); 47408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", 47508df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_POWER_PMI, &priv->status)); 47608df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", 47708df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_FW_ERROR, &priv->status)); 47808df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "STATUS_MODE_PENDING:\t %d\n", 47908df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy test_bit(STATUS_MODE_PENDING, &priv->status)); 48008df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 48108df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy} 48208df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy 483a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_read(struct file *file, 484a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy char __user *user_buf, 485a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy size_t count, loff_t *ppos) { 486a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 487a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 488a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int pos = 0; 489a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int cnt = 0; 490a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy char *buf; 491a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int bufsz = 24 * 64; /* 24 items * 64 char per item */ 492a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy ssize_t ret; 493a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 494a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy buf = kzalloc(bufsz, GFP_KERNEL); 495a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (!buf) { 496a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy IWL_ERR(priv, "Can not allocate Buffer\n"); 497a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return -ENOMEM; 498a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy } 499a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 500a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 501a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "Interrupt Statistics Report:\n"); 502a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 503a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n", 504a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.hw); 505a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", 506a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.sw); 507a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (priv->isr_stats.sw > 0) { 508a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 509a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "\tLast Restarting Code: 0x%X\n", 510a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.sw_err); 511a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy } 512a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#ifdef CONFIG_IWLWIFI_DEBUG 513a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", 514a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.sch); 515a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n", 516a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.alive); 517a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy#endif 518a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 519a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "HW RF KILL switch toggled:\t %u\n", 520a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.rfkill); 521a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 522a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n", 523a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.ctkill); 524a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 525a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n", 526a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.wakeup); 527a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 528a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 529a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "Rx command responses:\t\t %u\n", 530a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.rx); 531a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy for (cnt = 0; cnt < REPLY_MAX; cnt++) { 532a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (priv->isr_stats.rx_handlers[cnt] > 0) 533a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 534a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy "\tRx handler[%36s]:\t\t %u\n", 535a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy get_cmd_string(cnt), 536a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.rx_handlers[cnt]); 537a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy } 538a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 539a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n", 540a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.tx); 541a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 542a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n", 543a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy priv->isr_stats.unhandled); 544a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 545a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 546a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy kfree(buf); 547a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return ret; 548a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy} 549a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 550a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guystatic ssize_t iwl_dbgfs_interrupt_write(struct file *file, 551a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy const char __user *user_buf, 552a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy size_t count, loff_t *ppos) 553a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy{ 554a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy struct iwl_priv *priv = file->private_data; 555a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy char buf[8]; 556a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy int buf_size; 557a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy u32 reset_flag; 558a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 559a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy memset(buf, 0, sizeof(buf)); 560a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy buf_size = min(count, sizeof(buf) - 1); 561a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (copy_from_user(buf, user_buf, buf_size)) 562a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return -EFAULT; 563a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (sscanf(buf, "%x", &reset_flag) != 1) 564a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return -EFAULT; 565a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy if (reset_flag == 0) 566a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy iwl_clear_isr_stats(priv); 567a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 568a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy return count; 569a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy} 570a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 571f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guystatic ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, 572f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy size_t count, loff_t *ppos) 573f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy{ 574f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 575f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy int pos = 0, i; 576f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy char buf[256]; 577f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy const size_t bufsz = sizeof(buf); 578f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy ssize_t ret; 579f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy 580f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy for (i = 0; i < AC_NUM; i++) { 581f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 582f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy "\tcw_min\tcw_max\taifsn\ttxop\n"); 583f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 584f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy "AC[%d]\t%u\t%u\t%u\t%u\n", i, 585f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].cw_min, 586f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].cw_max, 587f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].aifsn, 588f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy priv->qos_data.def_qos_parm.ac[i].edca_txop); 589f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy } 590f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 591f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy return ret; 592f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy} 593a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy 594a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy#ifdef CONFIG_IWLWIFI_LEDS 595a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guystatic ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, 596a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy size_t count, loff_t *ppos) 597a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy{ 598a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 599a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy int pos = 0; 600a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy char buf[256]; 601a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy const size_t bufsz = sizeof(buf); 602a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy ssize_t ret; 603a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy 604a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 605a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy "allow blinking: %s\n", 606a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy (priv->allow_blinking) ? "True" : "False"); 607a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy if (priv->allow_blinking) { 608a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 609a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy "Led blinking rate: %u\n", 610a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy priv->last_blink_rate); 611a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 612a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy "Last blink time: %lu\n", 613a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy priv->last_blink_time); 614a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy } 615a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy 616a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 617a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy return ret; 618a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy} 619a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy#endif 620a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy 621fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guystatic ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, 622fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy char __user *user_buf, 623fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy size_t count, loff_t *ppos) 624fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy{ 625fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 626fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy struct iwl_tt_mgmt *tt = &priv->power_data.tt; 627fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy struct iwl_tt_restriction *restriction; 628fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy char buf[100]; 629fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy int pos = 0; 630fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy const size_t bufsz = sizeof(buf); 631fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy ssize_t ret; 632fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy 633fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 634fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Thermal Throttling Mode: %s\n", 635fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy (priv->power_data.adv_tt) 636fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy ? "Advance" : "Legacy"); 637fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 638fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Thermal Throttling State: %d\n", 639fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy tt->state); 640fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy if (priv->power_data.adv_tt) { 641fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction = tt->restriction + tt->state; 642fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 643fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Tx mode: %d\n", 644fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction->tx_stream); 645fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 646fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "Rx mode: %d\n", 647fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction->rx_stream); 648fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy pos += scnprintf(buf + pos, bufsz - pos, 649fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy "HT mode: %d\n", 650fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy restriction->is_ht); 651fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy } 652fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 653fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy return ret; 654fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy} 655fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy 656712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_WRITE_FILE_OPS(sram); 657189a2b5942d62bd18e1e01772c4c784253f5dd16Ester KummerDEBUGFS_WRITE_FILE_OPS(log_event); 6580848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi GuyDEBUGFS_READ_FILE_OPS(nvm); 659712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_FILE_OPS(stations); 660712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_FILE_OPS(rx_statistics); 661712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerDEBUGFS_READ_FILE_OPS(tx_statistics); 662d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, TomasDEBUGFS_READ_FILE_OPS(channels); 66308df05aa9b25f3079585855506022bb33a011183Wey-Yi GuyDEBUGFS_READ_FILE_OPS(status); 664a83b9141b540f96dd59409c6487828e880113a29Wey-Yi GuyDEBUGFS_READ_WRITE_FILE_OPS(interrupt); 665f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi GuyDEBUGFS_READ_FILE_OPS(qos); 666a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy#ifdef CONFIG_IWLWIFI_LEDS 667a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi GuyDEBUGFS_READ_FILE_OPS(led); 668a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy#endif 669fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi GuyDEBUGFS_READ_FILE_OPS(thermal_throttling); 670712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 671712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/* 672712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Create the debugfs files and directories 673712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 674712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */ 675712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklerint iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 676712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 677712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler struct iwl_debugfs *dbgfs; 67895b1a8224abf6230899856753c5506a3f737a65bZhu Yi struct dentry *phyd = priv->hw->wiphy->debugfsdir; 6793ac7f14694dd38273d9d96f1c873233d71190c15Tomas Winkler int ret = 0; 680712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 681712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); 682712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler if (!dbgfs) { 6833ac7f14694dd38273d9d96f1c873233d71190c15Tomas Winkler ret = -ENOMEM; 684712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler goto err; 685712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 686712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 687712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler priv->dbgfs = dbgfs; 688712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler dbgfs->name = name; 68995b1a8224abf6230899856753c5506a3f737a65bZhu Yi dbgfs->dir_drv = debugfs_create_dir(name, phyd); 6903ac7f14694dd38273d9d96f1c873233d71190c15Tomas Winkler if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) { 6913ac7f14694dd38273d9d96f1c873233d71190c15Tomas Winkler ret = -ENOENT; 692712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler goto err; 693712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler } 694712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 695712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); 696445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); 6970848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy DEBUGFS_ADD_FILE(nvm, data); 698712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_ADD_FILE(sram, data); 699189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer DEBUGFS_ADD_FILE(log_event, data); 700712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_ADD_FILE(stations, data); 701712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_ADD_FILE(rx_statistics, data); 702712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_ADD_FILE(tx_statistics, data); 703d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas DEBUGFS_ADD_FILE(channels, data); 70408df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy DEBUGFS_ADD_FILE(status, data); 705a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy DEBUGFS_ADD_FILE(interrupt, data); 706f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy DEBUGFS_ADD_FILE(qos, data); 707a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy#ifdef CONFIG_IWLWIFI_LEDS 708a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy DEBUGFS_ADD_FILE(led, data); 709a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy#endif 710fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy DEBUGFS_ADD_FILE(thermal_throttling, data); 711445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 712445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 713445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler &priv->disable_chain_noise_cal); 714030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || 715030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945)) 716030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy DEBUGFS_ADD_BOOL(disable_tx_power, rf, 717030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy &priv->disable_tx_power_cal); 718712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return 0; 719712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 720712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklererr: 72115b1687cb4f45b87ddbe4dfc7759ff5bb69497d2Winkler, Tomas IWL_ERR(priv, "Can't open the debugfs directory\n"); 722712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler iwl_dbgfs_unregister(priv); 7233ac7f14694dd38273d9d96f1c873233d71190c15Tomas Winkler return ret; 724712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 725712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerEXPORT_SYMBOL(iwl_dbgfs_register); 726712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 727712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler/** 728712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * Remove the debugfs files and directories 729712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler * 730712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler */ 731712b6cf57a53da608a682b5f782c5785bda76001Tomas Winklervoid iwl_dbgfs_unregister(struct iwl_priv *priv) 732712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler{ 7333ac7f14694dd38273d9d96f1c873233d71190c15Tomas Winkler if (!priv->dbgfs) 734712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler return; 735712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 7360848e297c2107dbc12a91a1709c879c73bd188d8Wey-Yi Guy DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm); 737712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics); 738712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics); 739712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); 740189a2b5942d62bd18e1e01772c4c784253f5dd16Ester Kummer DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); 741712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); 742d366df5abb8d5ce7e2c36d3b678177787ccd9749Winkler, Tomas DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels); 74308df05aa9b25f3079585855506022bb33a011183Wey-Yi Guy DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status); 744a83b9141b540f96dd59409c6487828e880113a29Wey-Yi Guy DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt); 745f5ad69fa47e7b204d0032d569812544cd9a351fbWey-Yi Guy DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos); 746a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy#ifdef CONFIG_IWLWIFI_LEDS 747a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led); 748a283c0116b0cc5e82327e50ad4d05f6d4d42c603Wey-Yi Guy#endif 749fbf3a2af3834e8e93e9c2876de62c5b49988e352Wey-Yi Guy DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling); 750712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_REMOVE(priv->dbgfs->dir_data); 751445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); 752445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); 753030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || 754030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945)) 755030b865520c3e26f4a316852aa022a22c4948907Wey-Yi Guy DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power); 756445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler DEBUGFS_REMOVE(priv->dbgfs->dir_rf); 757712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler DEBUGFS_REMOVE(priv->dbgfs->dir_drv); 758712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler kfree(priv->dbgfs); 759712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler priv->dbgfs = NULL; 760712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler} 761712b6cf57a53da608a682b5f782c5785bda76001Tomas WinklerEXPORT_SYMBOL(iwl_dbgfs_unregister); 762712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 763712b6cf57a53da608a682b5f782c5785bda76001Tomas Winkler 764445c2dff409ef9de5d2f964d20917ab238fd266fTomas Winkler 765