1 /******************************************************************************
5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
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.
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.
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,
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
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 <linux/export.h>
30 #include <net/mac80211.h>
34 #include "iwl-debug.h"
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_legacy_dbgfs_##name##_ops)) \
45 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
46 struct dentry *__tmp; \
47 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
49 if (IS_ERR(__tmp) || !__tmp) \
53 #define DEBUGFS_ADD_X32(name, parent, ptr) do { \
54 struct dentry *__tmp; \
55 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
57 if (IS_ERR(__tmp) || !__tmp) \
62 #define DEBUGFS_READ_FUNC(name) \
63 static ssize_t iwl_legacy_dbgfs_##name##_read(struct file *file, \
64 char __user *user_buf, \
65 size_t count, loff_t *ppos);
67 #define DEBUGFS_WRITE_FUNC(name) \
68 static ssize_t iwl_legacy_dbgfs_##name##_write(struct file *file, \
69 const char __user *user_buf, \
70 size_t count, loff_t *ppos);
74 iwl_legacy_dbgfs_open_file_generic(struct inode *inode, struct file *file)
76 file->private_data = inode->i_private;
80 #define DEBUGFS_READ_FILE_OPS(name) \
81 DEBUGFS_READ_FUNC(name); \
82 static const struct file_operations iwl_legacy_dbgfs_##name##_ops = { \
83 .read = iwl_legacy_dbgfs_##name##_read, \
84 .open = iwl_legacy_dbgfs_open_file_generic, \
85 .llseek = generic_file_llseek, \
88 #define DEBUGFS_WRITE_FILE_OPS(name) \
89 DEBUGFS_WRITE_FUNC(name); \
90 static const struct file_operations iwl_legacy_dbgfs_##name##_ops = { \
91 .write = iwl_legacy_dbgfs_##name##_write, \
92 .open = iwl_legacy_dbgfs_open_file_generic, \
93 .llseek = generic_file_llseek, \
96 #define DEBUGFS_READ_WRITE_FILE_OPS(name) \
97 DEBUGFS_READ_FUNC(name); \
98 DEBUGFS_WRITE_FUNC(name); \
99 static const struct file_operations iwl_legacy_dbgfs_##name##_ops = { \
100 .write = iwl_legacy_dbgfs_##name##_write, \
101 .read = iwl_legacy_dbgfs_##name##_read, \
102 .open = iwl_legacy_dbgfs_open_file_generic, \
103 .llseek = generic_file_llseek, \
106 static ssize_t iwl_legacy_dbgfs_tx_statistics_read(struct file *file,
107 char __user *user_buf,
108 size_t count, loff_t *ppos) {
110 struct iwl_priv *priv = file->private_data;
116 const size_t bufsz = 100 +
117 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
118 buf = kzalloc(bufsz, GFP_KERNEL);
121 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
122 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
123 pos += scnprintf(buf + pos, bufsz - pos,
125 iwl_legacy_get_mgmt_string(cnt),
126 priv->tx_stats.mgmt[cnt]);
128 pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
129 for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
130 pos += scnprintf(buf + pos, bufsz - pos,
132 iwl_legacy_get_ctrl_string(cnt),
133 priv->tx_stats.ctrl[cnt]);
135 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
136 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
137 priv->tx_stats.data_cnt);
138 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
139 priv->tx_stats.data_bytes);
140 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
146 iwl_legacy_dbgfs_clear_traffic_statistics_write(struct file *file,
147 const char __user *user_buf,
148 size_t count, loff_t *ppos)
150 struct iwl_priv *priv = file->private_data;
155 memset(buf, 0, sizeof(buf));
156 buf_size = min(count, sizeof(buf) - 1);
157 if (copy_from_user(buf, user_buf, buf_size))
159 if (sscanf(buf, "%x", &clear_flag) != 1)
161 iwl_legacy_clear_traffic_stats(priv);
166 static ssize_t iwl_legacy_dbgfs_rx_statistics_read(struct file *file,
167 char __user *user_buf,
168 size_t count, loff_t *ppos) {
170 struct iwl_priv *priv = file->private_data;
175 const size_t bufsz = 100 +
176 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
177 buf = kzalloc(bufsz, GFP_KERNEL);
181 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
182 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
183 pos += scnprintf(buf + pos, bufsz - pos,
185 iwl_legacy_get_mgmt_string(cnt),
186 priv->rx_stats.mgmt[cnt]);
188 pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
189 for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
190 pos += scnprintf(buf + pos, bufsz - pos,
192 iwl_legacy_get_ctrl_string(cnt),
193 priv->rx_stats.ctrl[cnt]);
195 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
196 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
197 priv->rx_stats.data_cnt);
198 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
199 priv->rx_stats.data_bytes);
201 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
206 #define BYTE1_MASK 0x000000ff;
207 #define BYTE2_MASK 0x0000ffff;
208 #define BYTE3_MASK 0x00ffffff;
209 static ssize_t iwl_legacy_dbgfs_sram_read(struct file *file,
210 char __user *user_buf,
211 size_t count, loff_t *ppos)
218 struct iwl_priv *priv = file->private_data;
221 /* default is to dump the entire data segment */
222 if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
223 priv->dbgfs_sram_offset = 0x800000;
224 if (priv->ucode_type == UCODE_INIT)
225 priv->dbgfs_sram_len = priv->ucode_init_data.len;
227 priv->dbgfs_sram_len = priv->ucode_data.len;
229 bufsz = 30 + priv->dbgfs_sram_len * sizeof(char) * 10;
230 buf = kmalloc(bufsz, GFP_KERNEL);
233 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
234 priv->dbgfs_sram_len);
235 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
236 priv->dbgfs_sram_offset);
237 for (i = priv->dbgfs_sram_len; i > 0; i -= 4) {
238 val = iwl_legacy_read_targ_mem(priv, priv->dbgfs_sram_offset + \
239 priv->dbgfs_sram_len - i);
254 pos += scnprintf(buf + pos, bufsz - pos, "\n");
255 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
257 pos += scnprintf(buf + pos, bufsz - pos, "\n");
259 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
264 static ssize_t iwl_legacy_dbgfs_sram_write(struct file *file,
265 const char __user *user_buf,
266 size_t count, loff_t *ppos)
268 struct iwl_priv *priv = file->private_data;
273 memset(buf, 0, sizeof(buf));
274 buf_size = min(count, sizeof(buf) - 1);
275 if (copy_from_user(buf, user_buf, buf_size))
278 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
279 priv->dbgfs_sram_offset = offset;
280 priv->dbgfs_sram_len = len;
282 priv->dbgfs_sram_offset = 0;
283 priv->dbgfs_sram_len = 0;
290 iwl_legacy_dbgfs_stations_read(struct file *file, char __user *user_buf,
291 size_t count, loff_t *ppos)
293 struct iwl_priv *priv = file->private_data;
294 struct iwl_station_entry *station;
295 int max_sta = priv->hw_params.max_stations;
299 /* Add 30 for initial string */
300 const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations);
302 buf = kmalloc(bufsz, GFP_KERNEL);
306 pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
309 for (i = 0; i < max_sta; i++) {
310 station = &priv->stations[i];
313 pos += scnprintf(buf + pos, bufsz - pos,
314 "station %d - addr: %pM, flags: %#x\n",
315 i, station->sta.sta.addr,
316 station->sta.station_flags_msk);
317 pos += scnprintf(buf + pos, bufsz - pos,
318 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
319 pos += scnprintf(buf + pos, bufsz - pos,
320 "start_idx\tbitmap\t\t\trate_n_flags\n");
322 for (j = 0; j < MAX_TID_COUNT; j++) {
323 pos += scnprintf(buf + pos, bufsz - pos,
324 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
325 j, station->tid[j].seq_number,
326 station->tid[j].agg.txq_id,
327 station->tid[j].agg.frame_count,
328 station->tid[j].tfds_in_queue,
329 station->tid[j].agg.start_idx,
330 station->tid[j].agg.bitmap,
331 station->tid[j].agg.rate_n_flags);
333 if (station->tid[j].agg.wait_for_ba)
334 pos += scnprintf(buf + pos, bufsz - pos,
336 pos += scnprintf(buf + pos, bufsz - pos, "\n");
339 pos += scnprintf(buf + pos, bufsz - pos, "\n");
342 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
347 static ssize_t iwl_legacy_dbgfs_nvm_read(struct file *file,
348 char __user *user_buf,
353 struct iwl_priv *priv = file->private_data;
354 int pos = 0, ofs = 0, buf_size = 0;
358 size_t eeprom_len = priv->cfg->base_params->eeprom_size;
359 buf_size = 4 * eeprom_len + 256;
361 if (eeprom_len % 16) {
362 IWL_ERR(priv, "NVM size is not multiple of 16.\n");
368 IWL_ERR(priv, "Invalid EEPROM memory\n");
372 /* 4 characters for byte 0xYY */
373 buf = kzalloc(buf_size, GFP_KERNEL);
375 IWL_ERR(priv, "Can not allocate Buffer\n");
378 eeprom_ver = iwl_legacy_eeprom_query16(priv, EEPROM_VERSION);
379 pos += scnprintf(buf + pos, buf_size - pos, "EEPROM "
380 "version: 0x%x\n", eeprom_ver);
381 for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
382 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
383 hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
385 pos += strlen(buf + pos);
386 if (buf_size - pos > 0)
390 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
396 iwl_legacy_dbgfs_channels_read(struct file *file, char __user *user_buf,
397 size_t count, loff_t *ppos)
399 struct iwl_priv *priv = file->private_data;
400 struct ieee80211_channel *channels = NULL;
401 const struct ieee80211_supported_band *supp_band = NULL;
402 int pos = 0, i, bufsz = PAGE_SIZE;
406 if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
409 buf = kzalloc(bufsz, GFP_KERNEL);
411 IWL_ERR(priv, "Can not allocate Buffer\n");
415 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
417 channels = supp_band->channels;
419 pos += scnprintf(buf + pos, bufsz - pos,
420 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
421 supp_band->n_channels);
423 for (i = 0; i < supp_band->n_channels; i++)
424 pos += scnprintf(buf + pos, bufsz - pos,
425 "%d: %ddBm: BSS%s%s, %s.\n",
426 channels[i].hw_value,
427 channels[i].max_power,
428 channels[i].flags & IEEE80211_CHAN_RADAR ?
429 " (IEEE 802.11h required)" : "",
430 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
431 || (channels[i].flags &
432 IEEE80211_CHAN_RADAR)) ? "" :
435 IEEE80211_CHAN_PASSIVE_SCAN ?
436 "passive only" : "active/passive");
438 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
440 channels = supp_band->channels;
442 pos += scnprintf(buf + pos, bufsz - pos,
443 "Displaying %d channels in 5.2GHz band (802.11a)\n",
444 supp_band->n_channels);
446 for (i = 0; i < supp_band->n_channels; i++)
447 pos += scnprintf(buf + pos, bufsz - pos,
448 "%d: %ddBm: BSS%s%s, %s.\n",
449 channels[i].hw_value,
450 channels[i].max_power,
451 channels[i].flags & IEEE80211_CHAN_RADAR ?
452 " (IEEE 802.11h required)" : "",
453 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
454 || (channels[i].flags &
455 IEEE80211_CHAN_RADAR)) ? "" :
458 IEEE80211_CHAN_PASSIVE_SCAN ?
459 "passive only" : "active/passive");
461 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
466 static ssize_t iwl_legacy_dbgfs_status_read(struct file *file,
467 char __user *user_buf,
468 size_t count, loff_t *ppos) {
470 struct iwl_priv *priv = file->private_data;
473 const size_t bufsz = sizeof(buf);
475 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
476 test_bit(STATUS_HCMD_ACTIVE, &priv->status));
477 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
478 test_bit(STATUS_INT_ENABLED, &priv->status));
479 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
480 test_bit(STATUS_RF_KILL_HW, &priv->status));
481 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n",
482 test_bit(STATUS_CT_KILL, &priv->status));
483 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
484 test_bit(STATUS_INIT, &priv->status));
485 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
486 test_bit(STATUS_ALIVE, &priv->status));
487 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
488 test_bit(STATUS_READY, &priv->status));
489 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
490 test_bit(STATUS_TEMPERATURE, &priv->status));
491 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
492 test_bit(STATUS_GEO_CONFIGURED, &priv->status));
493 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
494 test_bit(STATUS_EXIT_PENDING, &priv->status));
495 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
496 test_bit(STATUS_STATISTICS, &priv->status));
497 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
498 test_bit(STATUS_SCANNING, &priv->status));
499 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
500 test_bit(STATUS_SCAN_ABORTING, &priv->status));
501 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
502 test_bit(STATUS_SCAN_HW, &priv->status));
503 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
504 test_bit(STATUS_POWER_PMI, &priv->status));
505 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
506 test_bit(STATUS_FW_ERROR, &priv->status));
507 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
510 static ssize_t iwl_legacy_dbgfs_interrupt_read(struct file *file,
511 char __user *user_buf,
512 size_t count, loff_t *ppos) {
514 struct iwl_priv *priv = file->private_data;
518 int bufsz = 24 * 64; /* 24 items * 64 char per item */
521 buf = kzalloc(bufsz, GFP_KERNEL);
523 IWL_ERR(priv, "Can not allocate Buffer\n");
527 pos += scnprintf(buf + pos, bufsz - pos,
528 "Interrupt Statistics Report:\n");
530 pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
532 pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
534 if (priv->isr_stats.sw || priv->isr_stats.hw) {
535 pos += scnprintf(buf + pos, bufsz - pos,
536 "\tLast Restarting Code: 0x%X\n",
537 priv->isr_stats.err_code);
539 #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
540 pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
541 priv->isr_stats.sch);
542 pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
543 priv->isr_stats.alive);
545 pos += scnprintf(buf + pos, bufsz - pos,
546 "HW RF KILL switch toggled:\t %u\n",
547 priv->isr_stats.rfkill);
549 pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
550 priv->isr_stats.ctkill);
552 pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
553 priv->isr_stats.wakeup);
555 pos += scnprintf(buf + pos, bufsz - pos,
556 "Rx command responses:\t\t %u\n",
558 for (cnt = 0; cnt < REPLY_MAX; cnt++) {
559 if (priv->isr_stats.rx_handlers[cnt] > 0)
560 pos += scnprintf(buf + pos, bufsz - pos,
561 "\tRx handler[%36s]:\t\t %u\n",
562 iwl_legacy_get_cmd_string(cnt),
563 priv->isr_stats.rx_handlers[cnt]);
566 pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
569 pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
570 priv->isr_stats.unhandled);
572 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
577 static ssize_t iwl_legacy_dbgfs_interrupt_write(struct file *file,
578 const char __user *user_buf,
579 size_t count, loff_t *ppos)
581 struct iwl_priv *priv = file->private_data;
586 memset(buf, 0, sizeof(buf));
587 buf_size = min(count, sizeof(buf) - 1);
588 if (copy_from_user(buf, user_buf, buf_size))
590 if (sscanf(buf, "%x", &reset_flag) != 1)
593 iwl_legacy_clear_isr_stats(priv);
599 iwl_legacy_dbgfs_qos_read(struct file *file, char __user *user_buf,
600 size_t count, loff_t *ppos)
602 struct iwl_priv *priv = file->private_data;
603 struct iwl_rxon_context *ctx;
605 char buf[256 * NUM_IWL_RXON_CTX];
606 const size_t bufsz = sizeof(buf);
608 for_each_context(priv, ctx) {
609 pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n",
611 for (i = 0; i < AC_NUM; i++) {
612 pos += scnprintf(buf + pos, bufsz - pos,
613 "\tcw_min\tcw_max\taifsn\ttxop\n");
614 pos += scnprintf(buf + pos, bufsz - pos,
615 "AC[%d]\t%u\t%u\t%u\t%u\n", i,
616 ctx->qos_data.def_qos_parm.ac[i].cw_min,
617 ctx->qos_data.def_qos_parm.ac[i].cw_max,
618 ctx->qos_data.def_qos_parm.ac[i].aifsn,
619 ctx->qos_data.def_qos_parm.ac[i].edca_txop);
621 pos += scnprintf(buf + pos, bufsz - pos, "\n");
623 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
626 static ssize_t iwl_legacy_dbgfs_disable_ht40_write(struct file *file,
627 const char __user *user_buf,
628 size_t count, loff_t *ppos)
630 struct iwl_priv *priv = file->private_data;
635 memset(buf, 0, sizeof(buf));
636 buf_size = min(count, sizeof(buf) - 1);
637 if (copy_from_user(buf, user_buf, buf_size))
639 if (sscanf(buf, "%d", &ht40) != 1)
641 if (!iwl_legacy_is_any_associated(priv))
642 priv->disable_ht40 = ht40 ? true : false;
644 IWL_ERR(priv, "Sta associated with AP - "
645 "Change to 40MHz channel support is not allowed\n");
652 static ssize_t iwl_legacy_dbgfs_disable_ht40_read(struct file *file,
653 char __user *user_buf,
654 size_t count, loff_t *ppos)
656 struct iwl_priv *priv = file->private_data;
659 const size_t bufsz = sizeof(buf);
661 pos += scnprintf(buf + pos, bufsz - pos,
662 "11n 40MHz Mode: %s\n",
663 priv->disable_ht40 ? "Disabled" : "Enabled");
664 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
667 DEBUGFS_READ_WRITE_FILE_OPS(sram);
668 DEBUGFS_READ_FILE_OPS(nvm);
669 DEBUGFS_READ_FILE_OPS(stations);
670 DEBUGFS_READ_FILE_OPS(channels);
671 DEBUGFS_READ_FILE_OPS(status);
672 DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
673 DEBUGFS_READ_FILE_OPS(qos);
674 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
676 static ssize_t iwl_legacy_dbgfs_traffic_log_read(struct file *file,
677 char __user *user_buf,
678 size_t count, loff_t *ppos)
680 struct iwl_priv *priv = file->private_data;
681 int pos = 0, ofs = 0;
683 struct iwl_tx_queue *txq;
685 struct iwl_rx_queue *rxq = &priv->rxq;
687 int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
688 (priv->cfg->base_params->num_of_queues * 32 * 8) + 400;
693 IWL_ERR(priv, "txq not ready\n");
696 buf = kzalloc(bufsz, GFP_KERNEL);
698 IWL_ERR(priv, "Can not allocate buffer\n");
701 pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
702 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
703 txq = &priv->txq[cnt];
705 pos += scnprintf(buf + pos, bufsz - pos,
706 "q[%d]: read_ptr: %u, write_ptr: %u\n",
707 cnt, q->read_ptr, q->write_ptr);
709 if (priv->tx_traffic && (iwlegacy_debug_level & IWL_DL_TX)) {
710 ptr = priv->tx_traffic;
711 pos += scnprintf(buf + pos, bufsz - pos,
712 "Tx Traffic idx: %u\n", priv->tx_traffic_idx);
713 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
714 for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
715 entry++, ofs += 16) {
716 pos += scnprintf(buf + pos, bufsz - pos,
718 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
719 buf + pos, bufsz - pos, 0);
720 pos += strlen(buf + pos);
727 pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
728 pos += scnprintf(buf + pos, bufsz - pos,
729 "read: %u, write: %u\n",
730 rxq->read, rxq->write);
732 if (priv->rx_traffic && (iwlegacy_debug_level & IWL_DL_RX)) {
733 ptr = priv->rx_traffic;
734 pos += scnprintf(buf + pos, bufsz - pos,
735 "Rx Traffic idx: %u\n", priv->rx_traffic_idx);
736 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
737 for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
738 entry++, ofs += 16) {
739 pos += scnprintf(buf + pos, bufsz - pos,
741 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
742 buf + pos, bufsz - pos, 0);
743 pos += strlen(buf + pos);
750 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
755 static ssize_t iwl_legacy_dbgfs_traffic_log_write(struct file *file,
756 const char __user *user_buf,
757 size_t count, loff_t *ppos)
759 struct iwl_priv *priv = file->private_data;
764 memset(buf, 0, sizeof(buf));
765 buf_size = min(count, sizeof(buf) - 1);
766 if (copy_from_user(buf, user_buf, buf_size))
768 if (sscanf(buf, "%d", &traffic_log) != 1)
770 if (traffic_log == 0)
771 iwl_legacy_reset_traffic_log(priv);
776 static ssize_t iwl_legacy_dbgfs_tx_queue_read(struct file *file,
777 char __user *user_buf,
778 size_t count, loff_t *ppos) {
780 struct iwl_priv *priv = file->private_data;
781 struct iwl_tx_queue *txq;
787 const size_t bufsz = sizeof(char) * 64 *
788 priv->cfg->base_params->num_of_queues;
791 IWL_ERR(priv, "txq not ready\n");
794 buf = kzalloc(bufsz, GFP_KERNEL);
798 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
799 txq = &priv->txq[cnt];
801 pos += scnprintf(buf + pos, bufsz - pos,
802 "hwq %.2d: read=%u write=%u stop=%d"
803 " swq_id=%#.2x (ac %d/hwq %d)\n",
804 cnt, q->read_ptr, q->write_ptr,
805 !!test_bit(cnt, priv->queue_stopped),
806 txq->swq_id, txq->swq_id & 3,
807 (txq->swq_id >> 2) & 0x1f);
810 /* for the ACs, display the stop count too */
811 pos += scnprintf(buf + pos, bufsz - pos,
813 atomic_read(&priv->queue_stop_count[cnt]));
815 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
820 static ssize_t iwl_legacy_dbgfs_rx_queue_read(struct file *file,
821 char __user *user_buf,
822 size_t count, loff_t *ppos) {
824 struct iwl_priv *priv = file->private_data;
825 struct iwl_rx_queue *rxq = &priv->rxq;
828 const size_t bufsz = sizeof(buf);
830 pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
832 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
834 pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
837 pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
838 le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF);
840 pos += scnprintf(buf + pos, bufsz - pos,
841 "closed_rb_num: Not Allocated\n");
843 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
846 static ssize_t iwl_legacy_dbgfs_ucode_rx_stats_read(struct file *file,
847 char __user *user_buf,
848 size_t count, loff_t *ppos)
850 struct iwl_priv *priv = file->private_data;
851 return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
852 user_buf, count, ppos);
855 static ssize_t iwl_legacy_dbgfs_ucode_tx_stats_read(struct file *file,
856 char __user *user_buf,
857 size_t count, loff_t *ppos)
859 struct iwl_priv *priv = file->private_data;
860 return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
861 user_buf, count, ppos);
864 static ssize_t iwl_legacy_dbgfs_ucode_general_stats_read(struct file *file,
865 char __user *user_buf,
866 size_t count, loff_t *ppos)
868 struct iwl_priv *priv = file->private_data;
869 return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
870 user_buf, count, ppos);
873 static ssize_t iwl_legacy_dbgfs_sensitivity_read(struct file *file,
874 char __user *user_buf,
875 size_t count, loff_t *ppos) {
877 struct iwl_priv *priv = file->private_data;
881 int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100;
883 struct iwl_sensitivity_data *data;
885 data = &priv->sensitivity_data;
886 buf = kzalloc(bufsz, GFP_KERNEL);
888 IWL_ERR(priv, "Can not allocate Buffer\n");
892 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
893 data->auto_corr_ofdm);
894 pos += scnprintf(buf + pos, bufsz - pos,
895 "auto_corr_ofdm_mrc:\t\t %u\n",
896 data->auto_corr_ofdm_mrc);
897 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
898 data->auto_corr_ofdm_x1);
899 pos += scnprintf(buf + pos, bufsz - pos,
900 "auto_corr_ofdm_mrc_x1:\t\t %u\n",
901 data->auto_corr_ofdm_mrc_x1);
902 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
903 data->auto_corr_cck);
904 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
905 data->auto_corr_cck_mrc);
906 pos += scnprintf(buf + pos, bufsz - pos,
907 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
908 data->last_bad_plcp_cnt_ofdm);
909 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
910 data->last_fa_cnt_ofdm);
911 pos += scnprintf(buf + pos, bufsz - pos,
912 "last_bad_plcp_cnt_cck:\t\t %u\n",
913 data->last_bad_plcp_cnt_cck);
914 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
915 data->last_fa_cnt_cck);
916 pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
917 data->nrg_curr_state);
918 pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
919 data->nrg_prev_state);
920 pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
921 for (cnt = 0; cnt < 10; cnt++) {
922 pos += scnprintf(buf + pos, bufsz - pos, " %u",
923 data->nrg_value[cnt]);
925 pos += scnprintf(buf + pos, bufsz - pos, "\n");
926 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
927 for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
928 pos += scnprintf(buf + pos, bufsz - pos, " %u",
929 data->nrg_silence_rssi[cnt]);
931 pos += scnprintf(buf + pos, bufsz - pos, "\n");
932 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
933 data->nrg_silence_ref);
934 pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
935 data->nrg_energy_idx);
936 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
937 data->nrg_silence_idx);
938 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
940 pos += scnprintf(buf + pos, bufsz - pos,
941 "nrg_auto_corr_silence_diff:\t %u\n",
942 data->nrg_auto_corr_silence_diff);
943 pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
944 data->num_in_cck_no_fa);
945 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
948 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
954 static ssize_t iwl_legacy_dbgfs_chain_noise_read(struct file *file,
955 char __user *user_buf,
956 size_t count, loff_t *ppos) {
958 struct iwl_priv *priv = file->private_data;
962 int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100;
964 struct iwl_chain_noise_data *data;
966 data = &priv->chain_noise_data;
967 buf = kzalloc(bufsz, GFP_KERNEL);
969 IWL_ERR(priv, "Can not allocate Buffer\n");
973 pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
974 data->active_chains);
975 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
976 data->chain_noise_a);
977 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
978 data->chain_noise_b);
979 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
980 data->chain_noise_c);
981 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
982 data->chain_signal_a);
983 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
984 data->chain_signal_b);
985 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
986 data->chain_signal_c);
987 pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
990 pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
991 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
992 pos += scnprintf(buf + pos, bufsz - pos, " %u",
993 data->disconn_array[cnt]);
995 pos += scnprintf(buf + pos, bufsz - pos, "\n");
996 pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
997 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
998 pos += scnprintf(buf + pos, bufsz - pos, " %u",
999 data->delta_gain_code[cnt]);
1001 pos += scnprintf(buf + pos, bufsz - pos, "\n");
1002 pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
1004 pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
1007 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1012 static ssize_t iwl_legacy_dbgfs_power_save_status_read(struct file *file,
1013 char __user *user_buf,
1014 size_t count, loff_t *ppos)
1016 struct iwl_priv *priv = file->private_data;
1019 const size_t bufsz = sizeof(buf);
1022 pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) &
1023 CSR_GP_REG_POWER_SAVE_STATUS_MSK;
1025 pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
1026 pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
1027 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1028 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1029 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1032 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1035 static ssize_t iwl_legacy_dbgfs_clear_ucode_statistics_write(struct file *file,
1036 const char __user *user_buf,
1037 size_t count, loff_t *ppos)
1039 struct iwl_priv *priv = file->private_data;
1044 memset(buf, 0, sizeof(buf));
1045 buf_size = min(count, sizeof(buf) - 1);
1046 if (copy_from_user(buf, user_buf, buf_size))
1048 if (sscanf(buf, "%d", &clear) != 1)
1051 /* make request to uCode to retrieve statistics information */
1052 mutex_lock(&priv->mutex);
1053 iwl_legacy_send_statistics_request(priv, CMD_SYNC, true);
1054 mutex_unlock(&priv->mutex);
1059 static ssize_t iwl_legacy_dbgfs_rxon_flags_read(struct file *file,
1060 char __user *user_buf,
1061 size_t count, loff_t *ppos) {
1063 struct iwl_priv *priv = file->private_data;
1067 len = sprintf(buf, "0x%04X\n",
1068 le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags));
1069 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1072 static ssize_t iwl_legacy_dbgfs_rxon_filter_flags_read(struct file *file,
1073 char __user *user_buf,
1074 size_t count, loff_t *ppos) {
1076 struct iwl_priv *priv = file->private_data;
1080 len = sprintf(buf, "0x%04X\n",
1081 le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags));
1082 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1085 static ssize_t iwl_legacy_dbgfs_fh_reg_read(struct file *file,
1086 char __user *user_buf,
1087 size_t count, loff_t *ppos)
1089 struct iwl_priv *priv = file->private_data;
1092 ssize_t ret = -EFAULT;
1094 if (priv->cfg->ops->lib->dump_fh) {
1095 ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true);
1097 ret = simple_read_from_buffer(user_buf,
1098 count, ppos, buf, pos);
1106 static ssize_t iwl_legacy_dbgfs_missed_beacon_read(struct file *file,
1107 char __user *user_buf,
1108 size_t count, loff_t *ppos) {
1110 struct iwl_priv *priv = file->private_data;
1113 const size_t bufsz = sizeof(buf);
1115 pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
1116 priv->missed_beacon_threshold);
1118 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1121 static ssize_t iwl_legacy_dbgfs_missed_beacon_write(struct file *file,
1122 const char __user *user_buf,
1123 size_t count, loff_t *ppos)
1125 struct iwl_priv *priv = file->private_data;
1130 memset(buf, 0, sizeof(buf));
1131 buf_size = min(count, sizeof(buf) - 1);
1132 if (copy_from_user(buf, user_buf, buf_size))
1134 if (sscanf(buf, "%d", &missed) != 1)
1137 if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN ||
1138 missed > IWL_MISSED_BEACON_THRESHOLD_MAX)
1139 priv->missed_beacon_threshold =
1140 IWL_MISSED_BEACON_THRESHOLD_DEF;
1142 priv->missed_beacon_threshold = missed;
1147 static ssize_t iwl_legacy_dbgfs_force_reset_read(struct file *file,
1148 char __user *user_buf,
1149 size_t count, loff_t *ppos) {
1151 struct iwl_priv *priv = file->private_data;
1154 const size_t bufsz = sizeof(buf);
1155 struct iwl_force_reset *force_reset;
1157 force_reset = &priv->force_reset;
1159 pos += scnprintf(buf + pos, bufsz - pos,
1160 "\tnumber of reset request: %d\n",
1161 force_reset->reset_request_count);
1162 pos += scnprintf(buf + pos, bufsz - pos,
1163 "\tnumber of reset request success: %d\n",
1164 force_reset->reset_success_count);
1165 pos += scnprintf(buf + pos, bufsz - pos,
1166 "\tnumber of reset request reject: %d\n",
1167 force_reset->reset_reject_count);
1168 pos += scnprintf(buf + pos, bufsz - pos,
1169 "\treset duration: %lu\n",
1170 force_reset->reset_duration);
1172 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1175 static ssize_t iwl_legacy_dbgfs_force_reset_write(struct file *file,
1176 const char __user *user_buf,
1177 size_t count, loff_t *ppos) {
1180 struct iwl_priv *priv = file->private_data;
1182 ret = iwl_legacy_force_reset(priv, true);
1184 return ret ? ret : count;
1187 static ssize_t iwl_legacy_dbgfs_wd_timeout_write(struct file *file,
1188 const char __user *user_buf,
1189 size_t count, loff_t *ppos) {
1191 struct iwl_priv *priv = file->private_data;
1196 memset(buf, 0, sizeof(buf));
1197 buf_size = min(count, sizeof(buf) - 1);
1198 if (copy_from_user(buf, user_buf, buf_size))
1200 if (sscanf(buf, "%d", &timeout) != 1)
1202 if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT)
1203 timeout = IWL_DEF_WD_TIMEOUT;
1205 priv->cfg->base_params->wd_timeout = timeout;
1206 iwl_legacy_setup_watchdog(priv);
1210 DEBUGFS_READ_FILE_OPS(rx_statistics);
1211 DEBUGFS_READ_FILE_OPS(tx_statistics);
1212 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
1213 DEBUGFS_READ_FILE_OPS(rx_queue);
1214 DEBUGFS_READ_FILE_OPS(tx_queue);
1215 DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1216 DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1217 DEBUGFS_READ_FILE_OPS(ucode_general_stats);
1218 DEBUGFS_READ_FILE_OPS(sensitivity);
1219 DEBUGFS_READ_FILE_OPS(chain_noise);
1220 DEBUGFS_READ_FILE_OPS(power_save_status);
1221 DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
1222 DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
1223 DEBUGFS_READ_FILE_OPS(fh_reg);
1224 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
1225 DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1226 DEBUGFS_READ_FILE_OPS(rxon_flags);
1227 DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
1228 DEBUGFS_WRITE_FILE_OPS(wd_timeout);
1231 * Create the debugfs files and directories
1234 int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name)
1236 struct dentry *phyd = priv->hw->wiphy->debugfsdir;
1237 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1239 dir_drv = debugfs_create_dir(name, phyd);
1243 priv->debugfs_dir = dir_drv;
1245 dir_data = debugfs_create_dir("data", dir_drv);
1248 dir_rf = debugfs_create_dir("rf", dir_drv);
1251 dir_debug = debugfs_create_dir("debug", dir_drv);
1255 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1256 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
1257 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1258 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1259 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1260 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1261 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1262 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
1263 DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
1264 DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
1265 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
1266 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
1267 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
1268 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
1269 DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
1270 DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
1271 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
1272 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
1273 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
1274 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1275 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1276 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
1278 if (priv->cfg->base_params->sensitivity_calib_by_driver)
1279 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
1280 if (priv->cfg->base_params->chain_noise_calib_by_driver)
1281 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
1282 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
1283 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
1284 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
1285 if (priv->cfg->base_params->sensitivity_calib_by_driver)
1286 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
1287 &priv->disable_sens_cal);
1288 if (priv->cfg->base_params->chain_noise_calib_by_driver)
1289 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
1290 &priv->disable_chain_noise_cal);
1291 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
1292 &priv->disable_tx_power_cal);
1296 IWL_ERR(priv, "Can't create the debugfs directory\n");
1297 iwl_legacy_dbgfs_unregister(priv);
1300 EXPORT_SYMBOL(iwl_legacy_dbgfs_register);
1303 * Remove the debugfs files and directories
1306 void iwl_legacy_dbgfs_unregister(struct iwl_priv *priv)
1308 if (!priv->debugfs_dir)
1311 debugfs_remove_recursive(priv->debugfs_dir);
1312 priv->debugfs_dir = NULL;
1314 EXPORT_SYMBOL(iwl_legacy_dbgfs_unregister);