1 /******************************************************************************
5 * Copyright(c) 2008 - 2009 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_DIR(name, parent) do { \
45 dbgfs->dir_##name = debugfs_create_dir(#name, parent); \
46 if (!(dbgfs->dir_##name)) \
50 #define DEBUGFS_ADD_FILE(name, parent) do { \
51 dbgfs->dbgfs_##parent##_files.file_##name = \
52 debugfs_create_file(#name, S_IWUSR | S_IRUSR, \
53 dbgfs->dir_##parent, priv, \
54 &iwl_dbgfs_##name##_ops); \
55 if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \
59 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
60 dbgfs->dbgfs_##parent##_files.file_##name = \
61 debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
62 dbgfs->dir_##parent, ptr); \
63 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \
64 || !dbgfs->dbgfs_##parent##_files.file_##name) \
68 #define DEBUGFS_ADD_X32(name, parent, ptr) do { \
69 dbgfs->dbgfs_##parent##_files.file_##name = \
70 debugfs_create_x32(#name, S_IRUSR, dbgfs->dir_##parent, ptr); \
71 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \
72 || !dbgfs->dbgfs_##parent##_files.file_##name) \
76 #define DEBUGFS_REMOVE(name) do { \
77 debugfs_remove(name); \
82 #define DEBUGFS_READ_FUNC(name) \
83 static ssize_t iwl_dbgfs_##name##_read(struct file *file, \
84 char __user *user_buf, \
85 size_t count, loff_t *ppos);
87 #define DEBUGFS_WRITE_FUNC(name) \
88 static ssize_t iwl_dbgfs_##name##_write(struct file *file, \
89 const char __user *user_buf, \
90 size_t count, loff_t *ppos);
93 static int iwl_dbgfs_open_file_generic(struct inode
*inode
, struct file
*file
)
95 file
->private_data
= inode
->i_private
;
99 #define DEBUGFS_READ_FILE_OPS(name) \
100 DEBUGFS_READ_FUNC(name); \
101 static const struct file_operations iwl_dbgfs_##name##_ops = { \
102 .read = iwl_dbgfs_##name##_read, \
103 .open = iwl_dbgfs_open_file_generic, \
106 #define DEBUGFS_WRITE_FILE_OPS(name) \
107 DEBUGFS_WRITE_FUNC(name); \
108 static const struct file_operations iwl_dbgfs_##name##_ops = { \
109 .write = iwl_dbgfs_##name##_write, \
110 .open = iwl_dbgfs_open_file_generic, \
114 #define DEBUGFS_READ_WRITE_FILE_OPS(name) \
115 DEBUGFS_READ_FUNC(name); \
116 DEBUGFS_WRITE_FUNC(name); \
117 static const struct file_operations iwl_dbgfs_##name##_ops = { \
118 .write = iwl_dbgfs_##name##_write, \
119 .read = iwl_dbgfs_##name##_read, \
120 .open = iwl_dbgfs_open_file_generic, \
124 static ssize_t
iwl_dbgfs_tx_statistics_read(struct file
*file
,
125 char __user
*user_buf
,
126 size_t count
, loff_t
*ppos
) {
128 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
134 const size_t bufsz
= 100 + sizeof(char) * 24 * (MANAGEMENT_MAX
+ CONTROL_MAX
);
135 buf
= kzalloc(bufsz
, GFP_KERNEL
);
138 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Management:\n");
139 for (cnt
= 0; cnt
< MANAGEMENT_MAX
; cnt
++) {
140 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
142 get_mgmt_string(cnt
),
143 priv
->tx_stats
.mgmt
[cnt
]);
145 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Control\n");
146 for (cnt
= 0; cnt
< CONTROL_MAX
; cnt
++) {
147 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
149 get_ctrl_string(cnt
),
150 priv
->tx_stats
.ctrl
[cnt
]);
152 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Data:\n");
153 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tcnt: %u\n",
154 priv
->tx_stats
.data_cnt
);
155 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tbytes: %llu\n",
156 priv
->tx_stats
.data_bytes
);
157 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
162 static ssize_t
iwl_dbgfs_tx_statistics_write(struct file
*file
,
163 const char __user
*user_buf
,
164 size_t count
, loff_t
*ppos
)
166 struct iwl_priv
*priv
= file
->private_data
;
171 memset(buf
, 0, sizeof(buf
));
172 buf_size
= min(count
, sizeof(buf
) - 1);
173 if (copy_from_user(buf
, user_buf
, buf_size
))
175 if (sscanf(buf
, "%x", &clear_flag
) != 1)
178 iwl_clear_tx_stats(priv
);
183 static ssize_t
iwl_dbgfs_rx_statistics_read(struct file
*file
,
184 char __user
*user_buf
,
185 size_t count
, loff_t
*ppos
) {
187 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
192 const size_t bufsz
= 100 +
193 sizeof(char) * 24 * (MANAGEMENT_MAX
+ CONTROL_MAX
);
194 buf
= kzalloc(bufsz
, GFP_KERNEL
);
198 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Management:\n");
199 for (cnt
= 0; cnt
< MANAGEMENT_MAX
; cnt
++) {
200 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
202 get_mgmt_string(cnt
),
203 priv
->rx_stats
.mgmt
[cnt
]);
205 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Control:\n");
206 for (cnt
= 0; cnt
< CONTROL_MAX
; cnt
++) {
207 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
209 get_ctrl_string(cnt
),
210 priv
->rx_stats
.ctrl
[cnt
]);
212 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Data:\n");
213 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tcnt: %u\n",
214 priv
->rx_stats
.data_cnt
);
215 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\tbytes: %llu\n",
216 priv
->rx_stats
.data_bytes
);
218 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
223 static ssize_t
iwl_dbgfs_rx_statistics_write(struct file
*file
,
224 const char __user
*user_buf
,
225 size_t count
, loff_t
*ppos
)
227 struct iwl_priv
*priv
= file
->private_data
;
232 memset(buf
, 0, sizeof(buf
));
233 buf_size
= min(count
, sizeof(buf
) - 1);
234 if (copy_from_user(buf
, user_buf
, buf_size
))
236 if (sscanf(buf
, "%x", &clear_flag
) != 1)
239 iwl_clear_rx_stats(priv
);
243 #define BYTE1_MASK 0x000000ff;
244 #define BYTE2_MASK 0x0000ffff;
245 #define BYTE3_MASK 0x00ffffff;
246 static ssize_t
iwl_dbgfs_sram_read(struct file
*file
,
247 char __user
*user_buf
,
248 size_t count
, loff_t
*ppos
)
255 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
256 const size_t bufsz
= sizeof(buf
);
258 for (i
= priv
->dbgfs
->sram_len
; i
> 0; i
-= 4) {
259 val
= iwl_read_targ_mem(priv
, priv
->dbgfs
->sram_offset
+ \
260 priv
->dbgfs
->sram_len
- i
);
274 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "0x%08x ", val
);
276 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
278 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
282 static ssize_t
iwl_dbgfs_sram_write(struct file
*file
,
283 const char __user
*user_buf
,
284 size_t count
, loff_t
*ppos
)
286 struct iwl_priv
*priv
= file
->private_data
;
291 memset(buf
, 0, sizeof(buf
));
292 buf_size
= min(count
, sizeof(buf
) - 1);
293 if (copy_from_user(buf
, user_buf
, buf_size
))
296 if (sscanf(buf
, "%x,%x", &offset
, &len
) == 2) {
297 priv
->dbgfs
->sram_offset
= offset
;
298 priv
->dbgfs
->sram_len
= len
;
300 priv
->dbgfs
->sram_offset
= 0;
301 priv
->dbgfs
->sram_len
= 0;
307 static ssize_t
iwl_dbgfs_stations_read(struct file
*file
, char __user
*user_buf
,
308 size_t count
, loff_t
*ppos
)
310 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
311 struct iwl_station_entry
*station
;
312 int max_sta
= priv
->hw_params
.max_stations
;
316 /* Add 30 for initial string */
317 const size_t bufsz
= 30 + sizeof(char) * 500 * (priv
->num_stations
);
319 buf
= kmalloc(bufsz
, GFP_KERNEL
);
323 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "num of stations: %d\n\n",
326 for (i
= 0; i
< max_sta
; i
++) {
327 station
= &priv
->stations
[i
];
329 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
330 "station %d:\ngeneral data:\n", i
+1);
331 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "id: %u\n",
332 station
->sta
.sta
.sta_id
);
333 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "mode: %u\n",
335 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
337 station
->sta
.station_flags_msk
);
338 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
339 "ps_status: %u\n", station
->ps_status
);
340 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "tid data:\n");
341 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
342 "seq_num\t\ttxq_id");
343 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
344 "\tframe_count\twait_for_ba\t");
345 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
346 "start_idx\tbitmap0\t");
347 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
348 "bitmap1\trate_n_flags");
349 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
351 for (j
= 0; j
< MAX_TID_COUNT
; j
++) {
352 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
354 station
->tid
[j
].seq_number
);
355 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
356 "\t%u\t\t%u\t\t%u\t\t",
357 station
->tid
[j
].agg
.txq_id
,
358 station
->tid
[j
].agg
.frame_count
,
359 station
->tid
[j
].agg
.wait_for_ba
);
360 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
362 station
->tid
[j
].agg
.start_idx
,
363 (unsigned long long)station
->tid
[j
].agg
.bitmap
,
364 station
->tid
[j
].agg
.rate_n_flags
);
365 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
367 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
371 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
376 static ssize_t
iwl_dbgfs_nvm_read(struct file
*file
,
377 char __user
*user_buf
,
382 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
383 int pos
= 0, ofs
= 0, buf_size
= 0;
387 size_t eeprom_len
= priv
->cfg
->eeprom_size
;
388 buf_size
= 4 * eeprom_len
+ 256;
390 if (eeprom_len
% 16) {
391 IWL_ERR(priv
, "NVM size is not multiple of 16.\n");
397 IWL_ERR(priv
, "Invalid EEPROM/OTP memory\n");
401 /* 4 characters for byte 0xYY */
402 buf
= kzalloc(buf_size
, GFP_KERNEL
);
404 IWL_ERR(priv
, "Can not allocate Buffer\n");
407 eeprom_ver
= iwl_eeprom_query16(priv
, EEPROM_VERSION
);
408 pos
+= scnprintf(buf
+ pos
, buf_size
- pos
, "NVM Type: %s, "
410 (priv
->nvm_device_type
== NVM_DEVICE_TYPE_OTP
)
411 ? "OTP" : "EEPROM", eeprom_ver
);
412 for (ofs
= 0 ; ofs
< eeprom_len
; ofs
+= 16) {
413 pos
+= scnprintf(buf
+ pos
, buf_size
- pos
, "0x%.4x ", ofs
);
414 hex_dump_to_buffer(ptr
+ ofs
, 16 , 16, 2, buf
+ pos
,
416 pos
+= strlen(buf
+ pos
);
417 if (buf_size
- pos
> 0)
421 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
);
449 static ssize_t
iwl_dbgfs_channels_read(struct file
*file
, char __user
*user_buf
,
450 size_t count
, loff_t
*ppos
)
452 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
453 struct ieee80211_channel
*channels
= NULL
;
454 const struct ieee80211_supported_band
*supp_band
= NULL
;
455 int pos
= 0, i
, bufsz
= PAGE_SIZE
;
459 if (!test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
))
462 buf
= kzalloc(bufsz
, GFP_KERNEL
);
464 IWL_ERR(priv
, "Can not allocate Buffer\n");
468 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_2GHZ
);
470 channels
= supp_band
->channels
;
472 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
473 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
474 supp_band
->n_channels
);
476 for (i
= 0; i
< supp_band
->n_channels
; i
++)
477 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
478 "%d: %ddBm: BSS%s%s, %s.\n",
479 ieee80211_frequency_to_channel(
480 channels
[i
].center_freq
),
481 channels
[i
].max_power
,
482 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
483 " (IEEE 802.11h required)" : "",
484 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
485 || (channels
[i
].flags
&
486 IEEE80211_CHAN_RADAR
)) ? "" :
489 IEEE80211_CHAN_PASSIVE_SCAN
?
490 "passive only" : "active/passive");
492 supp_band
= iwl_get_hw_mode(priv
, IEEE80211_BAND_5GHZ
);
494 channels
= supp_band
->channels
;
496 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
497 "Displaying %d channels in 5.2GHz band (802.11a)\n",
498 supp_band
->n_channels
);
500 for (i
= 0; i
< supp_band
->n_channels
; i
++)
501 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
502 "%d: %ddBm: BSS%s%s, %s.\n",
503 ieee80211_frequency_to_channel(
504 channels
[i
].center_freq
),
505 channels
[i
].max_power
,
506 channels
[i
].flags
& IEEE80211_CHAN_RADAR
?
507 " (IEEE 802.11h required)" : "",
508 ((channels
[i
].flags
& IEEE80211_CHAN_NO_IBSS
)
509 || (channels
[i
].flags
&
510 IEEE80211_CHAN_RADAR
)) ? "" :
513 IEEE80211_CHAN_PASSIVE_SCAN
?
514 "passive only" : "active/passive");
516 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
521 static ssize_t
iwl_dbgfs_status_read(struct file
*file
,
522 char __user
*user_buf
,
523 size_t count
, loff_t
*ppos
) {
525 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
528 const size_t bufsz
= sizeof(buf
);
530 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_HCMD_ACTIVE:\t %d\n",
531 test_bit(STATUS_HCMD_ACTIVE
, &priv
->status
));
532 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_HCMD_SYNC_ACTIVE: %d\n",
533 test_bit(STATUS_HCMD_SYNC_ACTIVE
, &priv
->status
));
534 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INT_ENABLED:\t %d\n",
535 test_bit(STATUS_INT_ENABLED
, &priv
->status
));
536 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_RF_KILL_HW:\t %d\n",
537 test_bit(STATUS_RF_KILL_HW
, &priv
->status
));
538 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_CT_KILL:\t\t %d\n",
539 test_bit(STATUS_CT_KILL
, &priv
->status
));
540 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_INIT:\t\t %d\n",
541 test_bit(STATUS_INIT
, &priv
->status
));
542 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_ALIVE:\t\t %d\n",
543 test_bit(STATUS_ALIVE
, &priv
->status
));
544 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_READY:\t\t %d\n",
545 test_bit(STATUS_READY
, &priv
->status
));
546 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_TEMPERATURE:\t %d\n",
547 test_bit(STATUS_TEMPERATURE
, &priv
->status
));
548 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_GEO_CONFIGURED:\t %d\n",
549 test_bit(STATUS_GEO_CONFIGURED
, &priv
->status
));
550 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_EXIT_PENDING:\t %d\n",
551 test_bit(STATUS_EXIT_PENDING
, &priv
->status
));
552 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_STATISTICS:\t %d\n",
553 test_bit(STATUS_STATISTICS
, &priv
->status
));
554 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCANNING:\t %d\n",
555 test_bit(STATUS_SCANNING
, &priv
->status
));
556 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_ABORTING:\t %d\n",
557 test_bit(STATUS_SCAN_ABORTING
, &priv
->status
));
558 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_SCAN_HW:\t\t %d\n",
559 test_bit(STATUS_SCAN_HW
, &priv
->status
));
560 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_POWER_PMI:\t %d\n",
561 test_bit(STATUS_POWER_PMI
, &priv
->status
));
562 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_FW_ERROR:\t %d\n",
563 test_bit(STATUS_FW_ERROR
, &priv
->status
));
564 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "STATUS_MODE_PENDING:\t %d\n",
565 test_bit(STATUS_MODE_PENDING
, &priv
->status
));
566 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
569 static ssize_t
iwl_dbgfs_interrupt_read(struct file
*file
,
570 char __user
*user_buf
,
571 size_t count
, loff_t
*ppos
) {
573 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
577 int bufsz
= 24 * 64; /* 24 items * 64 char per item */
580 buf
= kzalloc(bufsz
, GFP_KERNEL
);
582 IWL_ERR(priv
, "Can not allocate Buffer\n");
586 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
587 "Interrupt Statistics Report:\n");
589 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "HW Error:\t\t\t %u\n",
591 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "SW Error:\t\t\t %u\n",
593 if (priv
->isr_stats
.sw
> 0) {
594 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
595 "\tLast Restarting Code: 0x%X\n",
596 priv
->isr_stats
.sw_err
);
598 #ifdef CONFIG_IWLWIFI_DEBUG
599 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Frame transmitted:\t\t %u\n",
600 priv
->isr_stats
.sch
);
601 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Alive interrupt:\t\t %u\n",
602 priv
->isr_stats
.alive
);
604 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
605 "HW RF KILL switch toggled:\t %u\n",
606 priv
->isr_stats
.rfkill
);
608 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "CT KILL:\t\t\t %u\n",
609 priv
->isr_stats
.ctkill
);
611 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Wakeup Interrupt:\t\t %u\n",
612 priv
->isr_stats
.wakeup
);
614 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
615 "Rx command responses:\t\t %u\n",
617 for (cnt
= 0; cnt
< REPLY_MAX
; cnt
++) {
618 if (priv
->isr_stats
.rx_handlers
[cnt
] > 0)
619 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
620 "\tRx handler[%36s]:\t\t %u\n",
622 priv
->isr_stats
.rx_handlers
[cnt
]);
625 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx/FH interrupt:\t\t %u\n",
628 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Unexpected INTA:\t\t %u\n",
629 priv
->isr_stats
.unhandled
);
631 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
636 static ssize_t
iwl_dbgfs_interrupt_write(struct file
*file
,
637 const char __user
*user_buf
,
638 size_t count
, loff_t
*ppos
)
640 struct iwl_priv
*priv
= file
->private_data
;
645 memset(buf
, 0, sizeof(buf
));
646 buf_size
= min(count
, sizeof(buf
) - 1);
647 if (copy_from_user(buf
, user_buf
, buf_size
))
649 if (sscanf(buf
, "%x", &reset_flag
) != 1)
652 iwl_clear_isr_stats(priv
);
657 static ssize_t
iwl_dbgfs_qos_read(struct file
*file
, char __user
*user_buf
,
658 size_t count
, loff_t
*ppos
)
660 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
663 const size_t bufsz
= sizeof(buf
);
666 for (i
= 0; i
< AC_NUM
; i
++) {
667 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
668 "\tcw_min\tcw_max\taifsn\ttxop\n");
669 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
670 "AC[%d]\t%u\t%u\t%u\t%u\n", i
,
671 priv
->qos_data
.def_qos_parm
.ac
[i
].cw_min
,
672 priv
->qos_data
.def_qos_parm
.ac
[i
].cw_max
,
673 priv
->qos_data
.def_qos_parm
.ac
[i
].aifsn
,
674 priv
->qos_data
.def_qos_parm
.ac
[i
].edca_txop
);
676 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
680 static ssize_t
iwl_dbgfs_led_read(struct file
*file
, char __user
*user_buf
,
681 size_t count
, loff_t
*ppos
)
683 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
686 const size_t bufsz
= sizeof(buf
);
689 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
690 "allow blinking: %s\n",
691 (priv
->allow_blinking
) ? "True" : "False");
692 if (priv
->allow_blinking
) {
693 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
694 "Led blinking rate: %u\n",
695 priv
->last_blink_rate
);
696 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
697 "Last blink time: %lu\n",
698 priv
->last_blink_time
);
701 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
705 static ssize_t
iwl_dbgfs_thermal_throttling_read(struct file
*file
,
706 char __user
*user_buf
,
707 size_t count
, loff_t
*ppos
)
709 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
710 struct iwl_tt_mgmt
*tt
= &priv
->thermal_throttle
;
711 struct iwl_tt_restriction
*restriction
;
714 const size_t bufsz
= sizeof(buf
);
717 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
718 "Thermal Throttling Mode: %s\n",
719 tt
->advanced_tt
? "Advance" : "Legacy");
720 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
721 "Thermal Throttling State: %d\n",
723 if (tt
->advanced_tt
) {
724 restriction
= tt
->restriction
+ tt
->state
;
725 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
727 restriction
->tx_stream
);
728 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
730 restriction
->rx_stream
);
731 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
735 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
739 static ssize_t
iwl_dbgfs_disable_ht40_write(struct file
*file
,
740 const char __user
*user_buf
,
741 size_t count
, loff_t
*ppos
)
743 struct iwl_priv
*priv
= file
->private_data
;
748 memset(buf
, 0, sizeof(buf
));
749 buf_size
= min(count
, sizeof(buf
) - 1);
750 if (copy_from_user(buf
, user_buf
, buf_size
))
752 if (sscanf(buf
, "%d", &ht40
) != 1)
754 if (!iwl_is_associated(priv
))
755 priv
->disable_ht40
= ht40
? true : false;
757 IWL_ERR(priv
, "Sta associated with AP - "
758 "Change to 40MHz channel support is not allowed\n");
765 static ssize_t
iwl_dbgfs_disable_ht40_read(struct file
*file
,
766 char __user
*user_buf
,
767 size_t count
, loff_t
*ppos
)
769 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
772 const size_t bufsz
= sizeof(buf
);
775 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
776 "11n 40MHz Mode: %s\n",
777 priv
->disable_ht40
? "Disabled" : "Enabled");
778 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
782 static ssize_t
iwl_dbgfs_sleep_level_override_write(struct file
*file
,
783 const char __user
*user_buf
,
784 size_t count
, loff_t
*ppos
)
786 struct iwl_priv
*priv
= file
->private_data
;
791 memset(buf
, 0, sizeof(buf
));
792 buf_size
= min(count
, sizeof(buf
) - 1);
793 if (copy_from_user(buf
, user_buf
, buf_size
))
796 if (sscanf(buf
, "%d", &value
) != 1)
800 * Our users expect 0 to be "CAM", but 0 isn't actually
801 * valid here. However, let's not confuse them and present
802 * IWL_POWER_INDEX_1 as "1", not "0".
809 if (value
!= -1 && (value
< 0 || value
>= IWL_POWER_NUM
))
812 priv
->power_data
.debug_sleep_level_override
= value
;
814 iwl_power_update_mode(priv
, false);
819 static ssize_t
iwl_dbgfs_sleep_level_override_read(struct file
*file
,
820 char __user
*user_buf
,
821 size_t count
, loff_t
*ppos
)
823 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
826 const size_t bufsz
= sizeof(buf
);
828 /* see the write function */
829 value
= priv
->power_data
.debug_sleep_level_override
;
833 pos
= scnprintf(buf
, bufsz
, "%d\n", value
);
834 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
837 static ssize_t
iwl_dbgfs_current_sleep_command_read(struct file
*file
,
838 char __user
*user_buf
,
839 size_t count
, loff_t
*ppos
)
841 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
844 const size_t bufsz
= sizeof(buf
);
845 struct iwl_powertable_cmd
*cmd
= &priv
->power_data
.sleep_cmd
;
847 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
848 "flags: %#.2x\n", le16_to_cpu(cmd
->flags
));
849 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
850 "RX/TX timeout: %d/%d usec\n",
851 le32_to_cpu(cmd
->rx_data_timeout
),
852 le32_to_cpu(cmd
->tx_data_timeout
));
853 for (i
= 0; i
< IWL_POWER_VEC_SIZE
; i
++)
854 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
855 "sleep_interval[%d]: %d\n", i
,
856 le32_to_cpu(cmd
->sleep_interval
[i
]));
858 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
861 DEBUGFS_READ_WRITE_FILE_OPS(sram
);
862 DEBUGFS_WRITE_FILE_OPS(log_event
);
863 DEBUGFS_READ_FILE_OPS(nvm
);
864 DEBUGFS_READ_FILE_OPS(stations
);
865 DEBUGFS_READ_FILE_OPS(channels
);
866 DEBUGFS_READ_FILE_OPS(status
);
867 DEBUGFS_READ_WRITE_FILE_OPS(interrupt
);
868 DEBUGFS_READ_FILE_OPS(qos
);
869 DEBUGFS_READ_FILE_OPS(led
);
870 DEBUGFS_READ_FILE_OPS(thermal_throttling
);
871 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40
);
872 DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override
);
873 DEBUGFS_READ_FILE_OPS(current_sleep_command
);
875 static ssize_t
iwl_dbgfs_traffic_log_read(struct file
*file
,
876 char __user
*user_buf
,
877 size_t count
, loff_t
*ppos
)
879 struct iwl_priv
*priv
= file
->private_data
;
880 int pos
= 0, ofs
= 0;
882 struct iwl_tx_queue
*txq
;
884 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
886 int bufsz
= ((IWL_TRAFFIC_ENTRIES
* IWL_TRAFFIC_ENTRY_SIZE
* 64) * 2) +
887 (priv
->cfg
->num_of_queues
* 32 * 8) + 400;
892 IWL_ERR(priv
, "txq not ready\n");
895 buf
= kzalloc(bufsz
, GFP_KERNEL
);
897 IWL_ERR(priv
, "Can not allocate buffer\n");
900 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Tx Queue\n");
901 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
902 txq
= &priv
->txq
[cnt
];
904 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
905 "q[%d]: read_ptr: %u, write_ptr: %u\n",
906 cnt
, q
->read_ptr
, q
->write_ptr
);
908 if (priv
->tx_traffic
&& (iwl_debug_level
& IWL_DL_TX
)) {
909 ptr
= priv
->tx_traffic
;
910 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
911 "Tx Traffic idx: %u\n", priv
->tx_traffic_idx
);
912 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
913 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
914 entry
++, ofs
+= 16) {
915 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
917 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
918 buf
+ pos
, bufsz
- pos
, 0);
919 pos
+= strlen(buf
+ pos
);
926 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Rx Queue\n");
927 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
928 "read: %u, write: %u\n",
929 rxq
->read
, rxq
->write
);
931 if (priv
->rx_traffic
&& (iwl_debug_level
& IWL_DL_RX
)) {
932 ptr
= priv
->rx_traffic
;
933 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
934 "Rx Traffic idx: %u\n", priv
->rx_traffic_idx
);
935 for (cnt
= 0, ofs
= 0; cnt
< IWL_TRAFFIC_ENTRIES
; cnt
++) {
936 for (entry
= 0; entry
< IWL_TRAFFIC_ENTRY_SIZE
/ 16;
937 entry
++, ofs
+= 16) {
938 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
940 hex_dump_to_buffer(ptr
+ ofs
, 16, 16, 2,
941 buf
+ pos
, bufsz
- pos
, 0);
942 pos
+= strlen(buf
+ pos
);
949 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
954 static ssize_t
iwl_dbgfs_traffic_log_write(struct file
*file
,
955 const char __user
*user_buf
,
956 size_t count
, loff_t
*ppos
)
958 struct iwl_priv
*priv
= file
->private_data
;
963 memset(buf
, 0, sizeof(buf
));
964 buf_size
= min(count
, sizeof(buf
) - 1);
965 if (copy_from_user(buf
, user_buf
, buf_size
))
967 if (sscanf(buf
, "%d", &traffic_log
) != 1)
969 if (traffic_log
== 0)
970 iwl_reset_traffic_log(priv
);
975 static ssize_t
iwl_dbgfs_tx_queue_read(struct file
*file
,
976 char __user
*user_buf
,
977 size_t count
, loff_t
*ppos
) {
979 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
980 struct iwl_tx_queue
*txq
;
986 const size_t bufsz
= sizeof(char) * 60 * priv
->cfg
->num_of_queues
;
989 IWL_ERR(priv
, "txq not ready\n");
992 buf
= kzalloc(bufsz
, GFP_KERNEL
);
996 for (cnt
= 0; cnt
< priv
->hw_params
.max_txq_num
; cnt
++) {
997 txq
= &priv
->txq
[cnt
];
999 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1000 "hwq %.2d: read=%u write=%u stop=%d"
1001 " swq_id=%#.2x (ac %d/hwq %d)\n",
1002 cnt
, q
->read_ptr
, q
->write_ptr
,
1003 !!test_bit(cnt
, priv
->queue_stopped
),
1005 txq
->swq_id
& 0x80 ? txq
->swq_id
& 3 :
1007 txq
->swq_id
& 0x80 ? (txq
->swq_id
>> 2) &
1008 0x1f : txq
->swq_id
);
1011 /* for the ACs, display the stop count too */
1012 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1013 " stop-count: %d\n",
1014 atomic_read(&priv
->queue_stop_count
[cnt
]));
1016 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1021 static ssize_t
iwl_dbgfs_rx_queue_read(struct file
*file
,
1022 char __user
*user_buf
,
1023 size_t count
, loff_t
*ppos
) {
1025 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1026 struct iwl_rx_queue
*rxq
= &priv
->rxq
;
1029 const size_t bufsz
= sizeof(buf
);
1031 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "read: %u\n",
1033 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "write: %u\n",
1035 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "free_count: %u\n",
1037 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "closed_rb_num: %u\n",
1038 le16_to_cpu(rxq
->rb_stts
->closed_rb_num
) & 0x0FFF);
1039 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1042 #define UCODE_STATISTICS_CLEAR_MSK (0x1 << 0)
1043 #define UCODE_STATISTICS_FREQUENCY_MSK (0x1 << 1)
1044 #define UCODE_STATISTICS_NARROW_BAND_MSK (0x1 << 2)
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");
1071 static ssize_t
iwl_dbgfs_ucode_rx_stats_read(struct file
*file
,
1072 char __user
*user_buf
,
1073 size_t count
, loff_t
*ppos
)
1075 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1078 int bufsz
= sizeof(struct statistics_rx_phy
) * 20 +
1079 sizeof(struct statistics_rx_non_phy
) * 20 +
1080 sizeof(struct statistics_rx_ht_phy
) * 20 + 400;
1082 struct statistics_rx_phy
*ofdm
, *accum_ofdm
;
1083 struct statistics_rx_phy
*cck
, *accum_cck
;
1084 struct statistics_rx_non_phy
*general
, *accum_general
;
1085 struct statistics_rx_ht_phy
*ht
, *accum_ht
;
1087 if (!iwl_is_alive(priv
))
1090 /* make request to uCode to retrieve statistics information */
1091 mutex_lock(&priv
->mutex
);
1092 ret
= iwl_send_statistics_request(priv
, 0);
1093 mutex_unlock(&priv
->mutex
);
1097 "Error sending statistics request: %zd\n", ret
);
1100 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1102 IWL_ERR(priv
, "Can not allocate Buffer\n");
1106 /* the statistic information display here is based on
1107 * the last statistics notification from uCode
1108 * might not reflect the current uCode activity
1110 ofdm
= &priv
->statistics
.rx
.ofdm
;
1111 cck
= &priv
->statistics
.rx
.cck
;
1112 general
= &priv
->statistics
.rx
.general
;
1113 ht
= &priv
->statistics
.rx
.ofdm_ht
;
1114 accum_ofdm
= &priv
->accum_statistics
.rx
.ofdm
;
1115 accum_cck
= &priv
->accum_statistics
.rx
.cck
;
1116 accum_general
= &priv
->accum_statistics
.rx
.general
;
1117 accum_ht
= &priv
->accum_statistics
.rx
.ofdm_ht
;
1118 pos
+= iwl_dbgfs_statistics_flag(priv
, buf
, bufsz
);
1119 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Statistics_Rx - OFDM:\n");
1120 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1121 "\t\t\tcurrent\t\t\taccumulative\n");
1122 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "ina_cnt:\t\t%u\t\t\t%u\n",
1123 le32_to_cpu(ofdm
->ina_cnt
), accum_ofdm
->ina_cnt
);
1124 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "fina_cnt:\t\t%u\t\t\t%u\n",
1125 le32_to_cpu(ofdm
->fina_cnt
), accum_ofdm
->fina_cnt
);
1126 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "plcp_err:\t\t%u\t\t\t%u\n",
1127 le32_to_cpu(ofdm
->plcp_err
), accum_ofdm
->plcp_err
);
1128 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "crc32_err:\t\t%u\t\t\t%u\n",
1129 le32_to_cpu(ofdm
->crc32_err
), accum_ofdm
->crc32_err
);
1130 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1131 "overrun_err:\t\t%u\t\t\t%u\n",
1132 le32_to_cpu(ofdm
->overrun_err
),
1133 accum_ofdm
->overrun_err
);
1134 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1135 "early_overrun_err:\t%u\t\t\t%u\n",
1136 le32_to_cpu(ofdm
->early_overrun_err
),
1137 accum_ofdm
->early_overrun_err
);
1138 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "crc32_good:\t\t%u\t\t\t%u\n",
1139 le32_to_cpu(ofdm
->crc32_good
),
1140 accum_ofdm
->crc32_good
);
1141 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1142 "false_alarm_cnt:\t%u\t\t\t%u\n",
1143 le32_to_cpu(ofdm
->false_alarm_cnt
),
1144 accum_ofdm
->false_alarm_cnt
);
1145 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1146 "fina_sync_err_cnt:\t%u\t\t\t%u\n",
1147 le32_to_cpu(ofdm
->fina_sync_err_cnt
),
1148 accum_ofdm
->fina_sync_err_cnt
);
1149 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1150 "sfd_timeout:\t\t%u\t\t\t%u\n",
1151 le32_to_cpu(ofdm
->sfd_timeout
),
1152 accum_ofdm
->sfd_timeout
);
1153 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1154 "fina_timeout:\t\t%u\t\t\t%u\n",
1155 le32_to_cpu(ofdm
->fina_timeout
),
1156 accum_ofdm
->fina_timeout
);
1157 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1158 "unresponded_rts:\t%u\t\t\t%u\n",
1159 le32_to_cpu(ofdm
->unresponded_rts
),
1160 accum_ofdm
->unresponded_rts
);
1161 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1162 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n",
1163 le32_to_cpu(ofdm
->rxe_frame_limit_overrun
),
1164 accum_ofdm
->rxe_frame_limit_overrun
);
1165 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1166 "sent_ack_cnt:\t\t%u\t\t\t%u\n",
1167 le32_to_cpu(ofdm
->sent_ack_cnt
),
1168 accum_ofdm
->sent_ack_cnt
);
1169 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1170 "sent_cts_cnt:\t\t%u\t\t\t%u\n",
1171 le32_to_cpu(ofdm
->sent_cts_cnt
),
1172 accum_ofdm
->sent_cts_cnt
);
1173 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1174 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n",
1175 le32_to_cpu(ofdm
->sent_ba_rsp_cnt
),
1176 accum_ofdm
->sent_ba_rsp_cnt
);
1177 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1178 "dsp_self_kill:\t\t%u\t\t\t%u\n",
1179 le32_to_cpu(ofdm
->dsp_self_kill
),
1180 accum_ofdm
->dsp_self_kill
);
1181 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1182 "mh_format_err:\t\t%u\t\t\t%u\n",
1183 le32_to_cpu(ofdm
->mh_format_err
),
1184 accum_ofdm
->mh_format_err
);
1185 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1186 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n",
1187 le32_to_cpu(ofdm
->re_acq_main_rssi_sum
),
1188 accum_ofdm
->re_acq_main_rssi_sum
);
1190 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Statistics_Rx - CCK:\n");
1191 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1192 "\t\t\tcurrent\t\t\taccumulative\n");
1193 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "ina_cnt:\t\t%u\t\t\t%u\n",
1194 le32_to_cpu(cck
->ina_cnt
), accum_cck
->ina_cnt
);
1195 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "fina_cnt:\t\t%u\t\t\t%u\n",
1196 le32_to_cpu(cck
->fina_cnt
), accum_cck
->fina_cnt
);
1197 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "plcp_err:\t\t%u\t\t\t%u\n",
1198 le32_to_cpu(cck
->plcp_err
), accum_cck
->plcp_err
);
1199 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "crc32_err:\t\t%u\t\t\t%u\n",
1200 le32_to_cpu(cck
->crc32_err
), accum_cck
->crc32_err
);
1201 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1202 "overrun_err:\t\t%u\t\t\t%u\n",
1203 le32_to_cpu(cck
->overrun_err
),
1204 accum_cck
->overrun_err
);
1205 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1206 "early_overrun_err:\t%u\t\t\t%u\n",
1207 le32_to_cpu(cck
->early_overrun_err
),
1208 accum_cck
->early_overrun_err
);
1209 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "crc32_good:\t\t%u\t\t\t%u\n",
1210 le32_to_cpu(cck
->crc32_good
), accum_cck
->crc32_good
);
1211 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1212 "false_alarm_cnt:\t%u\t\t\t%u\n",
1213 le32_to_cpu(cck
->false_alarm_cnt
),
1214 accum_cck
->false_alarm_cnt
);
1215 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1216 "fina_sync_err_cnt:\t%u\t\t\t%u\n",
1217 le32_to_cpu(cck
->fina_sync_err_cnt
),
1218 accum_cck
->fina_sync_err_cnt
);
1219 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1220 "sfd_timeout:\t\t%u\t\t\t%u\n",
1221 le32_to_cpu(cck
->sfd_timeout
),
1222 accum_cck
->sfd_timeout
);
1223 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1224 "fina_timeout:\t\t%u\t\t\t%u\n",
1225 le32_to_cpu(cck
->fina_timeout
),
1226 accum_cck
->fina_timeout
);
1227 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1228 "unresponded_rts:\t%u\t\t\t%u\n",
1229 le32_to_cpu(cck
->unresponded_rts
),
1230 accum_cck
->unresponded_rts
);
1231 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1232 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n",
1233 le32_to_cpu(cck
->rxe_frame_limit_overrun
),
1234 accum_cck
->rxe_frame_limit_overrun
);
1235 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1236 "sent_ack_cnt:\t\t%u\t\t\t%u\n",
1237 le32_to_cpu(cck
->sent_ack_cnt
),
1238 accum_cck
->sent_ack_cnt
);
1239 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1240 "sent_cts_cnt:\t\t%u\t\t\t%u\n",
1241 le32_to_cpu(cck
->sent_cts_cnt
),
1242 accum_cck
->sent_cts_cnt
);
1243 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1244 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n",
1245 le32_to_cpu(cck
->sent_ba_rsp_cnt
),
1246 accum_cck
->sent_ba_rsp_cnt
);
1247 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1248 "dsp_self_kill:\t\t%u\t\t\t%u\n",
1249 le32_to_cpu(cck
->dsp_self_kill
),
1250 accum_cck
->dsp_self_kill
);
1251 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1252 "mh_format_err:\t\t%u\t\t\t%u\n",
1253 le32_to_cpu(cck
->mh_format_err
),
1254 accum_cck
->mh_format_err
);
1255 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1256 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n",
1257 le32_to_cpu(cck
->re_acq_main_rssi_sum
),
1258 accum_cck
->re_acq_main_rssi_sum
);
1260 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Statistics_Rx - GENERAL:\n");
1261 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1262 "\t\t\tcurrent\t\t\taccumulative\n");
1263 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "bogus_cts:\t\t%u\t\t\t%u\n",
1264 le32_to_cpu(general
->bogus_cts
),
1265 accum_general
->bogus_cts
);
1266 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "bogus_ack:\t\t%u\t\t\t%u\n",
1267 le32_to_cpu(general
->bogus_ack
),
1268 accum_general
->bogus_ack
);
1269 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1270 "non_bssid_frames:\t%u\t\t\t%u\n",
1271 le32_to_cpu(general
->non_bssid_frames
),
1272 accum_general
->non_bssid_frames
);
1273 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1274 "filtered_frames:\t%u\t\t\t%u\n",
1275 le32_to_cpu(general
->filtered_frames
),
1276 accum_general
->filtered_frames
);
1277 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1278 "non_channel_beacons:\t%u\t\t\t%u\n",
1279 le32_to_cpu(general
->non_channel_beacons
),
1280 accum_general
->non_channel_beacons
);
1281 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1282 "channel_beacons:\t%u\t\t\t%u\n",
1283 le32_to_cpu(general
->channel_beacons
),
1284 accum_general
->channel_beacons
);
1285 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1286 "num_missed_bcon:\t%u\t\t\t%u\n",
1287 le32_to_cpu(general
->num_missed_bcon
),
1288 accum_general
->num_missed_bcon
);
1289 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1290 "adc_rx_saturation_time:\t%u\t\t\t%u\n",
1291 le32_to_cpu(general
->adc_rx_saturation_time
),
1292 accum_general
->adc_rx_saturation_time
);
1293 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1294 "ina_detect_search_tm:\t%u\t\t\t%u\n",
1295 le32_to_cpu(general
->ina_detection_search_time
),
1296 accum_general
->ina_detection_search_time
);
1297 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1298 "beacon_silence_rssi_a:\t%u\t\t\t%u\n",
1299 le32_to_cpu(general
->beacon_silence_rssi_a
),
1300 accum_general
->beacon_silence_rssi_a
);
1301 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1302 "beacon_silence_rssi_b:\t%u\t\t\t%u\n",
1303 le32_to_cpu(general
->beacon_silence_rssi_b
),
1304 accum_general
->beacon_silence_rssi_b
);
1305 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1306 "beacon_silence_rssi_c:\t%u\t\t\t%u\n",
1307 le32_to_cpu(general
->beacon_silence_rssi_c
),
1308 accum_general
->beacon_silence_rssi_c
);
1309 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1310 "interference_data_flag:\t%u\t\t\t%u\n",
1311 le32_to_cpu(general
->interference_data_flag
),
1312 accum_general
->interference_data_flag
);
1313 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1314 "channel_load:\t\t%u\t\t\t%u\n",
1315 le32_to_cpu(general
->channel_load
),
1316 accum_general
->channel_load
);
1317 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1318 "dsp_false_alarms:\t%u\t\t\t%u\n",
1319 le32_to_cpu(general
->dsp_false_alarms
),
1320 accum_general
->dsp_false_alarms
);
1321 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1322 "beacon_rssi_a:\t\t%u\t\t\t%u\n",
1323 le32_to_cpu(general
->beacon_rssi_a
),
1324 accum_general
->beacon_rssi_a
);
1325 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1326 "beacon_rssi_b:\t\t%u\t\t\t%u\n",
1327 le32_to_cpu(general
->beacon_rssi_b
),
1328 accum_general
->beacon_rssi_b
);
1329 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1330 "beacon_rssi_c:\t\t%u\t\t\t%u\n",
1331 le32_to_cpu(general
->beacon_rssi_c
),
1332 accum_general
->beacon_rssi_c
);
1333 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1334 "beacon_energy_a:\t%u\t\t\t%u\n",
1335 le32_to_cpu(general
->beacon_energy_a
),
1336 accum_general
->beacon_energy_a
);
1337 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1338 "beacon_energy_b:\t%u\t\t\t%u\n",
1339 le32_to_cpu(general
->beacon_energy_b
),
1340 accum_general
->beacon_energy_b
);
1341 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1342 "beacon_energy_c:\t%u\t\t\t%u\n",
1343 le32_to_cpu(general
->beacon_energy_c
),
1344 accum_general
->beacon_energy_c
);
1346 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Statistics_Rx - OFDM_HT:\n");
1347 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1348 "\t\t\tcurrent\t\t\taccumulative\n");
1349 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "plcp_err:\t\t%u\t\t\t%u\n",
1350 le32_to_cpu(ht
->plcp_err
), accum_ht
->plcp_err
);
1351 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1352 "overrun_err:\t\t%u\t\t\t%u\n",
1353 le32_to_cpu(ht
->overrun_err
), accum_ht
->overrun_err
);
1354 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1355 "early_overrun_err:\t%u\t\t\t%u\n",
1356 le32_to_cpu(ht
->early_overrun_err
),
1357 accum_ht
->early_overrun_err
);
1358 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "crc32_good:\t\t%u\t\t\t%u\n",
1359 le32_to_cpu(ht
->crc32_good
), accum_ht
->crc32_good
);
1360 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "crc32_err:\t\t%u\t\t\t%u\n",
1361 le32_to_cpu(ht
->crc32_err
), accum_ht
->crc32_err
);
1362 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1363 "mh_format_err:\t\t%u\t\t\t%u\n",
1364 le32_to_cpu(ht
->mh_format_err
),
1365 accum_ht
->mh_format_err
);
1366 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1367 "agg_crc32_good:\t\t%u\t\t\t%u\n",
1368 le32_to_cpu(ht
->agg_crc32_good
),
1369 accum_ht
->agg_crc32_good
);
1370 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1371 "agg_mpdu_cnt:\t\t%u\t\t\t%u\n",
1372 le32_to_cpu(ht
->agg_mpdu_cnt
),
1373 accum_ht
->agg_mpdu_cnt
);
1374 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "agg_cnt:\t\t%u\t\t\t%u\n",
1375 le32_to_cpu(ht
->agg_cnt
), accum_ht
->agg_cnt
);
1377 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1382 static ssize_t
iwl_dbgfs_ucode_tx_stats_read(struct file
*file
,
1383 char __user
*user_buf
,
1384 size_t count
, loff_t
*ppos
)
1386 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1389 int bufsz
= (sizeof(struct statistics_tx
) * 24) + 250;
1391 struct statistics_tx
*tx
, *accum_tx
;
1393 if (!iwl_is_alive(priv
))
1396 /* make request to uCode to retrieve statistics information */
1397 mutex_lock(&priv
->mutex
);
1398 ret
= iwl_send_statistics_request(priv
, 0);
1399 mutex_unlock(&priv
->mutex
);
1403 "Error sending statistics request: %zd\n", ret
);
1406 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1408 IWL_ERR(priv
, "Can not allocate Buffer\n");
1412 /* the statistic information display here is based on
1413 * the last statistics notification from uCode
1414 * might not reflect the current uCode activity
1416 tx
= &priv
->statistics
.tx
;
1417 accum_tx
= &priv
->accum_statistics
.tx
;
1418 pos
+= iwl_dbgfs_statistics_flag(priv
, buf
, bufsz
);
1419 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Statistics_Tx:\n");
1420 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1421 "\t\t\tcurrent\t\t\taccumulative\n");
1422 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "preamble:\t\t\t%u\t\t\t%u\n",
1423 le32_to_cpu(tx
->preamble_cnt
),
1424 accum_tx
->preamble_cnt
);
1425 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1426 "rx_detected_cnt:\t\t%u\t\t\t%u\n",
1427 le32_to_cpu(tx
->rx_detected_cnt
),
1428 accum_tx
->rx_detected_cnt
);
1429 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1430 "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n",
1431 le32_to_cpu(tx
->bt_prio_defer_cnt
),
1432 accum_tx
->bt_prio_defer_cnt
);
1433 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1434 "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n",
1435 le32_to_cpu(tx
->bt_prio_kill_cnt
),
1436 accum_tx
->bt_prio_kill_cnt
);
1437 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1438 "few_bytes_cnt:\t\t\t%u\t\t\t%u\n",
1439 le32_to_cpu(tx
->few_bytes_cnt
),
1440 accum_tx
->few_bytes_cnt
);
1441 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1442 "cts_timeout:\t\t\t%u\t\t\t%u\n",
1443 le32_to_cpu(tx
->cts_timeout
), accum_tx
->cts_timeout
);
1444 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1445 "ack_timeout:\t\t\t%u\t\t\t%u\n",
1446 le32_to_cpu(tx
->ack_timeout
),
1447 accum_tx
->ack_timeout
);
1448 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1449 "expected_ack_cnt:\t\t%u\t\t\t%u\n",
1450 le32_to_cpu(tx
->expected_ack_cnt
),
1451 accum_tx
->expected_ack_cnt
);
1452 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1453 "actual_ack_cnt:\t\t\t%u\t\t\t%u\n",
1454 le32_to_cpu(tx
->actual_ack_cnt
),
1455 accum_tx
->actual_ack_cnt
);
1456 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1457 "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n",
1458 le32_to_cpu(tx
->dump_msdu_cnt
),
1459 accum_tx
->dump_msdu_cnt
);
1460 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1461 "abort_nxt_frame_mismatch:"
1463 le32_to_cpu(tx
->burst_abort_next_frame_mismatch_cnt
),
1464 accum_tx
->burst_abort_next_frame_mismatch_cnt
);
1465 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1466 "abort_missing_nxt_frame:"
1468 le32_to_cpu(tx
->burst_abort_missing_next_frame_cnt
),
1469 accum_tx
->burst_abort_missing_next_frame_cnt
);
1470 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1471 "cts_timeout_collision:\t\t%u\t\t\t%u\n",
1472 le32_to_cpu(tx
->cts_timeout_collision
),
1473 accum_tx
->cts_timeout_collision
);
1474 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1475 "ack_ba_timeout_collision:\t%u\t\t\t%u\n",
1476 le32_to_cpu(tx
->ack_or_ba_timeout_collision
),
1477 accum_tx
->ack_or_ba_timeout_collision
);
1478 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1479 "agg ba_timeout:\t\t\t%u\t\t\t%u\n",
1480 le32_to_cpu(tx
->agg
.ba_timeout
),
1481 accum_tx
->agg
.ba_timeout
);
1482 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1483 "agg ba_resched_frames:\t\t%u\t\t\t%u\n",
1484 le32_to_cpu(tx
->agg
.ba_reschedule_frames
),
1485 accum_tx
->agg
.ba_reschedule_frames
);
1486 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1487 "agg scd_query_agg_frame:\t%u\t\t\t%u\n",
1488 le32_to_cpu(tx
->agg
.scd_query_agg_frame_cnt
),
1489 accum_tx
->agg
.scd_query_agg_frame_cnt
);
1490 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1491 "agg scd_query_no_agg:\t\t%u\t\t\t%u\n",
1492 le32_to_cpu(tx
->agg
.scd_query_no_agg
),
1493 accum_tx
->agg
.scd_query_no_agg
);
1494 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1495 "agg scd_query_agg:\t\t%u\t\t\t%u\n",
1496 le32_to_cpu(tx
->agg
.scd_query_agg
),
1497 accum_tx
->agg
.scd_query_agg
);
1498 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1499 "agg scd_query_mismatch:\t\t%u\t\t\t%u\n",
1500 le32_to_cpu(tx
->agg
.scd_query_mismatch
),
1501 accum_tx
->agg
.scd_query_mismatch
);
1502 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1503 "agg frame_not_ready:\t\t%u\t\t\t%u\n",
1504 le32_to_cpu(tx
->agg
.frame_not_ready
),
1505 accum_tx
->agg
.frame_not_ready
);
1506 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1507 "agg underrun:\t\t\t%u\t\t\t%u\n",
1508 le32_to_cpu(tx
->agg
.underrun
),
1509 accum_tx
->agg
.underrun
);
1510 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1511 "agg bt_prio_kill:\t\t%u\t\t\t%u\n",
1512 le32_to_cpu(tx
->agg
.bt_prio_kill
),
1513 accum_tx
->agg
.bt_prio_kill
);
1514 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1515 "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n",
1516 le32_to_cpu(tx
->agg
.rx_ba_rsp_cnt
),
1517 accum_tx
->agg
.rx_ba_rsp_cnt
);
1519 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1524 static ssize_t
iwl_dbgfs_ucode_general_stats_read(struct file
*file
,
1525 char __user
*user_buf
,
1526 size_t count
, loff_t
*ppos
)
1528 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1531 int bufsz
= sizeof(struct statistics_general
) * 4 + 250;
1533 struct statistics_general
*general
, *accum_general
;
1534 struct statistics_dbg
*dbg
, *accum_dbg
;
1535 struct statistics_div
*div
, *accum_div
;
1537 if (!iwl_is_alive(priv
))
1540 /* make request to uCode to retrieve statistics information */
1541 mutex_lock(&priv
->mutex
);
1542 ret
= iwl_send_statistics_request(priv
, 0);
1543 mutex_unlock(&priv
->mutex
);
1547 "Error sending statistics request: %zd\n", ret
);
1550 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1552 IWL_ERR(priv
, "Can not allocate Buffer\n");
1556 /* the statistic information display here is based on
1557 * the last statistics notification from uCode
1558 * might not reflect the current uCode activity
1560 general
= &priv
->statistics
.general
;
1561 dbg
= &priv
->statistics
.general
.dbg
;
1562 div
= &priv
->statistics
.general
.div
;
1563 accum_general
= &priv
->accum_statistics
.general
;
1564 accum_dbg
= &priv
->accum_statistics
.general
.dbg
;
1565 accum_div
= &priv
->accum_statistics
.general
.div
;
1566 pos
+= iwl_dbgfs_statistics_flag(priv
, buf
, bufsz
);
1567 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Statistics_General:\n");
1568 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1569 "\t\t\tcurrent\t\t\taccumulative\n");
1570 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "temperature:\t\t\t%u\n",
1571 le32_to_cpu(general
->temperature
));
1572 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "temperature_m:\t\t\t%u\n",
1573 le32_to_cpu(general
->temperature_m
));
1574 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1575 "burst_check:\t\t\t%u\t\t\t%u\n",
1576 le32_to_cpu(dbg
->burst_check
),
1577 accum_dbg
->burst_check
);
1578 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1579 "burst_count:\t\t\t%u\t\t\t%u\n",
1580 le32_to_cpu(dbg
->burst_count
),
1581 accum_dbg
->burst_count
);
1582 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1583 "sleep_time:\t\t\t%u\t\t\t%u\n",
1584 le32_to_cpu(general
->sleep_time
),
1585 accum_general
->sleep_time
);
1586 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1587 "slots_out:\t\t\t%u\t\t\t%u\n",
1588 le32_to_cpu(general
->slots_out
),
1589 accum_general
->slots_out
);
1590 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1591 "slots_idle:\t\t\t%u\t\t\t%u\n",
1592 le32_to_cpu(general
->slots_idle
),
1593 accum_general
->slots_idle
);
1594 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "ttl_timestamp:\t\t\t%u\n",
1595 le32_to_cpu(general
->ttl_timestamp
));
1596 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "tx_on_a:\t\t\t%u\t\t\t%u\n",
1597 le32_to_cpu(div
->tx_on_a
), accum_div
->tx_on_a
);
1598 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "tx_on_b:\t\t\t%u\t\t\t%u\n",
1599 le32_to_cpu(div
->tx_on_b
), accum_div
->tx_on_b
);
1600 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1601 "exec_time:\t\t\t%u\t\t\t%u\n",
1602 le32_to_cpu(div
->exec_time
), accum_div
->exec_time
);
1603 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1604 "probe_time:\t\t\t%u\t\t\t%u\n",
1605 le32_to_cpu(div
->probe_time
), accum_div
->probe_time
);
1606 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1607 "rx_enable_counter:\t\t%u\t\t\t%u\n",
1608 le32_to_cpu(general
->rx_enable_counter
),
1609 accum_general
->rx_enable_counter
);
1610 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1615 static ssize_t
iwl_dbgfs_sensitivity_read(struct file
*file
,
1616 char __user
*user_buf
,
1617 size_t count
, loff_t
*ppos
) {
1619 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1623 int bufsz
= sizeof(struct iwl_sensitivity_data
) * 4 + 100;
1625 struct iwl_sensitivity_data
*data
;
1627 data
= &priv
->sensitivity_data
;
1628 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1630 IWL_ERR(priv
, "Can not allocate Buffer\n");
1634 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm:\t\t\t %u\n",
1635 data
->auto_corr_ofdm
);
1636 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1637 "auto_corr_ofdm_mrc:\t\t %u\n",
1638 data
->auto_corr_ofdm_mrc
);
1639 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_ofdm_x1:\t\t %u\n",
1640 data
->auto_corr_ofdm_x1
);
1641 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1642 "auto_corr_ofdm_mrc_x1:\t\t %u\n",
1643 data
->auto_corr_ofdm_mrc_x1
);
1644 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck:\t\t\t %u\n",
1645 data
->auto_corr_cck
);
1646 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "auto_corr_cck_mrc:\t\t %u\n",
1647 data
->auto_corr_cck_mrc
);
1648 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1649 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
1650 data
->last_bad_plcp_cnt_ofdm
);
1651 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_ofdm:\t\t %u\n",
1652 data
->last_fa_cnt_ofdm
);
1653 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1654 "last_bad_plcp_cnt_cck:\t\t %u\n",
1655 data
->last_bad_plcp_cnt_cck
);
1656 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "last_fa_cnt_cck:\t\t %u\n",
1657 data
->last_fa_cnt_cck
);
1658 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_curr_state:\t\t\t %u\n",
1659 data
->nrg_curr_state
);
1660 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_prev_state:\t\t\t %u\n",
1661 data
->nrg_prev_state
);
1662 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_value:\t\t\t");
1663 for (cnt
= 0; cnt
< 10; cnt
++) {
1664 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1665 data
->nrg_value
[cnt
]);
1667 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1668 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_rssi:\t\t");
1669 for (cnt
= 0; cnt
< NRG_NUM_PREV_STAT_L
; cnt
++) {
1670 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1671 data
->nrg_silence_rssi
[cnt
]);
1673 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1674 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_ref:\t\t %u\n",
1675 data
->nrg_silence_ref
);
1676 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_energy_idx:\t\t\t %u\n",
1677 data
->nrg_energy_idx
);
1678 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_silence_idx:\t\t %u\n",
1679 data
->nrg_silence_idx
);
1680 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_cck:\t\t\t %u\n",
1682 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1683 "nrg_auto_corr_silence_diff:\t %u\n",
1684 data
->nrg_auto_corr_silence_diff
);
1685 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "num_in_cck_no_fa:\t\t %u\n",
1686 data
->num_in_cck_no_fa
);
1687 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "nrg_th_ofdm:\t\t\t %u\n",
1690 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1696 static ssize_t
iwl_dbgfs_chain_noise_read(struct file
*file
,
1697 char __user
*user_buf
,
1698 size_t count
, loff_t
*ppos
) {
1700 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1704 int bufsz
= sizeof(struct iwl_chain_noise_data
) * 4 + 100;
1706 struct iwl_chain_noise_data
*data
;
1708 data
= &priv
->chain_noise_data
;
1709 buf
= kzalloc(bufsz
, GFP_KERNEL
);
1711 IWL_ERR(priv
, "Can not allocate Buffer\n");
1715 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "active_chains:\t\t\t %u\n",
1716 data
->active_chains
);
1717 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_a:\t\t\t %u\n",
1718 data
->chain_noise_a
);
1719 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_b:\t\t\t %u\n",
1720 data
->chain_noise_b
);
1721 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_noise_c:\t\t\t %u\n",
1722 data
->chain_noise_c
);
1723 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_a:\t\t\t %u\n",
1724 data
->chain_signal_a
);
1725 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_b:\t\t\t %u\n",
1726 data
->chain_signal_b
);
1727 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "chain_signal_c:\t\t\t %u\n",
1728 data
->chain_signal_c
);
1729 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "beacon_count:\t\t\t %u\n",
1730 data
->beacon_count
);
1732 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "disconn_array:\t\t\t");
1733 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1734 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1735 data
->disconn_array
[cnt
]);
1737 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1738 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "delta_gain_code:\t\t");
1739 for (cnt
= 0; cnt
< NUM_RX_CHAINS
; cnt
++) {
1740 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, " %u",
1741 data
->delta_gain_code
[cnt
]);
1743 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "\n");
1744 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "radio_write:\t\t\t %u\n",
1746 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "state:\t\t\t\t %u\n",
1749 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1754 static ssize_t
iwl_dbgfs_tx_power_read(struct file
*file
,
1755 char __user
*user_buf
,
1756 size_t count
, loff_t
*ppos
) {
1758 struct iwl_priv
*priv
= (struct iwl_priv
*)file
->private_data
;
1762 const size_t bufsz
= sizeof(buf
);
1763 struct statistics_tx
*tx
;
1765 if (!iwl_is_alive(priv
))
1766 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "N/A\n");
1768 /* make request to uCode to retrieve statistics information */
1769 mutex_lock(&priv
->mutex
);
1770 ret
= iwl_send_statistics_request(priv
, 0);
1771 mutex_unlock(&priv
->mutex
);
1774 IWL_ERR(priv
, "Error sending statistics request: %zd\n",
1778 tx
= &priv
->statistics
.tx
;
1779 if (tx
->tx_power
.ant_a
||
1780 tx
->tx_power
.ant_b
||
1781 tx
->tx_power
.ant_c
) {
1782 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1783 "tx power: (1/2 dB step)\n");
1784 if ((priv
->cfg
->valid_tx_ant
& ANT_A
) &&
1786 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1787 "\tantenna A: 0x%X\n",
1788 tx
->tx_power
.ant_a
);
1789 if ((priv
->cfg
->valid_tx_ant
& ANT_B
) &&
1791 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1792 "\tantenna B: 0x%X\n",
1793 tx
->tx_power
.ant_b
);
1794 if ((priv
->cfg
->valid_tx_ant
& ANT_C
) &&
1796 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
,
1797 "\tantenna C: 0x%X\n",
1798 tx
->tx_power
.ant_c
);
1800 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "N/A\n");
1802 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, pos
);
1805 DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics
);
1806 DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics
);
1807 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log
);
1808 DEBUGFS_READ_FILE_OPS(rx_queue
);
1809 DEBUGFS_READ_FILE_OPS(tx_queue
);
1810 DEBUGFS_READ_FILE_OPS(ucode_rx_stats
);
1811 DEBUGFS_READ_FILE_OPS(ucode_tx_stats
);
1812 DEBUGFS_READ_FILE_OPS(ucode_general_stats
);
1813 DEBUGFS_READ_FILE_OPS(sensitivity
);
1814 DEBUGFS_READ_FILE_OPS(chain_noise
);
1815 DEBUGFS_READ_FILE_OPS(tx_power
);
1818 * Create the debugfs files and directories
1821 int iwl_dbgfs_register(struct iwl_priv
*priv
, const char *name
)
1823 struct iwl_debugfs
*dbgfs
;
1824 struct dentry
*phyd
= priv
->hw
->wiphy
->debugfsdir
;
1827 dbgfs
= kzalloc(sizeof(struct iwl_debugfs
), GFP_KERNEL
);
1833 priv
->dbgfs
= dbgfs
;
1835 dbgfs
->dir_drv
= debugfs_create_dir(name
, phyd
);
1836 if (!dbgfs
->dir_drv
|| IS_ERR(dbgfs
->dir_drv
)) {
1841 DEBUGFS_ADD_DIR(data
, dbgfs
->dir_drv
);
1842 DEBUGFS_ADD_DIR(rf
, dbgfs
->dir_drv
);
1843 DEBUGFS_ADD_DIR(debug
, dbgfs
->dir_drv
);
1844 DEBUGFS_ADD_FILE(nvm
, data
);
1845 DEBUGFS_ADD_FILE(sram
, data
);
1846 DEBUGFS_ADD_FILE(log_event
, data
);
1847 DEBUGFS_ADD_FILE(stations
, data
);
1848 DEBUGFS_ADD_FILE(channels
, data
);
1849 DEBUGFS_ADD_FILE(status
, data
);
1850 DEBUGFS_ADD_FILE(interrupt
, data
);
1851 DEBUGFS_ADD_FILE(qos
, data
);
1852 DEBUGFS_ADD_FILE(led
, data
);
1853 DEBUGFS_ADD_FILE(sleep_level_override
, data
);
1854 DEBUGFS_ADD_FILE(current_sleep_command
, data
);
1855 DEBUGFS_ADD_FILE(thermal_throttling
, data
);
1856 DEBUGFS_ADD_FILE(disable_ht40
, data
);
1857 DEBUGFS_ADD_FILE(rx_statistics
, debug
);
1858 DEBUGFS_ADD_FILE(tx_statistics
, debug
);
1859 DEBUGFS_ADD_FILE(traffic_log
, debug
);
1860 DEBUGFS_ADD_FILE(rx_queue
, debug
);
1861 DEBUGFS_ADD_FILE(tx_queue
, debug
);
1862 DEBUGFS_ADD_FILE(tx_power
, debug
);
1863 if ((priv
->hw_rev
& CSR_HW_REV_TYPE_MSK
) != CSR_HW_REV_TYPE_3945
) {
1864 DEBUGFS_ADD_FILE(ucode_rx_stats
, debug
);
1865 DEBUGFS_ADD_FILE(ucode_tx_stats
, debug
);
1866 DEBUGFS_ADD_FILE(ucode_general_stats
, debug
);
1867 DEBUGFS_ADD_FILE(sensitivity
, debug
);
1868 DEBUGFS_ADD_FILE(chain_noise
, debug
);
1870 DEBUGFS_ADD_BOOL(disable_sensitivity
, rf
, &priv
->disable_sens_cal
);
1871 DEBUGFS_ADD_BOOL(disable_chain_noise
, rf
,
1872 &priv
->disable_chain_noise_cal
);
1873 if (((priv
->hw_rev
& CSR_HW_REV_TYPE_MSK
) == CSR_HW_REV_TYPE_4965
) ||
1874 ((priv
->hw_rev
& CSR_HW_REV_TYPE_MSK
) == CSR_HW_REV_TYPE_3945
))
1875 DEBUGFS_ADD_BOOL(disable_tx_power
, rf
,
1876 &priv
->disable_tx_power_cal
);
1880 IWL_ERR(priv
, "Can't open the debugfs directory\n");
1881 iwl_dbgfs_unregister(priv
);
1884 EXPORT_SYMBOL(iwl_dbgfs_register
);
1887 * Remove the debugfs files and directories
1890 void iwl_dbgfs_unregister(struct iwl_priv
*priv
)
1895 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_sleep_level_override
);
1896 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_current_sleep_command
);
1897 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_nvm
);
1898 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_sram
);
1899 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_log_event
);
1900 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_stations
);
1901 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_channels
);
1902 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_status
);
1903 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_interrupt
);
1904 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_qos
);
1905 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_led
);
1906 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_thermal_throttling
);
1907 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_data_files
.file_disable_ht40
);
1908 DEBUGFS_REMOVE(priv
->dbgfs
->dir_data
);
1909 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_debug_files
.file_rx_statistics
);
1910 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_debug_files
.file_tx_statistics
);
1911 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_debug_files
.file_traffic_log
);
1912 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_debug_files
.file_rx_queue
);
1913 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_debug_files
.file_tx_queue
);
1914 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_debug_files
.file_tx_power
);
1915 if ((priv
->hw_rev
& CSR_HW_REV_TYPE_MSK
) != CSR_HW_REV_TYPE_3945
) {
1916 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_debug_files
.
1917 file_ucode_rx_stats
);
1918 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_debug_files
.
1919 file_ucode_tx_stats
);
1920 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_debug_files
.
1921 file_ucode_general_stats
);
1922 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_debug_files
.
1924 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_debug_files
.
1927 DEBUGFS_REMOVE(priv
->dbgfs
->dir_debug
);
1928 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_rf_files
.file_disable_sensitivity
);
1929 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_rf_files
.file_disable_chain_noise
);
1930 if (((priv
->hw_rev
& CSR_HW_REV_TYPE_MSK
) == CSR_HW_REV_TYPE_4965
) ||
1931 ((priv
->hw_rev
& CSR_HW_REV_TYPE_MSK
) == CSR_HW_REV_TYPE_3945
))
1932 DEBUGFS_REMOVE(priv
->dbgfs
->dbgfs_rf_files
.file_disable_tx_power
);
1933 DEBUGFS_REMOVE(priv
->dbgfs
->dir_rf
);
1934 DEBUGFS_REMOVE(priv
->dbgfs
->dir_drv
);
1938 EXPORT_SYMBOL(iwl_dbgfs_unregister
);