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-12-10 17:37:26 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-21 18:56:16 -0500
commita9e1cb6a78ea8a74c49bf76726a2942f636a833b (patch)
treee1f4f083c7154f322b2a65c90a04da817403fcba /drivers/net/wireless/iwlwifi/iwl-debugfs.c
parent696bdee3ba216186e21997d20a839b76158346e6 (diff)
iwlwifi: add continuous uCode event log capability
In order to help uCode debugging, adding the capability to provide continuous uCode event logging function. uCode events is located in round-robin event queue and filled by uCode, by enable continuous event logging, driver check the write pointer and log the newly added events in iwl_bg_ucode_trace() timer function. There is still possibility of missing events if event queue being wrapped before next event dump; but with this capability, we can have much better understanding of the uCode behavior during runtime; it can help to debug the uCode related issues. Methods to enable/disable the continuous event log: step 1: enable ucode trace timer "echo 1 > /sys/kernel/debug/ieee80211/phyX/iwlagn/debug/ucode_tracing" step 2: start ftrace sudo ./trace-cmd record -e iwlwifi_ucode:* sleep 1d step 3: stop ftrace sudo ./trace-cmd report trace.dat step 4: disable ucode trace timer "echo 0 > /sys/kernel/debug/ieee80211/phyX/iwlagn/debug/ucode_tracing" use "ucode_tracing" debugfs file to display number of event queue wrapped when driver attempt the continuous event logging. If event queue being wrapped more than once when driver has opportunity to log the event; it indicated there are events missing in the event log trace. This continuous event log function only available for 4965 and newer NICs. 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.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 2be3549be01d..822de46e4f34 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1867,6 +1867,58 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file,
1867 return count; 1867 return count;
1868} 1868}
1869 1869
1870static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
1871 char __user *user_buf,
1872 size_t count, loff_t *ppos) {
1873
1874 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1875 int pos = 0;
1876 char buf[128];
1877 const size_t bufsz = sizeof(buf);
1878 ssize_t ret;
1879
1880 pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
1881 priv->event_log.ucode_trace ? "On" : "Off");
1882 pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n",
1883 priv->event_log.non_wraps_count);
1884 pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n",
1885 priv->event_log.wraps_once_count);
1886 pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
1887 priv->event_log.wraps_more_count);
1888
1889 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1890 return ret;
1891}
1892
1893static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
1894 const char __user *user_buf,
1895 size_t count, loff_t *ppos)
1896{
1897 struct iwl_priv *priv = file->private_data;
1898 char buf[8];
1899 int buf_size;
1900 int trace;
1901
1902 memset(buf, 0, sizeof(buf));
1903 buf_size = min(count, sizeof(buf) - 1);
1904 if (copy_from_user(buf, user_buf, buf_size))
1905 return -EFAULT;
1906 if (sscanf(buf, "%d", &trace) != 1)
1907 return -EFAULT;
1908
1909 if (trace) {
1910 priv->event_log.ucode_trace = true;
1911 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
1912 mod_timer(&priv->ucode_trace,
1913 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
1914 } else {
1915 priv->event_log.ucode_trace = false;
1916 del_timer_sync(&priv->ucode_trace);
1917 }
1918
1919 return count;
1920}
1921
1870DEBUGFS_READ_FILE_OPS(rx_statistics); 1922DEBUGFS_READ_FILE_OPS(rx_statistics);
1871DEBUGFS_READ_FILE_OPS(tx_statistics); 1923DEBUGFS_READ_FILE_OPS(tx_statistics);
1872DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 1924DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1882,6 +1934,7 @@ DEBUGFS_READ_FILE_OPS(power_save_status);
1882DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); 1934DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
1883DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); 1935DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
1884DEBUGFS_WRITE_FILE_OPS(csr); 1936DEBUGFS_WRITE_FILE_OPS(csr);
1937DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
1885 1938
1886/* 1939/*
1887 * Create the debugfs files and directories 1940 * Create the debugfs files and directories
@@ -1939,6 +1992,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1939 DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR); 1992 DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR);
1940 DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR); 1993 DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR);
1941 DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR); 1994 DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR);
1995 DEBUGFS_ADD_FILE(ucode_tracing, debug, S_IWUSR | S_IRUSR);
1942 } 1996 }
1943 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 1997 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
1944 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 1998 DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
@@ -2002,6 +2056,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
2002 file_sensitivity); 2056 file_sensitivity);
2003 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 2057 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2004 file_chain_noise); 2058 file_chain_noise);
2059 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2060 file_ucode_tracing);
2005 } 2061 }
2006 DEBUGFS_REMOVE(priv->dbgfs->dir_debug); 2062 DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
2007 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); 2063 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);