blob: 928bdbb00085a12856e66d748fd0587e1c3ec71b [file] [log] [blame]
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
28#include <linux/ieee80211.h>
29#include <net/mac80211.h>
30
Stanislaw Gruszka98613be2011-11-15 14:19:34 +010031#include "common.h"
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080032
33/* create and remove of files */
34#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +020035 if (!debugfs_create_file(#name, mode, parent, il, \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020036 &il_dbgfs_##name##_ops)) \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080037 goto err; \
38} while (0)
39
40#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
41 struct dentry *__tmp; \
42 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
43 parent, ptr); \
44 if (IS_ERR(__tmp) || !__tmp) \
45 goto err; \
46} while (0)
47
48#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
49 struct dentry *__tmp; \
50 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
51 parent, ptr); \
52 if (IS_ERR(__tmp) || !__tmp) \
53 goto err; \
54} while (0)
55
56/* file operation */
57#define DEBUGFS_READ_FUNC(name) \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020058static ssize_t il_dbgfs_##name##_read(struct file *file, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080059 char __user *user_buf, \
60 size_t count, loff_t *ppos);
61
62#define DEBUGFS_WRITE_FUNC(name) \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020063static ssize_t il_dbgfs_##name##_write(struct file *file, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080064 const char __user *user_buf, \
65 size_t count, loff_t *ppos);
66
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080067static int
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020068il_dbgfs_open_file_generic(struct inode *inode, struct file *file)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080069{
70 file->private_data = inode->i_private;
71 return 0;
72}
73
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010074#define DEBUGFS_READ_FILE_OPS(name) \
75 DEBUGFS_READ_FUNC(name); \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020076static const struct file_operations il_dbgfs_##name##_ops = { \
77 .read = il_dbgfs_##name##_read, \
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010078 .open = il_dbgfs_open_file_generic, \
79 .llseek = generic_file_llseek, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080080};
81
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010082#define DEBUGFS_WRITE_FILE_OPS(name) \
83 DEBUGFS_WRITE_FUNC(name); \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020084static const struct file_operations il_dbgfs_##name##_ops = { \
85 .write = il_dbgfs_##name##_write, \
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010086 .open = il_dbgfs_open_file_generic, \
87 .llseek = generic_file_llseek, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080088};
89
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010090#define DEBUGFS_READ_WRITE_FILE_OPS(name) \
91 DEBUGFS_READ_FUNC(name); \
92 DEBUGFS_WRITE_FUNC(name); \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020093static const struct file_operations il_dbgfs_##name##_ops = { \
94 .write = il_dbgfs_##name##_write, \
95 .read = il_dbgfs_##name##_read, \
96 .open = il_dbgfs_open_file_generic, \
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010097 .llseek = generic_file_llseek, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080098};
99
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100100static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100101il_dbgfs_tx_stats_read(struct file *file, char __user *user_buf, size_t count,
102 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100103{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800104
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200105 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800106 char *buf;
107 int pos = 0;
108
109 int cnt;
110 ssize_t ret;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100111 const size_t bufsz =
112 100 + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800113 buf = kzalloc(bufsz, GFP_KERNEL);
114 if (!buf)
115 return -ENOMEM;
116 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
117 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100118 pos +=
119 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
120 il_get_mgmt_string(cnt), il->tx_stats.mgmt[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800121 }
122 pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
123 for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100124 pos +=
125 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
126 il_get_ctrl_string(cnt), il->tx_stats.ctrl[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800127 }
128 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100129 pos +=
130 scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
131 il->tx_stats.data_cnt);
132 pos +=
133 scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
134 il->tx_stats.data_bytes);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800135 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
136 kfree(buf);
137 return ret;
138}
139
140static ssize_t
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200141il_dbgfs_clear_traffic_stats_write(struct file *file,
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100142 const char __user *user_buf, size_t count,
143 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800144{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200145 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800146 u32 clear_flag;
147 char buf[8];
148 int buf_size;
149
150 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100151 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800152 if (copy_from_user(buf, user_buf, buf_size))
153 return -EFAULT;
154 if (sscanf(buf, "%x", &clear_flag) != 1)
155 return -EFAULT;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200156 il_clear_traffic_stats(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800157
158 return count;
159}
160
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100161static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100162il_dbgfs_rx_stats_read(struct file *file, char __user *user_buf, size_t count,
163 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100164{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800165
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200166 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800167 char *buf;
168 int pos = 0;
169 int cnt;
170 ssize_t ret;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100171 const size_t bufsz =
172 100 + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800173 buf = kzalloc(bufsz, GFP_KERNEL);
174 if (!buf)
175 return -ENOMEM;
176
177 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
178 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100179 pos +=
180 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
181 il_get_mgmt_string(cnt), il->rx_stats.mgmt[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800182 }
183 pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
184 for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100185 pos +=
186 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
187 il_get_ctrl_string(cnt), il->rx_stats.ctrl[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800188 }
189 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100190 pos +=
191 scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
192 il->rx_stats.data_cnt);
193 pos +=
194 scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
195 il->rx_stats.data_bytes);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800196
197 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
198 kfree(buf);
199 return ret;
200}
201
202#define BYTE1_MASK 0x000000ff;
203#define BYTE2_MASK 0x0000ffff;
204#define BYTE3_MASK 0x00ffffff;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100205static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100206il_dbgfs_sram_read(struct file *file, char __user *user_buf, size_t count,
207 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800208{
209 u32 val;
210 char *buf;
211 ssize_t ret;
212 int i;
213 int pos = 0;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200214 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800215 size_t bufsz;
216
217 /* default is to dump the entire data segment */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200218 if (!il->dbgfs_sram_offset && !il->dbgfs_sram_len) {
219 il->dbgfs_sram_offset = 0x800000;
220 if (il->ucode_type == UCODE_INIT)
221 il->dbgfs_sram_len = il->ucode_init_data.len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800222 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200223 il->dbgfs_sram_len = il->ucode_data.len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800224 }
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100225 bufsz = 30 + il->dbgfs_sram_len * sizeof(char) * 10;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800226 buf = kmalloc(bufsz, GFP_KERNEL);
227 if (!buf)
228 return -ENOMEM;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100229 pos +=
230 scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
231 il->dbgfs_sram_len);
232 pos +=
233 scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
234 il->dbgfs_sram_offset);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200235 for (i = il->dbgfs_sram_len; i > 0; i -= 4) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100236 val =
237 il_read_targ_mem(il,
238 il->dbgfs_sram_offset +
239 il->dbgfs_sram_len - i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800240 if (i < 4) {
241 switch (i) {
242 case 1:
243 val &= BYTE1_MASK;
244 break;
245 case 2:
246 val &= BYTE2_MASK;
247 break;
248 case 3:
249 val &= BYTE3_MASK;
250 break;
251 }
252 }
253 if (!(i % 16))
254 pos += scnprintf(buf + pos, bufsz - pos, "\n");
255 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
256 }
257 pos += scnprintf(buf + pos, bufsz - pos, "\n");
258
259 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
260 kfree(buf);
261 return ret;
262}
263
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100264static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100265il_dbgfs_sram_write(struct file *file, const char __user *user_buf,
266 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800267{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200268 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800269 char buf[64];
270 int buf_size;
271 u32 offset, len;
272
273 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100274 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800275 if (copy_from_user(buf, user_buf, buf_size))
276 return -EFAULT;
277
278 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200279 il->dbgfs_sram_offset = offset;
280 il->dbgfs_sram_len = len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800281 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200282 il->dbgfs_sram_offset = 0;
283 il->dbgfs_sram_len = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800284 }
285
286 return count;
287}
288
289static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100290il_dbgfs_stations_read(struct file *file, char __user *user_buf, size_t count,
291 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800292{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200293 struct il_priv *il = file->private_data;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200294 struct il_station_entry *station;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200295 int max_sta = il->hw_params.max_stations;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800296 char *buf;
297 int i, j, pos = 0;
298 ssize_t ret;
299 /* Add 30 for initial string */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200300 const size_t bufsz = 30 + sizeof(char) * 500 * (il->num_stations);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800301
302 buf = kmalloc(bufsz, GFP_KERNEL);
303 if (!buf)
304 return -ENOMEM;
305
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100306 pos +=
307 scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
308 il->num_stations);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800309
310 for (i = 0; i < max_sta; i++) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200311 station = &il->stations[i];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800312 if (!station->used)
313 continue;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100314 pos +=
315 scnprintf(buf + pos, bufsz - pos,
316 "station %d - addr: %pM, flags: %#x\n", i,
317 station->sta.sta.addr,
318 station->sta.station_flags_msk);
319 pos +=
320 scnprintf(buf + pos, bufsz - pos,
321 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
322 pos +=
323 scnprintf(buf + pos, bufsz - pos,
324 "start_idx\tbitmap\t\t\trate_n_flags\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800325
326 for (j = 0; j < MAX_TID_COUNT; j++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100327 pos +=
328 scnprintf(buf + pos, bufsz - pos,
329 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
330 j, station->tid[j].seq_number,
331 station->tid[j].agg.txq_id,
332 station->tid[j].agg.frame_count,
333 station->tid[j].tfds_in_queue,
334 station->tid[j].agg.start_idx,
335 station->tid[j].agg.bitmap,
336 station->tid[j].agg.rate_n_flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800337
338 if (station->tid[j].agg.wait_for_ba)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100339 pos +=
340 scnprintf(buf + pos, bufsz - pos,
341 " - waitforba");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800342 pos += scnprintf(buf + pos, bufsz - pos, "\n");
343 }
344
345 pos += scnprintf(buf + pos, bufsz - pos, "\n");
346 }
347
348 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
349 kfree(buf);
350 return ret;
351}
352
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100353static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100354il_dbgfs_nvm_read(struct file *file, char __user *user_buf, size_t count,
355 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800356{
357 ssize_t ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200358 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800359 int pos = 0, ofs = 0, buf_size = 0;
360 const u8 *ptr;
361 char *buf;
362 u16 eeprom_ver;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200363 size_t eeprom_len = il->cfg->base_params->eeprom_size;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800364 buf_size = 4 * eeprom_len + 256;
365
366 if (eeprom_len % 16) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200367 IL_ERR("NVM size is not multiple of 16.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800368 return -ENODATA;
369 }
370
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200371 ptr = il->eeprom;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800372 if (!ptr) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200373 IL_ERR("Invalid EEPROM memory\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800374 return -ENOMEM;
375 }
376
377 /* 4 characters for byte 0xYY */
378 buf = kzalloc(buf_size, GFP_KERNEL);
379 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200380 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800381 return -ENOMEM;
382 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200383 eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION);
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100384 pos +=
385 scnprintf(buf + pos, buf_size - pos, "EEPROM " "version: 0x%x\n",
386 eeprom_ver);
387 for (ofs = 0; ofs < eeprom_len; ofs += 16) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800388 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100389 hex_dump_to_buffer(ptr + ofs, 16, 16, 2, buf + pos,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800390 buf_size - pos, 0);
391 pos += strlen(buf + pos);
392 if (buf_size - pos > 0)
393 buf[pos++] = '\n';
394 }
395
396 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
397 kfree(buf);
398 return ret;
399}
400
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800401static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100402il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
403 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800404{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200405 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800406 struct ieee80211_channel *channels = NULL;
407 const struct ieee80211_supported_band *supp_band = NULL;
408 int pos = 0, i, bufsz = PAGE_SIZE;
409 char *buf;
410 ssize_t ret;
411
Stanislaw Gruszkaa6766cc2011-11-15 13:09:01 +0100412 if (!test_bit(S_GEO_CONFIGURED, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800413 return -EAGAIN;
414
415 buf = kzalloc(bufsz, GFP_KERNEL);
416 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200417 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800418 return -ENOMEM;
419 }
420
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200421 supp_band = il_get_hw_mode(il, IEEE80211_BAND_2GHZ);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800422 if (supp_band) {
423 channels = supp_band->channels;
424
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100425 pos +=
426 scnprintf(buf + pos, bufsz - pos,
427 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
428 supp_band->n_channels);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800429
430 for (i = 0; i < supp_band->n_channels; i++)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100431 pos +=
432 scnprintf(buf + pos, bufsz - pos,
433 "%d: %ddBm: BSS%s%s, %s.\n",
434 channels[i].hw_value,
435 channels[i].max_power,
436 channels[i].
437 flags & IEEE80211_CHAN_RADAR ?
438 " (IEEE 802.11h required)" : "",
439 ((channels[i].
440 flags & IEEE80211_CHAN_NO_IBSS) ||
441 (channels[i].
442 flags & IEEE80211_CHAN_RADAR)) ? "" :
443 ", IBSS",
444 channels[i].
445 flags & IEEE80211_CHAN_PASSIVE_SCAN ?
446 "passive only" : "active/passive");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800447 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200448 supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800449 if (supp_band) {
450 channels = supp_band->channels;
451
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100452 pos +=
453 scnprintf(buf + pos, bufsz - pos,
454 "Displaying %d channels in 5.2GHz band (802.11a)\n",
455 supp_band->n_channels);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800456
457 for (i = 0; i < supp_band->n_channels; i++)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100458 pos +=
459 scnprintf(buf + pos, bufsz - pos,
460 "%d: %ddBm: BSS%s%s, %s.\n",
461 channels[i].hw_value,
462 channels[i].max_power,
463 channels[i].
464 flags & IEEE80211_CHAN_RADAR ?
465 " (IEEE 802.11h required)" : "",
466 ((channels[i].
467 flags & IEEE80211_CHAN_NO_IBSS) ||
468 (channels[i].
469 flags & IEEE80211_CHAN_RADAR)) ? "" :
470 ", IBSS",
471 channels[i].
472 flags & IEEE80211_CHAN_PASSIVE_SCAN ?
473 "passive only" : "active/passive");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800474 }
475 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
476 kfree(buf);
477 return ret;
478}
479
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100480static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100481il_dbgfs_status_read(struct file *file, char __user *user_buf, size_t count,
482 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100483{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800484
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200485 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800486 char buf[512];
487 int pos = 0;
488 const size_t bufsz = sizeof(buf);
489
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100490 pos +=
491 scnprintf(buf + pos, bufsz - pos, "S_HCMD_ACTIVE:\t %d\n",
492 test_bit(S_HCMD_ACTIVE, &il->status));
493 pos +=
494 scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n",
495 test_bit(S_INT_ENABLED, &il->status));
496 pos +=
497 scnprintf(buf + pos, bufsz - pos, "S_RF_KILL_HW:\t %d\n",
498 test_bit(S_RF_KILL_HW, &il->status));
499 pos +=
500 scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n",
501 test_bit(S_CT_KILL, &il->status));
502 pos +=
503 scnprintf(buf + pos, bufsz - pos, "S_INIT:\t\t %d\n",
504 test_bit(S_INIT, &il->status));
505 pos +=
506 scnprintf(buf + pos, bufsz - pos, "S_ALIVE:\t\t %d\n",
507 test_bit(S_ALIVE, &il->status));
508 pos +=
509 scnprintf(buf + pos, bufsz - pos, "S_READY:\t\t %d\n",
510 test_bit(S_READY, &il->status));
511 pos +=
512 scnprintf(buf + pos, bufsz - pos, "S_TEMPERATURE:\t %d\n",
513 test_bit(S_TEMPERATURE, &il->status));
514 pos +=
515 scnprintf(buf + pos, bufsz - pos, "S_GEO_CONFIGURED:\t %d\n",
516 test_bit(S_GEO_CONFIGURED, &il->status));
517 pos +=
518 scnprintf(buf + pos, bufsz - pos, "S_EXIT_PENDING:\t %d\n",
519 test_bit(S_EXIT_PENDING, &il->status));
520 pos +=
521 scnprintf(buf + pos, bufsz - pos, "S_STATS:\t %d\n",
522 test_bit(S_STATS, &il->status));
523 pos +=
524 scnprintf(buf + pos, bufsz - pos, "S_SCANNING:\t %d\n",
525 test_bit(S_SCANNING, &il->status));
526 pos +=
527 scnprintf(buf + pos, bufsz - pos, "S_SCAN_ABORTING:\t %d\n",
528 test_bit(S_SCAN_ABORTING, &il->status));
529 pos +=
530 scnprintf(buf + pos, bufsz - pos, "S_SCAN_HW:\t\t %d\n",
531 test_bit(S_SCAN_HW, &il->status));
532 pos +=
533 scnprintf(buf + pos, bufsz - pos, "S_POWER_PMI:\t %d\n",
534 test_bit(S_POWER_PMI, &il->status));
535 pos +=
536 scnprintf(buf + pos, bufsz - pos, "S_FW_ERROR:\t %d\n",
537 test_bit(S_FW_ERROR, &il->status));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800538 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
539}
540
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100541static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100542il_dbgfs_interrupt_read(struct file *file, char __user *user_buf, size_t count,
543 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100544{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800545
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200546 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800547 int pos = 0;
548 int cnt = 0;
549 char *buf;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100550 int bufsz = 24 * 64; /* 24 items * 64 char per item */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800551 ssize_t ret;
552
553 buf = kzalloc(bufsz, GFP_KERNEL);
554 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200555 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800556 return -ENOMEM;
557 }
558
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100559 pos +=
560 scnprintf(buf + pos, bufsz - pos, "Interrupt Statistics Report:\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800561
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100562 pos +=
563 scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
564 il->isr_stats.hw);
565 pos +=
566 scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
567 il->isr_stats.sw);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200568 if (il->isr_stats.sw || il->isr_stats.hw) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100569 pos +=
570 scnprintf(buf + pos, bufsz - pos,
571 "\tLast Restarting Code: 0x%X\n",
572 il->isr_stats.err_code);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800573 }
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100574#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100575 pos +=
576 scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
577 il->isr_stats.sch);
578 pos +=
579 scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
580 il->isr_stats.alive);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800581#endif
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100582 pos +=
583 scnprintf(buf + pos, bufsz - pos,
584 "HW RF KILL switch toggled:\t %u\n",
585 il->isr_stats.rfkill);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800586
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100587 pos +=
588 scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
589 il->isr_stats.ctkill);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800590
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100591 pos +=
592 scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
593 il->isr_stats.wakeup);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800594
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100595 pos +=
596 scnprintf(buf + pos, bufsz - pos, "Rx command responses:\t\t %u\n",
597 il->isr_stats.rx);
Stanislaw Gruszka4d69c752011-08-30 15:26:35 +0200598 for (cnt = 0; cnt < IL_CN_MAX; cnt++) {
Stanislaw Gruszkad0c72342011-08-30 15:39:42 +0200599 if (il->isr_stats.handlers[cnt] > 0)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100600 pos +=
601 scnprintf(buf + pos, bufsz - pos,
602 "\tRx handler[%36s]:\t\t %u\n",
603 il_get_cmd_string(cnt),
604 il->isr_stats.handlers[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800605 }
606
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100607 pos +=
608 scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
609 il->isr_stats.tx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800610
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100611 pos +=
612 scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
613 il->isr_stats.unhandled);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800614
615 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
616 kfree(buf);
617 return ret;
618}
619
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100620static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100621il_dbgfs_interrupt_write(struct file *file, const char __user *user_buf,
622 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800623{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200624 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800625 char buf[8];
626 int buf_size;
627 u32 reset_flag;
628
629 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100630 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800631 if (copy_from_user(buf, user_buf, buf_size))
632 return -EFAULT;
633 if (sscanf(buf, "%x", &reset_flag) != 1)
634 return -EFAULT;
635 if (reset_flag == 0)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200636 il_clear_isr_stats(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800637
638 return count;
639}
640
641static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100642il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count,
643 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800644{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200645 struct il_priv *il = file->private_data;
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200646 struct il_rxon_context *ctx = &il->ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800647 int pos = 0, i;
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +0100648 char buf[256];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800649 const size_t bufsz = sizeof(buf);
650
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100651 pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n", ctx->ctxid);
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200652 for (i = 0; i < AC_NUM; i++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100653 pos +=
654 scnprintf(buf + pos, bufsz - pos,
655 "\tcw_min\tcw_max\taifsn\ttxop\n");
656 pos +=
657 scnprintf(buf + pos, bufsz - pos,
658 "AC[%d]\t%u\t%u\t%u\t%u\n", i,
659 ctx->qos_data.def_qos_parm.ac[i].cw_min,
660 ctx->qos_data.def_qos_parm.ac[i].cw_max,
661 ctx->qos_data.def_qos_parm.ac[i].aifsn,
662 ctx->qos_data.def_qos_parm.ac[i].edca_txop);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800663 }
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200664
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800665 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
666}
667
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100668static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100669il_dbgfs_disable_ht40_write(struct file *file, const char __user *user_buf,
670 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800671{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200672 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800673 char buf[8];
674 int buf_size;
675 int ht40;
676
677 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100678 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800679 if (copy_from_user(buf, user_buf, buf_size))
680 return -EFAULT;
681 if (sscanf(buf, "%d", &ht40) != 1)
682 return -EFAULT;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200683 if (!il_is_any_associated(il))
684 il->disable_ht40 = ht40 ? true : false;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800685 else {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200686 IL_ERR("Sta associated with AP - "
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100687 "Change to 40MHz channel support is not allowed\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800688 return -EINVAL;
689 }
690
691 return count;
692}
693
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100694static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100695il_dbgfs_disable_ht40_read(struct file *file, char __user *user_buf,
696 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800697{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200698 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800699 char buf[100];
700 int pos = 0;
701 const size_t bufsz = sizeof(buf);
702
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100703 pos +=
704 scnprintf(buf + pos, bufsz - pos, "11n 40MHz Mode: %s\n",
705 il->disable_ht40 ? "Disabled" : "Enabled");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800706 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
707}
708
709DEBUGFS_READ_WRITE_FILE_OPS(sram);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800710DEBUGFS_READ_FILE_OPS(nvm);
711DEBUGFS_READ_FILE_OPS(stations);
712DEBUGFS_READ_FILE_OPS(channels);
713DEBUGFS_READ_FILE_OPS(status);
714DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
715DEBUGFS_READ_FILE_OPS(qos);
716DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
717
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100718static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100719il_dbgfs_traffic_log_read(struct file *file, char __user *user_buf,
720 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800721{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200722 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800723 int pos = 0, ofs = 0;
724 int cnt = 0, entry;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200725 struct il_tx_queue *txq;
726 struct il_queue *q;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200727 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800728 char *buf;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100729 int bufsz =
730 ((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
731 (il->cfg->base_params->num_of_queues * 32 * 8) + 400;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800732 const u8 *ptr;
733 ssize_t ret;
734
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200735 if (!il->txq) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200736 IL_ERR("txq not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800737 return -EAGAIN;
738 }
739 buf = kzalloc(bufsz, GFP_KERNEL);
740 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200741 IL_ERR("Can not allocate buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800742 return -ENOMEM;
743 }
744 pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200745 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
746 txq = &il->txq[cnt];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800747 q = &txq->q;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100748 pos +=
749 scnprintf(buf + pos, bufsz - pos,
750 "q[%d]: read_ptr: %u, write_ptr: %u\n", cnt,
751 q->read_ptr, q->write_ptr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800752 }
Stanislaw Gruszkad2ddf6212011-08-16 14:17:04 +0200753 if (il->tx_traffic && (il_debug_level & IL_DL_TX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200754 ptr = il->tx_traffic;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100755 pos +=
756 scnprintf(buf + pos, bufsz - pos, "Tx Traffic idx: %u\n",
757 il->tx_traffic_idx);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200758 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
759 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100760 entry++, ofs += 16) {
761 pos +=
762 scnprintf(buf + pos, bufsz - pos, "0x%.4x ",
763 ofs);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800764 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
765 buf + pos, bufsz - pos, 0);
766 pos += strlen(buf + pos);
767 if (bufsz - pos > 0)
768 buf[pos++] = '\n';
769 }
770 }
771 }
772
773 pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100774 pos +=
775 scnprintf(buf + pos, bufsz - pos, "read: %u, write: %u\n",
776 rxq->read, rxq->write);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800777
Stanislaw Gruszkad2ddf6212011-08-16 14:17:04 +0200778 if (il->rx_traffic && (il_debug_level & IL_DL_RX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200779 ptr = il->rx_traffic;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100780 pos +=
781 scnprintf(buf + pos, bufsz - pos, "Rx Traffic idx: %u\n",
782 il->rx_traffic_idx);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200783 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
784 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100785 entry++, ofs += 16) {
786 pos +=
787 scnprintf(buf + pos, bufsz - pos, "0x%.4x ",
788 ofs);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800789 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
790 buf + pos, bufsz - pos, 0);
791 pos += strlen(buf + pos);
792 if (bufsz - pos > 0)
793 buf[pos++] = '\n';
794 }
795 }
796 }
797
798 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
799 kfree(buf);
800 return ret;
801}
802
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100803static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100804il_dbgfs_traffic_log_write(struct file *file, const char __user *user_buf,
805 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800806{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200807 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800808 char buf[8];
809 int buf_size;
810 int traffic_log;
811
812 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100813 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800814 if (copy_from_user(buf, user_buf, buf_size))
815 return -EFAULT;
816 if (sscanf(buf, "%d", &traffic_log) != 1)
817 return -EFAULT;
818 if (traffic_log == 0)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200819 il_reset_traffic_log(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800820
821 return count;
822}
823
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100824static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100825il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,
826 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100827{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800828
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200829 struct il_priv *il = file->private_data;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200830 struct il_tx_queue *txq;
831 struct il_queue *q;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800832 char *buf;
833 int pos = 0;
834 int cnt;
835 int ret;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100836 const size_t bufsz =
837 sizeof(char) * 64 * il->cfg->base_params->num_of_queues;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800838
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200839 if (!il->txq) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200840 IL_ERR("txq not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800841 return -EAGAIN;
842 }
843 buf = kzalloc(bufsz, GFP_KERNEL);
844 if (!buf)
845 return -ENOMEM;
846
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200847 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
848 txq = &il->txq[cnt];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800849 q = &txq->q;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100850 pos +=
851 scnprintf(buf + pos, bufsz - pos,
852 "hwq %.2d: read=%u write=%u stop=%d"
853 " swq_id=%#.2x (ac %d/hwq %d)\n", cnt,
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100854 q->read_ptr, q->write_ptr,
855 !!test_bit(cnt, il->queue_stopped),
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100856 txq->swq_id, txq->swq_id & 3,
857 (txq->swq_id >> 2) & 0x1f);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800858 if (cnt >= 4)
859 continue;
860 /* for the ACs, display the stop count too */
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100861 pos +=
862 scnprintf(buf + pos, bufsz - pos,
863 " stop-count: %d\n",
864 atomic_read(&il->queue_stop_count[cnt]));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800865 }
866 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
867 kfree(buf);
868 return ret;
869}
870
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100871static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100872il_dbgfs_rx_queue_read(struct file *file, char __user *user_buf, size_t count,
873 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100874{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800875
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200876 struct il_priv *il = file->private_data;
877 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800878 char buf[256];
879 int pos = 0;
880 const size_t bufsz = sizeof(buf);
881
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100882 pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n", rxq->read);
883 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", rxq->write);
884 pos +=
885 scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
886 rxq->free_count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800887 if (rxq->rb_stts) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100888 pos +=
889 scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
890 le16_to_cpu(rxq->rb_stts->
891 closed_rb_num) & 0x0FFF);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800892 } else {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100893 pos +=
894 scnprintf(buf + pos, bufsz - pos,
895 "closed_rb_num: Not Allocated\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800896 }
897 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
898}
899
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100900static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100901il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf,
902 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800903{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200904 struct il_priv *il = file->private_data;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100905 return il->cfg->ops->lib->debugfs_ops.rx_stats_read(file, user_buf,
906 count, ppos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800907}
908
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100909static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100910il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf,
911 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800912{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200913 struct il_priv *il = file->private_data;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100914 return il->cfg->ops->lib->debugfs_ops.tx_stats_read(file, user_buf,
915 count, ppos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800916}
917
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100918static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100919il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf,
920 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800921{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200922 struct il_priv *il = file->private_data;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100923 return il->cfg->ops->lib->debugfs_ops.general_stats_read(file, user_buf,
924 count, ppos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800925}
926
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100927static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100928il_dbgfs_sensitivity_read(struct file *file, char __user *user_buf,
929 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100930{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800931
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200932 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800933 int pos = 0;
934 int cnt = 0;
935 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200936 int bufsz = sizeof(struct il_sensitivity_data) * 4 + 100;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800937 ssize_t ret;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200938 struct il_sensitivity_data *data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800939
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200940 data = &il->sensitivity_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800941 buf = kzalloc(bufsz, GFP_KERNEL);
942 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200943 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800944 return -ENOMEM;
945 }
946
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100947 pos +=
948 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
949 data->auto_corr_ofdm);
950 pos +=
951 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc:\t\t %u\n",
952 data->auto_corr_ofdm_mrc);
953 pos +=
954 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
955 data->auto_corr_ofdm_x1);
956 pos +=
957 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc_x1:\t\t %u\n",
958 data->auto_corr_ofdm_mrc_x1);
959 pos +=
960 scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
961 data->auto_corr_cck);
962 pos +=
963 scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
964 data->auto_corr_cck_mrc);
965 pos +=
966 scnprintf(buf + pos, bufsz - pos,
967 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
968 data->last_bad_plcp_cnt_ofdm);
969 pos +=
970 scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
971 data->last_fa_cnt_ofdm);
972 pos +=
973 scnprintf(buf + pos, bufsz - pos, "last_bad_plcp_cnt_cck:\t\t %u\n",
974 data->last_bad_plcp_cnt_cck);
975 pos +=
976 scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
977 data->last_fa_cnt_cck);
978 pos +=
979 scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
980 data->nrg_curr_state);
981 pos +=
982 scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
983 data->nrg_prev_state);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800984 pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
985 for (cnt = 0; cnt < 10; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100986 pos +=
987 scnprintf(buf + pos, bufsz - pos, " %u",
988 data->nrg_value[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800989 }
990 pos += scnprintf(buf + pos, bufsz - pos, "\n");
991 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
992 for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100993 pos +=
994 scnprintf(buf + pos, bufsz - pos, " %u",
995 data->nrg_silence_rssi[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800996 }
997 pos += scnprintf(buf + pos, bufsz - pos, "\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100998 pos +=
999 scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
1000 data->nrg_silence_ref);
1001 pos +=
1002 scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
1003 data->nrg_energy_idx);
1004 pos +=
1005 scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
1006 data->nrg_silence_idx);
1007 pos +=
1008 scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
1009 data->nrg_th_cck);
1010 pos +=
1011 scnprintf(buf + pos, bufsz - pos,
1012 "nrg_auto_corr_silence_diff:\t %u\n",
1013 data->nrg_auto_corr_silence_diff);
1014 pos +=
1015 scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
1016 data->num_in_cck_no_fa);
1017 pos +=
1018 scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
1019 data->nrg_th_ofdm);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001020
1021 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1022 kfree(buf);
1023 return ret;
1024}
1025
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001026static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001027il_dbgfs_chain_noise_read(struct file *file, char __user *user_buf,
1028 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001029{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001030
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001031 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001032 int pos = 0;
1033 int cnt = 0;
1034 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001035 int bufsz = sizeof(struct il_chain_noise_data) * 4 + 100;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001036 ssize_t ret;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001037 struct il_chain_noise_data *data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001038
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001039 data = &il->chain_noise_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001040 buf = kzalloc(bufsz, GFP_KERNEL);
1041 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001042 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001043 return -ENOMEM;
1044 }
1045
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001046 pos +=
1047 scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
1048 data->active_chains);
1049 pos +=
1050 scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
1051 data->chain_noise_a);
1052 pos +=
1053 scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
1054 data->chain_noise_b);
1055 pos +=
1056 scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
1057 data->chain_noise_c);
1058 pos +=
1059 scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
1060 data->chain_signal_a);
1061 pos +=
1062 scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
1063 data->chain_signal_b);
1064 pos +=
1065 scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
1066 data->chain_signal_c);
1067 pos +=
1068 scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
1069 data->beacon_count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001070
1071 pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
1072 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001073 pos +=
1074 scnprintf(buf + pos, bufsz - pos, " %u",
1075 data->disconn_array[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001076 }
1077 pos += scnprintf(buf + pos, bufsz - pos, "\n");
1078 pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
1079 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001080 pos +=
1081 scnprintf(buf + pos, bufsz - pos, " %u",
1082 data->delta_gain_code[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001083 }
1084 pos += scnprintf(buf + pos, bufsz - pos, "\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001085 pos +=
1086 scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
1087 data->radio_write);
1088 pos +=
1089 scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
1090 data->state);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001091
1092 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1093 kfree(buf);
1094 return ret;
1095}
1096
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001097static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001098il_dbgfs_power_save_status_read(struct file *file, char __user *user_buf,
1099 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001100{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001101 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001102 char buf[60];
1103 int pos = 0;
1104 const size_t bufsz = sizeof(buf);
1105 u32 pwrsave_status;
1106
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001107 pwrsave_status =
1108 _il_rd(il, CSR_GP_CNTRL) & CSR_GP_REG_POWER_SAVE_STATUS_MSK;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001109
1110 pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001111 pos +=
1112 scnprintf(buf + pos, bufsz - pos, "%s\n",
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001113 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1114 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1115 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1116 "error");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001117
1118 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1119}
1120
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001121static ssize_t
1122il_dbgfs_clear_ucode_stats_write(struct file *file,
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001123 const char __user *user_buf, size_t count,
1124 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001125{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001126 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001127 char buf[8];
1128 int buf_size;
1129 int clear;
1130
1131 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001132 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001133 if (copy_from_user(buf, user_buf, buf_size))
1134 return -EFAULT;
1135 if (sscanf(buf, "%d", &clear) != 1)
1136 return -EFAULT;
1137
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001138 /* make request to uCode to retrieve stats information */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001139 mutex_lock(&il->mutex);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001140 il_send_stats_request(il, CMD_SYNC, true);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001141 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001142
1143 return count;
1144}
1145
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001146static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001147il_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf,
1148 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001149{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001150
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001151 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001152 int len = 0;
1153 char buf[20];
1154
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001155 len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.flags));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001156 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1157}
1158
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001159static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001160il_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf,
1161 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001162{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001163
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001164 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001165 int len = 0;
1166 char buf[20];
1167
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001168 len =
1169 sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.filter_flags));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001170 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1171}
1172
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001173static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001174il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count,
1175 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001176{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001177 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001178 char *buf;
1179 int pos = 0;
1180 ssize_t ret = -EFAULT;
1181
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001182 if (il->cfg->ops->lib->dump_fh) {
1183 ret = pos = il->cfg->ops->lib->dump_fh(il, &buf, true);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001184 if (buf) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001185 ret =
1186 simple_read_from_buffer(user_buf, count, ppos, buf,
1187 pos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001188 kfree(buf);
1189 }
1190 }
1191
1192 return ret;
1193}
1194
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001195static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001196il_dbgfs_missed_beacon_read(struct file *file, char __user *user_buf,
1197 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001198{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001199
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001200 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001201 int pos = 0;
1202 char buf[12];
1203 const size_t bufsz = sizeof(buf);
1204
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001205 pos +=
1206 scnprintf(buf + pos, bufsz - pos, "%d\n",
1207 il->missed_beacon_threshold);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001208
1209 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1210}
1211
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001212static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001213il_dbgfs_missed_beacon_write(struct file *file, const char __user *user_buf,
1214 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001215{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001216 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001217 char buf[8];
1218 int buf_size;
1219 int missed;
1220
1221 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001222 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001223 if (copy_from_user(buf, user_buf, buf_size))
1224 return -EFAULT;
1225 if (sscanf(buf, "%d", &missed) != 1)
1226 return -EINVAL;
1227
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001228 if (missed < IL_MISSED_BEACON_THRESHOLD_MIN ||
1229 missed > IL_MISSED_BEACON_THRESHOLD_MAX)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001230 il->missed_beacon_threshold = IL_MISSED_BEACON_THRESHOLD_DEF;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001231 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001232 il->missed_beacon_threshold = missed;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001233
1234 return count;
1235}
1236
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001237static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001238il_dbgfs_force_reset_read(struct file *file, char __user *user_buf,
1239 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001240{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001241
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001242 struct il_priv *il = file->private_data;
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001243 int pos = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001244 char buf[300];
1245 const size_t bufsz = sizeof(buf);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001246 struct il_force_reset *force_reset;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001247
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001248 force_reset = &il->force_reset;
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001249
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001250 pos +=
1251 scnprintf(buf + pos, bufsz - pos, "\tnumber of reset request: %d\n",
1252 force_reset->reset_request_count);
1253 pos +=
1254 scnprintf(buf + pos, bufsz - pos,
1255 "\tnumber of reset request success: %d\n",
1256 force_reset->reset_success_count);
1257 pos +=
1258 scnprintf(buf + pos, bufsz - pos,
1259 "\tnumber of reset request reject: %d\n",
1260 force_reset->reset_reject_count);
1261 pos +=
1262 scnprintf(buf + pos, bufsz - pos, "\treset duration: %lu\n",
1263 force_reset->reset_duration);
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001264
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001265 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1266}
1267
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001268static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001269il_dbgfs_force_reset_write(struct file *file, const char __user *user_buf,
1270 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001271{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001272
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001273 int ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001274 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001275
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001276 ret = il_force_reset(il, true);
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001277
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001278 return ret ? ret : count;
1279}
1280
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001281static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001282il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf,
1283 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001284{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001285
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001286 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001287 char buf[8];
1288 int buf_size;
1289 int timeout;
1290
1291 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001292 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001293 if (copy_from_user(buf, user_buf, buf_size))
1294 return -EFAULT;
1295 if (sscanf(buf, "%d", &timeout) != 1)
1296 return -EINVAL;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001297 if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)
1298 timeout = IL_DEF_WD_TIMEOUT;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001299
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001300 il->cfg->base_params->wd_timeout = timeout;
1301 il_setup_watchdog(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001302 return count;
1303}
1304
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001305DEBUGFS_READ_FILE_OPS(rx_stats);
1306DEBUGFS_READ_FILE_OPS(tx_stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001307DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
1308DEBUGFS_READ_FILE_OPS(rx_queue);
1309DEBUGFS_READ_FILE_OPS(tx_queue);
1310DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1311DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1312DEBUGFS_READ_FILE_OPS(ucode_general_stats);
1313DEBUGFS_READ_FILE_OPS(sensitivity);
1314DEBUGFS_READ_FILE_OPS(chain_noise);
1315DEBUGFS_READ_FILE_OPS(power_save_status);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001316DEBUGFS_WRITE_FILE_OPS(clear_ucode_stats);
1317DEBUGFS_WRITE_FILE_OPS(clear_traffic_stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001318DEBUGFS_READ_FILE_OPS(fh_reg);
1319DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001320DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1321DEBUGFS_READ_FILE_OPS(rxon_flags);
1322DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
1323DEBUGFS_WRITE_FILE_OPS(wd_timeout);
1324
1325/*
1326 * Create the debugfs files and directories
1327 *
1328 */
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001329int
1330il_dbgfs_register(struct il_priv *il, const char *name)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001331{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001332 struct dentry *phyd = il->hw->wiphy->debugfsdir;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001333 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1334
1335 dir_drv = debugfs_create_dir(name, phyd);
1336 if (!dir_drv)
1337 return -ENOMEM;
1338
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001339 il->debugfs_dir = dir_drv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001340
1341 dir_data = debugfs_create_dir("data", dir_drv);
1342 if (!dir_data)
1343 goto err;
1344 dir_rf = debugfs_create_dir("rf", dir_drv);
1345 if (!dir_rf)
1346 goto err;
1347 dir_debug = debugfs_create_dir("debug", dir_drv);
1348 if (!dir_debug)
1349 goto err;
1350
1351 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1352 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001353 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1354 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1355 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1356 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1357 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1358 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001359 DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR);
1360 DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001361 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
1362 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
1363 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
1364 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001365 DEBUGFS_ADD_FILE(clear_ucode_stats, dir_debug, S_IWUSR);
1366 DEBUGFS_ADD_FILE(clear_traffic_stats, dir_debug, S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001367 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
1368 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001369 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
1370 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1371 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1372 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
1373
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001374 if (il->cfg->base_params->sensitivity_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001375 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001376 if (il->cfg->base_params->chain_noise_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001377 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001378 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
1379 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
1380 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001381 if (il->cfg->base_params->sensitivity_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001382 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001383 &il->disable_sens_cal);
1384 if (il->cfg->base_params->chain_noise_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001385 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001386 &il->disable_chain_noise_cal);
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001387 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &il->disable_tx_power_cal);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001388 return 0;
1389
1390err:
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001391 IL_ERR("Can't create the debugfs directory\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001392 il_dbgfs_unregister(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001393 return -ENOMEM;
1394}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001395EXPORT_SYMBOL(il_dbgfs_register);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001396
1397/**
1398 * Remove the debugfs files and directories
1399 *
1400 */
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001401void
1402il_dbgfs_unregister(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001403{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001404 if (!il->debugfs_dir)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001405 return;
1406
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001407 debugfs_remove_recursive(il->debugfs_dir);
1408 il->debugfs_dir = NULL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001409}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001410EXPORT_SYMBOL(il_dbgfs_unregister);