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/kernel.h>
30 #include <linux/module.h>
31 #include <linux/debugfs.h>
33 #include <linux/ieee80211.h>
34 #include <net/mac80211.h>
38 #include "iwl-debug.h"
41 #include "iwl-calib.h"
43 /* create and remove of files */
44 #define DEBUGFS_ADD_FILE(name, parent, mode) do { \
45 if (!debugfs_create_file(#name, mode, parent, priv, \
46 &iwl_dbgfs_##name##_ops)) \
50 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
51 struct dentry *__tmp; \
52 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
54 if (IS_ERR(__tmp) || !__tmp) \
58 #define DEBUGFS_ADD_X32(name, parent, ptr) do { \
59 struct dentry *__tmp; \
60 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
62 if (IS_ERR(__tmp) || !__tmp) \
67 #define DEBUGFS_READ_FUNC(name) \
68 static ssize_t iwl_dbgfs_##name##_read(struct file *file, \
69 char __user *user_buf, \
70 size_t count, loff_t *ppos);
72 #define DEBUGFS_WRITE_FUNC(name) \
73 static ssize_t iwl_dbgfs_##name##_write(struct file *file, \
74 const char __user *user_buf, \
75 size_t count, loff_t *ppos);
78 static int iwl_dbgfs_open_file_generic(struct inode
*inode
, struct file
*file
)
80 file
->private_data
= inode
->i_private
;
84 #define DEBUGFS_READ_FILE_OPS(name) \
85 DEBUGFS_READ_FUNC(name); \
86 static const struct file_operations iwl_dbgfs_##name##_ops = { \
87 .read = iwl_dbgfs_##name##_read, \
88 .open = iwl_dbgfs_open_file_generic, \
91 #define DEBUGFS_WRITE_FILE_OPS(name) \
92 DEBUGFS_WRITE_FUNC(name); \
93 static const struct file_operations iwl_dbgfs_##name##_ops = { \
94 .write = iwl_dbgfs_##name##_write, \
95 .open = iwl_dbgfs_open_file_generic, \
99 #define DEBUGFS_READ_WRITE_FILE_OPS(name) \
100 DEBUGFS_READ_FUNC(name); \
101 DEBUGFS_WRITE_FUNC(name); \
102 static const struct file_operations iwl_dbgfs_##name##_ops = { \
103 .write = iwl_dbgfs_##name##_write, \
104 .read = iwl_dbgfs_##name##_read, \
105 .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
];
313 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
314 "station %d:\ngeneral data:\n", i
+1);
315 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "id: %u\n",
316 station
->sta
.sta
.sta_id
);
317 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "mode: %u\n",
319 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
321 station
->sta
.station_flags_msk
);
322 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "tid data:\n");
323 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
324 "seq_num\t\ttxq_id");
325 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
326 "\tframe_count\twait_for_ba\t");
327 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
328 "start_idx\tbitmap0\t");
329 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
330 "bitmap1\trate_n_flags");
331 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
333 for (j
= 0; j
< MAX_TID_COUNT
; j
++) {
334 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
336 station
->tid
[j
].seq_number
);
337 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
338 "\t%u\t\t%u\t\t%u\t\t",
339 station
->tid
[j
].agg
.txq_id
,
340 station
->tid
[j
].agg
.frame_count
,
341 station
->tid
[j
].agg
.wait_for_ba
);
342 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
344 station
->tid
[j
].agg
.start_idx
,
345 (unsigned long long)station
->tid
[j
].agg
.bitmap
,
346 station
->tid
[j
].agg
.rate_n_flags
);
347 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
349 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
353 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
358 static ssize_t
iwl_dbgfs_nvm_read(struct file
*file
,
359 char __user
*user_buf
,
364 struct iwl_priv
*priv
= file
->private_data
;
365 int pos
= 0, ofs
= 0, buf_size
= 0;
369 size_t eeprom_len
= priv
->cfg
->eeprom_size
;
370 buf_size
= 4 * eeprom_len
+ 256;
372 if (eeprom_len
% 16) {
373 IWL_ERR(priv
, "NVM size is not multiple of 16.\n");
379 IWL_ERR(priv
, "Invalid EEPROM/OTP memory\n");
383 /* 4 characters for byte 0xYY */
384 buf
= kzalloc(buf_size
, GFP_KERNEL
);
386 IWL_ERR(priv
, "Can not allocate Buffer\n");
389 eeprom_ver
= iwl_eeprom_query16(priv
, EEPROM_VERSION
);
390 pos
+= scnprintf(buf
+ pos
, buf_size
- pos
, "NVM Type: %s, "
392 (priv
->nvm_device_type
== NVM_DEVICE_TYPE_OTP
)
393 ? "OTP" : "EEPROM", eeprom_ver
);
394 for (ofs
= 0 ; ofs
< eeprom_len
; ofs
+= 16) {
395 pos
+= scnprintf(buf
+ pos
, buf_size
- pos
, "0x%.4x ", ofs
);
396 hex_dump_to_buffer(ptr
+ ofs
, 16 , 16, 2, buf
+ pos
,
398 pos
+= strlen(buf
+ pos
);
399 if (buf_size
- pos
> 0)
403 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
408 static ssize_t
iwl_dbgfs_log_event_read(struct file
*file
,
409 char __user
*user_buf
,
410 size_t count
, loff_t
*ppos
)
412 struct iwl_priv
*priv
= file
->private_data
;
415 ssize_t ret
= -ENOMEM
;
417 ret
= pos
= priv
->cfg
->ops
->lib
->dump_nic_event_log(
418 priv
, true, &buf
, true);
420 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
426 static ssize_t
iwl_dbgfs_log_event_write(struct file
*file
,
427 const char __user
*user_buf
,
428 size_t count
, loff_t
*ppos
)
430 struct iwl_priv
*priv
= file
->private_data
;
435 memset(buf
, 0, sizeof(buf
));
436 buf_size
= min(count
, sizeof(buf
) - 1);
437 if (copy_from_user(buf
, user_buf
, buf_size
))
439 if (sscanf(buf
, "%d", &event_log_flag
) != 1)
441 if (event_log_flag
== 1)
442 priv
->cfg
->ops
->lib
->dump_nic_event_log(priv
, true,
450 static ssize_t
iwl_dbgfs_channels_read(struct file
*file
, char __user
*user_buf
,
451 size_t count
, loff_t
*ppos
)
453 struct iwl_priv
*priv
= file
->private_data
;
454 struct ieee80211_channel
*channels
= NULL
;
455 const struct ieee80211_supported_band
*supp_band
= NULL
;
456 int pos
= 0, i
, bufsz
= PAGE_SIZE
;
460 if (!test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
))
463 buf
= kzalloc(bufsz
, GFP_KERNEL
);
465 IWL_ERR(priv
, "Can not allocate Buffer\n");
469 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_2GHZ
);
471 channels
= supp_band
->channels
;
473 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
474 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
475 supp_band
->n_channels
);
477 for (i
= 0; i
< supp_band
->n_channels
; i
++)
478 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
479 "%d: %ddBm: BSS%s%s, %s.\n",
480 ieee80211_frequency_to_channel(
481 channels
[i
].center_freq
),
482 channels
[i
].max_power
,
483 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
484 " (IEEE 802.11h required)" : "",
485 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
486 || (channels
[i
].flags
&
487 IEEE80211_CHAN_RADAR
)) ? "" :
490 IEEE80211_CHAN_PASSIVE_SCAN
?
491 "passive only" : "active/passive");
493 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_5GHZ
);
495 channels
= supp_band
->channels
;
497 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
498 "Displaying %d channels in 5.2GHz band (802.11a)\n",
499 supp_band
->n_channels
);
501 for (i
= 0; i
< supp_band
->n_channels
; i
++)
502 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
503 "%d: %ddBm: BSS%s%s, %s.\n",
504 ieee80211_frequency_to_channel(
505 channels
[i
].center_freq
),
506 channels
[i
].max_power
,
507 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
508 " (IEEE 802.11h required)" : "",
509 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
510 || (channels
[i
].flags
&
511 IEEE80211_CHAN_RADAR
)) ? "" :
514 IEEE80211_CHAN_PASSIVE_SCAN
?
515 "passive only" : "active/passive");
517 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
522 static ssize_t
iwl_dbgfs_status_read(struct file
*file
,
523 char __user
*user_buf
,
524 size_t count
, loff_t
*ppos
) {
526 struct iwl_priv
*priv
= file
->private_data
;
529 const size_t bufsz
= sizeof(buf
);
531 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_HCMD_ACTIVE:\t %d\n",
532 test_bit(STATUS_HCMD_ACTIVE
, &priv
->status
));
533 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INT_ENABLED:\t %d\n",
534 test_bit(STATUS_INT_ENABLED
, &priv
->status
));
535 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_RF_KILL_HW:\t %d\n",
536 test_bit(STATUS_RF_KILL_HW
, &priv
->status
));
537 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_CT_KILL:\t\t %d\n",
538 test_bit(STATUS_CT_KILL
, &priv
->status
));
539 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INIT:\t\t %d\n",
540 test_bit(STATUS_INIT
, &priv
->status
));
541 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_ALIVE:\t\t %d\n",
542 test_bit(STATUS_ALIVE
, &priv
->status
));
543 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_READY:\t\t %d\n",
544 test_bit(STATUS_READY
, &priv
->status
));
545 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_TEMPERATURE:\t %d\n",
546 test_bit(STATUS_TEMPERATURE
, &priv
->status
));
547 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_GEO_CONFIGURED:\t %d\n",
548 test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
));
549 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_EXIT_PENDING:\t %d\n",
550 test_bit(STATUS_EXIT_PENDING
, &priv
->status
));
551 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_STATISTICS:\t %d\n",
552 test_bit(STATUS_STATISTICS
, &priv
->status
));
553 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCANNING:\t %d\n",
554 test_bit(STATUS_SCANNING
, &priv
->status
));
555 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_ABORTING:\t %d\n",
556 test_bit(STATUS_SCAN_ABORTING
, &priv
->status
));
557 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_HW:\t\t %d\n",
558 test_bit(STATUS_SCAN_HW
, &priv
->status
));
559 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_POWER_PMI:\t %d\n",
560 test_bit(STATUS_POWER_PMI
, &priv
->status
));
561 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_FW_ERROR:\t %d\n",
562 test_bit(STATUS_FW_ERROR
, &priv
->status
));
563 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_MODE_PENDING:\t %d\n",
564 test_bit(STATUS_MODE_PENDING
, &priv
->status
));
565 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
568 static ssize_t
iwl_dbgfs_interrupt_read(struct file
*file
,
569 char __user
*user_buf
,
570 size_t count
, loff_t
*ppos
) {
572 struct iwl_priv
*priv
= file
->private_data
;
576 int bufsz
= 24 * 64; /* 24 items * 64 char per item */
579 buf
= kzalloc(bufsz
, GFP_KERNEL
);
581 IWL_ERR(priv
, "Can not allocate Buffer\n");
585 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
586 "Interrupt Statistics Report:\n");
588 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "HW Error:\t\t\t %u\n",
590 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "SW Error:\t\t\t %u\n",
592 if (priv
->isr_stats
.sw
> 0) {
593 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
594 "\tLast Restarting Code: 0x%X\n",
595 priv
->isr_stats
.sw_err
);
597 #ifdef CONFIG_IWLWIFI_DEBUG
598 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Frame transmitted:\t\t %u\n",
599 priv
->isr_stats
.sch
);
600 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Alive interrupt:\t\t %u\n",
601 priv
->isr_stats
.alive
);
603 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
604 "HW RF KILL switch toggled:\t %u\n",
605 priv
->isr_stats
.rfkill
);
607 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "CT KILL:\t\t\t %u\n",
608 priv
->isr_stats
.ctkill
);
610 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Wakeup Interrupt:\t\t %u\n",
611 priv
->isr_stats
.wakeup
);
613 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
614 "Rx command responses:\t\t %u\n",
616 for (cnt
= 0; cnt
< REPLY_MAX
; cnt
++) {
617 if (priv
->isr_stats
.rx_handlers
[cnt
] > 0)
618 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
619 "\tRx handler[%36s]:\t\t %u\n",
621 priv
->isr_stats
.rx_handlers
[cnt
]);
624 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx/FH interrupt:\t\t %u\n",
627 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Unexpected INTA:\t\t %u\n",
628 priv
->isr_stats
.unhandled
);
630 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
635 static ssize_t
iwl_dbgfs_interrupt_write(struct file
*file
,
636 const char __user
*user_buf
,
637 size_t count
, loff_t
*ppos
)
639 struct iwl_priv
*priv
= file
->private_data
;
644 memset(buf
, 0, sizeof(buf
));
645 buf_size
= min(count
, sizeof(buf
) - 1);
646 if (copy_from_user(buf
, user_buf
, buf_size
))
648 if (sscanf(buf
, "%x", &reset_flag
) != 1)
651 iwl_clear_isr_stats(priv
);
656 static ssize_t
iwl_dbgfs_qos_read(struct file
*file
, char __user
*user_buf
,
657 size_t count
, loff_t
*ppos
)
659 struct iwl_priv
*priv
= file
->private_data
;
662 const size_t bufsz
= sizeof(buf
);
665 for (i
= 0; i
< AC_NUM
; i
++) {
666 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
667 "\tcw_min\tcw_max\taifsn\ttxop\n");
668 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
669 "AC[%d]\t%u\t%u\t%u\t%u\n", i
,
670 priv
->qos_data
.def_qos_parm
.ac
[i
].cw_min
,
671 priv
->qos_data
.def_qos_parm
.ac
[i
].cw_max
,
672 priv
->qos_data
.def_qos_parm
.ac
[i
].aifsn
,
673 priv
->qos_data
.def_qos_parm
.ac
[i
].edca_txop
);
675 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
679 static ssize_t
iwl_dbgfs_led_read(struct file
*file
, char __user
*user_buf
,
680 size_t count
, loff_t
*ppos
)
682 struct iwl_priv
*priv
= file
->private_data
;
685 const size_t bufsz
= sizeof(buf
);
688 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
689 "allow blinking: %s\n",
690 (priv
->allow_blinking
) ? "True" : "False");
691 if (priv
->allow_blinking
) {
692 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
693 "Led blinking rate: %u\n",
694 priv
->last_blink_rate
);
695 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
696 "Last blink time: %lu\n",
697 priv
->last_blink_time
);
700 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
704 static ssize_t
iwl_dbgfs_thermal_throttling_read(struct file
*file
,
705 char __user
*user_buf
,
706 size_t count
, loff_t
*ppos
)
708 struct iwl_priv
*priv
= file
->private_data
;
709 struct iwl_tt_mgmt
*tt
= &priv
->thermal_throttle
;
710 struct iwl_tt_restriction
*restriction
;
713 const size_t bufsz
= sizeof(buf
);
716 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
717 "Thermal Throttling Mode: %s\n",
718 tt
->advanced_tt
? "Advance" : "Legacy");
719 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
720 "Thermal Throttling State: %d\n",
722 if (tt
->advanced_tt
) {
723 restriction
= tt
->restriction
+ tt
->state
;
724 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
726 restriction
->tx_stream
);
727 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
729 restriction
->rx_stream
);
730 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
734 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
738 static ssize_t
iwl_dbgfs_disable_ht40_write(struct file
*file
,
739 const char __user
*user_buf
,
740 size_t count
, loff_t
*ppos
)
742 struct iwl_priv
*priv
= file
->private_data
;
747 memset(buf
, 0, sizeof(buf
));
748 buf_size
= min(count
, sizeof(buf
) - 1);
749 if (copy_from_user(buf
, user_buf
, buf_size
))
751 if (sscanf(buf
, "%d", &ht40
) != 1)
753 if (!iwl_is_associated(priv
))
754 priv
->disable_ht40
= ht40
? true : false;
756 IWL_ERR(priv
, "Sta associated with AP - "
757 "Change to 40MHz channel support is not allowed\n");
764 static ssize_t
iwl_dbgfs_disable_ht40_read(struct file
*file
,
765 char __user
*user_buf
,
766 size_t count
, loff_t
*ppos
)
768 struct iwl_priv
*priv
= file
->private_data
;
771 const size_t bufsz
= sizeof(buf
);
774 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
775 "11n 40MHz Mode: %s\n",
776 priv
->disable_ht40
? "Disabled" : "Enabled");
777 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
781 static ssize_t
iwl_dbgfs_sleep_level_override_write(struct file
*file
,
782 const char __user
*user_buf
,
783 size_t count
, loff_t
*ppos
)
785 struct iwl_priv
*priv
= file
->private_data
;
790 memset(buf
, 0, sizeof(buf
));
791 buf_size
= min(count
, sizeof(buf
) - 1);
792 if (copy_from_user(buf
, user_buf
, buf_size
))
795 if (sscanf(buf
, "%d", &value
) != 1)
799 * Our users expect 0 to be "CAM", but 0 isn't actually
800 * valid here. However, let's not confuse them and present
801 * IWL_POWER_INDEX_1 as "1", not "0".
808 if (value
!= -1 && (value
< 0 || value
>= IWL_POWER_NUM
))
811 if (!iwl_is_ready_rf(priv
))
814 priv
->power_data
.debug_sleep_level_override
= value
;
816 mutex_lock(&priv
->mutex
);
817 iwl_power_update_mode(priv
, true);
818 mutex_unlock(&priv
->mutex
);
823 static ssize_t
iwl_dbgfs_sleep_level_override_read(struct file
*file
,
824 char __user
*user_buf
,
825 size_t count
, loff_t
*ppos
)
827 struct iwl_priv
*priv
= file
->private_data
;
830 const size_t bufsz
= sizeof(buf
);
832 /* see the write function */
833 value
= priv
->power_data
.debug_sleep_level_override
;
837 pos
= scnprintf(buf
, bufsz
, "%d\n", value
);
838 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
841 static ssize_t
iwl_dbgfs_current_sleep_command_read(struct file
*file
,
842 char __user
*user_buf
,
843 size_t count
, loff_t
*ppos
)
845 struct iwl_priv
*priv
= file
->private_data
;
848 const size_t bufsz
= sizeof(buf
);
849 struct iwl_powertable_cmd
*cmd
= &priv
->power_data
.sleep_cmd
;
851 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
852 "flags: %#.2x\n", le16_to_cpu(cmd
->flags
));
853 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
854 "RX/TX timeout: %d/%d usec\n",
855 le32_to_cpu(cmd
->rx_data_timeout
),
856 le32_to_cpu(cmd
->tx_data_timeout
));
857 for (i
= 0; i
< IWL_POWER_VEC_SIZE
; i
++)
858 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
859 "sleep_interval[%d]: %d\n", i
,
860 le32_to_cpu(cmd
->sleep_interval
[i
]));
862 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
865 DEBUGFS_READ_WRITE_FILE_OPS(sram
);
866 DEBUGFS_READ_WRITE_FILE_OPS(log_event
);
867 DEBUGFS_READ_FILE_OPS(nvm
);
868 DEBUGFS_READ_FILE_OPS(stations
);
869 DEBUGFS_READ_FILE_OPS(channels
);
870 DEBUGFS_READ_FILE_OPS(status
);
871 DEBUGFS_READ_WRITE_FILE_OPS(interrupt
);
872 DEBUGFS_READ_FILE_OPS(qos
);
873 DEBUGFS_READ_FILE_OPS(led
);
874 DEBUGFS_READ_FILE_OPS(thermal_throttling
);
875 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40
);
876 DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override
);
877 DEBUGFS_READ_FILE_OPS(current_sleep_command
);
879 static ssize_t
iwl_dbgfs_traffic_log_read(struct file
*file
,
880 char __user
*user_buf
,
881 size_t count
, loff_t
*ppos
)
883 struct iwl_priv
*priv
= file
->private_data
;
884 int pos
= 0, ofs
= 0;
886 struct iwl_tx_queue
*txq
;
888 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
890 int bufsz
= ((IWL_TRAFFIC_ENTRIES
* IWL_TRAFFIC_ENTRY_SIZE
* 64) * 2) +
891 (priv
->cfg
->num_of_queues
* 32 * 8) + 400;
896 IWL_ERR(priv
, "txq not ready\n");
899 buf
= kzalloc(bufsz
, GFP_KERNEL
);
901 IWL_ERR(priv
, "Can not allocate buffer\n");
904 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx Queue\n");
905 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
906 txq
= &priv
->txq
[cnt
];
908 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
909 "q[%d]: read_ptr: %u, write_ptr: %u\n",
910 cnt
, q
->read_ptr
, q
->write_ptr
);
912 if (priv
->tx_traffic
&& (iwl_debug_level
& IWL_DL_TX
)) {
913 ptr
= priv
->tx_traffic
;
914 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
915 "Tx Traffic idx: %u\n", priv
->tx_traffic_idx
);
916 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
917 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
918 entry
++, ofs
+= 16) {
919 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
921 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
922 buf
+ pos
, bufsz
- pos
, 0);
923 pos
+= strlen(buf
+ pos
);
930 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Rx Queue\n");
931 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
932 "read: %u, write: %u\n",
933 rxq
->read
, rxq
->write
);
935 if (priv
->rx_traffic
&& (iwl_debug_level
& IWL_DL_RX
)) {
936 ptr
= priv
->rx_traffic
;
937 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
938 "Rx Traffic idx: %u\n", priv
->rx_traffic_idx
);
939 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
940 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
941 entry
++, ofs
+= 16) {
942 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
944 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
945 buf
+ pos
, bufsz
- pos
, 0);
946 pos
+= strlen(buf
+ pos
);
953 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
958 static ssize_t
iwl_dbgfs_traffic_log_write(struct file
*file
,
959 const char __user
*user_buf
,
960 size_t count
, loff_t
*ppos
)
962 struct iwl_priv
*priv
= file
->private_data
;
967 memset(buf
, 0, sizeof(buf
));
968 buf_size
= min(count
, sizeof(buf
) - 1);
969 if (copy_from_user(buf
, user_buf
, buf_size
))
971 if (sscanf(buf
, "%d", &traffic_log
) != 1)
973 if (traffic_log
== 0)
974 iwl_reset_traffic_log(priv
);
979 static ssize_t
iwl_dbgfs_tx_queue_read(struct file
*file
,
980 char __user
*user_buf
,
981 size_t count
, loff_t
*ppos
) {
983 struct iwl_priv
*priv
= file
->private_data
;
984 struct iwl_tx_queue
*txq
;
990 const size_t bufsz
= sizeof(char) * 64 * priv
->cfg
->num_of_queues
;
993 IWL_ERR(priv
, "txq not ready\n");
996 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1000 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
1001 txq
= &priv
->txq
[cnt
];
1003 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1004 "hwq %.2d: read=%u write=%u stop=%d"
1005 " swq_id=%#.2x (ac %d/hwq %d)\n",
1006 cnt
, q
->read_ptr
, q
->write_ptr
,
1007 !!test_bit(cnt
, priv
->queue_stopped
),
1009 txq
->swq_id
& 0x80 ? txq
->swq_id
& 3 :
1011 txq
->swq_id
& 0x80 ? (txq
->swq_id
>> 2) &
1012 0x1f : txq
->swq_id
);
1015 /* for the ACs, display the stop count too */
1016 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1017 " stop-count: %d\n",
1018 atomic_read(&priv
->queue_stop_count
[cnt
]));
1020 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1025 static ssize_t
iwl_dbgfs_rx_queue_read(struct file
*file
,
1026 char __user
*user_buf
,
1027 size_t count
, loff_t
*ppos
) {
1029 struct iwl_priv
*priv
= file
->private_data
;
1030 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
1033 const size_t bufsz
= sizeof(buf
);
1035 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "read: %u\n",
1037 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "write: %u\n",
1039 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "free_count: %u\n",
1041 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "closed_rb_num: %u\n",
1042 le16_to_cpu(rxq
->rb_stts
->closed_rb_num
) & 0x0FFF);
1043 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1046 static int iwl_dbgfs_statistics_flag(struct iwl_priv
*priv
, char *buf
,
1051 p
+= scnprintf(buf
+ p
, bufsz
- p
,
1052 "Statistics Flag(0x%X):\n",
1053 le32_to_cpu(priv
->statistics
.flag
));
1054 if (le32_to_cpu(priv
->statistics
.flag
) & UCODE_STATISTICS_CLEAR_MSK
)
1055 p
+= scnprintf(buf
+ p
, bufsz
- p
,
1056 "\tStatistics have been cleared\n");
1057 p
+= scnprintf(buf
+ p
, bufsz
- p
,
1058 "\tOperational Frequency: %s\n",
1059 (le32_to_cpu(priv
->statistics
.flag
) &
1060 UCODE_STATISTICS_FREQUENCY_MSK
)
1061 ? "2.4 GHz" : "5.2 GHz");
1062 p
+= scnprintf(buf
+ p
, bufsz
- p
,
1063 "\tTGj Narrow Band: %s\n",
1064 (le32_to_cpu(priv
->statistics
.flag
) &
1065 UCODE_STATISTICS_NARROW_BAND_MSK
)
1066 ? "enabled" : "disabled");
1070 static const char ucode_stats_header
[] =
1071 "%-32s current acumulative delta max\n";
1072 static const char ucode_stats_short_format
[] =
1074 static const char ucode_stats_format
[] =
1075 " %-30s %10u %10u %10u %10u\n";
1077 static ssize_t
iwl_dbgfs_ucode_rx_stats_read(struct file
*file
,
1078 char __user
*user_buf
,
1079 size_t count
, loff_t
*ppos
)
1081 struct iwl_priv
*priv
= file
->private_data
;
1084 int bufsz
= sizeof(struct statistics_rx_phy
) * 40 +
1085 sizeof(struct statistics_rx_non_phy
) * 40 +
1086 sizeof(struct statistics_rx_ht_phy
) * 40 + 400;
1088 struct statistics_rx_phy
*ofdm
, *accum_ofdm
, *delta_ofdm
, *max_ofdm
;
1089 struct statistics_rx_phy
*cck
, *accum_cck
, *delta_cck
, *max_cck
;
1090 struct statistics_rx_non_phy
*general
, *accum_general
;
1091 struct statistics_rx_non_phy
*delta_general
, *max_general
;
1092 struct statistics_rx_ht_phy
*ht
, *accum_ht
, *delta_ht
, *max_ht
;
1094 if (!iwl_is_alive(priv
))
1097 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1099 IWL_ERR(priv
, "Can not allocate Buffer\n");
1103 /* the statistic information display here is based on
1104 * the last statistics notification from uCode
1105 * might not reflect the current uCode activity
1107 ofdm
= &priv
->statistics
.rx
.ofdm
;
1108 cck
= &priv
->statistics
.rx
.cck
;
1109 general
= &priv
->statistics
.rx
.general
;
1110 ht
= &priv
->statistics
.rx
.ofdm_ht
;
1111 accum_ofdm
= &priv
->accum_statistics
.rx
.ofdm
;
1112 accum_cck
= &priv
->accum_statistics
.rx
.cck
;
1113 accum_general
= &priv
->accum_statistics
.rx
.general
;
1114 accum_ht
= &priv
->accum_statistics
.rx
.ofdm_ht
;
1115 delta_ofdm
= &priv
->delta_statistics
.rx
.ofdm
;
1116 delta_cck
= &priv
->delta_statistics
.rx
.cck
;
1117 delta_general
= &priv
->delta_statistics
.rx
.general
;
1118 delta_ht
= &priv
->delta_statistics
.rx
.ofdm_ht
;
1119 max_ofdm
= &priv
->max_delta
.rx
.ofdm
;
1120 max_cck
= &priv
->max_delta
.rx
.cck
;
1121 max_general
= &priv
->max_delta
.rx
.general
;
1122 max_ht
= &priv
->max_delta
.rx
.ofdm_ht
;
1124 pos
+= iwl_dbgfs_statistics_flag(priv
, buf
, bufsz
);
1125 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_header
,
1126 "Statistics_Rx - OFDM:");
1127 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1128 "ina_cnt:", le32_to_cpu(ofdm
->ina_cnt
),
1129 accum_ofdm
->ina_cnt
,
1130 delta_ofdm
->ina_cnt
, max_ofdm
->ina_cnt
);
1131 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1133 le32_to_cpu(ofdm
->fina_cnt
), accum_ofdm
->fina_cnt
,
1134 delta_ofdm
->fina_cnt
, max_ofdm
->fina_cnt
);
1135 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1137 le32_to_cpu(ofdm
->plcp_err
), accum_ofdm
->plcp_err
,
1138 delta_ofdm
->plcp_err
, max_ofdm
->plcp_err
);
1139 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1141 le32_to_cpu(ofdm
->crc32_err
), accum_ofdm
->crc32_err
,
1142 delta_ofdm
->crc32_err
, max_ofdm
->crc32_err
);
1143 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1145 le32_to_cpu(ofdm
->overrun_err
),
1146 accum_ofdm
->overrun_err
,
1147 delta_ofdm
->overrun_err
, max_ofdm
->overrun_err
);
1148 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1149 "early_overrun_err:",
1150 le32_to_cpu(ofdm
->early_overrun_err
),
1151 accum_ofdm
->early_overrun_err
,
1152 delta_ofdm
->early_overrun_err
,
1153 max_ofdm
->early_overrun_err
);
1154 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1156 le32_to_cpu(ofdm
->crc32_good
),
1157 accum_ofdm
->crc32_good
,
1158 delta_ofdm
->crc32_good
, max_ofdm
->crc32_good
);
1159 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1161 le32_to_cpu(ofdm
->false_alarm_cnt
),
1162 accum_ofdm
->false_alarm_cnt
,
1163 delta_ofdm
->false_alarm_cnt
,
1164 max_ofdm
->false_alarm_cnt
);
1165 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1166 "fina_sync_err_cnt:",
1167 le32_to_cpu(ofdm
->fina_sync_err_cnt
),
1168 accum_ofdm
->fina_sync_err_cnt
,
1169 delta_ofdm
->fina_sync_err_cnt
,
1170 max_ofdm
->fina_sync_err_cnt
);
1171 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1173 le32_to_cpu(ofdm
->sfd_timeout
),
1174 accum_ofdm
->sfd_timeout
,
1175 delta_ofdm
->sfd_timeout
,
1176 max_ofdm
->sfd_timeout
);
1177 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1179 le32_to_cpu(ofdm
->fina_timeout
),
1180 accum_ofdm
->fina_timeout
,
1181 delta_ofdm
->fina_timeout
,
1182 max_ofdm
->fina_timeout
);
1183 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1185 le32_to_cpu(ofdm
->unresponded_rts
),
1186 accum_ofdm
->unresponded_rts
,
1187 delta_ofdm
->unresponded_rts
,
1188 max_ofdm
->unresponded_rts
);
1189 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1190 "rxe_frame_lmt_ovrun:",
1191 le32_to_cpu(ofdm
->rxe_frame_limit_overrun
),
1192 accum_ofdm
->rxe_frame_limit_overrun
,
1193 delta_ofdm
->rxe_frame_limit_overrun
,
1194 max_ofdm
->rxe_frame_limit_overrun
);
1195 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1197 le32_to_cpu(ofdm
->sent_ack_cnt
),
1198 accum_ofdm
->sent_ack_cnt
,
1199 delta_ofdm
->sent_ack_cnt
,
1200 max_ofdm
->sent_ack_cnt
);
1201 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1203 le32_to_cpu(ofdm
->sent_cts_cnt
),
1204 accum_ofdm
->sent_cts_cnt
,
1205 delta_ofdm
->sent_cts_cnt
, max_ofdm
->sent_cts_cnt
);
1206 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1208 le32_to_cpu(ofdm
->sent_ba_rsp_cnt
),
1209 accum_ofdm
->sent_ba_rsp_cnt
,
1210 delta_ofdm
->sent_ba_rsp_cnt
,
1211 max_ofdm
->sent_ba_rsp_cnt
);
1212 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1214 le32_to_cpu(ofdm
->dsp_self_kill
),
1215 accum_ofdm
->dsp_self_kill
,
1216 delta_ofdm
->dsp_self_kill
,
1217 max_ofdm
->dsp_self_kill
);
1218 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1220 le32_to_cpu(ofdm
->mh_format_err
),
1221 accum_ofdm
->mh_format_err
,
1222 delta_ofdm
->mh_format_err
,
1223 max_ofdm
->mh_format_err
);
1224 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1225 "re_acq_main_rssi_sum:",
1226 le32_to_cpu(ofdm
->re_acq_main_rssi_sum
),
1227 accum_ofdm
->re_acq_main_rssi_sum
,
1228 delta_ofdm
->re_acq_main_rssi_sum
,
1229 max_ofdm
->re_acq_main_rssi_sum
);
1231 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_header
,
1232 "Statistics_Rx - CCK:");
1233 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1235 le32_to_cpu(cck
->ina_cnt
), accum_cck
->ina_cnt
,
1236 delta_cck
->ina_cnt
, max_cck
->ina_cnt
);
1237 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1239 le32_to_cpu(cck
->fina_cnt
), accum_cck
->fina_cnt
,
1240 delta_cck
->fina_cnt
, max_cck
->fina_cnt
);
1241 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1243 le32_to_cpu(cck
->plcp_err
), accum_cck
->plcp_err
,
1244 delta_cck
->plcp_err
, max_cck
->plcp_err
);
1245 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1247 le32_to_cpu(cck
->crc32_err
), accum_cck
->crc32_err
,
1248 delta_cck
->crc32_err
, max_cck
->crc32_err
);
1249 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1251 le32_to_cpu(cck
->overrun_err
),
1252 accum_cck
->overrun_err
,
1253 delta_cck
->overrun_err
, max_cck
->overrun_err
);
1254 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1255 "early_overrun_err:",
1256 le32_to_cpu(cck
->early_overrun_err
),
1257 accum_cck
->early_overrun_err
,
1258 delta_cck
->early_overrun_err
,
1259 max_cck
->early_overrun_err
);
1260 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1262 le32_to_cpu(cck
->crc32_good
), accum_cck
->crc32_good
,
1263 delta_cck
->crc32_good
,
1264 max_cck
->crc32_good
);
1265 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1267 le32_to_cpu(cck
->false_alarm_cnt
),
1268 accum_cck
->false_alarm_cnt
,
1269 delta_cck
->false_alarm_cnt
, max_cck
->false_alarm_cnt
);
1270 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1271 "fina_sync_err_cnt:",
1272 le32_to_cpu(cck
->fina_sync_err_cnt
),
1273 accum_cck
->fina_sync_err_cnt
,
1274 delta_cck
->fina_sync_err_cnt
,
1275 max_cck
->fina_sync_err_cnt
);
1276 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1278 le32_to_cpu(cck
->sfd_timeout
),
1279 accum_cck
->sfd_timeout
,
1280 delta_cck
->sfd_timeout
, max_cck
->sfd_timeout
);
1281 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1283 le32_to_cpu(cck
->fina_timeout
),
1284 accum_cck
->fina_timeout
,
1285 delta_cck
->fina_timeout
, max_cck
->fina_timeout
);
1286 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1288 le32_to_cpu(cck
->unresponded_rts
),
1289 accum_cck
->unresponded_rts
,
1290 delta_cck
->unresponded_rts
,
1291 max_cck
->unresponded_rts
);
1292 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1293 "rxe_frame_lmt_ovrun:",
1294 le32_to_cpu(cck
->rxe_frame_limit_overrun
),
1295 accum_cck
->rxe_frame_limit_overrun
,
1296 delta_cck
->rxe_frame_limit_overrun
,
1297 max_cck
->rxe_frame_limit_overrun
);
1298 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1300 le32_to_cpu(cck
->sent_ack_cnt
),
1301 accum_cck
->sent_ack_cnt
,
1302 delta_cck
->sent_ack_cnt
,
1303 max_cck
->sent_ack_cnt
);
1304 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1306 le32_to_cpu(cck
->sent_cts_cnt
),
1307 accum_cck
->sent_cts_cnt
,
1308 delta_cck
->sent_cts_cnt
,
1309 max_cck
->sent_cts_cnt
);
1310 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1312 le32_to_cpu(cck
->sent_ba_rsp_cnt
),
1313 accum_cck
->sent_ba_rsp_cnt
,
1314 delta_cck
->sent_ba_rsp_cnt
,
1315 max_cck
->sent_ba_rsp_cnt
);
1316 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1318 le32_to_cpu(cck
->dsp_self_kill
),
1319 accum_cck
->dsp_self_kill
,
1320 delta_cck
->dsp_self_kill
,
1321 max_cck
->dsp_self_kill
);
1322 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1324 le32_to_cpu(cck
->mh_format_err
),
1325 accum_cck
->mh_format_err
,
1326 delta_cck
->mh_format_err
, max_cck
->mh_format_err
);
1327 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1328 "re_acq_main_rssi_sum:",
1329 le32_to_cpu(cck
->re_acq_main_rssi_sum
),
1330 accum_cck
->re_acq_main_rssi_sum
,
1331 delta_cck
->re_acq_main_rssi_sum
,
1332 max_cck
->re_acq_main_rssi_sum
);
1334 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_header
,
1335 "Statistics_Rx - GENERAL:");
1336 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1338 le32_to_cpu(general
->bogus_cts
),
1339 accum_general
->bogus_cts
,
1340 delta_general
->bogus_cts
, max_general
->bogus_cts
);
1341 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1343 le32_to_cpu(general
->bogus_ack
),
1344 accum_general
->bogus_ack
,
1345 delta_general
->bogus_ack
, max_general
->bogus_ack
);
1346 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1347 "non_bssid_frames:",
1348 le32_to_cpu(general
->non_bssid_frames
),
1349 accum_general
->non_bssid_frames
,
1350 delta_general
->non_bssid_frames
,
1351 max_general
->non_bssid_frames
);
1352 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1354 le32_to_cpu(general
->filtered_frames
),
1355 accum_general
->filtered_frames
,
1356 delta_general
->filtered_frames
,
1357 max_general
->filtered_frames
);
1358 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1359 "non_channel_beacons:",
1360 le32_to_cpu(general
->non_channel_beacons
),
1361 accum_general
->non_channel_beacons
,
1362 delta_general
->non_channel_beacons
,
1363 max_general
->non_channel_beacons
);
1364 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1366 le32_to_cpu(general
->channel_beacons
),
1367 accum_general
->channel_beacons
,
1368 delta_general
->channel_beacons
,
1369 max_general
->channel_beacons
);
1370 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1372 le32_to_cpu(general
->num_missed_bcon
),
1373 accum_general
->num_missed_bcon
,
1374 delta_general
->num_missed_bcon
,
1375 max_general
->num_missed_bcon
);
1376 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1377 "adc_rx_saturation_time:",
1378 le32_to_cpu(general
->adc_rx_saturation_time
),
1379 accum_general
->adc_rx_saturation_time
,
1380 delta_general
->adc_rx_saturation_time
,
1381 max_general
->adc_rx_saturation_time
);
1382 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1383 "ina_detect_search_tm:",
1384 le32_to_cpu(general
->ina_detection_search_time
),
1385 accum_general
->ina_detection_search_time
,
1386 delta_general
->ina_detection_search_time
,
1387 max_general
->ina_detection_search_time
);
1388 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1389 "beacon_silence_rssi_a:",
1390 le32_to_cpu(general
->beacon_silence_rssi_a
),
1391 accum_general
->beacon_silence_rssi_a
,
1392 delta_general
->beacon_silence_rssi_a
,
1393 max_general
->beacon_silence_rssi_a
);
1394 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1395 "beacon_silence_rssi_b:",
1396 le32_to_cpu(general
->beacon_silence_rssi_b
),
1397 accum_general
->beacon_silence_rssi_b
,
1398 delta_general
->beacon_silence_rssi_b
,
1399 max_general
->beacon_silence_rssi_b
);
1400 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1401 "beacon_silence_rssi_c:",
1402 le32_to_cpu(general
->beacon_silence_rssi_c
),
1403 accum_general
->beacon_silence_rssi_c
,
1404 delta_general
->beacon_silence_rssi_c
,
1405 max_general
->beacon_silence_rssi_c
);
1406 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1407 "interference_data_flag:",
1408 le32_to_cpu(general
->interference_data_flag
),
1409 accum_general
->interference_data_flag
,
1410 delta_general
->interference_data_flag
,
1411 max_general
->interference_data_flag
);
1412 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1414 le32_to_cpu(general
->channel_load
),
1415 accum_general
->channel_load
,
1416 delta_general
->channel_load
,
1417 max_general
->channel_load
);
1418 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1419 "dsp_false_alarms:",
1420 le32_to_cpu(general
->dsp_false_alarms
),
1421 accum_general
->dsp_false_alarms
,
1422 delta_general
->dsp_false_alarms
,
1423 max_general
->dsp_false_alarms
);
1424 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1426 le32_to_cpu(general
->beacon_rssi_a
),
1427 accum_general
->beacon_rssi_a
,
1428 delta_general
->beacon_rssi_a
,
1429 max_general
->beacon_rssi_a
);
1430 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1432 le32_to_cpu(general
->beacon_rssi_b
),
1433 accum_general
->beacon_rssi_b
,
1434 delta_general
->beacon_rssi_b
,
1435 max_general
->beacon_rssi_b
);
1436 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1438 le32_to_cpu(general
->beacon_rssi_c
),
1439 accum_general
->beacon_rssi_c
,
1440 delta_general
->beacon_rssi_c
,
1441 max_general
->beacon_rssi_c
);
1442 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1444 le32_to_cpu(general
->beacon_energy_a
),
1445 accum_general
->beacon_energy_a
,
1446 delta_general
->beacon_energy_a
,
1447 max_general
->beacon_energy_a
);
1448 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1450 le32_to_cpu(general
->beacon_energy_b
),
1451 accum_general
->beacon_energy_b
,
1452 delta_general
->beacon_energy_b
,
1453 max_general
->beacon_energy_b
);
1454 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1456 le32_to_cpu(general
->beacon_energy_c
),
1457 accum_general
->beacon_energy_c
,
1458 delta_general
->beacon_energy_c
,
1459 max_general
->beacon_energy_c
);
1461 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Statistics_Rx - OFDM_HT:\n");
1462 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_header
,
1463 "Statistics_Rx - OFDM_HT:");
1464 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1466 le32_to_cpu(ht
->plcp_err
), accum_ht
->plcp_err
,
1467 delta_ht
->plcp_err
, max_ht
->plcp_err
);
1468 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1470 le32_to_cpu(ht
->overrun_err
), accum_ht
->overrun_err
,
1471 delta_ht
->overrun_err
, max_ht
->overrun_err
);
1472 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1473 "early_overrun_err:",
1474 le32_to_cpu(ht
->early_overrun_err
),
1475 accum_ht
->early_overrun_err
,
1476 delta_ht
->early_overrun_err
,
1477 max_ht
->early_overrun_err
);
1478 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1480 le32_to_cpu(ht
->crc32_good
), accum_ht
->crc32_good
,
1481 delta_ht
->crc32_good
, max_ht
->crc32_good
);
1482 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1484 le32_to_cpu(ht
->crc32_err
), accum_ht
->crc32_err
,
1485 delta_ht
->crc32_err
, max_ht
->crc32_err
);
1486 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1488 le32_to_cpu(ht
->mh_format_err
),
1489 accum_ht
->mh_format_err
,
1490 delta_ht
->mh_format_err
, max_ht
->mh_format_err
);
1491 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1493 le32_to_cpu(ht
->agg_crc32_good
),
1494 accum_ht
->agg_crc32_good
,
1495 delta_ht
->agg_crc32_good
, max_ht
->agg_crc32_good
);
1496 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1498 le32_to_cpu(ht
->agg_mpdu_cnt
),
1499 accum_ht
->agg_mpdu_cnt
,
1500 delta_ht
->agg_mpdu_cnt
, max_ht
->agg_mpdu_cnt
);
1501 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1503 le32_to_cpu(ht
->agg_cnt
), accum_ht
->agg_cnt
,
1504 delta_ht
->agg_cnt
, max_ht
->agg_cnt
);
1505 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1507 le32_to_cpu(ht
->unsupport_mcs
),
1508 accum_ht
->unsupport_mcs
,
1509 delta_ht
->unsupport_mcs
, max_ht
->unsupport_mcs
);
1511 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1516 static ssize_t
iwl_dbgfs_ucode_tx_stats_read(struct file
*file
,
1517 char __user
*user_buf
,
1518 size_t count
, loff_t
*ppos
)
1520 struct iwl_priv
*priv
= file
->private_data
;
1523 int bufsz
= (sizeof(struct statistics_tx
) * 48) + 250;
1525 struct statistics_tx
*tx
, *accum_tx
, *delta_tx
, *max_tx
;
1527 if (!iwl_is_alive(priv
))
1530 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1532 IWL_ERR(priv
, "Can not allocate Buffer\n");
1536 /* the statistic information display here is based on
1537 * the last statistics notification from uCode
1538 * might not reflect the current uCode activity
1540 tx
= &priv
->statistics
.tx
;
1541 accum_tx
= &priv
->accum_statistics
.tx
;
1542 delta_tx
= &priv
->delta_statistics
.tx
;
1543 max_tx
= &priv
->max_delta
.tx
;
1544 pos
+= iwl_dbgfs_statistics_flag(priv
, buf
, bufsz
);
1545 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_header
,
1547 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1549 le32_to_cpu(tx
->preamble_cnt
),
1550 accum_tx
->preamble_cnt
,
1551 delta_tx
->preamble_cnt
, max_tx
->preamble_cnt
);
1552 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1554 le32_to_cpu(tx
->rx_detected_cnt
),
1555 accum_tx
->rx_detected_cnt
,
1556 delta_tx
->rx_detected_cnt
, max_tx
->rx_detected_cnt
);
1557 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1558 "bt_prio_defer_cnt:",
1559 le32_to_cpu(tx
->bt_prio_defer_cnt
),
1560 accum_tx
->bt_prio_defer_cnt
,
1561 delta_tx
->bt_prio_defer_cnt
,
1562 max_tx
->bt_prio_defer_cnt
);
1563 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1564 "bt_prio_kill_cnt:",
1565 le32_to_cpu(tx
->bt_prio_kill_cnt
),
1566 accum_tx
->bt_prio_kill_cnt
,
1567 delta_tx
->bt_prio_kill_cnt
,
1568 max_tx
->bt_prio_kill_cnt
);
1569 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1571 le32_to_cpu(tx
->few_bytes_cnt
),
1572 accum_tx
->few_bytes_cnt
,
1573 delta_tx
->few_bytes_cnt
, max_tx
->few_bytes_cnt
);
1574 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1576 le32_to_cpu(tx
->cts_timeout
), accum_tx
->cts_timeout
,
1577 delta_tx
->cts_timeout
, max_tx
->cts_timeout
);
1578 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1580 le32_to_cpu(tx
->ack_timeout
),
1581 accum_tx
->ack_timeout
,
1582 delta_tx
->ack_timeout
, max_tx
->ack_timeout
);
1583 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1584 "expected_ack_cnt:",
1585 le32_to_cpu(tx
->expected_ack_cnt
),
1586 accum_tx
->expected_ack_cnt
,
1587 delta_tx
->expected_ack_cnt
,
1588 max_tx
->expected_ack_cnt
);
1589 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1591 le32_to_cpu(tx
->actual_ack_cnt
),
1592 accum_tx
->actual_ack_cnt
,
1593 delta_tx
->actual_ack_cnt
,
1594 max_tx
->actual_ack_cnt
);
1595 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1597 le32_to_cpu(tx
->dump_msdu_cnt
),
1598 accum_tx
->dump_msdu_cnt
,
1599 delta_tx
->dump_msdu_cnt
,
1600 max_tx
->dump_msdu_cnt
);
1601 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1602 "abort_nxt_frame_mismatch:",
1603 le32_to_cpu(tx
->burst_abort_next_frame_mismatch_cnt
),
1604 accum_tx
->burst_abort_next_frame_mismatch_cnt
,
1605 delta_tx
->burst_abort_next_frame_mismatch_cnt
,
1606 max_tx
->burst_abort_next_frame_mismatch_cnt
);
1607 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1608 "abort_missing_nxt_frame:",
1609 le32_to_cpu(tx
->burst_abort_missing_next_frame_cnt
),
1610 accum_tx
->burst_abort_missing_next_frame_cnt
,
1611 delta_tx
->burst_abort_missing_next_frame_cnt
,
1612 max_tx
->burst_abort_missing_next_frame_cnt
);
1613 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1614 "cts_timeout_collision:",
1615 le32_to_cpu(tx
->cts_timeout_collision
),
1616 accum_tx
->cts_timeout_collision
,
1617 delta_tx
->cts_timeout_collision
,
1618 max_tx
->cts_timeout_collision
);
1619 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1620 "ack_ba_timeout_collision:",
1621 le32_to_cpu(tx
->ack_or_ba_timeout_collision
),
1622 accum_tx
->ack_or_ba_timeout_collision
,
1623 delta_tx
->ack_or_ba_timeout_collision
,
1624 max_tx
->ack_or_ba_timeout_collision
);
1625 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1627 le32_to_cpu(tx
->agg
.ba_timeout
),
1628 accum_tx
->agg
.ba_timeout
,
1629 delta_tx
->agg
.ba_timeout
,
1630 max_tx
->agg
.ba_timeout
);
1631 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1632 "agg ba_resched_frames:",
1633 le32_to_cpu(tx
->agg
.ba_reschedule_frames
),
1634 accum_tx
->agg
.ba_reschedule_frames
,
1635 delta_tx
->agg
.ba_reschedule_frames
,
1636 max_tx
->agg
.ba_reschedule_frames
);
1637 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1638 "agg scd_query_agg_frame:",
1639 le32_to_cpu(tx
->agg
.scd_query_agg_frame_cnt
),
1640 accum_tx
->agg
.scd_query_agg_frame_cnt
,
1641 delta_tx
->agg
.scd_query_agg_frame_cnt
,
1642 max_tx
->agg
.scd_query_agg_frame_cnt
);
1643 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1644 "agg scd_query_no_agg:",
1645 le32_to_cpu(tx
->agg
.scd_query_no_agg
),
1646 accum_tx
->agg
.scd_query_no_agg
,
1647 delta_tx
->agg
.scd_query_no_agg
,
1648 max_tx
->agg
.scd_query_no_agg
);
1649 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1650 "agg scd_query_agg:",
1651 le32_to_cpu(tx
->agg
.scd_query_agg
),
1652 accum_tx
->agg
.scd_query_agg
,
1653 delta_tx
->agg
.scd_query_agg
,
1654 max_tx
->agg
.scd_query_agg
);
1655 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1656 "agg scd_query_mismatch:",
1657 le32_to_cpu(tx
->agg
.scd_query_mismatch
),
1658 accum_tx
->agg
.scd_query_mismatch
,
1659 delta_tx
->agg
.scd_query_mismatch
,
1660 max_tx
->agg
.scd_query_mismatch
);
1661 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1662 "agg frame_not_ready:",
1663 le32_to_cpu(tx
->agg
.frame_not_ready
),
1664 accum_tx
->agg
.frame_not_ready
,
1665 delta_tx
->agg
.frame_not_ready
,
1666 max_tx
->agg
.frame_not_ready
);
1667 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1669 le32_to_cpu(tx
->agg
.underrun
),
1670 accum_tx
->agg
.underrun
,
1671 delta_tx
->agg
.underrun
, max_tx
->agg
.underrun
);
1672 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1673 "agg bt_prio_kill:",
1674 le32_to_cpu(tx
->agg
.bt_prio_kill
),
1675 accum_tx
->agg
.bt_prio_kill
,
1676 delta_tx
->agg
.bt_prio_kill
,
1677 max_tx
->agg
.bt_prio_kill
);
1678 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1679 "agg rx_ba_rsp_cnt:",
1680 le32_to_cpu(tx
->agg
.rx_ba_rsp_cnt
),
1681 accum_tx
->agg
.rx_ba_rsp_cnt
,
1682 delta_tx
->agg
.rx_ba_rsp_cnt
,
1683 max_tx
->agg
.rx_ba_rsp_cnt
);
1685 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1690 static ssize_t
iwl_dbgfs_ucode_general_stats_read(struct file
*file
,
1691 char __user
*user_buf
,
1692 size_t count
, loff_t
*ppos
)
1694 struct iwl_priv
*priv
= file
->private_data
;
1697 int bufsz
= sizeof(struct statistics_general
) * 10 + 300;
1699 struct statistics_general
*general
, *accum_general
;
1700 struct statistics_general
*delta_general
, *max_general
;
1701 struct statistics_dbg
*dbg
, *accum_dbg
, *delta_dbg
, *max_dbg
;
1702 struct statistics_div
*div
, *accum_div
, *delta_div
, *max_div
;
1704 if (!iwl_is_alive(priv
))
1707 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1709 IWL_ERR(priv
, "Can not allocate Buffer\n");
1713 /* the statistic information display here is based on
1714 * the last statistics notification from uCode
1715 * might not reflect the current uCode activity
1717 general
= &priv
->statistics
.general
;
1718 dbg
= &priv
->statistics
.general
.dbg
;
1719 div
= &priv
->statistics
.general
.div
;
1720 accum_general
= &priv
->accum_statistics
.general
;
1721 delta_general
= &priv
->delta_statistics
.general
;
1722 max_general
= &priv
->max_delta
.general
;
1723 accum_dbg
= &priv
->accum_statistics
.general
.dbg
;
1724 delta_dbg
= &priv
->delta_statistics
.general
.dbg
;
1725 max_dbg
= &priv
->max_delta
.general
.dbg
;
1726 accum_div
= &priv
->accum_statistics
.general
.div
;
1727 delta_div
= &priv
->delta_statistics
.general
.div
;
1728 max_div
= &priv
->max_delta
.general
.div
;
1729 pos
+= iwl_dbgfs_statistics_flag(priv
, buf
, bufsz
);
1730 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_header
,
1731 "Statistics_General:");
1732 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_short_format
,
1734 le32_to_cpu(general
->temperature
));
1735 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_short_format
,
1737 le32_to_cpu(general
->temperature_m
));
1738 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1740 le32_to_cpu(dbg
->burst_check
),
1741 accum_dbg
->burst_check
,
1742 delta_dbg
->burst_check
, max_dbg
->burst_check
);
1743 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1745 le32_to_cpu(dbg
->burst_count
),
1746 accum_dbg
->burst_count
,
1747 delta_dbg
->burst_count
, max_dbg
->burst_count
);
1748 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1750 le32_to_cpu(general
->sleep_time
),
1751 accum_general
->sleep_time
,
1752 delta_general
->sleep_time
, max_general
->sleep_time
);
1753 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1755 le32_to_cpu(general
->slots_out
),
1756 accum_general
->slots_out
,
1757 delta_general
->slots_out
, max_general
->slots_out
);
1758 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1760 le32_to_cpu(general
->slots_idle
),
1761 accum_general
->slots_idle
,
1762 delta_general
->slots_idle
, max_general
->slots_idle
);
1763 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "ttl_timestamp:\t\t\t%u\n",
1764 le32_to_cpu(general
->ttl_timestamp
));
1765 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1767 le32_to_cpu(div
->tx_on_a
), accum_div
->tx_on_a
,
1768 delta_div
->tx_on_a
, max_div
->tx_on_a
);
1769 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1771 le32_to_cpu(div
->tx_on_b
), accum_div
->tx_on_b
,
1772 delta_div
->tx_on_b
, max_div
->tx_on_b
);
1773 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1775 le32_to_cpu(div
->exec_time
), accum_div
->exec_time
,
1776 delta_div
->exec_time
, max_div
->exec_time
);
1777 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1779 le32_to_cpu(div
->probe_time
), accum_div
->probe_time
,
1780 delta_div
->probe_time
, max_div
->probe_time
);
1781 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1782 "rx_enable_counter:",
1783 le32_to_cpu(general
->rx_enable_counter
),
1784 accum_general
->rx_enable_counter
,
1785 delta_general
->rx_enable_counter
,
1786 max_general
->rx_enable_counter
);
1787 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, ucode_stats_format
,
1788 "num_of_sos_states:",
1789 le32_to_cpu(general
->num_of_sos_states
),
1790 accum_general
->num_of_sos_states
,
1791 delta_general
->num_of_sos_states
,
1792 max_general
->num_of_sos_states
);
1793 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1798 static ssize_t
iwl_dbgfs_sensitivity_read(struct file
*file
,
1799 char __user
*user_buf
,
1800 size_t count
, loff_t
*ppos
) {
1802 struct iwl_priv
*priv
= file
->private_data
;
1806 int bufsz
= sizeof(struct iwl_sensitivity_data
) * 4 + 100;
1808 struct iwl_sensitivity_data
*data
;
1810 data
= &priv
->sensitivity_data
;
1811 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1813 IWL_ERR(priv
, "Can not allocate Buffer\n");
1817 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm:\t\t\t %u\n",
1818 data
->auto_corr_ofdm
);
1819 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1820 "auto_corr_ofdm_mrc:\t\t %u\n",
1821 data
->auto_corr_ofdm_mrc
);
1822 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm_x1:\t\t %u\n",
1823 data
->auto_corr_ofdm_x1
);
1824 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1825 "auto_corr_ofdm_mrc_x1:\t\t %u\n",
1826 data
->auto_corr_ofdm_mrc_x1
);
1827 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck:\t\t\t %u\n",
1828 data
->auto_corr_cck
);
1829 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck_mrc:\t\t %u\n",
1830 data
->auto_corr_cck_mrc
);
1831 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1832 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
1833 data
->last_bad_plcp_cnt_ofdm
);
1834 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_ofdm:\t\t %u\n",
1835 data
->last_fa_cnt_ofdm
);
1836 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1837 "last_bad_plcp_cnt_cck:\t\t %u\n",
1838 data
->last_bad_plcp_cnt_cck
);
1839 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_cck:\t\t %u\n",
1840 data
->last_fa_cnt_cck
);
1841 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_curr_state:\t\t\t %u\n",
1842 data
->nrg_curr_state
);
1843 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_prev_state:\t\t\t %u\n",
1844 data
->nrg_prev_state
);
1845 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_value:\t\t\t");
1846 for (cnt
= 0; cnt
< 10; cnt
++) {
1847 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1848 data
->nrg_value
[cnt
]);
1850 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1851 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_rssi:\t\t");
1852 for (cnt
= 0; cnt
< NRG_NUM_PREV_STAT_L
; cnt
++) {
1853 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1854 data
->nrg_silence_rssi
[cnt
]);
1856 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1857 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_ref:\t\t %u\n",
1858 data
->nrg_silence_ref
);
1859 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_energy_idx:\t\t\t %u\n",
1860 data
->nrg_energy_idx
);
1861 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_idx:\t\t %u\n",
1862 data
->nrg_silence_idx
);
1863 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_cck:\t\t\t %u\n",
1865 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1866 "nrg_auto_corr_silence_diff:\t %u\n",
1867 data
->nrg_auto_corr_silence_diff
);
1868 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "num_in_cck_no_fa:\t\t %u\n",
1869 data
->num_in_cck_no_fa
);
1870 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_ofdm:\t\t\t %u\n",
1873 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1879 static ssize_t
iwl_dbgfs_chain_noise_read(struct file
*file
,
1880 char __user
*user_buf
,
1881 size_t count
, loff_t
*ppos
) {
1883 struct iwl_priv
*priv
= file
->private_data
;
1887 int bufsz
= sizeof(struct iwl_chain_noise_data
) * 4 + 100;
1889 struct iwl_chain_noise_data
*data
;
1891 data
= &priv
->chain_noise_data
;
1892 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1894 IWL_ERR(priv
, "Can not allocate Buffer\n");
1898 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "active_chains:\t\t\t %u\n",
1899 data
->active_chains
);
1900 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_a:\t\t\t %u\n",
1901 data
->chain_noise_a
);
1902 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_b:\t\t\t %u\n",
1903 data
->chain_noise_b
);
1904 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_c:\t\t\t %u\n",
1905 data
->chain_noise_c
);
1906 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_a:\t\t\t %u\n",
1907 data
->chain_signal_a
);
1908 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_b:\t\t\t %u\n",
1909 data
->chain_signal_b
);
1910 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_c:\t\t\t %u\n",
1911 data
->chain_signal_c
);
1912 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "beacon_count:\t\t\t %u\n",
1913 data
->beacon_count
);
1915 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "disconn_array:\t\t\t");
1916 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1917 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1918 data
->disconn_array
[cnt
]);
1920 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1921 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "delta_gain_code:\t\t");
1922 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1923 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1924 data
->delta_gain_code
[cnt
]);
1926 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1927 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "radio_write:\t\t\t %u\n",
1929 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "state:\t\t\t\t %u\n",
1932 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1937 static ssize_t
iwl_dbgfs_tx_power_read(struct file
*file
,
1938 char __user
*user_buf
,
1939 size_t count
, loff_t
*ppos
) {
1941 struct iwl_priv
*priv
= file
->private_data
;
1944 const size_t bufsz
= sizeof(buf
);
1945 struct statistics_tx
*tx
;
1947 if (!iwl_is_alive(priv
))
1948 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "N/A\n");
1950 tx
= &priv
->statistics
.tx
;
1951 if (tx
->tx_power
.ant_a
||
1952 tx
->tx_power
.ant_b
||
1953 tx
->tx_power
.ant_c
) {
1954 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1955 "tx power: (1/2 dB step)\n");
1956 if ((priv
->cfg
->valid_tx_ant
& ANT_A
) &&
1958 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1959 "\tantenna A: 0x%X\n",
1960 tx
->tx_power
.ant_a
);
1961 if ((priv
->cfg
->valid_tx_ant
& ANT_B
) &&
1963 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1964 "\tantenna B: 0x%X\n",
1965 tx
->tx_power
.ant_b
);
1966 if ((priv
->cfg
->valid_tx_ant
& ANT_C
) &&
1968 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1969 "\tantenna C: 0x%X\n",
1970 tx
->tx_power
.ant_c
);
1972 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "N/A\n");
1974 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1977 static ssize_t
iwl_dbgfs_power_save_status_read(struct file
*file
,
1978 char __user
*user_buf
,
1979 size_t count
, loff_t
*ppos
)
1981 struct iwl_priv
*priv
= file
->private_data
;
1984 const size_t bufsz
= sizeof(buf
);
1987 pwrsave_status
= iwl_read32(priv
, CSR_GP_CNTRL
) &
1988 CSR_GP_REG_POWER_SAVE_STATUS_MSK
;
1990 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Power Save Status: ");
1991 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%s\n",
1992 (pwrsave_status
== CSR_GP_REG_NO_POWER_SAVE
) ? "none" :
1993 (pwrsave_status
== CSR_GP_REG_MAC_POWER_SAVE
) ? "MAC" :
1994 (pwrsave_status
== CSR_GP_REG_PHY_POWER_SAVE
) ? "PHY" :
1997 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
2000 static ssize_t
iwl_dbgfs_clear_ucode_statistics_write(struct file
*file
,
2001 const char __user
*user_buf
,
2002 size_t count
, loff_t
*ppos
)
2004 struct iwl_priv
*priv
= file
->private_data
;
2009 memset(buf
, 0, sizeof(buf
));
2010 buf_size
= min(count
, sizeof(buf
) - 1);
2011 if (copy_from_user(buf
, user_buf
, buf_size
))
2013 if (sscanf(buf
, "%d", &clear
) != 1)
2016 /* make request to uCode to retrieve statistics information */
2017 mutex_lock(&priv
->mutex
);
2018 iwl_send_statistics_request(priv
, CMD_SYNC
, true);
2019 mutex_unlock(&priv
->mutex
);
2024 static ssize_t
iwl_dbgfs_csr_write(struct file
*file
,
2025 const char __user
*user_buf
,
2026 size_t count
, loff_t
*ppos
)
2028 struct iwl_priv
*priv
= file
->private_data
;
2033 memset(buf
, 0, sizeof(buf
));
2034 buf_size
= min(count
, sizeof(buf
) - 1);
2035 if (copy_from_user(buf
, user_buf
, buf_size
))
2037 if (sscanf(buf
, "%d", &csr
) != 1)
2040 if (priv
->cfg
->ops
->lib
->dump_csr
)
2041 priv
->cfg
->ops
->lib
->dump_csr(priv
);
2046 static ssize_t
iwl_dbgfs_ucode_tracing_read(struct file
*file
,
2047 char __user
*user_buf
,
2048 size_t count
, loff_t
*ppos
) {
2050 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
2053 const size_t bufsz
= sizeof(buf
);
2056 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "ucode trace timer is %s\n",
2057 priv
->event_log
.ucode_trace
? "On" : "Off");
2058 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "non_wraps_count:\t\t %u\n",
2059 priv
->event_log
.non_wraps_count
);
2060 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "wraps_once_count:\t\t %u\n",
2061 priv
->event_log
.wraps_once_count
);
2062 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "wraps_more_count:\t\t %u\n",
2063 priv
->event_log
.wraps_more_count
);
2065 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
2069 static ssize_t
iwl_dbgfs_ucode_tracing_write(struct file
*file
,
2070 const char __user
*user_buf
,
2071 size_t count
, loff_t
*ppos
)
2073 struct iwl_priv
*priv
= file
->private_data
;
2078 memset(buf
, 0, sizeof(buf
));
2079 buf_size
= min(count
, sizeof(buf
) - 1);
2080 if (copy_from_user(buf
, user_buf
, buf_size
))
2082 if (sscanf(buf
, "%d", &trace
) != 1)
2086 priv
->event_log
.ucode_trace
= true;
2087 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
2088 mod_timer(&priv
->ucode_trace
,
2089 jiffies
+ msecs_to_jiffies(UCODE_TRACE_PERIOD
));
2091 priv
->event_log
.ucode_trace
= false;
2092 del_timer_sync(&priv
->ucode_trace
);
2098 static ssize_t
iwl_dbgfs_fh_reg_read(struct file
*file
,
2099 char __user
*user_buf
,
2100 size_t count
, loff_t
*ppos
)
2102 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
2105 ssize_t ret
= -EFAULT
;
2107 if (priv
->cfg
->ops
->lib
->dump_fh
) {
2108 ret
= pos
= priv
->cfg
->ops
->lib
->dump_fh(priv
, &buf
, true);
2110 ret
= simple_read_from_buffer(user_buf
,
2111 count
, ppos
, buf
, pos
);
2119 static ssize_t
iwl_dbgfs_missed_beacon_read(struct file
*file
,
2120 char __user
*user_buf
,
2121 size_t count
, loff_t
*ppos
) {
2123 struct iwl_priv
*priv
= file
->private_data
;
2126 const size_t bufsz
= sizeof(buf
);
2129 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%d\n",
2130 priv
->missed_beacon_threshold
);
2132 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
2136 static ssize_t
iwl_dbgfs_missed_beacon_write(struct file
*file
,
2137 const char __user
*user_buf
,
2138 size_t count
, loff_t
*ppos
)
2140 struct iwl_priv
*priv
= file
->private_data
;
2145 memset(buf
, 0, sizeof(buf
));
2146 buf_size
= min(count
, sizeof(buf
) - 1);
2147 if (copy_from_user(buf
, user_buf
, buf_size
))
2149 if (sscanf(buf
, "%d", &missed
) != 1)
2152 if (missed
< IWL_MISSED_BEACON_THRESHOLD_MIN
||
2153 missed
> IWL_MISSED_BEACON_THRESHOLD_MAX
)
2154 priv
->missed_beacon_threshold
=
2155 IWL_MISSED_BEACON_THRESHOLD_DEF
;
2157 priv
->missed_beacon_threshold
= missed
;
2162 static ssize_t
iwl_dbgfs_internal_scan_write(struct file
*file
,
2163 const char __user
*user_buf
,
2164 size_t count
, loff_t
*ppos
)
2166 struct iwl_priv
*priv
= file
->private_data
;
2171 memset(buf
, 0, sizeof(buf
));
2172 buf_size
= min(count
, sizeof(buf
) - 1);
2173 if (copy_from_user(buf
, user_buf
, buf_size
))
2175 if (sscanf(buf
, "%d", &scan
) != 1)
2178 iwl_internal_short_hw_scan(priv
);
2183 static ssize_t
iwl_dbgfs_plcp_delta_read(struct file
*file
,
2184 char __user
*user_buf
,
2185 size_t count
, loff_t
*ppos
) {
2187 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
2190 const size_t bufsz
= sizeof(buf
);
2193 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "%u\n",
2194 priv
->cfg
->plcp_delta_threshold
);
2196 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
2200 static ssize_t
iwl_dbgfs_plcp_delta_write(struct file
*file
,
2201 const char __user
*user_buf
,
2202 size_t count
, loff_t
*ppos
) {
2204 struct iwl_priv
*priv
= file
->private_data
;
2209 memset(buf
, 0, sizeof(buf
));
2210 buf_size
= min(count
, sizeof(buf
) - 1);
2211 if (copy_from_user(buf
, user_buf
, buf_size
))
2213 if (sscanf(buf
, "%d", &plcp
) != 1)
2215 if ((plcp
<= IWL_MAX_PLCP_ERR_THRESHOLD_MIN
) ||
2216 (plcp
> IWL_MAX_PLCP_ERR_THRESHOLD_MAX
))
2217 priv
->cfg
->plcp_delta_threshold
=
2218 IWL_MAX_PLCP_ERR_THRESHOLD_DEF
;
2220 priv
->cfg
->plcp_delta_threshold
= plcp
;
2224 static ssize_t
iwl_dbgfs_force_reset_read(struct file
*file
,
2225 char __user
*user_buf
,
2226 size_t count
, loff_t
*ppos
) {
2228 struct iwl_priv
*priv
= file
->private_data
;
2231 const size_t bufsz
= sizeof(buf
);
2232 struct iwl_force_reset
*force_reset
;
2234 for (i
= 0; i
< IWL_MAX_FORCE_RESET
; i
++) {
2235 force_reset
= &priv
->force_reset
[i
];
2236 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
2237 "Force reset method %d\n", i
);
2238 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
2239 "\tnumber of reset request: %d\n",
2240 force_reset
->reset_request_count
);
2241 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
2242 "\tnumber of reset request success: %d\n",
2243 force_reset
->reset_success_count
);
2244 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
2245 "\tnumber of reset request reject: %d\n",
2246 force_reset
->reset_reject_count
);
2247 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
2248 "\treset duration: %lu\n",
2249 force_reset
->reset_duration
);
2251 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
2254 static ssize_t
iwl_dbgfs_force_reset_write(struct file
*file
,
2255 const char __user
*user_buf
,
2256 size_t count
, loff_t
*ppos
) {
2258 struct iwl_priv
*priv
= file
->private_data
;
2263 memset(buf
, 0, sizeof(buf
));
2264 buf_size
= min(count
, sizeof(buf
) - 1);
2265 if (copy_from_user(buf
, user_buf
, buf_size
))
2267 if (sscanf(buf
, "%d", &reset
) != 1)
2272 ret
= iwl_force_reset(priv
, reset
);
2277 return ret
? ret
: count
;
2280 DEBUGFS_READ_FILE_OPS(rx_statistics
);
2281 DEBUGFS_READ_FILE_OPS(tx_statistics
);
2282 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log
);
2283 DEBUGFS_READ_FILE_OPS(rx_queue
);
2284 DEBUGFS_READ_FILE_OPS(tx_queue
);
2285 DEBUGFS_READ_FILE_OPS(ucode_rx_stats
);
2286 DEBUGFS_READ_FILE_OPS(ucode_tx_stats
);
2287 DEBUGFS_READ_FILE_OPS(ucode_general_stats
);
2288 DEBUGFS_READ_FILE_OPS(sensitivity
);
2289 DEBUGFS_READ_FILE_OPS(chain_noise
);
2290 DEBUGFS_READ_FILE_OPS(tx_power
);
2291 DEBUGFS_READ_FILE_OPS(power_save_status
);
2292 DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics
);
2293 DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics
);
2294 DEBUGFS_WRITE_FILE_OPS(csr
);
2295 DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing
);
2296 DEBUGFS_READ_FILE_OPS(fh_reg
);
2297 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon
);
2298 DEBUGFS_WRITE_FILE_OPS(internal_scan
);
2299 DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta
);
2300 DEBUGFS_READ_WRITE_FILE_OPS(force_reset
);
2303 * Create the debugfs files and directories
2306 int iwl_dbgfs_register(struct iwl_priv
*priv
, const char *name
)
2308 struct dentry
*phyd
= priv
->hw
->wiphy
->debugfsdir
;
2309 struct dentry
*dir_drv
, *dir_data
, *dir_rf
, *dir_debug
;
2311 dir_drv
= debugfs_create_dir(name
, phyd
);
2315 priv
->debugfs_dir
= dir_drv
;
2317 dir_data
= debugfs_create_dir("data", dir_drv
);
2320 dir_rf
= debugfs_create_dir("rf", dir_drv
);
2323 dir_debug
= debugfs_create_dir("debug", dir_drv
);
2327 DEBUGFS_ADD_FILE(nvm
, dir_data
, S_IRUSR
);
2328 DEBUGFS_ADD_FILE(sram
, dir_data
, S_IWUSR
| S_IRUSR
);
2329 DEBUGFS_ADD_FILE(log_event
, dir_data
, S_IWUSR
| S_IRUSR
);
2330 DEBUGFS_ADD_FILE(stations
, dir_data
, S_IRUSR
);
2331 DEBUGFS_ADD_FILE(channels
, dir_data
, S_IRUSR
);
2332 DEBUGFS_ADD_FILE(status
, dir_data
, S_IRUSR
);
2333 DEBUGFS_ADD_FILE(interrupt
, dir_data
, S_IWUSR
| S_IRUSR
);
2334 DEBUGFS_ADD_FILE(qos
, dir_data
, S_IRUSR
);
2335 DEBUGFS_ADD_FILE(led
, dir_data
, S_IRUSR
);
2336 DEBUGFS_ADD_FILE(sleep_level_override
, dir_data
, S_IWUSR
| S_IRUSR
);
2337 DEBUGFS_ADD_FILE(current_sleep_command
, dir_data
, S_IRUSR
);
2338 DEBUGFS_ADD_FILE(thermal_throttling
, dir_data
, S_IRUSR
);
2339 DEBUGFS_ADD_FILE(disable_ht40
, dir_data
, S_IWUSR
| S_IRUSR
);
2340 DEBUGFS_ADD_FILE(rx_statistics
, dir_debug
, S_IRUSR
);
2341 DEBUGFS_ADD_FILE(tx_statistics
, dir_debug
, S_IRUSR
);
2342 DEBUGFS_ADD_FILE(traffic_log
, dir_debug
, S_IWUSR
| S_IRUSR
);
2343 DEBUGFS_ADD_FILE(rx_queue
, dir_debug
, S_IRUSR
);
2344 DEBUGFS_ADD_FILE(tx_queue
, dir_debug
, S_IRUSR
);
2345 DEBUGFS_ADD_FILE(tx_power
, dir_debug
, S_IRUSR
);
2346 DEBUGFS_ADD_FILE(power_save_status
, dir_debug
, S_IRUSR
);
2347 DEBUGFS_ADD_FILE(clear_ucode_statistics
, dir_debug
, S_IWUSR
);
2348 DEBUGFS_ADD_FILE(clear_traffic_statistics
, dir_debug
, S_IWUSR
);
2349 DEBUGFS_ADD_FILE(csr
, dir_debug
, S_IWUSR
);
2350 DEBUGFS_ADD_FILE(fh_reg
, dir_debug
, S_IRUSR
);
2351 DEBUGFS_ADD_FILE(missed_beacon
, dir_debug
, S_IWUSR
);
2352 DEBUGFS_ADD_FILE(internal_scan
, dir_debug
, S_IWUSR
);
2353 DEBUGFS_ADD_FILE(plcp_delta
, dir_debug
, S_IWUSR
| S_IRUSR
);
2354 DEBUGFS_ADD_FILE(force_reset
, dir_debug
, S_IWUSR
| S_IRUSR
);
2355 if ((priv
->hw_rev
& CSR_HW_REV_TYPE_MSK
) != CSR_HW_REV_TYPE_3945
) {
2356 DEBUGFS_ADD_FILE(ucode_rx_stats
, dir_debug
, S_IRUSR
);
2357 DEBUGFS_ADD_FILE(ucode_tx_stats
, dir_debug
, S_IRUSR
);
2358 DEBUGFS_ADD_FILE(ucode_general_stats
, dir_debug
, S_IRUSR
);
2359 DEBUGFS_ADD_FILE(sensitivity
, dir_debug
, S_IRUSR
);
2360 DEBUGFS_ADD_FILE(chain_noise
, dir_debug
, S_IRUSR
);
2361 DEBUGFS_ADD_FILE(ucode_tracing
, dir_debug
, S_IWUSR
| S_IRUSR
);
2363 DEBUGFS_ADD_BOOL(disable_sensitivity
, dir_rf
, &priv
->disable_sens_cal
);
2364 DEBUGFS_ADD_BOOL(disable_chain_noise
, dir_rf
,
2365 &priv
->disable_chain_noise_cal
);
2366 if (((priv
->hw_rev
& CSR_HW_REV_TYPE_MSK
) == CSR_HW_REV_TYPE_4965
) ||
2367 ((priv
->hw_rev
& CSR_HW_REV_TYPE_MSK
) == CSR_HW_REV_TYPE_3945
))
2368 DEBUGFS_ADD_BOOL(disable_tx_power
, dir_rf
,
2369 &priv
->disable_tx_power_cal
);
2373 IWL_ERR(priv
, "Can't create the debugfs directory\n");
2374 iwl_dbgfs_unregister(priv
);
2377 EXPORT_SYMBOL(iwl_dbgfs_register
);
2380 * Remove the debugfs files and directories
2383 void iwl_dbgfs_unregister(struct iwl_priv
*priv
)
2385 if (!priv
->debugfs_dir
)
2388 debugfs_remove_recursive(priv
->debugfs_dir
);
2389 priv
->debugfs_dir
= NULL
;
2391 EXPORT_SYMBOL(iwl_dbgfs_unregister
);