blob: f3cb45e53c05c1a5744fccd6b185eec34e017531 [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 Gruszka46bc8d42011-10-24 16:49:25 +0200364 size_t eeprom_len = il->cfg->base_params->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;
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200647 struct il_rxon_context *ctx = &il->ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800648 int pos = 0, i;
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +0100649 char buf[256];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800650 const size_t bufsz = sizeof(buf);
651
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200652 for (i = 0; i < AC_NUM; i++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100653 pos +=
654 scnprintf(buf + pos, bufsz - pos,
655 "\tcw_min\tcw_max\taifsn\ttxop\n");
656 pos +=
657 scnprintf(buf + pos, bufsz - pos,
658 "AC[%d]\t%u\t%u\t%u\t%u\n", i,
659 ctx->qos_data.def_qos_parm.ac[i].cw_min,
660 ctx->qos_data.def_qos_parm.ac[i].cw_max,
661 ctx->qos_data.def_qos_parm.ac[i].aifsn,
662 ctx->qos_data.def_qos_parm.ac[i].edca_txop);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800663 }
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +0200664
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800665 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
666}
667
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100668static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100669il_dbgfs_disable_ht40_write(struct file *file, const char __user *user_buf,
670 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800671{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200672 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800673 char buf[8];
674 int buf_size;
675 int ht40;
676
677 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100678 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800679 if (copy_from_user(buf, user_buf, buf_size))
680 return -EFAULT;
681 if (sscanf(buf, "%d", &ht40) != 1)
682 return -EFAULT;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200683 if (!il_is_any_associated(il))
684 il->disable_ht40 = ht40 ? true : false;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800685 else {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200686 IL_ERR("Sta associated with AP - "
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100687 "Change to 40MHz channel support is not allowed\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800688 return -EINVAL;
689 }
690
691 return count;
692}
693
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100694static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100695il_dbgfs_disable_ht40_read(struct file *file, char __user *user_buf,
696 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800697{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200698 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800699 char buf[100];
700 int pos = 0;
701 const size_t bufsz = sizeof(buf);
702
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100703 pos +=
704 scnprintf(buf + pos, bufsz - pos, "11n 40MHz Mode: %s\n",
705 il->disable_ht40 ? "Disabled" : "Enabled");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800706 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
707}
708
709DEBUGFS_READ_WRITE_FILE_OPS(sram);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800710DEBUGFS_READ_FILE_OPS(nvm);
711DEBUGFS_READ_FILE_OPS(stations);
712DEBUGFS_READ_FILE_OPS(channels);
713DEBUGFS_READ_FILE_OPS(status);
714DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
715DEBUGFS_READ_FILE_OPS(qos);
716DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
717
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100718static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100719il_dbgfs_traffic_log_read(struct file *file, char __user *user_buf,
720 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800721{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200722 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800723 int pos = 0, ofs = 0;
724 int cnt = 0, entry;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200725 struct il_tx_queue *txq;
726 struct il_queue *q;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200727 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800728 char *buf;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100729 int bufsz =
730 ((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
731 (il->cfg->base_params->num_of_queues * 32 * 8) + 400;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800732 const u8 *ptr;
733 ssize_t ret;
734
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200735 if (!il->txq) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200736 IL_ERR("txq not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800737 return -EAGAIN;
738 }
739 buf = kzalloc(bufsz, GFP_KERNEL);
740 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200741 IL_ERR("Can not allocate buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800742 return -ENOMEM;
743 }
744 pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200745 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
746 txq = &il->txq[cnt];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800747 q = &txq->q;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100748 pos +=
749 scnprintf(buf + pos, bufsz - pos,
750 "q[%d]: read_ptr: %u, write_ptr: %u\n", cnt,
751 q->read_ptr, q->write_ptr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800752 }
Stanislaw Gruszkad2ddf622011-08-16 14:17:04 +0200753 if (il->tx_traffic && (il_debug_level & IL_DL_TX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200754 ptr = il->tx_traffic;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100755 pos +=
756 scnprintf(buf + pos, bufsz - pos, "Tx Traffic idx: %u\n",
757 il->tx_traffic_idx);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200758 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
759 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100760 entry++, ofs += 16) {
761 pos +=
762 scnprintf(buf + pos, bufsz - pos, "0x%.4x ",
763 ofs);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800764 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
765 buf + pos, bufsz - pos, 0);
766 pos += strlen(buf + pos);
767 if (bufsz - pos > 0)
768 buf[pos++] = '\n';
769 }
770 }
771 }
772
773 pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100774 pos +=
775 scnprintf(buf + pos, bufsz - pos, "read: %u, write: %u\n",
776 rxq->read, rxq->write);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800777
Stanislaw Gruszkad2ddf622011-08-16 14:17:04 +0200778 if (il->rx_traffic && (il_debug_level & IL_DL_RX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200779 ptr = il->rx_traffic;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100780 pos +=
781 scnprintf(buf + pos, bufsz - pos, "Rx Traffic idx: %u\n",
782 il->rx_traffic_idx);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200783 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
784 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100785 entry++, ofs += 16) {
786 pos +=
787 scnprintf(buf + pos, bufsz - pos, "0x%.4x ",
788 ofs);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800789 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
790 buf + pos, bufsz - pos, 0);
791 pos += strlen(buf + pos);
792 if (bufsz - pos > 0)
793 buf[pos++] = '\n';
794 }
795 }
796 }
797
798 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
799 kfree(buf);
800 return ret;
801}
802
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100803static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100804il_dbgfs_traffic_log_write(struct file *file, const char __user *user_buf,
805 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800806{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200807 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800808 char buf[8];
809 int buf_size;
810 int traffic_log;
811
812 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100813 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800814 if (copy_from_user(buf, user_buf, buf_size))
815 return -EFAULT;
816 if (sscanf(buf, "%d", &traffic_log) != 1)
817 return -EFAULT;
818 if (traffic_log == 0)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200819 il_reset_traffic_log(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800820
821 return count;
822}
823
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100824static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100825il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,
826 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100827{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800828
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200829 struct il_priv *il = file->private_data;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200830 struct il_tx_queue *txq;
831 struct il_queue *q;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800832 char *buf;
833 int pos = 0;
834 int cnt;
835 int ret;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100836 const size_t bufsz =
837 sizeof(char) * 64 * il->cfg->base_params->num_of_queues;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800838
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200839 if (!il->txq) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200840 IL_ERR("txq not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800841 return -EAGAIN;
842 }
843 buf = kzalloc(bufsz, GFP_KERNEL);
844 if (!buf)
845 return -ENOMEM;
846
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200847 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
848 txq = &il->txq[cnt];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800849 q = &txq->q;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100850 pos +=
851 scnprintf(buf + pos, bufsz - pos,
852 "hwq %.2d: read=%u write=%u stop=%d"
853 " swq_id=%#.2x (ac %d/hwq %d)\n", cnt,
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100854 q->read_ptr, q->write_ptr,
855 !!test_bit(cnt, il->queue_stopped),
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100856 txq->swq_id, txq->swq_id & 3,
857 (txq->swq_id >> 2) & 0x1f);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800858 if (cnt >= 4)
859 continue;
860 /* for the ACs, display the stop count too */
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100861 pos +=
862 scnprintf(buf + pos, bufsz - pos,
863 " stop-count: %d\n",
864 atomic_read(&il->queue_stop_count[cnt]));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800865 }
866 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
867 kfree(buf);
868 return ret;
869}
870
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100871static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100872il_dbgfs_rx_queue_read(struct file *file, char __user *user_buf, size_t count,
873 loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100874{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800875
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200876 struct il_priv *il = file->private_data;
877 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800878 char buf[256];
879 int pos = 0;
880 const size_t bufsz = sizeof(buf);
881
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100882 pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n", rxq->read);
883 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", rxq->write);
884 pos +=
885 scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
886 rxq->free_count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800887 if (rxq->rb_stts) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100888 pos +=
889 scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
890 le16_to_cpu(rxq->rb_stts->
891 closed_rb_num) & 0x0FFF);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800892 } else {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100893 pos +=
894 scnprintf(buf + pos, bufsz - pos,
895 "closed_rb_num: Not Allocated\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800896 }
897 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
898}
899
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100900static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100901il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf,
902 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800903{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200904 struct il_priv *il = file->private_data;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100905 return il->cfg->ops->lib->debugfs_ops.rx_stats_read(file, user_buf,
906 count, ppos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800907}
908
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100909static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100910il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf,
911 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800912{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200913 struct il_priv *il = file->private_data;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100914 return il->cfg->ops->lib->debugfs_ops.tx_stats_read(file, user_buf,
915 count, ppos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800916}
917
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100918static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100919il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf,
920 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800921{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200922 struct il_priv *il = file->private_data;
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100923 return il->cfg->ops->lib->debugfs_ops.general_stats_read(file, user_buf,
924 count, ppos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800925}
926
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100927static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +0100928il_dbgfs_sensitivity_read(struct file *file, char __user *user_buf,
929 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100930{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800931
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200932 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800933 int pos = 0;
934 int cnt = 0;
935 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200936 int bufsz = sizeof(struct il_sensitivity_data) * 4 + 100;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800937 ssize_t ret;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200938 struct il_sensitivity_data *data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800939
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200940 data = &il->sensitivity_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800941 buf = kzalloc(bufsz, GFP_KERNEL);
942 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200943 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800944 return -ENOMEM;
945 }
946
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100947 pos +=
948 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
949 data->auto_corr_ofdm);
950 pos +=
951 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc:\t\t %u\n",
952 data->auto_corr_ofdm_mrc);
953 pos +=
954 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
955 data->auto_corr_ofdm_x1);
956 pos +=
957 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc_x1:\t\t %u\n",
958 data->auto_corr_ofdm_mrc_x1);
959 pos +=
960 scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
961 data->auto_corr_cck);
962 pos +=
963 scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
964 data->auto_corr_cck_mrc);
965 pos +=
966 scnprintf(buf + pos, bufsz - pos,
967 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
968 data->last_bad_plcp_cnt_ofdm);
969 pos +=
970 scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
971 data->last_fa_cnt_ofdm);
972 pos +=
973 scnprintf(buf + pos, bufsz - pos, "last_bad_plcp_cnt_cck:\t\t %u\n",
974 data->last_bad_plcp_cnt_cck);
975 pos +=
976 scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
977 data->last_fa_cnt_cck);
978 pos +=
979 scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
980 data->nrg_curr_state);
981 pos +=
982 scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
983 data->nrg_prev_state);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800984 pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
985 for (cnt = 0; cnt < 10; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100986 pos +=
987 scnprintf(buf + pos, bufsz - pos, " %u",
988 data->nrg_value[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800989 }
990 pos += scnprintf(buf + pos, bufsz - pos, "\n");
991 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
992 for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100993 pos +=
994 scnprintf(buf + pos, bufsz - pos, " %u",
995 data->nrg_silence_rssi[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800996 }
997 pos += scnprintf(buf + pos, bufsz - pos, "\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +0100998 pos +=
999 scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
1000 data->nrg_silence_ref);
1001 pos +=
1002 scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
1003 data->nrg_energy_idx);
1004 pos +=
1005 scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
1006 data->nrg_silence_idx);
1007 pos +=
1008 scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
1009 data->nrg_th_cck);
1010 pos +=
1011 scnprintf(buf + pos, bufsz - pos,
1012 "nrg_auto_corr_silence_diff:\t %u\n",
1013 data->nrg_auto_corr_silence_diff);
1014 pos +=
1015 scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
1016 data->num_in_cck_no_fa);
1017 pos +=
1018 scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
1019 data->nrg_th_ofdm);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001020
1021 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1022 kfree(buf);
1023 return ret;
1024}
1025
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001026static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001027il_dbgfs_chain_noise_read(struct file *file, char __user *user_buf,
1028 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001029{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001030
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001031 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001032 int pos = 0;
1033 int cnt = 0;
1034 char *buf;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001035 int bufsz = sizeof(struct il_chain_noise_data) * 4 + 100;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001036 ssize_t ret;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001037 struct il_chain_noise_data *data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001038
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001039 data = &il->chain_noise_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001040 buf = kzalloc(bufsz, GFP_KERNEL);
1041 if (!buf) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001042 IL_ERR("Can not allocate Buffer\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001043 return -ENOMEM;
1044 }
1045
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001046 pos +=
1047 scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
1048 data->active_chains);
1049 pos +=
1050 scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
1051 data->chain_noise_a);
1052 pos +=
1053 scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
1054 data->chain_noise_b);
1055 pos +=
1056 scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
1057 data->chain_noise_c);
1058 pos +=
1059 scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
1060 data->chain_signal_a);
1061 pos +=
1062 scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
1063 data->chain_signal_b);
1064 pos +=
1065 scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
1066 data->chain_signal_c);
1067 pos +=
1068 scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
1069 data->beacon_count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001070
1071 pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
1072 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001073 pos +=
1074 scnprintf(buf + pos, bufsz - pos, " %u",
1075 data->disconn_array[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001076 }
1077 pos += scnprintf(buf + pos, bufsz - pos, "\n");
1078 pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
1079 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001080 pos +=
1081 scnprintf(buf + pos, bufsz - pos, " %u",
1082 data->delta_gain_code[cnt]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001083 }
1084 pos += scnprintf(buf + pos, bufsz - pos, "\n");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001085 pos +=
1086 scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
1087 data->radio_write);
1088 pos +=
1089 scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
1090 data->state);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001091
1092 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1093 kfree(buf);
1094 return ret;
1095}
1096
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001097static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001098il_dbgfs_power_save_status_read(struct file *file, char __user *user_buf,
1099 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001100{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001101 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001102 char buf[60];
1103 int pos = 0;
1104 const size_t bufsz = sizeof(buf);
1105 u32 pwrsave_status;
1106
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001107 pwrsave_status =
1108 _il_rd(il, CSR_GP_CNTRL) & CSR_GP_REG_POWER_SAVE_STATUS_MSK;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001109
1110 pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001111 pos +=
1112 scnprintf(buf + pos, bufsz - pos, "%s\n",
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001113 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1114 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1115 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1116 "error");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001117
1118 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1119}
1120
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001121static ssize_t
1122il_dbgfs_clear_ucode_stats_write(struct file *file,
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001123 const char __user *user_buf, size_t count,
1124 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001125{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001126 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001127 char buf[8];
1128 int buf_size;
1129 int clear;
1130
1131 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001132 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001133 if (copy_from_user(buf, user_buf, buf_size))
1134 return -EFAULT;
1135 if (sscanf(buf, "%d", &clear) != 1)
1136 return -EFAULT;
1137
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001138 /* make request to uCode to retrieve stats information */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001139 mutex_lock(&il->mutex);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001140 il_send_stats_request(il, CMD_SYNC, true);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001141 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001142
1143 return count;
1144}
1145
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001146static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001147il_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf,
1148 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001149{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001150
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001151 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001152 int len = 0;
1153 char buf[20];
1154
Stanislaw Gruszkac8b03952012-02-03 17:31:37 +01001155 len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.flags));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001156 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1157}
1158
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001159static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001160il_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf,
1161 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001162{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001163
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001164 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001165 int len = 0;
1166 char buf[20];
1167
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001168 len =
Stanislaw Gruszkac8b03952012-02-03 17:31:37 +01001169 sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001170 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1171}
1172
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001173static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001174il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count,
1175 loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001176{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001177 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001178 char *buf;
1179 int pos = 0;
1180 ssize_t ret = -EFAULT;
1181
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001182 if (il->cfg->ops->lib->dump_fh) {
1183 ret = pos = il->cfg->ops->lib->dump_fh(il, &buf, true);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001184 if (buf) {
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001185 ret =
1186 simple_read_from_buffer(user_buf, count, ppos, buf,
1187 pos);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001188 kfree(buf);
1189 }
1190 }
1191
1192 return ret;
1193}
1194
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001195static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001196il_dbgfs_missed_beacon_read(struct file *file, char __user *user_buf,
1197 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001198{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001199
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001200 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001201 int pos = 0;
1202 char buf[12];
1203 const size_t bufsz = sizeof(buf);
1204
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001205 pos +=
1206 scnprintf(buf + pos, bufsz - pos, "%d\n",
1207 il->missed_beacon_threshold);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001208
1209 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1210}
1211
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001212static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001213il_dbgfs_missed_beacon_write(struct file *file, const char __user *user_buf,
1214 size_t count, loff_t *ppos)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001215{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001216 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001217 char buf[8];
1218 int buf_size;
1219 int missed;
1220
1221 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001222 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001223 if (copy_from_user(buf, user_buf, buf_size))
1224 return -EFAULT;
1225 if (sscanf(buf, "%d", &missed) != 1)
1226 return -EINVAL;
1227
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001228 if (missed < IL_MISSED_BEACON_THRESHOLD_MIN ||
1229 missed > IL_MISSED_BEACON_THRESHOLD_MAX)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001230 il->missed_beacon_threshold = IL_MISSED_BEACON_THRESHOLD_DEF;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001231 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001232 il->missed_beacon_threshold = missed;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001233
1234 return count;
1235}
1236
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001237static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001238il_dbgfs_force_reset_read(struct file *file, char __user *user_buf,
1239 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001240{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001241
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001242 struct il_priv *il = file->private_data;
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001243 int pos = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001244 char buf[300];
1245 const size_t bufsz = sizeof(buf);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001246 struct il_force_reset *force_reset;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001247
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001248 force_reset = &il->force_reset;
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001249
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001250 pos +=
1251 scnprintf(buf + pos, bufsz - pos, "\tnumber of reset request: %d\n",
1252 force_reset->reset_request_count);
1253 pos +=
1254 scnprintf(buf + pos, bufsz - pos,
1255 "\tnumber of reset request success: %d\n",
1256 force_reset->reset_success_count);
1257 pos +=
1258 scnprintf(buf + pos, bufsz - pos,
1259 "\tnumber of reset request reject: %d\n",
1260 force_reset->reset_reject_count);
1261 pos +=
1262 scnprintf(buf + pos, bufsz - pos, "\treset duration: %lu\n",
1263 force_reset->reset_duration);
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001264
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001265 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1266}
1267
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001268static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001269il_dbgfs_force_reset_write(struct file *file, const char __user *user_buf,
1270 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001271{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001272
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001273 int ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001274 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001275
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001276 ret = il_force_reset(il, true);
Stanislaw Gruszkadd6d2a82011-06-08 15:28:26 +02001277
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001278 return ret ? ret : count;
1279}
1280
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001281static ssize_t
Stanislaw Gruszka1722f8e2011-11-15 14:51:01 +01001282il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf,
1283 size_t count, loff_t *ppos)
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001284{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001285
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001286 struct il_priv *il = file->private_data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001287 char buf[8];
1288 int buf_size;
1289 int timeout;
1290
1291 memset(buf, 0, sizeof(buf));
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001292 buf_size = min(count, sizeof(buf) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001293 if (copy_from_user(buf, user_buf, buf_size))
1294 return -EFAULT;
1295 if (sscanf(buf, "%d", &timeout) != 1)
1296 return -EINVAL;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001297 if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)
1298 timeout = IL_DEF_WD_TIMEOUT;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001299
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001300 il->cfg->base_params->wd_timeout = timeout;
1301 il_setup_watchdog(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001302 return count;
1303}
1304
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001305DEBUGFS_READ_FILE_OPS(rx_stats);
1306DEBUGFS_READ_FILE_OPS(tx_stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001307DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
1308DEBUGFS_READ_FILE_OPS(rx_queue);
1309DEBUGFS_READ_FILE_OPS(tx_queue);
1310DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1311DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1312DEBUGFS_READ_FILE_OPS(ucode_general_stats);
1313DEBUGFS_READ_FILE_OPS(sensitivity);
1314DEBUGFS_READ_FILE_OPS(chain_noise);
1315DEBUGFS_READ_FILE_OPS(power_save_status);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001316DEBUGFS_WRITE_FILE_OPS(clear_ucode_stats);
1317DEBUGFS_WRITE_FILE_OPS(clear_traffic_stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001318DEBUGFS_READ_FILE_OPS(fh_reg);
1319DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001320DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1321DEBUGFS_READ_FILE_OPS(rxon_flags);
1322DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
1323DEBUGFS_WRITE_FILE_OPS(wd_timeout);
1324
1325/*
1326 * Create the debugfs files and directories
1327 *
1328 */
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001329int
1330il_dbgfs_register(struct il_priv *il, const char *name)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001331{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001332 struct dentry *phyd = il->hw->wiphy->debugfsdir;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001333 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1334
1335 dir_drv = debugfs_create_dir(name, phyd);
1336 if (!dir_drv)
1337 return -ENOMEM;
1338
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001339 il->debugfs_dir = dir_drv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001340
1341 dir_data = debugfs_create_dir("data", dir_drv);
1342 if (!dir_data)
1343 goto err;
1344 dir_rf = debugfs_create_dir("rf", dir_drv);
1345 if (!dir_rf)
1346 goto err;
1347 dir_debug = debugfs_create_dir("debug", dir_drv);
1348 if (!dir_debug)
1349 goto err;
1350
1351 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1352 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001353 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1354 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1355 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1356 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1357 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1358 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001359 DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR);
1360 DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001361 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
1362 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
1363 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
1364 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02001365 DEBUGFS_ADD_FILE(clear_ucode_stats, dir_debug, S_IWUSR);
1366 DEBUGFS_ADD_FILE(clear_traffic_stats, dir_debug, S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001367 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
1368 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001369 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
1370 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1371 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1372 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
1373
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001374 if (il->cfg->base_params->sensitivity_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001375 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001376 if (il->cfg->base_params->chain_noise_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001377 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001378 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
1379 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
1380 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001381 if (il->cfg->base_params->sensitivity_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001382 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001383 &il->disable_sens_cal);
1384 if (il->cfg->base_params->chain_noise_calib_by_driver)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001385 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001386 &il->disable_chain_noise_cal);
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001387 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &il->disable_tx_power_cal);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001388 return 0;
1389
1390err:
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001391 IL_ERR("Can't create the debugfs directory\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001392 il_dbgfs_unregister(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001393 return -ENOMEM;
1394}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001395EXPORT_SYMBOL(il_dbgfs_register);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001396
1397/**
1398 * Remove the debugfs files and directories
1399 *
1400 */
Stanislaw Gruszkae7392362011-11-15 14:45:59 +01001401void
1402il_dbgfs_unregister(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001403{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001404 if (!il->debugfs_dir)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001405 return;
1406
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001407 debugfs_remove_recursive(il->debugfs_dir);
1408 il->debugfs_dir = NULL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001409}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001410EXPORT_SYMBOL(il_dbgfs_unregister);