]> Pileus Git - ~andy/linux/blob - drivers/net/wireless/iwlwifi/iwl-debugfs.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[~andy/linux] / drivers / net / wireless / iwlwifi / iwl-debugfs.c
1 /******************************************************************************
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
29 #include <linux/slab.h>
30 #include <linux/kernel.h>
31 #include <linux/module.h>
32 #include <linux/debugfs.h>
33
34 #include <linux/ieee80211.h>
35 #include <net/mac80211.h>
36
37
38 #include "iwl-dev.h"
39 #include "iwl-debug.h"
40 #include "iwl-core.h"
41 #include "iwl-io.h"
42 #include "iwl-agn.h"
43
44 /* create and remove of files */
45 #define DEBUGFS_ADD_FILE(name, parent, mode) do {                       \
46         if (!debugfs_create_file(#name, mode, parent, priv,             \
47                                  &iwl_dbgfs_##name##_ops))              \
48                 goto err;                                               \
49 } while (0)
50
51 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do {                        \
52         struct dentry *__tmp;                                           \
53         __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR,           \
54                                     parent, ptr);                       \
55         if (IS_ERR(__tmp) || !__tmp)                                    \
56                 goto err;                                               \
57 } while (0)
58
59 #define DEBUGFS_ADD_X32(name, parent, ptr) do {                         \
60         struct dentry *__tmp;                                           \
61         __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR,            \
62                                    parent, ptr);                        \
63         if (IS_ERR(__tmp) || !__tmp)                                    \
64                 goto err;                                               \
65 } while (0)
66
67 /* file operation */
68 #define DEBUGFS_READ_FUNC(name)                                         \
69 static ssize_t iwl_dbgfs_##name##_read(struct file *file,               \
70                                         char __user *user_buf,          \
71                                         size_t count, loff_t *ppos);
72
73 #define DEBUGFS_WRITE_FUNC(name)                                        \
74 static ssize_t iwl_dbgfs_##name##_write(struct file *file,              \
75                                         const char __user *user_buf,    \
76                                         size_t count, loff_t *ppos);
77
78
79 static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
80 {
81         file->private_data = inode->i_private;
82         return 0;
83 }
84
85 #define DEBUGFS_READ_FILE_OPS(name)                                     \
86         DEBUGFS_READ_FUNC(name);                                        \
87 static const struct file_operations iwl_dbgfs_##name##_ops = {          \
88         .read = iwl_dbgfs_##name##_read,                                \
89         .open = iwl_dbgfs_open_file_generic,                            \
90         .llseek = generic_file_llseek,                                  \
91 };
92
93 #define DEBUGFS_WRITE_FILE_OPS(name)                                    \
94         DEBUGFS_WRITE_FUNC(name);                                       \
95 static const struct file_operations iwl_dbgfs_##name##_ops = {          \
96         .write = iwl_dbgfs_##name##_write,                              \
97         .open = iwl_dbgfs_open_file_generic,                            \
98         .llseek = generic_file_llseek,                                  \
99 };
100
101
102 #define DEBUGFS_READ_WRITE_FILE_OPS(name)                               \
103         DEBUGFS_READ_FUNC(name);                                        \
104         DEBUGFS_WRITE_FUNC(name);                                       \
105 static const struct file_operations iwl_dbgfs_##name##_ops = {          \
106         .write = iwl_dbgfs_##name##_write,                              \
107         .read = iwl_dbgfs_##name##_read,                                \
108         .open = iwl_dbgfs_open_file_generic,                            \
109         .llseek = generic_file_llseek,                                  \
110 };
111
112 static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
113                                                 char __user *user_buf,
114                                                 size_t count, loff_t *ppos) {
115
116         struct iwl_priv *priv = file->private_data;
117         char *buf;
118         int pos = 0;
119
120         int cnt;
121         ssize_t ret;
122         const size_t bufsz = 100 +
123                 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
124         buf = kzalloc(bufsz, GFP_KERNEL);
125         if (!buf)
126                 return -ENOMEM;
127         pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
128         for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
129                 pos += scnprintf(buf + pos, bufsz - pos,
130                                  "\t%25s\t\t: %u\n",
131                                  get_mgmt_string(cnt),
132                                  priv->tx_stats.mgmt[cnt]);
133         }
134         pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
135         for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
136                 pos += scnprintf(buf + pos, bufsz - pos,
137                                  "\t%25s\t\t: %u\n",
138                                  get_ctrl_string(cnt),
139                                  priv->tx_stats.ctrl[cnt]);
140         }
141         pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
142         pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
143                          priv->tx_stats.data_cnt);
144         pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
145                          priv->tx_stats.data_bytes);
146         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
147         kfree(buf);
148         return ret;
149 }
150
151 static ssize_t iwl_dbgfs_clear_traffic_statistics_write(struct file *file,
152                                         const char __user *user_buf,
153                                         size_t count, loff_t *ppos)
154 {
155         struct iwl_priv *priv = file->private_data;
156         u32 clear_flag;
157         char buf[8];
158         int buf_size;
159
160         memset(buf, 0, sizeof(buf));
161         buf_size = min(count, sizeof(buf) -  1);
162         if (copy_from_user(buf, user_buf, buf_size))
163                 return -EFAULT;
164         if (sscanf(buf, "%x", &clear_flag) != 1)
165                 return -EFAULT;
166         iwl_clear_traffic_stats(priv);
167
168         return count;
169 }
170
171 static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
172                                                 char __user *user_buf,
173                                                 size_t count, loff_t *ppos) {
174
175         struct iwl_priv *priv = file->private_data;
176         char *buf;
177         int pos = 0;
178         int cnt;
179         ssize_t ret;
180         const size_t bufsz = 100 +
181                 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
182         buf = kzalloc(bufsz, GFP_KERNEL);
183         if (!buf)
184                 return -ENOMEM;
185
186         pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
187         for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
188                 pos += scnprintf(buf + pos, bufsz - pos,
189                                  "\t%25s\t\t: %u\n",
190                                  get_mgmt_string(cnt),
191                                  priv->rx_stats.mgmt[cnt]);
192         }
193         pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
194         for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
195                 pos += scnprintf(buf + pos, bufsz - pos,
196                                  "\t%25s\t\t: %u\n",
197                                  get_ctrl_string(cnt),
198                                  priv->rx_stats.ctrl[cnt]);
199         }
200         pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
201         pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
202                          priv->rx_stats.data_cnt);
203         pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
204                          priv->rx_stats.data_bytes);
205
206         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
207         kfree(buf);
208         return ret;
209 }
210
211 static ssize_t iwl_dbgfs_sram_read(struct file *file,
212                                         char __user *user_buf,
213                                         size_t count, loff_t *ppos)
214 {
215         u32 val = 0;
216         char *buf;
217         ssize_t ret;
218         int i = 0;
219         bool device_format = false;
220         int offset = 0;
221         int len = 0;
222         int pos = 0;
223         int sram;
224         struct iwl_priv *priv = file->private_data;
225         size_t bufsz;
226
227         /* default is to dump the entire data segment */
228         if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
229                 priv->dbgfs_sram_offset = 0x800000;
230                 if (priv->ucode_type == IWL_UCODE_INIT)
231                         priv->dbgfs_sram_len = priv->ucode_init.data.len;
232                 else
233                         priv->dbgfs_sram_len = priv->ucode_rt.data.len;
234         }
235         len = priv->dbgfs_sram_len;
236
237         if (len == -4) {
238                 device_format = true;
239                 len = 4;
240         }
241
242         bufsz =  50 + len * 4;
243         buf = kmalloc(bufsz, GFP_KERNEL);
244         if (!buf)
245                 return -ENOMEM;
246
247         pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
248                          len);
249         pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
250                         priv->dbgfs_sram_offset);
251
252         /* adjust sram address since reads are only on even u32 boundaries */
253         offset = priv->dbgfs_sram_offset & 0x3;
254         sram = priv->dbgfs_sram_offset & ~0x3;
255
256         /* read the first u32 from sram */
257         val = iwl_read_targ_mem(priv, sram);
258
259         for (; len; len--) {
260                 /* put the address at the start of every line */
261                 if (i == 0)
262                         pos += scnprintf(buf + pos, bufsz - pos,
263                                 "%08X: ", sram + offset);
264
265                 if (device_format)
266                         pos += scnprintf(buf + pos, bufsz - pos,
267                                 "%02x", (val >> (8 * (3 - offset))) & 0xff);
268                 else
269                         pos += scnprintf(buf + pos, bufsz - pos,
270                                 "%02x ", (val >> (8 * offset)) & 0xff);
271
272                 /* if all bytes processed, read the next u32 from sram */
273                 if (++offset == 4) {
274                         sram += 4;
275                         offset = 0;
276                         val = iwl_read_targ_mem(priv, sram);
277                 }
278
279                 /* put in extra spaces and split lines for human readability */
280                 if (++i == 16) {
281                         i = 0;
282                         pos += scnprintf(buf + pos, bufsz - pos, "\n");
283                 } else if (!(i & 7)) {
284                         pos += scnprintf(buf + pos, bufsz - pos, "   ");
285                 } else if (!(i & 3)) {
286                         pos += scnprintf(buf + pos, bufsz - pos, " ");
287                 }
288         }
289         if (i)
290                 pos += scnprintf(buf + pos, bufsz - pos, "\n");
291
292         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
293         kfree(buf);
294         return ret;
295 }
296
297 static ssize_t iwl_dbgfs_sram_write(struct file *file,
298                                         const char __user *user_buf,
299                                         size_t count, loff_t *ppos)
300 {
301         struct iwl_priv *priv = file->private_data;
302         char buf[64];
303         int buf_size;
304         u32 offset, len;
305
306         memset(buf, 0, sizeof(buf));
307         buf_size = min(count, sizeof(buf) -  1);
308         if (copy_from_user(buf, user_buf, buf_size))
309                 return -EFAULT;
310
311         if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
312                 priv->dbgfs_sram_offset = offset;
313                 priv->dbgfs_sram_len = len;
314         } else if (sscanf(buf, "%x", &offset) == 1) {
315                 priv->dbgfs_sram_offset = offset;
316                 priv->dbgfs_sram_len = -4;
317         } else {
318                 priv->dbgfs_sram_offset = 0;
319                 priv->dbgfs_sram_len = 0;
320         }
321
322         return count;
323 }
324
325 static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
326                                           char __user *user_buf,
327                                           size_t count, loff_t *ppos)
328 {
329         struct iwl_priv *priv = file->private_data;
330
331         if (!priv->wowlan_sram)
332                 return -ENODATA;
333
334         return simple_read_from_buffer(user_buf, count, ppos,
335                                        priv->wowlan_sram,
336                                        priv->ucode_wowlan.data.len);
337 }
338 static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
339                                         size_t count, loff_t *ppos)
340 {
341         struct iwl_priv *priv = file->private_data;
342         struct iwl_station_entry *station;
343         int max_sta = priv->hw_params.max_stations;
344         char *buf;
345         int i, j, pos = 0;
346         ssize_t ret;
347         /* Add 30 for initial string */
348         const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations);
349
350         buf = kmalloc(bufsz, GFP_KERNEL);
351         if (!buf)
352                 return -ENOMEM;
353
354         pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
355                         priv->num_stations);
356
357         for (i = 0; i < max_sta; i++) {
358                 station = &priv->stations[i];
359                 if (!station->used)
360                         continue;
361                 pos += scnprintf(buf + pos, bufsz - pos,
362                                  "station %d - addr: %pM, flags: %#x\n",
363                                  i, station->sta.sta.addr,
364                                  station->sta.station_flags_msk);
365                 pos += scnprintf(buf + pos, bufsz - pos,
366                                 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
367                 pos += scnprintf(buf + pos, bufsz - pos,
368                                 "start_idx\tbitmap\t\t\trate_n_flags\n");
369
370                 for (j = 0; j < MAX_TID_COUNT; j++) {
371                         pos += scnprintf(buf + pos, bufsz - pos,
372                                 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
373                                 j, station->tid[j].seq_number,
374                                 station->tid[j].agg.txq_id,
375                                 station->tid[j].agg.frame_count,
376                                 station->tid[j].tfds_in_queue,
377                                 station->tid[j].agg.start_idx,
378                                 station->tid[j].agg.bitmap,
379                                 station->tid[j].agg.rate_n_flags);
380
381                         if (station->tid[j].agg.wait_for_ba)
382                                 pos += scnprintf(buf + pos, bufsz - pos,
383                                                  " - waitforba");
384                         pos += scnprintf(buf + pos, bufsz - pos, "\n");
385                 }
386
387                 pos += scnprintf(buf + pos, bufsz - pos, "\n");
388         }
389
390         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
391         kfree(buf);
392         return ret;
393 }
394
395 static ssize_t iwl_dbgfs_nvm_read(struct file *file,
396                                        char __user *user_buf,
397                                        size_t count,
398                                        loff_t *ppos)
399 {
400         ssize_t ret;
401         struct iwl_priv *priv = file->private_data;
402         int pos = 0, ofs = 0, buf_size = 0;
403         const u8 *ptr;
404         char *buf;
405         u16 eeprom_ver;
406         size_t eeprom_len = priv->cfg->base_params->eeprom_size;
407         buf_size = 4 * eeprom_len + 256;
408
409         if (eeprom_len % 16) {
410                 IWL_ERR(priv, "NVM size is not multiple of 16.\n");
411                 return -ENODATA;
412         }
413
414         ptr = priv->eeprom;
415         if (!ptr) {
416                 IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
417                 return -ENOMEM;
418         }
419
420         /* 4 characters for byte 0xYY */
421         buf = kzalloc(buf_size, GFP_KERNEL);
422         if (!buf) {
423                 IWL_ERR(priv, "Can not allocate Buffer\n");
424                 return -ENOMEM;
425         }
426         eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
427         pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, "
428                         "version: 0x%x\n",
429                         (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
430                          ? "OTP" : "EEPROM", eeprom_ver);
431         for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
432                 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
433                 hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
434                                    buf_size - pos, 0);
435                 pos += strlen(buf + pos);
436                 if (buf_size - pos > 0)
437                         buf[pos++] = '\n';
438         }
439
440         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
441         kfree(buf);
442         return ret;
443 }
444
445 static ssize_t iwl_dbgfs_log_event_read(struct file *file,
446                                          char __user *user_buf,
447                                          size_t count, loff_t *ppos)
448 {
449         struct iwl_priv *priv = file->private_data;
450         char *buf;
451         int pos = 0;
452         ssize_t ret = -ENOMEM;
453
454         ret = pos = iwl_dump_nic_event_log(priv, true, &buf, true);
455         if (buf) {
456                 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
457                 kfree(buf);
458         }
459         return ret;
460 }
461
462 static ssize_t iwl_dbgfs_log_event_write(struct file *file,
463                                         const char __user *user_buf,
464                                         size_t count, loff_t *ppos)
465 {
466         struct iwl_priv *priv = file->private_data;
467         u32 event_log_flag;
468         char buf[8];
469         int buf_size;
470
471         memset(buf, 0, sizeof(buf));
472         buf_size = min(count, sizeof(buf) -  1);
473         if (copy_from_user(buf, user_buf, buf_size))
474                 return -EFAULT;
475         if (sscanf(buf, "%d", &event_log_flag) != 1)
476                 return -EFAULT;
477         if (event_log_flag == 1)
478                 iwl_dump_nic_event_log(priv, true, NULL, false);
479
480         return count;
481 }
482
483
484
485 static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
486                                        size_t count, loff_t *ppos)
487 {
488         struct iwl_priv *priv = file->private_data;
489         struct ieee80211_channel *channels = NULL;
490         const struct ieee80211_supported_band *supp_band = NULL;
491         int pos = 0, i, bufsz = PAGE_SIZE;
492         char *buf;
493         ssize_t ret;
494
495         if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
496                 return -EAGAIN;
497
498         buf = kzalloc(bufsz, GFP_KERNEL);
499         if (!buf) {
500                 IWL_ERR(priv, "Can not allocate Buffer\n");
501                 return -ENOMEM;
502         }
503
504         supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
505         if (supp_band) {
506                 channels = supp_band->channels;
507
508                 pos += scnprintf(buf + pos, bufsz - pos,
509                                 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
510                                 supp_band->n_channels);
511
512                 for (i = 0; i < supp_band->n_channels; i++)
513                         pos += scnprintf(buf + pos, bufsz - pos,
514                                         "%d: %ddBm: BSS%s%s, %s.\n",
515                                         channels[i].hw_value,
516                                         channels[i].max_power,
517                                         channels[i].flags & IEEE80211_CHAN_RADAR ?
518                                         " (IEEE 802.11h required)" : "",
519                                         ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
520                                         || (channels[i].flags &
521                                         IEEE80211_CHAN_RADAR)) ? "" :
522                                         ", IBSS",
523                                         channels[i].flags &
524                                         IEEE80211_CHAN_PASSIVE_SCAN ?
525                                         "passive only" : "active/passive");
526         }
527         supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
528         if (supp_band) {
529                 channels = supp_band->channels;
530
531                 pos += scnprintf(buf + pos, bufsz - pos,
532                                 "Displaying %d channels in 5.2GHz band (802.11a)\n",
533                                 supp_band->n_channels);
534
535                 for (i = 0; i < supp_band->n_channels; i++)
536                         pos += scnprintf(buf + pos, bufsz - pos,
537                                         "%d: %ddBm: BSS%s%s, %s.\n",
538                                         channels[i].hw_value,
539                                         channels[i].max_power,
540                                         channels[i].flags & IEEE80211_CHAN_RADAR ?
541                                         " (IEEE 802.11h required)" : "",
542                                         ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
543                                         || (channels[i].flags &
544                                         IEEE80211_CHAN_RADAR)) ? "" :
545                                         ", IBSS",
546                                         channels[i].flags &
547                                         IEEE80211_CHAN_PASSIVE_SCAN ?
548                                         "passive only" : "active/passive");
549         }
550         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
551         kfree(buf);
552         return ret;
553 }
554
555 static ssize_t iwl_dbgfs_status_read(struct file *file,
556                                                 char __user *user_buf,
557                                                 size_t count, loff_t *ppos) {
558
559         struct iwl_priv *priv = file->private_data;
560         char buf[512];
561         int pos = 0;
562         const size_t bufsz = sizeof(buf);
563
564         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
565                 test_bit(STATUS_HCMD_ACTIVE, &priv->status));
566         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
567                 test_bit(STATUS_INT_ENABLED, &priv->status));
568         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
569                 test_bit(STATUS_RF_KILL_HW, &priv->status));
570         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n",
571                 test_bit(STATUS_CT_KILL, &priv->status));
572         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
573                 test_bit(STATUS_INIT, &priv->status));
574         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
575                 test_bit(STATUS_ALIVE, &priv->status));
576         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
577                 test_bit(STATUS_READY, &priv->status));
578         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
579                 test_bit(STATUS_TEMPERATURE, &priv->status));
580         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
581                 test_bit(STATUS_GEO_CONFIGURED, &priv->status));
582         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
583                 test_bit(STATUS_EXIT_PENDING, &priv->status));
584         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
585                 test_bit(STATUS_STATISTICS, &priv->status));
586         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
587                 test_bit(STATUS_SCANNING, &priv->status));
588         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
589                 test_bit(STATUS_SCAN_ABORTING, &priv->status));
590         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
591                 test_bit(STATUS_SCAN_HW, &priv->status));
592         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
593                 test_bit(STATUS_POWER_PMI, &priv->status));
594         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
595                 test_bit(STATUS_FW_ERROR, &priv->status));
596         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
597 }
598
599 static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
600                                         char __user *user_buf,
601                                         size_t count, loff_t *ppos) {
602
603         struct iwl_priv *priv = file->private_data;
604         int pos = 0;
605         int cnt = 0;
606         char *buf;
607         int bufsz = 24 * 64; /* 24 items * 64 char per item */
608         ssize_t ret;
609
610         buf = kzalloc(bufsz, GFP_KERNEL);
611         if (!buf) {
612                 IWL_ERR(priv, "Can not allocate Buffer\n");
613                 return -ENOMEM;
614         }
615
616         pos += scnprintf(buf + pos, bufsz - pos,
617                         "Interrupt Statistics Report:\n");
618
619         pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
620                 priv->isr_stats.hw);
621         pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
622                 priv->isr_stats.sw);
623         if (priv->isr_stats.sw || priv->isr_stats.hw) {
624                 pos += scnprintf(buf + pos, bufsz - pos,
625                         "\tLast Restarting Code:  0x%X\n",
626                         priv->isr_stats.err_code);
627         }
628 #ifdef CONFIG_IWLWIFI_DEBUG
629         pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
630                 priv->isr_stats.sch);
631         pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
632                 priv->isr_stats.alive);
633 #endif
634         pos += scnprintf(buf + pos, bufsz - pos,
635                 "HW RF KILL switch toggled:\t %u\n",
636                 priv->isr_stats.rfkill);
637
638         pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
639                 priv->isr_stats.ctkill);
640
641         pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
642                 priv->isr_stats.wakeup);
643
644         pos += scnprintf(buf + pos, bufsz - pos,
645                 "Rx command responses:\t\t %u\n",
646                 priv->isr_stats.rx);
647         for (cnt = 0; cnt < REPLY_MAX; cnt++) {
648                 if (priv->isr_stats.rx_handlers[cnt] > 0)
649                         pos += scnprintf(buf + pos, bufsz - pos,
650                                 "\tRx handler[%36s]:\t\t %u\n",
651                                 get_cmd_string(cnt),
652                                 priv->isr_stats.rx_handlers[cnt]);
653         }
654
655         pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
656                 priv->isr_stats.tx);
657
658         pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
659                 priv->isr_stats.unhandled);
660
661         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
662         kfree(buf);
663         return ret;
664 }
665
666 static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
667                                          const char __user *user_buf,
668                                          size_t count, loff_t *ppos)
669 {
670         struct iwl_priv *priv = file->private_data;
671         char buf[8];
672         int buf_size;
673         u32 reset_flag;
674
675         memset(buf, 0, sizeof(buf));
676         buf_size = min(count, sizeof(buf) -  1);
677         if (copy_from_user(buf, user_buf, buf_size))
678                 return -EFAULT;
679         if (sscanf(buf, "%x", &reset_flag) != 1)
680                 return -EFAULT;
681         if (reset_flag == 0)
682                 iwl_clear_isr_stats(priv);
683
684         return count;
685 }
686
687 static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
688                                        size_t count, loff_t *ppos)
689 {
690         struct iwl_priv *priv = file->private_data;
691         struct iwl_rxon_context *ctx;
692         int pos = 0, i;
693         char buf[256 * NUM_IWL_RXON_CTX];
694         const size_t bufsz = sizeof(buf);
695
696         for_each_context(priv, ctx) {
697                 pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n",
698                                  ctx->ctxid);
699                 for (i = 0; i < AC_NUM; i++) {
700                         pos += scnprintf(buf + pos, bufsz - pos,
701                                 "\tcw_min\tcw_max\taifsn\ttxop\n");
702                         pos += scnprintf(buf + pos, bufsz - pos,
703                                 "AC[%d]\t%u\t%u\t%u\t%u\n", i,
704                                 ctx->qos_data.def_qos_parm.ac[i].cw_min,
705                                 ctx->qos_data.def_qos_parm.ac[i].cw_max,
706                                 ctx->qos_data.def_qos_parm.ac[i].aifsn,
707                                 ctx->qos_data.def_qos_parm.ac[i].edca_txop);
708                 }
709                 pos += scnprintf(buf + pos, bufsz - pos, "\n");
710         }
711         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
712 }
713
714 static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
715                                 char __user *user_buf,
716                                 size_t count, loff_t *ppos)
717 {
718         struct iwl_priv *priv = file->private_data;
719         struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
720         struct iwl_tt_restriction *restriction;
721         char buf[100];
722         int pos = 0;
723         const size_t bufsz = sizeof(buf);
724
725         pos += scnprintf(buf + pos, bufsz - pos,
726                         "Thermal Throttling Mode: %s\n",
727                         tt->advanced_tt ? "Advance" : "Legacy");
728         pos += scnprintf(buf + pos, bufsz - pos,
729                         "Thermal Throttling State: %d\n",
730                         tt->state);
731         if (tt->advanced_tt) {
732                 restriction = tt->restriction + tt->state;
733                 pos += scnprintf(buf + pos, bufsz - pos,
734                                 "Tx mode: %d\n",
735                                 restriction->tx_stream);
736                 pos += scnprintf(buf + pos, bufsz - pos,
737                                 "Rx mode: %d\n",
738                                 restriction->rx_stream);
739                 pos += scnprintf(buf + pos, bufsz - pos,
740                                 "HT mode: %d\n",
741                                 restriction->is_ht);
742         }
743         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
744 }
745
746 static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
747                                          const char __user *user_buf,
748                                          size_t count, loff_t *ppos)
749 {
750         struct iwl_priv *priv = file->private_data;
751         char buf[8];
752         int buf_size;
753         int ht40;
754
755         memset(buf, 0, sizeof(buf));
756         buf_size = min(count, sizeof(buf) -  1);
757         if (copy_from_user(buf, user_buf, buf_size))
758                 return -EFAULT;
759         if (sscanf(buf, "%d", &ht40) != 1)
760                 return -EFAULT;
761         if (!iwl_is_any_associated(priv))
762                 priv->disable_ht40 = ht40 ? true : false;
763         else {
764                 IWL_ERR(priv, "Sta associated with AP - "
765                         "Change to 40MHz channel support is not allowed\n");
766                 return -EINVAL;
767         }
768
769         return count;
770 }
771
772 static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
773                                          char __user *user_buf,
774                                          size_t count, loff_t *ppos)
775 {
776         struct iwl_priv *priv = file->private_data;
777         char buf[100];
778         int pos = 0;
779         const size_t bufsz = sizeof(buf);
780
781         pos += scnprintf(buf + pos, bufsz - pos,
782                         "11n 40MHz Mode: %s\n",
783                         priv->disable_ht40 ? "Disabled" : "Enabled");
784         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
785 }
786
787 static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
788                                                     const char __user *user_buf,
789                                                     size_t count, loff_t *ppos)
790 {
791         struct iwl_priv *priv = file->private_data;
792         char buf[8];
793         int buf_size;
794         int value;
795
796         memset(buf, 0, sizeof(buf));
797         buf_size = min(count, sizeof(buf) -  1);
798         if (copy_from_user(buf, user_buf, buf_size))
799                 return -EFAULT;
800
801         if (sscanf(buf, "%d", &value) != 1)
802                 return -EINVAL;
803
804         /*
805          * Our users expect 0 to be "CAM", but 0 isn't actually
806          * valid here. However, let's not confuse them and present
807          * IWL_POWER_INDEX_1 as "1", not "0".
808          */
809         if (value == 0)
810                 return -EINVAL;
811         else if (value > 0)
812                 value -= 1;
813
814         if (value != -1 && (value < 0 || value >= IWL_POWER_NUM))
815                 return -EINVAL;
816
817         if (!iwl_is_ready_rf(priv))
818                 return -EAGAIN;
819
820         priv->power_data.debug_sleep_level_override = value;
821
822         mutex_lock(&priv->mutex);
823         iwl_power_update_mode(priv, true);
824         mutex_unlock(&priv->mutex);
825
826         return count;
827 }
828
829 static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
830                                                    char __user *user_buf,
831                                                    size_t count, loff_t *ppos)
832 {
833         struct iwl_priv *priv = file->private_data;
834         char buf[10];
835         int pos, value;
836         const size_t bufsz = sizeof(buf);
837
838         /* see the write function */
839         value = priv->power_data.debug_sleep_level_override;
840         if (value >= 0)
841                 value += 1;
842
843         pos = scnprintf(buf, bufsz, "%d\n", value);
844         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
845 }
846
847 static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
848                                                     char __user *user_buf,
849                                                     size_t count, loff_t *ppos)
850 {
851         struct iwl_priv *priv = file->private_data;
852         char buf[200];
853         int pos = 0, i;
854         const size_t bufsz = sizeof(buf);
855         struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd;
856
857         pos += scnprintf(buf + pos, bufsz - pos,
858                          "flags: %#.2x\n", le16_to_cpu(cmd->flags));
859         pos += scnprintf(buf + pos, bufsz - pos,
860                          "RX/TX timeout: %d/%d usec\n",
861                          le32_to_cpu(cmd->rx_data_timeout),
862                          le32_to_cpu(cmd->tx_data_timeout));
863         for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
864                 pos += scnprintf(buf + pos, bufsz - pos,
865                                  "sleep_interval[%d]: %d\n", i,
866                                  le32_to_cpu(cmd->sleep_interval[i]));
867
868         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
869 }
870
871 DEBUGFS_READ_WRITE_FILE_OPS(sram);
872 DEBUGFS_READ_FILE_OPS(wowlan_sram);
873 DEBUGFS_READ_WRITE_FILE_OPS(log_event);
874 DEBUGFS_READ_FILE_OPS(nvm);
875 DEBUGFS_READ_FILE_OPS(stations);
876 DEBUGFS_READ_FILE_OPS(channels);
877 DEBUGFS_READ_FILE_OPS(status);
878 DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
879 DEBUGFS_READ_FILE_OPS(qos);
880 DEBUGFS_READ_FILE_OPS(thermal_throttling);
881 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
882 DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
883 DEBUGFS_READ_FILE_OPS(current_sleep_command);
884
885 static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
886                                          char __user *user_buf,
887                                          size_t count, loff_t *ppos)
888 {
889         struct iwl_priv *priv = file->private_data;
890         int pos = 0, ofs = 0;
891         int cnt = 0, entry;
892         struct iwl_tx_queue *txq;
893         struct iwl_queue *q;
894         struct iwl_rx_queue *rxq = &priv->rxq;
895         char *buf;
896         int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
897                 (priv->cfg->base_params->num_of_queues * 32 * 8) + 400;
898         const u8 *ptr;
899         ssize_t ret;
900
901         if (!priv->txq) {
902                 IWL_ERR(priv, "txq not ready\n");
903                 return -EAGAIN;
904         }
905         buf = kzalloc(bufsz, GFP_KERNEL);
906         if (!buf) {
907                 IWL_ERR(priv, "Can not allocate buffer\n");
908                 return -ENOMEM;
909         }
910         pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
911         for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
912                 txq = &priv->txq[cnt];
913                 q = &txq->q;
914                 pos += scnprintf(buf + pos, bufsz - pos,
915                                 "q[%d]: read_ptr: %u, write_ptr: %u\n",
916                                 cnt, q->read_ptr, q->write_ptr);
917         }
918         if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) {
919                 ptr = priv->tx_traffic;
920                 pos += scnprintf(buf + pos, bufsz - pos,
921                                 "Tx Traffic idx: %u\n", priv->tx_traffic_idx);
922                 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
923                         for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
924                              entry++,  ofs += 16) {
925                                 pos += scnprintf(buf + pos, bufsz - pos,
926                                                 "0x%.4x ", ofs);
927                                 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
928                                                    buf + pos, bufsz - pos, 0);
929                                 pos += strlen(buf + pos);
930                                 if (bufsz - pos > 0)
931                                         buf[pos++] = '\n';
932                         }
933                 }
934         }
935
936         pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
937         pos += scnprintf(buf + pos, bufsz - pos,
938                         "read: %u, write: %u\n",
939                          rxq->read, rxq->write);
940
941         if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) {
942                 ptr = priv->rx_traffic;
943                 pos += scnprintf(buf + pos, bufsz - pos,
944                                 "Rx Traffic idx: %u\n", priv->rx_traffic_idx);
945                 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
946                         for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
947                              entry++,  ofs += 16) {
948                                 pos += scnprintf(buf + pos, bufsz - pos,
949                                                 "0x%.4x ", ofs);
950                                 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
951                                                    buf + pos, bufsz - pos, 0);
952                                 pos += strlen(buf + pos);
953                                 if (bufsz - pos > 0)
954                                         buf[pos++] = '\n';
955                         }
956                 }
957         }
958
959         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
960         kfree(buf);
961         return ret;
962 }
963
964 static ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
965                                          const char __user *user_buf,
966                                          size_t count, loff_t *ppos)
967 {
968         struct iwl_priv *priv = file->private_data;
969         char buf[8];
970         int buf_size;
971         int traffic_log;
972
973         memset(buf, 0, sizeof(buf));
974         buf_size = min(count, sizeof(buf) -  1);
975         if (copy_from_user(buf, user_buf, buf_size))
976                 return -EFAULT;
977         if (sscanf(buf, "%d", &traffic_log) != 1)
978                 return -EFAULT;
979         if (traffic_log == 0)
980                 iwl_reset_traffic_log(priv);
981
982         return count;
983 }
984
985 static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
986                                                 char __user *user_buf,
987                                                 size_t count, loff_t *ppos) {
988
989         struct iwl_priv *priv = file->private_data;
990         struct iwl_tx_queue *txq;
991         struct iwl_queue *q;
992         char *buf;
993         int pos = 0;
994         int cnt;
995         int ret;
996         const size_t bufsz = sizeof(char) * 64 *
997                                 priv->cfg->base_params->num_of_queues;
998
999         if (!priv->txq) {
1000                 IWL_ERR(priv, "txq not ready\n");
1001                 return -EAGAIN;
1002         }
1003         buf = kzalloc(bufsz, GFP_KERNEL);
1004         if (!buf)
1005                 return -ENOMEM;
1006
1007         for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
1008                 txq = &priv->txq[cnt];
1009                 q = &txq->q;
1010                 pos += scnprintf(buf + pos, bufsz - pos,
1011                                 "hwq %.2d: read=%u write=%u stop=%d"
1012                                 " swq_id=%#.2x (ac %d/hwq %d)\n",
1013                                 cnt, q->read_ptr, q->write_ptr,
1014                                 !!test_bit(cnt, priv->queue_stopped),
1015                                 txq->swq_id, txq->swq_id & 3,
1016                                 (txq->swq_id >> 2) & 0x1f);
1017                 if (cnt >= 4)
1018                         continue;
1019                 /* for the ACs, display the stop count too */
1020                 pos += scnprintf(buf + pos, bufsz - pos,
1021                                 "        stop-count: %d\n",
1022                                 atomic_read(&priv->queue_stop_count[cnt]));
1023         }
1024         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1025         kfree(buf);
1026         return ret;
1027 }
1028
1029 static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1030                                                 char __user *user_buf,
1031                                                 size_t count, loff_t *ppos) {
1032
1033         struct iwl_priv *priv = file->private_data;
1034         struct iwl_rx_queue *rxq = &priv->rxq;
1035         char buf[256];
1036         int pos = 0;
1037         const size_t bufsz = sizeof(buf);
1038
1039         pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
1040                                                 rxq->read);
1041         pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
1042                                                 rxq->write);
1043         pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
1044                                                 rxq->free_count);
1045         if (rxq->rb_stts) {
1046                 pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
1047                          le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF);
1048         } else {
1049                 pos += scnprintf(buf + pos, bufsz - pos,
1050                                         "closed_rb_num: Not Allocated\n");
1051         }
1052         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1053 }
1054
1055 static const char *fmt_value = "  %-30s %10u\n";
1056 static const char *fmt_hex   = "  %-30s       0x%02X\n";
1057 static const char *fmt_table = "  %-30s %10u  %10u  %10u  %10u\n";
1058 static const char *fmt_header =
1059         "%-32s    current  cumulative       delta         max\n";
1060
1061 static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
1062 {
1063         int p = 0;
1064         u32 flag;
1065
1066         flag = le32_to_cpu(priv->statistics.flag);
1067
1068         p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
1069         if (flag & UCODE_STATISTICS_CLEAR_MSK)
1070                 p += scnprintf(buf + p, bufsz - p,
1071                 "\tStatistics have been cleared\n");
1072         p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
1073                 (flag & UCODE_STATISTICS_FREQUENCY_MSK)
1074                 ? "2.4 GHz" : "5.2 GHz");
1075         p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
1076                 (flag & UCODE_STATISTICS_NARROW_BAND_MSK)
1077                  ? "enabled" : "disabled");
1078
1079         return p;
1080 }
1081
1082 static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1083                                         char __user *user_buf,
1084                                         size_t count, loff_t *ppos)
1085 {
1086         struct iwl_priv *priv = file->private_data;
1087         int pos = 0;
1088         char *buf;
1089         int bufsz = sizeof(struct statistics_rx_phy) * 40 +
1090                     sizeof(struct statistics_rx_non_phy) * 40 +
1091                     sizeof(struct statistics_rx_ht_phy) * 40 + 400;
1092         ssize_t ret;
1093         struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm;
1094         struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
1095         struct statistics_rx_non_phy *general, *accum_general;
1096         struct statistics_rx_non_phy *delta_general, *max_general;
1097         struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht;
1098
1099         if (!iwl_is_alive(priv))
1100                 return -EAGAIN;
1101
1102         buf = kzalloc(bufsz, GFP_KERNEL);
1103         if (!buf) {
1104                 IWL_ERR(priv, "Can not allocate Buffer\n");
1105                 return -ENOMEM;
1106         }
1107
1108         /*
1109          * the statistic information display here is based on
1110          * the last statistics notification from uCode
1111          * might not reflect the current uCode activity
1112          */
1113         ofdm = &priv->statistics.rx_ofdm;
1114         cck = &priv->statistics.rx_cck;
1115         general = &priv->statistics.rx_non_phy;
1116         ht = &priv->statistics.rx_ofdm_ht;
1117         accum_ofdm = &priv->accum_stats.rx_ofdm;
1118         accum_cck = &priv->accum_stats.rx_cck;
1119         accum_general = &priv->accum_stats.rx_non_phy;
1120         accum_ht = &priv->accum_stats.rx_ofdm_ht;
1121         delta_ofdm = &priv->delta_stats.rx_ofdm;
1122         delta_cck = &priv->delta_stats.rx_cck;
1123         delta_general = &priv->delta_stats.rx_non_phy;
1124         delta_ht = &priv->delta_stats.rx_ofdm_ht;
1125         max_ofdm = &priv->max_delta_stats.rx_ofdm;
1126         max_cck = &priv->max_delta_stats.rx_cck;
1127         max_general = &priv->max_delta_stats.rx_non_phy;
1128         max_ht = &priv->max_delta_stats.rx_ofdm_ht;
1129
1130         pos += iwl_statistics_flag(priv, buf, bufsz);
1131         pos += scnprintf(buf + pos, bufsz - pos,
1132                          fmt_header, "Statistics_Rx - OFDM:");
1133         pos += scnprintf(buf + pos, bufsz - pos,
1134                          fmt_table, "ina_cnt:",
1135                          le32_to_cpu(ofdm->ina_cnt),
1136                          accum_ofdm->ina_cnt,
1137                          delta_ofdm->ina_cnt, max_ofdm->ina_cnt);
1138         pos += scnprintf(buf + pos, bufsz - pos,
1139                          fmt_table, "fina_cnt:",
1140                          le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt,
1141                          delta_ofdm->fina_cnt, max_ofdm->fina_cnt);
1142         pos += scnprintf(buf + pos, bufsz - pos,
1143                          fmt_table, "plcp_err:",
1144                          le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err,
1145                          delta_ofdm->plcp_err, max_ofdm->plcp_err);
1146         pos += scnprintf(buf + pos, bufsz - pos,
1147                          fmt_table, "crc32_err:",
1148                          le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err,
1149                          delta_ofdm->crc32_err, max_ofdm->crc32_err);
1150         pos += scnprintf(buf + pos, bufsz - pos,
1151                          fmt_table, "overrun_err:",
1152                          le32_to_cpu(ofdm->overrun_err),
1153                          accum_ofdm->overrun_err, delta_ofdm->overrun_err,
1154                          max_ofdm->overrun_err);
1155         pos += scnprintf(buf + pos, bufsz - pos,
1156                          fmt_table, "early_overrun_err:",
1157                          le32_to_cpu(ofdm->early_overrun_err),
1158                          accum_ofdm->early_overrun_err,
1159                          delta_ofdm->early_overrun_err,
1160                          max_ofdm->early_overrun_err);
1161         pos += scnprintf(buf + pos, bufsz - pos,
1162                          fmt_table, "crc32_good:",
1163                          le32_to_cpu(ofdm->crc32_good),
1164                          accum_ofdm->crc32_good, delta_ofdm->crc32_good,
1165                          max_ofdm->crc32_good);
1166         pos += scnprintf(buf + pos, bufsz - pos,
1167                          fmt_table, "false_alarm_cnt:",
1168                          le32_to_cpu(ofdm->false_alarm_cnt),
1169                          accum_ofdm->false_alarm_cnt,
1170                          delta_ofdm->false_alarm_cnt,
1171                          max_ofdm->false_alarm_cnt);
1172         pos += scnprintf(buf + pos, bufsz - pos,
1173                          fmt_table, "fina_sync_err_cnt:",
1174                          le32_to_cpu(ofdm->fina_sync_err_cnt),
1175                          accum_ofdm->fina_sync_err_cnt,
1176                          delta_ofdm->fina_sync_err_cnt,
1177                          max_ofdm->fina_sync_err_cnt);
1178         pos += scnprintf(buf + pos, bufsz - pos,
1179                          fmt_table, "sfd_timeout:",
1180                          le32_to_cpu(ofdm->sfd_timeout),
1181                          accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
1182                          max_ofdm->sfd_timeout);
1183         pos += scnprintf(buf + pos, bufsz - pos,
1184                          fmt_table, "fina_timeout:",
1185                          le32_to_cpu(ofdm->fina_timeout),
1186                          accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
1187                          max_ofdm->fina_timeout);
1188         pos += scnprintf(buf + pos, bufsz - pos,
1189                          fmt_table, "unresponded_rts:",
1190                          le32_to_cpu(ofdm->unresponded_rts),
1191                          accum_ofdm->unresponded_rts,
1192                          delta_ofdm->unresponded_rts,
1193                          max_ofdm->unresponded_rts);
1194         pos += scnprintf(buf + pos, bufsz - pos,
1195                          fmt_table, "rxe_frame_lmt_ovrun:",
1196                          le32_to_cpu(ofdm->rxe_frame_limit_overrun),
1197                          accum_ofdm->rxe_frame_limit_overrun,
1198                          delta_ofdm->rxe_frame_limit_overrun,
1199                          max_ofdm->rxe_frame_limit_overrun);
1200         pos += scnprintf(buf + pos, bufsz - pos,
1201                          fmt_table, "sent_ack_cnt:",
1202                          le32_to_cpu(ofdm->sent_ack_cnt),
1203                          accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
1204                          max_ofdm->sent_ack_cnt);
1205         pos += scnprintf(buf + pos, bufsz - pos,
1206                          fmt_table, "sent_cts_cnt:",
1207                          le32_to_cpu(ofdm->sent_cts_cnt),
1208                          accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
1209                          max_ofdm->sent_cts_cnt);
1210         pos += scnprintf(buf + pos, bufsz - pos,
1211                          fmt_table, "sent_ba_rsp_cnt:",
1212                          le32_to_cpu(ofdm->sent_ba_rsp_cnt),
1213                          accum_ofdm->sent_ba_rsp_cnt,
1214                          delta_ofdm->sent_ba_rsp_cnt,
1215                          max_ofdm->sent_ba_rsp_cnt);
1216         pos += scnprintf(buf + pos, bufsz - pos,
1217                          fmt_table, "dsp_self_kill:",
1218                          le32_to_cpu(ofdm->dsp_self_kill),
1219                          accum_ofdm->dsp_self_kill,
1220                          delta_ofdm->dsp_self_kill,
1221                          max_ofdm->dsp_self_kill);
1222         pos += scnprintf(buf + pos, bufsz - pos,
1223                          fmt_table, "mh_format_err:",
1224                          le32_to_cpu(ofdm->mh_format_err),
1225                          accum_ofdm->mh_format_err,
1226                          delta_ofdm->mh_format_err,
1227                          max_ofdm->mh_format_err);
1228         pos += scnprintf(buf + pos, bufsz - pos,
1229                          fmt_table, "re_acq_main_rssi_sum:",
1230                          le32_to_cpu(ofdm->re_acq_main_rssi_sum),
1231                          accum_ofdm->re_acq_main_rssi_sum,
1232                          delta_ofdm->re_acq_main_rssi_sum,
1233                          max_ofdm->re_acq_main_rssi_sum);
1234
1235         pos += scnprintf(buf + pos, bufsz - pos,
1236                          fmt_header, "Statistics_Rx - CCK:");
1237         pos += scnprintf(buf + pos, bufsz - pos,
1238                          fmt_table, "ina_cnt:",
1239                          le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt,
1240                          delta_cck->ina_cnt, max_cck->ina_cnt);
1241         pos += scnprintf(buf + pos, bufsz - pos,
1242                          fmt_table, "fina_cnt:",
1243                          le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt,
1244                          delta_cck->fina_cnt, max_cck->fina_cnt);
1245         pos += scnprintf(buf + pos, bufsz - pos,
1246                          fmt_table, "plcp_err:",
1247                          le32_to_cpu(cck->plcp_err), accum_cck->plcp_err,
1248                          delta_cck->plcp_err, max_cck->plcp_err);
1249         pos += scnprintf(buf + pos, bufsz - pos,
1250                          fmt_table, "crc32_err:",
1251                          le32_to_cpu(cck->crc32_err), accum_cck->crc32_err,
1252                          delta_cck->crc32_err, max_cck->crc32_err);
1253         pos += scnprintf(buf + pos, bufsz - pos,
1254                          fmt_table, "overrun_err:",
1255                          le32_to_cpu(cck->overrun_err),
1256                          accum_cck->overrun_err, delta_cck->overrun_err,
1257                          max_cck->overrun_err);
1258         pos += scnprintf(buf + pos, bufsz - pos,
1259                          fmt_table, "early_overrun_err:",
1260                          le32_to_cpu(cck->early_overrun_err),
1261                          accum_cck->early_overrun_err,
1262                          delta_cck->early_overrun_err,
1263                          max_cck->early_overrun_err);
1264         pos += scnprintf(buf + pos, bufsz - pos,
1265                          fmt_table, "crc32_good:",
1266                          le32_to_cpu(cck->crc32_good), accum_cck->crc32_good,
1267                          delta_cck->crc32_good, max_cck->crc32_good);
1268         pos += scnprintf(buf + pos, bufsz - pos,
1269                          fmt_table, "false_alarm_cnt:",
1270                          le32_to_cpu(cck->false_alarm_cnt),
1271                          accum_cck->false_alarm_cnt,
1272                          delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
1273         pos += scnprintf(buf + pos, bufsz - pos,
1274                          fmt_table, "fina_sync_err_cnt:",
1275                          le32_to_cpu(cck->fina_sync_err_cnt),
1276                          accum_cck->fina_sync_err_cnt,
1277                          delta_cck->fina_sync_err_cnt,
1278                          max_cck->fina_sync_err_cnt);
1279         pos += scnprintf(buf + pos, bufsz - pos,
1280                          fmt_table, "sfd_timeout:",
1281                          le32_to_cpu(cck->sfd_timeout),
1282                          accum_cck->sfd_timeout, delta_cck->sfd_timeout,
1283                          max_cck->sfd_timeout);
1284         pos += scnprintf(buf + pos, bufsz - pos,
1285                          fmt_table, "fina_timeout:",
1286                          le32_to_cpu(cck->fina_timeout),
1287                          accum_cck->fina_timeout, delta_cck->fina_timeout,
1288                          max_cck->fina_timeout);
1289         pos += scnprintf(buf + pos, bufsz - pos,
1290                          fmt_table, "unresponded_rts:",
1291                          le32_to_cpu(cck->unresponded_rts),
1292                          accum_cck->unresponded_rts, delta_cck->unresponded_rts,
1293                          max_cck->unresponded_rts);
1294         pos += scnprintf(buf + pos, bufsz - pos,
1295                          fmt_table, "rxe_frame_lmt_ovrun:",
1296                          le32_to_cpu(cck->rxe_frame_limit_overrun),
1297                          accum_cck->rxe_frame_limit_overrun,
1298                          delta_cck->rxe_frame_limit_overrun,
1299                          max_cck->rxe_frame_limit_overrun);
1300         pos += scnprintf(buf + pos, bufsz - pos,
1301                          fmt_table, "sent_ack_cnt:",
1302                          le32_to_cpu(cck->sent_ack_cnt),
1303                          accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
1304                          max_cck->sent_ack_cnt);
1305         pos += scnprintf(buf + pos, bufsz - pos,
1306                          fmt_table, "sent_cts_cnt:",
1307                          le32_to_cpu(cck->sent_cts_cnt),
1308                          accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
1309                          max_cck->sent_cts_cnt);
1310         pos += scnprintf(buf + pos, bufsz - pos,
1311                          fmt_table, "sent_ba_rsp_cnt:",
1312                          le32_to_cpu(cck->sent_ba_rsp_cnt),
1313                          accum_cck->sent_ba_rsp_cnt,
1314                          delta_cck->sent_ba_rsp_cnt,
1315                          max_cck->sent_ba_rsp_cnt);
1316         pos += scnprintf(buf + pos, bufsz - pos,
1317                          fmt_table, "dsp_self_kill:",
1318                          le32_to_cpu(cck->dsp_self_kill),
1319                          accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
1320                          max_cck->dsp_self_kill);
1321         pos += scnprintf(buf + pos, bufsz - pos,
1322                          fmt_table, "mh_format_err:",
1323                          le32_to_cpu(cck->mh_format_err),
1324                          accum_cck->mh_format_err, delta_cck->mh_format_err,
1325                          max_cck->mh_format_err);
1326         pos += scnprintf(buf + pos, bufsz - pos,
1327                          fmt_table, "re_acq_main_rssi_sum:",
1328                          le32_to_cpu(cck->re_acq_main_rssi_sum),
1329                          accum_cck->re_acq_main_rssi_sum,
1330                          delta_cck->re_acq_main_rssi_sum,
1331                          max_cck->re_acq_main_rssi_sum);
1332
1333         pos += scnprintf(buf + pos, bufsz - pos,
1334                          fmt_header, "Statistics_Rx - GENERAL:");
1335         pos += scnprintf(buf + pos, bufsz - pos,
1336                          fmt_table, "bogus_cts:",
1337                          le32_to_cpu(general->bogus_cts),
1338                          accum_general->bogus_cts, delta_general->bogus_cts,
1339                          max_general->bogus_cts);
1340         pos += scnprintf(buf + pos, bufsz - pos,
1341                          fmt_table, "bogus_ack:",
1342                          le32_to_cpu(general->bogus_ack),
1343                          accum_general->bogus_ack, delta_general->bogus_ack,
1344                          max_general->bogus_ack);
1345         pos += scnprintf(buf + pos, bufsz - pos,
1346                          fmt_table, "non_bssid_frames:",
1347                          le32_to_cpu(general->non_bssid_frames),
1348                          accum_general->non_bssid_frames,
1349                          delta_general->non_bssid_frames,
1350                          max_general->non_bssid_frames);
1351         pos += scnprintf(buf + pos, bufsz - pos,
1352                          fmt_table, "filtered_frames:",
1353                          le32_to_cpu(general->filtered_frames),
1354                          accum_general->filtered_frames,
1355                          delta_general->filtered_frames,
1356                          max_general->filtered_frames);
1357         pos += scnprintf(buf + pos, bufsz - pos,
1358                          fmt_table, "non_channel_beacons:",
1359                          le32_to_cpu(general->non_channel_beacons),
1360                          accum_general->non_channel_beacons,
1361                          delta_general->non_channel_beacons,
1362                          max_general->non_channel_beacons);
1363         pos += scnprintf(buf + pos, bufsz - pos,
1364                          fmt_table, "channel_beacons:",
1365                          le32_to_cpu(general->channel_beacons),
1366                          accum_general->channel_beacons,
1367                          delta_general->channel_beacons,
1368                          max_general->channel_beacons);
1369         pos += scnprintf(buf + pos, bufsz - pos,
1370                          fmt_table, "num_missed_bcon:",
1371                          le32_to_cpu(general->num_missed_bcon),
1372                          accum_general->num_missed_bcon,
1373                          delta_general->num_missed_bcon,
1374                          max_general->num_missed_bcon);
1375         pos += scnprintf(buf + pos, bufsz - pos,
1376                          fmt_table, "adc_rx_saturation_time:",
1377                          le32_to_cpu(general->adc_rx_saturation_time),
1378                          accum_general->adc_rx_saturation_time,
1379                          delta_general->adc_rx_saturation_time,
1380                          max_general->adc_rx_saturation_time);
1381         pos += scnprintf(buf + pos, bufsz - pos,
1382                          fmt_table, "ina_detect_search_tm:",
1383                          le32_to_cpu(general->ina_detection_search_time),
1384                          accum_general->ina_detection_search_time,
1385                          delta_general->ina_detection_search_time,
1386                          max_general->ina_detection_search_time);
1387         pos += scnprintf(buf + pos, bufsz - pos,
1388                          fmt_table, "beacon_silence_rssi_a:",
1389                          le32_to_cpu(general->beacon_silence_rssi_a),
1390                          accum_general->beacon_silence_rssi_a,
1391                          delta_general->beacon_silence_rssi_a,
1392                          max_general->beacon_silence_rssi_a);
1393         pos += scnprintf(buf + pos, bufsz - pos,
1394                          fmt_table, "beacon_silence_rssi_b:",
1395                          le32_to_cpu(general->beacon_silence_rssi_b),
1396                          accum_general->beacon_silence_rssi_b,
1397                          delta_general->beacon_silence_rssi_b,
1398                          max_general->beacon_silence_rssi_b);
1399         pos += scnprintf(buf + pos, bufsz - pos,
1400                          fmt_table, "beacon_silence_rssi_c:",
1401                          le32_to_cpu(general->beacon_silence_rssi_c),
1402                          accum_general->beacon_silence_rssi_c,
1403                          delta_general->beacon_silence_rssi_c,
1404                          max_general->beacon_silence_rssi_c);
1405         pos += scnprintf(buf + pos, bufsz - pos,
1406                          fmt_table, "interference_data_flag:",
1407                          le32_to_cpu(general->interference_data_flag),
1408                          accum_general->interference_data_flag,
1409                          delta_general->interference_data_flag,
1410                          max_general->interference_data_flag);
1411         pos += scnprintf(buf + pos, bufsz - pos,
1412                          fmt_table, "channel_load:",
1413                          le32_to_cpu(general->channel_load),
1414                          accum_general->channel_load,
1415                          delta_general->channel_load,
1416                          max_general->channel_load);
1417         pos += scnprintf(buf + pos, bufsz - pos,
1418                          fmt_table, "dsp_false_alarms:",
1419                          le32_to_cpu(general->dsp_false_alarms),
1420                          accum_general->dsp_false_alarms,
1421                          delta_general->dsp_false_alarms,
1422                          max_general->dsp_false_alarms);
1423         pos += scnprintf(buf + pos, bufsz - pos,
1424                          fmt_table, "beacon_rssi_a:",
1425                          le32_to_cpu(general->beacon_rssi_a),
1426                          accum_general->beacon_rssi_a,
1427                          delta_general->beacon_rssi_a,
1428                          max_general->beacon_rssi_a);
1429         pos += scnprintf(buf + pos, bufsz - pos,
1430                          fmt_table, "beacon_rssi_b:",
1431                          le32_to_cpu(general->beacon_rssi_b),
1432                          accum_general->beacon_rssi_b,
1433                          delta_general->beacon_rssi_b,
1434                          max_general->beacon_rssi_b);
1435         pos += scnprintf(buf + pos, bufsz - pos,
1436                          fmt_table, "beacon_rssi_c:",
1437                          le32_to_cpu(general->beacon_rssi_c),
1438                          accum_general->beacon_rssi_c,
1439                          delta_general->beacon_rssi_c,
1440                          max_general->beacon_rssi_c);
1441         pos += scnprintf(buf + pos, bufsz - pos,
1442                          fmt_table, "beacon_energy_a:",
1443                          le32_to_cpu(general->beacon_energy_a),
1444                          accum_general->beacon_energy_a,
1445                          delta_general->beacon_energy_a,
1446                          max_general->beacon_energy_a);
1447         pos += scnprintf(buf + pos, bufsz - pos,
1448                          fmt_table, "beacon_energy_b:",
1449                          le32_to_cpu(general->beacon_energy_b),
1450                          accum_general->beacon_energy_b,
1451                          delta_general->beacon_energy_b,
1452                          max_general->beacon_energy_b);
1453         pos += scnprintf(buf + pos, bufsz - pos,
1454                          fmt_table, "beacon_energy_c:",
1455                          le32_to_cpu(general->beacon_energy_c),
1456                          accum_general->beacon_energy_c,
1457                          delta_general->beacon_energy_c,
1458                          max_general->beacon_energy_c);
1459
1460         pos += scnprintf(buf + pos, bufsz - pos,
1461                          fmt_header, "Statistics_Rx - OFDM_HT:");
1462         pos += scnprintf(buf + pos, bufsz - pos,
1463                          fmt_table, "plcp_err:",
1464                          le32_to_cpu(ht->plcp_err), accum_ht->plcp_err,
1465                          delta_ht->plcp_err, max_ht->plcp_err);
1466         pos += scnprintf(buf + pos, bufsz - pos,
1467                          fmt_table, "overrun_err:",
1468                          le32_to_cpu(ht->overrun_err), accum_ht->overrun_err,
1469                          delta_ht->overrun_err, max_ht->overrun_err);
1470         pos += scnprintf(buf + pos, bufsz - pos,
1471                          fmt_table, "early_overrun_err:",
1472                          le32_to_cpu(ht->early_overrun_err),
1473                          accum_ht->early_overrun_err,
1474                          delta_ht->early_overrun_err,
1475                          max_ht->early_overrun_err);
1476         pos += scnprintf(buf + pos, bufsz - pos,
1477                          fmt_table, "crc32_good:",
1478                          le32_to_cpu(ht->crc32_good), accum_ht->crc32_good,
1479                          delta_ht->crc32_good, max_ht->crc32_good);
1480         pos += scnprintf(buf + pos, bufsz - pos,
1481                          fmt_table, "crc32_err:",
1482                          le32_to_cpu(ht->crc32_err), accum_ht->crc32_err,
1483                          delta_ht->crc32_err, max_ht->crc32_err);
1484         pos += scnprintf(buf + pos, bufsz - pos,
1485                          fmt_table, "mh_format_err:",
1486                          le32_to_cpu(ht->mh_format_err),
1487                          accum_ht->mh_format_err,
1488                          delta_ht->mh_format_err, max_ht->mh_format_err);
1489         pos += scnprintf(buf + pos, bufsz - pos,
1490                          fmt_table, "agg_crc32_good:",
1491                          le32_to_cpu(ht->agg_crc32_good),
1492                          accum_ht->agg_crc32_good,
1493                          delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
1494         pos += scnprintf(buf + pos, bufsz - pos,
1495                          fmt_table, "agg_mpdu_cnt:",
1496                          le32_to_cpu(ht->agg_mpdu_cnt),
1497                          accum_ht->agg_mpdu_cnt,
1498                          delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
1499         pos += scnprintf(buf + pos, bufsz - pos,
1500                          fmt_table, "agg_cnt:",
1501                          le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt,
1502                          delta_ht->agg_cnt, max_ht->agg_cnt);
1503         pos += scnprintf(buf + pos, bufsz - pos,
1504                          fmt_table, "unsupport_mcs:",
1505                          le32_to_cpu(ht->unsupport_mcs),
1506                          accum_ht->unsupport_mcs,
1507                          delta_ht->unsupport_mcs, max_ht->unsupport_mcs);
1508
1509         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1510         kfree(buf);
1511         return ret;
1512 }
1513
1514 static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1515                                         char __user *user_buf,
1516                                         size_t count, loff_t *ppos)
1517 {
1518         struct iwl_priv *priv = file->private_data;
1519         int pos = 0;
1520         char *buf;
1521         int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
1522         ssize_t ret;
1523         struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
1524
1525         if (!iwl_is_alive(priv))
1526                 return -EAGAIN;
1527
1528         buf = kzalloc(bufsz, GFP_KERNEL);
1529         if (!buf) {
1530                 IWL_ERR(priv, "Can not allocate Buffer\n");
1531                 return -ENOMEM;
1532         }
1533
1534         /* the statistic information display here is based on
1535          * the last statistics notification from uCode
1536          * might not reflect the current uCode activity
1537          */
1538         tx = &priv->statistics.tx;
1539         accum_tx = &priv->accum_stats.tx;
1540         delta_tx = &priv->delta_stats.tx;
1541         max_tx = &priv->max_delta_stats.tx;
1542
1543         pos += iwl_statistics_flag(priv, buf, bufsz);
1544         pos += scnprintf(buf + pos, bufsz - pos,
1545                          fmt_header, "Statistics_Tx:");
1546         pos += scnprintf(buf + pos, bufsz - pos,
1547                          fmt_table, "preamble:",
1548                          le32_to_cpu(tx->preamble_cnt),
1549                          accum_tx->preamble_cnt,
1550                          delta_tx->preamble_cnt, max_tx->preamble_cnt);
1551         pos += scnprintf(buf + pos, bufsz - pos,
1552                          fmt_table, "rx_detected_cnt:",
1553                          le32_to_cpu(tx->rx_detected_cnt),
1554                          accum_tx->rx_detected_cnt,
1555                          delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
1556         pos += scnprintf(buf + pos, bufsz - pos,
1557                          fmt_table, "bt_prio_defer_cnt:",
1558                          le32_to_cpu(tx->bt_prio_defer_cnt),
1559                          accum_tx->bt_prio_defer_cnt,
1560                          delta_tx->bt_prio_defer_cnt,
1561                          max_tx->bt_prio_defer_cnt);
1562         pos += scnprintf(buf + pos, bufsz - pos,
1563                          fmt_table, "bt_prio_kill_cnt:",
1564                          le32_to_cpu(tx->bt_prio_kill_cnt),
1565                          accum_tx->bt_prio_kill_cnt,
1566                          delta_tx->bt_prio_kill_cnt,
1567                          max_tx->bt_prio_kill_cnt);
1568         pos += scnprintf(buf + pos, bufsz - pos,
1569                          fmt_table, "few_bytes_cnt:",
1570                          le32_to_cpu(tx->few_bytes_cnt),
1571                          accum_tx->few_bytes_cnt,
1572                          delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
1573         pos += scnprintf(buf + pos, bufsz - pos,
1574                          fmt_table, "cts_timeout:",
1575                          le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout,
1576                          delta_tx->cts_timeout, max_tx->cts_timeout);
1577         pos += scnprintf(buf + pos, bufsz - pos,
1578                          fmt_table, "ack_timeout:",
1579                          le32_to_cpu(tx->ack_timeout),
1580                          accum_tx->ack_timeout,
1581                          delta_tx->ack_timeout, max_tx->ack_timeout);
1582         pos += scnprintf(buf + pos, bufsz - pos,
1583                          fmt_table, "expected_ack_cnt:",
1584                          le32_to_cpu(tx->expected_ack_cnt),
1585                          accum_tx->expected_ack_cnt,
1586                          delta_tx->expected_ack_cnt,
1587                          max_tx->expected_ack_cnt);
1588         pos += scnprintf(buf + pos, bufsz - pos,
1589                          fmt_table, "actual_ack_cnt:",
1590                          le32_to_cpu(tx->actual_ack_cnt),
1591                          accum_tx->actual_ack_cnt,
1592                          delta_tx->actual_ack_cnt,
1593                          max_tx->actual_ack_cnt);
1594         pos += scnprintf(buf + pos, bufsz - pos,
1595                          fmt_table, "dump_msdu_cnt:",
1596                          le32_to_cpu(tx->dump_msdu_cnt),
1597                          accum_tx->dump_msdu_cnt,
1598                          delta_tx->dump_msdu_cnt,
1599                          max_tx->dump_msdu_cnt);
1600         pos += scnprintf(buf + pos, bufsz - pos,
1601                          fmt_table, "abort_nxt_frame_mismatch:",
1602                          le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
1603                          accum_tx->burst_abort_next_frame_mismatch_cnt,
1604                          delta_tx->burst_abort_next_frame_mismatch_cnt,
1605                          max_tx->burst_abort_next_frame_mismatch_cnt);
1606         pos += scnprintf(buf + pos, bufsz - pos,
1607                          fmt_table, "abort_missing_nxt_frame:",
1608                          le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
1609                          accum_tx->burst_abort_missing_next_frame_cnt,
1610                          delta_tx->burst_abort_missing_next_frame_cnt,
1611                          max_tx->burst_abort_missing_next_frame_cnt);
1612         pos += scnprintf(buf + pos, bufsz - pos,
1613                          fmt_table, "cts_timeout_collision:",
1614                          le32_to_cpu(tx->cts_timeout_collision),
1615                          accum_tx->cts_timeout_collision,
1616                          delta_tx->cts_timeout_collision,
1617                          max_tx->cts_timeout_collision);
1618         pos += scnprintf(buf + pos, bufsz - pos,
1619                          fmt_table, "ack_ba_timeout_collision:",
1620                          le32_to_cpu(tx->ack_or_ba_timeout_collision),
1621                          accum_tx->ack_or_ba_timeout_collision,
1622                          delta_tx->ack_or_ba_timeout_collision,
1623                          max_tx->ack_or_ba_timeout_collision);
1624         pos += scnprintf(buf + pos, bufsz - pos,
1625                          fmt_table, "agg ba_timeout:",
1626                          le32_to_cpu(tx->agg.ba_timeout),
1627                          accum_tx->agg.ba_timeout,
1628                          delta_tx->agg.ba_timeout,
1629                          max_tx->agg.ba_timeout);
1630         pos += scnprintf(buf + pos, bufsz - pos,
1631                          fmt_table, "agg ba_resched_frames:",
1632                          le32_to_cpu(tx->agg.ba_reschedule_frames),
1633                          accum_tx->agg.ba_reschedule_frames,
1634                          delta_tx->agg.ba_reschedule_frames,
1635                          max_tx->agg.ba_reschedule_frames);
1636         pos += scnprintf(buf + pos, bufsz - pos,
1637                          fmt_table, "agg scd_query_agg_frame:",
1638                          le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
1639                          accum_tx->agg.scd_query_agg_frame_cnt,
1640                          delta_tx->agg.scd_query_agg_frame_cnt,
1641                          max_tx->agg.scd_query_agg_frame_cnt);
1642         pos += scnprintf(buf + pos, bufsz - pos,
1643                          fmt_table, "agg scd_query_no_agg:",
1644                          le32_to_cpu(tx->agg.scd_query_no_agg),
1645                          accum_tx->agg.scd_query_no_agg,
1646                          delta_tx->agg.scd_query_no_agg,
1647                          max_tx->agg.scd_query_no_agg);
1648         pos += scnprintf(buf + pos, bufsz - pos,
1649                          fmt_table, "agg scd_query_agg:",
1650                          le32_to_cpu(tx->agg.scd_query_agg),
1651                          accum_tx->agg.scd_query_agg,
1652                          delta_tx->agg.scd_query_agg,
1653                          max_tx->agg.scd_query_agg);
1654         pos += scnprintf(buf + pos, bufsz - pos,
1655                          fmt_table, "agg scd_query_mismatch:",
1656                          le32_to_cpu(tx->agg.scd_query_mismatch),
1657                          accum_tx->agg.scd_query_mismatch,
1658                          delta_tx->agg.scd_query_mismatch,
1659                          max_tx->agg.scd_query_mismatch);
1660         pos += scnprintf(buf + pos, bufsz - pos,
1661                          fmt_table, "agg frame_not_ready:",
1662                          le32_to_cpu(tx->agg.frame_not_ready),
1663                          accum_tx->agg.frame_not_ready,
1664                          delta_tx->agg.frame_not_ready,
1665                          max_tx->agg.frame_not_ready);
1666         pos += scnprintf(buf + pos, bufsz - pos,
1667                          fmt_table, "agg underrun:",
1668                          le32_to_cpu(tx->agg.underrun),
1669                          accum_tx->agg.underrun,
1670                          delta_tx->agg.underrun, max_tx->agg.underrun);
1671         pos += scnprintf(buf + pos, bufsz - pos,
1672                          fmt_table, "agg bt_prio_kill:",
1673                          le32_to_cpu(tx->agg.bt_prio_kill),
1674                          accum_tx->agg.bt_prio_kill,
1675                          delta_tx->agg.bt_prio_kill,
1676                          max_tx->agg.bt_prio_kill);
1677         pos += scnprintf(buf + pos, bufsz - pos,
1678                          fmt_table, "agg rx_ba_rsp_cnt:",
1679                          le32_to_cpu(tx->agg.rx_ba_rsp_cnt),
1680                          accum_tx->agg.rx_ba_rsp_cnt,
1681                          delta_tx->agg.rx_ba_rsp_cnt,
1682                          max_tx->agg.rx_ba_rsp_cnt);
1683
1684         if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
1685                 pos += scnprintf(buf + pos, bufsz - pos,
1686                         "tx power: (1/2 dB step)\n");
1687                 if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
1688                         pos += scnprintf(buf + pos, bufsz - pos,
1689                                         fmt_hex, "antenna A:",
1690                                         tx->tx_power.ant_a);
1691                 if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
1692                         pos += scnprintf(buf + pos, bufsz - pos,
1693                                         fmt_hex, "antenna B:",
1694                                         tx->tx_power.ant_b);
1695                 if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
1696                         pos += scnprintf(buf + pos, bufsz - pos,
1697                                         fmt_hex, "antenna C:",
1698                                         tx->tx_power.ant_c);
1699         }
1700         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1701         kfree(buf);
1702         return ret;
1703 }
1704
1705 static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1706                                         char __user *user_buf,
1707                                         size_t count, loff_t *ppos)
1708 {
1709         struct iwl_priv *priv = file->private_data;
1710         int pos = 0;
1711         char *buf;
1712         int bufsz = sizeof(struct statistics_general) * 10 + 300;
1713         ssize_t ret;
1714         struct statistics_general_common *general, *accum_general;
1715         struct statistics_general_common *delta_general, *max_general;
1716         struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
1717         struct statistics_div *div, *accum_div, *delta_div, *max_div;
1718
1719         if (!iwl_is_alive(priv))
1720                 return -EAGAIN;
1721
1722         buf = kzalloc(bufsz, GFP_KERNEL);
1723         if (!buf) {
1724                 IWL_ERR(priv, "Can not allocate Buffer\n");
1725                 return -ENOMEM;
1726         }
1727
1728         /* the statistic information display here is based on
1729          * the last statistics notification from uCode
1730          * might not reflect the current uCode activity
1731          */
1732         general = &priv->statistics.common;
1733         dbg = &priv->statistics.common.dbg;
1734         div = &priv->statistics.common.div;
1735         accum_general = &priv->accum_stats.common;
1736         accum_dbg = &priv->accum_stats.common.dbg;
1737         accum_div = &priv->accum_stats.common.div;
1738         delta_general = &priv->delta_stats.common;
1739         max_general = &priv->max_delta_stats.common;
1740         delta_dbg = &priv->delta_stats.common.dbg;
1741         max_dbg = &priv->max_delta_stats.common.dbg;
1742         delta_div = &priv->delta_stats.common.div;
1743         max_div = &priv->max_delta_stats.common.div;
1744
1745         pos += iwl_statistics_flag(priv, buf, bufsz);
1746         pos += scnprintf(buf + pos, bufsz - pos,
1747                          fmt_header, "Statistics_General:");
1748         pos += scnprintf(buf + pos, bufsz - pos,
1749                          fmt_value, "temperature:",
1750                          le32_to_cpu(general->temperature));
1751         pos += scnprintf(buf + pos, bufsz - pos,
1752                          fmt_value, "temperature_m:",
1753                          le32_to_cpu(general->temperature_m));
1754         pos += scnprintf(buf + pos, bufsz - pos,
1755                          fmt_value, "ttl_timestamp:",
1756                          le32_to_cpu(general->ttl_timestamp));
1757         pos += scnprintf(buf + pos, bufsz - pos,
1758                          fmt_table, "burst_check:",
1759                          le32_to_cpu(dbg->burst_check),
1760                          accum_dbg->burst_check,
1761                          delta_dbg->burst_check, max_dbg->burst_check);
1762         pos += scnprintf(buf + pos, bufsz - pos,
1763                          fmt_table, "burst_count:",
1764                          le32_to_cpu(dbg->burst_count),
1765                          accum_dbg->burst_count,
1766                          delta_dbg->burst_count, max_dbg->burst_count);
1767         pos += scnprintf(buf + pos, bufsz - pos,
1768                          fmt_table, "wait_for_silence_timeout_count:",
1769                          le32_to_cpu(dbg->wait_for_silence_timeout_cnt),
1770                          accum_dbg->wait_for_silence_timeout_cnt,
1771                          delta_dbg->wait_for_silence_timeout_cnt,
1772                          max_dbg->wait_for_silence_timeout_cnt);
1773         pos += scnprintf(buf + pos, bufsz - pos,
1774                          fmt_table, "sleep_time:",
1775                          le32_to_cpu(general->sleep_time),
1776                          accum_general->sleep_time,
1777                          delta_general->sleep_time, max_general->sleep_time);
1778         pos += scnprintf(buf + pos, bufsz - pos,
1779                          fmt_table, "slots_out:",
1780                          le32_to_cpu(general->slots_out),
1781                          accum_general->slots_out,
1782                          delta_general->slots_out, max_general->slots_out);
1783         pos += scnprintf(buf + pos, bufsz - pos,
1784                          fmt_table, "slots_idle:",
1785                          le32_to_cpu(general->slots_idle),
1786                          accum_general->slots_idle,
1787                          delta_general->slots_idle, max_general->slots_idle);
1788         pos += scnprintf(buf + pos, bufsz - pos,
1789                          fmt_table, "tx_on_a:",
1790                          le32_to_cpu(div->tx_on_a), accum_div->tx_on_a,
1791                          delta_div->tx_on_a, max_div->tx_on_a);
1792         pos += scnprintf(buf + pos, bufsz - pos,
1793                          fmt_table, "tx_on_b:",
1794                          le32_to_cpu(div->tx_on_b), accum_div->tx_on_b,
1795                          delta_div->tx_on_b, max_div->tx_on_b);
1796         pos += scnprintf(buf + pos, bufsz - pos,
1797                          fmt_table, "exec_time:",
1798                          le32_to_cpu(div->exec_time), accum_div->exec_time,
1799                          delta_div->exec_time, max_div->exec_time);
1800         pos += scnprintf(buf + pos, bufsz - pos,
1801                          fmt_table, "probe_time:",
1802                          le32_to_cpu(div->probe_time), accum_div->probe_time,
1803                          delta_div->probe_time, max_div->probe_time);
1804         pos += scnprintf(buf + pos, bufsz - pos,
1805                          fmt_table, "rx_enable_counter:",
1806                          le32_to_cpu(general->rx_enable_counter),
1807                          accum_general->rx_enable_counter,
1808                          delta_general->rx_enable_counter,
1809                          max_general->rx_enable_counter);
1810         pos += scnprintf(buf + pos, bufsz - pos,
1811                          fmt_table, "num_of_sos_states:",
1812                          le32_to_cpu(general->num_of_sos_states),
1813                          accum_general->num_of_sos_states,
1814                          delta_general->num_of_sos_states,
1815                          max_general->num_of_sos_states);
1816         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1817         kfree(buf);
1818         return ret;
1819 }
1820
1821 static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
1822                                         char __user *user_buf,
1823                                         size_t count, loff_t *ppos)
1824 {
1825         struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1826         int pos = 0;
1827         char *buf;
1828         int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
1829         ssize_t ret;
1830         struct statistics_bt_activity *bt, *accum_bt;
1831
1832         if (!iwl_is_alive(priv))
1833                 return -EAGAIN;
1834
1835         if (!priv->bt_enable_flag)
1836                 return -EINVAL;
1837
1838         /* make request to uCode to retrieve statistics information */
1839         mutex_lock(&priv->mutex);
1840         ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
1841         mutex_unlock(&priv->mutex);
1842
1843         if (ret) {
1844                 IWL_ERR(priv,
1845                         "Error sending statistics request: %zd\n", ret);
1846                 return -EAGAIN;
1847         }
1848         buf = kzalloc(bufsz, GFP_KERNEL);
1849         if (!buf) {
1850                 IWL_ERR(priv, "Can not allocate Buffer\n");
1851                 return -ENOMEM;
1852         }
1853
1854         /*
1855          * the statistic information display here is based on
1856          * the last statistics notification from uCode
1857          * might not reflect the current uCode activity
1858          */
1859         bt = &priv->statistics.bt_activity;
1860         accum_bt = &priv->accum_stats.bt_activity;
1861
1862         pos += iwl_statistics_flag(priv, buf, bufsz);
1863         pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
1864         pos += scnprintf(buf + pos, bufsz - pos,
1865                         "\t\t\tcurrent\t\t\taccumulative\n");
1866         pos += scnprintf(buf + pos, bufsz - pos,
1867                          "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
1868                          le32_to_cpu(bt->hi_priority_tx_req_cnt),
1869                          accum_bt->hi_priority_tx_req_cnt);
1870         pos += scnprintf(buf + pos, bufsz - pos,
1871                          "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
1872                          le32_to_cpu(bt->hi_priority_tx_denied_cnt),
1873                          accum_bt->hi_priority_tx_denied_cnt);
1874         pos += scnprintf(buf + pos, bufsz - pos,
1875                          "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
1876                          le32_to_cpu(bt->lo_priority_tx_req_cnt),
1877                          accum_bt->lo_priority_tx_req_cnt);
1878         pos += scnprintf(buf + pos, bufsz - pos,
1879                          "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
1880                          le32_to_cpu(bt->lo_priority_tx_denied_cnt),
1881                          accum_bt->lo_priority_tx_denied_cnt);
1882         pos += scnprintf(buf + pos, bufsz - pos,
1883                          "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
1884                          le32_to_cpu(bt->hi_priority_rx_req_cnt),
1885                          accum_bt->hi_priority_rx_req_cnt);
1886         pos += scnprintf(buf + pos, bufsz - pos,
1887                          "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
1888                          le32_to_cpu(bt->hi_priority_rx_denied_cnt),
1889                          accum_bt->hi_priority_rx_denied_cnt);
1890         pos += scnprintf(buf + pos, bufsz - pos,
1891                          "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
1892                          le32_to_cpu(bt->lo_priority_rx_req_cnt),
1893                          accum_bt->lo_priority_rx_req_cnt);
1894         pos += scnprintf(buf + pos, bufsz - pos,
1895                          "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
1896                          le32_to_cpu(bt->lo_priority_rx_denied_cnt),
1897                          accum_bt->lo_priority_rx_denied_cnt);
1898
1899         pos += scnprintf(buf + pos, bufsz - pos,
1900                          "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
1901                          le32_to_cpu(priv->statistics.num_bt_kills),
1902                          priv->statistics.accum_num_bt_kills);
1903
1904         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1905         kfree(buf);
1906         return ret;
1907 }
1908
1909 static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
1910                                         char __user *user_buf,
1911                                         size_t count, loff_t *ppos)
1912 {
1913         struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1914         int pos = 0;
1915         char *buf;
1916         int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) +
1917                 (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
1918         ssize_t ret;
1919
1920         if (!iwl_is_alive(priv))
1921                 return -EAGAIN;
1922
1923         buf = kzalloc(bufsz, GFP_KERNEL);
1924         if (!buf) {
1925                 IWL_ERR(priv, "Can not allocate Buffer\n");
1926                 return -ENOMEM;
1927         }
1928
1929         pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
1930         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
1931                          iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY),
1932                          priv->reply_tx_stats.pp_delay);
1933         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1934                          iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES),
1935                          priv->reply_tx_stats.pp_few_bytes);
1936         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1937                          iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO),
1938                          priv->reply_tx_stats.pp_bt_prio);
1939         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1940                          iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD),
1941                          priv->reply_tx_stats.pp_quiet_period);
1942         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1943                          iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK),
1944                          priv->reply_tx_stats.pp_calc_ttak);
1945         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
1946                          iwl_get_tx_fail_reason(
1947                                 TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY),
1948                          priv->reply_tx_stats.int_crossed_retry);
1949         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1950                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT),
1951                          priv->reply_tx_stats.short_limit);
1952         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1953                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT),
1954                          priv->reply_tx_stats.long_limit);
1955         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1956                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN),
1957                          priv->reply_tx_stats.fifo_underrun);
1958         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1959                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW),
1960                          priv->reply_tx_stats.drain_flow);
1961         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1962                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH),
1963                          priv->reply_tx_stats.rfkill_flush);
1964         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1965                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE),
1966                          priv->reply_tx_stats.life_expire);
1967         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1968                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS),
1969                          priv->reply_tx_stats.dest_ps);
1970         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1971                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED),
1972                          priv->reply_tx_stats.host_abort);
1973         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1974                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY),
1975                          priv->reply_tx_stats.pp_delay);
1976         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1977                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID),
1978                          priv->reply_tx_stats.sta_invalid);
1979         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1980                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED),
1981                          priv->reply_tx_stats.frag_drop);
1982         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1983                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE),
1984                          priv->reply_tx_stats.tid_disable);
1985         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1986                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED),
1987                          priv->reply_tx_stats.fifo_flush);
1988         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
1989                          iwl_get_tx_fail_reason(
1990                                 TX_STATUS_FAIL_INSUFFICIENT_CF_POLL),
1991                          priv->reply_tx_stats.insuff_cf_poll);
1992         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
1993                          iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX),
1994                          priv->reply_tx_stats.fail_hw_drop);
1995         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
1996                          iwl_get_tx_fail_reason(
1997                                 TX_STATUS_FAIL_NO_BEACON_ON_RADAR),
1998                          priv->reply_tx_stats.sta_color_mismatch);
1999         pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
2000                          priv->reply_tx_stats.unknown);
2001
2002         pos += scnprintf(buf + pos, bufsz - pos,
2003                          "\nStatistics_Agg_TX_Error:\n");
2004
2005         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2006                          iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK),
2007                          priv->reply_agg_tx_stats.underrun);
2008         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2009                          iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK),
2010                          priv->reply_agg_tx_stats.bt_prio);
2011         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2012                          iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK),
2013                          priv->reply_agg_tx_stats.few_bytes);
2014         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2015                          iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK),
2016                          priv->reply_agg_tx_stats.abort);
2017         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
2018                          iwl_get_agg_tx_fail_reason(
2019                                 AGG_TX_STATE_LAST_SENT_TTL_MSK),
2020                          priv->reply_agg_tx_stats.last_sent_ttl);
2021         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
2022                          iwl_get_agg_tx_fail_reason(
2023                                 AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK),
2024                          priv->reply_agg_tx_stats.last_sent_try);
2025         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
2026                          iwl_get_agg_tx_fail_reason(
2027                                 AGG_TX_STATE_LAST_SENT_BT_KILL_MSK),
2028                          priv->reply_agg_tx_stats.last_sent_bt_kill);
2029         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2030                          iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK),
2031                          priv->reply_agg_tx_stats.scd_query);
2032         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
2033                          iwl_get_agg_tx_fail_reason(
2034                                 AGG_TX_STATE_TEST_BAD_CRC32_MSK),
2035                          priv->reply_agg_tx_stats.bad_crc32);
2036         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2037                          iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK),
2038                          priv->reply_agg_tx_stats.response);
2039         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2040                          iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK),
2041                          priv->reply_agg_tx_stats.dump_tx);
2042         pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
2043                          iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK),
2044                          priv->reply_agg_tx_stats.delay_tx);
2045         pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
2046                          priv->reply_agg_tx_stats.unknown);
2047
2048         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2049         kfree(buf);
2050         return ret;
2051 }
2052
2053 static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
2054                                         char __user *user_buf,
2055                                         size_t count, loff_t *ppos) {
2056
2057         struct iwl_priv *priv = file->private_data;
2058         int pos = 0;
2059         int cnt = 0;
2060         char *buf;
2061         int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100;
2062         ssize_t ret;
2063         struct iwl_sensitivity_data *data;
2064
2065         data = &priv->sensitivity_data;
2066         buf = kzalloc(bufsz, GFP_KERNEL);
2067         if (!buf) {
2068                 IWL_ERR(priv, "Can not allocate Buffer\n");
2069                 return -ENOMEM;
2070         }
2071
2072         pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
2073                         data->auto_corr_ofdm);
2074         pos += scnprintf(buf + pos, bufsz - pos,
2075                         "auto_corr_ofdm_mrc:\t\t %u\n",
2076                         data->auto_corr_ofdm_mrc);
2077         pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
2078                         data->auto_corr_ofdm_x1);
2079         pos += scnprintf(buf + pos, bufsz - pos,
2080                         "auto_corr_ofdm_mrc_x1:\t\t %u\n",
2081                         data->auto_corr_ofdm_mrc_x1);
2082         pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
2083                         data->auto_corr_cck);
2084         pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
2085                         data->auto_corr_cck_mrc);
2086         pos += scnprintf(buf + pos, bufsz - pos,
2087                         "last_bad_plcp_cnt_ofdm:\t\t %u\n",
2088                         data->last_bad_plcp_cnt_ofdm);
2089         pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
2090                         data->last_fa_cnt_ofdm);
2091         pos += scnprintf(buf + pos, bufsz - pos,
2092                         "last_bad_plcp_cnt_cck:\t\t %u\n",
2093                         data->last_bad_plcp_cnt_cck);
2094         pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
2095                         data->last_fa_cnt_cck);
2096         pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
2097                         data->nrg_curr_state);
2098         pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
2099                         data->nrg_prev_state);
2100         pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
2101         for (cnt = 0; cnt < 10; cnt++) {
2102                 pos += scnprintf(buf + pos, bufsz - pos, " %u",
2103                                 data->nrg_value[cnt]);
2104         }
2105         pos += scnprintf(buf + pos, bufsz - pos, "\n");
2106         pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
2107         for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
2108                 pos += scnprintf(buf + pos, bufsz - pos, " %u",
2109                                 data->nrg_silence_rssi[cnt]);
2110         }
2111         pos += scnprintf(buf + pos, bufsz - pos, "\n");
2112         pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
2113                         data->nrg_silence_ref);
2114         pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
2115                         data->nrg_energy_idx);
2116         pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
2117                         data->nrg_silence_idx);
2118         pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
2119                         data->nrg_th_cck);
2120         pos += scnprintf(buf + pos, bufsz - pos,
2121                         "nrg_auto_corr_silence_diff:\t %u\n",
2122                         data->nrg_auto_corr_silence_diff);
2123         pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
2124                         data->num_in_cck_no_fa);
2125         pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
2126                         data->nrg_th_ofdm);
2127
2128         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2129         kfree(buf);
2130         return ret;
2131 }
2132
2133
2134 static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
2135                                         char __user *user_buf,
2136                                         size_t count, loff_t *ppos) {
2137
2138         struct iwl_priv *priv = file->private_data;
2139         int pos = 0;
2140         int cnt = 0;
2141         char *buf;
2142         int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100;
2143         ssize_t ret;
2144         struct iwl_chain_noise_data *data;
2145
2146         data = &priv->chain_noise_data;
2147         buf = kzalloc(bufsz, GFP_KERNEL);
2148         if (!buf) {
2149                 IWL_ERR(priv, "Can not allocate Buffer\n");
2150                 return -ENOMEM;
2151         }
2152
2153         pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
2154                         data->active_chains);
2155         pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
2156                         data->chain_noise_a);
2157         pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
2158                         data->chain_noise_b);
2159         pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
2160                         data->chain_noise_c);
2161         pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
2162                         data->chain_signal_a);
2163         pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
2164                         data->chain_signal_b);
2165         pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
2166                         data->chain_signal_c);
2167         pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
2168                         data->beacon_count);
2169
2170         pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
2171         for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
2172                 pos += scnprintf(buf + pos, bufsz - pos, " %u",
2173                                 data->disconn_array[cnt]);
2174         }
2175         pos += scnprintf(buf + pos, bufsz - pos, "\n");
2176         pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
2177         for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
2178                 pos += scnprintf(buf + pos, bufsz - pos, " %u",
2179                                 data->delta_gain_code[cnt]);
2180         }
2181         pos += scnprintf(buf + pos, bufsz - pos, "\n");
2182         pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
2183                         data->radio_write);
2184         pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
2185                         data->state);
2186
2187         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2188         kfree(buf);
2189         return ret;
2190 }
2191
2192 static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
2193                                                     char __user *user_buf,
2194                                                     size_t count, loff_t *ppos)
2195 {
2196         struct iwl_priv *priv = file->private_data;
2197         char buf[60];
2198         int pos = 0;
2199         const size_t bufsz = sizeof(buf);
2200         u32 pwrsave_status;
2201
2202         pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) &
2203                         CSR_GP_REG_POWER_SAVE_STATUS_MSK;
2204
2205         pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
2206         pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
2207                 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
2208                 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
2209                 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
2210                 "error");
2211
2212         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2213 }
2214
2215 static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
2216                                          const char __user *user_buf,
2217                                          size_t count, loff_t *ppos)
2218 {
2219         struct iwl_priv *priv = file->private_data;
2220         char buf[8];
2221         int buf_size;
2222         int clear;
2223
2224         memset(buf, 0, sizeof(buf));
2225         buf_size = min(count, sizeof(buf) -  1);
2226         if (copy_from_user(buf, user_buf, buf_size))
2227                 return -EFAULT;
2228         if (sscanf(buf, "%d", &clear) != 1)
2229                 return -EFAULT;
2230
2231         /* make request to uCode to retrieve statistics information */
2232         mutex_lock(&priv->mutex);
2233         iwl_send_statistics_request(priv, CMD_SYNC, true);
2234         mutex_unlock(&priv->mutex);
2235
2236         return count;
2237 }
2238
2239 static ssize_t iwl_dbgfs_csr_write(struct file *file,
2240                                          const char __user *user_buf,
2241                                          size_t count, loff_t *ppos)
2242 {
2243         struct iwl_priv *priv = file->private_data;
2244         char buf[8];
2245         int buf_size;
2246         int csr;
2247
2248         memset(buf, 0, sizeof(buf));
2249         buf_size = min(count, sizeof(buf) -  1);
2250         if (copy_from_user(buf, user_buf, buf_size))
2251                 return -EFAULT;
2252         if (sscanf(buf, "%d", &csr) != 1)
2253                 return -EFAULT;
2254
2255         iwl_dump_csr(priv);
2256
2257         return count;
2258 }
2259
2260 static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
2261                                         char __user *user_buf,
2262                                         size_t count, loff_t *ppos) {
2263
2264         struct iwl_priv *priv = file->private_data;
2265         int pos = 0;
2266         char buf[128];
2267         const size_t bufsz = sizeof(buf);
2268
2269         pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
2270                         priv->event_log.ucode_trace ? "On" : "Off");
2271         pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n",
2272                         priv->event_log.non_wraps_count);
2273         pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n",
2274                         priv->event_log.wraps_once_count);
2275         pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
2276                         priv->event_log.wraps_more_count);
2277
2278         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2279 }
2280
2281 static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
2282                                          const char __user *user_buf,
2283                                          size_t count, loff_t *ppos)
2284 {
2285         struct iwl_priv *priv = file->private_data;
2286         char buf[8];
2287         int buf_size;
2288         int trace;
2289
2290         memset(buf, 0, sizeof(buf));
2291         buf_size = min(count, sizeof(buf) -  1);
2292         if (copy_from_user(buf, user_buf, buf_size))
2293                 return -EFAULT;
2294         if (sscanf(buf, "%d", &trace) != 1)
2295                 return -EFAULT;
2296
2297         if (trace) {
2298                 priv->event_log.ucode_trace = true;
2299                 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
2300                 mod_timer(&priv->ucode_trace,
2301                         jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
2302         } else {
2303                 priv->event_log.ucode_trace = false;
2304                 del_timer_sync(&priv->ucode_trace);
2305         }
2306
2307         return count;
2308 }
2309
2310 static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file,
2311                                          char __user *user_buf,
2312                                          size_t count, loff_t *ppos) {
2313
2314         struct iwl_priv *priv = file->private_data;
2315         int len = 0;
2316         char buf[20];
2317
2318         len = sprintf(buf, "0x%04X\n",
2319                 le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags));
2320         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2321 }
2322
2323 static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file,
2324                                                 char __user *user_buf,
2325                                                 size_t count, loff_t *ppos) {
2326
2327         struct iwl_priv *priv = file->private_data;
2328         int len = 0;
2329         char buf[20];
2330
2331         len = sprintf(buf, "0x%04X\n",
2332                 le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags));
2333         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2334 }
2335
2336 static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
2337                                          char __user *user_buf,
2338                                          size_t count, loff_t *ppos)
2339 {
2340         struct iwl_priv *priv = file->private_data;
2341         char *buf;
2342         int pos = 0;
2343         ssize_t ret = -EFAULT;
2344
2345         ret = pos = iwl_dump_fh(priv, &buf, true);
2346         if (buf) {
2347                 ret = simple_read_from_buffer(user_buf,
2348                                               count, ppos, buf, pos);
2349                 kfree(buf);
2350         }
2351
2352         return ret;
2353 }
2354
2355 static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
2356                                         char __user *user_buf,
2357                                         size_t count, loff_t *ppos) {
2358
2359         struct iwl_priv *priv = file->private_data;
2360         int pos = 0;
2361         char buf[12];
2362         const size_t bufsz = sizeof(buf);
2363
2364         pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
2365                         priv->missed_beacon_threshold);
2366
2367         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2368 }
2369
2370 static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
2371                                          const char __user *user_buf,
2372                                          size_t count, loff_t *ppos)
2373 {
2374         struct iwl_priv *priv = file->private_data;
2375         char buf[8];
2376         int buf_size;
2377         int missed;
2378
2379         memset(buf, 0, sizeof(buf));
2380         buf_size = min(count, sizeof(buf) -  1);
2381         if (copy_from_user(buf, user_buf, buf_size))
2382                 return -EFAULT;
2383         if (sscanf(buf, "%d", &missed) != 1)
2384                 return -EINVAL;
2385
2386         if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
2387             missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
2388                 priv->missed_beacon_threshold =
2389                         IWL_MISSED_BEACON_THRESHOLD_DEF;
2390         else
2391                 priv->missed_beacon_threshold = missed;
2392
2393         return count;
2394 }
2395
2396 static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
2397                                         char __user *user_buf,
2398                                         size_t count, loff_t *ppos) {
2399
2400         struct iwl_priv *priv = file->private_data;
2401         int pos = 0;
2402         char buf[12];
2403         const size_t bufsz = sizeof(buf);
2404
2405         pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
2406                         priv->cfg->base_params->plcp_delta_threshold);
2407
2408         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2409 }
2410
2411 static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
2412                                         const char __user *user_buf,
2413                                         size_t count, loff_t *ppos) {
2414
2415         struct iwl_priv *priv = file->private_data;
2416         char buf[8];
2417         int buf_size;
2418         int plcp;
2419
2420         memset(buf, 0, sizeof(buf));
2421         buf_size = min(count, sizeof(buf) -  1);
2422         if (copy_from_user(buf, user_buf, buf_size))
2423                 return -EFAULT;
2424         if (sscanf(buf, "%d", &plcp) != 1)
2425                 return -EINVAL;
2426         if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
2427                 (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
2428                 priv->cfg->base_params->plcp_delta_threshold =
2429                         IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE;
2430         else
2431                 priv->cfg->base_params->plcp_delta_threshold = plcp;
2432         return count;
2433 }
2434
2435 static ssize_t iwl_dbgfs_force_reset_read(struct file *file,
2436                                         char __user *user_buf,
2437                                         size_t count, loff_t *ppos) {
2438
2439         struct iwl_priv *priv = file->private_data;
2440         int i, pos = 0;
2441         char buf[300];
2442         const size_t bufsz = sizeof(buf);
2443         struct iwl_force_reset *force_reset;
2444
2445         for (i = 0; i < IWL_MAX_FORCE_RESET; i++) {
2446                 force_reset = &priv->force_reset[i];
2447                 pos += scnprintf(buf + pos, bufsz - pos,
2448                                 "Force reset method %d\n", i);
2449                 pos += scnprintf(buf + pos, bufsz - pos,
2450                                 "\tnumber of reset request: %d\n",
2451                                 force_reset->reset_request_count);
2452                 pos += scnprintf(buf + pos, bufsz - pos,
2453                                 "\tnumber of reset request success: %d\n",
2454                                 force_reset->reset_success_count);
2455                 pos += scnprintf(buf + pos, bufsz - pos,
2456                                 "\tnumber of reset request reject: %d\n",
2457                                 force_reset->reset_reject_count);
2458                 pos += scnprintf(buf + pos, bufsz - pos,
2459                                 "\treset duration: %lu\n",
2460                                 force_reset->reset_duration);
2461         }
2462         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2463 }
2464
2465 static ssize_t iwl_dbgfs_force_reset_write(struct file *file,
2466                                         const char __user *user_buf,
2467                                         size_t count, loff_t *ppos) {
2468
2469         struct iwl_priv *priv = file->private_data;
2470         char buf[8];
2471         int buf_size;
2472         int reset, ret;
2473
2474         memset(buf, 0, sizeof(buf));
2475         buf_size = min(count, sizeof(buf) -  1);
2476         if (copy_from_user(buf, user_buf, buf_size))
2477                 return -EFAULT;
2478         if (sscanf(buf, "%d", &reset) != 1)
2479                 return -EINVAL;
2480         switch (reset) {
2481         case IWL_RF_RESET:
2482         case IWL_FW_RESET:
2483                 ret = iwl_force_reset(priv, reset, true);
2484                 break;
2485         default:
2486                 return -EINVAL;
2487         }
2488         return ret ? ret : count;
2489 }
2490
2491 static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
2492                                         const char __user *user_buf,
2493                                         size_t count, loff_t *ppos) {
2494
2495         struct iwl_priv *priv = file->private_data;
2496         char buf[8];
2497         int buf_size;
2498         int flush;
2499
2500         memset(buf, 0, sizeof(buf));
2501         buf_size = min(count, sizeof(buf) -  1);
2502         if (copy_from_user(buf, user_buf, buf_size))
2503                 return -EFAULT;
2504         if (sscanf(buf, "%d", &flush) != 1)
2505                 return -EINVAL;
2506
2507         if (iwl_is_rfkill(priv))
2508                 return -EFAULT;
2509
2510         iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
2511
2512         return count;
2513 }
2514
2515 static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file,
2516                                         const char __user *user_buf,
2517                                         size_t count, loff_t *ppos) {
2518
2519         struct iwl_priv *priv = file->private_data;
2520         char buf[8];
2521         int buf_size;
2522         int timeout;
2523
2524         memset(buf, 0, sizeof(buf));
2525         buf_size = min(count, sizeof(buf) -  1);
2526         if (copy_from_user(buf, user_buf, buf_size))
2527                 return -EFAULT;
2528         if (sscanf(buf, "%d", &timeout) != 1)
2529                 return -EINVAL;
2530         if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT)
2531                 timeout = IWL_DEF_WD_TIMEOUT;
2532
2533         priv->cfg->base_params->wd_timeout = timeout;
2534         iwl_setup_watchdog(priv);
2535         return count;
2536 }
2537
2538 static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
2539                                         char __user *user_buf,
2540                                         size_t count, loff_t *ppos) {
2541
2542         struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2543         int pos = 0;
2544         char buf[200];
2545         const size_t bufsz = sizeof(buf);
2546
2547         if (!priv->bt_enable_flag) {
2548                 pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n");
2549                 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2550         }
2551         pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n",
2552                 priv->bt_enable_flag);
2553         pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n",
2554                 priv->bt_full_concurrent ? "full concurrency" : "3-wire");
2555         pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, "
2556                          "last traffic notif: %d\n",
2557                 priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load);
2558         pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, "
2559                          "kill_ack_mask: %x, kill_cts_mask: %x\n",
2560                 priv->bt_ch_announce, priv->kill_ack_mask,
2561                 priv->kill_cts_mask);
2562
2563         pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: ");
2564         switch (priv->bt_traffic_load) {
2565         case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
2566                 pos += scnprintf(buf + pos, bufsz - pos, "Continuous\n");
2567                 break;
2568         case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
2569                 pos += scnprintf(buf + pos, bufsz - pos, "High\n");
2570                 break;
2571         case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
2572                 pos += scnprintf(buf + pos, bufsz - pos, "Low\n");
2573                 break;
2574         case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
2575         default:
2576                 pos += scnprintf(buf + pos, bufsz - pos, "None\n");
2577                 break;
2578         }
2579
2580         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2581 }
2582
2583 static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
2584                                         char __user *user_buf,
2585                                         size_t count, loff_t *ppos)
2586 {
2587         struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
2588
2589         int pos = 0;
2590         char buf[40];
2591         const size_t bufsz = sizeof(buf);
2592
2593         if (priv->cfg->ht_params)
2594                 pos += scnprintf(buf + pos, bufsz - pos,
2595                          "use %s for aggregation\n",
2596                          (priv->cfg->ht_params->use_rts_for_aggregation) ?
2597                                 "rts/cts" : "cts-to-self");
2598         else
2599                 pos += scnprintf(buf + pos, bufsz - pos, "N/A");
2600
2601         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2602 }
2603
2604 static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
2605                                         const char __user *user_buf,
2606                                         size_t count, loff_t *ppos) {
2607
2608         struct iwl_priv *priv = file->private_data;
2609         char buf[8];
2610         int buf_size;
2611         int rts;
2612
2613         if (!priv->cfg->ht_params)
2614                 return -EINVAL;
2615
2616         memset(buf, 0, sizeof(buf));
2617         buf_size = min(count, sizeof(buf) -  1);
2618         if (copy_from_user(buf, user_buf, buf_size))
2619                 return -EFAULT;
2620         if (sscanf(buf, "%d", &rts) != 1)
2621                 return -EINVAL;
2622         if (rts)
2623                 priv->cfg->ht_params->use_rts_for_aggregation = true;
2624         else
2625                 priv->cfg->ht_params->use_rts_for_aggregation = false;
2626         return count;
2627 }
2628
2629 DEBUGFS_READ_FILE_OPS(rx_statistics);
2630 DEBUGFS_READ_FILE_OPS(tx_statistics);
2631 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
2632 DEBUGFS_READ_FILE_OPS(rx_queue);
2633 DEBUGFS_READ_FILE_OPS(tx_queue);
2634 DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
2635 DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
2636 DEBUGFS_READ_FILE_OPS(ucode_general_stats);
2637 DEBUGFS_READ_FILE_OPS(sensitivity);
2638 DEBUGFS_READ_FILE_OPS(chain_noise);
2639 DEBUGFS_READ_FILE_OPS(power_save_status);
2640 DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
2641 DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
2642 DEBUGFS_WRITE_FILE_OPS(csr);
2643 DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
2644 DEBUGFS_READ_FILE_OPS(fh_reg);
2645 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
2646 DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
2647 DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
2648 DEBUGFS_READ_FILE_OPS(rxon_flags);
2649 DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
2650 DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
2651 DEBUGFS_READ_FILE_OPS(ucode_bt_stats);
2652 DEBUGFS_WRITE_FILE_OPS(wd_timeout);
2653 DEBUGFS_READ_FILE_OPS(bt_traffic);
2654 DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
2655 DEBUGFS_READ_FILE_OPS(reply_tx_error);
2656
2657 /*
2658  * Create the debugfs files and directories
2659  *
2660  */
2661 int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
2662 {
2663         struct dentry *phyd = priv->hw->wiphy->debugfsdir;
2664         struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
2665
2666         dir_drv = debugfs_create_dir(name, phyd);
2667         if (!dir_drv)
2668                 return -ENOMEM;
2669
2670         priv->debugfs_dir = dir_drv;
2671
2672         dir_data = debugfs_create_dir("data", dir_drv);
2673         if (!dir_data)
2674                 goto err;
2675         dir_rf = debugfs_create_dir("rf", dir_drv);
2676         if (!dir_rf)
2677                 goto err;
2678         dir_debug = debugfs_create_dir("debug", dir_drv);
2679         if (!dir_debug)
2680                 goto err;
2681
2682         DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
2683         DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
2684         DEBUGFS_ADD_FILE(wowlan_sram, dir_data, S_IRUSR);
2685         DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
2686         DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
2687         DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
2688         DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
2689         DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
2690         DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
2691         DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
2692         DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
2693         DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
2694         DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
2695         DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
2696         DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
2697         DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
2698         DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
2699         DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
2700         DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
2701         DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
2702         DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
2703         DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
2704         DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
2705         DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
2706         DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
2707         DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
2708         DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
2709         DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
2710         DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
2711         DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
2712         DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR);
2713
2714         DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
2715         DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
2716         DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
2717         DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
2718         DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
2719         DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
2720         DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
2721         DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
2722         if (iwl_advanced_bt_coexist(priv))
2723                 DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
2724         DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
2725                          &priv->disable_sens_cal);
2726         DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
2727                          &priv->disable_chain_noise_cal);
2728         return 0;
2729
2730 err:
2731         IWL_ERR(priv, "Can't create the debugfs directory\n");
2732         iwl_dbgfs_unregister(priv);
2733         return -ENOMEM;
2734 }
2735
2736 /**
2737  * Remove the debugfs files and directories
2738  *
2739  */
2740 void iwl_dbgfs_unregister(struct iwl_priv *priv)
2741 {
2742         if (!priv->debugfs_dir)
2743                 return;
2744
2745         debugfs_remove_recursive(priv->debugfs_dir);
2746         priv->debugfs_dir = NULL;
2747 }
2748
2749
2750