1 /******************************************************************************
5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
28 #include <linux/ieee80211.h>
29 #include <net/mac80211.h>
33 #include "iwl-debug.h"
37 /* create and remove of files */
38 #define DEBUGFS_ADD_FILE(name, parent, mode) do { \
39 if (!debugfs_create_file(#name, mode, parent, il, \
40 &il_dbgfs_##name##_ops)) \
44 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
45 struct dentry *__tmp; \
46 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
48 if (IS_ERR(__tmp) || !__tmp) \
52 #define DEBUGFS_ADD_X32(name, parent, ptr) do { \
53 struct dentry *__tmp; \
54 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \
56 if (IS_ERR(__tmp) || !__tmp) \
61 #define DEBUGFS_READ_FUNC(name) \
62 static ssize_t il_dbgfs_##name##_read(struct file *file, \
63 char __user *user_buf, \
64 size_t count, loff_t *ppos);
66 #define DEBUGFS_WRITE_FUNC(name) \
67 static ssize_t il_dbgfs_##name##_write(struct file *file, \
68 const char __user *user_buf, \
69 size_t count, loff_t *ppos);
73 il_dbgfs_open_file_generic(struct inode *inode, struct file *file)
75 file->private_data = inode->i_private;
79 #define DEBUGFS_READ_FILE_OPS(name) \
80 DEBUGFS_READ_FUNC(name); \
81 static const struct file_operations il_dbgfs_##name##_ops = { \
82 .read = il_dbgfs_##name##_read, \
83 .open = il_dbgfs_open_file_generic, \
84 .llseek = generic_file_llseek, \
87 #define DEBUGFS_WRITE_FILE_OPS(name) \
88 DEBUGFS_WRITE_FUNC(name); \
89 static const struct file_operations il_dbgfs_##name##_ops = { \
90 .write = il_dbgfs_##name##_write, \
91 .open = il_dbgfs_open_file_generic, \
92 .llseek = generic_file_llseek, \
95 #define DEBUGFS_READ_WRITE_FILE_OPS(name) \
96 DEBUGFS_READ_FUNC(name); \
97 DEBUGFS_WRITE_FUNC(name); \
98 static const struct file_operations il_dbgfs_##name##_ops = { \
99 .write = il_dbgfs_##name##_write, \
100 .read = il_dbgfs_##name##_read, \
101 .open = il_dbgfs_open_file_generic, \
102 .llseek = generic_file_llseek, \
105 static ssize_t il_dbgfs_tx_stats_read(struct file *file,
106 char __user *user_buf,
107 size_t count, loff_t *ppos) {
109 struct il_priv *il = file->private_data;
115 const size_t bufsz = 100 +
116 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
117 buf = kzalloc(bufsz, GFP_KERNEL);
120 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
121 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
122 pos += scnprintf(buf + pos, bufsz - pos,
124 il_get_mgmt_string(cnt),
125 il->tx_stats.mgmt[cnt]);
127 pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
128 for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
129 pos += scnprintf(buf + pos, bufsz - pos,
131 il_get_ctrl_string(cnt),
132 il->tx_stats.ctrl[cnt]);
134 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
135 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
136 il->tx_stats.data_cnt);
137 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
138 il->tx_stats.data_bytes);
139 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
145 il_dbgfs_clear_traffic_stats_write(struct file *file,
146 const char __user *user_buf,
147 size_t count, loff_t *ppos)
149 struct il_priv *il = file->private_data;
154 memset(buf, 0, sizeof(buf));
155 buf_size = min(count, sizeof(buf) - 1);
156 if (copy_from_user(buf, user_buf, buf_size))
158 if (sscanf(buf, "%x", &clear_flag) != 1)
160 il_clear_traffic_stats(il);
165 static ssize_t il_dbgfs_rx_stats_read(struct file *file,
166 char __user *user_buf,
167 size_t count, loff_t *ppos) {
169 struct il_priv *il = file->private_data;
174 const size_t bufsz = 100 +
175 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
176 buf = kzalloc(bufsz, GFP_KERNEL);
180 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
181 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
182 pos += scnprintf(buf + pos, bufsz - pos,
184 il_get_mgmt_string(cnt),
185 il->rx_stats.mgmt[cnt]);
187 pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
188 for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
189 pos += scnprintf(buf + pos, bufsz - pos,
191 il_get_ctrl_string(cnt),
192 il->rx_stats.ctrl[cnt]);
194 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
195 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
196 il->rx_stats.data_cnt);
197 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
198 il->rx_stats.data_bytes);
200 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
205 #define BYTE1_MASK 0x000000ff;
206 #define BYTE2_MASK 0x0000ffff;
207 #define BYTE3_MASK 0x00ffffff;
208 static ssize_t il_dbgfs_sram_read(struct file *file,
209 char __user *user_buf,
210 size_t count, loff_t *ppos)
217 struct il_priv *il = file->private_data;
220 /* default is to dump the entire data segment */
221 if (!il->dbgfs_sram_offset && !il->dbgfs_sram_len) {
222 il->dbgfs_sram_offset = 0x800000;
223 if (il->ucode_type == UCODE_INIT)
224 il->dbgfs_sram_len = il->ucode_init_data.len;
226 il->dbgfs_sram_len = il->ucode_data.len;
228 bufsz = 30 + il->dbgfs_sram_len * sizeof(char) * 10;
229 buf = kmalloc(bufsz, GFP_KERNEL);
232 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
234 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
235 il->dbgfs_sram_offset);
236 for (i = il->dbgfs_sram_len; i > 0; i -= 4) {
237 val = il_read_targ_mem(il, il->dbgfs_sram_offset + \
238 il->dbgfs_sram_len - i);
253 pos += scnprintf(buf + pos, bufsz - pos, "\n");
254 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
256 pos += scnprintf(buf + pos, bufsz - pos, "\n");
258 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
263 static ssize_t il_dbgfs_sram_write(struct file *file,
264 const char __user *user_buf,
265 size_t count, loff_t *ppos)
267 struct il_priv *il = file->private_data;
272 memset(buf, 0, sizeof(buf));
273 buf_size = min(count, sizeof(buf) - 1);
274 if (copy_from_user(buf, user_buf, buf_size))
277 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
278 il->dbgfs_sram_offset = offset;
279 il->dbgfs_sram_len = len;
281 il->dbgfs_sram_offset = 0;
282 il->dbgfs_sram_len = 0;
289 il_dbgfs_stations_read(struct file *file, char __user *user_buf,
290 size_t count, loff_t *ppos)
292 struct il_priv *il = file->private_data;
293 struct il_station_entry *station;
294 int max_sta = il->hw_params.max_stations;
298 /* Add 30 for initial string */
299 const size_t bufsz = 30 + sizeof(char) * 500 * (il->num_stations);
301 buf = kmalloc(bufsz, GFP_KERNEL);
305 pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
308 for (i = 0; i < max_sta; i++) {
309 station = &il->stations[i];
312 pos += scnprintf(buf + pos, bufsz - pos,
313 "station %d - addr: %pM, flags: %#x\n",
314 i, station->sta.sta.addr,
315 station->sta.station_flags_msk);
316 pos += scnprintf(buf + pos, bufsz - pos,
317 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
318 pos += scnprintf(buf + pos, bufsz - pos,
319 "start_idx\tbitmap\t\t\trate_n_flags\n");
321 for (j = 0; j < MAX_TID_COUNT; j++) {
322 pos += scnprintf(buf + pos, bufsz - pos,
323 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
324 j, station->tid[j].seq_number,
325 station->tid[j].agg.txq_id,
326 station->tid[j].agg.frame_count,
327 station->tid[j].tfds_in_queue,
328 station->tid[j].agg.start_idx,
329 station->tid[j].agg.bitmap,
330 station->tid[j].agg.rate_n_flags);
332 if (station->tid[j].agg.wait_for_ba)
333 pos += scnprintf(buf + pos, bufsz - pos,
335 pos += scnprintf(buf + pos, bufsz - pos, "\n");
338 pos += scnprintf(buf + pos, bufsz - pos, "\n");
341 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
346 static ssize_t il_dbgfs_nvm_read(struct file *file,
347 char __user *user_buf,
352 struct il_priv *il = file->private_data;
353 int pos = 0, ofs = 0, buf_size = 0;
357 size_t eeprom_len = il->cfg->base_params->eeprom_size;
358 buf_size = 4 * eeprom_len + 256;
360 if (eeprom_len % 16) {
361 IL_ERR("NVM size is not multiple of 16.\n");
367 IL_ERR("Invalid EEPROM memory\n");
371 /* 4 characters for byte 0xYY */
372 buf = kzalloc(buf_size, GFP_KERNEL);
374 IL_ERR("Can not allocate Buffer\n");
377 eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION);
378 pos += scnprintf(buf + pos, buf_size - pos, "EEPROM "
379 "version: 0x%x\n", eeprom_ver);
380 for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
381 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
382 hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
384 pos += strlen(buf + pos);
385 if (buf_size - pos > 0)
389 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
395 il_dbgfs_channels_read(struct file *file, char __user *user_buf,
396 size_t count, loff_t *ppos)
398 struct il_priv *il = file->private_data;
399 struct ieee80211_channel *channels = NULL;
400 const struct ieee80211_supported_band *supp_band = NULL;
401 int pos = 0, i, bufsz = PAGE_SIZE;
405 if (!test_bit(S_GEO_CONFIGURED, &il->status))
408 buf = kzalloc(bufsz, GFP_KERNEL);
410 IL_ERR("Can not allocate Buffer\n");
414 supp_band = il_get_hw_mode(il, IEEE80211_BAND_2GHZ);
416 channels = supp_band->channels;
418 pos += scnprintf(buf + pos, bufsz - pos,
419 "Displaying %d channels in 2.4GHz band 802.11bg):\n",
420 supp_band->n_channels);
422 for (i = 0; i < supp_band->n_channels; i++)
423 pos += scnprintf(buf + pos, bufsz - pos,
424 "%d: %ddBm: BSS%s%s, %s.\n",
425 channels[i].hw_value,
426 channels[i].max_power,
427 channels[i].flags & IEEE80211_CHAN_RADAR ?
428 " (IEEE 802.11h required)" : "",
429 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
430 || (channels[i].flags &
431 IEEE80211_CHAN_RADAR)) ? "" :
434 IEEE80211_CHAN_PASSIVE_SCAN ?
435 "passive only" : "active/passive");
437 supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ);
439 channels = supp_band->channels;
441 pos += scnprintf(buf + pos, bufsz - pos,
442 "Displaying %d channels in 5.2GHz band (802.11a)\n",
443 supp_band->n_channels);
445 for (i = 0; i < supp_band->n_channels; i++)
446 pos += scnprintf(buf + pos, bufsz - pos,
447 "%d: %ddBm: BSS%s%s, %s.\n",
448 channels[i].hw_value,
449 channels[i].max_power,
450 channels[i].flags & IEEE80211_CHAN_RADAR ?
451 " (IEEE 802.11h required)" : "",
452 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
453 || (channels[i].flags &
454 IEEE80211_CHAN_RADAR)) ? "" :
457 IEEE80211_CHAN_PASSIVE_SCAN ?
458 "passive only" : "active/passive");
460 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
465 static ssize_t il_dbgfs_status_read(struct file *file,
466 char __user *user_buf,
467 size_t count, loff_t *ppos) {
469 struct il_priv *il = file->private_data;
472 const size_t bufsz = sizeof(buf);
474 pos += scnprintf(buf + pos, bufsz - pos, "S_HCMD_ACTIVE:\t %d\n",
475 test_bit(S_HCMD_ACTIVE, &il->status));
476 pos += scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n",
477 test_bit(S_INT_ENABLED, &il->status));
478 pos += scnprintf(buf + pos, bufsz - pos, "S_RF_KILL_HW:\t %d\n",
479 test_bit(S_RF_KILL_HW, &il->status));
480 pos += scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n",
481 test_bit(S_CT_KILL, &il->status));
482 pos += scnprintf(buf + pos, bufsz - pos, "S_INIT:\t\t %d\n",
483 test_bit(S_INIT, &il->status));
484 pos += scnprintf(buf + pos, bufsz - pos, "S_ALIVE:\t\t %d\n",
485 test_bit(S_ALIVE, &il->status));
486 pos += scnprintf(buf + pos, bufsz - pos, "S_READY:\t\t %d\n",
487 test_bit(S_READY, &il->status));
488 pos += scnprintf(buf + pos, bufsz - pos, "S_TEMPERATURE:\t %d\n",
489 test_bit(S_TEMPERATURE, &il->status));
490 pos += scnprintf(buf + pos, bufsz - pos, "S_GEO_CONFIGURED:\t %d\n",
491 test_bit(S_GEO_CONFIGURED, &il->status));
492 pos += scnprintf(buf + pos, bufsz - pos, "S_EXIT_PENDING:\t %d\n",
493 test_bit(S_EXIT_PENDING, &il->status));
494 pos += scnprintf(buf + pos, bufsz - pos, "S_STATS:\t %d\n",
495 test_bit(S_STATS, &il->status));
496 pos += scnprintf(buf + pos, bufsz - pos, "S_SCANNING:\t %d\n",
497 test_bit(S_SCANNING, &il->status));
498 pos += scnprintf(buf + pos, bufsz - pos, "S_SCAN_ABORTING:\t %d\n",
499 test_bit(S_SCAN_ABORTING, &il->status));
500 pos += scnprintf(buf + pos, bufsz - pos, "S_SCAN_HW:\t\t %d\n",
501 test_bit(S_SCAN_HW, &il->status));
502 pos += scnprintf(buf + pos, bufsz - pos, "S_POWER_PMI:\t %d\n",
503 test_bit(S_POWER_PMI, &il->status));
504 pos += scnprintf(buf + pos, bufsz - pos, "S_FW_ERROR:\t %d\n",
505 test_bit(S_FW_ERROR, &il->status));
506 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
509 static ssize_t il_dbgfs_interrupt_read(struct file *file,
510 char __user *user_buf,
511 size_t count, loff_t *ppos) {
513 struct il_priv *il = file->private_data;
517 int bufsz = 24 * 64; /* 24 items * 64 char per item */
520 buf = kzalloc(bufsz, GFP_KERNEL);
522 IL_ERR("Can not allocate Buffer\n");
526 pos += scnprintf(buf + pos, bufsz - pos,
527 "Interrupt Statistics Report:\n");
529 pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
531 pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
533 if (il->isr_stats.sw || il->isr_stats.hw) {
534 pos += scnprintf(buf + pos, bufsz - pos,
535 "\tLast Restarting Code: 0x%X\n",
536 il->isr_stats.err_code);
538 #ifdef CONFIG_IWLEGACY_DEBUG
539 pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
541 pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
542 il->isr_stats.alive);
544 pos += scnprintf(buf + pos, bufsz - pos,
545 "HW RF KILL switch toggled:\t %u\n",
546 il->isr_stats.rfkill);
548 pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
549 il->isr_stats.ctkill);
551 pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
552 il->isr_stats.wakeup);
554 pos += scnprintf(buf + pos, bufsz - pos,
555 "Rx command responses:\t\t %u\n",
557 for (cnt = 0; cnt < IL_CN_MAX; cnt++) {
558 if (il->isr_stats.handlers[cnt] > 0)
559 pos += scnprintf(buf + pos, bufsz - pos,
560 "\tRx handler[%36s]:\t\t %u\n",
561 il_get_cmd_string(cnt),
562 il->isr_stats.handlers[cnt]);
565 pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
568 pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
569 il->isr_stats.unhandled);
571 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
576 static ssize_t il_dbgfs_interrupt_write(struct file *file,
577 const char __user *user_buf,
578 size_t count, loff_t *ppos)
580 struct il_priv *il = file->private_data;
585 memset(buf, 0, sizeof(buf));
586 buf_size = min(count, sizeof(buf) - 1);
587 if (copy_from_user(buf, user_buf, buf_size))
589 if (sscanf(buf, "%x", &reset_flag) != 1)
592 il_clear_isr_stats(il);
598 il_dbgfs_qos_read(struct file *file, char __user *user_buf,
599 size_t count, loff_t *ppos)
601 struct il_priv *il = file->private_data;
602 struct il_rxon_context *ctx = &il->ctx;
605 const size_t bufsz = sizeof(buf);
607 pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n",
609 for (i = 0; i < AC_NUM; i++) {
610 pos += scnprintf(buf + pos, bufsz - pos,
611 "\tcw_min\tcw_max\taifsn\ttxop\n");
612 pos += scnprintf(buf + pos, bufsz - pos,
613 "AC[%d]\t%u\t%u\t%u\t%u\n", i,
614 ctx->qos_data.def_qos_parm.ac[i].cw_min,
615 ctx->qos_data.def_qos_parm.ac[i].cw_max,
616 ctx->qos_data.def_qos_parm.ac[i].aifsn,
617 ctx->qos_data.def_qos_parm.ac[i].edca_txop);
620 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
623 static ssize_t il_dbgfs_disable_ht40_write(struct file *file,
624 const char __user *user_buf,
625 size_t count, loff_t *ppos)
627 struct il_priv *il = file->private_data;
632 memset(buf, 0, sizeof(buf));
633 buf_size = min(count, sizeof(buf) - 1);
634 if (copy_from_user(buf, user_buf, buf_size))
636 if (sscanf(buf, "%d", &ht40) != 1)
638 if (!il_is_any_associated(il))
639 il->disable_ht40 = ht40 ? true : false;
641 IL_ERR("Sta associated with AP - "
642 "Change to 40MHz channel support is not allowed\n");
649 static ssize_t il_dbgfs_disable_ht40_read(struct file *file,
650 char __user *user_buf,
651 size_t count, loff_t *ppos)
653 struct il_priv *il = file->private_data;
656 const size_t bufsz = sizeof(buf);
658 pos += scnprintf(buf + pos, bufsz - pos,
659 "11n 40MHz Mode: %s\n",
660 il->disable_ht40 ? "Disabled" : "Enabled");
661 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
664 DEBUGFS_READ_WRITE_FILE_OPS(sram);
665 DEBUGFS_READ_FILE_OPS(nvm);
666 DEBUGFS_READ_FILE_OPS(stations);
667 DEBUGFS_READ_FILE_OPS(channels);
668 DEBUGFS_READ_FILE_OPS(status);
669 DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
670 DEBUGFS_READ_FILE_OPS(qos);
671 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
673 static ssize_t il_dbgfs_traffic_log_read(struct file *file,
674 char __user *user_buf,
675 size_t count, loff_t *ppos)
677 struct il_priv *il = file->private_data;
678 int pos = 0, ofs = 0;
680 struct il_tx_queue *txq;
682 struct il_rx_queue *rxq = &il->rxq;
684 int bufsz = ((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
685 (il->cfg->base_params->num_of_queues * 32 * 8) + 400;
690 IL_ERR("txq not ready\n");
693 buf = kzalloc(bufsz, GFP_KERNEL);
695 IL_ERR("Can not allocate buffer\n");
698 pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
699 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
702 pos += scnprintf(buf + pos, bufsz - pos,
703 "q[%d]: read_ptr: %u, write_ptr: %u\n",
704 cnt, q->read_ptr, q->write_ptr);
706 if (il->tx_traffic && (il_debug_level & IL_DL_TX)) {
707 ptr = il->tx_traffic;
708 pos += scnprintf(buf + pos, bufsz - pos,
709 "Tx Traffic idx: %u\n", il->tx_traffic_idx);
710 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
711 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
712 entry++, ofs += 16) {
713 pos += scnprintf(buf + pos, bufsz - pos,
715 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
716 buf + pos, bufsz - pos, 0);
717 pos += strlen(buf + pos);
724 pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
725 pos += scnprintf(buf + pos, bufsz - pos,
726 "read: %u, write: %u\n",
727 rxq->read, rxq->write);
729 if (il->rx_traffic && (il_debug_level & IL_DL_RX)) {
730 ptr = il->rx_traffic;
731 pos += scnprintf(buf + pos, bufsz - pos,
732 "Rx Traffic idx: %u\n", il->rx_traffic_idx);
733 for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
734 for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
735 entry++, ofs += 16) {
736 pos += scnprintf(buf + pos, bufsz - pos,
738 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
739 buf + pos, bufsz - pos, 0);
740 pos += strlen(buf + pos);
747 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
752 static ssize_t il_dbgfs_traffic_log_write(struct file *file,
753 const char __user *user_buf,
754 size_t count, loff_t *ppos)
756 struct il_priv *il = file->private_data;
761 memset(buf, 0, sizeof(buf));
762 buf_size = min(count, sizeof(buf) - 1);
763 if (copy_from_user(buf, user_buf, buf_size))
765 if (sscanf(buf, "%d", &traffic_log) != 1)
767 if (traffic_log == 0)
768 il_reset_traffic_log(il);
773 static ssize_t il_dbgfs_tx_queue_read(struct file *file,
774 char __user *user_buf,
775 size_t count, loff_t *ppos) {
777 struct il_priv *il = file->private_data;
778 struct il_tx_queue *txq;
784 const size_t bufsz = sizeof(char) * 64 *
785 il->cfg->base_params->num_of_queues;
788 IL_ERR("txq not ready\n");
791 buf = kzalloc(bufsz, GFP_KERNEL);
795 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
798 pos += scnprintf(buf + pos, bufsz - pos,
799 "hwq %.2d: read=%u write=%u stop=%d"
800 " swq_id=%#.2x (ac %d/hwq %d)\n",
801 cnt, q->read_ptr, q->write_ptr,
802 !!test_bit(cnt, il->queue_stopped),
803 txq->swq_id, txq->swq_id & 3,
804 (txq->swq_id >> 2) & 0x1f);
807 /* for the ACs, display the stop count too */
808 pos += scnprintf(buf + pos, bufsz - pos,
810 atomic_read(&il->queue_stop_count[cnt]));
812 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
817 static ssize_t il_dbgfs_rx_queue_read(struct file *file,
818 char __user *user_buf,
819 size_t count, loff_t *ppos) {
821 struct il_priv *il = file->private_data;
822 struct il_rx_queue *rxq = &il->rxq;
825 const size_t bufsz = sizeof(buf);
827 pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
829 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
831 pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
834 pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
835 le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF);
837 pos += scnprintf(buf + pos, bufsz - pos,
838 "closed_rb_num: Not Allocated\n");
840 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
843 static ssize_t il_dbgfs_ucode_rx_stats_read(struct file *file,
844 char __user *user_buf,
845 size_t count, loff_t *ppos)
847 struct il_priv *il = file->private_data;
848 return il->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
849 user_buf, count, ppos);
852 static ssize_t il_dbgfs_ucode_tx_stats_read(struct file *file,
853 char __user *user_buf,
854 size_t count, loff_t *ppos)
856 struct il_priv *il = file->private_data;
857 return il->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
858 user_buf, count, ppos);
861 static ssize_t il_dbgfs_ucode_general_stats_read(struct file *file,
862 char __user *user_buf,
863 size_t count, loff_t *ppos)
865 struct il_priv *il = file->private_data;
866 return il->cfg->ops->lib->debugfs_ops.general_stats_read(file,
867 user_buf, count, ppos);
870 static ssize_t il_dbgfs_sensitivity_read(struct file *file,
871 char __user *user_buf,
872 size_t count, loff_t *ppos) {
874 struct il_priv *il = file->private_data;
878 int bufsz = sizeof(struct il_sensitivity_data) * 4 + 100;
880 struct il_sensitivity_data *data;
882 data = &il->sensitivity_data;
883 buf = kzalloc(bufsz, GFP_KERNEL);
885 IL_ERR("Can not allocate Buffer\n");
889 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
890 data->auto_corr_ofdm);
891 pos += scnprintf(buf + pos, bufsz - pos,
892 "auto_corr_ofdm_mrc:\t\t %u\n",
893 data->auto_corr_ofdm_mrc);
894 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
895 data->auto_corr_ofdm_x1);
896 pos += scnprintf(buf + pos, bufsz - pos,
897 "auto_corr_ofdm_mrc_x1:\t\t %u\n",
898 data->auto_corr_ofdm_mrc_x1);
899 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
900 data->auto_corr_cck);
901 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
902 data->auto_corr_cck_mrc);
903 pos += scnprintf(buf + pos, bufsz - pos,
904 "last_bad_plcp_cnt_ofdm:\t\t %u\n",
905 data->last_bad_plcp_cnt_ofdm);
906 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
907 data->last_fa_cnt_ofdm);
908 pos += scnprintf(buf + pos, bufsz - pos,
909 "last_bad_plcp_cnt_cck:\t\t %u\n",
910 data->last_bad_plcp_cnt_cck);
911 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
912 data->last_fa_cnt_cck);
913 pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
914 data->nrg_curr_state);
915 pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
916 data->nrg_prev_state);
917 pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
918 for (cnt = 0; cnt < 10; cnt++) {
919 pos += scnprintf(buf + pos, bufsz - pos, " %u",
920 data->nrg_value[cnt]);
922 pos += scnprintf(buf + pos, bufsz - pos, "\n");
923 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
924 for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
925 pos += scnprintf(buf + pos, bufsz - pos, " %u",
926 data->nrg_silence_rssi[cnt]);
928 pos += scnprintf(buf + pos, bufsz - pos, "\n");
929 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
930 data->nrg_silence_ref);
931 pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
932 data->nrg_energy_idx);
933 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
934 data->nrg_silence_idx);
935 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
937 pos += scnprintf(buf + pos, bufsz - pos,
938 "nrg_auto_corr_silence_diff:\t %u\n",
939 data->nrg_auto_corr_silence_diff);
940 pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
941 data->num_in_cck_no_fa);
942 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
945 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
951 static ssize_t il_dbgfs_chain_noise_read(struct file *file,
952 char __user *user_buf,
953 size_t count, loff_t *ppos) {
955 struct il_priv *il = file->private_data;
959 int bufsz = sizeof(struct il_chain_noise_data) * 4 + 100;
961 struct il_chain_noise_data *data;
963 data = &il->chain_noise_data;
964 buf = kzalloc(bufsz, GFP_KERNEL);
966 IL_ERR("Can not allocate Buffer\n");
970 pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
971 data->active_chains);
972 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
973 data->chain_noise_a);
974 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
975 data->chain_noise_b);
976 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
977 data->chain_noise_c);
978 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
979 data->chain_signal_a);
980 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
981 data->chain_signal_b);
982 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
983 data->chain_signal_c);
984 pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
987 pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
988 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
989 pos += scnprintf(buf + pos, bufsz - pos, " %u",
990 data->disconn_array[cnt]);
992 pos += scnprintf(buf + pos, bufsz - pos, "\n");
993 pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
994 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
995 pos += scnprintf(buf + pos, bufsz - pos, " %u",
996 data->delta_gain_code[cnt]);
998 pos += scnprintf(buf + pos, bufsz - pos, "\n");
999 pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
1001 pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
1004 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1009 static ssize_t il_dbgfs_power_save_status_read(struct file *file,
1010 char __user *user_buf,
1011 size_t count, loff_t *ppos)
1013 struct il_priv *il = file->private_data;
1016 const size_t bufsz = sizeof(buf);
1019 pwrsave_status = _il_rd(il, CSR_GP_CNTRL) &
1020 CSR_GP_REG_POWER_SAVE_STATUS_MSK;
1022 pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
1023 pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
1024 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1025 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1026 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1029 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1032 static ssize_t il_dbgfs_clear_ucode_stats_write(struct file *file,
1033 const char __user *user_buf,
1034 size_t count, loff_t *ppos)
1036 struct il_priv *il = file->private_data;
1041 memset(buf, 0, sizeof(buf));
1042 buf_size = min(count, sizeof(buf) - 1);
1043 if (copy_from_user(buf, user_buf, buf_size))
1045 if (sscanf(buf, "%d", &clear) != 1)
1048 /* make request to uCode to retrieve stats information */
1049 mutex_lock(&il->mutex);
1050 il_send_stats_request(il, CMD_SYNC, true);
1051 mutex_unlock(&il->mutex);
1056 static ssize_t il_dbgfs_rxon_flags_read(struct file *file,
1057 char __user *user_buf,
1058 size_t count, loff_t *ppos) {
1060 struct il_priv *il = file->private_data;
1064 len = sprintf(buf, "0x%04X\n",
1065 le32_to_cpu(il->ctx.active.flags));
1066 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1069 static ssize_t il_dbgfs_rxon_filter_flags_read(struct file *file,
1070 char __user *user_buf,
1071 size_t count, loff_t *ppos) {
1073 struct il_priv *il = file->private_data;
1077 len = sprintf(buf, "0x%04X\n",
1078 le32_to_cpu(il->ctx.active.filter_flags));
1079 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1082 static ssize_t il_dbgfs_fh_reg_read(struct file *file,
1083 char __user *user_buf,
1084 size_t count, loff_t *ppos)
1086 struct il_priv *il = file->private_data;
1089 ssize_t ret = -EFAULT;
1091 if (il->cfg->ops->lib->dump_fh) {
1092 ret = pos = il->cfg->ops->lib->dump_fh(il, &buf, true);
1094 ret = simple_read_from_buffer(user_buf,
1095 count, ppos, buf, pos);
1103 static ssize_t il_dbgfs_missed_beacon_read(struct file *file,
1104 char __user *user_buf,
1105 size_t count, loff_t *ppos) {
1107 struct il_priv *il = file->private_data;
1110 const size_t bufsz = sizeof(buf);
1112 pos += scnprintf(buf + pos, bufsz - pos, "%d\n",
1113 il->missed_beacon_threshold);
1115 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1118 static ssize_t il_dbgfs_missed_beacon_write(struct file *file,
1119 const char __user *user_buf,
1120 size_t count, loff_t *ppos)
1122 struct il_priv *il = file->private_data;
1127 memset(buf, 0, sizeof(buf));
1128 buf_size = min(count, sizeof(buf) - 1);
1129 if (copy_from_user(buf, user_buf, buf_size))
1131 if (sscanf(buf, "%d", &missed) != 1)
1134 if (missed < IL_MISSED_BEACON_THRESHOLD_MIN ||
1135 missed > IL_MISSED_BEACON_THRESHOLD_MAX)
1136 il->missed_beacon_threshold =
1137 IL_MISSED_BEACON_THRESHOLD_DEF;
1139 il->missed_beacon_threshold = missed;
1144 static ssize_t il_dbgfs_force_reset_read(struct file *file,
1145 char __user *user_buf,
1146 size_t count, loff_t *ppos) {
1148 struct il_priv *il = file->private_data;
1151 const size_t bufsz = sizeof(buf);
1152 struct il_force_reset *force_reset;
1154 force_reset = &il->force_reset;
1156 pos += scnprintf(buf + pos, bufsz - pos,
1157 "\tnumber of reset request: %d\n",
1158 force_reset->reset_request_count);
1159 pos += scnprintf(buf + pos, bufsz - pos,
1160 "\tnumber of reset request success: %d\n",
1161 force_reset->reset_success_count);
1162 pos += scnprintf(buf + pos, bufsz - pos,
1163 "\tnumber of reset request reject: %d\n",
1164 force_reset->reset_reject_count);
1165 pos += scnprintf(buf + pos, bufsz - pos,
1166 "\treset duration: %lu\n",
1167 force_reset->reset_duration);
1169 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1172 static ssize_t il_dbgfs_force_reset_write(struct file *file,
1173 const char __user *user_buf,
1174 size_t count, loff_t *ppos) {
1177 struct il_priv *il = file->private_data;
1179 ret = il_force_reset(il, true);
1181 return ret ? ret : count;
1184 static ssize_t il_dbgfs_wd_timeout_write(struct file *file,
1185 const char __user *user_buf,
1186 size_t count, loff_t *ppos) {
1188 struct il_priv *il = file->private_data;
1193 memset(buf, 0, sizeof(buf));
1194 buf_size = min(count, sizeof(buf) - 1);
1195 if (copy_from_user(buf, user_buf, buf_size))
1197 if (sscanf(buf, "%d", &timeout) != 1)
1199 if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)
1200 timeout = IL_DEF_WD_TIMEOUT;
1202 il->cfg->base_params->wd_timeout = timeout;
1203 il_setup_watchdog(il);
1207 DEBUGFS_READ_FILE_OPS(rx_stats);
1208 DEBUGFS_READ_FILE_OPS(tx_stats);
1209 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
1210 DEBUGFS_READ_FILE_OPS(rx_queue);
1211 DEBUGFS_READ_FILE_OPS(tx_queue);
1212 DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1213 DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1214 DEBUGFS_READ_FILE_OPS(ucode_general_stats);
1215 DEBUGFS_READ_FILE_OPS(sensitivity);
1216 DEBUGFS_READ_FILE_OPS(chain_noise);
1217 DEBUGFS_READ_FILE_OPS(power_save_status);
1218 DEBUGFS_WRITE_FILE_OPS(clear_ucode_stats);
1219 DEBUGFS_WRITE_FILE_OPS(clear_traffic_stats);
1220 DEBUGFS_READ_FILE_OPS(fh_reg);
1221 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
1222 DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1223 DEBUGFS_READ_FILE_OPS(rxon_flags);
1224 DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
1225 DEBUGFS_WRITE_FILE_OPS(wd_timeout);
1228 * Create the debugfs files and directories
1231 int il_dbgfs_register(struct il_priv *il, const char *name)
1233 struct dentry *phyd = il->hw->wiphy->debugfsdir;
1234 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1236 dir_drv = debugfs_create_dir(name, phyd);
1240 il->debugfs_dir = dir_drv;
1242 dir_data = debugfs_create_dir("data", dir_drv);
1245 dir_rf = debugfs_create_dir("rf", dir_drv);
1248 dir_debug = debugfs_create_dir("debug", dir_drv);
1252 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR);
1253 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR);
1254 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR);
1255 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR);
1256 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR);
1257 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
1258 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
1259 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
1260 DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR);
1261 DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR);
1262 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
1263 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
1264 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
1265 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
1266 DEBUGFS_ADD_FILE(clear_ucode_stats, dir_debug, S_IWUSR);
1267 DEBUGFS_ADD_FILE(clear_traffic_stats, dir_debug, S_IWUSR);
1268 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR);
1269 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
1270 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR);
1271 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
1272 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
1273 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
1275 if (il->cfg->base_params->sensitivity_calib_by_driver)
1276 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
1277 if (il->cfg->base_params->chain_noise_calib_by_driver)
1278 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
1279 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
1280 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
1281 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
1282 if (il->cfg->base_params->sensitivity_calib_by_driver)
1283 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
1284 &il->disable_sens_cal);
1285 if (il->cfg->base_params->chain_noise_calib_by_driver)
1286 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
1287 &il->disable_chain_noise_cal);
1288 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
1289 &il->disable_tx_power_cal);
1293 IL_ERR("Can't create the debugfs directory\n");
1294 il_dbgfs_unregister(il);
1297 EXPORT_SYMBOL(il_dbgfs_register);
1300 * Remove the debugfs files and directories
1303 void il_dbgfs_unregister(struct il_priv *il)
1305 if (!il->debugfs_dir)
1308 debugfs_remove_recursive(il->debugfs_dir);
1309 il->debugfs_dir = NULL;
1311 EXPORT_SYMBOL(il_dbgfs_unregister);