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