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
);
395 iwl_legacy_dbgfs_channels_read(struct file
*file
, char __user
*user_buf
,
396 size_t count
, loff_t
*ppos
)
398 struct iwl_priv
*priv
= file
->private_data
;
399 struct ieee80211_channel
*channels
= NULL
;
400 const struct ieee80211_supported_band
*supp_band
= NULL
;
401 int pos
= 0, i
, bufsz
= PAGE_SIZE
;
405 if (!test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
))
408 buf
= kzalloc(bufsz
, GFP_KERNEL
);
410 IWL_ERR(priv
, "Can not allocate Buffer\n");
414 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_2GHZ
);
416 channels
= supp_band
->channels
;
418 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
419 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
420 supp_band
->n_channels
);
422 for (i
= 0; i
< supp_band
->n_channels
; i
++)
423 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
424 "%d: %ddBm: BSS%s%s, %s.\n",
425 channels
[i
].hw_value
,
426 channels
[i
].max_power
,
427 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
428 " (IEEE 802.11h required)" : "",
429 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
430 || (channels
[i
].flags
&
431 IEEE80211_CHAN_RADAR
)) ? "" :
434 IEEE80211_CHAN_PASSIVE_SCAN
?
435 "passive only" : "active/passive");
437 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_5GHZ
);
439 channels
= supp_band
->channels
;
441 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
442 "Displaying %d channels in 5.2GHz band (802.11a)\n",
443 supp_band
->n_channels
);
445 for (i
= 0; i
< supp_band
->n_channels
; i
++)
446 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
447 "%d: %ddBm: BSS%s%s, %s.\n",
448 channels
[i
].hw_value
,
449 channels
[i
].max_power
,
450 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
451 " (IEEE 802.11h required)" : "",
452 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
453 || (channels
[i
].flags
&
454 IEEE80211_CHAN_RADAR
)) ? "" :
457 IEEE80211_CHAN_PASSIVE_SCAN
?
458 "passive only" : "active/passive");
460 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
465 static ssize_t
iwl_legacy_dbgfs_status_read(struct file
*file
,
466 char __user
*user_buf
,
467 size_t count
, loff_t
*ppos
) {
469 struct iwl_priv
*priv
= file
->private_data
;
472 const size_t bufsz
= sizeof(buf
);
474 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_HCMD_ACTIVE:\t %d\n",
475 test_bit(STATUS_HCMD_ACTIVE
, &priv
->status
));
476 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INT_ENABLED:\t %d\n",
477 test_bit(STATUS_INT_ENABLED
, &priv
->status
));
478 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_RF_KILL_HW:\t %d\n",
479 test_bit(STATUS_RF_KILL_HW
, &priv
->status
));
480 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_CT_KILL:\t\t %d\n",
481 test_bit(STATUS_CT_KILL
, &priv
->status
));
482 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INIT:\t\t %d\n",
483 test_bit(STATUS_INIT
, &priv
->status
));
484 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_ALIVE:\t\t %d\n",
485 test_bit(STATUS_ALIVE
, &priv
->status
));
486 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_READY:\t\t %d\n",
487 test_bit(STATUS_READY
, &priv
->status
));
488 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_TEMPERATURE:\t %d\n",
489 test_bit(STATUS_TEMPERATURE
, &priv
->status
));
490 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_GEO_CONFIGURED:\t %d\n",
491 test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
));
492 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_EXIT_PENDING:\t %d\n",
493 test_bit(STATUS_EXIT_PENDING
, &priv
->status
));
494 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_STATISTICS:\t %d\n",
495 test_bit(STATUS_STATISTICS
, &priv
->status
));
496 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCANNING:\t %d\n",
497 test_bit(STATUS_SCANNING
, &priv
->status
));
498 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_ABORTING:\t %d\n",
499 test_bit(STATUS_SCAN_ABORTING
, &priv
->status
));
500 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_HW:\t\t %d\n",
501 test_bit(STATUS_SCAN_HW
, &priv
->status
));
502 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_POWER_PMI:\t %d\n",
503 test_bit(STATUS_POWER_PMI
, &priv
->status
));
504 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_FW_ERROR:\t %d\n",
505 test_bit(STATUS_FW_ERROR
, &priv
->status
));
506 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
509 static ssize_t
iwl_legacy_dbgfs_interrupt_read(struct file
*file
,
510 char __user
*user_buf
,
511 size_t count
, loff_t
*ppos
) {
513 struct iwl_priv
*priv
= file
->private_data
;
517 int bufsz
= 24 * 64; /* 24 items * 64 char per item */
520 buf
= kzalloc(bufsz
, GFP_KERNEL
);
522 IWL_ERR(priv
, "Can not allocate Buffer\n");
526 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
527 "Interrupt Statistics Report:\n");
529 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "HW Error:\t\t\t %u\n",
531 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "SW Error:\t\t\t %u\n",
533 if (priv
->isr_stats
.sw
|| priv
->isr_stats
.hw
) {
534 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
535 "\tLast Restarting Code: 0x%X\n",
536 priv
->isr_stats
.err_code
);
538 #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
539 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Frame transmitted:\t\t %u\n",
540 priv
->isr_stats
.sch
);
541 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Alive interrupt:\t\t %u\n",
542 priv
->isr_stats
.alive
);
544 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
545 "HW RF KILL switch toggled:\t %u\n",
546 priv
->isr_stats
.rfkill
);
548 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "CT KILL:\t\t\t %u\n",
549 priv
->isr_stats
.ctkill
);
551 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Wakeup Interrupt:\t\t %u\n",
552 priv
->isr_stats
.wakeup
);
554 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
555 "Rx command responses:\t\t %u\n",
557 for (cnt
= 0; cnt
< REPLY_MAX
; cnt
++) {
558 if (priv
->isr_stats
.rx_handlers
[cnt
] > 0)
559 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
560 "\tRx handler[%36s]:\t\t %u\n",
561 iwl_legacy_get_cmd_string(cnt
),
562 priv
->isr_stats
.rx_handlers
[cnt
]);
565 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx/FH interrupt:\t\t %u\n",
568 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Unexpected INTA:\t\t %u\n",
569 priv
->isr_stats
.unhandled
);
571 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
576 static ssize_t
iwl_legacy_dbgfs_interrupt_write(struct file
*file
,
577 const char __user
*user_buf
,
578 size_t count
, loff_t
*ppos
)
580 struct iwl_priv
*priv
= file
->private_data
;
585 memset(buf
, 0, sizeof(buf
));
586 buf_size
= min(count
, sizeof(buf
) - 1);
587 if (copy_from_user(buf
, user_buf
, buf_size
))
589 if (sscanf(buf
, "%x", &reset_flag
) != 1)
592 iwl_legacy_clear_isr_stats(priv
);
598 iwl_legacy_dbgfs_qos_read(struct file
*file
, char __user
*user_buf
,
599 size_t count
, loff_t
*ppos
)
601 struct iwl_priv
*priv
= file
->private_data
;
602 struct iwl_rxon_context
*ctx
;
604 char buf
[256 * NUM_IWL_RXON_CTX
];
605 const size_t bufsz
= sizeof(buf
);
607 for_each_context(priv
, ctx
) {
608 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "context %d:\n",
610 for (i
= 0; i
< AC_NUM
; i
++) {
611 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
612 "\tcw_min\tcw_max\taifsn\ttxop\n");
613 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
614 "AC[%d]\t%u\t%u\t%u\t%u\n", i
,
615 ctx
->qos_data
.def_qos_parm
.ac
[i
].cw_min
,
616 ctx
->qos_data
.def_qos_parm
.ac
[i
].cw_max
,
617 ctx
->qos_data
.def_qos_parm
.ac
[i
].aifsn
,
618 ctx
->qos_data
.def_qos_parm
.ac
[i
].edca_txop
);
620 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
622 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
625 static ssize_t
iwl_legacy_dbgfs_disable_ht40_write(struct file
*file
,
626 const char __user
*user_buf
,
627 size_t count
, loff_t
*ppos
)
629 struct iwl_priv
*priv
= file
->private_data
;
634 memset(buf
, 0, sizeof(buf
));
635 buf_size
= min(count
, sizeof(buf
) - 1);
636 if (copy_from_user(buf
, user_buf
, buf_size
))
638 if (sscanf(buf
, "%d", &ht40
) != 1)
640 if (!iwl_legacy_is_any_associated(priv
))
641 priv
->disable_ht40
= ht40
? true : false;
643 IWL_ERR(priv
, "Sta associated with AP - "
644 "Change to 40MHz channel support is not allowed\n");
651 static ssize_t
iwl_legacy_dbgfs_disable_ht40_read(struct file
*file
,
652 char __user
*user_buf
,
653 size_t count
, loff_t
*ppos
)
655 struct iwl_priv
*priv
= file
->private_data
;
658 const size_t bufsz
= sizeof(buf
);
660 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
661 "11n 40MHz Mode: %s\n",
662 priv
->disable_ht40
? "Disabled" : "Enabled");
663 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
666 DEBUGFS_READ_WRITE_FILE_OPS(sram
);
667 DEBUGFS_READ_FILE_OPS(nvm
);
668 DEBUGFS_READ_FILE_OPS(stations
);
669 DEBUGFS_READ_FILE_OPS(channels
);
670 DEBUGFS_READ_FILE_OPS(status
);
671 DEBUGFS_READ_WRITE_FILE_OPS(interrupt
);
672 DEBUGFS_READ_FILE_OPS(qos
);
673 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40
);
675 static ssize_t
iwl_legacy_dbgfs_traffic_log_read(struct file
*file
,
676 char __user
*user_buf
,
677 size_t count
, loff_t
*ppos
)
679 struct iwl_priv
*priv
= file
->private_data
;
680 int pos
= 0, ofs
= 0;
682 struct iwl_tx_queue
*txq
;
684 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
686 int bufsz
= ((IWL_TRAFFIC_ENTRIES
* IWL_TRAFFIC_ENTRY_SIZE
* 64) * 2) +
687 (priv
->cfg
->base_params
->num_of_queues
* 32 * 8) + 400;
692 IWL_ERR(priv
, "txq not ready\n");
695 buf
= kzalloc(bufsz
, GFP_KERNEL
);
697 IWL_ERR(priv
, "Can not allocate buffer\n");
700 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx Queue\n");
701 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
702 txq
= &priv
->txq
[cnt
];
704 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
705 "q[%d]: read_ptr: %u, write_ptr: %u\n",
706 cnt
, q
->read_ptr
, q
->write_ptr
);
708 if (priv
->tx_traffic
&& (iwlegacy_debug_level
& IWL_DL_TX
)) {
709 ptr
= priv
->tx_traffic
;
710 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
711 "Tx Traffic idx: %u\n", priv
->tx_traffic_idx
);
712 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
713 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
714 entry
++, ofs
+= 16) {
715 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
717 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
718 buf
+ pos
, bufsz
- pos
, 0);
719 pos
+= strlen(buf
+ pos
);
726 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Rx Queue\n");
727 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
728 "read: %u, write: %u\n",
729 rxq
->read
, rxq
->write
);
731 if (priv
->rx_traffic
&& (iwlegacy_debug_level
& IWL_DL_RX
)) {
732 ptr
= priv
->rx_traffic
;
733 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
734 "Rx Traffic idx: %u\n", priv
->rx_traffic_idx
);
735 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
736 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
737 entry
++, ofs
+= 16) {
738 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
740 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
741 buf
+ pos
, bufsz
- pos
, 0);
742 pos
+= strlen(buf
+ pos
);
749 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
754 static ssize_t
iwl_legacy_dbgfs_traffic_log_write(struct file
*file
,
755 const char __user
*user_buf
,
756 size_t count
, loff_t
*ppos
)
758 struct iwl_priv
*priv
= file
->private_data
;
763 memset(buf
, 0, sizeof(buf
));
764 buf_size
= min(count
, sizeof(buf
) - 1);
765 if (copy_from_user(buf
, user_buf
, buf_size
))
767 if (sscanf(buf
, "%d", &traffic_log
) != 1)
769 if (traffic_log
== 0)
770 iwl_legacy_reset_traffic_log(priv
);
775 static ssize_t
iwl_legacy_dbgfs_tx_queue_read(struct file
*file
,
776 char __user
*user_buf
,
777 size_t count
, loff_t
*ppos
) {
779 struct iwl_priv
*priv
= file
->private_data
;
780 struct iwl_tx_queue
*txq
;
786 const size_t bufsz
= sizeof(char) * 64 *
787 priv
->cfg
->base_params
->num_of_queues
;
790 IWL_ERR(priv
, "txq not ready\n");
793 buf
= kzalloc(bufsz
, GFP_KERNEL
);
797 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
798 txq
= &priv
->txq
[cnt
];
800 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
801 "hwq %.2d: read=%u write=%u stop=%d"
802 " swq_id=%#.2x (ac %d/hwq %d)\n",
803 cnt
, q
->read_ptr
, q
->write_ptr
,
804 !!test_bit(cnt
, priv
->queue_stopped
),
805 txq
->swq_id
, txq
->swq_id
& 3,
806 (txq
->swq_id
>> 2) & 0x1f);
809 /* for the ACs, display the stop count too */
810 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
812 atomic_read(&priv
->queue_stop_count
[cnt
]));
814 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
819 static ssize_t
iwl_legacy_dbgfs_rx_queue_read(struct file
*file
,
820 char __user
*user_buf
,
821 size_t count
, loff_t
*ppos
) {
823 struct iwl_priv
*priv
= file
->private_data
;
824 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
827 const size_t bufsz
= sizeof(buf
);
829 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "read: %u\n",
831 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "write: %u\n",
833 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "free_count: %u\n",
836 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "closed_rb_num: %u\n",
837 le16_to_cpu(rxq
->rb_stts
->closed_rb_num
) & 0x0FFF);
839 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
840 "closed_rb_num: Not Allocated\n");
842 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
845 static ssize_t
iwl_legacy_dbgfs_ucode_rx_stats_read(struct file
*file
,
846 char __user
*user_buf
,
847 size_t count
, loff_t
*ppos
)
849 struct iwl_priv
*priv
= file
->private_data
;
850 return priv
->cfg
->ops
->lib
->debugfs_ops
.rx_stats_read(file
,
851 user_buf
, count
, ppos
);
854 static ssize_t
iwl_legacy_dbgfs_ucode_tx_stats_read(struct file
*file
,
855 char __user
*user_buf
,
856 size_t count
, loff_t
*ppos
)
858 struct iwl_priv
*priv
= file
->private_data
;
859 return priv
->cfg
->ops
->lib
->debugfs_ops
.tx_stats_read(file
,
860 user_buf
, count
, ppos
);
863 static ssize_t
iwl_legacy_dbgfs_ucode_general_stats_read(struct file
*file
,
864 char __user
*user_buf
,
865 size_t count
, loff_t
*ppos
)
867 struct iwl_priv
*priv
= file
->private_data
;
868 return priv
->cfg
->ops
->lib
->debugfs_ops
.general_stats_read(file
,
869 user_buf
, count
, ppos
);
872 static ssize_t
iwl_legacy_dbgfs_sensitivity_read(struct file
*file
,
873 char __user
*user_buf
,
874 size_t count
, loff_t
*ppos
) {
876 struct iwl_priv
*priv
= file
->private_data
;
880 int bufsz
= sizeof(struct iwl_sensitivity_data
) * 4 + 100;
882 struct iwl_sensitivity_data
*data
;
884 data
= &priv
->sensitivity_data
;
885 buf
= kzalloc(bufsz
, GFP_KERNEL
);
887 IWL_ERR(priv
, "Can not allocate Buffer\n");
891 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm:\t\t\t %u\n",
892 data
->auto_corr_ofdm
);
893 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
894 "auto_corr_ofdm_mrc:\t\t %u\n",
895 data
->auto_corr_ofdm_mrc
);
896 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm_x1:\t\t %u\n",
897 data
->auto_corr_ofdm_x1
);
898 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
899 "auto_corr_ofdm_mrc_x1:\t\t %u\n",
900 data
->auto_corr_ofdm_mrc_x1
);
901 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck:\t\t\t %u\n",
902 data
->auto_corr_cck
);
903 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck_mrc:\t\t %u\n",
904 data
->auto_corr_cck_mrc
);
905 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
906 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
907 data
->last_bad_plcp_cnt_ofdm
);
908 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_ofdm:\t\t %u\n",
909 data
->last_fa_cnt_ofdm
);
910 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
911 "last_bad_plcp_cnt_cck:\t\t %u\n",
912 data
->last_bad_plcp_cnt_cck
);
913 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_cck:\t\t %u\n",
914 data
->last_fa_cnt_cck
);
915 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_curr_state:\t\t\t %u\n",
916 data
->nrg_curr_state
);
917 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_prev_state:\t\t\t %u\n",
918 data
->nrg_prev_state
);
919 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_value:\t\t\t");
920 for (cnt
= 0; cnt
< 10; cnt
++) {
921 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
922 data
->nrg_value
[cnt
]);
924 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
925 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_rssi:\t\t");
926 for (cnt
= 0; cnt
< NRG_NUM_PREV_STAT_L
; cnt
++) {
927 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
928 data
->nrg_silence_rssi
[cnt
]);
930 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
931 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_ref:\t\t %u\n",
932 data
->nrg_silence_ref
);
933 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_energy_idx:\t\t\t %u\n",
934 data
->nrg_energy_idx
);
935 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_idx:\t\t %u\n",
936 data
->nrg_silence_idx
);
937 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_cck:\t\t\t %u\n",
939 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
940 "nrg_auto_corr_silence_diff:\t %u\n",
941 data
->nrg_auto_corr_silence_diff
);
942 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "num_in_cck_no_fa:\t\t %u\n",
943 data
->num_in_cck_no_fa
);
944 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_ofdm:\t\t\t %u\n",
947 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
953 static ssize_t
iwl_legacy_dbgfs_chain_noise_read(struct file
*file
,
954 char __user
*user_buf
,
955 size_t count
, loff_t
*ppos
) {
957 struct iwl_priv
*priv
= file
->private_data
;
961 int bufsz
= sizeof(struct iwl_chain_noise_data
) * 4 + 100;
963 struct iwl_chain_noise_data
*data
;
965 data
= &priv
->chain_noise_data
;
966 buf
= kzalloc(bufsz
, GFP_KERNEL
);
968 IWL_ERR(priv
, "Can not allocate Buffer\n");
972 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "active_chains:\t\t\t %u\n",
973 data
->active_chains
);
974 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_a:\t\t\t %u\n",
975 data
->chain_noise_a
);
976 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_b:\t\t\t %u\n",
977 data
->chain_noise_b
);
978 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_c:\t\t\t %u\n",
979 data
->chain_noise_c
);
980 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_a:\t\t\t %u\n",
981 data
->chain_signal_a
);
982 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_b:\t\t\t %u\n",
983 data
->chain_signal_b
);
984 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_c:\t\t\t %u\n",
985 data
->chain_signal_c
);
986 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "beacon_count:\t\t\t %u\n",
989 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "disconn_array:\t\t\t");
990 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
991 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
992 data
->disconn_array
[cnt
]);
994 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
995 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "delta_gain_code:\t\t");
996 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
997 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
998 data
->delta_gain_code
[cnt
]);
1000 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1001 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "radio_write:\t\t\t %u\n",
1003 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "state:\t\t\t\t %u\n",
1006 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1011 static ssize_t
iwl_legacy_dbgfs_power_save_status_read(struct file
*file
,
1012 char __user
*user_buf
,
1013 size_t count
, loff_t
*ppos
)
1015 struct iwl_priv
*priv
= file
->private_data
;
1018 const size_t bufsz
= sizeof(buf
);
1021 pwrsave_status
= iwl_read32(priv
, CSR_GP_CNTRL
) &
1022 CSR_GP_REG_POWER_SAVE_STATUS_MSK
;
1024 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Power Save Status: ");
1025 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%s\n",
1026 (pwrsave_status
== CSR_GP_REG_NO_POWER_SAVE
) ? "none" :
1027 (pwrsave_status
== CSR_GP_REG_MAC_POWER_SAVE
) ? "MAC" :
1028 (pwrsave_status
== CSR_GP_REG_PHY_POWER_SAVE
) ? "PHY" :
1031 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1034 static ssize_t
iwl_legacy_dbgfs_clear_ucode_statistics_write(struct file
*file
,
1035 const char __user
*user_buf
,
1036 size_t count
, loff_t
*ppos
)
1038 struct iwl_priv
*priv
= file
->private_data
;
1043 memset(buf
, 0, sizeof(buf
));
1044 buf_size
= min(count
, sizeof(buf
) - 1);
1045 if (copy_from_user(buf
, user_buf
, buf_size
))
1047 if (sscanf(buf
, "%d", &clear
) != 1)
1050 /* make request to uCode to retrieve statistics information */
1051 mutex_lock(&priv
->mutex
);
1052 iwl_legacy_send_statistics_request(priv
, CMD_SYNC
, true);
1053 mutex_unlock(&priv
->mutex
);
1058 static ssize_t
iwl_legacy_dbgfs_rxon_flags_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 len
= sprintf(buf
, "0x%04X\n",
1067 le32_to_cpu(priv
->contexts
[IWL_RXON_CTX_BSS
].active
.flags
));
1068 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1071 static ssize_t
iwl_legacy_dbgfs_rxon_filter_flags_read(struct file
*file
,
1072 char __user
*user_buf
,
1073 size_t count
, loff_t
*ppos
) {
1075 struct iwl_priv
*priv
= file
->private_data
;
1079 len
= sprintf(buf
, "0x%04X\n",
1080 le32_to_cpu(priv
->contexts
[IWL_RXON_CTX_BSS
].active
.filter_flags
));
1081 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1084 static ssize_t
iwl_legacy_dbgfs_fh_reg_read(struct file
*file
,
1085 char __user
*user_buf
,
1086 size_t count
, loff_t
*ppos
)
1088 struct iwl_priv
*priv
= file
->private_data
;
1091 ssize_t ret
= -EFAULT
;
1093 if (priv
->cfg
->ops
->lib
->dump_fh
) {
1094 ret
= pos
= priv
->cfg
->ops
->lib
->dump_fh(priv
, &buf
, true);
1096 ret
= simple_read_from_buffer(user_buf
,
1097 count
, ppos
, buf
, pos
);
1105 static ssize_t
iwl_legacy_dbgfs_missed_beacon_read(struct file
*file
,
1106 char __user
*user_buf
,
1107 size_t count
, loff_t
*ppos
) {
1109 struct iwl_priv
*priv
= file
->private_data
;
1112 const size_t bufsz
= sizeof(buf
);
1114 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%d\n",
1115 priv
->missed_beacon_threshold
);
1117 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1120 static ssize_t
iwl_legacy_dbgfs_missed_beacon_write(struct file
*file
,
1121 const char __user
*user_buf
,
1122 size_t count
, loff_t
*ppos
)
1124 struct iwl_priv
*priv
= file
->private_data
;
1129 memset(buf
, 0, sizeof(buf
));
1130 buf_size
= min(count
, sizeof(buf
) - 1);
1131 if (copy_from_user(buf
, user_buf
, buf_size
))
1133 if (sscanf(buf
, "%d", &missed
) != 1)
1136 if (missed
< IWL_MISSED_BEACON_THRESHOLD_MIN
||
1137 missed
> IWL_MISSED_BEACON_THRESHOLD_MAX
)
1138 priv
->missed_beacon_threshold
=
1139 IWL_MISSED_BEACON_THRESHOLD_DEF
;
1141 priv
->missed_beacon_threshold
= missed
;
1146 static ssize_t
iwl_legacy_dbgfs_force_reset_read(struct file
*file
,
1147 char __user
*user_buf
,
1148 size_t count
, loff_t
*ppos
) {
1150 struct iwl_priv
*priv
= file
->private_data
;
1153 const size_t bufsz
= sizeof(buf
);
1154 struct iwl_force_reset
*force_reset
;
1156 force_reset
= &priv
->force_reset
;
1158 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1159 "\tnumber of reset request: %d\n",
1160 force_reset
->reset_request_count
);
1161 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1162 "\tnumber of reset request success: %d\n",
1163 force_reset
->reset_success_count
);
1164 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1165 "\tnumber of reset request reject: %d\n",
1166 force_reset
->reset_reject_count
);
1167 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1168 "\treset duration: %lu\n",
1169 force_reset
->reset_duration
);
1171 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1174 static ssize_t
iwl_legacy_dbgfs_force_reset_write(struct file
*file
,
1175 const char __user
*user_buf
,
1176 size_t count
, loff_t
*ppos
) {
1179 struct iwl_priv
*priv
= file
->private_data
;
1181 ret
= iwl_legacy_force_reset(priv
, true);
1183 return ret
? ret
: count
;
1186 static ssize_t
iwl_legacy_dbgfs_wd_timeout_write(struct file
*file
,
1187 const char __user
*user_buf
,
1188 size_t count
, loff_t
*ppos
) {
1190 struct iwl_priv
*priv
= file
->private_data
;
1195 memset(buf
, 0, sizeof(buf
));
1196 buf_size
= min(count
, sizeof(buf
) - 1);
1197 if (copy_from_user(buf
, user_buf
, buf_size
))
1199 if (sscanf(buf
, "%d", &timeout
) != 1)
1201 if (timeout
< 0 || timeout
> IWL_MAX_WD_TIMEOUT
)
1202 timeout
= IWL_DEF_WD_TIMEOUT
;
1204 priv
->cfg
->base_params
->wd_timeout
= timeout
;
1205 iwl_legacy_setup_watchdog(priv
);
1209 DEBUGFS_READ_FILE_OPS(rx_statistics
);
1210 DEBUGFS_READ_FILE_OPS(tx_statistics
);
1211 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log
);
1212 DEBUGFS_READ_FILE_OPS(rx_queue
);
1213 DEBUGFS_READ_FILE_OPS(tx_queue
);
1214 DEBUGFS_READ_FILE_OPS(ucode_rx_stats
);
1215 DEBUGFS_READ_FILE_OPS(ucode_tx_stats
);
1216 DEBUGFS_READ_FILE_OPS(ucode_general_stats
);
1217 DEBUGFS_READ_FILE_OPS(sensitivity
);
1218 DEBUGFS_READ_FILE_OPS(chain_noise
);
1219 DEBUGFS_READ_FILE_OPS(power_save_status
);
1220 DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics
);
1221 DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics
);
1222 DEBUGFS_READ_FILE_OPS(fh_reg
);
1223 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon
);
1224 DEBUGFS_READ_WRITE_FILE_OPS(force_reset
);
1225 DEBUGFS_READ_FILE_OPS(rxon_flags
);
1226 DEBUGFS_READ_FILE_OPS(rxon_filter_flags
);
1227 DEBUGFS_WRITE_FILE_OPS(wd_timeout
);
1230 * Create the debugfs files and directories
1233 int iwl_legacy_dbgfs_register(struct iwl_priv
*priv
, const char *name
)
1235 struct dentry
*phyd
= priv
->hw
->wiphy
->debugfsdir
;
1236 struct dentry
*dir_drv
, *dir_data
, *dir_rf
, *dir_debug
;
1238 dir_drv
= debugfs_create_dir(name
, phyd
);
1242 priv
->debugfs_dir
= dir_drv
;
1244 dir_data
= debugfs_create_dir("data", dir_drv
);
1247 dir_rf
= debugfs_create_dir("rf", dir_drv
);
1250 dir_debug
= debugfs_create_dir("debug", dir_drv
);
1254 DEBUGFS_ADD_FILE(nvm
, dir_data
, S_IRUSR
);
1255 DEBUGFS_ADD_FILE(sram
, dir_data
, S_IWUSR
| S_IRUSR
);
1256 DEBUGFS_ADD_FILE(stations
, dir_data
, S_IRUSR
);
1257 DEBUGFS_ADD_FILE(channels
, dir_data
, S_IRUSR
);
1258 DEBUGFS_ADD_FILE(status
, dir_data
, S_IRUSR
);
1259 DEBUGFS_ADD_FILE(interrupt
, dir_data
, S_IWUSR
| S_IRUSR
);
1260 DEBUGFS_ADD_FILE(qos
, dir_data
, S_IRUSR
);
1261 DEBUGFS_ADD_FILE(disable_ht40
, dir_data
, S_IWUSR
| S_IRUSR
);
1262 DEBUGFS_ADD_FILE(rx_statistics
, dir_debug
, S_IRUSR
);
1263 DEBUGFS_ADD_FILE(tx_statistics
, dir_debug
, S_IRUSR
);
1264 DEBUGFS_ADD_FILE(traffic_log
, dir_debug
, S_IWUSR
| S_IRUSR
);
1265 DEBUGFS_ADD_FILE(rx_queue
, dir_debug
, S_IRUSR
);
1266 DEBUGFS_ADD_FILE(tx_queue
, dir_debug
, S_IRUSR
);
1267 DEBUGFS_ADD_FILE(power_save_status
, dir_debug
, S_IRUSR
);
1268 DEBUGFS_ADD_FILE(clear_ucode_statistics
, dir_debug
, S_IWUSR
);
1269 DEBUGFS_ADD_FILE(clear_traffic_statistics
, dir_debug
, S_IWUSR
);
1270 DEBUGFS_ADD_FILE(fh_reg
, dir_debug
, S_IRUSR
);
1271 DEBUGFS_ADD_FILE(missed_beacon
, dir_debug
, S_IWUSR
);
1272 DEBUGFS_ADD_FILE(force_reset
, dir_debug
, S_IWUSR
| S_IRUSR
);
1273 DEBUGFS_ADD_FILE(ucode_rx_stats
, dir_debug
, S_IRUSR
);
1274 DEBUGFS_ADD_FILE(ucode_tx_stats
, dir_debug
, S_IRUSR
);
1275 DEBUGFS_ADD_FILE(ucode_general_stats
, dir_debug
, S_IRUSR
);
1277 if (priv
->cfg
->base_params
->sensitivity_calib_by_driver
)
1278 DEBUGFS_ADD_FILE(sensitivity
, dir_debug
, S_IRUSR
);
1279 if (priv
->cfg
->base_params
->chain_noise_calib_by_driver
)
1280 DEBUGFS_ADD_FILE(chain_noise
, dir_debug
, S_IRUSR
);
1281 DEBUGFS_ADD_FILE(rxon_flags
, dir_debug
, S_IWUSR
);
1282 DEBUGFS_ADD_FILE(rxon_filter_flags
, dir_debug
, S_IWUSR
);
1283 DEBUGFS_ADD_FILE(wd_timeout
, dir_debug
, S_IWUSR
);
1284 if (priv
->cfg
->base_params
->sensitivity_calib_by_driver
)
1285 DEBUGFS_ADD_BOOL(disable_sensitivity
, dir_rf
,
1286 &priv
->disable_sens_cal
);
1287 if (priv
->cfg
->base_params
->chain_noise_calib_by_driver
)
1288 DEBUGFS_ADD_BOOL(disable_chain_noise
, dir_rf
,
1289 &priv
->disable_chain_noise_cal
);
1290 DEBUGFS_ADD_BOOL(disable_tx_power
, dir_rf
,
1291 &priv
->disable_tx_power_cal
);
1295 IWL_ERR(priv
, "Can't create the debugfs directory\n");
1296 iwl_legacy_dbgfs_unregister(priv
);
1299 EXPORT_SYMBOL(iwl_legacy_dbgfs_register
);
1302 * Remove the debugfs files and directories
1305 void iwl_legacy_dbgfs_unregister(struct iwl_priv
*priv
)
1307 if (!priv
->debugfs_dir
)
1310 debugfs_remove_recursive(priv
->debugfs_dir
);
1311 priv
->debugfs_dir
= NULL
;
1313 EXPORT_SYMBOL(iwl_legacy_dbgfs_unregister
);