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 ieee80211_frequency_to_channel(
471 channels
[i
].center_freq
),
472 channels
[i
].max_power
,
473 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
474 " (IEEE 802.11h required)" : "",
475 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
476 || (channels
[i
].flags
&
477 IEEE80211_CHAN_RADAR
)) ? "" :
480 IEEE80211_CHAN_PASSIVE_SCAN
?
481 "passive only" : "active/passive");
483 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_5GHZ
);
485 channels
= supp_band
->channels
;
487 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
488 "Displaying %d channels in 5.2GHz band (802.11a)\n",
489 supp_band
->n_channels
);
491 for (i
= 0; i
< supp_band
->n_channels
; i
++)
492 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
493 "%d: %ddBm: BSS%s%s, %s.\n",
494 ieee80211_frequency_to_channel(
495 channels
[i
].center_freq
),
496 channels
[i
].max_power
,
497 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
498 " (IEEE 802.11h required)" : "",
499 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
500 || (channels
[i
].flags
&
501 IEEE80211_CHAN_RADAR
)) ? "" :
504 IEEE80211_CHAN_PASSIVE_SCAN
?
505 "passive only" : "active/passive");
507 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
512 static ssize_t
iwl_dbgfs_status_read(struct file
*file
,
513 char __user
*user_buf
,
514 size_t count
, loff_t
*ppos
) {
516 struct iwl_priv
*priv
= file
->private_data
;
519 const size_t bufsz
= sizeof(buf
);
521 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_HCMD_ACTIVE:\t %d\n",
522 test_bit(STATUS_HCMD_ACTIVE
, &priv
->status
));
523 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INT_ENABLED:\t %d\n",
524 test_bit(STATUS_INT_ENABLED
, &priv
->status
));
525 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_RF_KILL_HW:\t %d\n",
526 test_bit(STATUS_RF_KILL_HW
, &priv
->status
));
527 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_CT_KILL:\t\t %d\n",
528 test_bit(STATUS_CT_KILL
, &priv
->status
));
529 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INIT:\t\t %d\n",
530 test_bit(STATUS_INIT
, &priv
->status
));
531 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_ALIVE:\t\t %d\n",
532 test_bit(STATUS_ALIVE
, &priv
->status
));
533 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_READY:\t\t %d\n",
534 test_bit(STATUS_READY
, &priv
->status
));
535 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_TEMPERATURE:\t %d\n",
536 test_bit(STATUS_TEMPERATURE
, &priv
->status
));
537 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_GEO_CONFIGURED:\t %d\n",
538 test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
));
539 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_EXIT_PENDING:\t %d\n",
540 test_bit(STATUS_EXIT_PENDING
, &priv
->status
));
541 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_STATISTICS:\t %d\n",
542 test_bit(STATUS_STATISTICS
, &priv
->status
));
543 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCANNING:\t %d\n",
544 test_bit(STATUS_SCANNING
, &priv
->status
));
545 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_ABORTING:\t %d\n",
546 test_bit(STATUS_SCAN_ABORTING
, &priv
->status
));
547 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_HW:\t\t %d\n",
548 test_bit(STATUS_SCAN_HW
, &priv
->status
));
549 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_POWER_PMI:\t %d\n",
550 test_bit(STATUS_POWER_PMI
, &priv
->status
));
551 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_FW_ERROR:\t %d\n",
552 test_bit(STATUS_FW_ERROR
, &priv
->status
));
553 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
556 static ssize_t
iwl_dbgfs_interrupt_read(struct file
*file
,
557 char __user
*user_buf
,
558 size_t count
, loff_t
*ppos
) {
560 struct iwl_priv
*priv
= file
->private_data
;
564 int bufsz
= 24 * 64; /* 24 items * 64 char per item */
567 buf
= kzalloc(bufsz
, GFP_KERNEL
);
569 IWL_ERR(priv
, "Can not allocate Buffer\n");
573 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
574 "Interrupt Statistics Report:\n");
576 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "HW Error:\t\t\t %u\n",
578 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "SW Error:\t\t\t %u\n",
580 if (priv
->isr_stats
.sw
> 0) {
581 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
582 "\tLast Restarting Code: 0x%X\n",
583 priv
->isr_stats
.sw_err
);
585 #ifdef CONFIG_IWLWIFI_DEBUG
586 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Frame transmitted:\t\t %u\n",
587 priv
->isr_stats
.sch
);
588 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Alive interrupt:\t\t %u\n",
589 priv
->isr_stats
.alive
);
591 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
592 "HW RF KILL switch toggled:\t %u\n",
593 priv
->isr_stats
.rfkill
);
595 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "CT KILL:\t\t\t %u\n",
596 priv
->isr_stats
.ctkill
);
598 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Wakeup Interrupt:\t\t %u\n",
599 priv
->isr_stats
.wakeup
);
601 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
602 "Rx command responses:\t\t %u\n",
604 for (cnt
= 0; cnt
< REPLY_MAX
; cnt
++) {
605 if (priv
->isr_stats
.rx_handlers
[cnt
] > 0)
606 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
607 "\tRx handler[%36s]:\t\t %u\n",
609 priv
->isr_stats
.rx_handlers
[cnt
]);
612 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx/FH interrupt:\t\t %u\n",
615 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Unexpected INTA:\t\t %u\n",
616 priv
->isr_stats
.unhandled
);
618 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
623 static ssize_t
iwl_dbgfs_interrupt_write(struct file
*file
,
624 const char __user
*user_buf
,
625 size_t count
, loff_t
*ppos
)
627 struct iwl_priv
*priv
= file
->private_data
;
632 memset(buf
, 0, sizeof(buf
));
633 buf_size
= min(count
, sizeof(buf
) - 1);
634 if (copy_from_user(buf
, user_buf
, buf_size
))
636 if (sscanf(buf
, "%x", &reset_flag
) != 1)
639 iwl_clear_isr_stats(priv
);
644 static ssize_t
iwl_dbgfs_qos_read(struct file
*file
, char __user
*user_buf
,
645 size_t count
, loff_t
*ppos
)
647 struct iwl_priv
*priv
= file
->private_data
;
650 const size_t bufsz
= sizeof(buf
);
652 for (i
= 0; i
< AC_NUM
; i
++) {
653 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
654 "\tcw_min\tcw_max\taifsn\ttxop\n");
655 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
656 "AC[%d]\t%u\t%u\t%u\t%u\n", i
,
657 priv
->qos_data
.def_qos_parm
.ac
[i
].cw_min
,
658 priv
->qos_data
.def_qos_parm
.ac
[i
].cw_max
,
659 priv
->qos_data
.def_qos_parm
.ac
[i
].aifsn
,
660 priv
->qos_data
.def_qos_parm
.ac
[i
].edca_txop
);
662 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
665 static ssize_t
iwl_dbgfs_led_read(struct file
*file
, char __user
*user_buf
,
666 size_t count
, loff_t
*ppos
)
668 struct iwl_priv
*priv
= file
->private_data
;
671 const size_t bufsz
= sizeof(buf
);
673 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
674 "allow blinking: %s\n",
675 (priv
->allow_blinking
) ? "True" : "False");
676 if (priv
->allow_blinking
) {
677 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
678 "Led blinking rate: %u\n",
679 priv
->last_blink_rate
);
680 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
681 "Last blink time: %lu\n",
682 priv
->last_blink_time
);
685 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
688 static ssize_t
iwl_dbgfs_thermal_throttling_read(struct file
*file
,
689 char __user
*user_buf
,
690 size_t count
, loff_t
*ppos
)
692 struct iwl_priv
*priv
= file
->private_data
;
693 struct iwl_tt_mgmt
*tt
= &priv
->thermal_throttle
;
694 struct iwl_tt_restriction
*restriction
;
697 const size_t bufsz
= sizeof(buf
);
699 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
700 "Thermal Throttling Mode: %s\n",
701 tt
->advanced_tt
? "Advance" : "Legacy");
702 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
703 "Thermal Throttling State: %d\n",
705 if (tt
->advanced_tt
) {
706 restriction
= tt
->restriction
+ tt
->state
;
707 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
709 restriction
->tx_stream
);
710 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
712 restriction
->rx_stream
);
713 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
717 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
720 static ssize_t
iwl_dbgfs_disable_ht40_write(struct file
*file
,
721 const char __user
*user_buf
,
722 size_t count
, loff_t
*ppos
)
724 struct iwl_priv
*priv
= file
->private_data
;
729 memset(buf
, 0, sizeof(buf
));
730 buf_size
= min(count
, sizeof(buf
) - 1);
731 if (copy_from_user(buf
, user_buf
, buf_size
))
733 if (sscanf(buf
, "%d", &ht40
) != 1)
735 if (!iwl_is_associated(priv
))
736 priv
->disable_ht40
= ht40
? true : false;
738 IWL_ERR(priv
, "Sta associated with AP - "
739 "Change to 40MHz channel support is not allowed\n");
746 static ssize_t
iwl_dbgfs_disable_ht40_read(struct file
*file
,
747 char __user
*user_buf
,
748 size_t count
, loff_t
*ppos
)
750 struct iwl_priv
*priv
= file
->private_data
;
753 const size_t bufsz
= sizeof(buf
);
755 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
756 "11n 40MHz Mode: %s\n",
757 priv
->disable_ht40
? "Disabled" : "Enabled");
758 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
761 static ssize_t
iwl_dbgfs_sleep_level_override_write(struct file
*file
,
762 const char __user
*user_buf
,
763 size_t count
, loff_t
*ppos
)
765 struct iwl_priv
*priv
= file
->private_data
;
770 memset(buf
, 0, sizeof(buf
));
771 buf_size
= min(count
, sizeof(buf
) - 1);
772 if (copy_from_user(buf
, user_buf
, buf_size
))
775 if (sscanf(buf
, "%d", &value
) != 1)
779 * Our users expect 0 to be "CAM", but 0 isn't actually
780 * valid here. However, let's not confuse them and present
781 * IWL_POWER_INDEX_1 as "1", not "0".
788 if (value
!= -1 && (value
< 0 || value
>= IWL_POWER_NUM
))
791 if (!iwl_is_ready_rf(priv
))
794 priv
->power_data
.debug_sleep_level_override
= value
;
796 mutex_lock(&priv
->mutex
);
797 iwl_power_update_mode(priv
, true);
798 mutex_unlock(&priv
->mutex
);
803 static ssize_t
iwl_dbgfs_sleep_level_override_read(struct file
*file
,
804 char __user
*user_buf
,
805 size_t count
, loff_t
*ppos
)
807 struct iwl_priv
*priv
= file
->private_data
;
810 const size_t bufsz
= sizeof(buf
);
812 /* see the write function */
813 value
= priv
->power_data
.debug_sleep_level_override
;
817 pos
= scnprintf(buf
, bufsz
, "%d\n", value
);
818 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
821 static ssize_t
iwl_dbgfs_current_sleep_command_read(struct file
*file
,
822 char __user
*user_buf
,
823 size_t count
, loff_t
*ppos
)
825 struct iwl_priv
*priv
= file
->private_data
;
828 const size_t bufsz
= sizeof(buf
);
829 struct iwl_powertable_cmd
*cmd
= &priv
->power_data
.sleep_cmd
;
831 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
832 "flags: %#.2x\n", le16_to_cpu(cmd
->flags
));
833 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
834 "RX/TX timeout: %d/%d usec\n",
835 le32_to_cpu(cmd
->rx_data_timeout
),
836 le32_to_cpu(cmd
->tx_data_timeout
));
837 for (i
= 0; i
< IWL_POWER_VEC_SIZE
; i
++)
838 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
839 "sleep_interval[%d]: %d\n", i
,
840 le32_to_cpu(cmd
->sleep_interval
[i
]));
842 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
845 DEBUGFS_READ_WRITE_FILE_OPS(sram
);
846 DEBUGFS_READ_WRITE_FILE_OPS(log_event
);
847 DEBUGFS_READ_FILE_OPS(nvm
);
848 DEBUGFS_READ_FILE_OPS(stations
);
849 DEBUGFS_READ_FILE_OPS(channels
);
850 DEBUGFS_READ_FILE_OPS(status
);
851 DEBUGFS_READ_WRITE_FILE_OPS(interrupt
);
852 DEBUGFS_READ_FILE_OPS(qos
);
853 DEBUGFS_READ_FILE_OPS(led
);
854 DEBUGFS_READ_FILE_OPS(thermal_throttling
);
855 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40
);
856 DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override
);
857 DEBUGFS_READ_FILE_OPS(current_sleep_command
);
859 static ssize_t
iwl_dbgfs_traffic_log_read(struct file
*file
,
860 char __user
*user_buf
,
861 size_t count
, loff_t
*ppos
)
863 struct iwl_priv
*priv
= file
->private_data
;
864 int pos
= 0, ofs
= 0;
866 struct iwl_tx_queue
*txq
;
868 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
870 int bufsz
= ((IWL_TRAFFIC_ENTRIES
* IWL_TRAFFIC_ENTRY_SIZE
* 64) * 2) +
871 (priv
->cfg
->num_of_queues
* 32 * 8) + 400;
876 IWL_ERR(priv
, "txq not ready\n");
879 buf
= kzalloc(bufsz
, GFP_KERNEL
);
881 IWL_ERR(priv
, "Can not allocate buffer\n");
884 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx Queue\n");
885 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
886 txq
= &priv
->txq
[cnt
];
888 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
889 "q[%d]: read_ptr: %u, write_ptr: %u\n",
890 cnt
, q
->read_ptr
, q
->write_ptr
);
892 if (priv
->tx_traffic
&& (iwl_debug_level
& IWL_DL_TX
)) {
893 ptr
= priv
->tx_traffic
;
894 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
895 "Tx Traffic idx: %u\n", priv
->tx_traffic_idx
);
896 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
897 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
898 entry
++, ofs
+= 16) {
899 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
901 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
902 buf
+ pos
, bufsz
- pos
, 0);
903 pos
+= strlen(buf
+ pos
);
910 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Rx Queue\n");
911 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
912 "read: %u, write: %u\n",
913 rxq
->read
, rxq
->write
);
915 if (priv
->rx_traffic
&& (iwl_debug_level
& IWL_DL_RX
)) {
916 ptr
= priv
->rx_traffic
;
917 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
918 "Rx Traffic idx: %u\n", priv
->rx_traffic_idx
);
919 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
920 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
921 entry
++, ofs
+= 16) {
922 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
924 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
925 buf
+ pos
, bufsz
- pos
, 0);
926 pos
+= strlen(buf
+ pos
);
933 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
938 static ssize_t
iwl_dbgfs_traffic_log_write(struct file
*file
,
939 const char __user
*user_buf
,
940 size_t count
, loff_t
*ppos
)
942 struct iwl_priv
*priv
= file
->private_data
;
947 memset(buf
, 0, sizeof(buf
));
948 buf_size
= min(count
, sizeof(buf
) - 1);
949 if (copy_from_user(buf
, user_buf
, buf_size
))
951 if (sscanf(buf
, "%d", &traffic_log
) != 1)
953 if (traffic_log
== 0)
954 iwl_reset_traffic_log(priv
);
959 static ssize_t
iwl_dbgfs_tx_queue_read(struct file
*file
,
960 char __user
*user_buf
,
961 size_t count
, loff_t
*ppos
) {
963 struct iwl_priv
*priv
= file
->private_data
;
964 struct iwl_tx_queue
*txq
;
970 const size_t bufsz
= sizeof(char) * 64 * priv
->cfg
->num_of_queues
;
973 IWL_ERR(priv
, "txq not ready\n");
976 buf
= kzalloc(bufsz
, GFP_KERNEL
);
980 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
981 txq
= &priv
->txq
[cnt
];
983 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
984 "hwq %.2d: read=%u write=%u stop=%d"
985 " swq_id=%#.2x (ac %d/hwq %d)\n",
986 cnt
, q
->read_ptr
, q
->write_ptr
,
987 !!test_bit(cnt
, priv
->queue_stopped
),
989 txq
->swq_id
& 0x80 ? txq
->swq_id
& 3 :
991 txq
->swq_id
& 0x80 ? (txq
->swq_id
>> 2) &
995 /* for the ACs, display the stop count too */
996 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
998 atomic_read(&priv
->queue_stop_count
[cnt
]));
1000 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1005 static ssize_t
iwl_dbgfs_rx_queue_read(struct file
*file
,
1006 char __user
*user_buf
,
1007 size_t count
, loff_t
*ppos
) {
1009 struct iwl_priv
*priv
= file
->private_data
;
1010 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
1013 const size_t bufsz
= sizeof(buf
);
1015 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "read: %u\n",
1017 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "write: %u\n",
1019 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "free_count: %u\n",
1022 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "closed_rb_num: %u\n",
1023 le16_to_cpu(rxq
->rb_stts
->closed_rb_num
) & 0x0FFF);
1025 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1026 "closed_rb_num: Not Allocated\n");
1028 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1031 static ssize_t
iwl_dbgfs_ucode_rx_stats_read(struct file
*file
,
1032 char __user
*user_buf
,
1033 size_t count
, loff_t
*ppos
)
1035 struct iwl_priv
*priv
= file
->private_data
;
1036 return priv
->cfg
->ops
->lib
->debugfs_ops
.rx_stats_read(file
,
1037 user_buf
, count
, ppos
);
1040 static ssize_t
iwl_dbgfs_ucode_tx_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
.tx_stats_read(file
,
1046 user_buf
, count
, ppos
);
1049 static ssize_t
iwl_dbgfs_ucode_general_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
.general_stats_read(file
,
1055 user_buf
, count
, ppos
);
1058 static ssize_t
iwl_dbgfs_sensitivity_read(struct file
*file
,
1059 char __user
*user_buf
,
1060 size_t count
, loff_t
*ppos
) {
1062 struct iwl_priv
*priv
= file
->private_data
;
1066 int bufsz
= sizeof(struct iwl_sensitivity_data
) * 4 + 100;
1068 struct iwl_sensitivity_data
*data
;
1070 data
= &priv
->sensitivity_data
;
1071 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1073 IWL_ERR(priv
, "Can not allocate Buffer\n");
1077 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm:\t\t\t %u\n",
1078 data
->auto_corr_ofdm
);
1079 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1080 "auto_corr_ofdm_mrc:\t\t %u\n",
1081 data
->auto_corr_ofdm_mrc
);
1082 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm_x1:\t\t %u\n",
1083 data
->auto_corr_ofdm_x1
);
1084 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1085 "auto_corr_ofdm_mrc_x1:\t\t %u\n",
1086 data
->auto_corr_ofdm_mrc_x1
);
1087 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck:\t\t\t %u\n",
1088 data
->auto_corr_cck
);
1089 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck_mrc:\t\t %u\n",
1090 data
->auto_corr_cck_mrc
);
1091 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1092 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
1093 data
->last_bad_plcp_cnt_ofdm
);
1094 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_ofdm:\t\t %u\n",
1095 data
->last_fa_cnt_ofdm
);
1096 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1097 "last_bad_plcp_cnt_cck:\t\t %u\n",
1098 data
->last_bad_plcp_cnt_cck
);
1099 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_cck:\t\t %u\n",
1100 data
->last_fa_cnt_cck
);
1101 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_curr_state:\t\t\t %u\n",
1102 data
->nrg_curr_state
);
1103 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_prev_state:\t\t\t %u\n",
1104 data
->nrg_prev_state
);
1105 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_value:\t\t\t");
1106 for (cnt
= 0; cnt
< 10; cnt
++) {
1107 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1108 data
->nrg_value
[cnt
]);
1110 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1111 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_rssi:\t\t");
1112 for (cnt
= 0; cnt
< NRG_NUM_PREV_STAT_L
; cnt
++) {
1113 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1114 data
->nrg_silence_rssi
[cnt
]);
1116 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1117 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_ref:\t\t %u\n",
1118 data
->nrg_silence_ref
);
1119 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_energy_idx:\t\t\t %u\n",
1120 data
->nrg_energy_idx
);
1121 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_idx:\t\t %u\n",
1122 data
->nrg_silence_idx
);
1123 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_cck:\t\t\t %u\n",
1125 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1126 "nrg_auto_corr_silence_diff:\t %u\n",
1127 data
->nrg_auto_corr_silence_diff
);
1128 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "num_in_cck_no_fa:\t\t %u\n",
1129 data
->num_in_cck_no_fa
);
1130 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_ofdm:\t\t\t %u\n",
1133 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1139 static ssize_t
iwl_dbgfs_chain_noise_read(struct file
*file
,
1140 char __user
*user_buf
,
1141 size_t count
, loff_t
*ppos
) {
1143 struct iwl_priv
*priv
= file
->private_data
;
1147 int bufsz
= sizeof(struct iwl_chain_noise_data
) * 4 + 100;
1149 struct iwl_chain_noise_data
*data
;
1151 data
= &priv
->chain_noise_data
;
1152 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1154 IWL_ERR(priv
, "Can not allocate Buffer\n");
1158 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "active_chains:\t\t\t %u\n",
1159 data
->active_chains
);
1160 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_a:\t\t\t %u\n",
1161 data
->chain_noise_a
);
1162 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_b:\t\t\t %u\n",
1163 data
->chain_noise_b
);
1164 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_c:\t\t\t %u\n",
1165 data
->chain_noise_c
);
1166 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_a:\t\t\t %u\n",
1167 data
->chain_signal_a
);
1168 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_b:\t\t\t %u\n",
1169 data
->chain_signal_b
);
1170 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_c:\t\t\t %u\n",
1171 data
->chain_signal_c
);
1172 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "beacon_count:\t\t\t %u\n",
1173 data
->beacon_count
);
1175 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "disconn_array:\t\t\t");
1176 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1177 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1178 data
->disconn_array
[cnt
]);
1180 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1181 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "delta_gain_code:\t\t");
1182 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1183 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1184 data
->delta_gain_code
[cnt
]);
1186 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1187 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "radio_write:\t\t\t %u\n",
1189 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "state:\t\t\t\t %u\n",
1192 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1197 static ssize_t
iwl_dbgfs_power_save_status_read(struct file
*file
,
1198 char __user
*user_buf
,
1199 size_t count
, loff_t
*ppos
)
1201 struct iwl_priv
*priv
= file
->private_data
;
1204 const size_t bufsz
= sizeof(buf
);
1207 pwrsave_status
= iwl_read32(priv
, CSR_GP_CNTRL
) &
1208 CSR_GP_REG_POWER_SAVE_STATUS_MSK
;
1210 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Power Save Status: ");
1211 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%s\n",
1212 (pwrsave_status
== CSR_GP_REG_NO_POWER_SAVE
) ? "none" :
1213 (pwrsave_status
== CSR_GP_REG_MAC_POWER_SAVE
) ? "MAC" :
1214 (pwrsave_status
== CSR_GP_REG_PHY_POWER_SAVE
) ? "PHY" :
1217 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1220 static ssize_t
iwl_dbgfs_clear_ucode_statistics_write(struct file
*file
,
1221 const char __user
*user_buf
,
1222 size_t count
, loff_t
*ppos
)
1224 struct iwl_priv
*priv
= file
->private_data
;
1229 memset(buf
, 0, sizeof(buf
));
1230 buf_size
= min(count
, sizeof(buf
) - 1);
1231 if (copy_from_user(buf
, user_buf
, buf_size
))
1233 if (sscanf(buf
, "%d", &clear
) != 1)
1236 /* make request to uCode to retrieve statistics information */
1237 mutex_lock(&priv
->mutex
);
1238 iwl_send_statistics_request(priv
, CMD_SYNC
, true);
1239 mutex_unlock(&priv
->mutex
);
1244 static ssize_t
iwl_dbgfs_csr_write(struct file
*file
,
1245 const char __user
*user_buf
,
1246 size_t count
, loff_t
*ppos
)
1248 struct iwl_priv
*priv
= file
->private_data
;
1253 memset(buf
, 0, sizeof(buf
));
1254 buf_size
= min(count
, sizeof(buf
) - 1);
1255 if (copy_from_user(buf
, user_buf
, buf_size
))
1257 if (sscanf(buf
, "%d", &csr
) != 1)
1260 if (priv
->cfg
->ops
->lib
->dump_csr
)
1261 priv
->cfg
->ops
->lib
->dump_csr(priv
);
1266 static ssize_t
iwl_dbgfs_ucode_tracing_read(struct file
*file
,
1267 char __user
*user_buf
,
1268 size_t count
, loff_t
*ppos
) {
1270 struct iwl_priv
*priv
= file
->private_data
;
1273 const size_t bufsz
= sizeof(buf
);
1275 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "ucode trace timer is %s\n",
1276 priv
->event_log
.ucode_trace
? "On" : "Off");
1277 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "non_wraps_count:\t\t %u\n",
1278 priv
->event_log
.non_wraps_count
);
1279 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "wraps_once_count:\t\t %u\n",
1280 priv
->event_log
.wraps_once_count
);
1281 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "wraps_more_count:\t\t %u\n",
1282 priv
->event_log
.wraps_more_count
);
1284 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1287 static ssize_t
iwl_dbgfs_ucode_tracing_write(struct file
*file
,
1288 const char __user
*user_buf
,
1289 size_t count
, loff_t
*ppos
)
1291 struct iwl_priv
*priv
= file
->private_data
;
1296 memset(buf
, 0, sizeof(buf
));
1297 buf_size
= min(count
, sizeof(buf
) - 1);
1298 if (copy_from_user(buf
, user_buf
, buf_size
))
1300 if (sscanf(buf
, "%d", &trace
) != 1)
1304 priv
->event_log
.ucode_trace
= true;
1305 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
1306 mod_timer(&priv
->ucode_trace
,
1307 jiffies
+ msecs_to_jiffies(UCODE_TRACE_PERIOD
));
1309 priv
->event_log
.ucode_trace
= false;
1310 del_timer_sync(&priv
->ucode_trace
);
1316 static ssize_t
iwl_dbgfs_rxon_flags_read(struct file
*file
,
1317 char __user
*user_buf
,
1318 size_t count
, loff_t
*ppos
) {
1320 struct iwl_priv
*priv
= file
->private_data
;
1324 len
= sprintf(buf
, "0x%04X\n", le32_to_cpu(priv
->active_rxon
.flags
));
1325 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1328 static ssize_t
iwl_dbgfs_rxon_filter_flags_read(struct file
*file
,
1329 char __user
*user_buf
,
1330 size_t count
, loff_t
*ppos
) {
1332 struct iwl_priv
*priv
= file
->private_data
;
1336 len
= sprintf(buf
, "0x%04X\n",
1337 le32_to_cpu(priv
->active_rxon
.filter_flags
));
1338 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1341 static ssize_t
iwl_dbgfs_fh_reg_read(struct file
*file
,
1342 char __user
*user_buf
,
1343 size_t count
, loff_t
*ppos
)
1345 struct iwl_priv
*priv
= file
->private_data
;
1348 ssize_t ret
= -EFAULT
;
1350 if (priv
->cfg
->ops
->lib
->dump_fh
) {
1351 ret
= pos
= priv
->cfg
->ops
->lib
->dump_fh(priv
, &buf
, true);
1353 ret
= simple_read_from_buffer(user_buf
,
1354 count
, ppos
, buf
, pos
);
1362 static ssize_t
iwl_dbgfs_missed_beacon_read(struct file
*file
,
1363 char __user
*user_buf
,
1364 size_t count
, loff_t
*ppos
) {
1366 struct iwl_priv
*priv
= file
->private_data
;
1369 const size_t bufsz
= sizeof(buf
);
1371 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%d\n",
1372 priv
->missed_beacon_threshold
);
1374 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1377 static ssize_t
iwl_dbgfs_missed_beacon_write(struct file
*file
,
1378 const char __user
*user_buf
,
1379 size_t count
, loff_t
*ppos
)
1381 struct iwl_priv
*priv
= file
->private_data
;
1386 memset(buf
, 0, sizeof(buf
));
1387 buf_size
= min(count
, sizeof(buf
) - 1);
1388 if (copy_from_user(buf
, user_buf
, buf_size
))
1390 if (sscanf(buf
, "%d", &missed
) != 1)
1393 if (missed
< IWL_MISSED_BEACON_THRESHOLD_MIN
||
1394 missed
> IWL_MISSED_BEACON_THRESHOLD_MAX
)
1395 priv
->missed_beacon_threshold
=
1396 IWL_MISSED_BEACON_THRESHOLD_DEF
;
1398 priv
->missed_beacon_threshold
= missed
;
1403 static ssize_t
iwl_dbgfs_plcp_delta_read(struct file
*file
,
1404 char __user
*user_buf
,
1405 size_t count
, loff_t
*ppos
) {
1407 struct iwl_priv
*priv
= file
->private_data
;
1410 const size_t bufsz
= sizeof(buf
);
1412 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%u\n",
1413 priv
->cfg
->plcp_delta_threshold
);
1415 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1418 static ssize_t
iwl_dbgfs_plcp_delta_write(struct file
*file
,
1419 const char __user
*user_buf
,
1420 size_t count
, loff_t
*ppos
) {
1422 struct iwl_priv
*priv
= file
->private_data
;
1427 memset(buf
, 0, sizeof(buf
));
1428 buf_size
= min(count
, sizeof(buf
) - 1);
1429 if (copy_from_user(buf
, user_buf
, buf_size
))
1431 if (sscanf(buf
, "%d", &plcp
) != 1)
1433 if ((plcp
< IWL_MAX_PLCP_ERR_THRESHOLD_MIN
) ||
1434 (plcp
> IWL_MAX_PLCP_ERR_THRESHOLD_MAX
))
1435 priv
->cfg
->plcp_delta_threshold
=
1436 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE
;
1438 priv
->cfg
->plcp_delta_threshold
= plcp
;
1442 static ssize_t
iwl_dbgfs_force_reset_read(struct file
*file
,
1443 char __user
*user_buf
,
1444 size_t count
, loff_t
*ppos
) {
1446 struct iwl_priv
*priv
= file
->private_data
;
1449 const size_t bufsz
= sizeof(buf
);
1450 struct iwl_force_reset
*force_reset
;
1452 for (i
= 0; i
< IWL_MAX_FORCE_RESET
; i
++) {
1453 force_reset
= &priv
->force_reset
[i
];
1454 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1455 "Force reset method %d\n", i
);
1456 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1457 "\tnumber of reset request: %d\n",
1458 force_reset
->reset_request_count
);
1459 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1460 "\tnumber of reset request success: %d\n",
1461 force_reset
->reset_success_count
);
1462 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1463 "\tnumber of reset request reject: %d\n",
1464 force_reset
->reset_reject_count
);
1465 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1466 "\treset duration: %lu\n",
1467 force_reset
->reset_duration
);
1469 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1472 static ssize_t
iwl_dbgfs_force_reset_write(struct file
*file
,
1473 const char __user
*user_buf
,
1474 size_t count
, loff_t
*ppos
) {
1476 struct iwl_priv
*priv
= file
->private_data
;
1481 memset(buf
, 0, sizeof(buf
));
1482 buf_size
= min(count
, sizeof(buf
) - 1);
1483 if (copy_from_user(buf
, user_buf
, buf_size
))
1485 if (sscanf(buf
, "%d", &reset
) != 1)
1490 ret
= iwl_force_reset(priv
, reset
, true);
1495 return ret
? ret
: count
;
1498 static ssize_t
iwl_dbgfs_txfifo_flush_write(struct file
*file
,
1499 const char __user
*user_buf
,
1500 size_t count
, loff_t
*ppos
) {
1502 struct iwl_priv
*priv
= file
->private_data
;
1507 memset(buf
, 0, sizeof(buf
));
1508 buf_size
= min(count
, sizeof(buf
) - 1);
1509 if (copy_from_user(buf
, user_buf
, buf_size
))
1511 if (sscanf(buf
, "%d", &flush
) != 1)
1514 if (iwl_is_rfkill(priv
))
1517 priv
->cfg
->ops
->lib
->dev_txfifo_flush(priv
, IWL_DROP_ALL
);
1522 static ssize_t
iwl_dbgfs_ucode_bt_stats_read(struct file
*file
,
1523 char __user
*user_buf
,
1524 size_t count
, loff_t
*ppos
)
1526 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1528 return priv
->cfg
->ops
->lib
->debugfs_ops
.bt_stats_read(file
,
1529 user_buf
, count
, ppos
);
1532 DEBUGFS_READ_FILE_OPS(rx_statistics
);
1533 DEBUGFS_READ_FILE_OPS(tx_statistics
);
1534 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log
);
1535 DEBUGFS_READ_FILE_OPS(rx_queue
);
1536 DEBUGFS_READ_FILE_OPS(tx_queue
);
1537 DEBUGFS_READ_FILE_OPS(ucode_rx_stats
);
1538 DEBUGFS_READ_FILE_OPS(ucode_tx_stats
);
1539 DEBUGFS_READ_FILE_OPS(ucode_general_stats
);
1540 DEBUGFS_READ_FILE_OPS(sensitivity
);
1541 DEBUGFS_READ_FILE_OPS(chain_noise
);
1542 DEBUGFS_READ_FILE_OPS(power_save_status
);
1543 DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics
);
1544 DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics
);
1545 DEBUGFS_WRITE_FILE_OPS(csr
);
1546 DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing
);
1547 DEBUGFS_READ_FILE_OPS(fh_reg
);
1548 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon
);
1549 DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta
);
1550 DEBUGFS_READ_WRITE_FILE_OPS(force_reset
);
1551 DEBUGFS_READ_FILE_OPS(rxon_flags
);
1552 DEBUGFS_READ_FILE_OPS(rxon_filter_flags
);
1553 DEBUGFS_WRITE_FILE_OPS(txfifo_flush
);
1554 DEBUGFS_READ_FILE_OPS(ucode_bt_stats
);
1557 * Create the debugfs files and directories
1560 int iwl_dbgfs_register(struct iwl_priv
*priv
, const char *name
)
1562 struct dentry
*phyd
= priv
->hw
->wiphy
->debugfsdir
;
1563 struct dentry
*dir_drv
, *dir_data
, *dir_rf
, *dir_debug
;
1565 dir_drv
= debugfs_create_dir(name
, phyd
);
1569 priv
->debugfs_dir
= dir_drv
;
1571 dir_data
= debugfs_create_dir("data", dir_drv
);
1574 dir_rf
= debugfs_create_dir("rf", dir_drv
);
1577 dir_debug
= debugfs_create_dir("debug", dir_drv
);
1581 DEBUGFS_ADD_FILE(nvm
, dir_data
, S_IRUSR
);
1582 DEBUGFS_ADD_FILE(sram
, dir_data
, S_IWUSR
| S_IRUSR
);
1583 DEBUGFS_ADD_FILE(log_event
, dir_data
, S_IWUSR
| S_IRUSR
);
1584 DEBUGFS_ADD_FILE(stations
, dir_data
, S_IRUSR
);
1585 DEBUGFS_ADD_FILE(channels
, dir_data
, S_IRUSR
);
1586 DEBUGFS_ADD_FILE(status
, dir_data
, S_IRUSR
);
1587 DEBUGFS_ADD_FILE(interrupt
, dir_data
, S_IWUSR
| S_IRUSR
);
1588 DEBUGFS_ADD_FILE(qos
, dir_data
, S_IRUSR
);
1589 DEBUGFS_ADD_FILE(led
, dir_data
, S_IRUSR
);
1590 if (!priv
->cfg
->broken_powersave
) {
1591 DEBUGFS_ADD_FILE(sleep_level_override
, dir_data
,
1593 DEBUGFS_ADD_FILE(current_sleep_command
, dir_data
, S_IRUSR
);
1595 DEBUGFS_ADD_FILE(thermal_throttling
, dir_data
, S_IRUSR
);
1596 DEBUGFS_ADD_FILE(disable_ht40
, dir_data
, S_IWUSR
| S_IRUSR
);
1597 DEBUGFS_ADD_FILE(rx_statistics
, dir_debug
, S_IRUSR
);
1598 DEBUGFS_ADD_FILE(tx_statistics
, dir_debug
, S_IRUSR
);
1599 DEBUGFS_ADD_FILE(traffic_log
, dir_debug
, S_IWUSR
| S_IRUSR
);
1600 DEBUGFS_ADD_FILE(rx_queue
, dir_debug
, S_IRUSR
);
1601 DEBUGFS_ADD_FILE(tx_queue
, dir_debug
, S_IRUSR
);
1602 DEBUGFS_ADD_FILE(power_save_status
, dir_debug
, S_IRUSR
);
1603 DEBUGFS_ADD_FILE(clear_ucode_statistics
, dir_debug
, S_IWUSR
);
1604 DEBUGFS_ADD_FILE(clear_traffic_statistics
, dir_debug
, S_IWUSR
);
1605 DEBUGFS_ADD_FILE(csr
, dir_debug
, S_IWUSR
);
1606 DEBUGFS_ADD_FILE(fh_reg
, dir_debug
, S_IRUSR
);
1607 DEBUGFS_ADD_FILE(missed_beacon
, dir_debug
, S_IWUSR
);
1608 DEBUGFS_ADD_FILE(plcp_delta
, dir_debug
, S_IWUSR
| S_IRUSR
);
1609 DEBUGFS_ADD_FILE(force_reset
, dir_debug
, S_IWUSR
| S_IRUSR
);
1610 DEBUGFS_ADD_FILE(ucode_rx_stats
, dir_debug
, S_IRUSR
);
1611 DEBUGFS_ADD_FILE(ucode_tx_stats
, dir_debug
, S_IRUSR
);
1612 DEBUGFS_ADD_FILE(ucode_general_stats
, dir_debug
, S_IRUSR
);
1613 if (priv
->cfg
->ops
->lib
->dev_txfifo_flush
)
1614 DEBUGFS_ADD_FILE(txfifo_flush
, dir_debug
, S_IWUSR
);
1616 if (priv
->cfg
->sensitivity_calib_by_driver
)
1617 DEBUGFS_ADD_FILE(sensitivity
, dir_debug
, S_IRUSR
);
1618 if (priv
->cfg
->chain_noise_calib_by_driver
)
1619 DEBUGFS_ADD_FILE(chain_noise
, dir_debug
, S_IRUSR
);
1620 if (priv
->cfg
->ucode_tracing
)
1621 DEBUGFS_ADD_FILE(ucode_tracing
, dir_debug
, S_IWUSR
| S_IRUSR
);
1622 if (priv
->cfg
->bt_statistics
)
1623 DEBUGFS_ADD_FILE(ucode_bt_stats
, dir_debug
, S_IRUSR
);
1624 DEBUGFS_ADD_FILE(rxon_flags
, dir_debug
, S_IWUSR
);
1625 DEBUGFS_ADD_FILE(rxon_filter_flags
, dir_debug
, S_IWUSR
);
1626 if (priv
->cfg
->sensitivity_calib_by_driver
)
1627 DEBUGFS_ADD_BOOL(disable_sensitivity
, dir_rf
,
1628 &priv
->disable_sens_cal
);
1629 if (priv
->cfg
->chain_noise_calib_by_driver
)
1630 DEBUGFS_ADD_BOOL(disable_chain_noise
, dir_rf
,
1631 &priv
->disable_chain_noise_cal
);
1632 if (priv
->cfg
->tx_power_by_driver
)
1633 DEBUGFS_ADD_BOOL(disable_tx_power
, dir_rf
,
1634 &priv
->disable_tx_power_cal
);
1638 IWL_ERR(priv
, "Can't create the debugfs directory\n");
1639 iwl_dbgfs_unregister(priv
);
1642 EXPORT_SYMBOL(iwl_dbgfs_register
);
1645 * Remove the debugfs files and directories
1648 void iwl_dbgfs_unregister(struct iwl_priv
*priv
)
1650 if (!priv
->debugfs_dir
)
1653 debugfs_remove_recursive(priv
->debugfs_dir
);
1654 priv
->debugfs_dir
= NULL
;
1656 EXPORT_SYMBOL(iwl_dbgfs_unregister
);