blob: 62292a68567df692eec43e351b9aa49a8419dcc3 [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
31
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080032#include "iwl-debug.h"
Stanislaw Gruszka98613be2011-11-15 14:19:34 +010033#include "common.h"
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080034
35/* create and remove of files */
36#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +020037 if (!debugfs_create_file(#name, mode, parent, il, \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020038 &il_dbgfs_##name##_ops)) \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080039 goto err; \
40} while (0)
41
42#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
43 struct dentry *__tmp; \
44 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
45 parent, ptr); \
46 if (IS_ERR(__tmp) || !__tmp) \
47 goto err; \
48} while (0)
49
50#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
51 struct dentry *__tmp; \
52 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
53 parent, ptr); \
54 if (IS_ERR(__tmp) || !__tmp) \
55 goto err; \
56} while (0)
57
58/* file operation */
59#define DEBUGFS_READ_FUNC(name) \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020060static ssize_t il_dbgfs_##name##_read(struct file *file, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080061 char __user *user_buf, \
62 size_t count, loff_t *ppos);
63
64#define DEBUGFS_WRITE_FUNC(name) \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020065static ssize_t il_dbgfs_##name##_write(struct file *file, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080066 const char __user *user_buf, \
67 size_t count, loff_t *ppos);
68
69
70static int
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020071il_dbgfs_open_file_generic(struct inode *inode, struct file *file)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080072{
73 file->private_data = inode->i_private;
74 return 0;
75}
76
77#define DEBUGFS_READ_FILE_OPS(name) \
78 DEBUGFS_READ_FUNC(name); \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020079static const struct file_operations il_dbgfs_##name##_ops = { \
80 .read = il_dbgfs_##name##_read, \
81 .open = il_dbgfs_open_file_generic, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080082 .llseek = generic_file_llseek, \
83};
84
85#define DEBUGFS_WRITE_FILE_OPS(name) \
86 DEBUGFS_WRITE_FUNC(name); \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020087static const struct file_operations il_dbgfs_##name##_ops = { \
88 .write = il_dbgfs_##name##_write, \
89 .open = il_dbgfs_open_file_generic, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080090 .llseek = generic_file_llseek, \
91};
92
93#define DEBUGFS_READ_WRITE_FILE_OPS(name) \
94 DEBUGFS_READ_FUNC(name); \
95 DEBUGFS_WRITE_FUNC(name); \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020096static const struct file_operations il_dbgfs_##name##_ops = { \
97 .write = il_dbgfs_##name##_write, \
98 .read = il_dbgfs_##name##_read, \
99 .open = il_dbgfs_open_file_generic, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800100 .llseek = generic_file_llseek, \
101};
102
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200103static ssize_t il_dbgfs_tx_stats_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800104 char __user *user_buf,
105 size_t count, loff_t *ppos) {
106
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200107 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800108 char *buf;
109 int pos = 0;
110
111 int cnt;
112 ssize_t ret;
113 const size_t bufsz = 100 +
114 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
115 buf = kzalloc(bufsz, GFP_KERNEL);
116 if (!buf)
117 return -ENOMEM;
118 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
119 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
120 pos += scnprintf(buf + pos, bufsz - pos,
121 "\t%25s\t\t: %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200122 il_get_mgmt_string(cnt),
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200123 il->tx_stats.mgmt[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800124 }
125 pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
126 for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
127 pos += scnprintf(buf + pos, bufsz - pos,
128 "\t%25s\t\t: %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200129 il_get_ctrl_string(cnt),
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200130 il->tx_stats.ctrl[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800131 }
132 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
133 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200134 il->tx_stats.data_cnt);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800135 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200136 il->tx_stats.data_bytes);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800137 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
138 kfree(buf);
139 return ret;
140}
141
142static ssize_t
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200143il_dbgfs_clear_traffic_stats_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800144 const char __user *user_buf,
145 size_t count, loff_t *ppos)
146{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200147 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800148 u32 clear_flag;
149 char buf[8];
150 int buf_size;
151
152 memset(buf, 0, sizeof(buf));
153 buf_size = min(count, sizeof(buf) - 1);
154 if (copy_from_user(buf, user_buf, buf_size))
155 return -EFAULT;
156 if (sscanf(buf, "%x", &clear_flag) != 1)
157 return -EFAULT;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200158 il_clear_traffic_stats(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800159
160 return count;
161}
162
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200163static ssize_t il_dbgfs_rx_stats_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800164 char __user *user_buf,
165 size_t count, loff_t *ppos) {
166
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200167 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800168 char *buf;
169 int pos = 0;
170 int cnt;
171 ssize_t ret;
172 const size_t bufsz = 100 +
173 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
174 buf = kzalloc(bufsz, GFP_KERNEL);
175 if (!buf)
176 return -ENOMEM;
177
178 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
179 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
180 pos += scnprintf(buf + pos, bufsz - pos,
181 "\t%25s\t\t: %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200182 il_get_mgmt_string(cnt),
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200183 il->rx_stats.mgmt[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800184 }
185 pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
186 for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
187 pos += scnprintf(buf + pos, bufsz - pos,
188 "\t%25s\t\t: %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200189 il_get_ctrl_string(cnt),
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200190 il->rx_stats.ctrl[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800191 }
192 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
193 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200194 il->rx_stats.data_cnt);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800195 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200196 il->rx_stats.data_bytes);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800197
198 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
199 kfree(buf);
200 return ret;
201}
202
203#define BYTE1_MASK 0x000000ff;
204#define BYTE2_MASK 0x0000ffff;
205#define BYTE3_MASK 0x00ffffff;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200206static ssize_t il_dbgfs_sram_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800207 char __user *user_buf,
208 size_t count, loff_t *ppos)
209{
210 u32 val;
211 char *buf;
212 ssize_t ret;
213 int i;
214 int pos = 0;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200215 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800216 size_t bufsz;
217
218 /* default is to dump the entire data segment */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200219 if (!il->dbgfs_sram_offset && !il->dbgfs_sram_len) {
220 il->dbgfs_sram_offset = 0x800000;
221 if (il->ucode_type == UCODE_INIT)
222 il->dbgfs_sram_len = il->ucode_init_data.len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800223 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200224 il->dbgfs_sram_len = il->ucode_data.len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800225 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200226 bufsz = 30 + il->dbgfs_sram_len * sizeof(char) * 10;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800227 buf = kmalloc(bufsz, GFP_KERNEL);
228 if (!buf)
229 return -ENOMEM;
230 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200231 il->dbgfs_sram_len);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800232 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200233 il->dbgfs_sram_offset);
234 for (i = il->dbgfs_sram_len; i > 0; i -= 4) {
235 val = il_read_targ_mem(il, il->dbgfs_sram_offset + \
236 il->dbgfs_sram_len - i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800237 if (i < 4) {
238 switch (i) {
239 case 1:
240 val &= BYTE1_MASK;
241 break;
242 case 2:
243 val &= BYTE2_MASK;
244 break;
245 case 3:
246 val &= BYTE3_MASK;
247 break;
248 }
249 }
250 if (!(i % 16))
251 pos += scnprintf(buf + pos, bufsz - pos, "\n");
252 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
253 }
254 pos += scnprintf(buf + pos, bufsz - pos, "\n");
255
256 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
257 kfree(buf);
258 return ret;
259}
260
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200261static ssize_t il_dbgfs_sram_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800262 const char __user *user_buf,
263 size_t count, loff_t *ppos)
264{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200265 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800266 char buf[64];
267 int buf_size;
268 u32 offset, len;
269
270 memset(buf, 0, sizeof(buf));
271 buf_size = min(count, sizeof(buf) - 1);
272 if (copy_from_user(buf, user_buf, buf_size))
273 return -EFAULT;
274
275 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200276 il->dbgfs_sram_offset = offset;
277 il->dbgfs_sram_len = len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800278 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200279 il->dbgfs_sram_offset = 0;
280 il->dbgfs_sram_len = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800281 }
282
283 return count;
284}
285
286static ssize_t
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200287il_dbgfs_stations_read(struct file *file, char __user *user_buf,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800288 size_t count, loff_t *ppos)
289{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200290 struct il_priv *il = file->private_data;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200291 struct il_station_entry *station;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200292 int max_sta = il->hw_params.max_stations;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800293 char *buf;
294 int i, j, pos = 0;
295 ssize_t ret;
296 /* Add 30 for initial string */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200297 const size_t bufsz = 30 + sizeof(char) * 500 * (il->num_stations);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800298
299 buf = kmalloc(bufsz, GFP_KERNEL);
300 if (!buf)
301 return -ENOMEM;
302
303 pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200304 il->num_stations);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800305
306 for (i = 0; i < max_sta; i++) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200307 station = &il->stations[i];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800308 if (!station->used)
309 continue;
310 pos += scnprintf(buf + pos, bufsz - pos,
311 "station %d - addr: %pM, flags: %#x\n",
312 i, station->sta.sta.addr,
313 station->sta.station_flags_msk);
314 pos += scnprintf(buf + pos, bufsz - pos,
315 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
316 pos += scnprintf(buf + pos, bufsz - pos,
317 "start_idx\tbitmap\t\t\trate_n_flags\n");
318
319 for (j = 0; j < MAX_TID_COUNT; j++) {
320 pos += scnprintf(buf + pos, bufsz - pos,
321 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
322 j, station->tid[j].seq_number,
323 station->tid[j].agg.txq_id,
324 station->tid[j].agg.frame_count,
325 station->tid[j].tfds_in_queue,
326 station->tid[j].agg.start_idx,
327 station->tid[j].agg.bitmap,
328 station->tid[j].agg.rate_n_flags);
329
330 if (station->tid[j].agg.wait_for_ba)
331 pos += scnprintf(buf + pos, bufsz - pos,
332 " - waitforba");
333 pos += scnprintf(buf + pos, bufsz - pos, "\n");
334 }
335
336 pos += scnprintf(buf + pos, bufsz - pos, "\n");
337 }
338
339 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
340 kfree(buf);
341 return ret;
342}
343
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200344static ssize_t il_dbgfs_nvm_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800345 char __user *user_buf,
346 size_t count,
347 loff_t *ppos)
348{
349 ssize_t ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200350 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800351 int pos = 0, ofs = 0, buf_size = 0;
352 const u8 *ptr;
353 char *buf;
354 u16 eeprom_ver;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200355 size_t eeprom_len = il->cfg->base_params->eeprom_size;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800356 buf_size = 4 * eeprom_len + 256;
357
358 if (eeprom_len % 16) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200359 IL_ERR("NVM size is not multiple of 16.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800360 return -ENODATA;
361 }
362
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200363 ptr = il->eeprom;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800364 if (!ptr) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200365 IL_ERR("Invalid EEPROM memory\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800366 return -ENOMEM;
367 }
368
369 /* 4 characters for byte 0xYY */
370 buf = kzalloc(buf_size, GFP_KERNEL);
371 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200372 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800373 return -ENOMEM;
374 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200375 eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800376 pos += scnprintf(buf + pos, buf_size - pos, "EEPROM "
377 "version: 0x%x\n", eeprom_ver);
378 for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
379 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
380 hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
381 buf_size - pos, 0);
382 pos += strlen(buf + pos);
383 if (buf_size - pos > 0)
384 buf[pos++] = '\n';
385 }
386
387 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
388 kfree(buf);
389 return ret;
390}
391
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800392static ssize_t
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200393il_dbgfs_channels_read(struct file *file, char __user *user_buf,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800394 size_t count, loff_t *ppos)
395{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200396 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800397 struct ieee80211_channel *channels = NULL;
398 const struct ieee80211_supported_band *supp_band = NULL;
399 int pos = 0, i, bufsz = PAGE_SIZE;
400 char *buf;
401 ssize_t ret;
402
Stanislaw Gruszkaa6766cc2011-11-15 13:09:01 +0100403 if (!test_bit(S_GEO_CONFIGURED, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800404 return -EAGAIN;
405
406 buf = kzalloc(bufsz, GFP_KERNEL);
407 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200408 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800409 return -ENOMEM;
410 }
411
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200412 supp_band = il_get_hw_mode(il, IEEE80211_BAND_2GHZ);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800413 if (supp_band) {
414 channels = supp_band->channels;
415
416 pos += scnprintf(buf + pos, bufsz - pos,
417 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
418 supp_band->n_channels);
419
420 for (i = 0; i < supp_band->n_channels; i++)
421 pos += scnprintf(buf + pos, bufsz - pos,
422 "%d: %ddBm: BSS%s%s, %s.\n",
423 channels[i].hw_value,
424 channels[i].max_power,
425 channels[i].flags & IEEE80211_CHAN_RADAR ?
426 " (IEEE 802.11h required)" : "",
427 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
428 || (channels[i].flags &
429 IEEE80211_CHAN_RADAR)) ? "" :
430 ", IBSS",
431 channels[i].flags &
432 IEEE80211_CHAN_PASSIVE_SCAN ?
433 "passive only" : "active/passive");
434 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200435 supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800436 if (supp_band) {
437 channels = supp_band->channels;
438
439 pos += scnprintf(buf + pos, bufsz - pos,
440 "Displaying %d channels in 5.2GHz band (802.11a)\n",
441 supp_band->n_channels);
442
443 for (i = 0; i < supp_band->n_channels; i++)
444 pos += scnprintf(buf + pos, bufsz - pos,
445 "%d: %ddBm: BSS%s%s, %s.\n",
446 channels[i].hw_value,
447 channels[i].max_power,
448 channels[i].flags & IEEE80211_CHAN_RADAR ?
449 " (IEEE 802.11h required)" : "",
450 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
451 || (channels[i].flags &
452 IEEE80211_CHAN_RADAR)) ? "" :
453 ", IBSS",
454 channels[i].flags &
455 IEEE80211_CHAN_PASSIVE_SCAN ?
456 "passive only" : "active/passive");
457 }
458 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
459 kfree(buf);
460 return ret;
461}
462
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200463static ssize_t il_dbgfs_status_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800464 char __user *user_buf,
465 size_t count, loff_t *ppos) {
466
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200467 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800468 char buf[512];
469 int pos = 0;
470 const size_t bufsz = sizeof(buf);
471
Stanislaw Gruszkaa6766cc2011-11-15 13:09:01 +0100472 pos += scnprintf(buf + pos, bufsz - pos, "S_HCMD_ACTIVE:\t %d\n",
473 test_bit(S_HCMD_ACTIVE, &il->status));
474 pos += scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n",
475 test_bit(S_INT_ENABLED, &il->status));
476 pos += scnprintf(buf + pos, bufsz - pos, "S_RF_KILL_HW:\t %d\n",
477 test_bit(S_RF_KILL_HW, &il->status));
478 pos += scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n",
479 test_bit(S_CT_KILL, &il->status));
480 pos += scnprintf(buf + pos, bufsz - pos, "S_INIT:\t\t %d\n",
481 test_bit(S_INIT, &il->status));
482 pos += scnprintf(buf + pos, bufsz - pos, "S_ALIVE:\t\t %d\n",
483 test_bit(S_ALIVE, &il->status));
484 pos += scnprintf(buf + pos, bufsz - pos, "S_READY:\t\t %d\n",
485 test_bit(S_READY, &il->status));
486 pos += scnprintf(buf + pos, bufsz - pos, "S_TEMPERATURE:\t %d\n",
487 test_bit(S_TEMPERATURE, &il->status));
488 pos += scnprintf(buf + pos, bufsz - pos, "S_GEO_CONFIGURED:\t %d\n",
489 test_bit(S_GEO_CONFIGURED, &il->status));
490 pos += scnprintf(buf + pos, bufsz - pos, "S_EXIT_PENDING:\t %d\n",
491 test_bit(S_EXIT_PENDING, &il->status));
Stanislaw Gruszkadb7746f2011-11-15 13:11:50 +0100492 pos += scnprintf(buf + pos, bufsz - pos, "S_STATS:\t %d\n",
493 test_bit(S_STATS, &il->status));
Stanislaw Gruszkaa6766cc2011-11-15 13:09:01 +0100494 pos += scnprintf(buf + pos, bufsz - pos, "S_SCANNING:\t %d\n",
495 test_bit(S_SCANNING, &il->status));
496 pos += scnprintf(buf + pos, bufsz - pos, "S_SCAN_ABORTING:\t %d\n",
497 test_bit(S_SCAN_ABORTING, &il->status));
498 pos += scnprintf(buf + pos, bufsz - pos, "S_SCAN_HW:\t\t %d\n",
499 test_bit(S_SCAN_HW, &il->status));
500 pos += scnprintf(buf + pos, bufsz - pos, "S_POWER_PMI:\t %d\n",
501 test_bit(S_POWER_PMI, &il->status));
502 pos += scnprintf(buf + pos, bufsz - pos, "S_FW_ERROR:\t %d\n",
503 test_bit(S_FW_ERROR, &il->status));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800504 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
505}
506
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200507static ssize_t il_dbgfs_interrupt_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800508 char __user *user_buf,
509 size_t count, loff_t *ppos) {
510
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200511 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800512 int pos = 0;
513 int cnt = 0;
514 char *buf;
515 int bufsz = 24 * 64; /* 24 items * 64 char per item */
516 ssize_t ret;
517
518 buf = kzalloc(bufsz, GFP_KERNEL);
519 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200520 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800521 return -ENOMEM;
522 }
523
524 pos += scnprintf(buf + pos, bufsz - pos,
525 "Interrupt Statistics Report:\n");
526
527 pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200528 il->isr_stats.hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800529 pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200530 il->isr_stats.sw);
531 if (il->isr_stats.sw || il->isr_stats.hw) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800532 pos += scnprintf(buf + pos, bufsz - pos,
533 "\tLast Restarting Code: 0x%X\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200534 il->isr_stats.err_code);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800535 }
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100536#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800537 pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200538 il->isr_stats.sch);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800539 pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200540 il->isr_stats.alive);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800541#endif
542 pos += scnprintf(buf + pos, bufsz - pos,
543 "HW RF KILL switch toggled:\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200544 il->isr_stats.rfkill);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800545
546 pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200547 il->isr_stats.ctkill);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800548
549 pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200550 il->isr_stats.wakeup);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800551
552 pos += scnprintf(buf + pos, bufsz - pos,
553 "Rx command responses:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200554 il->isr_stats.rx);
Stanislaw Gruszka4d69c752011-08-30 15:26:35 +0200555 for (cnt = 0; cnt < IL_CN_MAX; cnt++) {
Stanislaw Gruszkad0c72342011-08-30 15:39:42 +0200556 if (il->isr_stats.handlers[cnt] > 0)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800557 pos += scnprintf(buf + pos, bufsz - pos,
558 "\tRx handler[%36s]:\t\t %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200559 il_get_cmd_string(cnt),
Stanislaw Gruszkad0c72342011-08-30 15:39:42 +0200560 il->isr_stats.handlers[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800561 }
562
563 pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200564 il->isr_stats.tx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800565
566 pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200567 il->isr_stats.unhandled);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800568
569 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
570 kfree(buf);
571 return ret;
572}
573
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200574static ssize_t il_dbgfs_interrupt_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800575 const char __user *user_buf,
576 size_t count, loff_t *ppos)
577{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200578 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800579 char buf[8];
580 int buf_size;
581 u32 reset_flag;
582
583 memset(buf, 0, sizeof(buf));
584 buf_size = min(count, sizeof(buf) - 1);
585 if (copy_from_user(buf, user_buf, buf_size))
586 return -EFAULT;
587 if (sscanf(buf, "%x", &reset_flag) != 1)
588 return -EFAULT;
589 if (reset_flag == 0)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200590 il_clear_isr_stats(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800591
592 return count;
593}
594
595static ssize_t
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200596il_dbgfs_qos_read(struct file *file, char __user *user_buf,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800597 size_t count, loff_t *ppos)
598{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200599 struct il_priv *il = file->private_data;
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200600 struct il_rxon_context *ctx = &il->ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800601 int pos = 0, i;
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +0100602 char buf[256];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800603 const size_t bufsz = sizeof(buf);
604
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200605 pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n",
606 ctx->ctxid);
607 for (i = 0; i < AC_NUM; i++) {
608 pos += scnprintf(buf + pos, bufsz - pos,
609 "\tcw_min\tcw_max\taifsn\ttxop\n");
610 pos += scnprintf(buf + pos, bufsz - pos,
611 "AC[%d]\t%u\t%u\t%u\t%u\n", i,
612 ctx->qos_data.def_qos_parm.ac[i].cw_min,
613 ctx->qos_data.def_qos_parm.ac[i].cw_max,
614 ctx->qos_data.def_qos_parm.ac[i].aifsn,
615 ctx->qos_data.def_qos_parm.ac[i].edca_txop);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800616 }
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200617
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800618 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
619}
620
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200621static ssize_t il_dbgfs_disable_ht40_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800622 const char __user *user_buf,
623 size_t count, loff_t *ppos)
624{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200625 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800626 char buf[8];
627 int buf_size;
628 int ht40;
629
630 memset(buf, 0, sizeof(buf));
631 buf_size = min(count, sizeof(buf) - 1);
632 if (copy_from_user(buf, user_buf, buf_size))
633 return -EFAULT;
634 if (sscanf(buf, "%d", &ht40) != 1)
635 return -EFAULT;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200636 if (!il_is_any_associated(il))
637 il->disable_ht40 = ht40 ? true : false;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800638 else {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200639 IL_ERR("Sta associated with AP - "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800640 "Change to 40MHz channel support is not allowed\n");
641 return -EINVAL;
642 }
643
644 return count;
645}
646
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200647static ssize_t il_dbgfs_disable_ht40_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800648 char __user *user_buf,
649 size_t count, loff_t *ppos)
650{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200651 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800652 char buf[100];
653 int pos = 0;
654 const size_t bufsz = sizeof(buf);
655
656 pos += scnprintf(buf + pos, bufsz - pos,
657 "11n 40MHz Mode: %s\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200658 il->disable_ht40 ? "Disabled" : "Enabled");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800659 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
660}
661
662DEBUGFS_READ_WRITE_FILE_OPS(sram);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800663DEBUGFS_READ_FILE_OPS(nvm);
664DEBUGFS_READ_FILE_OPS(stations);
665DEBUGFS_READ_FILE_OPS(channels);
666DEBUGFS_READ_FILE_OPS(status);
667DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
668DEBUGFS_READ_FILE_OPS(qos);
669DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
670
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200671static ssize_t il_dbgfs_traffic_log_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800672 char __user *user_buf,
673 size_t count, loff_t *ppos)
674{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200675 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800676 int pos = 0, ofs = 0;
677 int cnt = 0, entry;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200678 struct il_tx_queue *txq;
679 struct il_queue *q;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200680 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800681 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200682 int bufsz = ((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200683 (il->cfg->base_params->num_of_queues * 32 * 8) + 400;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800684 const u8 *ptr;
685 ssize_t ret;
686
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200687 if (!il->txq) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200688 IL_ERR("txq not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800689 return -EAGAIN;
690 }
691 buf = kzalloc(bufsz, GFP_KERNEL);
692 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200693 IL_ERR("Can not allocate buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800694 return -ENOMEM;
695 }
696 pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200697 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
698 txq = &il->txq[cnt];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800699 q = &txq->q;
700 pos += scnprintf(buf + pos, bufsz - pos,
701 "q[%d]: read_ptr: %u, write_ptr: %u\n",
702 cnt, q->read_ptr, q->write_ptr);
703 }
Stanislaw Gruszkad2ddf622011-08-16 14:17:04 +0200704 if (il->tx_traffic && (il_debug_level & IL_DL_TX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200705 ptr = il->tx_traffic;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800706 pos += scnprintf(buf + pos, bufsz - pos,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200707 "Tx Traffic idx: %u\n", il->tx_traffic_idx);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200708 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
709 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800710 entry++, ofs += 16) {
711 pos += scnprintf(buf + pos, bufsz - pos,
712 "0x%.4x ", ofs);
713 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
714 buf + pos, bufsz - pos, 0);
715 pos += strlen(buf + pos);
716 if (bufsz - pos > 0)
717 buf[pos++] = '\n';
718 }
719 }
720 }
721
722 pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
723 pos += scnprintf(buf + pos, bufsz - pos,
724 "read: %u, write: %u\n",
725 rxq->read, rxq->write);
726
Stanislaw Gruszkad2ddf622011-08-16 14:17:04 +0200727 if (il->rx_traffic && (il_debug_level & IL_DL_RX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200728 ptr = il->rx_traffic;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800729 pos += scnprintf(buf + pos, bufsz - pos,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200730 "Rx Traffic idx: %u\n", il->rx_traffic_idx);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200731 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
732 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800733 entry++, ofs += 16) {
734 pos += scnprintf(buf + pos, bufsz - pos,
735 "0x%.4x ", ofs);
736 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
737 buf + pos, bufsz - pos, 0);
738 pos += strlen(buf + pos);
739 if (bufsz - pos > 0)
740 buf[pos++] = '\n';
741 }
742 }
743 }
744
745 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
746 kfree(buf);
747 return ret;
748}
749
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200750static ssize_t il_dbgfs_traffic_log_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800751 const char __user *user_buf,
752 size_t count, loff_t *ppos)
753{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200754 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800755 char buf[8];
756 int buf_size;
757 int traffic_log;
758
759 memset(buf, 0, sizeof(buf));
760 buf_size = min(count, sizeof(buf) - 1);
761 if (copy_from_user(buf, user_buf, buf_size))
762 return -EFAULT;
763 if (sscanf(buf, "%d", &traffic_log) != 1)
764 return -EFAULT;
765 if (traffic_log == 0)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200766 il_reset_traffic_log(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800767
768 return count;
769}
770
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200771static ssize_t il_dbgfs_tx_queue_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800772 char __user *user_buf,
773 size_t count, loff_t *ppos) {
774
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200775 struct il_priv *il = file->private_data;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200776 struct il_tx_queue *txq;
777 struct il_queue *q;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800778 char *buf;
779 int pos = 0;
780 int cnt;
781 int ret;
782 const size_t bufsz = sizeof(char) * 64 *
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200783 il->cfg->base_params->num_of_queues;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800784
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200785 if (!il->txq) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200786 IL_ERR("txq not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800787 return -EAGAIN;
788 }
789 buf = kzalloc(bufsz, GFP_KERNEL);
790 if (!buf)
791 return -ENOMEM;
792
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200793 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
794 txq = &il->txq[cnt];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800795 q = &txq->q;
796 pos += scnprintf(buf + pos, bufsz - pos,
797 "hwq %.2d: read=%u write=%u stop=%d"
798 " swq_id=%#.2x (ac %d/hwq %d)\n",
799 cnt, q->read_ptr, q->write_ptr,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200800 !!test_bit(cnt, il->queue_stopped),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800801 txq->swq_id, txq->swq_id & 3,
802 (txq->swq_id >> 2) & 0x1f);
803 if (cnt >= 4)
804 continue;
805 /* for the ACs, display the stop count too */
806 pos += scnprintf(buf + pos, bufsz - pos,
807 " stop-count: %d\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200808 atomic_read(&il->queue_stop_count[cnt]));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800809 }
810 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
811 kfree(buf);
812 return ret;
813}
814
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200815static ssize_t il_dbgfs_rx_queue_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800816 char __user *user_buf,
817 size_t count, loff_t *ppos) {
818
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200819 struct il_priv *il = file->private_data;
820 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800821 char buf[256];
822 int pos = 0;
823 const size_t bufsz = sizeof(buf);
824
825 pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
826 rxq->read);
827 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
828 rxq->write);
829 pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
830 rxq->free_count);
831 if (rxq->rb_stts) {
832 pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
833 le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF);
834 } else {
835 pos += scnprintf(buf + pos, bufsz - pos,
836 "closed_rb_num: Not Allocated\n");
837 }
838 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
839}
840
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200841static ssize_t il_dbgfs_ucode_rx_stats_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800842 char __user *user_buf,
843 size_t count, loff_t *ppos)
844{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200845 struct il_priv *il = file->private_data;
846 return il->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800847 user_buf, count, ppos);
848}
849
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200850static ssize_t il_dbgfs_ucode_tx_stats_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800851 char __user *user_buf,
852 size_t count, loff_t *ppos)
853{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200854 struct il_priv *il = file->private_data;
855 return il->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800856 user_buf, count, ppos);
857}
858
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200859static ssize_t il_dbgfs_ucode_general_stats_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800860 char __user *user_buf,
861 size_t count, loff_t *ppos)
862{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200863 struct il_priv *il = file->private_data;
864 return il->cfg->ops->lib->debugfs_ops.general_stats_read(file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800865 user_buf, count, ppos);
866}
867
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200868static ssize_t il_dbgfs_sensitivity_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800869 char __user *user_buf,
870 size_t count, loff_t *ppos) {
871
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200872 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800873 int pos = 0;
874 int cnt = 0;
875 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200876 int bufsz = sizeof(struct il_sensitivity_data) * 4 + 100;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800877 ssize_t ret;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200878 struct il_sensitivity_data *data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800879
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200880 data = &il->sensitivity_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800881 buf = kzalloc(bufsz, GFP_KERNEL);
882 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200883 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800884 return -ENOMEM;
885 }
886
887 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
888 data->auto_corr_ofdm);
889 pos += scnprintf(buf + pos, bufsz - pos,
890 "auto_corr_ofdm_mrc:\t\t %u\n",
891 data->auto_corr_ofdm_mrc);
892 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
893 data->auto_corr_ofdm_x1);
894 pos += scnprintf(buf + pos, bufsz - pos,
895 "auto_corr_ofdm_mrc_x1:\t\t %u\n",
896 data->auto_corr_ofdm_mrc_x1);
897 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
898 data->auto_corr_cck);
899 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
900 data->auto_corr_cck_mrc);
901 pos += scnprintf(buf + pos, bufsz - pos,
902 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
903 data->last_bad_plcp_cnt_ofdm);
904 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
905 data->last_fa_cnt_ofdm);
906 pos += scnprintf(buf + pos, bufsz - pos,
907 "last_bad_plcp_cnt_cck:\t\t %u\n",
908 data->last_bad_plcp_cnt_cck);
909 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
910 data->last_fa_cnt_cck);
911 pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
912 data->nrg_curr_state);
913 pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
914 data->nrg_prev_state);
915 pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
916 for (cnt = 0; cnt < 10; cnt++) {
917 pos += scnprintf(buf + pos, bufsz - pos, " %u",
918 data->nrg_value[cnt]);
919 }
920 pos += scnprintf(buf + pos, bufsz - pos, "\n");
921 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
922 for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
923 pos += scnprintf(buf + pos, bufsz - pos, " %u",
924 data->nrg_silence_rssi[cnt]);
925 }
926 pos += scnprintf(buf + pos, bufsz - pos, "\n");
927 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
928 data->nrg_silence_ref);
929 pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
930 data->nrg_energy_idx);
931 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
932 data->nrg_silence_idx);
933 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
934 data->nrg_th_cck);
935 pos += scnprintf(buf + pos, bufsz - pos,
936 "nrg_auto_corr_silence_diff:\t %u\n",
937 data->nrg_auto_corr_silence_diff);
938 pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
939 data->num_in_cck_no_fa);
940 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
941 data->nrg_th_ofdm);
942
943 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
944 kfree(buf);
945 return ret;
946}
947
948
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200949static ssize_t il_dbgfs_chain_noise_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800950 char __user *user_buf,
951 size_t count, loff_t *ppos) {
952
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200953 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800954 int pos = 0;
955 int cnt = 0;
956 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200957 int bufsz = sizeof(struct il_chain_noise_data) * 4 + 100;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800958 ssize_t ret;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200959 struct il_chain_noise_data *data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800960
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200961 data = &il->chain_noise_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800962 buf = kzalloc(bufsz, GFP_KERNEL);
963 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200964 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800965 return -ENOMEM;
966 }
967
968 pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
969 data->active_chains);
970 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
971 data->chain_noise_a);
972 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
973 data->chain_noise_b);
974 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
975 data->chain_noise_c);
976 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
977 data->chain_signal_a);
978 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
979 data->chain_signal_b);
980 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
981 data->chain_signal_c);
982 pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
983 data->beacon_count);
984
985 pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
986 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
987 pos += scnprintf(buf + pos, bufsz - pos, " %u",
988 data->disconn_array[cnt]);
989 }
990 pos += scnprintf(buf + pos, bufsz - pos, "\n");
991 pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
992 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
993 pos += scnprintf(buf + pos, bufsz - pos, " %u",
994 data->delta_gain_code[cnt]);
995 }
996 pos += scnprintf(buf + pos, bufsz - pos, "\n");
997 pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
998 data->radio_write);
999 pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
1000 data->state);
1001
1002 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1003 kfree(buf);
1004 return ret;
1005}
1006
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001007static ssize_t il_dbgfs_power_save_status_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001008 char __user *user_buf,
1009 size_t count, loff_t *ppos)
1010{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001011 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001012 char buf[60];
1013 int pos = 0;
1014 const size_t bufsz = sizeof(buf);
1015 u32 pwrsave_status;
1016
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001017 pwrsave_status = _il_rd(il, CSR_GP_CNTRL) &
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001018 CSR_GP_REG_POWER_SAVE_STATUS_MSK;
1019
1020 pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
1021 pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
1022 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1023 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1024 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1025 "error");
1026
1027 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1028}
1029
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001030static ssize_t il_dbgfs_clear_ucode_stats_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001031 const char __user *user_buf,
1032 size_t count, loff_t *ppos)
1033{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001034 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001035 char buf[8];
1036 int buf_size;
1037 int clear;
1038
1039 memset(buf, 0, sizeof(buf));
1040 buf_size = min(count, sizeof(buf) - 1);
1041 if (copy_from_user(buf, user_buf, buf_size))
1042 return -EFAULT;
1043 if (sscanf(buf, "%d", &clear) != 1)
1044 return -EFAULT;
1045
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001046 /* make request to uCode to retrieve stats information */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001047 mutex_lock(&il->mutex);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001048 il_send_stats_request(il, CMD_SYNC, true);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001049 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001050
1051 return count;
1052}
1053
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001054static ssize_t il_dbgfs_rxon_flags_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001055 char __user *user_buf,
1056 size_t count, loff_t *ppos) {
1057
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001058 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001059 int len = 0;
1060 char buf[20];
1061
1062 len = sprintf(buf, "0x%04X\n",
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01001063 le32_to_cpu(il->ctx.active.flags));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001064 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1065}
1066
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001067static ssize_t il_dbgfs_rxon_filter_flags_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001068 char __user *user_buf,
1069 size_t count, loff_t *ppos) {
1070
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001071 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001072 int len = 0;
1073 char buf[20];
1074
1075 len = sprintf(buf, "0x%04X\n",
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01001076 le32_to_cpu(il->ctx.active.filter_flags));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001077 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1078}
1079
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001080static ssize_t il_dbgfs_fh_reg_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001081 char __user *user_buf,
1082 size_t count, loff_t *ppos)
1083{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001084 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001085 char *buf;
1086 int pos = 0;
1087 ssize_t ret = -EFAULT;
1088
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001089 if (il->cfg->ops->lib->dump_fh) {
1090 ret = pos = il->cfg->ops->lib->dump_fh(il, &buf, true);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001091 if (buf) {
1092 ret = simple_read_from_buffer(user_buf,
1093 count, ppos, buf, pos);
1094 kfree(buf);
1095 }
1096 }
1097
1098 return ret;
1099}
1100
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001101static ssize_t il_dbgfs_missed_beacon_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001102 char __user *user_buf,
1103 size_t count, loff_t *ppos) {
1104
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001105 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001106 int pos = 0;
1107 char buf[12];
1108 const size_t bufsz = sizeof(buf);
1109
1110 pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001111 il->missed_beacon_threshold);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001112
1113 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1114}
1115
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001116static ssize_t il_dbgfs_missed_beacon_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001117 const char __user *user_buf,
1118 size_t count, loff_t *ppos)
1119{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001120 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001121 char buf[8];
1122 int buf_size;
1123 int missed;
1124
1125 memset(buf, 0, sizeof(buf));
1126 buf_size = min(count, sizeof(buf) - 1);
1127 if (copy_from_user(buf, user_buf, buf_size))
1128 return -EFAULT;
1129 if (sscanf(buf, "%d", &missed) != 1)
1130 return -EINVAL;
1131
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001132 if (missed < IL_MISSED_BEACON_THRESHOLD_MIN ||
1133 missed > IL_MISSED_BEACON_THRESHOLD_MAX)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001134 il->missed_beacon_threshold =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001135 IL_MISSED_BEACON_THRESHOLD_DEF;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001136 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001137 il->missed_beacon_threshold = missed;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001138
1139 return count;
1140}
1141
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001142static ssize_t il_dbgfs_force_reset_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001143 char __user *user_buf,
1144 size_t count, loff_t *ppos) {
1145
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001146 struct il_priv *il = file->private_data;
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001147 int pos = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001148 char buf[300];
1149 const size_t bufsz = sizeof(buf);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001150 struct il_force_reset *force_reset;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001151
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001152 force_reset = &il->force_reset;
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001153
1154 pos += scnprintf(buf + pos, bufsz - pos,
1155 "\tnumber of reset request: %d\n",
1156 force_reset->reset_request_count);
1157 pos += scnprintf(buf + pos, bufsz - pos,
1158 "\tnumber of reset request success: %d\n",
1159 force_reset->reset_success_count);
1160 pos += scnprintf(buf + pos, bufsz - pos,
1161 "\tnumber of reset request reject: %d\n",
1162 force_reset->reset_reject_count);
1163 pos += scnprintf(buf + pos, bufsz - pos,
1164 "\treset duration: %lu\n",
1165 force_reset->reset_duration);
1166
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001167 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1168}
1169
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001170static ssize_t il_dbgfs_force_reset_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001171 const char __user *user_buf,
1172 size_t count, loff_t *ppos) {
1173
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001174 int ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001175 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001176
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001177 ret = il_force_reset(il, true);
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001178
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001179 return ret ? ret : count;
1180}
1181
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001182static ssize_t il_dbgfs_wd_timeout_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001183 const char __user *user_buf,
1184 size_t count, loff_t *ppos) {
1185
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001186 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001187 char buf[8];
1188 int buf_size;
1189 int timeout;
1190
1191 memset(buf, 0, sizeof(buf));
1192 buf_size = min(count, sizeof(buf) - 1);
1193 if (copy_from_user(buf, user_buf, buf_size))
1194 return -EFAULT;
1195 if (sscanf(buf, "%d", &timeout) != 1)
1196 return -EINVAL;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001197 if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)
1198 timeout = IL_DEF_WD_TIMEOUT;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001199
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001200 il->cfg->base_params->wd_timeout = timeout;
1201 il_setup_watchdog(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001202 return count;
1203}
1204
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001205DEBUGFS_READ_FILE_OPS(rx_stats);
1206DEBUGFS_READ_FILE_OPS(tx_stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001207DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
1208DEBUGFS_READ_FILE_OPS(rx_queue);
1209DEBUGFS_READ_FILE_OPS(tx_queue);
1210DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1211DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1212DEBUGFS_READ_FILE_OPS(ucode_general_stats);
1213DEBUGFS_READ_FILE_OPS(sensitivity);
1214DEBUGFS_READ_FILE_OPS(chain_noise);
1215DEBUGFS_READ_FILE_OPS(power_save_status);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001216DEBUGFS_WRITE_FILE_OPS(clear_ucode_stats);
1217DEBUGFS_WRITE_FILE_OPS(clear_traffic_stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001218DEBUGFS_READ_FILE_OPS(fh_reg);
1219DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001220DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1221DEBUGFS_READ_FILE_OPS(rxon_flags);
1222DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
1223DEBUGFS_WRITE_FILE_OPS(wd_timeout);
1224
1225/*
1226 * Create the debugfs files and directories
1227 *
1228 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001229int il_dbgfs_register(struct il_priv *il, const char *name)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001230{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001231 struct dentry *phyd = il->hw->wiphy->debugfsdir;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001232 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1233
1234 dir_drv = debugfs_create_dir(name, phyd);
1235 if (!dir_drv)
1236 return -ENOMEM;
1237
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001238 il->debugfs_dir = dir_drv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001239
1240 dir_data = debugfs_create_dir("data", dir_drv);
1241 if (!dir_data)
1242 goto err;
1243 dir_rf = debugfs_create_dir("rf", dir_drv);
1244 if (!dir_rf)
1245 goto err;
1246 dir_debug = debugfs_create_dir("debug", dir_drv);
1247 if (!dir_debug)
1248 goto err;
1249
1250 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1251 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001252 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1253 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1254 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1255 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1256 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1257 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001258 DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR);
1259 DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001260 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
1261 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
1262 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
1263 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001264 DEBUGFS_ADD_FILE(clear_ucode_stats, dir_debug, S_IWUSR);
1265 DEBUGFS_ADD_FILE(clear_traffic_stats, dir_debug, S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001266 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
1267 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001268 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
1269 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1270 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1271 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
1272
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001273 if (il->cfg->base_params->sensitivity_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001274 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001275 if (il->cfg->base_params->chain_noise_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001276 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001277 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
1278 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
1279 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001280 if (il->cfg->base_params->sensitivity_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001281 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001282 &il->disable_sens_cal);
1283 if (il->cfg->base_params->chain_noise_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001284 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001285 &il->disable_chain_noise_cal);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001286 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001287 &il->disable_tx_power_cal);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001288 return 0;
1289
1290err:
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001291 IL_ERR("Can't create the debugfs directory\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001292 il_dbgfs_unregister(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001293 return -ENOMEM;
1294}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001295EXPORT_SYMBOL(il_dbgfs_register);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001296
1297/**
1298 * Remove the debugfs files and directories
1299 *
1300 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001301void il_dbgfs_unregister(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001302{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001303 if (!il->debugfs_dir)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001304 return;
1305
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001306 debugfs_remove_recursive(il->debugfs_dir);
1307 il->debugfs_dir = NULL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001308}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001309EXPORT_SYMBOL(il_dbgfs_unregister);