blob: 4e2b6c80849e673a79226a54ea079ccd62d0e72f [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
67
68static int
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020069il_dbgfs_open_file_generic(struct inode *inode, struct file *file)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080070{
71 file->private_data = inode->i_private;
72 return 0;
73}
74
75#define DEBUGFS_READ_FILE_OPS(name) \
76 DEBUGFS_READ_FUNC(name); \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020077static const struct file_operations il_dbgfs_##name##_ops = { \
78 .read = il_dbgfs_##name##_read, \
79 .open = il_dbgfs_open_file_generic, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080080 .llseek = generic_file_llseek, \
81};
82
83#define DEBUGFS_WRITE_FILE_OPS(name) \
84 DEBUGFS_WRITE_FUNC(name); \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020085static const struct file_operations il_dbgfs_##name##_ops = { \
86 .write = il_dbgfs_##name##_write, \
87 .open = il_dbgfs_open_file_generic, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080088 .llseek = generic_file_llseek, \
89};
90
91#define DEBUGFS_READ_WRITE_FILE_OPS(name) \
92 DEBUGFS_READ_FUNC(name); \
93 DEBUGFS_WRITE_FUNC(name); \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020094static const struct file_operations il_dbgfs_##name##_ops = { \
95 .write = il_dbgfs_##name##_write, \
96 .read = il_dbgfs_##name##_read, \
97 .open = il_dbgfs_open_file_generic, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080098 .llseek = generic_file_llseek, \
99};
100
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200101static ssize_t il_dbgfs_tx_stats_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800102 char __user *user_buf,
103 size_t count, loff_t *ppos) {
104
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;
111 const size_t bufsz = 100 +
112 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
113 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++) {
118 pos += scnprintf(buf + pos, bufsz - pos,
119 "\t%25s\t\t: %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200120 il_get_mgmt_string(cnt),
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200121 il->tx_stats.mgmt[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800122 }
123 pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
124 for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
125 pos += scnprintf(buf + pos, bufsz - pos,
126 "\t%25s\t\t: %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200127 il_get_ctrl_string(cnt),
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200128 il->tx_stats.ctrl[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800129 }
130 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
131 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200132 il->tx_stats.data_cnt);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800133 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200134 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,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800142 const char __user *user_buf,
143 size_t count, loff_t *ppos)
144{
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));
151 buf_size = min(count, sizeof(buf) - 1);
152 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 Gruszkaebf0d902011-08-26 15:43:47 +0200161static ssize_t il_dbgfs_rx_stats_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800162 char __user *user_buf,
163 size_t count, loff_t *ppos) {
164
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200165 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800166 char *buf;
167 int pos = 0;
168 int cnt;
169 ssize_t ret;
170 const size_t bufsz = 100 +
171 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
172 buf = kzalloc(bufsz, GFP_KERNEL);
173 if (!buf)
174 return -ENOMEM;
175
176 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
177 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
178 pos += scnprintf(buf + pos, bufsz - pos,
179 "\t%25s\t\t: %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200180 il_get_mgmt_string(cnt),
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200181 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++) {
185 pos += scnprintf(buf + pos, bufsz - pos,
186 "\t%25s\t\t: %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200187 il_get_ctrl_string(cnt),
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200188 il->rx_stats.ctrl[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800189 }
190 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
191 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200192 il->rx_stats.data_cnt);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800193 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200194 il->rx_stats.data_bytes);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800195
196 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
197 kfree(buf);
198 return ret;
199}
200
201#define BYTE1_MASK 0x000000ff;
202#define BYTE2_MASK 0x0000ffff;
203#define BYTE3_MASK 0x00ffffff;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200204static ssize_t il_dbgfs_sram_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800205 char __user *user_buf,
206 size_t count, loff_t *ppos)
207{
208 u32 val;
209 char *buf;
210 ssize_t ret;
211 int i;
212 int pos = 0;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200213 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800214 size_t bufsz;
215
216 /* default is to dump the entire data segment */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200217 if (!il->dbgfs_sram_offset && !il->dbgfs_sram_len) {
218 il->dbgfs_sram_offset = 0x800000;
219 if (il->ucode_type == UCODE_INIT)
220 il->dbgfs_sram_len = il->ucode_init_data.len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800221 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200222 il->dbgfs_sram_len = il->ucode_data.len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800223 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200224 bufsz = 30 + il->dbgfs_sram_len * sizeof(char) * 10;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800225 buf = kmalloc(bufsz, GFP_KERNEL);
226 if (!buf)
227 return -ENOMEM;
228 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200229 il->dbgfs_sram_len);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800230 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200231 il->dbgfs_sram_offset);
232 for (i = il->dbgfs_sram_len; i > 0; i -= 4) {
233 val = il_read_targ_mem(il, il->dbgfs_sram_offset + \
234 il->dbgfs_sram_len - i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800235 if (i < 4) {
236 switch (i) {
237 case 1:
238 val &= BYTE1_MASK;
239 break;
240 case 2:
241 val &= BYTE2_MASK;
242 break;
243 case 3:
244 val &= BYTE3_MASK;
245 break;
246 }
247 }
248 if (!(i % 16))
249 pos += scnprintf(buf + pos, bufsz - pos, "\n");
250 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
251 }
252 pos += scnprintf(buf + pos, bufsz - pos, "\n");
253
254 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
255 kfree(buf);
256 return ret;
257}
258
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200259static ssize_t il_dbgfs_sram_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800260 const char __user *user_buf,
261 size_t count, loff_t *ppos)
262{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200263 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800264 char buf[64];
265 int buf_size;
266 u32 offset, len;
267
268 memset(buf, 0, sizeof(buf));
269 buf_size = min(count, sizeof(buf) - 1);
270 if (copy_from_user(buf, user_buf, buf_size))
271 return -EFAULT;
272
273 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200274 il->dbgfs_sram_offset = offset;
275 il->dbgfs_sram_len = len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800276 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200277 il->dbgfs_sram_offset = 0;
278 il->dbgfs_sram_len = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800279 }
280
281 return count;
282}
283
284static ssize_t
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200285il_dbgfs_stations_read(struct file *file, char __user *user_buf,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800286 size_t count, loff_t *ppos)
287{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200288 struct il_priv *il = file->private_data;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200289 struct il_station_entry *station;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200290 int max_sta = il->hw_params.max_stations;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800291 char *buf;
292 int i, j, pos = 0;
293 ssize_t ret;
294 /* Add 30 for initial string */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200295 const size_t bufsz = 30 + sizeof(char) * 500 * (il->num_stations);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800296
297 buf = kmalloc(bufsz, GFP_KERNEL);
298 if (!buf)
299 return -ENOMEM;
300
301 pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200302 il->num_stations);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800303
304 for (i = 0; i < max_sta; i++) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200305 station = &il->stations[i];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800306 if (!station->used)
307 continue;
308 pos += scnprintf(buf + pos, bufsz - pos,
309 "station %d - addr: %pM, flags: %#x\n",
310 i, station->sta.sta.addr,
311 station->sta.station_flags_msk);
312 pos += scnprintf(buf + pos, bufsz - pos,
313 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
314 pos += scnprintf(buf + pos, bufsz - pos,
315 "start_idx\tbitmap\t\t\trate_n_flags\n");
316
317 for (j = 0; j < MAX_TID_COUNT; j++) {
318 pos += scnprintf(buf + pos, bufsz - pos,
319 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
320 j, station->tid[j].seq_number,
321 station->tid[j].agg.txq_id,
322 station->tid[j].agg.frame_count,
323 station->tid[j].tfds_in_queue,
324 station->tid[j].agg.start_idx,
325 station->tid[j].agg.bitmap,
326 station->tid[j].agg.rate_n_flags);
327
328 if (station->tid[j].agg.wait_for_ba)
329 pos += scnprintf(buf + pos, bufsz - pos,
330 " - waitforba");
331 pos += scnprintf(buf + pos, bufsz - pos, "\n");
332 }
333
334 pos += scnprintf(buf + pos, bufsz - pos, "\n");
335 }
336
337 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
338 kfree(buf);
339 return ret;
340}
341
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200342static ssize_t il_dbgfs_nvm_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800343 char __user *user_buf,
344 size_t count,
345 loff_t *ppos)
346{
347 ssize_t ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200348 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800349 int pos = 0, ofs = 0, buf_size = 0;
350 const u8 *ptr;
351 char *buf;
352 u16 eeprom_ver;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200353 size_t eeprom_len = il->cfg->base_params->eeprom_size;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800354 buf_size = 4 * eeprom_len + 256;
355
356 if (eeprom_len % 16) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200357 IL_ERR("NVM size is not multiple of 16.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800358 return -ENODATA;
359 }
360
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200361 ptr = il->eeprom;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800362 if (!ptr) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200363 IL_ERR("Invalid EEPROM memory\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800364 return -ENOMEM;
365 }
366
367 /* 4 characters for byte 0xYY */
368 buf = kzalloc(buf_size, GFP_KERNEL);
369 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200370 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800371 return -ENOMEM;
372 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200373 eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800374 pos += scnprintf(buf + pos, buf_size - pos, "EEPROM "
375 "version: 0x%x\n", eeprom_ver);
376 for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
377 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
378 hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
379 buf_size - pos, 0);
380 pos += strlen(buf + pos);
381 if (buf_size - pos > 0)
382 buf[pos++] = '\n';
383 }
384
385 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
386 kfree(buf);
387 return ret;
388}
389
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800390static ssize_t
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200391il_dbgfs_channels_read(struct file *file, char __user *user_buf,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800392 size_t count, loff_t *ppos)
393{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200394 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800395 struct ieee80211_channel *channels = NULL;
396 const struct ieee80211_supported_band *supp_band = NULL;
397 int pos = 0, i, bufsz = PAGE_SIZE;
398 char *buf;
399 ssize_t ret;
400
Stanislaw Gruszkaa6766cc2011-11-15 13:09:01 +0100401 if (!test_bit(S_GEO_CONFIGURED, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800402 return -EAGAIN;
403
404 buf = kzalloc(bufsz, GFP_KERNEL);
405 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200406 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800407 return -ENOMEM;
408 }
409
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200410 supp_band = il_get_hw_mode(il, IEEE80211_BAND_2GHZ);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800411 if (supp_band) {
412 channels = supp_band->channels;
413
414 pos += scnprintf(buf + pos, bufsz - pos,
415 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
416 supp_band->n_channels);
417
418 for (i = 0; i < supp_band->n_channels; i++)
419 pos += scnprintf(buf + pos, bufsz - pos,
420 "%d: %ddBm: BSS%s%s, %s.\n",
421 channels[i].hw_value,
422 channels[i].max_power,
423 channels[i].flags & IEEE80211_CHAN_RADAR ?
424 " (IEEE 802.11h required)" : "",
425 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
426 || (channels[i].flags &
427 IEEE80211_CHAN_RADAR)) ? "" :
428 ", IBSS",
429 channels[i].flags &
430 IEEE80211_CHAN_PASSIVE_SCAN ?
431 "passive only" : "active/passive");
432 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200433 supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800434 if (supp_band) {
435 channels = supp_band->channels;
436
437 pos += scnprintf(buf + pos, bufsz - pos,
438 "Displaying %d channels in 5.2GHz band (802.11a)\n",
439 supp_band->n_channels);
440
441 for (i = 0; i < supp_band->n_channels; i++)
442 pos += scnprintf(buf + pos, bufsz - pos,
443 "%d: %ddBm: BSS%s%s, %s.\n",
444 channels[i].hw_value,
445 channels[i].max_power,
446 channels[i].flags & IEEE80211_CHAN_RADAR ?
447 " (IEEE 802.11h required)" : "",
448 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
449 || (channels[i].flags &
450 IEEE80211_CHAN_RADAR)) ? "" :
451 ", IBSS",
452 channels[i].flags &
453 IEEE80211_CHAN_PASSIVE_SCAN ?
454 "passive only" : "active/passive");
455 }
456 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
457 kfree(buf);
458 return ret;
459}
460
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200461static ssize_t il_dbgfs_status_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800462 char __user *user_buf,
463 size_t count, loff_t *ppos) {
464
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200465 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800466 char buf[512];
467 int pos = 0;
468 const size_t bufsz = sizeof(buf);
469
Stanislaw Gruszkaa6766cc2011-11-15 13:09:01 +0100470 pos += scnprintf(buf + pos, bufsz - pos, "S_HCMD_ACTIVE:\t %d\n",
471 test_bit(S_HCMD_ACTIVE, &il->status));
472 pos += scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n",
473 test_bit(S_INT_ENABLED, &il->status));
474 pos += scnprintf(buf + pos, bufsz - pos, "S_RF_KILL_HW:\t %d\n",
475 test_bit(S_RF_KILL_HW, &il->status));
476 pos += scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n",
477 test_bit(S_CT_KILL, &il->status));
478 pos += scnprintf(buf + pos, bufsz - pos, "S_INIT:\t\t %d\n",
479 test_bit(S_INIT, &il->status));
480 pos += scnprintf(buf + pos, bufsz - pos, "S_ALIVE:\t\t %d\n",
481 test_bit(S_ALIVE, &il->status));
482 pos += scnprintf(buf + pos, bufsz - pos, "S_READY:\t\t %d\n",
483 test_bit(S_READY, &il->status));
484 pos += scnprintf(buf + pos, bufsz - pos, "S_TEMPERATURE:\t %d\n",
485 test_bit(S_TEMPERATURE, &il->status));
486 pos += scnprintf(buf + pos, bufsz - pos, "S_GEO_CONFIGURED:\t %d\n",
487 test_bit(S_GEO_CONFIGURED, &il->status));
488 pos += scnprintf(buf + pos, bufsz - pos, "S_EXIT_PENDING:\t %d\n",
489 test_bit(S_EXIT_PENDING, &il->status));
Stanislaw Gruszkadb7746f2011-11-15 13:11:50 +0100490 pos += scnprintf(buf + pos, bufsz - pos, "S_STATS:\t %d\n",
491 test_bit(S_STATS, &il->status));
Stanislaw Gruszkaa6766cc2011-11-15 13:09:01 +0100492 pos += scnprintf(buf + pos, bufsz - pos, "S_SCANNING:\t %d\n",
493 test_bit(S_SCANNING, &il->status));
494 pos += scnprintf(buf + pos, bufsz - pos, "S_SCAN_ABORTING:\t %d\n",
495 test_bit(S_SCAN_ABORTING, &il->status));
496 pos += scnprintf(buf + pos, bufsz - pos, "S_SCAN_HW:\t\t %d\n",
497 test_bit(S_SCAN_HW, &il->status));
498 pos += scnprintf(buf + pos, bufsz - pos, "S_POWER_PMI:\t %d\n",
499 test_bit(S_POWER_PMI, &il->status));
500 pos += scnprintf(buf + pos, bufsz - pos, "S_FW_ERROR:\t %d\n",
501 test_bit(S_FW_ERROR, &il->status));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800502 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
503}
504
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200505static ssize_t il_dbgfs_interrupt_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800506 char __user *user_buf,
507 size_t count, loff_t *ppos) {
508
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200509 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800510 int pos = 0;
511 int cnt = 0;
512 char *buf;
513 int bufsz = 24 * 64; /* 24 items * 64 char per item */
514 ssize_t ret;
515
516 buf = kzalloc(bufsz, GFP_KERNEL);
517 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200518 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800519 return -ENOMEM;
520 }
521
522 pos += scnprintf(buf + pos, bufsz - pos,
523 "Interrupt Statistics Report:\n");
524
525 pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200526 il->isr_stats.hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800527 pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200528 il->isr_stats.sw);
529 if (il->isr_stats.sw || il->isr_stats.hw) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800530 pos += scnprintf(buf + pos, bufsz - pos,
531 "\tLast Restarting Code: 0x%X\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200532 il->isr_stats.err_code);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800533 }
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100534#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800535 pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200536 il->isr_stats.sch);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800537 pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200538 il->isr_stats.alive);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800539#endif
540 pos += scnprintf(buf + pos, bufsz - pos,
541 "HW RF KILL switch toggled:\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200542 il->isr_stats.rfkill);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800543
544 pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200545 il->isr_stats.ctkill);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800546
547 pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200548 il->isr_stats.wakeup);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800549
550 pos += scnprintf(buf + pos, bufsz - pos,
551 "Rx command responses:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200552 il->isr_stats.rx);
Stanislaw Gruszka4d69c752011-08-30 15:26:35 +0200553 for (cnt = 0; cnt < IL_CN_MAX; cnt++) {
Stanislaw Gruszkad0c72342011-08-30 15:39:42 +0200554 if (il->isr_stats.handlers[cnt] > 0)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800555 pos += scnprintf(buf + pos, bufsz - pos,
556 "\tRx handler[%36s]:\t\t %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200557 il_get_cmd_string(cnt),
Stanislaw Gruszkad0c72342011-08-30 15:39:42 +0200558 il->isr_stats.handlers[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800559 }
560
561 pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200562 il->isr_stats.tx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800563
564 pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200565 il->isr_stats.unhandled);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800566
567 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
568 kfree(buf);
569 return ret;
570}
571
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200572static ssize_t il_dbgfs_interrupt_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800573 const char __user *user_buf,
574 size_t count, loff_t *ppos)
575{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200576 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800577 char buf[8];
578 int buf_size;
579 u32 reset_flag;
580
581 memset(buf, 0, sizeof(buf));
582 buf_size = min(count, sizeof(buf) - 1);
583 if (copy_from_user(buf, user_buf, buf_size))
584 return -EFAULT;
585 if (sscanf(buf, "%x", &reset_flag) != 1)
586 return -EFAULT;
587 if (reset_flag == 0)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200588 il_clear_isr_stats(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800589
590 return count;
591}
592
593static ssize_t
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200594il_dbgfs_qos_read(struct file *file, char __user *user_buf,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800595 size_t count, loff_t *ppos)
596{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200597 struct il_priv *il = file->private_data;
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200598 struct il_rxon_context *ctx = &il->ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800599 int pos = 0, i;
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +0100600 char buf[256];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800601 const size_t bufsz = sizeof(buf);
602
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200603 pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n",
604 ctx->ctxid);
605 for (i = 0; i < AC_NUM; i++) {
606 pos += scnprintf(buf + pos, bufsz - pos,
607 "\tcw_min\tcw_max\taifsn\ttxop\n");
608 pos += scnprintf(buf + pos, bufsz - pos,
609 "AC[%d]\t%u\t%u\t%u\t%u\n", i,
610 ctx->qos_data.def_qos_parm.ac[i].cw_min,
611 ctx->qos_data.def_qos_parm.ac[i].cw_max,
612 ctx->qos_data.def_qos_parm.ac[i].aifsn,
613 ctx->qos_data.def_qos_parm.ac[i].edca_txop);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800614 }
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200615
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800616 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
617}
618
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200619static ssize_t il_dbgfs_disable_ht40_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800620 const char __user *user_buf,
621 size_t count, loff_t *ppos)
622{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200623 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800624 char buf[8];
625 int buf_size;
626 int ht40;
627
628 memset(buf, 0, sizeof(buf));
629 buf_size = min(count, sizeof(buf) - 1);
630 if (copy_from_user(buf, user_buf, buf_size))
631 return -EFAULT;
632 if (sscanf(buf, "%d", &ht40) != 1)
633 return -EFAULT;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200634 if (!il_is_any_associated(il))
635 il->disable_ht40 = ht40 ? true : false;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800636 else {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200637 IL_ERR("Sta associated with AP - "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800638 "Change to 40MHz channel support is not allowed\n");
639 return -EINVAL;
640 }
641
642 return count;
643}
644
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200645static ssize_t il_dbgfs_disable_ht40_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800646 char __user *user_buf,
647 size_t count, loff_t *ppos)
648{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200649 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800650 char buf[100];
651 int pos = 0;
652 const size_t bufsz = sizeof(buf);
653
654 pos += scnprintf(buf + pos, bufsz - pos,
655 "11n 40MHz Mode: %s\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200656 il->disable_ht40 ? "Disabled" : "Enabled");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800657 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
658}
659
660DEBUGFS_READ_WRITE_FILE_OPS(sram);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800661DEBUGFS_READ_FILE_OPS(nvm);
662DEBUGFS_READ_FILE_OPS(stations);
663DEBUGFS_READ_FILE_OPS(channels);
664DEBUGFS_READ_FILE_OPS(status);
665DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
666DEBUGFS_READ_FILE_OPS(qos);
667DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
668
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200669static ssize_t il_dbgfs_traffic_log_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800670 char __user *user_buf,
671 size_t count, loff_t *ppos)
672{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200673 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800674 int pos = 0, ofs = 0;
675 int cnt = 0, entry;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200676 struct il_tx_queue *txq;
677 struct il_queue *q;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200678 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800679 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200680 int bufsz = ((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200681 (il->cfg->base_params->num_of_queues * 32 * 8) + 400;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800682 const u8 *ptr;
683 ssize_t ret;
684
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200685 if (!il->txq) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200686 IL_ERR("txq not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800687 return -EAGAIN;
688 }
689 buf = kzalloc(bufsz, GFP_KERNEL);
690 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200691 IL_ERR("Can not allocate buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800692 return -ENOMEM;
693 }
694 pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200695 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
696 txq = &il->txq[cnt];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800697 q = &txq->q;
698 pos += scnprintf(buf + pos, bufsz - pos,
699 "q[%d]: read_ptr: %u, write_ptr: %u\n",
700 cnt, q->read_ptr, q->write_ptr);
701 }
Stanislaw Gruszkad2ddf622011-08-16 14:17:04 +0200702 if (il->tx_traffic && (il_debug_level & IL_DL_TX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200703 ptr = il->tx_traffic;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800704 pos += scnprintf(buf + pos, bufsz - pos,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200705 "Tx Traffic idx: %u\n", il->tx_traffic_idx);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200706 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
707 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800708 entry++, ofs += 16) {
709 pos += scnprintf(buf + pos, bufsz - pos,
710 "0x%.4x ", ofs);
711 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
712 buf + pos, bufsz - pos, 0);
713 pos += strlen(buf + pos);
714 if (bufsz - pos > 0)
715 buf[pos++] = '\n';
716 }
717 }
718 }
719
720 pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
721 pos += scnprintf(buf + pos, bufsz - pos,
722 "read: %u, write: %u\n",
723 rxq->read, rxq->write);
724
Stanislaw Gruszkad2ddf622011-08-16 14:17:04 +0200725 if (il->rx_traffic && (il_debug_level & IL_DL_RX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200726 ptr = il->rx_traffic;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800727 pos += scnprintf(buf + pos, bufsz - pos,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200728 "Rx Traffic idx: %u\n", il->rx_traffic_idx);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200729 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
730 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800731 entry++, ofs += 16) {
732 pos += scnprintf(buf + pos, bufsz - pos,
733 "0x%.4x ", ofs);
734 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
735 buf + pos, bufsz - pos, 0);
736 pos += strlen(buf + pos);
737 if (bufsz - pos > 0)
738 buf[pos++] = '\n';
739 }
740 }
741 }
742
743 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
744 kfree(buf);
745 return ret;
746}
747
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200748static ssize_t il_dbgfs_traffic_log_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800749 const char __user *user_buf,
750 size_t count, loff_t *ppos)
751{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200752 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800753 char buf[8];
754 int buf_size;
755 int traffic_log;
756
757 memset(buf, 0, sizeof(buf));
758 buf_size = min(count, sizeof(buf) - 1);
759 if (copy_from_user(buf, user_buf, buf_size))
760 return -EFAULT;
761 if (sscanf(buf, "%d", &traffic_log) != 1)
762 return -EFAULT;
763 if (traffic_log == 0)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200764 il_reset_traffic_log(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800765
766 return count;
767}
768
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200769static ssize_t il_dbgfs_tx_queue_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800770 char __user *user_buf,
771 size_t count, loff_t *ppos) {
772
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200773 struct il_priv *il = file->private_data;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200774 struct il_tx_queue *txq;
775 struct il_queue *q;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800776 char *buf;
777 int pos = 0;
778 int cnt;
779 int ret;
780 const size_t bufsz = sizeof(char) * 64 *
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200781 il->cfg->base_params->num_of_queues;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800782
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200783 if (!il->txq) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200784 IL_ERR("txq not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800785 return -EAGAIN;
786 }
787 buf = kzalloc(bufsz, GFP_KERNEL);
788 if (!buf)
789 return -ENOMEM;
790
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200791 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
792 txq = &il->txq[cnt];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800793 q = &txq->q;
794 pos += scnprintf(buf + pos, bufsz - pos,
795 "hwq %.2d: read=%u write=%u stop=%d"
796 " swq_id=%#.2x (ac %d/hwq %d)\n",
797 cnt, q->read_ptr, q->write_ptr,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200798 !!test_bit(cnt, il->queue_stopped),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800799 txq->swq_id, txq->swq_id & 3,
800 (txq->swq_id >> 2) & 0x1f);
801 if (cnt >= 4)
802 continue;
803 /* for the ACs, display the stop count too */
804 pos += scnprintf(buf + pos, bufsz - pos,
805 " stop-count: %d\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200806 atomic_read(&il->queue_stop_count[cnt]));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800807 }
808 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
809 kfree(buf);
810 return ret;
811}
812
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200813static ssize_t il_dbgfs_rx_queue_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800814 char __user *user_buf,
815 size_t count, loff_t *ppos) {
816
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200817 struct il_priv *il = file->private_data;
818 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800819 char buf[256];
820 int pos = 0;
821 const size_t bufsz = sizeof(buf);
822
823 pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
824 rxq->read);
825 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
826 rxq->write);
827 pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
828 rxq->free_count);
829 if (rxq->rb_stts) {
830 pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
831 le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF);
832 } else {
833 pos += scnprintf(buf + pos, bufsz - pos,
834 "closed_rb_num: Not Allocated\n");
835 }
836 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
837}
838
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200839static ssize_t il_dbgfs_ucode_rx_stats_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800840 char __user *user_buf,
841 size_t count, loff_t *ppos)
842{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200843 struct il_priv *il = file->private_data;
844 return il->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800845 user_buf, count, ppos);
846}
847
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200848static ssize_t il_dbgfs_ucode_tx_stats_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800849 char __user *user_buf,
850 size_t count, loff_t *ppos)
851{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200852 struct il_priv *il = file->private_data;
853 return il->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800854 user_buf, count, ppos);
855}
856
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200857static ssize_t il_dbgfs_ucode_general_stats_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800858 char __user *user_buf,
859 size_t count, loff_t *ppos)
860{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200861 struct il_priv *il = file->private_data;
862 return il->cfg->ops->lib->debugfs_ops.general_stats_read(file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800863 user_buf, count, ppos);
864}
865
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200866static ssize_t il_dbgfs_sensitivity_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800867 char __user *user_buf,
868 size_t count, loff_t *ppos) {
869
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200870 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800871 int pos = 0;
872 int cnt = 0;
873 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200874 int bufsz = sizeof(struct il_sensitivity_data) * 4 + 100;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800875 ssize_t ret;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200876 struct il_sensitivity_data *data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800877
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200878 data = &il->sensitivity_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800879 buf = kzalloc(bufsz, GFP_KERNEL);
880 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200881 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800882 return -ENOMEM;
883 }
884
885 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
886 data->auto_corr_ofdm);
887 pos += scnprintf(buf + pos, bufsz - pos,
888 "auto_corr_ofdm_mrc:\t\t %u\n",
889 data->auto_corr_ofdm_mrc);
890 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
891 data->auto_corr_ofdm_x1);
892 pos += scnprintf(buf + pos, bufsz - pos,
893 "auto_corr_ofdm_mrc_x1:\t\t %u\n",
894 data->auto_corr_ofdm_mrc_x1);
895 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
896 data->auto_corr_cck);
897 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
898 data->auto_corr_cck_mrc);
899 pos += scnprintf(buf + pos, bufsz - pos,
900 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
901 data->last_bad_plcp_cnt_ofdm);
902 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
903 data->last_fa_cnt_ofdm);
904 pos += scnprintf(buf + pos, bufsz - pos,
905 "last_bad_plcp_cnt_cck:\t\t %u\n",
906 data->last_bad_plcp_cnt_cck);
907 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
908 data->last_fa_cnt_cck);
909 pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
910 data->nrg_curr_state);
911 pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
912 data->nrg_prev_state);
913 pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
914 for (cnt = 0; cnt < 10; cnt++) {
915 pos += scnprintf(buf + pos, bufsz - pos, " %u",
916 data->nrg_value[cnt]);
917 }
918 pos += scnprintf(buf + pos, bufsz - pos, "\n");
919 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
920 for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
921 pos += scnprintf(buf + pos, bufsz - pos, " %u",
922 data->nrg_silence_rssi[cnt]);
923 }
924 pos += scnprintf(buf + pos, bufsz - pos, "\n");
925 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
926 data->nrg_silence_ref);
927 pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
928 data->nrg_energy_idx);
929 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
930 data->nrg_silence_idx);
931 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
932 data->nrg_th_cck);
933 pos += scnprintf(buf + pos, bufsz - pos,
934 "nrg_auto_corr_silence_diff:\t %u\n",
935 data->nrg_auto_corr_silence_diff);
936 pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
937 data->num_in_cck_no_fa);
938 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
939 data->nrg_th_ofdm);
940
941 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
942 kfree(buf);
943 return ret;
944}
945
946
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200947static ssize_t il_dbgfs_chain_noise_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800948 char __user *user_buf,
949 size_t count, loff_t *ppos) {
950
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200951 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800952 int pos = 0;
953 int cnt = 0;
954 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200955 int bufsz = sizeof(struct il_chain_noise_data) * 4 + 100;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800956 ssize_t ret;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200957 struct il_chain_noise_data *data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800958
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200959 data = &il->chain_noise_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800960 buf = kzalloc(bufsz, GFP_KERNEL);
961 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200962 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800963 return -ENOMEM;
964 }
965
966 pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
967 data->active_chains);
968 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
969 data->chain_noise_a);
970 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
971 data->chain_noise_b);
972 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
973 data->chain_noise_c);
974 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
975 data->chain_signal_a);
976 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
977 data->chain_signal_b);
978 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
979 data->chain_signal_c);
980 pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
981 data->beacon_count);
982
983 pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
984 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
985 pos += scnprintf(buf + pos, bufsz - pos, " %u",
986 data->disconn_array[cnt]);
987 }
988 pos += scnprintf(buf + pos, bufsz - pos, "\n");
989 pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
990 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
991 pos += scnprintf(buf + pos, bufsz - pos, " %u",
992 data->delta_gain_code[cnt]);
993 }
994 pos += scnprintf(buf + pos, bufsz - pos, "\n");
995 pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
996 data->radio_write);
997 pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
998 data->state);
999
1000 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1001 kfree(buf);
1002 return ret;
1003}
1004
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001005static ssize_t il_dbgfs_power_save_status_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001006 char __user *user_buf,
1007 size_t count, loff_t *ppos)
1008{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001009 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001010 char buf[60];
1011 int pos = 0;
1012 const size_t bufsz = sizeof(buf);
1013 u32 pwrsave_status;
1014
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001015 pwrsave_status = _il_rd(il, CSR_GP_CNTRL) &
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001016 CSR_GP_REG_POWER_SAVE_STATUS_MSK;
1017
1018 pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
1019 pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
1020 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1021 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1022 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1023 "error");
1024
1025 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1026}
1027
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001028static ssize_t il_dbgfs_clear_ucode_stats_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001029 const char __user *user_buf,
1030 size_t count, loff_t *ppos)
1031{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001032 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001033 char buf[8];
1034 int buf_size;
1035 int clear;
1036
1037 memset(buf, 0, sizeof(buf));
1038 buf_size = min(count, sizeof(buf) - 1);
1039 if (copy_from_user(buf, user_buf, buf_size))
1040 return -EFAULT;
1041 if (sscanf(buf, "%d", &clear) != 1)
1042 return -EFAULT;
1043
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001044 /* make request to uCode to retrieve stats information */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001045 mutex_lock(&il->mutex);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001046 il_send_stats_request(il, CMD_SYNC, true);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001047 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001048
1049 return count;
1050}
1051
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001052static ssize_t il_dbgfs_rxon_flags_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001053 char __user *user_buf,
1054 size_t count, loff_t *ppos) {
1055
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001056 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001057 int len = 0;
1058 char buf[20];
1059
1060 len = sprintf(buf, "0x%04X\n",
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01001061 le32_to_cpu(il->ctx.active.flags));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001062 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1063}
1064
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001065static ssize_t il_dbgfs_rxon_filter_flags_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001066 char __user *user_buf,
1067 size_t count, loff_t *ppos) {
1068
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001069 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001070 int len = 0;
1071 char buf[20];
1072
1073 len = sprintf(buf, "0x%04X\n",
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01001074 le32_to_cpu(il->ctx.active.filter_flags));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001075 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1076}
1077
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001078static ssize_t il_dbgfs_fh_reg_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001079 char __user *user_buf,
1080 size_t count, loff_t *ppos)
1081{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001082 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001083 char *buf;
1084 int pos = 0;
1085 ssize_t ret = -EFAULT;
1086
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001087 if (il->cfg->ops->lib->dump_fh) {
1088 ret = pos = il->cfg->ops->lib->dump_fh(il, &buf, true);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001089 if (buf) {
1090 ret = simple_read_from_buffer(user_buf,
1091 count, ppos, buf, pos);
1092 kfree(buf);
1093 }
1094 }
1095
1096 return ret;
1097}
1098
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001099static ssize_t il_dbgfs_missed_beacon_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001100 char __user *user_buf,
1101 size_t count, loff_t *ppos) {
1102
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001103 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001104 int pos = 0;
1105 char buf[12];
1106 const size_t bufsz = sizeof(buf);
1107
1108 pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001109 il->missed_beacon_threshold);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001110
1111 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1112}
1113
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001114static ssize_t il_dbgfs_missed_beacon_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001115 const char __user *user_buf,
1116 size_t count, loff_t *ppos)
1117{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001118 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001119 char buf[8];
1120 int buf_size;
1121 int missed;
1122
1123 memset(buf, 0, sizeof(buf));
1124 buf_size = min(count, sizeof(buf) - 1);
1125 if (copy_from_user(buf, user_buf, buf_size))
1126 return -EFAULT;
1127 if (sscanf(buf, "%d", &missed) != 1)
1128 return -EINVAL;
1129
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001130 if (missed < IL_MISSED_BEACON_THRESHOLD_MIN ||
1131 missed > IL_MISSED_BEACON_THRESHOLD_MAX)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001132 il->missed_beacon_threshold =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001133 IL_MISSED_BEACON_THRESHOLD_DEF;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001134 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001135 il->missed_beacon_threshold = missed;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001136
1137 return count;
1138}
1139
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001140static ssize_t il_dbgfs_force_reset_read(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001141 char __user *user_buf,
1142 size_t count, loff_t *ppos) {
1143
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001144 struct il_priv *il = file->private_data;
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001145 int pos = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001146 char buf[300];
1147 const size_t bufsz = sizeof(buf);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001148 struct il_force_reset *force_reset;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001149
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001150 force_reset = &il->force_reset;
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001151
1152 pos += scnprintf(buf + pos, bufsz - pos,
1153 "\tnumber of reset request: %d\n",
1154 force_reset->reset_request_count);
1155 pos += scnprintf(buf + pos, bufsz - pos,
1156 "\tnumber of reset request success: %d\n",
1157 force_reset->reset_success_count);
1158 pos += scnprintf(buf + pos, bufsz - pos,
1159 "\tnumber of reset request reject: %d\n",
1160 force_reset->reset_reject_count);
1161 pos += scnprintf(buf + pos, bufsz - pos,
1162 "\treset duration: %lu\n",
1163 force_reset->reset_duration);
1164
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001165 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1166}
1167
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001168static ssize_t il_dbgfs_force_reset_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001169 const char __user *user_buf,
1170 size_t count, loff_t *ppos) {
1171
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001172 int ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001173 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001174
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001175 ret = il_force_reset(il, true);
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001176
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001177 return ret ? ret : count;
1178}
1179
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001180static ssize_t il_dbgfs_wd_timeout_write(struct file *file,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001181 const char __user *user_buf,
1182 size_t count, loff_t *ppos) {
1183
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001184 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001185 char buf[8];
1186 int buf_size;
1187 int timeout;
1188
1189 memset(buf, 0, sizeof(buf));
1190 buf_size = min(count, sizeof(buf) - 1);
1191 if (copy_from_user(buf, user_buf, buf_size))
1192 return -EFAULT;
1193 if (sscanf(buf, "%d", &timeout) != 1)
1194 return -EINVAL;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001195 if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)
1196 timeout = IL_DEF_WD_TIMEOUT;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001197
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001198 il->cfg->base_params->wd_timeout = timeout;
1199 il_setup_watchdog(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001200 return count;
1201}
1202
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001203DEBUGFS_READ_FILE_OPS(rx_stats);
1204DEBUGFS_READ_FILE_OPS(tx_stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001205DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
1206DEBUGFS_READ_FILE_OPS(rx_queue);
1207DEBUGFS_READ_FILE_OPS(tx_queue);
1208DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1209DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1210DEBUGFS_READ_FILE_OPS(ucode_general_stats);
1211DEBUGFS_READ_FILE_OPS(sensitivity);
1212DEBUGFS_READ_FILE_OPS(chain_noise);
1213DEBUGFS_READ_FILE_OPS(power_save_status);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001214DEBUGFS_WRITE_FILE_OPS(clear_ucode_stats);
1215DEBUGFS_WRITE_FILE_OPS(clear_traffic_stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001216DEBUGFS_READ_FILE_OPS(fh_reg);
1217DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001218DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1219DEBUGFS_READ_FILE_OPS(rxon_flags);
1220DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
1221DEBUGFS_WRITE_FILE_OPS(wd_timeout);
1222
1223/*
1224 * Create the debugfs files and directories
1225 *
1226 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001227int il_dbgfs_register(struct il_priv *il, const char *name)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001228{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001229 struct dentry *phyd = il->hw->wiphy->debugfsdir;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001230 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1231
1232 dir_drv = debugfs_create_dir(name, phyd);
1233 if (!dir_drv)
1234 return -ENOMEM;
1235
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001236 il->debugfs_dir = dir_drv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001237
1238 dir_data = debugfs_create_dir("data", dir_drv);
1239 if (!dir_data)
1240 goto err;
1241 dir_rf = debugfs_create_dir("rf", dir_drv);
1242 if (!dir_rf)
1243 goto err;
1244 dir_debug = debugfs_create_dir("debug", dir_drv);
1245 if (!dir_debug)
1246 goto err;
1247
1248 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1249 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001250 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1251 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1252 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1253 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1254 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1255 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001256 DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR);
1257 DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001258 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
1259 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
1260 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
1261 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001262 DEBUGFS_ADD_FILE(clear_ucode_stats, dir_debug, S_IWUSR);
1263 DEBUGFS_ADD_FILE(clear_traffic_stats, dir_debug, S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001264 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
1265 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001266 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
1267 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1268 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1269 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
1270
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001271 if (il->cfg->base_params->sensitivity_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001272 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001273 if (il->cfg->base_params->chain_noise_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001274 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001275 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
1276 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
1277 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001278 if (il->cfg->base_params->sensitivity_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001279 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001280 &il->disable_sens_cal);
1281 if (il->cfg->base_params->chain_noise_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001282 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001283 &il->disable_chain_noise_cal);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001284 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001285 &il->disable_tx_power_cal);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001286 return 0;
1287
1288err:
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001289 IL_ERR("Can't create the debugfs directory\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001290 il_dbgfs_unregister(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001291 return -ENOMEM;
1292}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001293EXPORT_SYMBOL(il_dbgfs_register);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001294
1295/**
1296 * Remove the debugfs files and directories
1297 *
1298 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001299void il_dbgfs_unregister(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001300{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001301 if (!il->debugfs_dir)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001302 return;
1303
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001304 debugfs_remove_recursive(il->debugfs_dir);
1305 il->debugfs_dir = NULL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001306}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001307EXPORT_SYMBOL(il_dbgfs_unregister);