1 /******************************************************************************
5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
28 #include <linux/ieee80211.h>
29 #include <net/mac80211.h>
33 #include "iwl-debug.h"
37 /* create and remove of files */
38 #define DEBUGFS_ADD_FILE(name, parent, mode) do { \
39 if (!debugfs_create_file(#name, mode, parent, priv, \
40 &iwl_legacy_dbgfs_##name##_ops)) \
44 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
45 struct dentry *__tmp; \
46 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
48 if (IS_ERR(__tmp) || !__tmp) \
52 #define DEBUGFS_ADD_X32(name, parent, ptr) do { \
53 struct dentry *__tmp; \
54 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
56 if (IS_ERR(__tmp) || !__tmp) \
61 #define DEBUGFS_READ_FUNC(name) \
62 static ssize_t iwl_legacy_dbgfs_##name##_read(struct file *file, \
63 char __user *user_buf, \
64 size_t count, loff_t *ppos);
66 #define DEBUGFS_WRITE_FUNC(name) \
67 static ssize_t iwl_legacy_dbgfs_##name##_write(struct file *file, \
68 const char __user *user_buf, \
69 size_t count, loff_t *ppos);
73 iwl_legacy_dbgfs_open_file_generic(struct inode
*inode
, struct file
*file
)
75 file
->private_data
= inode
->i_private
;
79 #define DEBUGFS_READ_FILE_OPS(name) \
80 DEBUGFS_READ_FUNC(name); \
81 static const struct file_operations iwl_legacy_dbgfs_##name##_ops = { \
82 .read = iwl_legacy_dbgfs_##name##_read, \
83 .open = iwl_legacy_dbgfs_open_file_generic, \
84 .llseek = generic_file_llseek, \
87 #define DEBUGFS_WRITE_FILE_OPS(name) \
88 DEBUGFS_WRITE_FUNC(name); \
89 static const struct file_operations iwl_legacy_dbgfs_##name##_ops = { \
90 .write = iwl_legacy_dbgfs_##name##_write, \
91 .open = iwl_legacy_dbgfs_open_file_generic, \
92 .llseek = generic_file_llseek, \
95 #define DEBUGFS_READ_WRITE_FILE_OPS(name) \
96 DEBUGFS_READ_FUNC(name); \
97 DEBUGFS_WRITE_FUNC(name); \
98 static const struct file_operations iwl_legacy_dbgfs_##name##_ops = { \
99 .write = iwl_legacy_dbgfs_##name##_write, \
100 .read = iwl_legacy_dbgfs_##name##_read, \
101 .open = iwl_legacy_dbgfs_open_file_generic, \
102 .llseek = generic_file_llseek, \
105 static ssize_t
iwl_legacy_dbgfs_tx_statistics_read(struct file
*file
,
106 char __user
*user_buf
,
107 size_t count
, loff_t
*ppos
) {
109 struct iwl_priv
*priv
= file
->private_data
;
115 const size_t bufsz
= 100 +
116 sizeof(char) * 50 * (MANAGEMENT_MAX
+ CONTROL_MAX
);
117 buf
= kzalloc(bufsz
, GFP_KERNEL
);
120 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Management:\n");
121 for (cnt
= 0; cnt
< MANAGEMENT_MAX
; cnt
++) {
122 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
124 iwl_legacy_get_mgmt_string(cnt
),
125 priv
->tx_stats
.mgmt
[cnt
]);
127 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Control\n");
128 for (cnt
= 0; cnt
< CONTROL_MAX
; cnt
++) {
129 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
131 iwl_legacy_get_ctrl_string(cnt
),
132 priv
->tx_stats
.ctrl
[cnt
]);
134 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Data:\n");
135 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tcnt: %u\n",
136 priv
->tx_stats
.data_cnt
);
137 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tbytes: %llu\n",
138 priv
->tx_stats
.data_bytes
);
139 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
145 iwl_legacy_dbgfs_clear_traffic_statistics_write(struct file
*file
,
146 const char __user
*user_buf
,
147 size_t count
, loff_t
*ppos
)
149 struct iwl_priv
*priv
= file
->private_data
;
154 memset(buf
, 0, sizeof(buf
));
155 buf_size
= min(count
, sizeof(buf
) - 1);
156 if (copy_from_user(buf
, user_buf
, buf_size
))
158 if (sscanf(buf
, "%x", &clear_flag
) != 1)
160 iwl_legacy_clear_traffic_stats(priv
);
165 static ssize_t
iwl_legacy_dbgfs_rx_statistics_read(struct file
*file
,
166 char __user
*user_buf
,
167 size_t count
, loff_t
*ppos
) {
169 struct iwl_priv
*priv
= file
->private_data
;
174 const size_t bufsz
= 100 +
175 sizeof(char) * 50 * (MANAGEMENT_MAX
+ CONTROL_MAX
);
176 buf
= kzalloc(bufsz
, GFP_KERNEL
);
180 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Management:\n");
181 for (cnt
= 0; cnt
< MANAGEMENT_MAX
; cnt
++) {
182 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
184 iwl_legacy_get_mgmt_string(cnt
),
185 priv
->rx_stats
.mgmt
[cnt
]);
187 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Control:\n");
188 for (cnt
= 0; cnt
< CONTROL_MAX
; cnt
++) {
189 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
191 iwl_legacy_get_ctrl_string(cnt
),
192 priv
->rx_stats
.ctrl
[cnt
]);
194 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Data:\n");
195 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tcnt: %u\n",
196 priv
->rx_stats
.data_cnt
);
197 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tbytes: %llu\n",
198 priv
->rx_stats
.data_bytes
);
200 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
205 #define BYTE1_MASK 0x000000ff;
206 #define BYTE2_MASK 0x0000ffff;
207 #define BYTE3_MASK 0x00ffffff;
208 static ssize_t
iwl_legacy_dbgfs_sram_read(struct file
*file
,
209 char __user
*user_buf
,
210 size_t count
, loff_t
*ppos
)
217 struct iwl_priv
*priv
= file
->private_data
;
220 /* default is to dump the entire data segment */
221 if (!priv
->dbgfs_sram_offset
&& !priv
->dbgfs_sram_len
) {
222 priv
->dbgfs_sram_offset
= 0x800000;
223 if (priv
->ucode_type
== UCODE_INIT
)
224 priv
->dbgfs_sram_len
= priv
->ucode_init_data
.len
;
226 priv
->dbgfs_sram_len
= priv
->ucode_data
.len
;
228 bufsz
= 30 + priv
->dbgfs_sram_len
* sizeof(char) * 10;
229 buf
= kmalloc(bufsz
, GFP_KERNEL
);
232 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "sram_len: 0x%x\n",
233 priv
->dbgfs_sram_len
);
234 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "sram_offset: 0x%x\n",
235 priv
->dbgfs_sram_offset
);
236 for (i
= priv
->dbgfs_sram_len
; i
> 0; i
-= 4) {
237 val
= iwl_legacy_read_targ_mem(priv
, priv
->dbgfs_sram_offset
+ \
238 priv
->dbgfs_sram_len
- i
);
253 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
254 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "0x%08x ", val
);
256 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
258 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
263 static ssize_t
iwl_legacy_dbgfs_sram_write(struct file
*file
,
264 const char __user
*user_buf
,
265 size_t count
, loff_t
*ppos
)
267 struct iwl_priv
*priv
= file
->private_data
;
272 memset(buf
, 0, sizeof(buf
));
273 buf_size
= min(count
, sizeof(buf
) - 1);
274 if (copy_from_user(buf
, user_buf
, buf_size
))
277 if (sscanf(buf
, "%x,%x", &offset
, &len
) == 2) {
278 priv
->dbgfs_sram_offset
= offset
;
279 priv
->dbgfs_sram_len
= len
;
281 priv
->dbgfs_sram_offset
= 0;
282 priv
->dbgfs_sram_len
= 0;
289 iwl_legacy_dbgfs_stations_read(struct file
*file
, char __user
*user_buf
,
290 size_t count
, loff_t
*ppos
)
292 struct iwl_priv
*priv
= file
->private_data
;
293 struct iwl_station_entry
*station
;
294 int max_sta
= priv
->hw_params
.max_stations
;
298 /* Add 30 for initial string */
299 const size_t bufsz
= 30 + sizeof(char) * 500 * (priv
->num_stations
);
301 buf
= kmalloc(bufsz
, GFP_KERNEL
);
305 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "num of stations: %d\n\n",
308 for (i
= 0; i
< max_sta
; i
++) {
309 station
= &priv
->stations
[i
];
312 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
313 "station %d - addr: %pM, flags: %#x\n",
314 i
, station
->sta
.sta
.addr
,
315 station
->sta
.station_flags_msk
);
316 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
317 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
318 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
319 "start_idx\tbitmap\t\t\trate_n_flags\n");
321 for (j
= 0; j
< MAX_TID_COUNT
; j
++) {
322 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
323 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
324 j
, station
->tid
[j
].seq_number
,
325 station
->tid
[j
].agg
.txq_id
,
326 station
->tid
[j
].agg
.frame_count
,
327 station
->tid
[j
].tfds_in_queue
,
328 station
->tid
[j
].agg
.start_idx
,
329 station
->tid
[j
].agg
.bitmap
,
330 station
->tid
[j
].agg
.rate_n_flags
);
332 if (station
->tid
[j
].agg
.wait_for_ba
)
333 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
335 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
338 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
341 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
346 static ssize_t
iwl_legacy_dbgfs_nvm_read(struct file
*file
,
347 char __user
*user_buf
,
352 struct iwl_priv
*priv
= file
->private_data
;
353 int pos
= 0, ofs
= 0, buf_size
= 0;
357 size_t eeprom_len
= priv
->cfg
->base_params
->eeprom_size
;
358 buf_size
= 4 * eeprom_len
+ 256;
360 if (eeprom_len
% 16) {
361 IWL_ERR(priv
, "NVM size is not multiple of 16.\n");
367 IWL_ERR(priv
, "Invalid EEPROM memory\n");
371 /* 4 characters for byte 0xYY */
372 buf
= kzalloc(buf_size
, GFP_KERNEL
);
374 IWL_ERR(priv
, "Can not allocate Buffer\n");
377 eeprom_ver
= iwl_legacy_eeprom_query16(priv
, EEPROM_VERSION
);
378 pos
+= scnprintf(buf
+ pos
, buf_size
- pos
, "EEPROM "
379 "version: 0x%x\n", eeprom_ver
);
380 for (ofs
= 0 ; ofs
< eeprom_len
; ofs
+= 16) {
381 pos
+= scnprintf(buf
+ pos
, buf_size
- pos
, "0x%.4x ", ofs
);
382 hex_dump_to_buffer(ptr
+ ofs
, 16 , 16, 2, buf
+ pos
,
384 pos
+= strlen(buf
+ pos
);
385 if (buf_size
- pos
> 0)
389 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
394 static ssize_t
iwl_legacy_dbgfs_log_event_read(struct file
*file
,
395 char __user
*user_buf
,
396 size_t count
, loff_t
*ppos
)
398 struct iwl_priv
*priv
= file
->private_data
;
401 ssize_t ret
= -ENOMEM
;
403 ret
= pos
= priv
->cfg
->ops
->lib
->dump_nic_event_log(
404 priv
, true, &buf
, true);
406 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
412 static ssize_t
iwl_legacy_dbgfs_log_event_write(struct file
*file
,
413 const char __user
*user_buf
,
414 size_t count
, loff_t
*ppos
)
416 struct iwl_priv
*priv
= file
->private_data
;
421 memset(buf
, 0, sizeof(buf
));
422 buf_size
= min(count
, sizeof(buf
) - 1);
423 if (copy_from_user(buf
, user_buf
, buf_size
))
425 if (sscanf(buf
, "%d", &event_log_flag
) != 1)
427 if (event_log_flag
== 1)
428 priv
->cfg
->ops
->lib
->dump_nic_event_log(priv
, true,
437 iwl_legacy_dbgfs_channels_read(struct file
*file
, char __user
*user_buf
,
438 size_t count
, loff_t
*ppos
)
440 struct iwl_priv
*priv
= file
->private_data
;
441 struct ieee80211_channel
*channels
= NULL
;
442 const struct ieee80211_supported_band
*supp_band
= NULL
;
443 int pos
= 0, i
, bufsz
= PAGE_SIZE
;
447 if (!test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
))
450 buf
= kzalloc(bufsz
, GFP_KERNEL
);
452 IWL_ERR(priv
, "Can not allocate Buffer\n");
456 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_2GHZ
);
458 channels
= supp_band
->channels
;
460 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
461 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
462 supp_band
->n_channels
);
464 for (i
= 0; i
< supp_band
->n_channels
; i
++)
465 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
466 "%d: %ddBm: BSS%s%s, %s.\n",
467 channels
[i
].hw_value
,
468 channels
[i
].max_power
,
469 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
470 " (IEEE 802.11h required)" : "",
471 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
472 || (channels
[i
].flags
&
473 IEEE80211_CHAN_RADAR
)) ? "" :
476 IEEE80211_CHAN_PASSIVE_SCAN
?
477 "passive only" : "active/passive");
479 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_5GHZ
);
481 channels
= supp_band
->channels
;
483 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
484 "Displaying %d channels in 5.2GHz band (802.11a)\n",
485 supp_band
->n_channels
);
487 for (i
= 0; i
< supp_band
->n_channels
; i
++)
488 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
489 "%d: %ddBm: BSS%s%s, %s.\n",
490 channels
[i
].hw_value
,
491 channels
[i
].max_power
,
492 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
493 " (IEEE 802.11h required)" : "",
494 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
495 || (channels
[i
].flags
&
496 IEEE80211_CHAN_RADAR
)) ? "" :
499 IEEE80211_CHAN_PASSIVE_SCAN
?
500 "passive only" : "active/passive");
502 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
507 static ssize_t
iwl_legacy_dbgfs_status_read(struct file
*file
,
508 char __user
*user_buf
,
509 size_t count
, loff_t
*ppos
) {
511 struct iwl_priv
*priv
= file
->private_data
;
514 const size_t bufsz
= sizeof(buf
);
516 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_HCMD_ACTIVE:\t %d\n",
517 test_bit(STATUS_HCMD_ACTIVE
, &priv
->status
));
518 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INT_ENABLED:\t %d\n",
519 test_bit(STATUS_INT_ENABLED
, &priv
->status
));
520 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_RF_KILL_HW:\t %d\n",
521 test_bit(STATUS_RF_KILL_HW
, &priv
->status
));
522 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_CT_KILL:\t\t %d\n",
523 test_bit(STATUS_CT_KILL
, &priv
->status
));
524 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INIT:\t\t %d\n",
525 test_bit(STATUS_INIT
, &priv
->status
));
526 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_ALIVE:\t\t %d\n",
527 test_bit(STATUS_ALIVE
, &priv
->status
));
528 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_READY:\t\t %d\n",
529 test_bit(STATUS_READY
, &priv
->status
));
530 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_TEMPERATURE:\t %d\n",
531 test_bit(STATUS_TEMPERATURE
, &priv
->status
));
532 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_GEO_CONFIGURED:\t %d\n",
533 test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
));
534 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_EXIT_PENDING:\t %d\n",
535 test_bit(STATUS_EXIT_PENDING
, &priv
->status
));
536 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_STATISTICS:\t %d\n",
537 test_bit(STATUS_STATISTICS
, &priv
->status
));
538 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCANNING:\t %d\n",
539 test_bit(STATUS_SCANNING
, &priv
->status
));
540 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_ABORTING:\t %d\n",
541 test_bit(STATUS_SCAN_ABORTING
, &priv
->status
));
542 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_HW:\t\t %d\n",
543 test_bit(STATUS_SCAN_HW
, &priv
->status
));
544 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_POWER_PMI:\t %d\n",
545 test_bit(STATUS_POWER_PMI
, &priv
->status
));
546 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_FW_ERROR:\t %d\n",
547 test_bit(STATUS_FW_ERROR
, &priv
->status
));
548 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
551 static ssize_t
iwl_legacy_dbgfs_interrupt_read(struct file
*file
,
552 char __user
*user_buf
,
553 size_t count
, loff_t
*ppos
) {
555 struct iwl_priv
*priv
= file
->private_data
;
559 int bufsz
= 24 * 64; /* 24 items * 64 char per item */
562 buf
= kzalloc(bufsz
, GFP_KERNEL
);
564 IWL_ERR(priv
, "Can not allocate Buffer\n");
568 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
569 "Interrupt Statistics Report:\n");
571 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "HW Error:\t\t\t %u\n",
573 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "SW Error:\t\t\t %u\n",
575 if (priv
->isr_stats
.sw
|| priv
->isr_stats
.hw
) {
576 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
577 "\tLast Restarting Code: 0x%X\n",
578 priv
->isr_stats
.err_code
);
580 #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
581 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Frame transmitted:\t\t %u\n",
582 priv
->isr_stats
.sch
);
583 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Alive interrupt:\t\t %u\n",
584 priv
->isr_stats
.alive
);
586 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
587 "HW RF KILL switch toggled:\t %u\n",
588 priv
->isr_stats
.rfkill
);
590 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "CT KILL:\t\t\t %u\n",
591 priv
->isr_stats
.ctkill
);
593 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Wakeup Interrupt:\t\t %u\n",
594 priv
->isr_stats
.wakeup
);
596 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
597 "Rx command responses:\t\t %u\n",
599 for (cnt
= 0; cnt
< REPLY_MAX
; cnt
++) {
600 if (priv
->isr_stats
.rx_handlers
[cnt
] > 0)
601 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
602 "\tRx handler[%36s]:\t\t %u\n",
603 iwl_legacy_get_cmd_string(cnt
),
604 priv
->isr_stats
.rx_handlers
[cnt
]);
607 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx/FH interrupt:\t\t %u\n",
610 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Unexpected INTA:\t\t %u\n",
611 priv
->isr_stats
.unhandled
);
613 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
618 static ssize_t
iwl_legacy_dbgfs_interrupt_write(struct file
*file
,
619 const char __user
*user_buf
,
620 size_t count
, loff_t
*ppos
)
622 struct iwl_priv
*priv
= file
->private_data
;
627 memset(buf
, 0, sizeof(buf
));
628 buf_size
= min(count
, sizeof(buf
) - 1);
629 if (copy_from_user(buf
, user_buf
, buf_size
))
631 if (sscanf(buf
, "%x", &reset_flag
) != 1)
634 iwl_legacy_clear_isr_stats(priv
);
640 iwl_legacy_dbgfs_qos_read(struct file
*file
, char __user
*user_buf
,
641 size_t count
, loff_t
*ppos
)
643 struct iwl_priv
*priv
= file
->private_data
;
644 struct iwl_rxon_context
*ctx
;
646 char buf
[256 * NUM_IWL_RXON_CTX
];
647 const size_t bufsz
= sizeof(buf
);
649 for_each_context(priv
, ctx
) {
650 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "context %d:\n",
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 ctx
->qos_data
.def_qos_parm
.ac
[i
].cw_min
,
658 ctx
->qos_data
.def_qos_parm
.ac
[i
].cw_max
,
659 ctx
->qos_data
.def_qos_parm
.ac
[i
].aifsn
,
660 ctx
->qos_data
.def_qos_parm
.ac
[i
].edca_txop
);
662 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
664 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
667 static ssize_t
iwl_legacy_dbgfs_disable_ht40_write(struct file
*file
,
668 const char __user
*user_buf
,
669 size_t count
, loff_t
*ppos
)
671 struct iwl_priv
*priv
= file
->private_data
;
676 memset(buf
, 0, sizeof(buf
));
677 buf_size
= min(count
, sizeof(buf
) - 1);
678 if (copy_from_user(buf
, user_buf
, buf_size
))
680 if (sscanf(buf
, "%d", &ht40
) != 1)
682 if (!iwl_legacy_is_any_associated(priv
))
683 priv
->disable_ht40
= ht40
? true : false;
685 IWL_ERR(priv
, "Sta associated with AP - "
686 "Change to 40MHz channel support is not allowed\n");
693 static ssize_t
iwl_legacy_dbgfs_disable_ht40_read(struct file
*file
,
694 char __user
*user_buf
,
695 size_t count
, loff_t
*ppos
)
697 struct iwl_priv
*priv
= file
->private_data
;
700 const size_t bufsz
= sizeof(buf
);
702 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
703 "11n 40MHz Mode: %s\n",
704 priv
->disable_ht40
? "Disabled" : "Enabled");
705 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
708 DEBUGFS_READ_WRITE_FILE_OPS(sram
);
709 DEBUGFS_READ_WRITE_FILE_OPS(log_event
);
710 DEBUGFS_READ_FILE_OPS(nvm
);
711 DEBUGFS_READ_FILE_OPS(stations
);
712 DEBUGFS_READ_FILE_OPS(channels
);
713 DEBUGFS_READ_FILE_OPS(status
);
714 DEBUGFS_READ_WRITE_FILE_OPS(interrupt
);
715 DEBUGFS_READ_FILE_OPS(qos
);
716 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40
);
718 static ssize_t
iwl_legacy_dbgfs_traffic_log_read(struct file
*file
,
719 char __user
*user_buf
,
720 size_t count
, loff_t
*ppos
)
722 struct iwl_priv
*priv
= file
->private_data
;
723 int pos
= 0, ofs
= 0;
725 struct iwl_tx_queue
*txq
;
727 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
729 int bufsz
= ((IWL_TRAFFIC_ENTRIES
* IWL_TRAFFIC_ENTRY_SIZE
* 64) * 2) +
730 (priv
->cfg
->base_params
->num_of_queues
* 32 * 8) + 400;
735 IWL_ERR(priv
, "txq not ready\n");
738 buf
= kzalloc(bufsz
, GFP_KERNEL
);
740 IWL_ERR(priv
, "Can not allocate buffer\n");
743 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx Queue\n");
744 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
745 txq
= &priv
->txq
[cnt
];
747 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
748 "q[%d]: read_ptr: %u, write_ptr: %u\n",
749 cnt
, q
->read_ptr
, q
->write_ptr
);
751 if (priv
->tx_traffic
&& (iwlegacy_debug_level
& IWL_DL_TX
)) {
752 ptr
= priv
->tx_traffic
;
753 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
754 "Tx Traffic idx: %u\n", priv
->tx_traffic_idx
);
755 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
756 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
757 entry
++, ofs
+= 16) {
758 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
760 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
761 buf
+ pos
, bufsz
- pos
, 0);
762 pos
+= strlen(buf
+ pos
);
769 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Rx Queue\n");
770 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
771 "read: %u, write: %u\n",
772 rxq
->read
, rxq
->write
);
774 if (priv
->rx_traffic
&& (iwlegacy_debug_level
& IWL_DL_RX
)) {
775 ptr
= priv
->rx_traffic
;
776 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
777 "Rx Traffic idx: %u\n", priv
->rx_traffic_idx
);
778 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
779 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
780 entry
++, ofs
+= 16) {
781 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
783 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
784 buf
+ pos
, bufsz
- pos
, 0);
785 pos
+= strlen(buf
+ pos
);
792 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
797 static ssize_t
iwl_legacy_dbgfs_traffic_log_write(struct file
*file
,
798 const char __user
*user_buf
,
799 size_t count
, loff_t
*ppos
)
801 struct iwl_priv
*priv
= file
->private_data
;
806 memset(buf
, 0, sizeof(buf
));
807 buf_size
= min(count
, sizeof(buf
) - 1);
808 if (copy_from_user(buf
, user_buf
, buf_size
))
810 if (sscanf(buf
, "%d", &traffic_log
) != 1)
812 if (traffic_log
== 0)
813 iwl_legacy_reset_traffic_log(priv
);
818 static ssize_t
iwl_legacy_dbgfs_tx_queue_read(struct file
*file
,
819 char __user
*user_buf
,
820 size_t count
, loff_t
*ppos
) {
822 struct iwl_priv
*priv
= file
->private_data
;
823 struct iwl_tx_queue
*txq
;
829 const size_t bufsz
= sizeof(char) * 64 *
830 priv
->cfg
->base_params
->num_of_queues
;
833 IWL_ERR(priv
, "txq not ready\n");
836 buf
= kzalloc(bufsz
, GFP_KERNEL
);
840 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
841 txq
= &priv
->txq
[cnt
];
843 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
844 "hwq %.2d: read=%u write=%u stop=%d"
845 " swq_id=%#.2x (ac %d/hwq %d)\n",
846 cnt
, q
->read_ptr
, q
->write_ptr
,
847 !!test_bit(cnt
, priv
->queue_stopped
),
848 txq
->swq_id
, txq
->swq_id
& 3,
849 (txq
->swq_id
>> 2) & 0x1f);
852 /* for the ACs, display the stop count too */
853 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
855 atomic_read(&priv
->queue_stop_count
[cnt
]));
857 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
862 static ssize_t
iwl_legacy_dbgfs_rx_queue_read(struct file
*file
,
863 char __user
*user_buf
,
864 size_t count
, loff_t
*ppos
) {
866 struct iwl_priv
*priv
= file
->private_data
;
867 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
870 const size_t bufsz
= sizeof(buf
);
872 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "read: %u\n",
874 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "write: %u\n",
876 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "free_count: %u\n",
879 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "closed_rb_num: %u\n",
880 le16_to_cpu(rxq
->rb_stts
->closed_rb_num
) & 0x0FFF);
882 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
883 "closed_rb_num: Not Allocated\n");
885 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
888 static ssize_t
iwl_legacy_dbgfs_ucode_rx_stats_read(struct file
*file
,
889 char __user
*user_buf
,
890 size_t count
, loff_t
*ppos
)
892 struct iwl_priv
*priv
= file
->private_data
;
893 return priv
->cfg
->ops
->lib
->debugfs_ops
.rx_stats_read(file
,
894 user_buf
, count
, ppos
);
897 static ssize_t
iwl_legacy_dbgfs_ucode_tx_stats_read(struct file
*file
,
898 char __user
*user_buf
,
899 size_t count
, loff_t
*ppos
)
901 struct iwl_priv
*priv
= file
->private_data
;
902 return priv
->cfg
->ops
->lib
->debugfs_ops
.tx_stats_read(file
,
903 user_buf
, count
, ppos
);
906 static ssize_t
iwl_legacy_dbgfs_ucode_general_stats_read(struct file
*file
,
907 char __user
*user_buf
,
908 size_t count
, loff_t
*ppos
)
910 struct iwl_priv
*priv
= file
->private_data
;
911 return priv
->cfg
->ops
->lib
->debugfs_ops
.general_stats_read(file
,
912 user_buf
, count
, ppos
);
915 static ssize_t
iwl_legacy_dbgfs_sensitivity_read(struct file
*file
,
916 char __user
*user_buf
,
917 size_t count
, loff_t
*ppos
) {
919 struct iwl_priv
*priv
= file
->private_data
;
923 int bufsz
= sizeof(struct iwl_sensitivity_data
) * 4 + 100;
925 struct iwl_sensitivity_data
*data
;
927 data
= &priv
->sensitivity_data
;
928 buf
= kzalloc(bufsz
, GFP_KERNEL
);
930 IWL_ERR(priv
, "Can not allocate Buffer\n");
934 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm:\t\t\t %u\n",
935 data
->auto_corr_ofdm
);
936 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
937 "auto_corr_ofdm_mrc:\t\t %u\n",
938 data
->auto_corr_ofdm_mrc
);
939 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm_x1:\t\t %u\n",
940 data
->auto_corr_ofdm_x1
);
941 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
942 "auto_corr_ofdm_mrc_x1:\t\t %u\n",
943 data
->auto_corr_ofdm_mrc_x1
);
944 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck:\t\t\t %u\n",
945 data
->auto_corr_cck
);
946 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck_mrc:\t\t %u\n",
947 data
->auto_corr_cck_mrc
);
948 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
949 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
950 data
->last_bad_plcp_cnt_ofdm
);
951 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_ofdm:\t\t %u\n",
952 data
->last_fa_cnt_ofdm
);
953 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
954 "last_bad_plcp_cnt_cck:\t\t %u\n",
955 data
->last_bad_plcp_cnt_cck
);
956 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_cck:\t\t %u\n",
957 data
->last_fa_cnt_cck
);
958 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_curr_state:\t\t\t %u\n",
959 data
->nrg_curr_state
);
960 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_prev_state:\t\t\t %u\n",
961 data
->nrg_prev_state
);
962 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_value:\t\t\t");
963 for (cnt
= 0; cnt
< 10; cnt
++) {
964 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
965 data
->nrg_value
[cnt
]);
967 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
968 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_rssi:\t\t");
969 for (cnt
= 0; cnt
< NRG_NUM_PREV_STAT_L
; cnt
++) {
970 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
971 data
->nrg_silence_rssi
[cnt
]);
973 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
974 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_ref:\t\t %u\n",
975 data
->nrg_silence_ref
);
976 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_energy_idx:\t\t\t %u\n",
977 data
->nrg_energy_idx
);
978 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_idx:\t\t %u\n",
979 data
->nrg_silence_idx
);
980 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_cck:\t\t\t %u\n",
982 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
983 "nrg_auto_corr_silence_diff:\t %u\n",
984 data
->nrg_auto_corr_silence_diff
);
985 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "num_in_cck_no_fa:\t\t %u\n",
986 data
->num_in_cck_no_fa
);
987 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_ofdm:\t\t\t %u\n",
990 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
996 static ssize_t
iwl_legacy_dbgfs_chain_noise_read(struct file
*file
,
997 char __user
*user_buf
,
998 size_t count
, loff_t
*ppos
) {
1000 struct iwl_priv
*priv
= file
->private_data
;
1004 int bufsz
= sizeof(struct iwl_chain_noise_data
) * 4 + 100;
1006 struct iwl_chain_noise_data
*data
;
1008 data
= &priv
->chain_noise_data
;
1009 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1011 IWL_ERR(priv
, "Can not allocate Buffer\n");
1015 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "active_chains:\t\t\t %u\n",
1016 data
->active_chains
);
1017 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_a:\t\t\t %u\n",
1018 data
->chain_noise_a
);
1019 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_b:\t\t\t %u\n",
1020 data
->chain_noise_b
);
1021 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_c:\t\t\t %u\n",
1022 data
->chain_noise_c
);
1023 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_a:\t\t\t %u\n",
1024 data
->chain_signal_a
);
1025 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_b:\t\t\t %u\n",
1026 data
->chain_signal_b
);
1027 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_c:\t\t\t %u\n",
1028 data
->chain_signal_c
);
1029 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "beacon_count:\t\t\t %u\n",
1030 data
->beacon_count
);
1032 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "disconn_array:\t\t\t");
1033 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1034 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1035 data
->disconn_array
[cnt
]);
1037 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1038 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "delta_gain_code:\t\t");
1039 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1040 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1041 data
->delta_gain_code
[cnt
]);
1043 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1044 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "radio_write:\t\t\t %u\n",
1046 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "state:\t\t\t\t %u\n",
1049 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1054 static ssize_t
iwl_legacy_dbgfs_power_save_status_read(struct file
*file
,
1055 char __user
*user_buf
,
1056 size_t count
, loff_t
*ppos
)
1058 struct iwl_priv
*priv
= file
->private_data
;
1061 const size_t bufsz
= sizeof(buf
);
1064 pwrsave_status
= iwl_read32(priv
, CSR_GP_CNTRL
) &
1065 CSR_GP_REG_POWER_SAVE_STATUS_MSK
;
1067 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Power Save Status: ");
1068 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%s\n",
1069 (pwrsave_status
== CSR_GP_REG_NO_POWER_SAVE
) ? "none" :
1070 (pwrsave_status
== CSR_GP_REG_MAC_POWER_SAVE
) ? "MAC" :
1071 (pwrsave_status
== CSR_GP_REG_PHY_POWER_SAVE
) ? "PHY" :
1074 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1077 static ssize_t
iwl_legacy_dbgfs_clear_ucode_statistics_write(struct file
*file
,
1078 const char __user
*user_buf
,
1079 size_t count
, loff_t
*ppos
)
1081 struct iwl_priv
*priv
= file
->private_data
;
1086 memset(buf
, 0, sizeof(buf
));
1087 buf_size
= min(count
, sizeof(buf
) - 1);
1088 if (copy_from_user(buf
, user_buf
, buf_size
))
1090 if (sscanf(buf
, "%d", &clear
) != 1)
1093 /* make request to uCode to retrieve statistics information */
1094 mutex_lock(&priv
->mutex
);
1095 iwl_legacy_send_statistics_request(priv
, CMD_SYNC
, true);
1096 mutex_unlock(&priv
->mutex
);
1101 static ssize_t
iwl_legacy_dbgfs_ucode_tracing_read(struct file
*file
,
1102 char __user
*user_buf
,
1103 size_t count
, loff_t
*ppos
) {
1105 struct iwl_priv
*priv
= file
->private_data
;
1108 const size_t bufsz
= sizeof(buf
);
1110 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "ucode trace timer is %s\n",
1111 priv
->event_log
.ucode_trace
? "On" : "Off");
1112 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "non_wraps_count:\t\t %u\n",
1113 priv
->event_log
.non_wraps_count
);
1114 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "wraps_once_count:\t\t %u\n",
1115 priv
->event_log
.wraps_once_count
);
1116 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "wraps_more_count:\t\t %u\n",
1117 priv
->event_log
.wraps_more_count
);
1119 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1122 static ssize_t
iwl_legacy_dbgfs_ucode_tracing_write(struct file
*file
,
1123 const char __user
*user_buf
,
1124 size_t count
, loff_t
*ppos
)
1126 struct iwl_priv
*priv
= file
->private_data
;
1131 memset(buf
, 0, sizeof(buf
));
1132 buf_size
= min(count
, sizeof(buf
) - 1);
1133 if (copy_from_user(buf
, user_buf
, buf_size
))
1135 if (sscanf(buf
, "%d", &trace
) != 1)
1139 priv
->event_log
.ucode_trace
= true;
1140 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
1141 mod_timer(&priv
->ucode_trace
,
1142 jiffies
+ msecs_to_jiffies(UCODE_TRACE_PERIOD
));
1144 priv
->event_log
.ucode_trace
= false;
1145 del_timer_sync(&priv
->ucode_trace
);
1151 static ssize_t
iwl_legacy_dbgfs_rxon_flags_read(struct file
*file
,
1152 char __user
*user_buf
,
1153 size_t count
, loff_t
*ppos
) {
1155 struct iwl_priv
*priv
= file
->private_data
;
1159 len
= sprintf(buf
, "0x%04X\n",
1160 le32_to_cpu(priv
->contexts
[IWL_RXON_CTX_BSS
].active
.flags
));
1161 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1164 static ssize_t
iwl_legacy_dbgfs_rxon_filter_flags_read(struct file
*file
,
1165 char __user
*user_buf
,
1166 size_t count
, loff_t
*ppos
) {
1168 struct iwl_priv
*priv
= file
->private_data
;
1172 len
= sprintf(buf
, "0x%04X\n",
1173 le32_to_cpu(priv
->contexts
[IWL_RXON_CTX_BSS
].active
.filter_flags
));
1174 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1177 static ssize_t
iwl_legacy_dbgfs_fh_reg_read(struct file
*file
,
1178 char __user
*user_buf
,
1179 size_t count
, loff_t
*ppos
)
1181 struct iwl_priv
*priv
= file
->private_data
;
1184 ssize_t ret
= -EFAULT
;
1186 if (priv
->cfg
->ops
->lib
->dump_fh
) {
1187 ret
= pos
= priv
->cfg
->ops
->lib
->dump_fh(priv
, &buf
, true);
1189 ret
= simple_read_from_buffer(user_buf
,
1190 count
, ppos
, buf
, pos
);
1198 static ssize_t
iwl_legacy_dbgfs_missed_beacon_read(struct file
*file
,
1199 char __user
*user_buf
,
1200 size_t count
, loff_t
*ppos
) {
1202 struct iwl_priv
*priv
= file
->private_data
;
1205 const size_t bufsz
= sizeof(buf
);
1207 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%d\n",
1208 priv
->missed_beacon_threshold
);
1210 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1213 static ssize_t
iwl_legacy_dbgfs_missed_beacon_write(struct file
*file
,
1214 const char __user
*user_buf
,
1215 size_t count
, loff_t
*ppos
)
1217 struct iwl_priv
*priv
= file
->private_data
;
1222 memset(buf
, 0, sizeof(buf
));
1223 buf_size
= min(count
, sizeof(buf
) - 1);
1224 if (copy_from_user(buf
, user_buf
, buf_size
))
1226 if (sscanf(buf
, "%d", &missed
) != 1)
1229 if (missed
< IWL_MISSED_BEACON_THRESHOLD_MIN
||
1230 missed
> IWL_MISSED_BEACON_THRESHOLD_MAX
)
1231 priv
->missed_beacon_threshold
=
1232 IWL_MISSED_BEACON_THRESHOLD_DEF
;
1234 priv
->missed_beacon_threshold
= missed
;
1239 static ssize_t
iwl_legacy_dbgfs_plcp_delta_read(struct file
*file
,
1240 char __user
*user_buf
,
1241 size_t count
, loff_t
*ppos
) {
1243 struct iwl_priv
*priv
= file
->private_data
;
1246 const size_t bufsz
= sizeof(buf
);
1248 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%u\n",
1249 priv
->cfg
->base_params
->plcp_delta_threshold
);
1251 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1254 static ssize_t
iwl_legacy_dbgfs_plcp_delta_write(struct file
*file
,
1255 const char __user
*user_buf
,
1256 size_t count
, loff_t
*ppos
) {
1258 struct iwl_priv
*priv
= file
->private_data
;
1263 memset(buf
, 0, sizeof(buf
));
1264 buf_size
= min(count
, sizeof(buf
) - 1);
1265 if (copy_from_user(buf
, user_buf
, buf_size
))
1267 if (sscanf(buf
, "%d", &plcp
) != 1)
1269 if ((plcp
< IWL_MAX_PLCP_ERR_THRESHOLD_MIN
) ||
1270 (plcp
> IWL_MAX_PLCP_ERR_THRESHOLD_MAX
))
1271 priv
->cfg
->base_params
->plcp_delta_threshold
=
1272 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE
;
1274 priv
->cfg
->base_params
->plcp_delta_threshold
= plcp
;
1278 static ssize_t
iwl_legacy_dbgfs_force_reset_read(struct file
*file
,
1279 char __user
*user_buf
,
1280 size_t count
, loff_t
*ppos
) {
1282 struct iwl_priv
*priv
= file
->private_data
;
1285 const size_t bufsz
= sizeof(buf
);
1286 struct iwl_force_reset
*force_reset
;
1288 for (i
= 0; i
< IWL_MAX_FORCE_RESET
; i
++) {
1289 force_reset
= &priv
->force_reset
[i
];
1290 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1291 "Force reset method %d\n", i
);
1292 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1293 "\tnumber of reset request: %d\n",
1294 force_reset
->reset_request_count
);
1295 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1296 "\tnumber of reset request success: %d\n",
1297 force_reset
->reset_success_count
);
1298 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1299 "\tnumber of reset request reject: %d\n",
1300 force_reset
->reset_reject_count
);
1301 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1302 "\treset duration: %lu\n",
1303 force_reset
->reset_duration
);
1305 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1308 static ssize_t
iwl_legacy_dbgfs_force_reset_write(struct file
*file
,
1309 const char __user
*user_buf
,
1310 size_t count
, loff_t
*ppos
) {
1312 struct iwl_priv
*priv
= file
->private_data
;
1317 memset(buf
, 0, sizeof(buf
));
1318 buf_size
= min(count
, sizeof(buf
) - 1);
1319 if (copy_from_user(buf
, user_buf
, buf_size
))
1321 if (sscanf(buf
, "%d", &reset
) != 1)
1326 ret
= iwl_legacy_force_reset(priv
, reset
, true);
1331 return ret
? ret
: count
;
1334 static ssize_t
iwl_legacy_dbgfs_wd_timeout_write(struct file
*file
,
1335 const char __user
*user_buf
,
1336 size_t count
, loff_t
*ppos
) {
1338 struct iwl_priv
*priv
= file
->private_data
;
1343 memset(buf
, 0, sizeof(buf
));
1344 buf_size
= min(count
, sizeof(buf
) - 1);
1345 if (copy_from_user(buf
, user_buf
, buf_size
))
1347 if (sscanf(buf
, "%d", &timeout
) != 1)
1349 if (timeout
< 0 || timeout
> IWL_MAX_WD_TIMEOUT
)
1350 timeout
= IWL_DEF_WD_TIMEOUT
;
1352 priv
->cfg
->base_params
->wd_timeout
= timeout
;
1353 iwl_legacy_setup_watchdog(priv
);
1357 DEBUGFS_READ_FILE_OPS(rx_statistics
);
1358 DEBUGFS_READ_FILE_OPS(tx_statistics
);
1359 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log
);
1360 DEBUGFS_READ_FILE_OPS(rx_queue
);
1361 DEBUGFS_READ_FILE_OPS(tx_queue
);
1362 DEBUGFS_READ_FILE_OPS(ucode_rx_stats
);
1363 DEBUGFS_READ_FILE_OPS(ucode_tx_stats
);
1364 DEBUGFS_READ_FILE_OPS(ucode_general_stats
);
1365 DEBUGFS_READ_FILE_OPS(sensitivity
);
1366 DEBUGFS_READ_FILE_OPS(chain_noise
);
1367 DEBUGFS_READ_FILE_OPS(power_save_status
);
1368 DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics
);
1369 DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics
);
1370 DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing
);
1371 DEBUGFS_READ_FILE_OPS(fh_reg
);
1372 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon
);
1373 DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta
);
1374 DEBUGFS_READ_WRITE_FILE_OPS(force_reset
);
1375 DEBUGFS_READ_FILE_OPS(rxon_flags
);
1376 DEBUGFS_READ_FILE_OPS(rxon_filter_flags
);
1377 DEBUGFS_WRITE_FILE_OPS(wd_timeout
);
1380 * Create the debugfs files and directories
1383 int iwl_legacy_dbgfs_register(struct iwl_priv
*priv
, const char *name
)
1385 struct dentry
*phyd
= priv
->hw
->wiphy
->debugfsdir
;
1386 struct dentry
*dir_drv
, *dir_data
, *dir_rf
, *dir_debug
;
1388 dir_drv
= debugfs_create_dir(name
, phyd
);
1392 priv
->debugfs_dir
= dir_drv
;
1394 dir_data
= debugfs_create_dir("data", dir_drv
);
1397 dir_rf
= debugfs_create_dir("rf", dir_drv
);
1400 dir_debug
= debugfs_create_dir("debug", dir_drv
);
1404 DEBUGFS_ADD_FILE(nvm
, dir_data
, S_IRUSR
);
1405 DEBUGFS_ADD_FILE(sram
, dir_data
, S_IWUSR
| S_IRUSR
);
1406 DEBUGFS_ADD_FILE(log_event
, dir_data
, S_IWUSR
| S_IRUSR
);
1407 DEBUGFS_ADD_FILE(stations
, dir_data
, S_IRUSR
);
1408 DEBUGFS_ADD_FILE(channels
, dir_data
, S_IRUSR
);
1409 DEBUGFS_ADD_FILE(status
, dir_data
, S_IRUSR
);
1410 DEBUGFS_ADD_FILE(interrupt
, dir_data
, S_IWUSR
| S_IRUSR
);
1411 DEBUGFS_ADD_FILE(qos
, dir_data
, S_IRUSR
);
1412 DEBUGFS_ADD_FILE(disable_ht40
, dir_data
, S_IWUSR
| S_IRUSR
);
1413 DEBUGFS_ADD_FILE(rx_statistics
, dir_debug
, S_IRUSR
);
1414 DEBUGFS_ADD_FILE(tx_statistics
, dir_debug
, S_IRUSR
);
1415 DEBUGFS_ADD_FILE(traffic_log
, dir_debug
, S_IWUSR
| S_IRUSR
);
1416 DEBUGFS_ADD_FILE(rx_queue
, dir_debug
, S_IRUSR
);
1417 DEBUGFS_ADD_FILE(tx_queue
, dir_debug
, S_IRUSR
);
1418 DEBUGFS_ADD_FILE(power_save_status
, dir_debug
, S_IRUSR
);
1419 DEBUGFS_ADD_FILE(clear_ucode_statistics
, dir_debug
, S_IWUSR
);
1420 DEBUGFS_ADD_FILE(clear_traffic_statistics
, dir_debug
, S_IWUSR
);
1421 DEBUGFS_ADD_FILE(fh_reg
, dir_debug
, S_IRUSR
);
1422 DEBUGFS_ADD_FILE(missed_beacon
, dir_debug
, S_IWUSR
);
1423 DEBUGFS_ADD_FILE(plcp_delta
, dir_debug
, S_IWUSR
| S_IRUSR
);
1424 DEBUGFS_ADD_FILE(force_reset
, dir_debug
, S_IWUSR
| S_IRUSR
);
1425 DEBUGFS_ADD_FILE(ucode_rx_stats
, dir_debug
, S_IRUSR
);
1426 DEBUGFS_ADD_FILE(ucode_tx_stats
, dir_debug
, S_IRUSR
);
1427 DEBUGFS_ADD_FILE(ucode_general_stats
, dir_debug
, S_IRUSR
);
1429 if (priv
->cfg
->base_params
->sensitivity_calib_by_driver
)
1430 DEBUGFS_ADD_FILE(sensitivity
, dir_debug
, S_IRUSR
);
1431 if (priv
->cfg
->base_params
->chain_noise_calib_by_driver
)
1432 DEBUGFS_ADD_FILE(chain_noise
, dir_debug
, S_IRUSR
);
1433 if (priv
->cfg
->base_params
->ucode_tracing
)
1434 DEBUGFS_ADD_FILE(ucode_tracing
, dir_debug
, S_IWUSR
| S_IRUSR
);
1435 DEBUGFS_ADD_FILE(rxon_flags
, dir_debug
, S_IWUSR
);
1436 DEBUGFS_ADD_FILE(rxon_filter_flags
, dir_debug
, S_IWUSR
);
1437 DEBUGFS_ADD_FILE(wd_timeout
, dir_debug
, S_IWUSR
);
1438 if (priv
->cfg
->base_params
->sensitivity_calib_by_driver
)
1439 DEBUGFS_ADD_BOOL(disable_sensitivity
, dir_rf
,
1440 &priv
->disable_sens_cal
);
1441 if (priv
->cfg
->base_params
->chain_noise_calib_by_driver
)
1442 DEBUGFS_ADD_BOOL(disable_chain_noise
, dir_rf
,
1443 &priv
->disable_chain_noise_cal
);
1444 DEBUGFS_ADD_BOOL(disable_tx_power
, dir_rf
,
1445 &priv
->disable_tx_power_cal
);
1449 IWL_ERR(priv
, "Can't create the debugfs directory\n");
1450 iwl_legacy_dbgfs_unregister(priv
);
1453 EXPORT_SYMBOL(iwl_legacy_dbgfs_register
);
1456 * Remove the debugfs files and directories
1459 void iwl_legacy_dbgfs_unregister(struct iwl_priv
*priv
)
1461 if (!priv
->debugfs_dir
)
1464 debugfs_remove_recursive(priv
->debugfs_dir
);
1465 priv
->debugfs_dir
= NULL
;
1467 EXPORT_SYMBOL(iwl_legacy_dbgfs_unregister
);