upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / net / wireless / iwlwifi / iwl-debugfs.c
1 /******************************************************************************
2  *
3  * GPL LICENSE SUMMARY
4  *
5  * Copyright(c) 2008 - 2010 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-calib.h"
43
44 /* create and remove of files */
45 #define DEBUGFS_ADD_FILE(name, parent, mode) do {                       \
46         if (!debugfs_create_file(#name, mode, parent, priv,             \
47                                  &iwl_dbgfs_##name##_ops))              \
48                 goto err;                                               \
49 } while (0)
50
51 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do {                        \
52         struct dentry *__tmp;                                           \
53         __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR,           \
54                                     parent, ptr);                       \
55         if (IS_ERR(__tmp) || !__tmp)                                    \
56                 goto err;                                               \
57 } while (0)
58
59 #define DEBUGFS_ADD_X32(name, parent, ptr) do {                         \
60         struct dentry *__tmp;                                           \
61         __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR,            \
62                                    parent, ptr);                        \
63         if (IS_ERR(__tmp) || !__tmp)                                    \
64                 goto err;                                               \
65 } while (0)
66
67 /* file operation */
68 #define DEBUGFS_READ_FUNC(name)                                         \
69 static ssize_t iwl_dbgfs_##name##_read(struct file *file,               \
70                                         char __user *user_buf,          \
71                                         size_t count, loff_t *ppos);
72
73 #define DEBUGFS_WRITE_FUNC(name)                                        \
74 static ssize_t iwl_dbgfs_##name##_write(struct file *file,              \
75                                         const char __user *user_buf,    \
76                                         size_t count, loff_t *ppos);
77
78
79 static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
80 {
81         file->private_data = inode->i_private;
82         return 0;
83 }
84
85 #define DEBUGFS_READ_FILE_OPS(name)                                     \
86         DEBUGFS_READ_FUNC(name);                                        \
87 static const struct file_operations iwl_dbgfs_##name##_ops = {          \
88         .read = iwl_dbgfs_##name##_read,                                \
89         .open = iwl_dbgfs_open_file_generic,                            \
90 };
91
92 #define DEBUGFS_WRITE_FILE_OPS(name)                                    \
93         DEBUGFS_WRITE_FUNC(name);                                       \
94 static const struct file_operations iwl_dbgfs_##name##_ops = {          \
95         .write = iwl_dbgfs_##name##_write,                              \
96         .open = iwl_dbgfs_open_file_generic,                            \
97 };
98
99
100 #define DEBUGFS_READ_WRITE_FILE_OPS(name)                               \
101         DEBUGFS_READ_FUNC(name);                                        \
102         DEBUGFS_WRITE_FUNC(name);                                       \
103 static const struct file_operations iwl_dbgfs_##name##_ops = {          \
104         .write = iwl_dbgfs_##name##_write,                              \
105         .read = iwl_dbgfs_##name##_read,                                \
106         .open = iwl_dbgfs_open_file_generic,                            \
107 };
108
109 static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
110                                                 char __user *user_buf,
111                                                 size_t count, loff_t *ppos) {
112
113         struct iwl_priv *priv = file->private_data;
114         char *buf;
115         int pos = 0;
116
117         int cnt;
118         ssize_t ret;
119         const size_t bufsz = 100 +
120                 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
121         buf = kzalloc(bufsz, GFP_KERNEL);
122         if (!buf)
123                 return -ENOMEM;
124         pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
125         for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
126                 pos += scnprintf(buf + pos, bufsz - pos,
127                                  "\t%25s\t\t: %u\n",
128                                  get_mgmt_string(cnt),
129                                  priv->tx_stats.mgmt[cnt]);
130         }
131         pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
132         for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
133                 pos += scnprintf(buf + pos, bufsz - pos,
134                                  "\t%25s\t\t: %u\n",
135                                  get_ctrl_string(cnt),
136                                  priv->tx_stats.ctrl[cnt]);
137         }
138         pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
139         pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
140                          priv->tx_stats.data_cnt);
141         pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
142                          priv->tx_stats.data_bytes);
143         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
144         kfree(buf);
145         return ret;
146 }
147
148 static ssize_t iwl_dbgfs_clear_traffic_statistics_write(struct file *file,
149                                         const char __user *user_buf,
150                                         size_t count, loff_t *ppos)
151 {
152         struct iwl_priv *priv = file->private_data;
153         u32 clear_flag;
154         char buf[8];
155         int buf_size;
156
157         memset(buf, 0, sizeof(buf));
158         buf_size = min(count, sizeof(buf) -  1);
159         if (copy_from_user(buf, user_buf, buf_size))
160                 return -EFAULT;
161         if (sscanf(buf, "%x", &clear_flag) != 1)
162                 return -EFAULT;
163         iwl_clear_traffic_stats(priv);
164
165         return count;
166 }
167
168 static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
169                                                 char __user *user_buf,
170                                                 size_t count, loff_t *ppos) {
171
172         struct iwl_priv *priv = file->private_data;
173         char *buf;
174         int pos = 0;
175         int cnt;
176         ssize_t ret;
177         const size_t bufsz = 100 +
178                 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
179         buf = kzalloc(bufsz, GFP_KERNEL);
180         if (!buf)
181                 return -ENOMEM;
182
183         pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
184         for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
185                 pos += scnprintf(buf + pos, bufsz - pos,
186                                  "\t%25s\t\t: %u\n",
187                                  get_mgmt_string(cnt),
188                                  priv->rx_stats.mgmt[cnt]);
189         }
190         pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
191         for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
192                 pos += scnprintf(buf + pos, bufsz - pos,
193                                  "\t%25s\t\t: %u\n",
194                                  get_ctrl_string(cnt),
195                                  priv->rx_stats.ctrl[cnt]);
196         }
197         pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
198         pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
199                          priv->rx_stats.data_cnt);
200         pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
201                          priv->rx_stats.data_bytes);
202
203         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
204         kfree(buf);
205         return ret;
206 }
207
208 #define BYTE1_MASK 0x000000ff;
209 #define BYTE2_MASK 0x0000ffff;
210 #define BYTE3_MASK 0x00ffffff;
211 static ssize_t iwl_dbgfs_sram_read(struct file *file,
212                                         char __user *user_buf,
213                                         size_t count, loff_t *ppos)
214 {
215         u32 val;
216         char *buf;
217         ssize_t ret;
218         int i;
219         int pos = 0;
220         struct iwl_priv *priv = file->private_data;
221         size_t bufsz;
222
223         /* default is to dump the entire data segment */
224         if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
225                 priv->dbgfs_sram_offset = 0x800000;
226                 if (priv->ucode_type == UCODE_INIT)
227                         priv->dbgfs_sram_len = priv->ucode_init_data.len;
228                 else
229                         priv->dbgfs_sram_len = priv->ucode_data.len;
230         }
231         bufsz =  30 + priv->dbgfs_sram_len * sizeof(char) * 10;
232         buf = kmalloc(bufsz, GFP_KERNEL);
233         if (!buf)
234                 return -ENOMEM;
235         pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
236                         priv->dbgfs_sram_len);
237         pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
238                         priv->dbgfs_sram_offset);
239         for (i = priv->dbgfs_sram_len; i > 0; i -= 4) {
240                 val = iwl_read_targ_mem(priv, priv->dbgfs_sram_offset + \
241                                         priv->dbgfs_sram_len - i);
242                 if (i < 4) {
243                         switch (i) {
244                         case 1:
245                                 val &= BYTE1_MASK;
246                                 break;
247                         case 2:
248                                 val &= BYTE2_MASK;
249                                 break;
250                         case 3:
251                                 val &= BYTE3_MASK;
252                                 break;
253                         }
254                 }
255                 if (!(i % 16))
256                         pos += scnprintf(buf + pos, bufsz - pos, "\n");
257                 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
258         }
259         pos += scnprintf(buf + pos, bufsz - pos, "\n");
260
261         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
262         kfree(buf);
263         return ret;
264 }
265
266 static ssize_t iwl_dbgfs_sram_write(struct file *file,
267                                         const char __user *user_buf,
268                                         size_t count, loff_t *ppos)
269 {
270         struct iwl_priv *priv = file->private_data;
271         char buf[64];
272         int buf_size;
273         u32 offset, len;
274
275         memset(buf, 0, sizeof(buf));
276         buf_size = min(count, sizeof(buf) -  1);
277         if (copy_from_user(buf, user_buf, buf_size))
278                 return -EFAULT;
279
280         if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
281                 priv->dbgfs_sram_offset = offset;
282                 priv->dbgfs_sram_len = len;
283         } else {
284                 priv->dbgfs_sram_offset = 0;
285                 priv->dbgfs_sram_len = 0;
286         }
287
288         return count;
289 }
290
291 static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
292                                         size_t count, loff_t *ppos)
293 {
294         struct iwl_priv *priv = file->private_data;
295         struct iwl_station_entry *station;
296         int max_sta = priv->hw_params.max_stations;
297         char *buf;
298         int i, j, pos = 0;
299         ssize_t ret;
300         /* Add 30 for initial string */
301         const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations);
302
303         buf = kmalloc(bufsz, GFP_KERNEL);
304         if (!buf)
305                 return -ENOMEM;
306
307         pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
308                         priv->num_stations);
309
310         for (i = 0; i < max_sta; i++) {
311                 station = &priv->stations[i];
312                 if (!station->used)
313                         continue;
314                 pos += scnprintf(buf + pos, bufsz - pos,
315                                  "station %d - addr: %pM, flags: %#x\n",
316                                  i, station->sta.sta.addr,
317                                  station->sta.station_flags_msk);
318                 pos += scnprintf(buf + pos, bufsz - pos,
319                                 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
320                 pos += scnprintf(buf + pos, bufsz - pos,
321                                 "start_idx\tbitmap\t\t\trate_n_flags\n");
322
323                 for (j = 0; j < MAX_TID_COUNT; j++) {
324                         pos += scnprintf(buf + pos, bufsz - pos,
325                                 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
326                                 j, station->tid[j].seq_number,
327                                 station->tid[j].agg.txq_id,
328                                 station->tid[j].agg.frame_count,
329                                 station->tid[j].tfds_in_queue,
330                                 station->tid[j].agg.start_idx,
331                                 station->tid[j].agg.bitmap,
332                                 station->tid[j].agg.rate_n_flags);
333
334                         if (station->tid[j].agg.wait_for_ba)
335                                 pos += scnprintf(buf + pos, bufsz - pos,
336                                                  " - waitforba");
337                         pos += scnprintf(buf + pos, bufsz - pos, "\n");
338                 }
339
340                 pos += scnprintf(buf + pos, bufsz - pos, "\n");
341         }
342
343         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
344         kfree(buf);
345         return ret;
346 }
347
348 static ssize_t iwl_dbgfs_nvm_read(struct file *file,
349                                        char __user *user_buf,
350                                        size_t count,
351                                        loff_t *ppos)
352 {
353         ssize_t ret;
354         struct iwl_priv *priv = file->private_data;
355         int pos = 0, ofs = 0, buf_size = 0;
356         const u8 *ptr;
357         char *buf;
358         u16 eeprom_ver;
359         size_t eeprom_len = priv->cfg->eeprom_size;
360         buf_size = 4 * eeprom_len + 256;
361
362         if (eeprom_len % 16) {
363                 IWL_ERR(priv, "NVM size is not multiple of 16.\n");
364                 return -ENODATA;
365         }
366
367         ptr = priv->eeprom;
368         if (!ptr) {
369                 IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
370                 return -ENOMEM;
371         }
372
373         /* 4 characters for byte 0xYY */
374         buf = kzalloc(buf_size, GFP_KERNEL);
375         if (!buf) {
376                 IWL_ERR(priv, "Can not allocate Buffer\n");
377                 return -ENOMEM;
378         }
379         eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
380         pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, "
381                         "version: 0x%x\n",
382                         (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
383                          ? "OTP" : "EEPROM", eeprom_ver);
384         for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
385                 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
386                 hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
387                                    buf_size - pos, 0);
388                 pos += strlen(buf + pos);
389                 if (buf_size - pos > 0)
390                         buf[pos++] = '\n';
391         }
392
393         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
394         kfree(buf);
395         return ret;
396 }
397
398 static ssize_t iwl_dbgfs_log_event_read(struct file *file,
399                                          char __user *user_buf,
400                                          size_t count, loff_t *ppos)
401 {
402         struct iwl_priv *priv = file->private_data;
403         char *buf;
404         int pos = 0;
405         ssize_t ret = -ENOMEM;
406
407         ret = pos = priv->cfg->ops->lib->dump_nic_event_log(
408                                         priv, true, &buf, true);
409         if (buf) {
410                 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
411                 kfree(buf);
412         }
413         return ret;
414 }
415
416 static ssize_t iwl_dbgfs_log_event_write(struct file *file,
417                                         const char __user *user_buf,
418                                         size_t count, loff_t *ppos)
419 {
420         struct iwl_priv *priv = file->private_data;
421         u32 event_log_flag;
422         char buf[8];
423         int buf_size;
424
425         memset(buf, 0, sizeof(buf));
426         buf_size = min(count, sizeof(buf) -  1);
427         if (copy_from_user(buf, user_buf, buf_size))
428                 return -EFAULT;
429         if (sscanf(buf, "%d", &event_log_flag) != 1)
430                 return -EFAULT;
431         if (event_log_flag == 1)
432                 priv->cfg->ops->lib->dump_nic_event_log(priv, true,
433                                                         NULL, false);
434
435         return count;
436 }
437
438
439
440 static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
441                                        size_t count, loff_t *ppos)
442 {
443         struct iwl_priv *priv = file->private_data;
444         struct ieee80211_channel *channels = NULL;
445         const struct ieee80211_supported_band *supp_band = NULL;
446         int pos = 0, i, bufsz = PAGE_SIZE;
447         char *buf;
448         ssize_t ret;
449
450         if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
451                 return -EAGAIN;
452
453         buf = kzalloc(bufsz, GFP_KERNEL);
454         if (!buf) {
455                 IWL_ERR(priv, "Can not allocate Buffer\n");
456                 return -ENOMEM;
457         }
458
459         supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
460         if (supp_band) {
461                 channels = supp_band->channels;
462
463                 pos += scnprintf(buf + pos, bufsz - pos,
464                                 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
465                                 supp_band->n_channels);
466
467                 for (i = 0; i < supp_band->n_channels; i++)
468                         pos += scnprintf(buf + pos, bufsz - pos,
469                                         "%d: %ddBm: BSS%s%s, %s.\n",
470                                         ieee80211_frequency_to_channel(
471                                         channels[i].center_freq),
472                                         channels[i].max_power,
473                                         channels[i].flags & IEEE80211_CHAN_RADAR ?
474                                         " (IEEE 802.11h required)" : "",
475                                         ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
476                                         || (channels[i].flags &
477                                         IEEE80211_CHAN_RADAR)) ? "" :
478                                         ", IBSS",
479                                         channels[i].flags &
480                                         IEEE80211_CHAN_PASSIVE_SCAN ?
481                                         "passive only" : "active/passive");
482         }
483         supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
484         if (supp_band) {
485                 channels = supp_band->channels;
486
487                 pos += scnprintf(buf + pos, bufsz - pos,
488                                 "Displaying %d channels in 5.2GHz band (802.11a)\n",
489                                 supp_band->n_channels);
490
491                 for (i = 0; i < supp_band->n_channels; i++)
492                         pos += scnprintf(buf + pos, bufsz - pos,
493                                         "%d: %ddBm: BSS%s%s, %s.\n",
494                                         ieee80211_frequency_to_channel(
495                                         channels[i].center_freq),
496                                         channels[i].max_power,
497                                         channels[i].flags & IEEE80211_CHAN_RADAR ?
498                                         " (IEEE 802.11h required)" : "",
499                                         ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
500                                         || (channels[i].flags &
501                                         IEEE80211_CHAN_RADAR)) ? "" :
502                                         ", IBSS",
503                                         channels[i].flags &
504                                         IEEE80211_CHAN_PASSIVE_SCAN ?
505                                         "passive only" : "active/passive");
506         }
507         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
508         kfree(buf);
509         return ret;
510 }
511
512 static ssize_t iwl_dbgfs_status_read(struct file *file,
513                                                 char __user *user_buf,
514                                                 size_t count, loff_t *ppos) {
515
516         struct iwl_priv *priv = file->private_data;
517         char buf[512];
518         int pos = 0;
519         const size_t bufsz = sizeof(buf);
520
521         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
522                 test_bit(STATUS_HCMD_ACTIVE, &priv->status));
523         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
524                 test_bit(STATUS_INT_ENABLED, &priv->status));
525         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
526                 test_bit(STATUS_RF_KILL_HW, &priv->status));
527         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n",
528                 test_bit(STATUS_CT_KILL, &priv->status));
529         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
530                 test_bit(STATUS_INIT, &priv->status));
531         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
532                 test_bit(STATUS_ALIVE, &priv->status));
533         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
534                 test_bit(STATUS_READY, &priv->status));
535         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
536                 test_bit(STATUS_TEMPERATURE, &priv->status));
537         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
538                 test_bit(STATUS_GEO_CONFIGURED, &priv->status));
539         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
540                 test_bit(STATUS_EXIT_PENDING, &priv->status));
541         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
542                 test_bit(STATUS_STATISTICS, &priv->status));
543         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
544                 test_bit(STATUS_SCANNING, &priv->status));
545         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
546                 test_bit(STATUS_SCAN_ABORTING, &priv->status));
547         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
548                 test_bit(STATUS_SCAN_HW, &priv->status));
549         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
550                 test_bit(STATUS_POWER_PMI, &priv->status));
551         pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
552                 test_bit(STATUS_FW_ERROR, &priv->status));
553         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
554 }
555
556 static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
557                                         char __user *user_buf,
558                                         size_t count, loff_t *ppos) {
559
560         struct iwl_priv *priv = file->private_data;
561         int pos = 0;
562         int cnt = 0;
563         char *buf;
564         int bufsz = 24 * 64; /* 24 items * 64 char per item */
565         ssize_t ret;
566
567         buf = kzalloc(bufsz, GFP_KERNEL);
568         if (!buf) {
569                 IWL_ERR(priv, "Can not allocate Buffer\n");
570                 return -ENOMEM;
571         }
572
573         pos += scnprintf(buf + pos, bufsz - pos,
574                         "Interrupt Statistics Report:\n");
575
576         pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
577                 priv->isr_stats.hw);
578         pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
579                 priv->isr_stats.sw);
580         if (priv->isr_stats.sw > 0) {
581                 pos += scnprintf(buf + pos, bufsz - pos,
582                         "\tLast Restarting Code:  0x%X\n",
583                         priv->isr_stats.sw_err);
584         }
585 #ifdef CONFIG_IWLWIFI_DEBUG
586         pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
587                 priv->isr_stats.sch);
588         pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
589                 priv->isr_stats.alive);
590 #endif
591         pos += scnprintf(buf + pos, bufsz - pos,
592                 "HW RF KILL switch toggled:\t %u\n",
593                 priv->isr_stats.rfkill);
594
595         pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
596                 priv->isr_stats.ctkill);
597
598         pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
599                 priv->isr_stats.wakeup);
600
601         pos += scnprintf(buf + pos, bufsz - pos,
602                 "Rx command responses:\t\t %u\n",
603                 priv->isr_stats.rx);
604         for (cnt = 0; cnt < REPLY_MAX; cnt++) {
605                 if (priv->isr_stats.rx_handlers[cnt] > 0)
606                         pos += scnprintf(buf + pos, bufsz - pos,
607                                 "\tRx handler[%36s]:\t\t %u\n",
608                                 get_cmd_string(cnt),
609                                 priv->isr_stats.rx_handlers[cnt]);
610         }
611
612         pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
613                 priv->isr_stats.tx);
614
615         pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
616                 priv->isr_stats.unhandled);
617
618         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
619         kfree(buf);
620         return ret;
621 }
622
623 static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
624                                          const char __user *user_buf,
625                                          size_t count, loff_t *ppos)
626 {
627         struct iwl_priv *priv = file->private_data;
628         char buf[8];
629         int buf_size;
630         u32 reset_flag;
631
632         memset(buf, 0, sizeof(buf));
633         buf_size = min(count, sizeof(buf) -  1);
634         if (copy_from_user(buf, user_buf, buf_size))
635                 return -EFAULT;
636         if (sscanf(buf, "%x", &reset_flag) != 1)
637                 return -EFAULT;
638         if (reset_flag == 0)
639                 iwl_clear_isr_stats(priv);
640
641         return count;
642 }
643
644 static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
645                                        size_t count, loff_t *ppos)
646 {
647         struct iwl_priv *priv = file->private_data;
648         int pos = 0, i;
649         char buf[256];
650         const size_t bufsz = sizeof(buf);
651
652         for (i = 0; i < AC_NUM; i++) {
653                 pos += scnprintf(buf + pos, bufsz - pos,
654                         "\tcw_min\tcw_max\taifsn\ttxop\n");
655                 pos += scnprintf(buf + pos, bufsz - pos,
656                                 "AC[%d]\t%u\t%u\t%u\t%u\n", i,
657                                 priv->qos_data.def_qos_parm.ac[i].cw_min,
658                                 priv->qos_data.def_qos_parm.ac[i].cw_max,
659                                 priv->qos_data.def_qos_parm.ac[i].aifsn,
660                                 priv->qos_data.def_qos_parm.ac[i].edca_txop);
661         }
662         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
663 }
664
665 static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
666                                   size_t count, loff_t *ppos)
667 {
668         struct iwl_priv *priv = file->private_data;
669         int pos = 0;
670         char buf[256];
671         const size_t bufsz = sizeof(buf);
672
673         pos += scnprintf(buf + pos, bufsz - pos,
674                          "allow blinking: %s\n",
675                          (priv->allow_blinking) ? "True" : "False");
676         if (priv->allow_blinking) {
677                 pos += scnprintf(buf + pos, bufsz - pos,
678                                  "Led blinking rate: %u\n",
679                                  priv->last_blink_rate);
680                 pos += scnprintf(buf + pos, bufsz - pos,
681                                  "Last blink time: %lu\n",
682                                  priv->last_blink_time);
683         }
684
685         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
686 }
687
688 static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
689                                 char __user *user_buf,
690                                 size_t count, loff_t *ppos)
691 {
692         struct iwl_priv *priv = file->private_data;
693         struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
694         struct iwl_tt_restriction *restriction;
695         char buf[100];
696         int pos = 0;
697         const size_t bufsz = sizeof(buf);
698
699         pos += scnprintf(buf + pos, bufsz - pos,
700                         "Thermal Throttling Mode: %s\n",
701                         tt->advanced_tt ? "Advance" : "Legacy");
702         pos += scnprintf(buf + pos, bufsz - pos,
703                         "Thermal Throttling State: %d\n",
704                         tt->state);
705         if (tt->advanced_tt) {
706                 restriction = tt->restriction + tt->state;
707                 pos += scnprintf(buf + pos, bufsz - pos,
708                                 "Tx mode: %d\n",
709                                 restriction->tx_stream);
710                 pos += scnprintf(buf + pos, bufsz - pos,
711                                 "Rx mode: %d\n",
712                                 restriction->rx_stream);
713                 pos += scnprintf(buf + pos, bufsz - pos,
714                                 "HT mode: %d\n",
715                                 restriction->is_ht);
716         }
717         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
718 }
719
720 static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
721                                          const char __user *user_buf,
722                                          size_t count, loff_t *ppos)
723 {
724         struct iwl_priv *priv = file->private_data;
725         char buf[8];
726         int buf_size;
727         int ht40;
728
729         memset(buf, 0, sizeof(buf));
730         buf_size = min(count, sizeof(buf) -  1);
731         if (copy_from_user(buf, user_buf, buf_size))
732                 return -EFAULT;
733         if (sscanf(buf, "%d", &ht40) != 1)
734                 return -EFAULT;
735         if (!iwl_is_associated(priv))
736                 priv->disable_ht40 = ht40 ? true : false;
737         else {
738                 IWL_ERR(priv, "Sta associated with AP - "
739                         "Change to 40MHz channel support is not allowed\n");
740                 return -EINVAL;
741         }
742
743         return count;
744 }
745
746 static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
747                                          char __user *user_buf,
748                                          size_t count, loff_t *ppos)
749 {
750         struct iwl_priv *priv = file->private_data;
751         char buf[100];
752         int pos = 0;
753         const size_t bufsz = sizeof(buf);
754
755         pos += scnprintf(buf + pos, bufsz - pos,
756                         "11n 40MHz Mode: %s\n",
757                         priv->disable_ht40 ? "Disabled" : "Enabled");
758         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
759 }
760
761 static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
762                                                     const char __user *user_buf,
763                                                     size_t count, loff_t *ppos)
764 {
765         struct iwl_priv *priv = file->private_data;
766         char buf[8];
767         int buf_size;
768         int value;
769
770         memset(buf, 0, sizeof(buf));
771         buf_size = min(count, sizeof(buf) -  1);
772         if (copy_from_user(buf, user_buf, buf_size))
773                 return -EFAULT;
774
775         if (sscanf(buf, "%d", &value) != 1)
776                 return -EINVAL;
777
778         /*
779          * Our users expect 0 to be "CAM", but 0 isn't actually
780          * valid here. However, let's not confuse them and present
781          * IWL_POWER_INDEX_1 as "1", not "0".
782          */
783         if (value == 0)
784                 return -EINVAL;
785         else if (value > 0)
786                 value -= 1;
787
788         if (value != -1 && (value < 0 || value >= IWL_POWER_NUM))
789                 return -EINVAL;
790
791         if (!iwl_is_ready_rf(priv))
792                 return -EAGAIN;
793
794         priv->power_data.debug_sleep_level_override = value;
795
796         mutex_lock(&priv->mutex);
797         iwl_power_update_mode(priv, true);
798         mutex_unlock(&priv->mutex);
799
800         return count;
801 }
802
803 static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
804                                                    char __user *user_buf,
805                                                    size_t count, loff_t *ppos)
806 {
807         struct iwl_priv *priv = file->private_data;
808         char buf[10];
809         int pos, value;
810         const size_t bufsz = sizeof(buf);
811
812         /* see the write function */
813         value = priv->power_data.debug_sleep_level_override;
814         if (value >= 0)
815                 value += 1;
816
817         pos = scnprintf(buf, bufsz, "%d\n", value);
818         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
819 }
820
821 static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
822                                                     char __user *user_buf,
823                                                     size_t count, loff_t *ppos)
824 {
825         struct iwl_priv *priv = file->private_data;
826         char buf[200];
827         int pos = 0, i;
828         const size_t bufsz = sizeof(buf);
829         struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd;
830
831         pos += scnprintf(buf + pos, bufsz - pos,
832                          "flags: %#.2x\n", le16_to_cpu(cmd->flags));
833         pos += scnprintf(buf + pos, bufsz - pos,
834                          "RX/TX timeout: %d/%d usec\n",
835                          le32_to_cpu(cmd->rx_data_timeout),
836                          le32_to_cpu(cmd->tx_data_timeout));
837         for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
838                 pos += scnprintf(buf + pos, bufsz - pos,
839                                  "sleep_interval[%d]: %d\n", i,
840                                  le32_to_cpu(cmd->sleep_interval[i]));
841
842         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
843 }
844
845 DEBUGFS_READ_WRITE_FILE_OPS(sram);
846 DEBUGFS_READ_WRITE_FILE_OPS(log_event);
847 DEBUGFS_READ_FILE_OPS(nvm);
848 DEBUGFS_READ_FILE_OPS(stations);
849 DEBUGFS_READ_FILE_OPS(channels);
850 DEBUGFS_READ_FILE_OPS(status);
851 DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
852 DEBUGFS_READ_FILE_OPS(qos);
853 DEBUGFS_READ_FILE_OPS(led);
854 DEBUGFS_READ_FILE_OPS(thermal_throttling);
855 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
856 DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
857 DEBUGFS_READ_FILE_OPS(current_sleep_command);
858
859 static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
860                                          char __user *user_buf,
861                                          size_t count, loff_t *ppos)
862 {
863         struct iwl_priv *priv = file->private_data;
864         int pos = 0, ofs = 0;
865         int cnt = 0, entry;
866         struct iwl_tx_queue *txq;
867         struct iwl_queue *q;
868         struct iwl_rx_queue *rxq = &priv->rxq;
869         char *buf;
870         int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
871                 (priv->cfg->num_of_queues * 32 * 8) + 400;
872         const u8 *ptr;
873         ssize_t ret;
874
875         if (!priv->txq) {
876                 IWL_ERR(priv, "txq not ready\n");
877                 return -EAGAIN;
878         }
879         buf = kzalloc(bufsz, GFP_KERNEL);
880         if (!buf) {
881                 IWL_ERR(priv, "Can not allocate buffer\n");
882                 return -ENOMEM;
883         }
884         pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
885         for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
886                 txq = &priv->txq[cnt];
887                 q = &txq->q;
888                 pos += scnprintf(buf + pos, bufsz - pos,
889                                 "q[%d]: read_ptr: %u, write_ptr: %u\n",
890                                 cnt, q->read_ptr, q->write_ptr);
891         }
892         if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) {
893                 ptr = priv->tx_traffic;
894                 pos += scnprintf(buf + pos, bufsz - pos,
895                                 "Tx Traffic idx: %u\n", priv->tx_traffic_idx);
896                 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
897                         for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
898                              entry++,  ofs += 16) {
899                                 pos += scnprintf(buf + pos, bufsz - pos,
900                                                 "0x%.4x ", ofs);
901                                 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
902                                                    buf + pos, bufsz - pos, 0);
903                                 pos += strlen(buf + pos);
904                                 if (bufsz - pos > 0)
905                                         buf[pos++] = '\n';
906                         }
907                 }
908         }
909
910         pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
911         pos += scnprintf(buf + pos, bufsz - pos,
912                         "read: %u, write: %u\n",
913                          rxq->read, rxq->write);
914
915         if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) {
916                 ptr = priv->rx_traffic;
917                 pos += scnprintf(buf + pos, bufsz - pos,
918                                 "Rx Traffic idx: %u\n", priv->rx_traffic_idx);
919                 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
920                         for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
921                              entry++,  ofs += 16) {
922                                 pos += scnprintf(buf + pos, bufsz - pos,
923                                                 "0x%.4x ", ofs);
924                                 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
925                                                    buf + pos, bufsz - pos, 0);
926                                 pos += strlen(buf + pos);
927                                 if (bufsz - pos > 0)
928                                         buf[pos++] = '\n';
929                         }
930                 }
931         }
932
933         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
934         kfree(buf);
935         return ret;
936 }
937
938 static ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
939                                          const char __user *user_buf,
940                                          size_t count, loff_t *ppos)
941 {
942         struct iwl_priv *priv = file->private_data;
943         char buf[8];
944         int buf_size;
945         int traffic_log;
946
947         memset(buf, 0, sizeof(buf));
948         buf_size = min(count, sizeof(buf) -  1);
949         if (copy_from_user(buf, user_buf, buf_size))
950                 return -EFAULT;
951         if (sscanf(buf, "%d", &traffic_log) != 1)
952                 return -EFAULT;
953         if (traffic_log == 0)
954                 iwl_reset_traffic_log(priv);
955
956         return count;
957 }
958
959 static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
960                                                 char __user *user_buf,
961                                                 size_t count, loff_t *ppos) {
962
963         struct iwl_priv *priv = file->private_data;
964         struct iwl_tx_queue *txq;
965         struct iwl_queue *q;
966         char *buf;
967         int pos = 0;
968         int cnt;
969         int ret;
970         const size_t bufsz = sizeof(char) * 64 * priv->cfg->num_of_queues;
971
972         if (!priv->txq) {
973                 IWL_ERR(priv, "txq not ready\n");
974                 return -EAGAIN;
975         }
976         buf = kzalloc(bufsz, GFP_KERNEL);
977         if (!buf)
978                 return -ENOMEM;
979
980         for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
981                 txq = &priv->txq[cnt];
982                 q = &txq->q;
983                 pos += scnprintf(buf + pos, bufsz - pos,
984                                 "hwq %.2d: read=%u write=%u stop=%d"
985                                 " swq_id=%#.2x (ac %d/hwq %d)\n",
986                                 cnt, q->read_ptr, q->write_ptr,
987                                 !!test_bit(cnt, priv->queue_stopped),
988                                 txq->swq_id,
989                                 txq->swq_id & 0x80 ? txq->swq_id & 3 :
990                                 txq->swq_id,
991                                 txq->swq_id & 0x80 ? (txq->swq_id >> 2) &
992                                 0x1f : txq->swq_id);
993                 if (cnt >= 4)
994                         continue;
995                 /* for the ACs, display the stop count too */
996                 pos += scnprintf(buf + pos, bufsz - pos,
997                                 "        stop-count: %d\n",
998                                 atomic_read(&priv->queue_stop_count[cnt]));
999         }
1000         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1001         kfree(buf);
1002         return ret;
1003 }
1004
1005 static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1006                                                 char __user *user_buf,
1007                                                 size_t count, loff_t *ppos) {
1008
1009         struct iwl_priv *priv = file->private_data;
1010         struct iwl_rx_queue *rxq = &priv->rxq;
1011         char buf[256];
1012         int pos = 0;
1013         const size_t bufsz = sizeof(buf);
1014
1015         pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
1016                                                 rxq->read);
1017         pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
1018                                                 rxq->write);
1019         pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
1020                                                 rxq->free_count);
1021         if (rxq->rb_stts) {
1022                 pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
1023                          le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF);
1024         } else {
1025                 pos += scnprintf(buf + pos, bufsz - pos,
1026                                         "closed_rb_num: Not Allocated\n");
1027         }
1028         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1029 }
1030
1031 static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1032                                         char __user *user_buf,
1033                                         size_t count, loff_t *ppos)
1034 {
1035         struct iwl_priv *priv = file->private_data;
1036         return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
1037                         user_buf, count, ppos);
1038 }
1039
1040 static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1041                                         char __user *user_buf,
1042                                         size_t count, loff_t *ppos)
1043 {
1044         struct iwl_priv *priv = file->private_data;
1045         return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
1046                         user_buf, count, ppos);
1047 }
1048
1049 static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1050                                         char __user *user_buf,
1051                                         size_t count, loff_t *ppos)
1052 {
1053         struct iwl_priv *priv = file->private_data;
1054         return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
1055                         user_buf, count, ppos);
1056 }
1057
1058 static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
1059                                         char __user *user_buf,
1060                                         size_t count, loff_t *ppos) {
1061
1062         struct iwl_priv *priv = file->private_data;
1063         int pos = 0;
1064         int cnt = 0;
1065         char *buf;
1066         int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100;
1067         ssize_t ret;
1068         struct iwl_sensitivity_data *data;
1069
1070         data = &priv->sensitivity_data;
1071         buf = kzalloc(bufsz, GFP_KERNEL);
1072         if (!buf) {
1073                 IWL_ERR(priv, "Can not allocate Buffer\n");
1074                 return -ENOMEM;
1075         }
1076
1077         pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
1078                         data->auto_corr_ofdm);
1079         pos += scnprintf(buf + pos, bufsz - pos,
1080                         "auto_corr_ofdm_mrc:\t\t %u\n",
1081                         data->auto_corr_ofdm_mrc);
1082         pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
1083                         data->auto_corr_ofdm_x1);
1084         pos += scnprintf(buf + pos, bufsz - pos,
1085                         "auto_corr_ofdm_mrc_x1:\t\t %u\n",
1086                         data->auto_corr_ofdm_mrc_x1);
1087         pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
1088                         data->auto_corr_cck);
1089         pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
1090                         data->auto_corr_cck_mrc);
1091         pos += scnprintf(buf + pos, bufsz - pos,
1092                         "last_bad_plcp_cnt_ofdm:\t\t %u\n",
1093                         data->last_bad_plcp_cnt_ofdm);
1094         pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
1095                         data->last_fa_cnt_ofdm);
1096         pos += scnprintf(buf + pos, bufsz - pos,
1097                         "last_bad_plcp_cnt_cck:\t\t %u\n",
1098                         data->last_bad_plcp_cnt_cck);
1099         pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
1100                         data->last_fa_cnt_cck);
1101         pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
1102                         data->nrg_curr_state);
1103         pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
1104                         data->nrg_prev_state);
1105         pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
1106         for (cnt = 0; cnt < 10; cnt++) {
1107                 pos += scnprintf(buf + pos, bufsz - pos, " %u",
1108                                 data->nrg_value[cnt]);
1109         }
1110         pos += scnprintf(buf + pos, bufsz - pos, "\n");
1111         pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
1112         for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
1113                 pos += scnprintf(buf + pos, bufsz - pos, " %u",
1114                                 data->nrg_silence_rssi[cnt]);
1115         }
1116         pos += scnprintf(buf + pos, bufsz - pos, "\n");
1117         pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
1118                         data->nrg_silence_ref);
1119         pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
1120                         data->nrg_energy_idx);
1121         pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
1122                         data->nrg_silence_idx);
1123         pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
1124                         data->nrg_th_cck);
1125         pos += scnprintf(buf + pos, bufsz - pos,
1126                         "nrg_auto_corr_silence_diff:\t %u\n",
1127                         data->nrg_auto_corr_silence_diff);
1128         pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
1129                         data->num_in_cck_no_fa);
1130         pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
1131                         data->nrg_th_ofdm);
1132
1133         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1134         kfree(buf);
1135         return ret;
1136 }
1137
1138
1139 static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
1140                                         char __user *user_buf,
1141                                         size_t count, loff_t *ppos) {
1142
1143         struct iwl_priv *priv = file->private_data;
1144         int pos = 0;
1145         int cnt = 0;
1146         char *buf;
1147         int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100;
1148         ssize_t ret;
1149         struct iwl_chain_noise_data *data;
1150
1151         data = &priv->chain_noise_data;
1152         buf = kzalloc(bufsz, GFP_KERNEL);
1153         if (!buf) {
1154                 IWL_ERR(priv, "Can not allocate Buffer\n");
1155                 return -ENOMEM;
1156         }
1157
1158         pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
1159                         data->active_chains);
1160         pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
1161                         data->chain_noise_a);
1162         pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
1163                         data->chain_noise_b);
1164         pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
1165                         data->chain_noise_c);
1166         pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
1167                         data->chain_signal_a);
1168         pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
1169                         data->chain_signal_b);
1170         pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
1171                         data->chain_signal_c);
1172         pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
1173                         data->beacon_count);
1174
1175         pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
1176         for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
1177                 pos += scnprintf(buf + pos, bufsz - pos, " %u",
1178                                 data->disconn_array[cnt]);
1179         }
1180         pos += scnprintf(buf + pos, bufsz - pos, "\n");
1181         pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
1182         for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
1183                 pos += scnprintf(buf + pos, bufsz - pos, " %u",
1184                                 data->delta_gain_code[cnt]);
1185         }
1186         pos += scnprintf(buf + pos, bufsz - pos, "\n");
1187         pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
1188                         data->radio_write);
1189         pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
1190                         data->state);
1191
1192         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1193         kfree(buf);
1194         return ret;
1195 }
1196
1197 static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
1198                                                     char __user *user_buf,
1199                                                     size_t count, loff_t *ppos)
1200 {
1201         struct iwl_priv *priv = file->private_data;
1202         char buf[60];
1203         int pos = 0;
1204         const size_t bufsz = sizeof(buf);
1205         u32 pwrsave_status;
1206
1207         pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) &
1208                         CSR_GP_REG_POWER_SAVE_STATUS_MSK;
1209
1210         pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
1211         pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
1212                 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1213                 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1214                 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1215                 "error");
1216
1217         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1218 }
1219
1220 static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
1221                                          const char __user *user_buf,
1222                                          size_t count, loff_t *ppos)
1223 {
1224         struct iwl_priv *priv = file->private_data;
1225         char buf[8];
1226         int buf_size;
1227         int clear;
1228
1229         memset(buf, 0, sizeof(buf));
1230         buf_size = min(count, sizeof(buf) -  1);
1231         if (copy_from_user(buf, user_buf, buf_size))
1232                 return -EFAULT;
1233         if (sscanf(buf, "%d", &clear) != 1)
1234                 return -EFAULT;
1235
1236         /* make request to uCode to retrieve statistics information */
1237         mutex_lock(&priv->mutex);
1238         iwl_send_statistics_request(priv, CMD_SYNC, true);
1239         mutex_unlock(&priv->mutex);
1240
1241         return count;
1242 }
1243
1244 static ssize_t iwl_dbgfs_csr_write(struct file *file,
1245                                          const char __user *user_buf,
1246                                          size_t count, loff_t *ppos)
1247 {
1248         struct iwl_priv *priv = file->private_data;
1249         char buf[8];
1250         int buf_size;
1251         int csr;
1252
1253         memset(buf, 0, sizeof(buf));
1254         buf_size = min(count, sizeof(buf) -  1);
1255         if (copy_from_user(buf, user_buf, buf_size))
1256                 return -EFAULT;
1257         if (sscanf(buf, "%d", &csr) != 1)
1258                 return -EFAULT;
1259
1260         if (priv->cfg->ops->lib->dump_csr)
1261                 priv->cfg->ops->lib->dump_csr(priv);
1262
1263         return count;
1264 }
1265
1266 static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
1267                                         char __user *user_buf,
1268                                         size_t count, loff_t *ppos) {
1269
1270         struct iwl_priv *priv = file->private_data;
1271         int pos = 0;
1272         char buf[128];
1273         const size_t bufsz = sizeof(buf);
1274
1275         pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
1276                         priv->event_log.ucode_trace ? "On" : "Off");
1277         pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n",
1278                         priv->event_log.non_wraps_count);
1279         pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n",
1280                         priv->event_log.wraps_once_count);
1281         pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
1282                         priv->event_log.wraps_more_count);
1283
1284         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1285 }
1286
1287 static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
1288                                          const char __user *user_buf,
1289                                          size_t count, loff_t *ppos)
1290 {
1291         struct iwl_priv *priv = file->private_data;
1292         char buf[8];
1293         int buf_size;
1294         int trace;
1295
1296         memset(buf, 0, sizeof(buf));
1297         buf_size = min(count, sizeof(buf) -  1);
1298         if (copy_from_user(buf, user_buf, buf_size))
1299                 return -EFAULT;
1300         if (sscanf(buf, "%d", &trace) != 1)
1301                 return -EFAULT;
1302
1303         if (trace) {
1304                 priv->event_log.ucode_trace = true;
1305                 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
1306                 mod_timer(&priv->ucode_trace,
1307                         jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
1308         } else {
1309                 priv->event_log.ucode_trace = false;
1310                 del_timer_sync(&priv->ucode_trace);
1311         }
1312
1313         return count;
1314 }
1315
1316 static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file,
1317                                          char __user *user_buf,
1318                                          size_t count, loff_t *ppos) {
1319
1320         struct iwl_priv *priv = file->private_data;
1321         int len = 0;
1322         char buf[20];
1323
1324         len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags));
1325         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1326 }
1327
1328 static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file,
1329                                                 char __user *user_buf,
1330                                                 size_t count, loff_t *ppos) {
1331
1332         struct iwl_priv *priv = file->private_data;
1333         int len = 0;
1334         char buf[20];
1335
1336         len = sprintf(buf, "0x%04X\n",
1337                       le32_to_cpu(priv->active_rxon.filter_flags));
1338         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1339 }
1340
1341 static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
1342                                          char __user *user_buf,
1343                                          size_t count, loff_t *ppos)
1344 {
1345         struct iwl_priv *priv = file->private_data;
1346         char *buf;
1347         int pos = 0;
1348         ssize_t ret = -EFAULT;
1349
1350         if (priv->cfg->ops->lib->dump_fh) {
1351                 ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true);
1352                 if (buf) {
1353                         ret = simple_read_from_buffer(user_buf,
1354                                                       count, ppos, buf, pos);
1355                         kfree(buf);
1356                 }
1357         }
1358
1359         return ret;
1360 }
1361
1362 static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file,
1363                                         char __user *user_buf,
1364                                         size_t count, loff_t *ppos) {
1365
1366         struct iwl_priv *priv = file->private_data;
1367         int pos = 0;
1368         char buf[12];
1369         const size_t bufsz = sizeof(buf);
1370
1371         pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
1372                         priv->missed_beacon_threshold);
1373
1374         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1375 }
1376
1377 static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file,
1378                                          const char __user *user_buf,
1379                                          size_t count, loff_t *ppos)
1380 {
1381         struct iwl_priv *priv = file->private_data;
1382         char buf[8];
1383         int buf_size;
1384         int missed;
1385
1386         memset(buf, 0, sizeof(buf));
1387         buf_size = min(count, sizeof(buf) -  1);
1388         if (copy_from_user(buf, user_buf, buf_size))
1389                 return -EFAULT;
1390         if (sscanf(buf, "%d", &missed) != 1)
1391                 return -EINVAL;
1392
1393         if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
1394             missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
1395                 priv->missed_beacon_threshold =
1396                         IWL_MISSED_BEACON_THRESHOLD_DEF;
1397         else
1398                 priv->missed_beacon_threshold = missed;
1399
1400         return count;
1401 }
1402
1403 static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file,
1404                                         char __user *user_buf,
1405                                         size_t count, loff_t *ppos) {
1406
1407         struct iwl_priv *priv = file->private_data;
1408         int pos = 0;
1409         char buf[12];
1410         const size_t bufsz = sizeof(buf);
1411
1412         pos += scnprintf(buf + pos, bufsz - pos, "%u\n",
1413                         priv->cfg->plcp_delta_threshold);
1414
1415         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1416 }
1417
1418 static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file,
1419                                         const char __user *user_buf,
1420                                         size_t count, loff_t *ppos) {
1421
1422         struct iwl_priv *priv = file->private_data;
1423         char buf[8];
1424         int buf_size;
1425         int plcp;
1426
1427         memset(buf, 0, sizeof(buf));
1428         buf_size = min(count, sizeof(buf) -  1);
1429         if (copy_from_user(buf, user_buf, buf_size))
1430                 return -EFAULT;
1431         if (sscanf(buf, "%d", &plcp) != 1)
1432                 return -EINVAL;
1433         if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) ||
1434                 (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX))
1435                 priv->cfg->plcp_delta_threshold =
1436                         IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE;
1437         else
1438                 priv->cfg->plcp_delta_threshold = plcp;
1439         return count;
1440 }
1441
1442 static ssize_t iwl_dbgfs_force_reset_read(struct file *file,
1443                                         char __user *user_buf,
1444                                         size_t count, loff_t *ppos) {
1445
1446         struct iwl_priv *priv = file->private_data;
1447         int i, pos = 0;
1448         char buf[300];
1449         const size_t bufsz = sizeof(buf);
1450         struct iwl_force_reset *force_reset;
1451
1452         for (i = 0; i < IWL_MAX_FORCE_RESET; i++) {
1453                 force_reset = &priv->force_reset[i];
1454                 pos += scnprintf(buf + pos, bufsz - pos,
1455                                 "Force reset method %d\n", i);
1456                 pos += scnprintf(buf + pos, bufsz - pos,
1457                                 "\tnumber of reset request: %d\n",
1458                                 force_reset->reset_request_count);
1459                 pos += scnprintf(buf + pos, bufsz - pos,
1460                                 "\tnumber of reset request success: %d\n",
1461                                 force_reset->reset_success_count);
1462                 pos += scnprintf(buf + pos, bufsz - pos,
1463                                 "\tnumber of reset request reject: %d\n",
1464                                 force_reset->reset_reject_count);
1465                 pos += scnprintf(buf + pos, bufsz - pos,
1466                                 "\treset duration: %lu\n",
1467                                 force_reset->reset_duration);
1468         }
1469         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1470 }
1471
1472 static ssize_t iwl_dbgfs_force_reset_write(struct file *file,
1473                                         const char __user *user_buf,
1474                                         size_t count, loff_t *ppos) {
1475
1476         struct iwl_priv *priv = file->private_data;
1477         char buf[8];
1478         int buf_size;
1479         int reset, ret;
1480
1481         memset(buf, 0, sizeof(buf));
1482         buf_size = min(count, sizeof(buf) -  1);
1483         if (copy_from_user(buf, user_buf, buf_size))
1484                 return -EFAULT;
1485         if (sscanf(buf, "%d", &reset) != 1)
1486                 return -EINVAL;
1487         switch (reset) {
1488         case IWL_RF_RESET:
1489         case IWL_FW_RESET:
1490                 ret = iwl_force_reset(priv, reset, true);
1491                 break;
1492         default:
1493                 return -EINVAL;
1494         }
1495         return ret ? ret : count;
1496 }
1497
1498 static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
1499                                         const char __user *user_buf,
1500                                         size_t count, loff_t *ppos) {
1501
1502         struct iwl_priv *priv = file->private_data;
1503         char buf[8];
1504         int buf_size;
1505         int flush;
1506
1507         memset(buf, 0, sizeof(buf));
1508         buf_size = min(count, sizeof(buf) -  1);
1509         if (copy_from_user(buf, user_buf, buf_size))
1510                 return -EFAULT;
1511         if (sscanf(buf, "%d", &flush) != 1)
1512                 return -EINVAL;
1513
1514         if (iwl_is_rfkill(priv))
1515                 return -EFAULT;
1516
1517         priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL);
1518
1519         return count;
1520 }
1521
1522 static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
1523                                         char __user *user_buf,
1524                                         size_t count, loff_t *ppos)
1525 {
1526         struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1527
1528         return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file,
1529                         user_buf, count, ppos);
1530 }
1531
1532 DEBUGFS_READ_FILE_OPS(rx_statistics);
1533 DEBUGFS_READ_FILE_OPS(tx_statistics);
1534 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
1535 DEBUGFS_READ_FILE_OPS(rx_queue);
1536 DEBUGFS_READ_FILE_OPS(tx_queue);
1537 DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1538 DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1539 DEBUGFS_READ_FILE_OPS(ucode_general_stats);
1540 DEBUGFS_READ_FILE_OPS(sensitivity);
1541 DEBUGFS_READ_FILE_OPS(chain_noise);
1542 DEBUGFS_READ_FILE_OPS(power_save_status);
1543 DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
1544 DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
1545 DEBUGFS_WRITE_FILE_OPS(csr);
1546 DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
1547 DEBUGFS_READ_FILE_OPS(fh_reg);
1548 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
1549 DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
1550 DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1551 DEBUGFS_READ_FILE_OPS(rxon_flags);
1552 DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
1553 DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
1554 DEBUGFS_READ_FILE_OPS(ucode_bt_stats);
1555
1556 /*
1557  * Create the debugfs files and directories
1558  *
1559  */
1560 int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1561 {
1562         struct dentry *phyd = priv->hw->wiphy->debugfsdir;
1563         struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1564
1565         dir_drv = debugfs_create_dir(name, phyd);
1566         if (!dir_drv)
1567                 return -ENOMEM;
1568
1569         priv->debugfs_dir = dir_drv;
1570
1571         dir_data = debugfs_create_dir("data", dir_drv);
1572         if (!dir_data)
1573                 goto err;
1574         dir_rf = debugfs_create_dir("rf", dir_drv);
1575         if (!dir_rf)
1576                 goto err;
1577         dir_debug = debugfs_create_dir("debug", dir_drv);
1578         if (!dir_debug)
1579                 goto err;
1580
1581         DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1582         DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
1583         DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR);
1584         DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1585         DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1586         DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1587         DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1588         DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1589         DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
1590         if (!priv->cfg->broken_powersave) {
1591                 DEBUGFS_ADD_FILE(sleep_level_override, dir_data,
1592                                  S_IWUSR | S_IRUSR);
1593                 DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
1594         }
1595         DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
1596         DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
1597         DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
1598         DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
1599         DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
1600         DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
1601         DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
1602         DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
1603         DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
1604         DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
1605         DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR);
1606         DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
1607         DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
1608         DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
1609         DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
1610         DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1611         DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1612         DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
1613         if (priv->cfg->ops->lib->dev_txfifo_flush)
1614                 DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
1615
1616         if (priv->cfg->sensitivity_calib_by_driver)
1617                 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
1618         if (priv->cfg->chain_noise_calib_by_driver)
1619                 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
1620         if (priv->cfg->ucode_tracing)
1621                 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
1622         if (priv->cfg->bt_statistics)
1623                 DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
1624         DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
1625         DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
1626         if (priv->cfg->sensitivity_calib_by_driver)
1627                 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
1628                                  &priv->disable_sens_cal);
1629         if (priv->cfg->chain_noise_calib_by_driver)
1630                 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
1631                                  &priv->disable_chain_noise_cal);
1632         if (priv->cfg->tx_power_by_driver)
1633                 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
1634                                 &priv->disable_tx_power_cal);
1635         return 0;
1636
1637 err:
1638         IWL_ERR(priv, "Can't create the debugfs directory\n");
1639         iwl_dbgfs_unregister(priv);
1640         return -ENOMEM;
1641 }
1642 EXPORT_SYMBOL(iwl_dbgfs_register);
1643
1644 /**
1645  * Remove the debugfs files and directories
1646  *
1647  */
1648 void iwl_dbgfs_unregister(struct iwl_priv *priv)
1649 {
1650         if (!priv->debugfs_dir)
1651                 return;
1652
1653         debugfs_remove_recursive(priv->debugfs_dir);
1654         priv->debugfs_dir = NULL;
1655 }
1656 EXPORT_SYMBOL(iwl_dbgfs_unregister);
1657
1658
1659