diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2009-04-08 14:39:32 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-04-22 16:54:44 -0400 |
commit | a83b9141b540f96dd59409c6487828e880113a29 (patch) | |
tree | 040301dd80eb0307c9dcd5208f88082b4d3922cf /drivers/net/wireless/iwlwifi/iwl-debugfs.c | |
parent | 1620108910b07bc41f4ad462ca56e899faf7e61a (diff) |
iwlwifi: adding interrupt counter in debugfs for debugging
This patch adds interrupt statistics report to debugfs, this can help to
understand number of interrupts happened which including HW/SW error for
easier and better debugging.
in /sys/kernel/debug/ieee80211/phyN/iwlagn/data directory
use "cat interrupt" to view the current interrupt counter
use "echo 0 > interrupt" to clear interrupt counter
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-debugfs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debugfs.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 5b8c83939bf0..ffc4be3842b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -473,6 +473,95 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
473 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 473 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
474 | } | 474 | } |
475 | 475 | ||
476 | static ssize_t iwl_dbgfs_interrupt_read(struct file *file, | ||
477 | char __user *user_buf, | ||
478 | size_t count, loff_t *ppos) { | ||
479 | |||
480 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
481 | int pos = 0; | ||
482 | int cnt = 0; | ||
483 | char *buf; | ||
484 | int bufsz = 24 * 64; /* 24 items * 64 char per item */ | ||
485 | ssize_t ret; | ||
486 | |||
487 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
488 | if (!buf) { | ||
489 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
490 | return -ENOMEM; | ||
491 | } | ||
492 | |||
493 | pos += scnprintf(buf + pos, bufsz - pos, | ||
494 | "Interrupt Statistics Report:\n"); | ||
495 | |||
496 | pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n", | ||
497 | priv->isr_stats.hw); | ||
498 | pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", | ||
499 | priv->isr_stats.sw); | ||
500 | if (priv->isr_stats.sw > 0) { | ||
501 | pos += scnprintf(buf + pos, bufsz - pos, | ||
502 | "\tLast Restarting Code: 0x%X\n", | ||
503 | priv->isr_stats.sw_err); | ||
504 | } | ||
505 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
506 | pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", | ||
507 | priv->isr_stats.sch); | ||
508 | pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n", | ||
509 | priv->isr_stats.alive); | ||
510 | #endif | ||
511 | pos += scnprintf(buf + pos, bufsz - pos, | ||
512 | "HW RF KILL switch toggled:\t %u\n", | ||
513 | priv->isr_stats.rfkill); | ||
514 | |||
515 | pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n", | ||
516 | priv->isr_stats.ctkill); | ||
517 | |||
518 | pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n", | ||
519 | priv->isr_stats.wakeup); | ||
520 | |||
521 | pos += scnprintf(buf + pos, bufsz - pos, | ||
522 | "Rx command responses:\t\t %u\n", | ||
523 | priv->isr_stats.rx); | ||
524 | for (cnt = 0; cnt < REPLY_MAX; cnt++) { | ||
525 | if (priv->isr_stats.rx_handlers[cnt] > 0) | ||
526 | pos += scnprintf(buf + pos, bufsz - pos, | ||
527 | "\tRx handler[%36s]:\t\t %u\n", | ||
528 | get_cmd_string(cnt), | ||
529 | priv->isr_stats.rx_handlers[cnt]); | ||
530 | } | ||
531 | |||
532 | pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n", | ||
533 | priv->isr_stats.tx); | ||
534 | |||
535 | pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n", | ||
536 | priv->isr_stats.unhandled); | ||
537 | |||
538 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
539 | kfree(buf); | ||
540 | return ret; | ||
541 | } | ||
542 | |||
543 | static ssize_t iwl_dbgfs_interrupt_write(struct file *file, | ||
544 | const char __user *user_buf, | ||
545 | size_t count, loff_t *ppos) | ||
546 | { | ||
547 | struct iwl_priv *priv = file->private_data; | ||
548 | char buf[8]; | ||
549 | int buf_size; | ||
550 | u32 reset_flag; | ||
551 | |||
552 | memset(buf, 0, sizeof(buf)); | ||
553 | buf_size = min(count, sizeof(buf) - 1); | ||
554 | if (copy_from_user(buf, user_buf, buf_size)) | ||
555 | return -EFAULT; | ||
556 | if (sscanf(buf, "%x", &reset_flag) != 1) | ||
557 | return -EFAULT; | ||
558 | if (reset_flag == 0) | ||
559 | iwl_clear_isr_stats(priv); | ||
560 | |||
561 | return count; | ||
562 | } | ||
563 | |||
564 | |||
476 | DEBUGFS_READ_WRITE_FILE_OPS(sram); | 565 | DEBUGFS_READ_WRITE_FILE_OPS(sram); |
477 | DEBUGFS_WRITE_FILE_OPS(log_event); | 566 | DEBUGFS_WRITE_FILE_OPS(log_event); |
478 | DEBUGFS_READ_FILE_OPS(eeprom); | 567 | DEBUGFS_READ_FILE_OPS(eeprom); |
@@ -481,6 +570,7 @@ DEBUGFS_READ_FILE_OPS(rx_statistics); | |||
481 | DEBUGFS_READ_FILE_OPS(tx_statistics); | 570 | DEBUGFS_READ_FILE_OPS(tx_statistics); |
482 | DEBUGFS_READ_FILE_OPS(channels); | 571 | DEBUGFS_READ_FILE_OPS(channels); |
483 | DEBUGFS_READ_FILE_OPS(status); | 572 | DEBUGFS_READ_FILE_OPS(status); |
573 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); | ||
484 | 574 | ||
485 | /* | 575 | /* |
486 | * Create the debugfs files and directories | 576 | * Create the debugfs files and directories |
@@ -516,6 +606,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
516 | DEBUGFS_ADD_FILE(tx_statistics, data); | 606 | DEBUGFS_ADD_FILE(tx_statistics, data); |
517 | DEBUGFS_ADD_FILE(channels, data); | 607 | DEBUGFS_ADD_FILE(channels, data); |
518 | DEBUGFS_ADD_FILE(status, data); | 608 | DEBUGFS_ADD_FILE(status, data); |
609 | DEBUGFS_ADD_FILE(interrupt, data); | ||
519 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); | 610 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); |
520 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, | 611 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, |
521 | &priv->disable_chain_noise_cal); | 612 | &priv->disable_chain_noise_cal); |
@@ -546,6 +637,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
546 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); | 637 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); |
547 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels); | 638 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels); |
548 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status); | 639 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status); |
640 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt); | ||
549 | DEBUGFS_REMOVE(priv->dbgfs->dir_data); | 641 | DEBUGFS_REMOVE(priv->dbgfs->dir_data); |
550 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); | 642 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); |
551 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); | 643 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); |