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