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 *****************************************************************************/
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"
43 /* create and remove of files */
44 #define DEBUGFS_ADD_FILE(name, parent, mode) do { \
45 if (!debugfs_create_file(#name, mode, parent, priv, \
46 &iwl_dbgfs_##name##_ops)) \
50 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
51 struct dentry *__tmp; \
52 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
54 if (IS_ERR(__tmp) || !__tmp) \
58 #define DEBUGFS_ADD_X32(name, parent, ptr) do { \
59 struct dentry *__tmp; \
60 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
62 if (IS_ERR(__tmp) || !__tmp) \
67 #define DEBUGFS_READ_FUNC(name) \
68 static ssize_t iwl_dbgfs_##name##_read(struct file *file, \
69 char __user *user_buf, \
70 size_t count, loff_t *ppos);
72 #define DEBUGFS_WRITE_FUNC(name) \
73 static ssize_t iwl_dbgfs_##name##_write(struct file *file, \
74 const char __user *user_buf, \
75 size_t count, loff_t *ppos);
78 static int iwl_dbgfs_open_file_generic(struct inode
*inode
, struct file
*file
)
80 file
->private_data
= inode
->i_private
;
84 #define DEBUGFS_READ_FILE_OPS(name) \
85 DEBUGFS_READ_FUNC(name); \
86 static const struct file_operations iwl_dbgfs_##name##_ops = { \
87 .read = iwl_dbgfs_##name##_read, \
88 .open = iwl_dbgfs_open_file_generic, \
89 .llseek = generic_file_llseek, \
92 #define DEBUGFS_WRITE_FILE_OPS(name) \
93 DEBUGFS_WRITE_FUNC(name); \
94 static const struct file_operations iwl_dbgfs_##name##_ops = { \
95 .write = iwl_dbgfs_##name##_write, \
96 .open = iwl_dbgfs_open_file_generic, \
97 .llseek = generic_file_llseek, \
101 #define DEBUGFS_READ_WRITE_FILE_OPS(name) \
102 DEBUGFS_READ_FUNC(name); \
103 DEBUGFS_WRITE_FUNC(name); \
104 static const struct file_operations iwl_dbgfs_##name##_ops = { \
105 .write = iwl_dbgfs_##name##_write, \
106 .read = iwl_dbgfs_##name##_read, \
107 .open = iwl_dbgfs_open_file_generic, \
108 .llseek = generic_file_llseek, \
111 static ssize_t
iwl_dbgfs_tx_statistics_read(struct file
*file
,
112 char __user
*user_buf
,
113 size_t count
, loff_t
*ppos
) {
115 struct iwl_priv
*priv
= file
->private_data
;
121 const size_t bufsz
= 100 +
122 sizeof(char) * 50 * (MANAGEMENT_MAX
+ CONTROL_MAX
);
123 buf
= kzalloc(bufsz
, GFP_KERNEL
);
126 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Management:\n");
127 for (cnt
= 0; cnt
< MANAGEMENT_MAX
; cnt
++) {
128 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
130 get_mgmt_string(cnt
),
131 priv
->tx_stats
.mgmt
[cnt
]);
133 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Control\n");
134 for (cnt
= 0; cnt
< CONTROL_MAX
; cnt
++) {
135 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
137 get_ctrl_string(cnt
),
138 priv
->tx_stats
.ctrl
[cnt
]);
140 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Data:\n");
141 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tcnt: %u\n",
142 priv
->tx_stats
.data_cnt
);
143 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tbytes: %llu\n",
144 priv
->tx_stats
.data_bytes
);
145 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
150 static ssize_t
iwl_dbgfs_clear_traffic_statistics_write(struct file
*file
,
151 const char __user
*user_buf
,
152 size_t count
, loff_t
*ppos
)
154 struct iwl_priv
*priv
= file
->private_data
;
159 memset(buf
, 0, sizeof(buf
));
160 buf_size
= min(count
, sizeof(buf
) - 1);
161 if (copy_from_user(buf
, user_buf
, buf_size
))
163 if (sscanf(buf
, "%x", &clear_flag
) != 1)
165 iwl_clear_traffic_stats(priv
);
170 static ssize_t
iwl_dbgfs_rx_statistics_read(struct file
*file
,
171 char __user
*user_buf
,
172 size_t count
, loff_t
*ppos
) {
174 struct iwl_priv
*priv
= file
->private_data
;
179 const size_t bufsz
= 100 +
180 sizeof(char) * 50 * (MANAGEMENT_MAX
+ CONTROL_MAX
);
181 buf
= kzalloc(bufsz
, GFP_KERNEL
);
185 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Management:\n");
186 for (cnt
= 0; cnt
< MANAGEMENT_MAX
; cnt
++) {
187 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
189 get_mgmt_string(cnt
),
190 priv
->rx_stats
.mgmt
[cnt
]);
192 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Control:\n");
193 for (cnt
= 0; cnt
< CONTROL_MAX
; cnt
++) {
194 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
196 get_ctrl_string(cnt
),
197 priv
->rx_stats
.ctrl
[cnt
]);
199 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Data:\n");
200 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tcnt: %u\n",
201 priv
->rx_stats
.data_cnt
);
202 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tbytes: %llu\n",
203 priv
->rx_stats
.data_bytes
);
205 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
210 static ssize_t
iwl_dbgfs_sram_read(struct file
*file
,
211 char __user
*user_buf
,
212 size_t count
, loff_t
*ppos
)
218 bool device_format
= false;
223 struct iwl_priv
*priv
= file
->private_data
;
226 /* default is to dump the entire data segment */
227 if (!priv
->dbgfs_sram_offset
&& !priv
->dbgfs_sram_len
) {
228 priv
->dbgfs_sram_offset
= 0x800000;
229 if (priv
->ucode_type
== UCODE_SUBTYPE_INIT
)
230 priv
->dbgfs_sram_len
= priv
->ucode_init_data
.len
;
232 priv
->dbgfs_sram_len
= priv
->ucode_data
.len
;
234 len
= priv
->dbgfs_sram_len
;
237 device_format
= true;
241 bufsz
= 50 + len
* 4;
242 buf
= kmalloc(bufsz
, GFP_KERNEL
);
246 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "sram_len: 0x%x\n",
248 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "sram_offset: 0x%x\n",
249 priv
->dbgfs_sram_offset
);
251 /* adjust sram address since reads are only on even u32 boundaries */
252 offset
= priv
->dbgfs_sram_offset
& 0x3;
253 sram
= priv
->dbgfs_sram_offset
& ~0x3;
255 /* read the first u32 from sram */
256 val
= iwl_read_targ_mem(priv
, sram
);
259 /* put the address at the start of every line */
261 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
262 "%08X: ", sram
+ offset
);
265 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
266 "%02x", (val
>> (8 * (3 - offset
))) & 0xff);
268 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
269 "%02x ", (val
>> (8 * offset
)) & 0xff);
271 /* if all bytes processed, read the next u32 from sram */
275 val
= iwl_read_targ_mem(priv
, sram
);
278 /* put in extra spaces and split lines for human readability */
281 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
282 } else if (!(i
& 7)) {
283 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " ");
284 } else if (!(i
& 3)) {
285 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " ");
289 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
291 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
296 static ssize_t
iwl_dbgfs_sram_write(struct file
*file
,
297 const char __user
*user_buf
,
298 size_t count
, loff_t
*ppos
)
300 struct iwl_priv
*priv
= file
->private_data
;
305 memset(buf
, 0, sizeof(buf
));
306 buf_size
= min(count
, sizeof(buf
) - 1);
307 if (copy_from_user(buf
, user_buf
, buf_size
))
310 if (sscanf(buf
, "%x,%x", &offset
, &len
) == 2) {
311 priv
->dbgfs_sram_offset
= offset
;
312 priv
->dbgfs_sram_len
= len
;
313 } else if (sscanf(buf
, "%x", &offset
) == 1) {
314 priv
->dbgfs_sram_offset
= offset
;
315 priv
->dbgfs_sram_len
= -4;
317 priv
->dbgfs_sram_offset
= 0;
318 priv
->dbgfs_sram_len
= 0;
324 static ssize_t
iwl_dbgfs_stations_read(struct file
*file
, char __user
*user_buf
,
325 size_t count
, loff_t
*ppos
)
327 struct iwl_priv
*priv
= file
->private_data
;
328 struct iwl_station_entry
*station
;
329 int max_sta
= priv
->hw_params
.max_stations
;
333 /* Add 30 for initial string */
334 const size_t bufsz
= 30 + sizeof(char) * 500 * (priv
->num_stations
);
336 buf
= kmalloc(bufsz
, GFP_KERNEL
);
340 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "num of stations: %d\n\n",
343 for (i
= 0; i
< max_sta
; i
++) {
344 station
= &priv
->stations
[i
];
347 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
348 "station %d - addr: %pM, flags: %#x\n",
349 i
, station
->sta
.sta
.addr
,
350 station
->sta
.station_flags_msk
);
351 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
352 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
353 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
354 "start_idx\tbitmap\t\t\trate_n_flags\n");
356 for (j
= 0; j
< MAX_TID_COUNT
; j
++) {
357 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
358 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
359 j
, station
->tid
[j
].seq_number
,
360 station
->tid
[j
].agg
.txq_id
,
361 station
->tid
[j
].agg
.frame_count
,
362 station
->tid
[j
].tfds_in_queue
,
363 station
->tid
[j
].agg
.start_idx
,
364 station
->tid
[j
].agg
.bitmap
,
365 station
->tid
[j
].agg
.rate_n_flags
);
367 if (station
->tid
[j
].agg
.wait_for_ba
)
368 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
370 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
373 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
376 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
381 static ssize_t
iwl_dbgfs_nvm_read(struct file
*file
,
382 char __user
*user_buf
,
387 struct iwl_priv
*priv
= file
->private_data
;
388 int pos
= 0, ofs
= 0, buf_size
= 0;
392 size_t eeprom_len
= priv
->cfg
->base_params
->eeprom_size
;
393 buf_size
= 4 * eeprom_len
+ 256;
395 if (eeprom_len
% 16) {
396 IWL_ERR(priv
, "NVM size is not multiple of 16.\n");
402 IWL_ERR(priv
, "Invalid EEPROM/OTP memory\n");
406 /* 4 characters for byte 0xYY */
407 buf
= kzalloc(buf_size
, GFP_KERNEL
);
409 IWL_ERR(priv
, "Can not allocate Buffer\n");
412 eeprom_ver
= iwl_eeprom_query16(priv
, EEPROM_VERSION
);
413 pos
+= scnprintf(buf
+ pos
, buf_size
- pos
, "NVM Type: %s, "
415 (priv
->nvm_device_type
== NVM_DEVICE_TYPE_OTP
)
416 ? "OTP" : "EEPROM", eeprom_ver
);
417 for (ofs
= 0 ; ofs
< eeprom_len
; ofs
+= 16) {
418 pos
+= scnprintf(buf
+ pos
, buf_size
- pos
, "0x%.4x ", ofs
);
419 hex_dump_to_buffer(ptr
+ ofs
, 16 , 16, 2, buf
+ pos
,
421 pos
+= strlen(buf
+ pos
);
422 if (buf_size
- pos
> 0)
426 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
431 static ssize_t
iwl_dbgfs_log_event_read(struct file
*file
,
432 char __user
*user_buf
,
433 size_t count
, loff_t
*ppos
)
435 struct iwl_priv
*priv
= file
->private_data
;
438 ssize_t ret
= -ENOMEM
;
440 ret
= pos
= iwl_dump_nic_event_log(priv
, true, &buf
, true);
442 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
448 static ssize_t
iwl_dbgfs_log_event_write(struct file
*file
,
449 const char __user
*user_buf
,
450 size_t count
, loff_t
*ppos
)
452 struct iwl_priv
*priv
= file
->private_data
;
457 memset(buf
, 0, sizeof(buf
));
458 buf_size
= min(count
, sizeof(buf
) - 1);
459 if (copy_from_user(buf
, user_buf
, buf_size
))
461 if (sscanf(buf
, "%d", &event_log_flag
) != 1)
463 if (event_log_flag
== 1)
464 iwl_dump_nic_event_log(priv
, true, NULL
, false);
471 static ssize_t
iwl_dbgfs_channels_read(struct file
*file
, char __user
*user_buf
,
472 size_t count
, loff_t
*ppos
)
474 struct iwl_priv
*priv
= file
->private_data
;
475 struct ieee80211_channel
*channels
= NULL
;
476 const struct ieee80211_supported_band
*supp_band
= NULL
;
477 int pos
= 0, i
, bufsz
= PAGE_SIZE
;
481 if (!test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
))
484 buf
= kzalloc(bufsz
, GFP_KERNEL
);
486 IWL_ERR(priv
, "Can not allocate Buffer\n");
490 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_2GHZ
);
492 channels
= supp_band
->channels
;
494 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
495 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
496 supp_band
->n_channels
);
498 for (i
= 0; i
< supp_band
->n_channels
; i
++)
499 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
500 "%d: %ddBm: BSS%s%s, %s.\n",
501 channels
[i
].hw_value
,
502 channels
[i
].max_power
,
503 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
504 " (IEEE 802.11h required)" : "",
505 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
506 || (channels
[i
].flags
&
507 IEEE80211_CHAN_RADAR
)) ? "" :
510 IEEE80211_CHAN_PASSIVE_SCAN
?
511 "passive only" : "active/passive");
513 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_5GHZ
);
515 channels
= supp_band
->channels
;
517 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
518 "Displaying %d channels in 5.2GHz band (802.11a)\n",
519 supp_band
->n_channels
);
521 for (i
= 0; i
< supp_band
->n_channels
; i
++)
522 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
523 "%d: %ddBm: BSS%s%s, %s.\n",
524 channels
[i
].hw_value
,
525 channels
[i
].max_power
,
526 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
527 " (IEEE 802.11h required)" : "",
528 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
529 || (channels
[i
].flags
&
530 IEEE80211_CHAN_RADAR
)) ? "" :
533 IEEE80211_CHAN_PASSIVE_SCAN
?
534 "passive only" : "active/passive");
536 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
541 static ssize_t
iwl_dbgfs_status_read(struct file
*file
,
542 char __user
*user_buf
,
543 size_t count
, loff_t
*ppos
) {
545 struct iwl_priv
*priv
= file
->private_data
;
548 const size_t bufsz
= sizeof(buf
);
550 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_HCMD_ACTIVE:\t %d\n",
551 test_bit(STATUS_HCMD_ACTIVE
, &priv
->status
));
552 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INT_ENABLED:\t %d\n",
553 test_bit(STATUS_INT_ENABLED
, &priv
->status
));
554 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_RF_KILL_HW:\t %d\n",
555 test_bit(STATUS_RF_KILL_HW
, &priv
->status
));
556 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_CT_KILL:\t\t %d\n",
557 test_bit(STATUS_CT_KILL
, &priv
->status
));
558 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INIT:\t\t %d\n",
559 test_bit(STATUS_INIT
, &priv
->status
));
560 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_ALIVE:\t\t %d\n",
561 test_bit(STATUS_ALIVE
, &priv
->status
));
562 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_READY:\t\t %d\n",
563 test_bit(STATUS_READY
, &priv
->status
));
564 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_TEMPERATURE:\t %d\n",
565 test_bit(STATUS_TEMPERATURE
, &priv
->status
));
566 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_GEO_CONFIGURED:\t %d\n",
567 test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
));
568 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_EXIT_PENDING:\t %d\n",
569 test_bit(STATUS_EXIT_PENDING
, &priv
->status
));
570 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_STATISTICS:\t %d\n",
571 test_bit(STATUS_STATISTICS
, &priv
->status
));
572 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCANNING:\t %d\n",
573 test_bit(STATUS_SCANNING
, &priv
->status
));
574 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_ABORTING:\t %d\n",
575 test_bit(STATUS_SCAN_ABORTING
, &priv
->status
));
576 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_HW:\t\t %d\n",
577 test_bit(STATUS_SCAN_HW
, &priv
->status
));
578 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_POWER_PMI:\t %d\n",
579 test_bit(STATUS_POWER_PMI
, &priv
->status
));
580 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_FW_ERROR:\t %d\n",
581 test_bit(STATUS_FW_ERROR
, &priv
->status
));
582 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
585 static ssize_t
iwl_dbgfs_interrupt_read(struct file
*file
,
586 char __user
*user_buf
,
587 size_t count
, loff_t
*ppos
) {
589 struct iwl_priv
*priv
= file
->private_data
;
593 int bufsz
= 24 * 64; /* 24 items * 64 char per item */
596 buf
= kzalloc(bufsz
, GFP_KERNEL
);
598 IWL_ERR(priv
, "Can not allocate Buffer\n");
602 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
603 "Interrupt Statistics Report:\n");
605 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "HW Error:\t\t\t %u\n",
607 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "SW Error:\t\t\t %u\n",
609 if (priv
->isr_stats
.sw
|| priv
->isr_stats
.hw
) {
610 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
611 "\tLast Restarting Code: 0x%X\n",
612 priv
->isr_stats
.err_code
);
614 #ifdef CONFIG_IWLWIFI_DEBUG
615 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Frame transmitted:\t\t %u\n",
616 priv
->isr_stats
.sch
);
617 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Alive interrupt:\t\t %u\n",
618 priv
->isr_stats
.alive
);
620 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
621 "HW RF KILL switch toggled:\t %u\n",
622 priv
->isr_stats
.rfkill
);
624 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "CT KILL:\t\t\t %u\n",
625 priv
->isr_stats
.ctkill
);
627 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Wakeup Interrupt:\t\t %u\n",
628 priv
->isr_stats
.wakeup
);
630 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
631 "Rx command responses:\t\t %u\n",
633 for (cnt
= 0; cnt
< REPLY_MAX
; cnt
++) {
634 if (priv
->isr_stats
.rx_handlers
[cnt
] > 0)
635 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
636 "\tRx handler[%36s]:\t\t %u\n",
638 priv
->isr_stats
.rx_handlers
[cnt
]);
641 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx/FH interrupt:\t\t %u\n",
644 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Unexpected INTA:\t\t %u\n",
645 priv
->isr_stats
.unhandled
);
647 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
652 static ssize_t
iwl_dbgfs_interrupt_write(struct file
*file
,
653 const char __user
*user_buf
,
654 size_t count
, loff_t
*ppos
)
656 struct iwl_priv
*priv
= file
->private_data
;
661 memset(buf
, 0, sizeof(buf
));
662 buf_size
= min(count
, sizeof(buf
) - 1);
663 if (copy_from_user(buf
, user_buf
, buf_size
))
665 if (sscanf(buf
, "%x", &reset_flag
) != 1)
668 iwl_clear_isr_stats(priv
);
673 static ssize_t
iwl_dbgfs_qos_read(struct file
*file
, char __user
*user_buf
,
674 size_t count
, loff_t
*ppos
)
676 struct iwl_priv
*priv
= file
->private_data
;
677 struct iwl_rxon_context
*ctx
;
679 char buf
[256 * NUM_IWL_RXON_CTX
];
680 const size_t bufsz
= sizeof(buf
);
682 for_each_context(priv
, ctx
) {
683 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "context %d:\n",
685 for (i
= 0; i
< AC_NUM
; i
++) {
686 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
687 "\tcw_min\tcw_max\taifsn\ttxop\n");
688 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
689 "AC[%d]\t%u\t%u\t%u\t%u\n", i
,
690 ctx
->qos_data
.def_qos_parm
.ac
[i
].cw_min
,
691 ctx
->qos_data
.def_qos_parm
.ac
[i
].cw_max
,
692 ctx
->qos_data
.def_qos_parm
.ac
[i
].aifsn
,
693 ctx
->qos_data
.def_qos_parm
.ac
[i
].edca_txop
);
695 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
697 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
700 static ssize_t
iwl_dbgfs_thermal_throttling_read(struct file
*file
,
701 char __user
*user_buf
,
702 size_t count
, loff_t
*ppos
)
704 struct iwl_priv
*priv
= file
->private_data
;
705 struct iwl_tt_mgmt
*tt
= &priv
->thermal_throttle
;
706 struct iwl_tt_restriction
*restriction
;
709 const size_t bufsz
= sizeof(buf
);
711 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
712 "Thermal Throttling Mode: %s\n",
713 tt
->advanced_tt
? "Advance" : "Legacy");
714 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
715 "Thermal Throttling State: %d\n",
717 if (tt
->advanced_tt
) {
718 restriction
= tt
->restriction
+ tt
->state
;
719 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
721 restriction
->tx_stream
);
722 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
724 restriction
->rx_stream
);
725 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
729 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
732 static ssize_t
iwl_dbgfs_disable_ht40_write(struct file
*file
,
733 const char __user
*user_buf
,
734 size_t count
, loff_t
*ppos
)
736 struct iwl_priv
*priv
= file
->private_data
;
741 memset(buf
, 0, sizeof(buf
));
742 buf_size
= min(count
, sizeof(buf
) - 1);
743 if (copy_from_user(buf
, user_buf
, buf_size
))
745 if (sscanf(buf
, "%d", &ht40
) != 1)
747 if (!iwl_is_any_associated(priv
))
748 priv
->disable_ht40
= ht40
? true : false;
750 IWL_ERR(priv
, "Sta associated with AP - "
751 "Change to 40MHz channel support is not allowed\n");
758 static ssize_t
iwl_dbgfs_disable_ht40_read(struct file
*file
,
759 char __user
*user_buf
,
760 size_t count
, loff_t
*ppos
)
762 struct iwl_priv
*priv
= file
->private_data
;
765 const size_t bufsz
= sizeof(buf
);
767 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
768 "11n 40MHz Mode: %s\n",
769 priv
->disable_ht40
? "Disabled" : "Enabled");
770 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
773 static ssize_t
iwl_dbgfs_sleep_level_override_write(struct file
*file
,
774 const char __user
*user_buf
,
775 size_t count
, loff_t
*ppos
)
777 struct iwl_priv
*priv
= file
->private_data
;
782 memset(buf
, 0, sizeof(buf
));
783 buf_size
= min(count
, sizeof(buf
) - 1);
784 if (copy_from_user(buf
, user_buf
, buf_size
))
787 if (sscanf(buf
, "%d", &value
) != 1)
791 * Our users expect 0 to be "CAM", but 0 isn't actually
792 * valid here. However, let's not confuse them and present
793 * IWL_POWER_INDEX_1 as "1", not "0".
800 if (value
!= -1 && (value
< 0 || value
>= IWL_POWER_NUM
))
803 if (!iwl_is_ready_rf(priv
))
806 priv
->power_data
.debug_sleep_level_override
= value
;
808 mutex_lock(&priv
->mutex
);
809 iwl_power_update_mode(priv
, true);
810 mutex_unlock(&priv
->mutex
);
815 static ssize_t
iwl_dbgfs_sleep_level_override_read(struct file
*file
,
816 char __user
*user_buf
,
817 size_t count
, loff_t
*ppos
)
819 struct iwl_priv
*priv
= file
->private_data
;
822 const size_t bufsz
= sizeof(buf
);
824 /* see the write function */
825 value
= priv
->power_data
.debug_sleep_level_override
;
829 pos
= scnprintf(buf
, bufsz
, "%d\n", value
);
830 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
833 static ssize_t
iwl_dbgfs_current_sleep_command_read(struct file
*file
,
834 char __user
*user_buf
,
835 size_t count
, loff_t
*ppos
)
837 struct iwl_priv
*priv
= file
->private_data
;
840 const size_t bufsz
= sizeof(buf
);
841 struct iwl_powertable_cmd
*cmd
= &priv
->power_data
.sleep_cmd
;
843 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
844 "flags: %#.2x\n", le16_to_cpu(cmd
->flags
));
845 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
846 "RX/TX timeout: %d/%d usec\n",
847 le32_to_cpu(cmd
->rx_data_timeout
),
848 le32_to_cpu(cmd
->tx_data_timeout
));
849 for (i
= 0; i
< IWL_POWER_VEC_SIZE
; i
++)
850 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
851 "sleep_interval[%d]: %d\n", i
,
852 le32_to_cpu(cmd
->sleep_interval
[i
]));
854 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
857 DEBUGFS_READ_WRITE_FILE_OPS(sram
);
858 DEBUGFS_READ_WRITE_FILE_OPS(log_event
);
859 DEBUGFS_READ_FILE_OPS(nvm
);
860 DEBUGFS_READ_FILE_OPS(stations
);
861 DEBUGFS_READ_FILE_OPS(channels
);
862 DEBUGFS_READ_FILE_OPS(status
);
863 DEBUGFS_READ_WRITE_FILE_OPS(interrupt
);
864 DEBUGFS_READ_FILE_OPS(qos
);
865 DEBUGFS_READ_FILE_OPS(thermal_throttling
);
866 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40
);
867 DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override
);
868 DEBUGFS_READ_FILE_OPS(current_sleep_command
);
870 static ssize_t
iwl_dbgfs_traffic_log_read(struct file
*file
,
871 char __user
*user_buf
,
872 size_t count
, loff_t
*ppos
)
874 struct iwl_priv
*priv
= file
->private_data
;
875 int pos
= 0, ofs
= 0;
877 struct iwl_tx_queue
*txq
;
879 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
881 int bufsz
= ((IWL_TRAFFIC_ENTRIES
* IWL_TRAFFIC_ENTRY_SIZE
* 64) * 2) +
882 (priv
->cfg
->base_params
->num_of_queues
* 32 * 8) + 400;
887 IWL_ERR(priv
, "txq not ready\n");
890 buf
= kzalloc(bufsz
, GFP_KERNEL
);
892 IWL_ERR(priv
, "Can not allocate buffer\n");
895 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx Queue\n");
896 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
897 txq
= &priv
->txq
[cnt
];
899 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
900 "q[%d]: read_ptr: %u, write_ptr: %u\n",
901 cnt
, q
->read_ptr
, q
->write_ptr
);
903 if (priv
->tx_traffic
&& (iwl_debug_level
& IWL_DL_TX
)) {
904 ptr
= priv
->tx_traffic
;
905 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
906 "Tx Traffic idx: %u\n", priv
->tx_traffic_idx
);
907 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
908 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
909 entry
++, ofs
+= 16) {
910 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
912 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
913 buf
+ pos
, bufsz
- pos
, 0);
914 pos
+= strlen(buf
+ pos
);
921 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Rx Queue\n");
922 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
923 "read: %u, write: %u\n",
924 rxq
->read
, rxq
->write
);
926 if (priv
->rx_traffic
&& (iwl_debug_level
& IWL_DL_RX
)) {
927 ptr
= priv
->rx_traffic
;
928 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
929 "Rx Traffic idx: %u\n", priv
->rx_traffic_idx
);
930 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
931 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
932 entry
++, ofs
+= 16) {
933 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
935 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
936 buf
+ pos
, bufsz
- pos
, 0);
937 pos
+= strlen(buf
+ pos
);
944 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
949 static ssize_t
iwl_dbgfs_traffic_log_write(struct file
*file
,
950 const char __user
*user_buf
,
951 size_t count
, loff_t
*ppos
)
953 struct iwl_priv
*priv
= file
->private_data
;
958 memset(buf
, 0, sizeof(buf
));
959 buf_size
= min(count
, sizeof(buf
) - 1);
960 if (copy_from_user(buf
, user_buf
, buf_size
))
962 if (sscanf(buf
, "%d", &traffic_log
) != 1)
964 if (traffic_log
== 0)
965 iwl_reset_traffic_log(priv
);
970 static ssize_t
iwl_dbgfs_tx_queue_read(struct file
*file
,
971 char __user
*user_buf
,
972 size_t count
, loff_t
*ppos
) {
974 struct iwl_priv
*priv
= file
->private_data
;
975 struct iwl_tx_queue
*txq
;
981 const size_t bufsz
= sizeof(char) * 64 *
982 priv
->cfg
->base_params
->num_of_queues
;
985 IWL_ERR(priv
, "txq not ready\n");
988 buf
= kzalloc(bufsz
, GFP_KERNEL
);
992 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
993 txq
= &priv
->txq
[cnt
];
995 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
996 "hwq %.2d: read=%u write=%u stop=%d"
997 " swq_id=%#.2x (ac %d/hwq %d)\n",
998 cnt
, q
->read_ptr
, q
->write_ptr
,
999 !!test_bit(cnt
, priv
->queue_stopped
),
1000 txq
->swq_id
, txq
->swq_id
& 3,
1001 (txq
->swq_id
>> 2) & 0x1f);
1004 /* for the ACs, display the stop count too */
1005 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1006 " stop-count: %d\n",
1007 atomic_read(&priv
->queue_stop_count
[cnt
]));
1009 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1014 static ssize_t
iwl_dbgfs_rx_queue_read(struct file
*file
,
1015 char __user
*user_buf
,
1016 size_t count
, loff_t
*ppos
) {
1018 struct iwl_priv
*priv
= file
->private_data
;
1019 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
1022 const size_t bufsz
= sizeof(buf
);
1024 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "read: %u\n",
1026 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "write: %u\n",
1028 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "free_count: %u\n",
1031 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "closed_rb_num: %u\n",
1032 le16_to_cpu(rxq
->rb_stts
->closed_rb_num
) & 0x0FFF);
1034 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1035 "closed_rb_num: Not Allocated\n");
1037 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1040 static ssize_t
iwl_dbgfs_ucode_rx_stats_read(struct file
*file
,
1041 char __user
*user_buf
,
1042 size_t count
, loff_t
*ppos
)
1044 struct iwl_priv
*priv
= file
->private_data
;
1045 return priv
->cfg
->ops
->lib
->debugfs_ops
.rx_stats_read(file
,
1046 user_buf
, count
, ppos
);
1049 static ssize_t
iwl_dbgfs_ucode_tx_stats_read(struct file
*file
,
1050 char __user
*user_buf
,
1051 size_t count
, loff_t
*ppos
)
1053 struct iwl_priv
*priv
= file
->private_data
;
1054 return priv
->cfg
->ops
->lib
->debugfs_ops
.tx_stats_read(file
,
1055 user_buf
, count
, ppos
);
1058 static ssize_t
iwl_dbgfs_ucode_general_stats_read(struct file
*file
,
1059 char __user
*user_buf
,
1060 size_t count
, loff_t
*ppos
)
1062 struct iwl_priv
*priv
= file
->private_data
;
1063 return priv
->cfg
->ops
->lib
->debugfs_ops
.general_stats_read(file
,
1064 user_buf
, count
, ppos
);
1067 static ssize_t
iwl_dbgfs_sensitivity_read(struct file
*file
,
1068 char __user
*user_buf
,
1069 size_t count
, loff_t
*ppos
) {
1071 struct iwl_priv
*priv
= file
->private_data
;
1075 int bufsz
= sizeof(struct iwl_sensitivity_data
) * 4 + 100;
1077 struct iwl_sensitivity_data
*data
;
1079 data
= &priv
->sensitivity_data
;
1080 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1082 IWL_ERR(priv
, "Can not allocate Buffer\n");
1086 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm:\t\t\t %u\n",
1087 data
->auto_corr_ofdm
);
1088 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1089 "auto_corr_ofdm_mrc:\t\t %u\n",
1090 data
->auto_corr_ofdm_mrc
);
1091 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm_x1:\t\t %u\n",
1092 data
->auto_corr_ofdm_x1
);
1093 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1094 "auto_corr_ofdm_mrc_x1:\t\t %u\n",
1095 data
->auto_corr_ofdm_mrc_x1
);
1096 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck:\t\t\t %u\n",
1097 data
->auto_corr_cck
);
1098 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck_mrc:\t\t %u\n",
1099 data
->auto_corr_cck_mrc
);
1100 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1101 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
1102 data
->last_bad_plcp_cnt_ofdm
);
1103 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_ofdm:\t\t %u\n",
1104 data
->last_fa_cnt_ofdm
);
1105 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1106 "last_bad_plcp_cnt_cck:\t\t %u\n",
1107 data
->last_bad_plcp_cnt_cck
);
1108 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_cck:\t\t %u\n",
1109 data
->last_fa_cnt_cck
);
1110 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_curr_state:\t\t\t %u\n",
1111 data
->nrg_curr_state
);
1112 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_prev_state:\t\t\t %u\n",
1113 data
->nrg_prev_state
);
1114 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_value:\t\t\t");
1115 for (cnt
= 0; cnt
< 10; cnt
++) {
1116 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1117 data
->nrg_value
[cnt
]);
1119 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1120 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_rssi:\t\t");
1121 for (cnt
= 0; cnt
< NRG_NUM_PREV_STAT_L
; cnt
++) {
1122 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1123 data
->nrg_silence_rssi
[cnt
]);
1125 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1126 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_ref:\t\t %u\n",
1127 data
->nrg_silence_ref
);
1128 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_energy_idx:\t\t\t %u\n",
1129 data
->nrg_energy_idx
);
1130 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_idx:\t\t %u\n",
1131 data
->nrg_silence_idx
);
1132 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_cck:\t\t\t %u\n",
1134 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1135 "nrg_auto_corr_silence_diff:\t %u\n",
1136 data
->nrg_auto_corr_silence_diff
);
1137 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "num_in_cck_no_fa:\t\t %u\n",
1138 data
->num_in_cck_no_fa
);
1139 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_ofdm:\t\t\t %u\n",
1142 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1148 static ssize_t
iwl_dbgfs_chain_noise_read(struct file
*file
,
1149 char __user
*user_buf
,
1150 size_t count
, loff_t
*ppos
) {
1152 struct iwl_priv
*priv
= file
->private_data
;
1156 int bufsz
= sizeof(struct iwl_chain_noise_data
) * 4 + 100;
1158 struct iwl_chain_noise_data
*data
;
1160 data
= &priv
->chain_noise_data
;
1161 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1163 IWL_ERR(priv
, "Can not allocate Buffer\n");
1167 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "active_chains:\t\t\t %u\n",
1168 data
->active_chains
);
1169 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_a:\t\t\t %u\n",
1170 data
->chain_noise_a
);
1171 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_b:\t\t\t %u\n",
1172 data
->chain_noise_b
);
1173 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_c:\t\t\t %u\n",
1174 data
->chain_noise_c
);
1175 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_a:\t\t\t %u\n",
1176 data
->chain_signal_a
);
1177 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_b:\t\t\t %u\n",
1178 data
->chain_signal_b
);
1179 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_c:\t\t\t %u\n",
1180 data
->chain_signal_c
);
1181 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "beacon_count:\t\t\t %u\n",
1182 data
->beacon_count
);
1184 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "disconn_array:\t\t\t");
1185 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1186 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1187 data
->disconn_array
[cnt
]);
1189 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1190 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "delta_gain_code:\t\t");
1191 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1192 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1193 data
->delta_gain_code
[cnt
]);
1195 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1196 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "radio_write:\t\t\t %u\n",
1198 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "state:\t\t\t\t %u\n",
1201 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1206 static ssize_t
iwl_dbgfs_power_save_status_read(struct file
*file
,
1207 char __user
*user_buf
,
1208 size_t count
, loff_t
*ppos
)
1210 struct iwl_priv
*priv
= file
->private_data
;
1213 const size_t bufsz
= sizeof(buf
);
1216 pwrsave_status
= iwl_read32(priv
, CSR_GP_CNTRL
) &
1217 CSR_GP_REG_POWER_SAVE_STATUS_MSK
;
1219 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Power Save Status: ");
1220 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%s\n",
1221 (pwrsave_status
== CSR_GP_REG_NO_POWER_SAVE
) ? "none" :
1222 (pwrsave_status
== CSR_GP_REG_MAC_POWER_SAVE
) ? "MAC" :
1223 (pwrsave_status
== CSR_GP_REG_PHY_POWER_SAVE
) ? "PHY" :
1226 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1229 static ssize_t
iwl_dbgfs_clear_ucode_statistics_write(struct file
*file
,
1230 const char __user
*user_buf
,
1231 size_t count
, loff_t
*ppos
)
1233 struct iwl_priv
*priv
= file
->private_data
;
1238 memset(buf
, 0, sizeof(buf
));
1239 buf_size
= min(count
, sizeof(buf
) - 1);
1240 if (copy_from_user(buf
, user_buf
, buf_size
))
1242 if (sscanf(buf
, "%d", &clear
) != 1)
1245 /* make request to uCode to retrieve statistics information */
1246 mutex_lock(&priv
->mutex
);
1247 iwl_send_statistics_request(priv
, CMD_SYNC
, true);
1248 mutex_unlock(&priv
->mutex
);
1253 static ssize_t
iwl_dbgfs_csr_write(struct file
*file
,
1254 const char __user
*user_buf
,
1255 size_t count
, loff_t
*ppos
)
1257 struct iwl_priv
*priv
= file
->private_data
;
1262 memset(buf
, 0, sizeof(buf
));
1263 buf_size
= min(count
, sizeof(buf
) - 1);
1264 if (copy_from_user(buf
, user_buf
, buf_size
))
1266 if (sscanf(buf
, "%d", &csr
) != 1)
1274 static ssize_t
iwl_dbgfs_ucode_tracing_read(struct file
*file
,
1275 char __user
*user_buf
,
1276 size_t count
, loff_t
*ppos
) {
1278 struct iwl_priv
*priv
= file
->private_data
;
1281 const size_t bufsz
= sizeof(buf
);
1283 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "ucode trace timer is %s\n",
1284 priv
->event_log
.ucode_trace
? "On" : "Off");
1285 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "non_wraps_count:\t\t %u\n",
1286 priv
->event_log
.non_wraps_count
);
1287 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "wraps_once_count:\t\t %u\n",
1288 priv
->event_log
.wraps_once_count
);
1289 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "wraps_more_count:\t\t %u\n",
1290 priv
->event_log
.wraps_more_count
);
1292 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1295 static ssize_t
iwl_dbgfs_ucode_tracing_write(struct file
*file
,
1296 const char __user
*user_buf
,
1297 size_t count
, loff_t
*ppos
)
1299 struct iwl_priv
*priv
= file
->private_data
;
1304 memset(buf
, 0, sizeof(buf
));
1305 buf_size
= min(count
, sizeof(buf
) - 1);
1306 if (copy_from_user(buf
, user_buf
, buf_size
))
1308 if (sscanf(buf
, "%d", &trace
) != 1)
1312 priv
->event_log
.ucode_trace
= true;
1313 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
1314 mod_timer(&priv
->ucode_trace
,
1315 jiffies
+ msecs_to_jiffies(UCODE_TRACE_PERIOD
));
1317 priv
->event_log
.ucode_trace
= false;
1318 del_timer_sync(&priv
->ucode_trace
);
1324 static ssize_t
iwl_dbgfs_rxon_flags_read(struct file
*file
,
1325 char __user
*user_buf
,
1326 size_t count
, loff_t
*ppos
) {
1328 struct iwl_priv
*priv
= file
->private_data
;
1332 len
= sprintf(buf
, "0x%04X\n",
1333 le32_to_cpu(priv
->contexts
[IWL_RXON_CTX_BSS
].active
.flags
));
1334 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1337 static ssize_t
iwl_dbgfs_rxon_filter_flags_read(struct file
*file
,
1338 char __user
*user_buf
,
1339 size_t count
, loff_t
*ppos
) {
1341 struct iwl_priv
*priv
= file
->private_data
;
1345 len
= sprintf(buf
, "0x%04X\n",
1346 le32_to_cpu(priv
->contexts
[IWL_RXON_CTX_BSS
].active
.filter_flags
));
1347 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1350 static ssize_t
iwl_dbgfs_fh_reg_read(struct file
*file
,
1351 char __user
*user_buf
,
1352 size_t count
, loff_t
*ppos
)
1354 struct iwl_priv
*priv
= file
->private_data
;
1357 ssize_t ret
= -EFAULT
;
1359 ret
= pos
= iwl_dump_fh(priv
, &buf
, true);
1361 ret
= simple_read_from_buffer(user_buf
,
1362 count
, ppos
, buf
, pos
);
1369 static ssize_t
iwl_dbgfs_missed_beacon_read(struct file
*file
,
1370 char __user
*user_buf
,
1371 size_t count
, loff_t
*ppos
) {
1373 struct iwl_priv
*priv
= file
->private_data
;
1376 const size_t bufsz
= sizeof(buf
);
1378 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%d\n",
1379 priv
->missed_beacon_threshold
);
1381 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1384 static ssize_t
iwl_dbgfs_missed_beacon_write(struct file
*file
,
1385 const char __user
*user_buf
,
1386 size_t count
, loff_t
*ppos
)
1388 struct iwl_priv
*priv
= file
->private_data
;
1393 memset(buf
, 0, sizeof(buf
));
1394 buf_size
= min(count
, sizeof(buf
) - 1);
1395 if (copy_from_user(buf
, user_buf
, buf_size
))
1397 if (sscanf(buf
, "%d", &missed
) != 1)
1400 if (missed
< IWL_MISSED_BEACON_THRESHOLD_MIN
||
1401 missed
> IWL_MISSED_BEACON_THRESHOLD_MAX
)
1402 priv
->missed_beacon_threshold
=
1403 IWL_MISSED_BEACON_THRESHOLD_DEF
;
1405 priv
->missed_beacon_threshold
= missed
;
1410 static ssize_t
iwl_dbgfs_plcp_delta_read(struct file
*file
,
1411 char __user
*user_buf
,
1412 size_t count
, loff_t
*ppos
) {
1414 struct iwl_priv
*priv
= file
->private_data
;
1417 const size_t bufsz
= sizeof(buf
);
1419 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%u\n",
1420 priv
->cfg
->base_params
->plcp_delta_threshold
);
1422 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1425 static ssize_t
iwl_dbgfs_plcp_delta_write(struct file
*file
,
1426 const char __user
*user_buf
,
1427 size_t count
, loff_t
*ppos
) {
1429 struct iwl_priv
*priv
= file
->private_data
;
1434 memset(buf
, 0, sizeof(buf
));
1435 buf_size
= min(count
, sizeof(buf
) - 1);
1436 if (copy_from_user(buf
, user_buf
, buf_size
))
1438 if (sscanf(buf
, "%d", &plcp
) != 1)
1440 if ((plcp
< IWL_MAX_PLCP_ERR_THRESHOLD_MIN
) ||
1441 (plcp
> IWL_MAX_PLCP_ERR_THRESHOLD_MAX
))
1442 priv
->cfg
->base_params
->plcp_delta_threshold
=
1443 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE
;
1445 priv
->cfg
->base_params
->plcp_delta_threshold
= plcp
;
1449 static ssize_t
iwl_dbgfs_force_reset_read(struct file
*file
,
1450 char __user
*user_buf
,
1451 size_t count
, loff_t
*ppos
) {
1453 struct iwl_priv
*priv
= file
->private_data
;
1456 const size_t bufsz
= sizeof(buf
);
1457 struct iwl_force_reset
*force_reset
;
1459 for (i
= 0; i
< IWL_MAX_FORCE_RESET
; i
++) {
1460 force_reset
= &priv
->force_reset
[i
];
1461 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1462 "Force reset method %d\n", i
);
1463 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1464 "\tnumber of reset request: %d\n",
1465 force_reset
->reset_request_count
);
1466 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1467 "\tnumber of reset request success: %d\n",
1468 force_reset
->reset_success_count
);
1469 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1470 "\tnumber of reset request reject: %d\n",
1471 force_reset
->reset_reject_count
);
1472 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1473 "\treset duration: %lu\n",
1474 force_reset
->reset_duration
);
1476 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1479 static ssize_t
iwl_dbgfs_force_reset_write(struct file
*file
,
1480 const char __user
*user_buf
,
1481 size_t count
, loff_t
*ppos
) {
1483 struct iwl_priv
*priv
= file
->private_data
;
1488 memset(buf
, 0, sizeof(buf
));
1489 buf_size
= min(count
, sizeof(buf
) - 1);
1490 if (copy_from_user(buf
, user_buf
, buf_size
))
1492 if (sscanf(buf
, "%d", &reset
) != 1)
1497 ret
= iwl_force_reset(priv
, reset
, true);
1502 return ret
? ret
: count
;
1505 static ssize_t
iwl_dbgfs_txfifo_flush_write(struct file
*file
,
1506 const char __user
*user_buf
,
1507 size_t count
, loff_t
*ppos
) {
1509 struct iwl_priv
*priv
= file
->private_data
;
1514 memset(buf
, 0, sizeof(buf
));
1515 buf_size
= min(count
, sizeof(buf
) - 1);
1516 if (copy_from_user(buf
, user_buf
, buf_size
))
1518 if (sscanf(buf
, "%d", &flush
) != 1)
1521 if (iwl_is_rfkill(priv
))
1524 priv
->cfg
->ops
->lib
->dev_txfifo_flush(priv
, IWL_DROP_ALL
);
1529 static ssize_t
iwl_dbgfs_ucode_bt_stats_read(struct file
*file
,
1530 char __user
*user_buf
,
1531 size_t count
, loff_t
*ppos
)
1533 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1535 return priv
->cfg
->ops
->lib
->debugfs_ops
.bt_stats_read(file
,
1536 user_buf
, count
, ppos
);
1539 static ssize_t
iwl_dbgfs_wd_timeout_write(struct file
*file
,
1540 const char __user
*user_buf
,
1541 size_t count
, loff_t
*ppos
) {
1543 struct iwl_priv
*priv
= file
->private_data
;
1548 memset(buf
, 0, sizeof(buf
));
1549 buf_size
= min(count
, sizeof(buf
) - 1);
1550 if (copy_from_user(buf
, user_buf
, buf_size
))
1552 if (sscanf(buf
, "%d", &timeout
) != 1)
1554 if (timeout
< 0 || timeout
> IWL_MAX_WD_TIMEOUT
)
1555 timeout
= IWL_DEF_WD_TIMEOUT
;
1557 priv
->cfg
->base_params
->wd_timeout
= timeout
;
1558 iwl_setup_watchdog(priv
);
1562 static ssize_t
iwl_dbgfs_bt_traffic_read(struct file
*file
,
1563 char __user
*user_buf
,
1564 size_t count
, loff_t
*ppos
) {
1566 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1569 const size_t bufsz
= sizeof(buf
);
1571 if (!priv
->bt_enable_flag
) {
1572 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "BT coex disabled\n");
1573 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1575 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "BT enable flag: 0x%x\n",
1576 priv
->bt_enable_flag
);
1577 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "BT in %s mode\n",
1578 priv
->bt_full_concurrent
? "full concurrency" : "3-wire");
1579 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "BT status: %s, "
1580 "last traffic notif: %d\n",
1581 priv
->bt_status
? "On" : "Off", priv
->last_bt_traffic_load
);
1582 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "ch_announcement: %d, "
1583 "kill_ack_mask: %x, kill_cts_mask: %x\n",
1584 priv
->bt_ch_announce
, priv
->kill_ack_mask
,
1585 priv
->kill_cts_mask
);
1587 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "bluetooth traffic load: ");
1588 switch (priv
->bt_traffic_load
) {
1589 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS
:
1590 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Continuous\n");
1592 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH
:
1593 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "High\n");
1595 case IWL_BT_COEX_TRAFFIC_LOAD_LOW
:
1596 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Low\n");
1598 case IWL_BT_COEX_TRAFFIC_LOAD_NONE
:
1600 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "None\n");
1604 return 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 if (priv
->cfg
->ht_params
)
1618 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1619 "use %s for aggregation\n",
1620 (priv
->cfg
->ht_params
->use_rts_for_aggregation
) ?
1621 "rts/cts" : "cts-to-self");
1623 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "N/A");
1625 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1628 static ssize_t
iwl_dbgfs_protection_mode_write(struct file
*file
,
1629 const char __user
*user_buf
,
1630 size_t count
, loff_t
*ppos
) {
1632 struct iwl_priv
*priv
= file
->private_data
;
1637 if (!priv
->cfg
->ht_params
)
1640 memset(buf
, 0, sizeof(buf
));
1641 buf_size
= min(count
, sizeof(buf
) - 1);
1642 if (copy_from_user(buf
, user_buf
, buf_size
))
1644 if (sscanf(buf
, "%d", &rts
) != 1)
1647 priv
->cfg
->ht_params
->use_rts_for_aggregation
= true;
1649 priv
->cfg
->ht_params
->use_rts_for_aggregation
= false;
1653 static ssize_t
iwl_dbgfs_reply_tx_error_read(struct file
*file
,
1654 char __user
*user_buf
,
1655 size_t count
, loff_t
*ppos
)
1657 struct iwl_priv
*priv
= file
->private_data
;
1659 if (priv
->cfg
->ops
->lib
->debugfs_ops
.reply_tx_error
)
1660 return priv
->cfg
->ops
->lib
->debugfs_ops
.reply_tx_error(
1661 file
, user_buf
, count
, ppos
);
1665 DEBUGFS_READ_FILE_OPS(rx_statistics
);
1666 DEBUGFS_READ_FILE_OPS(tx_statistics
);
1667 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log
);
1668 DEBUGFS_READ_FILE_OPS(rx_queue
);
1669 DEBUGFS_READ_FILE_OPS(tx_queue
);
1670 DEBUGFS_READ_FILE_OPS(ucode_rx_stats
);
1671 DEBUGFS_READ_FILE_OPS(ucode_tx_stats
);
1672 DEBUGFS_READ_FILE_OPS(ucode_general_stats
);
1673 DEBUGFS_READ_FILE_OPS(sensitivity
);
1674 DEBUGFS_READ_FILE_OPS(chain_noise
);
1675 DEBUGFS_READ_FILE_OPS(power_save_status
);
1676 DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics
);
1677 DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics
);
1678 DEBUGFS_WRITE_FILE_OPS(csr
);
1679 DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing
);
1680 DEBUGFS_READ_FILE_OPS(fh_reg
);
1681 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon
);
1682 DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta
);
1683 DEBUGFS_READ_WRITE_FILE_OPS(force_reset
);
1684 DEBUGFS_READ_FILE_OPS(rxon_flags
);
1685 DEBUGFS_READ_FILE_OPS(rxon_filter_flags
);
1686 DEBUGFS_WRITE_FILE_OPS(txfifo_flush
);
1687 DEBUGFS_READ_FILE_OPS(ucode_bt_stats
);
1688 DEBUGFS_WRITE_FILE_OPS(wd_timeout
);
1689 DEBUGFS_READ_FILE_OPS(bt_traffic
);
1690 DEBUGFS_READ_WRITE_FILE_OPS(protection_mode
);
1691 DEBUGFS_READ_FILE_OPS(reply_tx_error
);
1694 * Create the debugfs files and directories
1697 int iwl_dbgfs_register(struct iwl_priv
*priv
, const char *name
)
1699 struct dentry
*phyd
= priv
->hw
->wiphy
->debugfsdir
;
1700 struct dentry
*dir_drv
, *dir_data
, *dir_rf
, *dir_debug
;
1702 dir_drv
= debugfs_create_dir(name
, phyd
);
1706 priv
->debugfs_dir
= dir_drv
;
1708 dir_data
= debugfs_create_dir("data", dir_drv
);
1711 dir_rf
= debugfs_create_dir("rf", dir_drv
);
1714 dir_debug
= debugfs_create_dir("debug", dir_drv
);
1718 DEBUGFS_ADD_FILE(nvm
, dir_data
, S_IRUSR
);
1719 DEBUGFS_ADD_FILE(sram
, dir_data
, S_IWUSR
| S_IRUSR
);
1720 DEBUGFS_ADD_FILE(log_event
, dir_data
, S_IWUSR
| S_IRUSR
);
1721 DEBUGFS_ADD_FILE(stations
, dir_data
, S_IRUSR
);
1722 DEBUGFS_ADD_FILE(channels
, dir_data
, S_IRUSR
);
1723 DEBUGFS_ADD_FILE(status
, dir_data
, S_IRUSR
);
1724 DEBUGFS_ADD_FILE(interrupt
, dir_data
, S_IWUSR
| S_IRUSR
);
1725 DEBUGFS_ADD_FILE(qos
, dir_data
, S_IRUSR
);
1726 DEBUGFS_ADD_FILE(sleep_level_override
, dir_data
, S_IWUSR
| S_IRUSR
);
1727 DEBUGFS_ADD_FILE(current_sleep_command
, dir_data
, S_IRUSR
);
1728 DEBUGFS_ADD_FILE(thermal_throttling
, dir_data
, S_IRUSR
);
1729 DEBUGFS_ADD_FILE(disable_ht40
, dir_data
, S_IWUSR
| S_IRUSR
);
1730 DEBUGFS_ADD_FILE(rx_statistics
, dir_debug
, S_IRUSR
);
1731 DEBUGFS_ADD_FILE(tx_statistics
, dir_debug
, S_IRUSR
);
1732 DEBUGFS_ADD_FILE(traffic_log
, dir_debug
, S_IWUSR
| S_IRUSR
);
1733 DEBUGFS_ADD_FILE(rx_queue
, dir_debug
, S_IRUSR
);
1734 DEBUGFS_ADD_FILE(tx_queue
, dir_debug
, S_IRUSR
);
1735 DEBUGFS_ADD_FILE(power_save_status
, dir_debug
, S_IRUSR
);
1736 DEBUGFS_ADD_FILE(clear_ucode_statistics
, dir_debug
, S_IWUSR
);
1737 DEBUGFS_ADD_FILE(clear_traffic_statistics
, dir_debug
, S_IWUSR
);
1738 DEBUGFS_ADD_FILE(csr
, dir_debug
, S_IWUSR
);
1739 DEBUGFS_ADD_FILE(fh_reg
, dir_debug
, S_IRUSR
);
1740 DEBUGFS_ADD_FILE(missed_beacon
, dir_debug
, S_IWUSR
);
1741 DEBUGFS_ADD_FILE(plcp_delta
, dir_debug
, S_IWUSR
| S_IRUSR
);
1742 DEBUGFS_ADD_FILE(force_reset
, dir_debug
, S_IWUSR
| S_IRUSR
);
1743 DEBUGFS_ADD_FILE(ucode_rx_stats
, dir_debug
, S_IRUSR
);
1744 DEBUGFS_ADD_FILE(ucode_tx_stats
, dir_debug
, S_IRUSR
);
1745 DEBUGFS_ADD_FILE(ucode_general_stats
, dir_debug
, S_IRUSR
);
1746 if (priv
->cfg
->ops
->lib
->dev_txfifo_flush
)
1747 DEBUGFS_ADD_FILE(txfifo_flush
, dir_debug
, S_IWUSR
);
1748 DEBUGFS_ADD_FILE(protection_mode
, dir_debug
, S_IWUSR
| S_IRUSR
);
1750 DEBUGFS_ADD_FILE(sensitivity
, dir_debug
, S_IRUSR
);
1751 DEBUGFS_ADD_FILE(chain_noise
, dir_debug
, S_IRUSR
);
1752 DEBUGFS_ADD_FILE(ucode_tracing
, dir_debug
, S_IWUSR
| S_IRUSR
);
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(wd_timeout
, dir_debug
, S_IWUSR
);
1758 if (iwl_advanced_bt_coexist(priv
))
1759 DEBUGFS_ADD_FILE(bt_traffic
, dir_debug
, S_IRUSR
);
1760 DEBUGFS_ADD_BOOL(disable_sensitivity
, dir_rf
,
1761 &priv
->disable_sens_cal
);
1762 DEBUGFS_ADD_BOOL(disable_chain_noise
, dir_rf
,
1763 &priv
->disable_chain_noise_cal
);
1767 IWL_ERR(priv
, "Can't create the debugfs directory\n");
1768 iwl_dbgfs_unregister(priv
);
1773 * Remove the debugfs files and directories
1776 void iwl_dbgfs_unregister(struct iwl_priv
*priv
)
1778 if (!priv
->debugfs_dir
)
1781 debugfs_remove_recursive(priv
->debugfs_dir
);
1782 priv
->debugfs_dir
= NULL
;