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