1 /******************************************************************************
5 * Copyright(c) 2008 - 2010 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 *****************************************************************************/
29 #include <linux/slab.h>
30 #include <linux/kernel.h>
31 #include <linux/module.h>
32 #include <linux/debugfs.h>
34 #include <linux/ieee80211.h>
35 #include <net/mac80211.h>
39 #include "iwl-debug.h"
42 #include "iwl-calib.h"
44 /* create and remove of files */
45 #define DEBUGFS_ADD_FILE(name, parent, mode) do { \
46 if (!debugfs_create_file(#name, mode, parent, priv, \
47 &iwl_dbgfs_##name##_ops)) \
51 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
52 struct dentry *__tmp; \
53 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
55 if (IS_ERR(__tmp) || !__tmp) \
59 #define DEBUGFS_ADD_X32(name, parent, ptr) do { \
60 struct dentry *__tmp; \
61 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
63 if (IS_ERR(__tmp) || !__tmp) \
68 #define DEBUGFS_READ_FUNC(name) \
69 static ssize_t iwl_dbgfs_##name##_read(struct file *file, \
70 char __user *user_buf, \
71 size_t count, loff_t *ppos);
73 #define DEBUGFS_WRITE_FUNC(name) \
74 static ssize_t iwl_dbgfs_##name##_write(struct file *file, \
75 const char __user *user_buf, \
76 size_t count, loff_t *ppos);
79 static int iwl_dbgfs_open_file_generic(struct inode
*inode
, struct file
*file
)
81 file
->private_data
= inode
->i_private
;
85 #define DEBUGFS_READ_FILE_OPS(name) \
86 DEBUGFS_READ_FUNC(name); \
87 static const struct file_operations iwl_dbgfs_##name##_ops = { \
88 .read = iwl_dbgfs_##name##_read, \
89 .open = iwl_dbgfs_open_file_generic, \
92 #define DEBUGFS_WRITE_FILE_OPS(name) \
93 DEBUGFS_WRITE_FUNC(name); \
94 static const struct file_operations iwl_dbgfs_##name##_ops = { \
95 .write = iwl_dbgfs_##name##_write, \
96 .open = iwl_dbgfs_open_file_generic, \
100 #define DEBUGFS_READ_WRITE_FILE_OPS(name) \
101 DEBUGFS_READ_FUNC(name); \
102 DEBUGFS_WRITE_FUNC(name); \
103 static const struct file_operations iwl_dbgfs_##name##_ops = { \
104 .write = iwl_dbgfs_##name##_write, \
105 .read = iwl_dbgfs_##name##_read, \
106 .open = iwl_dbgfs_open_file_generic, \
109 static ssize_t
iwl_dbgfs_tx_statistics_read(struct file
*file
,
110 char __user
*user_buf
,
111 size_t count
, loff_t
*ppos
) {
113 struct iwl_priv
*priv
= file
->private_data
;
119 const size_t bufsz
= 100 +
120 sizeof(char) * 50 * (MANAGEMENT_MAX
+ CONTROL_MAX
);
121 buf
= kzalloc(bufsz
, GFP_KERNEL
);
124 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Management:\n");
125 for (cnt
= 0; cnt
< MANAGEMENT_MAX
; cnt
++) {
126 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
128 get_mgmt_string(cnt
),
129 priv
->tx_stats
.mgmt
[cnt
]);
131 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Control\n");
132 for (cnt
= 0; cnt
< CONTROL_MAX
; cnt
++) {
133 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
135 get_ctrl_string(cnt
),
136 priv
->tx_stats
.ctrl
[cnt
]);
138 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Data:\n");
139 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tcnt: %u\n",
140 priv
->tx_stats
.data_cnt
);
141 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tbytes: %llu\n",
142 priv
->tx_stats
.data_bytes
);
143 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
148 static ssize_t
iwl_dbgfs_clear_traffic_statistics_write(struct file
*file
,
149 const char __user
*user_buf
,
150 size_t count
, loff_t
*ppos
)
152 struct iwl_priv
*priv
= file
->private_data
;
157 memset(buf
, 0, sizeof(buf
));
158 buf_size
= min(count
, sizeof(buf
) - 1);
159 if (copy_from_user(buf
, user_buf
, buf_size
))
161 if (sscanf(buf
, "%x", &clear_flag
) != 1)
163 iwl_clear_traffic_stats(priv
);
168 static ssize_t
iwl_dbgfs_rx_statistics_read(struct file
*file
,
169 char __user
*user_buf
,
170 size_t count
, loff_t
*ppos
) {
172 struct iwl_priv
*priv
= file
->private_data
;
177 const size_t bufsz
= 100 +
178 sizeof(char) * 50 * (MANAGEMENT_MAX
+ CONTROL_MAX
);
179 buf
= kzalloc(bufsz
, GFP_KERNEL
);
183 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Management:\n");
184 for (cnt
= 0; cnt
< MANAGEMENT_MAX
; cnt
++) {
185 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
187 get_mgmt_string(cnt
),
188 priv
->rx_stats
.mgmt
[cnt
]);
190 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Control:\n");
191 for (cnt
= 0; cnt
< CONTROL_MAX
; cnt
++) {
192 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
194 get_ctrl_string(cnt
),
195 priv
->rx_stats
.ctrl
[cnt
]);
197 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Data:\n");
198 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tcnt: %u\n",
199 priv
->rx_stats
.data_cnt
);
200 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tbytes: %llu\n",
201 priv
->rx_stats
.data_bytes
);
203 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
208 #define BYTE1_MASK 0x000000ff;
209 #define BYTE2_MASK 0x0000ffff;
210 #define BYTE3_MASK 0x00ffffff;
211 static ssize_t
iwl_dbgfs_sram_read(struct file
*file
,
212 char __user
*user_buf
,
213 size_t count
, loff_t
*ppos
)
220 struct iwl_priv
*priv
= file
->private_data
;
223 /* default is to dump the entire data segment */
224 if (!priv
->dbgfs_sram_offset
&& !priv
->dbgfs_sram_len
) {
225 priv
->dbgfs_sram_offset
= 0x800000;
226 if (priv
->ucode_type
== UCODE_INIT
)
227 priv
->dbgfs_sram_len
= priv
->ucode_init_data
.len
;
229 priv
->dbgfs_sram_len
= priv
->ucode_data
.len
;
231 bufsz
= 30 + priv
->dbgfs_sram_len
* sizeof(char) * 10;
232 buf
= kmalloc(bufsz
, GFP_KERNEL
);
235 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "sram_len: 0x%x\n",
236 priv
->dbgfs_sram_len
);
237 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "sram_offset: 0x%x\n",
238 priv
->dbgfs_sram_offset
);
239 for (i
= priv
->dbgfs_sram_len
; i
> 0; i
-= 4) {
240 val
= iwl_read_targ_mem(priv
, priv
->dbgfs_sram_offset
+ \
241 priv
->dbgfs_sram_len
- i
);
256 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
257 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "0x%08x ", val
);
259 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
261 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
266 static ssize_t
iwl_dbgfs_sram_write(struct file
*file
,
267 const char __user
*user_buf
,
268 size_t count
, loff_t
*ppos
)
270 struct iwl_priv
*priv
= file
->private_data
;
275 memset(buf
, 0, sizeof(buf
));
276 buf_size
= min(count
, sizeof(buf
) - 1);
277 if (copy_from_user(buf
, user_buf
, buf_size
))
280 if (sscanf(buf
, "%x,%x", &offset
, &len
) == 2) {
281 priv
->dbgfs_sram_offset
= offset
;
282 priv
->dbgfs_sram_len
= len
;
284 priv
->dbgfs_sram_offset
= 0;
285 priv
->dbgfs_sram_len
= 0;
291 static ssize_t
iwl_dbgfs_stations_read(struct file
*file
, char __user
*user_buf
,
292 size_t count
, loff_t
*ppos
)
294 struct iwl_priv
*priv
= file
->private_data
;
295 struct iwl_station_entry
*station
;
296 int max_sta
= priv
->hw_params
.max_stations
;
300 /* Add 30 for initial string */
301 const size_t bufsz
= 30 + sizeof(char) * 500 * (priv
->num_stations
);
303 buf
= kmalloc(bufsz
, GFP_KERNEL
);
307 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "num of stations: %d\n\n",
310 for (i
= 0; i
< max_sta
; i
++) {
311 station
= &priv
->stations
[i
];
314 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
315 "station %d - addr: %pM, flags: %#x\n",
316 i
, station
->sta
.sta
.addr
,
317 station
->sta
.station_flags_msk
);
318 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
319 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
320 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
321 "start_idx\tbitmap\t\t\trate_n_flags\n");
323 for (j
= 0; j
< MAX_TID_COUNT
; j
++) {
324 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
325 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
326 j
, station
->tid
[j
].seq_number
,
327 station
->tid
[j
].agg
.txq_id
,
328 station
->tid
[j
].agg
.frame_count
,
329 station
->tid
[j
].tfds_in_queue
,
330 station
->tid
[j
].agg
.start_idx
,
331 station
->tid
[j
].agg
.bitmap
,
332 station
->tid
[j
].agg
.rate_n_flags
);
334 if (station
->tid
[j
].agg
.wait_for_ba
)
335 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
337 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
340 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
343 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
348 static ssize_t
iwl_dbgfs_nvm_read(struct file
*file
,
349 char __user
*user_buf
,
354 struct iwl_priv
*priv
= file
->private_data
;
355 int pos
= 0, ofs
= 0, buf_size
= 0;
359 size_t eeprom_len
= priv
->cfg
->eeprom_size
;
360 buf_size
= 4 * eeprom_len
+ 256;
362 if (eeprom_len
% 16) {
363 IWL_ERR(priv
, "NVM size is not multiple of 16.\n");
369 IWL_ERR(priv
, "Invalid EEPROM/OTP memory\n");
373 /* 4 characters for byte 0xYY */
374 buf
= kzalloc(buf_size
, GFP_KERNEL
);
376 IWL_ERR(priv
, "Can not allocate Buffer\n");
379 eeprom_ver
= iwl_eeprom_query16(priv
, EEPROM_VERSION
);
380 pos
+= scnprintf(buf
+ pos
, buf_size
- pos
, "NVM Type: %s, "
382 (priv
->nvm_device_type
== NVM_DEVICE_TYPE_OTP
)
383 ? "OTP" : "EEPROM", eeprom_ver
);
384 for (ofs
= 0 ; ofs
< eeprom_len
; ofs
+= 16) {
385 pos
+= scnprintf(buf
+ pos
, buf_size
- pos
, "0x%.4x ", ofs
);
386 hex_dump_to_buffer(ptr
+ ofs
, 16 , 16, 2, buf
+ pos
,
388 pos
+= strlen(buf
+ pos
);
389 if (buf_size
- pos
> 0)
393 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
398 static ssize_t
iwl_dbgfs_log_event_read(struct file
*file
,
399 char __user
*user_buf
,
400 size_t count
, loff_t
*ppos
)
402 struct iwl_priv
*priv
= file
->private_data
;
405 ssize_t ret
= -ENOMEM
;
407 ret
= pos
= priv
->cfg
->ops
->lib
->dump_nic_event_log(
408 priv
, true, &buf
, true);
410 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
416 static ssize_t
iwl_dbgfs_log_event_write(struct file
*file
,
417 const char __user
*user_buf
,
418 size_t count
, loff_t
*ppos
)
420 struct iwl_priv
*priv
= file
->private_data
;
425 memset(buf
, 0, sizeof(buf
));
426 buf_size
= min(count
, sizeof(buf
) - 1);
427 if (copy_from_user(buf
, user_buf
, buf_size
))
429 if (sscanf(buf
, "%d", &event_log_flag
) != 1)
431 if (event_log_flag
== 1)
432 priv
->cfg
->ops
->lib
->dump_nic_event_log(priv
, true,
440 static ssize_t
iwl_dbgfs_channels_read(struct file
*file
, char __user
*user_buf
,
441 size_t count
, loff_t
*ppos
)
443 struct iwl_priv
*priv
= file
->private_data
;
444 struct ieee80211_channel
*channels
= NULL
;
445 const struct ieee80211_supported_band
*supp_band
= NULL
;
446 int pos
= 0, i
, bufsz
= PAGE_SIZE
;
450 if (!test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
))
453 buf
= kzalloc(bufsz
, GFP_KERNEL
);
455 IWL_ERR(priv
, "Can not allocate Buffer\n");
459 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_2GHZ
);
461 channels
= supp_band
->channels
;
463 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
464 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
465 supp_band
->n_channels
);
467 for (i
= 0; i
< supp_band
->n_channels
; i
++)
468 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
469 "%d: %ddBm: BSS%s%s, %s.\n",
470 channels
[i
].hw_value
,
471 channels
[i
].max_power
,
472 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
473 " (IEEE 802.11h required)" : "",
474 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
475 || (channels
[i
].flags
&
476 IEEE80211_CHAN_RADAR
)) ? "" :
479 IEEE80211_CHAN_PASSIVE_SCAN
?
480 "passive only" : "active/passive");
482 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_5GHZ
);
484 channels
= supp_band
->channels
;
486 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
487 "Displaying %d channels in 5.2GHz band (802.11a)\n",
488 supp_band
->n_channels
);
490 for (i
= 0; i
< supp_band
->n_channels
; i
++)
491 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
492 "%d: %ddBm: BSS%s%s, %s.\n",
493 channels
[i
].hw_value
,
494 channels
[i
].max_power
,
495 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
496 " (IEEE 802.11h required)" : "",
497 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
498 || (channels
[i
].flags
&
499 IEEE80211_CHAN_RADAR
)) ? "" :
502 IEEE80211_CHAN_PASSIVE_SCAN
?
503 "passive only" : "active/passive");
505 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
510 static ssize_t
iwl_dbgfs_status_read(struct file
*file
,
511 char __user
*user_buf
,
512 size_t count
, loff_t
*ppos
) {
514 struct iwl_priv
*priv
= file
->private_data
;
517 const size_t bufsz
= sizeof(buf
);
519 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_HCMD_ACTIVE:\t %d\n",
520 test_bit(STATUS_HCMD_ACTIVE
, &priv
->status
));
521 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INT_ENABLED:\t %d\n",
522 test_bit(STATUS_INT_ENABLED
, &priv
->status
));
523 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_RF_KILL_HW:\t %d\n",
524 test_bit(STATUS_RF_KILL_HW
, &priv
->status
));
525 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_CT_KILL:\t\t %d\n",
526 test_bit(STATUS_CT_KILL
, &priv
->status
));
527 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INIT:\t\t %d\n",
528 test_bit(STATUS_INIT
, &priv
->status
));
529 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_ALIVE:\t\t %d\n",
530 test_bit(STATUS_ALIVE
, &priv
->status
));
531 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_READY:\t\t %d\n",
532 test_bit(STATUS_READY
, &priv
->status
));
533 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_TEMPERATURE:\t %d\n",
534 test_bit(STATUS_TEMPERATURE
, &priv
->status
));
535 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_GEO_CONFIGURED:\t %d\n",
536 test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
));
537 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_EXIT_PENDING:\t %d\n",
538 test_bit(STATUS_EXIT_PENDING
, &priv
->status
));
539 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_STATISTICS:\t %d\n",
540 test_bit(STATUS_STATISTICS
, &priv
->status
));
541 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCANNING:\t %d\n",
542 test_bit(STATUS_SCANNING
, &priv
->status
));
543 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_ABORTING:\t %d\n",
544 test_bit(STATUS_SCAN_ABORTING
, &priv
->status
));
545 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_HW:\t\t %d\n",
546 test_bit(STATUS_SCAN_HW
, &priv
->status
));
547 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_POWER_PMI:\t %d\n",
548 test_bit(STATUS_POWER_PMI
, &priv
->status
));
549 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_FW_ERROR:\t %d\n",
550 test_bit(STATUS_FW_ERROR
, &priv
->status
));
551 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
554 static ssize_t
iwl_dbgfs_interrupt_read(struct file
*file
,
555 char __user
*user_buf
,
556 size_t count
, loff_t
*ppos
) {
558 struct iwl_priv
*priv
= file
->private_data
;
562 int bufsz
= 24 * 64; /* 24 items * 64 char per item */
565 buf
= kzalloc(bufsz
, GFP_KERNEL
);
567 IWL_ERR(priv
, "Can not allocate Buffer\n");
571 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
572 "Interrupt Statistics Report:\n");
574 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "HW Error:\t\t\t %u\n",
576 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "SW Error:\t\t\t %u\n",
578 if (priv
->isr_stats
.sw
|| priv
->isr_stats
.hw
) {
579 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
580 "\tLast Restarting Code: 0x%X\n",
581 priv
->isr_stats
.err_code
);
583 #ifdef CONFIG_IWLWIFI_DEBUG
584 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Frame transmitted:\t\t %u\n",
585 priv
->isr_stats
.sch
);
586 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Alive interrupt:\t\t %u\n",
587 priv
->isr_stats
.alive
);
589 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
590 "HW RF KILL switch toggled:\t %u\n",
591 priv
->isr_stats
.rfkill
);
593 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "CT KILL:\t\t\t %u\n",
594 priv
->isr_stats
.ctkill
);
596 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Wakeup Interrupt:\t\t %u\n",
597 priv
->isr_stats
.wakeup
);
599 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
600 "Rx command responses:\t\t %u\n",
602 for (cnt
= 0; cnt
< REPLY_MAX
; cnt
++) {
603 if (priv
->isr_stats
.rx_handlers
[cnt
] > 0)
604 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
605 "\tRx handler[%36s]:\t\t %u\n",
607 priv
->isr_stats
.rx_handlers
[cnt
]);
610 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx/FH interrupt:\t\t %u\n",
613 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Unexpected INTA:\t\t %u\n",
614 priv
->isr_stats
.unhandled
);
616 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
621 static ssize_t
iwl_dbgfs_interrupt_write(struct file
*file
,
622 const char __user
*user_buf
,
623 size_t count
, loff_t
*ppos
)
625 struct iwl_priv
*priv
= file
->private_data
;
630 memset(buf
, 0, sizeof(buf
));
631 buf_size
= min(count
, sizeof(buf
) - 1);
632 if (copy_from_user(buf
, user_buf
, buf_size
))
634 if (sscanf(buf
, "%x", &reset_flag
) != 1)
637 iwl_clear_isr_stats(priv
);
642 static ssize_t
iwl_dbgfs_qos_read(struct file
*file
, char __user
*user_buf
,
643 size_t count
, loff_t
*ppos
)
645 struct iwl_priv
*priv
= file
->private_data
;
646 struct iwl_rxon_context
*ctx
;
648 char buf
[256 * NUM_IWL_RXON_CTX
];
649 const size_t bufsz
= sizeof(buf
);
651 for_each_context(priv
, ctx
) {
652 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "context %d:\n",
654 for (i
= 0; i
< AC_NUM
; i
++) {
655 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
656 "\tcw_min\tcw_max\taifsn\ttxop\n");
657 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
658 "AC[%d]\t%u\t%u\t%u\t%u\n", i
,
659 ctx
->qos_data
.def_qos_parm
.ac
[i
].cw_min
,
660 ctx
->qos_data
.def_qos_parm
.ac
[i
].cw_max
,
661 ctx
->qos_data
.def_qos_parm
.ac
[i
].aifsn
,
662 ctx
->qos_data
.def_qos_parm
.ac
[i
].edca_txop
);
664 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
666 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
669 static ssize_t
iwl_dbgfs_led_read(struct file
*file
, char __user
*user_buf
,
670 size_t count
, loff_t
*ppos
)
672 struct iwl_priv
*priv
= file
->private_data
;
675 const size_t bufsz
= sizeof(buf
);
677 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
678 "allow blinking: %s\n",
679 (priv
->allow_blinking
) ? "True" : "False");
680 if (priv
->allow_blinking
) {
681 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
682 "Led blinking rate: %u\n",
683 priv
->last_blink_rate
);
684 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
685 "Last blink time: %lu\n",
686 priv
->last_blink_time
);
689 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
692 static ssize_t
iwl_dbgfs_thermal_throttling_read(struct file
*file
,
693 char __user
*user_buf
,
694 size_t count
, loff_t
*ppos
)
696 struct iwl_priv
*priv
= file
->private_data
;
697 struct iwl_tt_mgmt
*tt
= &priv
->thermal_throttle
;
698 struct iwl_tt_restriction
*restriction
;
701 const size_t bufsz
= sizeof(buf
);
703 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
704 "Thermal Throttling Mode: %s\n",
705 tt
->advanced_tt
? "Advance" : "Legacy");
706 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
707 "Thermal Throttling State: %d\n",
709 if (tt
->advanced_tt
) {
710 restriction
= tt
->restriction
+ tt
->state
;
711 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
713 restriction
->tx_stream
);
714 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
716 restriction
->rx_stream
);
717 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
721 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
724 static ssize_t
iwl_dbgfs_disable_ht40_write(struct file
*file
,
725 const char __user
*user_buf
,
726 size_t count
, loff_t
*ppos
)
728 struct iwl_priv
*priv
= file
->private_data
;
733 memset(buf
, 0, sizeof(buf
));
734 buf_size
= min(count
, sizeof(buf
) - 1);
735 if (copy_from_user(buf
, user_buf
, buf_size
))
737 if (sscanf(buf
, "%d", &ht40
) != 1)
739 if (!iwl_is_any_associated(priv
))
740 priv
->disable_ht40
= ht40
? true : false;
742 IWL_ERR(priv
, "Sta associated with AP - "
743 "Change to 40MHz channel support is not allowed\n");
750 static ssize_t
iwl_dbgfs_disable_ht40_read(struct file
*file
,
751 char __user
*user_buf
,
752 size_t count
, loff_t
*ppos
)
754 struct iwl_priv
*priv
= file
->private_data
;
757 const size_t bufsz
= sizeof(buf
);
759 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
760 "11n 40MHz Mode: %s\n",
761 priv
->disable_ht40
? "Disabled" : "Enabled");
762 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
765 static ssize_t
iwl_dbgfs_sleep_level_override_write(struct file
*file
,
766 const char __user
*user_buf
,
767 size_t count
, loff_t
*ppos
)
769 struct iwl_priv
*priv
= file
->private_data
;
774 memset(buf
, 0, sizeof(buf
));
775 buf_size
= min(count
, sizeof(buf
) - 1);
776 if (copy_from_user(buf
, user_buf
, buf_size
))
779 if (sscanf(buf
, "%d", &value
) != 1)
783 * Our users expect 0 to be "CAM", but 0 isn't actually
784 * valid here. However, let's not confuse them and present
785 * IWL_POWER_INDEX_1 as "1", not "0".
792 if (value
!= -1 && (value
< 0 || value
>= IWL_POWER_NUM
))
795 if (!iwl_is_ready_rf(priv
))
798 priv
->power_data
.debug_sleep_level_override
= value
;
800 mutex_lock(&priv
->mutex
);
801 iwl_power_update_mode(priv
, true);
802 mutex_unlock(&priv
->mutex
);
807 static ssize_t
iwl_dbgfs_sleep_level_override_read(struct file
*file
,
808 char __user
*user_buf
,
809 size_t count
, loff_t
*ppos
)
811 struct iwl_priv
*priv
= file
->private_data
;
814 const size_t bufsz
= sizeof(buf
);
816 /* see the write function */
817 value
= priv
->power_data
.debug_sleep_level_override
;
821 pos
= scnprintf(buf
, bufsz
, "%d\n", value
);
822 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
825 static ssize_t
iwl_dbgfs_current_sleep_command_read(struct file
*file
,
826 char __user
*user_buf
,
827 size_t count
, loff_t
*ppos
)
829 struct iwl_priv
*priv
= file
->private_data
;
832 const size_t bufsz
= sizeof(buf
);
833 struct iwl_powertable_cmd
*cmd
= &priv
->power_data
.sleep_cmd
;
835 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
836 "flags: %#.2x\n", le16_to_cpu(cmd
->flags
));
837 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
838 "RX/TX timeout: %d/%d usec\n",
839 le32_to_cpu(cmd
->rx_data_timeout
),
840 le32_to_cpu(cmd
->tx_data_timeout
));
841 for (i
= 0; i
< IWL_POWER_VEC_SIZE
; i
++)
842 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
843 "sleep_interval[%d]: %d\n", i
,
844 le32_to_cpu(cmd
->sleep_interval
[i
]));
846 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
849 DEBUGFS_READ_WRITE_FILE_OPS(sram
);
850 DEBUGFS_READ_WRITE_FILE_OPS(log_event
);
851 DEBUGFS_READ_FILE_OPS(nvm
);
852 DEBUGFS_READ_FILE_OPS(stations
);
853 DEBUGFS_READ_FILE_OPS(channels
);
854 DEBUGFS_READ_FILE_OPS(status
);
855 DEBUGFS_READ_WRITE_FILE_OPS(interrupt
);
856 DEBUGFS_READ_FILE_OPS(qos
);
857 DEBUGFS_READ_FILE_OPS(led
);
858 DEBUGFS_READ_FILE_OPS(thermal_throttling
);
859 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40
);
860 DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override
);
861 DEBUGFS_READ_FILE_OPS(current_sleep_command
);
863 static ssize_t
iwl_dbgfs_traffic_log_read(struct file
*file
,
864 char __user
*user_buf
,
865 size_t count
, loff_t
*ppos
)
867 struct iwl_priv
*priv
= file
->private_data
;
868 int pos
= 0, ofs
= 0;
870 struct iwl_tx_queue
*txq
;
872 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
874 int bufsz
= ((IWL_TRAFFIC_ENTRIES
* IWL_TRAFFIC_ENTRY_SIZE
* 64) * 2) +
875 (priv
->cfg
->num_of_queues
* 32 * 8) + 400;
880 IWL_ERR(priv
, "txq not ready\n");
883 buf
= kzalloc(bufsz
, GFP_KERNEL
);
885 IWL_ERR(priv
, "Can not allocate buffer\n");
888 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx Queue\n");
889 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
890 txq
= &priv
->txq
[cnt
];
892 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
893 "q[%d]: read_ptr: %u, write_ptr: %u\n",
894 cnt
, q
->read_ptr
, q
->write_ptr
);
896 if (priv
->tx_traffic
&& (iwl_debug_level
& IWL_DL_TX
)) {
897 ptr
= priv
->tx_traffic
;
898 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
899 "Tx Traffic idx: %u\n", priv
->tx_traffic_idx
);
900 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
901 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
902 entry
++, ofs
+= 16) {
903 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
905 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
906 buf
+ pos
, bufsz
- pos
, 0);
907 pos
+= strlen(buf
+ pos
);
914 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Rx Queue\n");
915 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
916 "read: %u, write: %u\n",
917 rxq
->read
, rxq
->write
);
919 if (priv
->rx_traffic
&& (iwl_debug_level
& IWL_DL_RX
)) {
920 ptr
= priv
->rx_traffic
;
921 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
922 "Rx Traffic idx: %u\n", priv
->rx_traffic_idx
);
923 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
924 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
925 entry
++, ofs
+= 16) {
926 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
928 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
929 buf
+ pos
, bufsz
- pos
, 0);
930 pos
+= strlen(buf
+ pos
);
937 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
942 static ssize_t
iwl_dbgfs_traffic_log_write(struct file
*file
,
943 const char __user
*user_buf
,
944 size_t count
, loff_t
*ppos
)
946 struct iwl_priv
*priv
= file
->private_data
;
951 memset(buf
, 0, sizeof(buf
));
952 buf_size
= min(count
, sizeof(buf
) - 1);
953 if (copy_from_user(buf
, user_buf
, buf_size
))
955 if (sscanf(buf
, "%d", &traffic_log
) != 1)
957 if (traffic_log
== 0)
958 iwl_reset_traffic_log(priv
);
963 static ssize_t
iwl_dbgfs_tx_queue_read(struct file
*file
,
964 char __user
*user_buf
,
965 size_t count
, loff_t
*ppos
) {
967 struct iwl_priv
*priv
= file
->private_data
;
968 struct iwl_tx_queue
*txq
;
974 const size_t bufsz
= sizeof(char) * 64 * priv
->cfg
->num_of_queues
;
977 IWL_ERR(priv
, "txq not ready\n");
980 buf
= kzalloc(bufsz
, GFP_KERNEL
);
984 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
985 txq
= &priv
->txq
[cnt
];
987 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
988 "hwq %.2d: read=%u write=%u stop=%d"
989 " swq_id=%#.2x (ac %d/hwq %d)\n",
990 cnt
, q
->read_ptr
, q
->write_ptr
,
991 !!test_bit(cnt
, priv
->queue_stopped
),
993 txq
->swq_id
& 0x80 ? txq
->swq_id
& 3 :
995 txq
->swq_id
& 0x80 ? (txq
->swq_id
>> 2) &
999 /* for the ACs, display the stop count too */
1000 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1001 " stop-count: %d\n",
1002 atomic_read(&priv
->queue_stop_count
[cnt
]));
1004 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1009 static ssize_t
iwl_dbgfs_rx_queue_read(struct file
*file
,
1010 char __user
*user_buf
,
1011 size_t count
, loff_t
*ppos
) {
1013 struct iwl_priv
*priv
= file
->private_data
;
1014 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
1017 const size_t bufsz
= sizeof(buf
);
1019 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "read: %u\n",
1021 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "write: %u\n",
1023 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "free_count: %u\n",
1026 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "closed_rb_num: %u\n",
1027 le16_to_cpu(rxq
->rb_stts
->closed_rb_num
) & 0x0FFF);
1029 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1030 "closed_rb_num: Not Allocated\n");
1032 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1035 static ssize_t
iwl_dbgfs_ucode_rx_stats_read(struct file
*file
,
1036 char __user
*user_buf
,
1037 size_t count
, loff_t
*ppos
)
1039 struct iwl_priv
*priv
= file
->private_data
;
1040 return priv
->cfg
->ops
->lib
->debugfs_ops
.rx_stats_read(file
,
1041 user_buf
, count
, ppos
);
1044 static ssize_t
iwl_dbgfs_ucode_tx_stats_read(struct file
*file
,
1045 char __user
*user_buf
,
1046 size_t count
, loff_t
*ppos
)
1048 struct iwl_priv
*priv
= file
->private_data
;
1049 return priv
->cfg
->ops
->lib
->debugfs_ops
.tx_stats_read(file
,
1050 user_buf
, count
, ppos
);
1053 static ssize_t
iwl_dbgfs_ucode_general_stats_read(struct file
*file
,
1054 char __user
*user_buf
,
1055 size_t count
, loff_t
*ppos
)
1057 struct iwl_priv
*priv
= file
->private_data
;
1058 return priv
->cfg
->ops
->lib
->debugfs_ops
.general_stats_read(file
,
1059 user_buf
, count
, ppos
);
1062 static ssize_t
iwl_dbgfs_sensitivity_read(struct file
*file
,
1063 char __user
*user_buf
,
1064 size_t count
, loff_t
*ppos
) {
1066 struct iwl_priv
*priv
= file
->private_data
;
1070 int bufsz
= sizeof(struct iwl_sensitivity_data
) * 4 + 100;
1072 struct iwl_sensitivity_data
*data
;
1074 data
= &priv
->sensitivity_data
;
1075 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1077 IWL_ERR(priv
, "Can not allocate Buffer\n");
1081 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm:\t\t\t %u\n",
1082 data
->auto_corr_ofdm
);
1083 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1084 "auto_corr_ofdm_mrc:\t\t %u\n",
1085 data
->auto_corr_ofdm_mrc
);
1086 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm_x1:\t\t %u\n",
1087 data
->auto_corr_ofdm_x1
);
1088 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1089 "auto_corr_ofdm_mrc_x1:\t\t %u\n",
1090 data
->auto_corr_ofdm_mrc_x1
);
1091 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck:\t\t\t %u\n",
1092 data
->auto_corr_cck
);
1093 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck_mrc:\t\t %u\n",
1094 data
->auto_corr_cck_mrc
);
1095 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1096 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
1097 data
->last_bad_plcp_cnt_ofdm
);
1098 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_ofdm:\t\t %u\n",
1099 data
->last_fa_cnt_ofdm
);
1100 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1101 "last_bad_plcp_cnt_cck:\t\t %u\n",
1102 data
->last_bad_plcp_cnt_cck
);
1103 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_cck:\t\t %u\n",
1104 data
->last_fa_cnt_cck
);
1105 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_curr_state:\t\t\t %u\n",
1106 data
->nrg_curr_state
);
1107 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_prev_state:\t\t\t %u\n",
1108 data
->nrg_prev_state
);
1109 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_value:\t\t\t");
1110 for (cnt
= 0; cnt
< 10; cnt
++) {
1111 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1112 data
->nrg_value
[cnt
]);
1114 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1115 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_rssi:\t\t");
1116 for (cnt
= 0; cnt
< NRG_NUM_PREV_STAT_L
; cnt
++) {
1117 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1118 data
->nrg_silence_rssi
[cnt
]);
1120 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1121 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_ref:\t\t %u\n",
1122 data
->nrg_silence_ref
);
1123 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_energy_idx:\t\t\t %u\n",
1124 data
->nrg_energy_idx
);
1125 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_idx:\t\t %u\n",
1126 data
->nrg_silence_idx
);
1127 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_cck:\t\t\t %u\n",
1129 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1130 "nrg_auto_corr_silence_diff:\t %u\n",
1131 data
->nrg_auto_corr_silence_diff
);
1132 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "num_in_cck_no_fa:\t\t %u\n",
1133 data
->num_in_cck_no_fa
);
1134 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_ofdm:\t\t\t %u\n",
1137 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1143 static ssize_t
iwl_dbgfs_chain_noise_read(struct file
*file
,
1144 char __user
*user_buf
,
1145 size_t count
, loff_t
*ppos
) {
1147 struct iwl_priv
*priv
= file
->private_data
;
1151 int bufsz
= sizeof(struct iwl_chain_noise_data
) * 4 + 100;
1153 struct iwl_chain_noise_data
*data
;
1155 data
= &priv
->chain_noise_data
;
1156 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1158 IWL_ERR(priv
, "Can not allocate Buffer\n");
1162 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "active_chains:\t\t\t %u\n",
1163 data
->active_chains
);
1164 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_a:\t\t\t %u\n",
1165 data
->chain_noise_a
);
1166 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_b:\t\t\t %u\n",
1167 data
->chain_noise_b
);
1168 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_c:\t\t\t %u\n",
1169 data
->chain_noise_c
);
1170 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_a:\t\t\t %u\n",
1171 data
->chain_signal_a
);
1172 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_b:\t\t\t %u\n",
1173 data
->chain_signal_b
);
1174 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_c:\t\t\t %u\n",
1175 data
->chain_signal_c
);
1176 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "beacon_count:\t\t\t %u\n",
1177 data
->beacon_count
);
1179 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "disconn_array:\t\t\t");
1180 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1181 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1182 data
->disconn_array
[cnt
]);
1184 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1185 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "delta_gain_code:\t\t");
1186 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1187 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1188 data
->delta_gain_code
[cnt
]);
1190 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1191 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "radio_write:\t\t\t %u\n",
1193 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "state:\t\t\t\t %u\n",
1196 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1201 static ssize_t
iwl_dbgfs_power_save_status_read(struct file
*file
,
1202 char __user
*user_buf
,
1203 size_t count
, loff_t
*ppos
)
1205 struct iwl_priv
*priv
= file
->private_data
;
1208 const size_t bufsz
= sizeof(buf
);
1211 pwrsave_status
= iwl_read32(priv
, CSR_GP_CNTRL
) &
1212 CSR_GP_REG_POWER_SAVE_STATUS_MSK
;
1214 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Power Save Status: ");
1215 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%s\n",
1216 (pwrsave_status
== CSR_GP_REG_NO_POWER_SAVE
) ? "none" :
1217 (pwrsave_status
== CSR_GP_REG_MAC_POWER_SAVE
) ? "MAC" :
1218 (pwrsave_status
== CSR_GP_REG_PHY_POWER_SAVE
) ? "PHY" :
1221 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1224 static ssize_t
iwl_dbgfs_clear_ucode_statistics_write(struct file
*file
,
1225 const char __user
*user_buf
,
1226 size_t count
, loff_t
*ppos
)
1228 struct iwl_priv
*priv
= file
->private_data
;
1233 memset(buf
, 0, sizeof(buf
));
1234 buf_size
= min(count
, sizeof(buf
) - 1);
1235 if (copy_from_user(buf
, user_buf
, buf_size
))
1237 if (sscanf(buf
, "%d", &clear
) != 1)
1240 /* make request to uCode to retrieve statistics information */
1241 mutex_lock(&priv
->mutex
);
1242 iwl_send_statistics_request(priv
, CMD_SYNC
, true);
1243 mutex_unlock(&priv
->mutex
);
1248 static ssize_t
iwl_dbgfs_csr_write(struct file
*file
,
1249 const char __user
*user_buf
,
1250 size_t count
, loff_t
*ppos
)
1252 struct iwl_priv
*priv
= file
->private_data
;
1257 memset(buf
, 0, sizeof(buf
));
1258 buf_size
= min(count
, sizeof(buf
) - 1);
1259 if (copy_from_user(buf
, user_buf
, buf_size
))
1261 if (sscanf(buf
, "%d", &csr
) != 1)
1264 if (priv
->cfg
->ops
->lib
->dump_csr
)
1265 priv
->cfg
->ops
->lib
->dump_csr(priv
);
1270 static ssize_t
iwl_dbgfs_ucode_tracing_read(struct file
*file
,
1271 char __user
*user_buf
,
1272 size_t count
, loff_t
*ppos
) {
1274 struct iwl_priv
*priv
= file
->private_data
;
1277 const size_t bufsz
= sizeof(buf
);
1279 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "ucode trace timer is %s\n",
1280 priv
->event_log
.ucode_trace
? "On" : "Off");
1281 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "non_wraps_count:\t\t %u\n",
1282 priv
->event_log
.non_wraps_count
);
1283 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "wraps_once_count:\t\t %u\n",
1284 priv
->event_log
.wraps_once_count
);
1285 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "wraps_more_count:\t\t %u\n",
1286 priv
->event_log
.wraps_more_count
);
1288 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1291 static ssize_t
iwl_dbgfs_ucode_tracing_write(struct file
*file
,
1292 const char __user
*user_buf
,
1293 size_t count
, loff_t
*ppos
)
1295 struct iwl_priv
*priv
= file
->private_data
;
1300 memset(buf
, 0, sizeof(buf
));
1301 buf_size
= min(count
, sizeof(buf
) - 1);
1302 if (copy_from_user(buf
, user_buf
, buf_size
))
1304 if (sscanf(buf
, "%d", &trace
) != 1)
1308 priv
->event_log
.ucode_trace
= true;
1309 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
1310 mod_timer(&priv
->ucode_trace
,
1311 jiffies
+ msecs_to_jiffies(UCODE_TRACE_PERIOD
));
1313 priv
->event_log
.ucode_trace
= false;
1314 del_timer_sync(&priv
->ucode_trace
);
1320 static ssize_t
iwl_dbgfs_rxon_flags_read(struct file
*file
,
1321 char __user
*user_buf
,
1322 size_t count
, loff_t
*ppos
) {
1324 struct iwl_priv
*priv
= file
->private_data
;
1328 len
= sprintf(buf
, "0x%04X\n",
1329 le32_to_cpu(priv
->contexts
[IWL_RXON_CTX_BSS
].active
.flags
));
1330 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1333 static ssize_t
iwl_dbgfs_rxon_filter_flags_read(struct file
*file
,
1334 char __user
*user_buf
,
1335 size_t count
, loff_t
*ppos
) {
1337 struct iwl_priv
*priv
= file
->private_data
;
1341 len
= sprintf(buf
, "0x%04X\n",
1342 le32_to_cpu(priv
->contexts
[IWL_RXON_CTX_BSS
].active
.filter_flags
));
1343 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1346 static ssize_t
iwl_dbgfs_fh_reg_read(struct file
*file
,
1347 char __user
*user_buf
,
1348 size_t count
, loff_t
*ppos
)
1350 struct iwl_priv
*priv
= file
->private_data
;
1353 ssize_t ret
= -EFAULT
;
1355 if (priv
->cfg
->ops
->lib
->dump_fh
) {
1356 ret
= pos
= priv
->cfg
->ops
->lib
->dump_fh(priv
, &buf
, true);
1358 ret
= simple_read_from_buffer(user_buf
,
1359 count
, ppos
, buf
, pos
);
1367 static ssize_t
iwl_dbgfs_missed_beacon_read(struct file
*file
,
1368 char __user
*user_buf
,
1369 size_t count
, loff_t
*ppos
) {
1371 struct iwl_priv
*priv
= file
->private_data
;
1374 const size_t bufsz
= sizeof(buf
);
1376 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%d\n",
1377 priv
->missed_beacon_threshold
);
1379 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1382 static ssize_t
iwl_dbgfs_missed_beacon_write(struct file
*file
,
1383 const char __user
*user_buf
,
1384 size_t count
, loff_t
*ppos
)
1386 struct iwl_priv
*priv
= file
->private_data
;
1391 memset(buf
, 0, sizeof(buf
));
1392 buf_size
= min(count
, sizeof(buf
) - 1);
1393 if (copy_from_user(buf
, user_buf
, buf_size
))
1395 if (sscanf(buf
, "%d", &missed
) != 1)
1398 if (missed
< IWL_MISSED_BEACON_THRESHOLD_MIN
||
1399 missed
> IWL_MISSED_BEACON_THRESHOLD_MAX
)
1400 priv
->missed_beacon_threshold
=
1401 IWL_MISSED_BEACON_THRESHOLD_DEF
;
1403 priv
->missed_beacon_threshold
= missed
;
1408 static ssize_t
iwl_dbgfs_plcp_delta_read(struct file
*file
,
1409 char __user
*user_buf
,
1410 size_t count
, loff_t
*ppos
) {
1412 struct iwl_priv
*priv
= file
->private_data
;
1415 const size_t bufsz
= sizeof(buf
);
1417 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%u\n",
1418 priv
->cfg
->plcp_delta_threshold
);
1420 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1423 static ssize_t
iwl_dbgfs_plcp_delta_write(struct file
*file
,
1424 const char __user
*user_buf
,
1425 size_t count
, loff_t
*ppos
) {
1427 struct iwl_priv
*priv
= file
->private_data
;
1432 memset(buf
, 0, sizeof(buf
));
1433 buf_size
= min(count
, sizeof(buf
) - 1);
1434 if (copy_from_user(buf
, user_buf
, buf_size
))
1436 if (sscanf(buf
, "%d", &plcp
) != 1)
1438 if ((plcp
< IWL_MAX_PLCP_ERR_THRESHOLD_MIN
) ||
1439 (plcp
> IWL_MAX_PLCP_ERR_THRESHOLD_MAX
))
1440 priv
->cfg
->plcp_delta_threshold
=
1441 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE
;
1443 priv
->cfg
->plcp_delta_threshold
= plcp
;
1447 static ssize_t
iwl_dbgfs_force_reset_read(struct file
*file
,
1448 char __user
*user_buf
,
1449 size_t count
, loff_t
*ppos
) {
1451 struct iwl_priv
*priv
= file
->private_data
;
1454 const size_t bufsz
= sizeof(buf
);
1455 struct iwl_force_reset
*force_reset
;
1457 for (i
= 0; i
< IWL_MAX_FORCE_RESET
; i
++) {
1458 force_reset
= &priv
->force_reset
[i
];
1459 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1460 "Force reset method %d\n", i
);
1461 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1462 "\tnumber of reset request: %d\n",
1463 force_reset
->reset_request_count
);
1464 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1465 "\tnumber of reset request success: %d\n",
1466 force_reset
->reset_success_count
);
1467 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1468 "\tnumber of reset request reject: %d\n",
1469 force_reset
->reset_reject_count
);
1470 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1471 "\treset duration: %lu\n",
1472 force_reset
->reset_duration
);
1474 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1477 static ssize_t
iwl_dbgfs_force_reset_write(struct file
*file
,
1478 const char __user
*user_buf
,
1479 size_t count
, loff_t
*ppos
) {
1481 struct iwl_priv
*priv
= file
->private_data
;
1486 memset(buf
, 0, sizeof(buf
));
1487 buf_size
= min(count
, sizeof(buf
) - 1);
1488 if (copy_from_user(buf
, user_buf
, buf_size
))
1490 if (sscanf(buf
, "%d", &reset
) != 1)
1495 ret
= iwl_force_reset(priv
, reset
, true);
1500 return ret
? ret
: count
;
1503 static ssize_t
iwl_dbgfs_txfifo_flush_write(struct file
*file
,
1504 const char __user
*user_buf
,
1505 size_t count
, loff_t
*ppos
) {
1507 struct iwl_priv
*priv
= file
->private_data
;
1512 memset(buf
, 0, sizeof(buf
));
1513 buf_size
= min(count
, sizeof(buf
) - 1);
1514 if (copy_from_user(buf
, user_buf
, buf_size
))
1516 if (sscanf(buf
, "%d", &flush
) != 1)
1519 if (iwl_is_rfkill(priv
))
1522 priv
->cfg
->ops
->lib
->dev_txfifo_flush(priv
, IWL_DROP_ALL
);
1527 static ssize_t
iwl_dbgfs_ucode_bt_stats_read(struct file
*file
,
1528 char __user
*user_buf
,
1529 size_t count
, loff_t
*ppos
)
1531 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1533 return priv
->cfg
->ops
->lib
->debugfs_ops
.bt_stats_read(file
,
1534 user_buf
, count
, ppos
);
1537 static ssize_t
iwl_dbgfs_monitor_period_write(struct file
*file
,
1538 const char __user
*user_buf
,
1539 size_t count
, loff_t
*ppos
) {
1541 struct iwl_priv
*priv
= file
->private_data
;
1546 memset(buf
, 0, sizeof(buf
));
1547 buf_size
= min(count
, sizeof(buf
) - 1);
1548 if (copy_from_user(buf
, user_buf
, buf_size
))
1550 if (sscanf(buf
, "%d", &period
) != 1)
1552 if (period
< 0 || period
> IWL_MAX_MONITORING_PERIOD
)
1553 priv
->cfg
->monitor_recover_period
= IWL_DEF_MONITORING_PERIOD
;
1555 priv
->cfg
->monitor_recover_period
= period
;
1557 if (priv
->cfg
->monitor_recover_period
)
1558 mod_timer(&priv
->monitor_recover
, jiffies
+ msecs_to_jiffies(
1559 priv
->cfg
->monitor_recover_period
));
1561 del_timer_sync(&priv
->monitor_recover
);
1565 static ssize_t
iwl_dbgfs_bt_traffic_read(struct file
*file
,
1566 char __user
*user_buf
,
1567 size_t count
, loff_t
*ppos
) {
1569 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1572 const size_t bufsz
= sizeof(buf
);
1575 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "BT in %s mode\n",
1576 priv
->bt_full_concurrent
? "full concurrency" : "3-wire");
1577 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "BT status: %s, "
1578 "last traffic notif: %d\n",
1579 priv
->bt_status
? "On" : "Off", priv
->notif_bt_traffic_load
);
1580 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "ch_announcement: %d, "
1581 "sco_active: %d, kill_ack_mask: %x, "
1582 "kill_cts_mask: %x\n",
1583 priv
->bt_ch_announce
, priv
->bt_sco_active
,
1584 priv
->kill_ack_mask
, priv
->kill_cts_mask
);
1586 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "bluetooth traffic load: ");
1587 switch (priv
->bt_traffic_load
) {
1588 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS
:
1589 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Continuous\n");
1591 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH
:
1592 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "High\n");
1594 case IWL_BT_COEX_TRAFFIC_LOAD_LOW
:
1595 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Low\n");
1597 case IWL_BT_COEX_TRAFFIC_LOAD_NONE
:
1599 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "None\n");
1603 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1607 static ssize_t
iwl_dbgfs_protection_mode_read(struct file
*file
,
1608 char __user
*user_buf
,
1609 size_t count
, loff_t
*ppos
)
1611 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1615 const size_t bufsz
= sizeof(buf
);
1617 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "use %s for aggregation\n",
1618 (priv
->cfg
->use_rts_for_aggregation
) ? "rts/cts" :
1620 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1623 static ssize_t
iwl_dbgfs_protection_mode_write(struct file
*file
,
1624 const char __user
*user_buf
,
1625 size_t count
, loff_t
*ppos
) {
1627 struct iwl_priv
*priv
= file
->private_data
;
1632 memset(buf
, 0, sizeof(buf
));
1633 buf_size
= min(count
, sizeof(buf
) - 1);
1634 if (copy_from_user(buf
, user_buf
, buf_size
))
1636 if (sscanf(buf
, "%d", &rts
) != 1)
1639 priv
->cfg
->use_rts_for_aggregation
= true;
1641 priv
->cfg
->use_rts_for_aggregation
= false;
1645 static ssize_t
iwl_dbgfs_reply_tx_error_read(struct file
*file
,
1646 char __user
*user_buf
,
1647 size_t count
, loff_t
*ppos
)
1649 struct iwl_priv
*priv
= file
->private_data
;
1651 if (priv
->cfg
->ops
->lib
->debugfs_ops
.reply_tx_error
)
1652 return priv
->cfg
->ops
->lib
->debugfs_ops
.reply_tx_error(
1653 file
, user_buf
, count
, ppos
);
1657 DEBUGFS_READ_FILE_OPS(rx_statistics
);
1658 DEBUGFS_READ_FILE_OPS(tx_statistics
);
1659 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log
);
1660 DEBUGFS_READ_FILE_OPS(rx_queue
);
1661 DEBUGFS_READ_FILE_OPS(tx_queue
);
1662 DEBUGFS_READ_FILE_OPS(ucode_rx_stats
);
1663 DEBUGFS_READ_FILE_OPS(ucode_tx_stats
);
1664 DEBUGFS_READ_FILE_OPS(ucode_general_stats
);
1665 DEBUGFS_READ_FILE_OPS(sensitivity
);
1666 DEBUGFS_READ_FILE_OPS(chain_noise
);
1667 DEBUGFS_READ_FILE_OPS(power_save_status
);
1668 DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics
);
1669 DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics
);
1670 DEBUGFS_WRITE_FILE_OPS(csr
);
1671 DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing
);
1672 DEBUGFS_READ_FILE_OPS(fh_reg
);
1673 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon
);
1674 DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta
);
1675 DEBUGFS_READ_WRITE_FILE_OPS(force_reset
);
1676 DEBUGFS_READ_FILE_OPS(rxon_flags
);
1677 DEBUGFS_READ_FILE_OPS(rxon_filter_flags
);
1678 DEBUGFS_WRITE_FILE_OPS(txfifo_flush
);
1679 DEBUGFS_READ_FILE_OPS(ucode_bt_stats
);
1680 DEBUGFS_WRITE_FILE_OPS(monitor_period
);
1681 DEBUGFS_READ_FILE_OPS(bt_traffic
);
1682 DEBUGFS_READ_WRITE_FILE_OPS(protection_mode
);
1683 DEBUGFS_READ_FILE_OPS(reply_tx_error
);
1686 * Create the debugfs files and directories
1689 int iwl_dbgfs_register(struct iwl_priv
*priv
, const char *name
)
1691 struct dentry
*phyd
= priv
->hw
->wiphy
->debugfsdir
;
1692 struct dentry
*dir_drv
, *dir_data
, *dir_rf
, *dir_debug
;
1694 dir_drv
= debugfs_create_dir(name
, phyd
);
1698 priv
->debugfs_dir
= dir_drv
;
1700 dir_data
= debugfs_create_dir("data", dir_drv
);
1703 dir_rf
= debugfs_create_dir("rf", dir_drv
);
1706 dir_debug
= debugfs_create_dir("debug", dir_drv
);
1710 DEBUGFS_ADD_FILE(nvm
, dir_data
, S_IRUSR
);
1711 DEBUGFS_ADD_FILE(sram
, dir_data
, S_IWUSR
| S_IRUSR
);
1712 DEBUGFS_ADD_FILE(log_event
, dir_data
, S_IWUSR
| S_IRUSR
);
1713 DEBUGFS_ADD_FILE(stations
, dir_data
, S_IRUSR
);
1714 DEBUGFS_ADD_FILE(channels
, dir_data
, S_IRUSR
);
1715 DEBUGFS_ADD_FILE(status
, dir_data
, S_IRUSR
);
1716 DEBUGFS_ADD_FILE(interrupt
, dir_data
, S_IWUSR
| S_IRUSR
);
1717 DEBUGFS_ADD_FILE(qos
, dir_data
, S_IRUSR
);
1718 DEBUGFS_ADD_FILE(led
, dir_data
, S_IRUSR
);
1719 if (!priv
->cfg
->broken_powersave
) {
1720 DEBUGFS_ADD_FILE(sleep_level_override
, dir_data
,
1722 DEBUGFS_ADD_FILE(current_sleep_command
, dir_data
, S_IRUSR
);
1724 DEBUGFS_ADD_FILE(thermal_throttling
, dir_data
, S_IRUSR
);
1725 DEBUGFS_ADD_FILE(disable_ht40
, dir_data
, S_IWUSR
| S_IRUSR
);
1726 DEBUGFS_ADD_FILE(rx_statistics
, dir_debug
, S_IRUSR
);
1727 DEBUGFS_ADD_FILE(tx_statistics
, dir_debug
, S_IRUSR
);
1728 DEBUGFS_ADD_FILE(traffic_log
, dir_debug
, S_IWUSR
| S_IRUSR
);
1729 DEBUGFS_ADD_FILE(rx_queue
, dir_debug
, S_IRUSR
);
1730 DEBUGFS_ADD_FILE(tx_queue
, dir_debug
, S_IRUSR
);
1731 DEBUGFS_ADD_FILE(power_save_status
, dir_debug
, S_IRUSR
);
1732 DEBUGFS_ADD_FILE(clear_ucode_statistics
, dir_debug
, S_IWUSR
);
1733 DEBUGFS_ADD_FILE(clear_traffic_statistics
, dir_debug
, S_IWUSR
);
1734 DEBUGFS_ADD_FILE(csr
, dir_debug
, S_IWUSR
);
1735 DEBUGFS_ADD_FILE(fh_reg
, dir_debug
, S_IRUSR
);
1736 DEBUGFS_ADD_FILE(missed_beacon
, dir_debug
, S_IWUSR
);
1737 DEBUGFS_ADD_FILE(plcp_delta
, dir_debug
, S_IWUSR
| S_IRUSR
);
1738 DEBUGFS_ADD_FILE(force_reset
, dir_debug
, S_IWUSR
| S_IRUSR
);
1739 DEBUGFS_ADD_FILE(ucode_rx_stats
, dir_debug
, S_IRUSR
);
1740 DEBUGFS_ADD_FILE(ucode_tx_stats
, dir_debug
, S_IRUSR
);
1741 DEBUGFS_ADD_FILE(ucode_general_stats
, dir_debug
, S_IRUSR
);
1742 if (priv
->cfg
->ops
->lib
->dev_txfifo_flush
)
1743 DEBUGFS_ADD_FILE(txfifo_flush
, dir_debug
, S_IWUSR
);
1744 DEBUGFS_ADD_FILE(protection_mode
, dir_debug
, S_IWUSR
| S_IRUSR
);
1746 if (priv
->cfg
->sensitivity_calib_by_driver
)
1747 DEBUGFS_ADD_FILE(sensitivity
, dir_debug
, S_IRUSR
);
1748 if (priv
->cfg
->chain_noise_calib_by_driver
)
1749 DEBUGFS_ADD_FILE(chain_noise
, dir_debug
, S_IRUSR
);
1750 if (priv
->cfg
->ucode_tracing
)
1751 DEBUGFS_ADD_FILE(ucode_tracing
, dir_debug
, S_IWUSR
| S_IRUSR
);
1752 if (priv
->cfg
->bt_statistics
)
1753 DEBUGFS_ADD_FILE(ucode_bt_stats
, dir_debug
, S_IRUSR
);
1754 DEBUGFS_ADD_FILE(reply_tx_error
, dir_debug
, S_IRUSR
);
1755 DEBUGFS_ADD_FILE(rxon_flags
, dir_debug
, S_IWUSR
);
1756 DEBUGFS_ADD_FILE(rxon_filter_flags
, dir_debug
, S_IWUSR
);
1757 DEBUGFS_ADD_FILE(monitor_period
, dir_debug
, S_IWUSR
);
1758 if (priv
->cfg
->advanced_bt_coexist
)
1759 DEBUGFS_ADD_FILE(bt_traffic
, dir_debug
, S_IRUSR
);
1760 if (priv
->cfg
->sensitivity_calib_by_driver
)
1761 DEBUGFS_ADD_BOOL(disable_sensitivity
, dir_rf
,
1762 &priv
->disable_sens_cal
);
1763 if (priv
->cfg
->chain_noise_calib_by_driver
)
1764 DEBUGFS_ADD_BOOL(disable_chain_noise
, dir_rf
,
1765 &priv
->disable_chain_noise_cal
);
1766 if (priv
->cfg
->tx_power_by_driver
)
1767 DEBUGFS_ADD_BOOL(disable_tx_power
, dir_rf
,
1768 &priv
->disable_tx_power_cal
);
1772 IWL_ERR(priv
, "Can't create the debugfs directory\n");
1773 iwl_dbgfs_unregister(priv
);
1776 EXPORT_SYMBOL(iwl_dbgfs_register
);
1779 * Remove the debugfs files and directories
1782 void iwl_dbgfs_unregister(struct iwl_priv
*priv
)
1784 if (!priv
->debugfs_dir
)
1787 debugfs_remove_recursive(priv
->debugfs_dir
);
1788 priv
->debugfs_dir
= NULL
;
1790 EXPORT_SYMBOL(iwl_dbgfs_unregister
);