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-08-07 18:41:39 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:13:46 -0400
commit20594eb0daa67f7a0cc19d74a1bafceb1bb09f4a (patch)
tree9ae022adef73139b524dcd7dde9c6f02809e8cf1 /drivers/net/wireless/iwlwifi/iwl-debugfs.c
parent7aafef1c6e2e24f9a10dc2972bf0ee70624ccc47 (diff)
iwlwifi: new debugging feature for dumping data traffic
The traffic buffer will only beallocated and used if either bit 23 (IWL_DX_TX) or bit 24 (IWL_DL_RX) of "debug" is set; example: "debug=0x800000" - log tx data traffic "debug=0x1000000" - log rx data traffic "debug=0x1800000" - log both tx and rx traffic The traffic log will store the beginning portion (64 bytes) of the latest 256 of tx and rx packets in the round-robbin buffer for debugging, user can examine the log through debugfs file. How to display the current logged tx/rx traffic and txfifo and rxfifo read/write point: "cat traffic_log" in /sys/kernel/debug/ieee80211/phy0/iwlagn/debug directory By echo "0" to traffic_log file will empty the traffic log buffer and reset both tx and rx taffic log index to 0. 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.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 6748a3fb966..031538c4206 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -712,6 +712,104 @@ DEBUGFS_READ_FILE_OPS(led);
712DEBUGFS_READ_FILE_OPS(thermal_throttling); 712DEBUGFS_READ_FILE_OPS(thermal_throttling);
713DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); 713DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
714 714
715static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
716 char __user *user_buf,
717 size_t count, loff_t *ppos)
718{
719 struct iwl_priv *priv = file->private_data;
720 int pos = 0, ofs = 0;
721 int cnt = 0, entry;
722 struct iwl_tx_queue *txq;
723 struct iwl_queue *q;
724 struct iwl_rx_queue *rxq = &priv->rxq;
725 char *buf;
726 int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
727 (IWL_MAX_NUM_QUEUES * 32 * 8) + 400;
728 const u8 *ptr;
729 ssize_t ret;
730
731 buf = kzalloc(bufsz, GFP_KERNEL);
732 if (!buf) {
733 IWL_ERR(priv, "Can not allocate buffer\n");
734 return -ENOMEM;
735 }
736 pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
737 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
738 txq = &priv->txq[cnt];
739 q = &txq->q;
740 pos += scnprintf(buf + pos, bufsz - pos,
741 "q[%d]: read_ptr: %u, write_ptr: %u\n",
742 cnt, q->read_ptr, q->write_ptr);
743 }
744 if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) {
745 ptr = priv->tx_traffic;
746 pos += scnprintf(buf + pos, bufsz - pos,
747 "Tx Traffic idx: %u\n", priv->tx_traffic_idx);
748 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
749 for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
750 entry++, ofs += 16) {
751 pos += scnprintf(buf + pos, bufsz - pos,
752 "0x%.4x ", ofs);
753 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
754 buf + pos, bufsz - pos, 0);
755 pos += strlen(buf);
756 if (bufsz - pos > 0)
757 buf[pos++] = '\n';
758 }
759 }
760 }
761
762 pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
763 pos += scnprintf(buf + pos, bufsz - pos,
764 "read: %u, write: %u\n",
765 rxq->read, rxq->write);
766
767 if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) {
768 ptr = priv->rx_traffic;
769 pos += scnprintf(buf + pos, bufsz - pos,
770 "Rx Traffic idx: %u\n", priv->rx_traffic_idx);
771 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
772 for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
773 entry++, ofs += 16) {
774 pos += scnprintf(buf + pos, bufsz - pos,
775 "0x%.4x ", ofs);
776 hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
777 buf + pos, bufsz - pos, 0);
778 pos += strlen(buf);
779 if (bufsz - pos > 0)
780 buf[pos++] = '\n';
781 }
782 }
783 }
784
785 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
786 kfree(buf);
787 return ret;
788}
789
790static ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
791 const char __user *user_buf,
792 size_t count, loff_t *ppos)
793{
794 struct iwl_priv *priv = file->private_data;
795 char buf[8];
796 int buf_size;
797 int traffic_log;
798
799 memset(buf, 0, sizeof(buf));
800 buf_size = min(count, sizeof(buf) - 1);
801 if (copy_from_user(buf, user_buf, buf_size))
802 return -EFAULT;
803 if (sscanf(buf, "%d", &traffic_log) != 1)
804 return -EFAULT;
805 if (traffic_log == 0)
806 iwl_reset_traffic_log(priv);
807
808 return count;
809}
810
811DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
812
715/* 813/*
716 * Create the debugfs files and directories 814 * Create the debugfs files and directories
717 * 815 *
@@ -738,6 +836,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
738 836
739 DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); 837 DEBUGFS_ADD_DIR(data, dbgfs->dir_drv);
740 DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); 838 DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv);
839 DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv);
741 DEBUGFS_ADD_FILE(nvm, data); 840 DEBUGFS_ADD_FILE(nvm, data);
742 DEBUGFS_ADD_FILE(sram, data); 841 DEBUGFS_ADD_FILE(sram, data);
743 DEBUGFS_ADD_FILE(log_event, data); 842 DEBUGFS_ADD_FILE(log_event, data);
@@ -753,6 +852,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
753#endif 852#endif
754 DEBUGFS_ADD_FILE(thermal_throttling, data); 853 DEBUGFS_ADD_FILE(thermal_throttling, data);
755 DEBUGFS_ADD_FILE(disable_ht40, data); 854 DEBUGFS_ADD_FILE(disable_ht40, data);
855 DEBUGFS_ADD_FILE(traffic_log, debug);
756 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 856 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
757 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 857 DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
758 &priv->disable_chain_noise_cal); 858 &priv->disable_chain_noise_cal);
@@ -794,6 +894,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
794 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling); 894 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
795 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40); 895 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
796 DEBUGFS_REMOVE(priv->dbgfs->dir_data); 896 DEBUGFS_REMOVE(priv->dbgfs->dir_data);
897 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log);
898 DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
797 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); 899 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
798 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); 900 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
799 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || 901 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||