blob: be6005da785df53b010daadf1c79cc77dba10e2d [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>
John W. Linville515db092011-11-22 14:05:46 -050029#include <linux/export.h>
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080030#include <net/mac80211.h>
31
Stanislaw Gruszka98613be2011-11-15 14:19:34 +010032#include "common.h"
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080033
34/* create and remove of files */
35#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +020036 if (!debugfs_create_file(#name, mode, parent, il, \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020037 &il_dbgfs_##name##_ops)) \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080038 goto err; \
39} while (0)
40
41#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
42 struct dentry *__tmp; \
43 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
44 parent, ptr); \
45 if (IS_ERR(__tmp) || !__tmp) \
46 goto err; \
47} while (0)
48
49#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
50 struct dentry *__tmp; \
51 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
52 parent, ptr); \
53 if (IS_ERR(__tmp) || !__tmp) \
54 goto err; \
55} while (0)
56
57/* file operation */
58#define DEBUGFS_READ_FUNC(name) \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020059static ssize_t il_dbgfs_##name##_read(struct file *file, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080060 char __user *user_buf, \
61 size_t count, loff_t *ppos);
62
63#define DEBUGFS_WRITE_FUNC(name) \
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020064static ssize_t il_dbgfs_##name##_write(struct file *file, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080065 const char __user *user_buf, \
66 size_t count, loff_t *ppos);
67
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080068static 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
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010075#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, \
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010079 .open = il_dbgfs_open_file_generic, \
80 .llseek = generic_file_llseek, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080081};
82
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010083#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, \
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010087 .open = il_dbgfs_open_file_generic, \
88 .llseek = generic_file_llseek, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080089};
90
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010091#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, \
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +010098 .llseek = generic_file_llseek, \
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080099};
100
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100101static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100102il_dbgfs_tx_stats_read(struct file *file, char __user *user_buf, size_t count,
103 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100104{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800105
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200106 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800107 char *buf;
108 int pos = 0;
109
110 int cnt;
111 ssize_t ret;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100112 const size_t bufsz =
113 100 + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800114 buf = kzalloc(bufsz, GFP_KERNEL);
115 if (!buf)
116 return -ENOMEM;
117 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
118 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100119 pos +=
120 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
121 il_get_mgmt_string(cnt), 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++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100125 pos +=
126 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
127 il_get_ctrl_string(cnt), il->tx_stats.ctrl[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800128 }
129 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100130 pos +=
131 scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
132 il->tx_stats.data_cnt);
133 pos +=
134 scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
135 il->tx_stats.data_bytes);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800136 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
137 kfree(buf);
138 return ret;
139}
140
141static ssize_t
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200142il_dbgfs_clear_traffic_stats_write(struct file *file,
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100143 const char __user *user_buf, size_t count,
144 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800145{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200146 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800147 u32 clear_flag;
148 char buf[8];
149 int buf_size;
150
151 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100152 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800153 if (copy_from_user(buf, user_buf, buf_size))
154 return -EFAULT;
155 if (sscanf(buf, "%x", &clear_flag) != 1)
156 return -EFAULT;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200157 il_clear_traffic_stats(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800158
159 return count;
160}
161
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100162static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100163il_dbgfs_rx_stats_read(struct file *file, char __user *user_buf, size_t count,
164 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100165{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800166
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;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100172 const size_t bufsz =
173 100 + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800174 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++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100180 pos +=
181 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
182 il_get_mgmt_string(cnt), il->rx_stats.mgmt[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800183 }
184 pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
185 for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100186 pos +=
187 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
188 il_get_ctrl_string(cnt), il->rx_stats.ctrl[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800189 }
190 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100191 pos +=
192 scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
193 il->rx_stats.data_cnt);
194 pos +=
195 scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
196 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 Gruszkae7392362011-11-15 14:45:59 +0100206static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100207il_dbgfs_sram_read(struct file *file, char __user *user_buf, size_t count,
208 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800209{
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 Gruszkae7392362011-11-15 14:45:59 +0100226 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;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100230 pos +=
231 scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
232 il->dbgfs_sram_len);
233 pos +=
234 scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
235 il->dbgfs_sram_offset);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200236 for (i = il->dbgfs_sram_len; i > 0; i -= 4) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100237 val =
238 il_read_targ_mem(il,
239 il->dbgfs_sram_offset +
240 il->dbgfs_sram_len - i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800241 if (i < 4) {
242 switch (i) {
243 case 1:
244 val &= BYTE1_MASK;
245 break;
246 case 2:
247 val &= BYTE2_MASK;
248 break;
249 case 3:
250 val &= BYTE3_MASK;
251 break;
252 }
253 }
254 if (!(i % 16))
255 pos += scnprintf(buf + pos, bufsz - pos, "\n");
256 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
257 }
258 pos += scnprintf(buf + pos, bufsz - pos, "\n");
259
260 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
261 kfree(buf);
262 return ret;
263}
264
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100265static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100266il_dbgfs_sram_write(struct file *file, const char __user *user_buf,
267 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800268{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200269 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800270 char buf[64];
271 int buf_size;
272 u32 offset, len;
273
274 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100275 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800276 if (copy_from_user(buf, user_buf, buf_size))
277 return -EFAULT;
278
279 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200280 il->dbgfs_sram_offset = offset;
281 il->dbgfs_sram_len = len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800282 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200283 il->dbgfs_sram_offset = 0;
284 il->dbgfs_sram_len = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800285 }
286
287 return count;
288}
289
290static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100291il_dbgfs_stations_read(struct file *file, char __user *user_buf, size_t count,
292 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800293{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200294 struct il_priv *il = file->private_data;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200295 struct il_station_entry *station;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200296 int max_sta = il->hw_params.max_stations;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800297 char *buf;
298 int i, j, pos = 0;
299 ssize_t ret;
300 /* Add 30 for initial string */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200301 const size_t bufsz = 30 + sizeof(char) * 500 * (il->num_stations);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800302
303 buf = kmalloc(bufsz, GFP_KERNEL);
304 if (!buf)
305 return -ENOMEM;
306
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100307 pos +=
308 scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
309 il->num_stations);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800310
311 for (i = 0; i < max_sta; i++) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200312 station = &il->stations[i];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800313 if (!station->used)
314 continue;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100315 pos +=
316 scnprintf(buf + pos, bufsz - pos,
317 "station %d - addr: %pM, flags: %#x\n", i,
318 station->sta.sta.addr,
319 station->sta.station_flags_msk);
320 pos +=
321 scnprintf(buf + pos, bufsz - pos,
322 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
323 pos +=
324 scnprintf(buf + pos, bufsz - pos,
325 "start_idx\tbitmap\t\t\trate_n_flags\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800326
327 for (j = 0; j < MAX_TID_COUNT; j++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100328 pos +=
329 scnprintf(buf + pos, bufsz - pos,
330 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
331 j, station->tid[j].seq_number,
332 station->tid[j].agg.txq_id,
333 station->tid[j].agg.frame_count,
334 station->tid[j].tfds_in_queue,
335 station->tid[j].agg.start_idx,
336 station->tid[j].agg.bitmap,
337 station->tid[j].agg.rate_n_flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800338
339 if (station->tid[j].agg.wait_for_ba)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100340 pos +=
341 scnprintf(buf + pos, bufsz - pos,
342 " - waitforba");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800343 pos += scnprintf(buf + pos, bufsz - pos, "\n");
344 }
345
346 pos += scnprintf(buf + pos, bufsz - pos, "\n");
347 }
348
349 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
350 kfree(buf);
351 return ret;
352}
353
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100354static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100355il_dbgfs_nvm_read(struct file *file, char __user *user_buf, size_t count,
356 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800357{
358 ssize_t ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200359 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800360 int pos = 0, ofs = 0, buf_size = 0;
361 const u8 *ptr;
362 char *buf;
363 u16 eeprom_ver;
Stanislaw Gruszka89ef1ed2012-02-03 17:31:59 +0100364 size_t eeprom_len = il->cfg->eeprom_size;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800365 buf_size = 4 * eeprom_len + 256;
366
367 if (eeprom_len % 16) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200368 IL_ERR("NVM size is not multiple of 16.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800369 return -ENODATA;
370 }
371
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200372 ptr = il->eeprom;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800373 if (!ptr) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200374 IL_ERR("Invalid EEPROM memory\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800375 return -ENOMEM;
376 }
377
378 /* 4 characters for byte 0xYY */
379 buf = kzalloc(buf_size, GFP_KERNEL);
380 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200381 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800382 return -ENOMEM;
383 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200384 eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION);
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100385 pos +=
386 scnprintf(buf + pos, buf_size - pos, "EEPROM " "version: 0x%x\n",
387 eeprom_ver);
388 for (ofs = 0; ofs < eeprom_len; ofs += 16) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800389 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100390 hex_dump_to_buffer(ptr + ofs, 16, 16, 2, buf + pos,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800391 buf_size - pos, 0);
392 pos += strlen(buf + pos);
393 if (buf_size - pos > 0)
394 buf[pos++] = '\n';
395 }
396
397 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
398 kfree(buf);
399 return ret;
400}
401
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800402static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100403il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
404 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800405{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200406 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800407 struct ieee80211_channel *channels = NULL;
408 const struct ieee80211_supported_band *supp_band = NULL;
409 int pos = 0, i, bufsz = PAGE_SIZE;
410 char *buf;
411 ssize_t ret;
412
Stanislaw Gruszkaa6766cc2011-11-15 13:09:01 +0100413 if (!test_bit(S_GEO_CONFIGURED, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800414 return -EAGAIN;
415
416 buf = kzalloc(bufsz, GFP_KERNEL);
417 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200418 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800419 return -ENOMEM;
420 }
421
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200422 supp_band = il_get_hw_mode(il, IEEE80211_BAND_2GHZ);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800423 if (supp_band) {
424 channels = supp_band->channels;
425
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100426 pos +=
427 scnprintf(buf + pos, bufsz - pos,
428 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
429 supp_band->n_channels);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800430
431 for (i = 0; i < supp_band->n_channels; i++)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100432 pos +=
433 scnprintf(buf + pos, bufsz - pos,
434 "%d: %ddBm: BSS%s%s, %s.\n",
435 channels[i].hw_value,
436 channels[i].max_power,
437 channels[i].
438 flags & IEEE80211_CHAN_RADAR ?
439 " (IEEE 802.11h required)" : "",
440 ((channels[i].
441 flags & IEEE80211_CHAN_NO_IBSS) ||
442 (channels[i].
443 flags & IEEE80211_CHAN_RADAR)) ? "" :
444 ", IBSS",
445 channels[i].
446 flags & IEEE80211_CHAN_PASSIVE_SCAN ?
447 "passive only" : "active/passive");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800448 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200449 supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800450 if (supp_band) {
451 channels = supp_band->channels;
452
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100453 pos +=
454 scnprintf(buf + pos, bufsz - pos,
455 "Displaying %d channels in 5.2GHz band (802.11a)\n",
456 supp_band->n_channels);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800457
458 for (i = 0; i < supp_band->n_channels; i++)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100459 pos +=
460 scnprintf(buf + pos, bufsz - pos,
461 "%d: %ddBm: BSS%s%s, %s.\n",
462 channels[i].hw_value,
463 channels[i].max_power,
464 channels[i].
465 flags & IEEE80211_CHAN_RADAR ?
466 " (IEEE 802.11h required)" : "",
467 ((channels[i].
468 flags & IEEE80211_CHAN_NO_IBSS) ||
469 (channels[i].
470 flags & IEEE80211_CHAN_RADAR)) ? "" :
471 ", IBSS",
472 channels[i].
473 flags & IEEE80211_CHAN_PASSIVE_SCAN ?
474 "passive only" : "active/passive");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800475 }
476 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
477 kfree(buf);
478 return ret;
479}
480
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100481static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100482il_dbgfs_status_read(struct file *file, char __user *user_buf, size_t count,
483 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100484{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800485
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200486 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800487 char buf[512];
488 int pos = 0;
489 const size_t bufsz = sizeof(buf);
490
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100491 pos +=
492 scnprintf(buf + pos, bufsz - pos, "S_HCMD_ACTIVE:\t %d\n",
493 test_bit(S_HCMD_ACTIVE, &il->status));
494 pos +=
495 scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n",
496 test_bit(S_INT_ENABLED, &il->status));
497 pos +=
498 scnprintf(buf + pos, bufsz - pos, "S_RF_KILL_HW:\t %d\n",
499 test_bit(S_RF_KILL_HW, &il->status));
500 pos +=
501 scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n",
502 test_bit(S_CT_KILL, &il->status));
503 pos +=
504 scnprintf(buf + pos, bufsz - pos, "S_INIT:\t\t %d\n",
505 test_bit(S_INIT, &il->status));
506 pos +=
507 scnprintf(buf + pos, bufsz - pos, "S_ALIVE:\t\t %d\n",
508 test_bit(S_ALIVE, &il->status));
509 pos +=
510 scnprintf(buf + pos, bufsz - pos, "S_READY:\t\t %d\n",
511 test_bit(S_READY, &il->status));
512 pos +=
513 scnprintf(buf + pos, bufsz - pos, "S_TEMPERATURE:\t %d\n",
514 test_bit(S_TEMPERATURE, &il->status));
515 pos +=
516 scnprintf(buf + pos, bufsz - pos, "S_GEO_CONFIGURED:\t %d\n",
517 test_bit(S_GEO_CONFIGURED, &il->status));
518 pos +=
519 scnprintf(buf + pos, bufsz - pos, "S_EXIT_PENDING:\t %d\n",
520 test_bit(S_EXIT_PENDING, &il->status));
521 pos +=
522 scnprintf(buf + pos, bufsz - pos, "S_STATS:\t %d\n",
523 test_bit(S_STATS, &il->status));
524 pos +=
525 scnprintf(buf + pos, bufsz - pos, "S_SCANNING:\t %d\n",
526 test_bit(S_SCANNING, &il->status));
527 pos +=
528 scnprintf(buf + pos, bufsz - pos, "S_SCAN_ABORTING:\t %d\n",
529 test_bit(S_SCAN_ABORTING, &il->status));
530 pos +=
531 scnprintf(buf + pos, bufsz - pos, "S_SCAN_HW:\t\t %d\n",
532 test_bit(S_SCAN_HW, &il->status));
533 pos +=
534 scnprintf(buf + pos, bufsz - pos, "S_POWER_PMI:\t %d\n",
535 test_bit(S_POWER_PMI, &il->status));
536 pos +=
537 scnprintf(buf + pos, bufsz - pos, "S_FW_ERROR:\t %d\n",
538 test_bit(S_FW_ERROR, &il->status));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800539 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
540}
541
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100542static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100543il_dbgfs_interrupt_read(struct file *file, char __user *user_buf, size_t count,
544 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100545{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800546
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200547 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800548 int pos = 0;
549 int cnt = 0;
550 char *buf;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100551 int bufsz = 24 * 64; /* 24 items * 64 char per item */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800552 ssize_t ret;
553
554 buf = kzalloc(bufsz, GFP_KERNEL);
555 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200556 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800557 return -ENOMEM;
558 }
559
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100560 pos +=
561 scnprintf(buf + pos, bufsz - pos, "Interrupt Statistics Report:\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800562
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100563 pos +=
564 scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
565 il->isr_stats.hw);
566 pos +=
567 scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
568 il->isr_stats.sw);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200569 if (il->isr_stats.sw || il->isr_stats.hw) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100570 pos +=
571 scnprintf(buf + pos, bufsz - pos,
572 "\tLast Restarting Code: 0x%X\n",
573 il->isr_stats.err_code);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800574 }
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100575#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100576 pos +=
577 scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
578 il->isr_stats.sch);
579 pos +=
580 scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
581 il->isr_stats.alive);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800582#endif
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100583 pos +=
584 scnprintf(buf + pos, bufsz - pos,
585 "HW RF KILL switch toggled:\t %u\n",
586 il->isr_stats.rfkill);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800587
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100588 pos +=
589 scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
590 il->isr_stats.ctkill);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800591
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100592 pos +=
593 scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
594 il->isr_stats.wakeup);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800595
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100596 pos +=
597 scnprintf(buf + pos, bufsz - pos, "Rx command responses:\t\t %u\n",
598 il->isr_stats.rx);
Stanislaw Gruszka4d69c752011-08-30 15:26:35 +0200599 for (cnt = 0; cnt < IL_CN_MAX; cnt++) {
Stanislaw Gruszkad0c72342011-08-30 15:39:42 +0200600 if (il->isr_stats.handlers[cnt] > 0)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100601 pos +=
602 scnprintf(buf + pos, bufsz - pos,
603 "\tRx handler[%36s]:\t\t %u\n",
604 il_get_cmd_string(cnt),
605 il->isr_stats.handlers[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800606 }
607
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100608 pos +=
609 scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
610 il->isr_stats.tx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800611
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100612 pos +=
613 scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
614 il->isr_stats.unhandled);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800615
616 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
617 kfree(buf);
618 return ret;
619}
620
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100621static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100622il_dbgfs_interrupt_write(struct file *file, const char __user *user_buf,
623 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800624{
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 u32 reset_flag;
629
630 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100631 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800632 if (copy_from_user(buf, user_buf, buf_size))
633 return -EFAULT;
634 if (sscanf(buf, "%x", &reset_flag) != 1)
635 return -EFAULT;
636 if (reset_flag == 0)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200637 il_clear_isr_stats(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800638
639 return count;
640}
641
642static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100643il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count,
644 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800645{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200646 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800647 int pos = 0, i;
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +0100648 char buf[256];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800649 const size_t bufsz = sizeof(buf);
650
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200651 for (i = 0; i < AC_NUM; i++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100652 pos +=
653 scnprintf(buf + pos, bufsz - pos,
654 "\tcw_min\tcw_max\taifsn\ttxop\n");
655 pos +=
656 scnprintf(buf + pos, bufsz - pos,
657 "AC[%d]\t%u\t%u\t%u\t%u\n", i,
Stanislaw Gruszka8d44f2b2012-02-03 17:31:51 +0100658 il->qos_data.def_qos_parm.ac[i].cw_min,
659 il->qos_data.def_qos_parm.ac[i].cw_max,
660 il->qos_data.def_qos_parm.ac[i].aifsn,
661 il->qos_data.def_qos_parm.ac[i].edca_txop);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800662 }
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200663
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800664 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
665}
666
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100667static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100668il_dbgfs_disable_ht40_write(struct file *file, const char __user *user_buf,
669 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800670{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200671 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800672 char buf[8];
673 int buf_size;
674 int ht40;
675
676 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100677 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800678 if (copy_from_user(buf, user_buf, buf_size))
679 return -EFAULT;
680 if (sscanf(buf, "%d", &ht40) != 1)
681 return -EFAULT;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200682 if (!il_is_any_associated(il))
683 il->disable_ht40 = ht40 ? true : false;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800684 else {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200685 IL_ERR("Sta associated with AP - "
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100686 "Change to 40MHz channel support is not allowed\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800687 return -EINVAL;
688 }
689
690 return count;
691}
692
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100693static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100694il_dbgfs_disable_ht40_read(struct file *file, char __user *user_buf,
695 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800696{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200697 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800698 char buf[100];
699 int pos = 0;
700 const size_t bufsz = sizeof(buf);
701
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100702 pos +=
703 scnprintf(buf + pos, bufsz - pos, "11n 40MHz Mode: %s\n",
704 il->disable_ht40 ? "Disabled" : "Enabled");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800705 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
706}
707
708DEBUGFS_READ_WRITE_FILE_OPS(sram);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800709DEBUGFS_READ_FILE_OPS(nvm);
710DEBUGFS_READ_FILE_OPS(stations);
711DEBUGFS_READ_FILE_OPS(channels);
712DEBUGFS_READ_FILE_OPS(status);
713DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
714DEBUGFS_READ_FILE_OPS(qos);
715DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
716
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100717static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100718il_dbgfs_traffic_log_read(struct file *file, char __user *user_buf,
719 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800720{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200721 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800722 int pos = 0, ofs = 0;
723 int cnt = 0, entry;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200724 struct il_tx_queue *txq;
725 struct il_queue *q;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200726 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800727 char *buf;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100728 int bufsz =
729 ((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
Stanislaw Gruszka89ef1ed2012-02-03 17:31:59 +0100730 (il->cfg->num_of_queues * 32 * 8) + 400;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800731 const u8 *ptr;
732 ssize_t ret;
733
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200734 if (!il->txq) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200735 IL_ERR("txq not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800736 return -EAGAIN;
737 }
738 buf = kzalloc(bufsz, GFP_KERNEL);
739 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200740 IL_ERR("Can not allocate buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800741 return -ENOMEM;
742 }
743 pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200744 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
745 txq = &il->txq[cnt];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800746 q = &txq->q;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100747 pos +=
748 scnprintf(buf + pos, bufsz - pos,
749 "q[%d]: read_ptr: %u, write_ptr: %u\n", cnt,
750 q->read_ptr, q->write_ptr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800751 }
Stanislaw Gruszkad2ddf622011-08-16 14:17:04 +0200752 if (il->tx_traffic && (il_debug_level & IL_DL_TX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200753 ptr = il->tx_traffic;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100754 pos +=
755 scnprintf(buf + pos, bufsz - pos, "Tx Traffic idx: %u\n",
756 il->tx_traffic_idx);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200757 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
758 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100759 entry++, ofs += 16) {
760 pos +=
761 scnprintf(buf + pos, bufsz - pos, "0x%.4x ",
762 ofs);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800763 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
764 buf + pos, bufsz - pos, 0);
765 pos += strlen(buf + pos);
766 if (bufsz - pos > 0)
767 buf[pos++] = '\n';
768 }
769 }
770 }
771
772 pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100773 pos +=
774 scnprintf(buf + pos, bufsz - pos, "read: %u, write: %u\n",
775 rxq->read, rxq->write);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800776
Stanislaw Gruszkad2ddf622011-08-16 14:17:04 +0200777 if (il->rx_traffic && (il_debug_level & IL_DL_RX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200778 ptr = il->rx_traffic;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100779 pos +=
780 scnprintf(buf + pos, bufsz - pos, "Rx Traffic idx: %u\n",
781 il->rx_traffic_idx);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200782 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
783 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100784 entry++, ofs += 16) {
785 pos +=
786 scnprintf(buf + pos, bufsz - pos, "0x%.4x ",
787 ofs);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800788 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
789 buf + pos, bufsz - pos, 0);
790 pos += strlen(buf + pos);
791 if (bufsz - pos > 0)
792 buf[pos++] = '\n';
793 }
794 }
795 }
796
797 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
798 kfree(buf);
799 return ret;
800}
801
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100802static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100803il_dbgfs_traffic_log_write(struct file *file, const char __user *user_buf,
804 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800805{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200806 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800807 char buf[8];
808 int buf_size;
809 int traffic_log;
810
811 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100812 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800813 if (copy_from_user(buf, user_buf, buf_size))
814 return -EFAULT;
815 if (sscanf(buf, "%d", &traffic_log) != 1)
816 return -EFAULT;
817 if (traffic_log == 0)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200818 il_reset_traffic_log(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800819
820 return count;
821}
822
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100823static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100824il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,
825 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100826{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800827
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200828 struct il_priv *il = file->private_data;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200829 struct il_tx_queue *txq;
830 struct il_queue *q;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800831 char *buf;
832 int pos = 0;
833 int cnt;
834 int ret;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100835 const size_t bufsz =
Stanislaw Gruszka89ef1ed2012-02-03 17:31:59 +0100836 sizeof(char) * 64 * il->cfg->num_of_queues;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800837
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200838 if (!il->txq) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200839 IL_ERR("txq not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800840 return -EAGAIN;
841 }
842 buf = kzalloc(bufsz, GFP_KERNEL);
843 if (!buf)
844 return -ENOMEM;
845
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200846 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
847 txq = &il->txq[cnt];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800848 q = &txq->q;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100849 pos +=
850 scnprintf(buf + pos, bufsz - pos,
851 "hwq %.2d: read=%u write=%u stop=%d"
852 " swq_id=%#.2x (ac %d/hwq %d)\n", cnt,
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100853 q->read_ptr, q->write_ptr,
854 !!test_bit(cnt, il->queue_stopped),
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100855 txq->swq_id, txq->swq_id & 3,
856 (txq->swq_id >> 2) & 0x1f);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800857 if (cnt >= 4)
858 continue;
859 /* for the ACs, display the stop count too */
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100860 pos +=
861 scnprintf(buf + pos, bufsz - pos,
862 " stop-count: %d\n",
863 atomic_read(&il->queue_stop_count[cnt]));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800864 }
865 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
866 kfree(buf);
867 return ret;
868}
869
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100870static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100871il_dbgfs_rx_queue_read(struct file *file, char __user *user_buf, size_t count,
872 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100873{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800874
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200875 struct il_priv *il = file->private_data;
876 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800877 char buf[256];
878 int pos = 0;
879 const size_t bufsz = sizeof(buf);
880
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100881 pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n", rxq->read);
882 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", rxq->write);
883 pos +=
884 scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
885 rxq->free_count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800886 if (rxq->rb_stts) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100887 pos +=
888 scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
889 le16_to_cpu(rxq->rb_stts->
890 closed_rb_num) & 0x0FFF);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800891 } else {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100892 pos +=
893 scnprintf(buf + pos, bufsz - pos,
894 "closed_rb_num: Not Allocated\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800895 }
896 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
897}
898
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100899static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100900il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf,
901 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800902{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200903 struct il_priv *il = file->private_data;
Stanislaw Gruszka93b76542012-02-13 11:23:14 +0100904
905 return il->debugfs_ops->rx_stats_read(file, user_buf, count, ppos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800906}
907
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100908static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100909il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf,
910 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800911{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200912 struct il_priv *il = file->private_data;
Stanislaw Gruszka93b76542012-02-13 11:23:14 +0100913
914 return il->debugfs_ops->tx_stats_read(file, user_buf, count, ppos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800915}
916
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100917static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100918il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf,
919 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800920{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200921 struct il_priv *il = file->private_data;
Stanislaw Gruszka93b76542012-02-13 11:23:14 +0100922
923 return il->debugfs_ops->general_stats_read(file, user_buf, count, ppos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800924}
925
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100926static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100927il_dbgfs_sensitivity_read(struct file *file, char __user *user_buf,
928 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100929{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800930
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200931 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800932 int pos = 0;
933 int cnt = 0;
934 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200935 int bufsz = sizeof(struct il_sensitivity_data) * 4 + 100;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800936 ssize_t ret;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200937 struct il_sensitivity_data *data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800938
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200939 data = &il->sensitivity_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800940 buf = kzalloc(bufsz, GFP_KERNEL);
941 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200942 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800943 return -ENOMEM;
944 }
945
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100946 pos +=
947 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
948 data->auto_corr_ofdm);
949 pos +=
950 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc:\t\t %u\n",
951 data->auto_corr_ofdm_mrc);
952 pos +=
953 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
954 data->auto_corr_ofdm_x1);
955 pos +=
956 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc_x1:\t\t %u\n",
957 data->auto_corr_ofdm_mrc_x1);
958 pos +=
959 scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
960 data->auto_corr_cck);
961 pos +=
962 scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
963 data->auto_corr_cck_mrc);
964 pos +=
965 scnprintf(buf + pos, bufsz - pos,
966 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
967 data->last_bad_plcp_cnt_ofdm);
968 pos +=
969 scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
970 data->last_fa_cnt_ofdm);
971 pos +=
972 scnprintf(buf + pos, bufsz - pos, "last_bad_plcp_cnt_cck:\t\t %u\n",
973 data->last_bad_plcp_cnt_cck);
974 pos +=
975 scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
976 data->last_fa_cnt_cck);
977 pos +=
978 scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
979 data->nrg_curr_state);
980 pos +=
981 scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
982 data->nrg_prev_state);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800983 pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
984 for (cnt = 0; cnt < 10; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100985 pos +=
986 scnprintf(buf + pos, bufsz - pos, " %u",
987 data->nrg_value[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800988 }
989 pos += scnprintf(buf + pos, bufsz - pos, "\n");
990 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
991 for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100992 pos +=
993 scnprintf(buf + pos, bufsz - pos, " %u",
994 data->nrg_silence_rssi[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800995 }
996 pos += scnprintf(buf + pos, bufsz - pos, "\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100997 pos +=
998 scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
999 data->nrg_silence_ref);
1000 pos +=
1001 scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
1002 data->nrg_energy_idx);
1003 pos +=
1004 scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
1005 data->nrg_silence_idx);
1006 pos +=
1007 scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
1008 data->nrg_th_cck);
1009 pos +=
1010 scnprintf(buf + pos, bufsz - pos,
1011 "nrg_auto_corr_silence_diff:\t %u\n",
1012 data->nrg_auto_corr_silence_diff);
1013 pos +=
1014 scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
1015 data->num_in_cck_no_fa);
1016 pos +=
1017 scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
1018 data->nrg_th_ofdm);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001019
1020 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1021 kfree(buf);
1022 return ret;
1023}
1024
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001025static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001026il_dbgfs_chain_noise_read(struct file *file, char __user *user_buf,
1027 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001028{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001029
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001030 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001031 int pos = 0;
1032 int cnt = 0;
1033 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001034 int bufsz = sizeof(struct il_chain_noise_data) * 4 + 100;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001035 ssize_t ret;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001036 struct il_chain_noise_data *data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001037
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001038 data = &il->chain_noise_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001039 buf = kzalloc(bufsz, GFP_KERNEL);
1040 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001041 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001042 return -ENOMEM;
1043 }
1044
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001045 pos +=
1046 scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
1047 data->active_chains);
1048 pos +=
1049 scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
1050 data->chain_noise_a);
1051 pos +=
1052 scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
1053 data->chain_noise_b);
1054 pos +=
1055 scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
1056 data->chain_noise_c);
1057 pos +=
1058 scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
1059 data->chain_signal_a);
1060 pos +=
1061 scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
1062 data->chain_signal_b);
1063 pos +=
1064 scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
1065 data->chain_signal_c);
1066 pos +=
1067 scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
1068 data->beacon_count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001069
1070 pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
1071 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001072 pos +=
1073 scnprintf(buf + pos, bufsz - pos, " %u",
1074 data->disconn_array[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001075 }
1076 pos += scnprintf(buf + pos, bufsz - pos, "\n");
1077 pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
1078 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001079 pos +=
1080 scnprintf(buf + pos, bufsz - pos, " %u",
1081 data->delta_gain_code[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001082 }
1083 pos += scnprintf(buf + pos, bufsz - pos, "\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001084 pos +=
1085 scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
1086 data->radio_write);
1087 pos +=
1088 scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
1089 data->state);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001090
1091 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1092 kfree(buf);
1093 return ret;
1094}
1095
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001096static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001097il_dbgfs_power_save_status_read(struct file *file, char __user *user_buf,
1098 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001099{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001100 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001101 char buf[60];
1102 int pos = 0;
1103 const size_t bufsz = sizeof(buf);
1104 u32 pwrsave_status;
1105
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001106 pwrsave_status =
1107 _il_rd(il, CSR_GP_CNTRL) & CSR_GP_REG_POWER_SAVE_STATUS_MSK;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001108
1109 pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001110 pos +=
1111 scnprintf(buf + pos, bufsz - pos, "%s\n",
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001112 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1113 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1114 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1115 "error");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001116
1117 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1118}
1119
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001120static ssize_t
1121il_dbgfs_clear_ucode_stats_write(struct file *file,
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001122 const char __user *user_buf, size_t count,
1123 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001124{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001125 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001126 char buf[8];
1127 int buf_size;
1128 int clear;
1129
1130 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001131 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001132 if (copy_from_user(buf, user_buf, buf_size))
1133 return -EFAULT;
1134 if (sscanf(buf, "%d", &clear) != 1)
1135 return -EFAULT;
1136
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001137 /* make request to uCode to retrieve stats information */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001138 mutex_lock(&il->mutex);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001139 il_send_stats_request(il, CMD_SYNC, true);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001140 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001141
1142 return count;
1143}
1144
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001145static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001146il_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf,
1147 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001148{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001149
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001150 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001151 int len = 0;
1152 char buf[20];
1153
Stanislaw Gruszkac8b03952012-02-03 17:31:37 +01001154 len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.flags));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001155 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1156}
1157
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001158static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001159il_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf,
1160 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001161{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001162
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001163 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001164 int len = 0;
1165 char buf[20];
1166
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001167 len =
Stanislaw Gruszkac8b03952012-02-03 17:31:37 +01001168 sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001169 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1170}
1171
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001172static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001173il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count,
1174 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001175{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001176 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001177 char *buf;
1178 int pos = 0;
1179 ssize_t ret = -EFAULT;
1180
Stanislaw Gruszka1600b872012-02-13 11:23:18 +01001181 if (il->ops->dump_fh) {
1182 ret = pos = il->ops->dump_fh(il, &buf, true);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001183 if (buf) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001184 ret =
1185 simple_read_from_buffer(user_buf, count, ppos, buf,
1186 pos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001187 kfree(buf);
1188 }
1189 }
1190
1191 return ret;
1192}
1193
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001194static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001195il_dbgfs_missed_beacon_read(struct file *file, char __user *user_buf,
1196 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001197{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001198
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001199 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001200 int pos = 0;
1201 char buf[12];
1202 const size_t bufsz = sizeof(buf);
1203
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001204 pos +=
1205 scnprintf(buf + pos, bufsz - pos, "%d\n",
1206 il->missed_beacon_threshold);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001207
1208 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1209}
1210
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001211static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001212il_dbgfs_missed_beacon_write(struct file *file, const char __user *user_buf,
1213 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001214{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001215 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001216 char buf[8];
1217 int buf_size;
1218 int missed;
1219
1220 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001221 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001222 if (copy_from_user(buf, user_buf, buf_size))
1223 return -EFAULT;
1224 if (sscanf(buf, "%d", &missed) != 1)
1225 return -EINVAL;
1226
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001227 if (missed < IL_MISSED_BEACON_THRESHOLD_MIN ||
1228 missed > IL_MISSED_BEACON_THRESHOLD_MAX)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001229 il->missed_beacon_threshold = IL_MISSED_BEACON_THRESHOLD_DEF;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001230 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001231 il->missed_beacon_threshold = missed;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001232
1233 return count;
1234}
1235
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001236static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001237il_dbgfs_force_reset_read(struct file *file, char __user *user_buf,
1238 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001239{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001240
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001241 struct il_priv *il = file->private_data;
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001242 int pos = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001243 char buf[300];
1244 const size_t bufsz = sizeof(buf);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001245 struct il_force_reset *force_reset;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001246
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001247 force_reset = &il->force_reset;
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001248
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001249 pos +=
1250 scnprintf(buf + pos, bufsz - pos, "\tnumber of reset request: %d\n",
1251 force_reset->reset_request_count);
1252 pos +=
1253 scnprintf(buf + pos, bufsz - pos,
1254 "\tnumber of reset request success: %d\n",
1255 force_reset->reset_success_count);
1256 pos +=
1257 scnprintf(buf + pos, bufsz - pos,
1258 "\tnumber of reset request reject: %d\n",
1259 force_reset->reset_reject_count);
1260 pos +=
1261 scnprintf(buf + pos, bufsz - pos, "\treset duration: %lu\n",
1262 force_reset->reset_duration);
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001263
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001264 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1265}
1266
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001267static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001268il_dbgfs_force_reset_write(struct file *file, const char __user *user_buf,
1269 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001270{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001271
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001272 int ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001273 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001274
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001275 ret = il_force_reset(il, true);
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001276
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001277 return ret ? ret : count;
1278}
1279
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001280static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001281il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf,
1282 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001283{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001284
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001285 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001286 char buf[8];
1287 int buf_size;
1288 int timeout;
1289
1290 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001291 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001292 if (copy_from_user(buf, user_buf, buf_size))
1293 return -EFAULT;
1294 if (sscanf(buf, "%d", &timeout) != 1)
1295 return -EINVAL;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001296 if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)
1297 timeout = IL_DEF_WD_TIMEOUT;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001298
Stanislaw Gruszka89ef1ed2012-02-03 17:31:59 +01001299 il->cfg->wd_timeout = timeout;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001300 il_setup_watchdog(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001301 return count;
1302}
1303
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001304DEBUGFS_READ_FILE_OPS(rx_stats);
1305DEBUGFS_READ_FILE_OPS(tx_stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001306DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
1307DEBUGFS_READ_FILE_OPS(rx_queue);
1308DEBUGFS_READ_FILE_OPS(tx_queue);
1309DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1310DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1311DEBUGFS_READ_FILE_OPS(ucode_general_stats);
1312DEBUGFS_READ_FILE_OPS(sensitivity);
1313DEBUGFS_READ_FILE_OPS(chain_noise);
1314DEBUGFS_READ_FILE_OPS(power_save_status);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001315DEBUGFS_WRITE_FILE_OPS(clear_ucode_stats);
1316DEBUGFS_WRITE_FILE_OPS(clear_traffic_stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001317DEBUGFS_READ_FILE_OPS(fh_reg);
1318DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001319DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1320DEBUGFS_READ_FILE_OPS(rxon_flags);
1321DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
1322DEBUGFS_WRITE_FILE_OPS(wd_timeout);
1323
1324/*
1325 * Create the debugfs files and directories
1326 *
1327 */
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001328int
1329il_dbgfs_register(struct il_priv *il, const char *name)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001330{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001331 struct dentry *phyd = il->hw->wiphy->debugfsdir;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001332 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1333
1334 dir_drv = debugfs_create_dir(name, phyd);
1335 if (!dir_drv)
1336 return -ENOMEM;
1337
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001338 il->debugfs_dir = dir_drv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001339
1340 dir_data = debugfs_create_dir("data", dir_drv);
1341 if (!dir_data)
1342 goto err;
1343 dir_rf = debugfs_create_dir("rf", dir_drv);
1344 if (!dir_rf)
1345 goto err;
1346 dir_debug = debugfs_create_dir("debug", dir_drv);
1347 if (!dir_debug)
1348 goto err;
1349
1350 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1351 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001352 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1353 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1354 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1355 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1356 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1357 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001358 DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR);
1359 DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001360 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
1361 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
1362 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
1363 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001364 DEBUGFS_ADD_FILE(clear_ucode_stats, dir_debug, S_IWUSR);
1365 DEBUGFS_ADD_FILE(clear_traffic_stats, dir_debug, S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001366 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
1367 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001368 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
1369 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1370 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1371 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
1372
Stanislaw Gruszka89ef1ed2012-02-03 17:31:59 +01001373 if (il->cfg->sensitivity_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001374 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
Stanislaw Gruszka89ef1ed2012-02-03 17:31:59 +01001375 if (il->cfg->chain_noise_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001376 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001377 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
1378 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
1379 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
Stanislaw Gruszka89ef1ed2012-02-03 17:31:59 +01001380 if (il->cfg->sensitivity_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001381 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001382 &il->disable_sens_cal);
Stanislaw Gruszka89ef1ed2012-02-03 17:31:59 +01001383 if (il->cfg->chain_noise_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001384 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001385 &il->disable_chain_noise_cal);
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001386 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &il->disable_tx_power_cal);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001387 return 0;
1388
1389err:
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001390 IL_ERR("Can't create the debugfs directory\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001391 il_dbgfs_unregister(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001392 return -ENOMEM;
1393}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001394EXPORT_SYMBOL(il_dbgfs_register);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001395
1396/**
1397 * Remove the debugfs files and directories
1398 *
1399 */
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001400void
1401il_dbgfs_unregister(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001402{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001403 if (!il->debugfs_dir)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001404 return;
1405
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001406 debugfs_remove_recursive(il->debugfs_dir);
1407 il->debugfs_dir = NULL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001408}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001409EXPORT_SYMBOL(il_dbgfs_unregister);