aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-debugfs.c
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2009-04-08 14:39:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-04-22 16:54:44 -0400
commita83b9141b540f96dd59409c6487828e880113a29 (patch)
tree040301dd80eb0307c9dcd5208f88082b4d3922cf /drivers/net/wireless/iwlwifi/iwl-debugfs.c
parent1620108910b07bc41f4ad462ca56e899faf7e61a (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.c92
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
476static 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
543static 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
476DEBUGFS_READ_WRITE_FILE_OPS(sram); 565DEBUGFS_READ_WRITE_FILE_OPS(sram);
477DEBUGFS_WRITE_FILE_OPS(log_event); 566DEBUGFS_WRITE_FILE_OPS(log_event);
478DEBUGFS_READ_FILE_OPS(eeprom); 567DEBUGFS_READ_FILE_OPS(eeprom);
@@ -481,6 +570,7 @@ DEBUGFS_READ_FILE_OPS(rx_statistics);
481DEBUGFS_READ_FILE_OPS(tx_statistics); 570DEBUGFS_READ_FILE_OPS(tx_statistics);
482DEBUGFS_READ_FILE_OPS(channels); 571DEBUGFS_READ_FILE_OPS(channels);
483DEBUGFS_READ_FILE_OPS(status); 572DEBUGFS_READ_FILE_OPS(status);
573DEBUGFS_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);