diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 104 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debugfs.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 101 |
6 files changed, 171 insertions, 69 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index ecc23ec1f6a4..28f6eb5f2cba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -227,7 +227,8 @@ extern void iwl3945_rx_replenish(void *data); | |||
227 | extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | 227 | extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); |
228 | extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, | 228 | extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, |
229 | struct ieee80211_hdr *hdr,int left); | 229 | struct ieee80211_hdr *hdr,int left); |
230 | extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log); | 230 | extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, |
231 | char **buf, bool display); | ||
231 | extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); | 232 | extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); |
232 | 233 | ||
233 | /* | 234 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4d85c28e38e2..0b3669f317a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1832,8 +1832,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1832 | * iwl_print_event_log - Dump error event log to syslog | 1832 | * iwl_print_event_log - Dump error event log to syslog |
1833 | * | 1833 | * |
1834 | */ | 1834 | */ |
1835 | static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | 1835 | static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, |
1836 | u32 num_events, u32 mode) | 1836 | u32 num_events, u32 mode, |
1837 | int pos, char **buf, size_t bufsz) | ||
1837 | { | 1838 | { |
1838 | u32 i; | 1839 | u32 i; |
1839 | u32 base; /* SRAM byte address of event log header */ | 1840 | u32 base; /* SRAM byte address of event log header */ |
@@ -1843,7 +1844,7 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1843 | unsigned long reg_flags; | 1844 | unsigned long reg_flags; |
1844 | 1845 | ||
1845 | if (num_events == 0) | 1846 | if (num_events == 0) |
1846 | return; | 1847 | return pos; |
1847 | if (priv->ucode_type == UCODE_INIT) | 1848 | if (priv->ucode_type == UCODE_INIT) |
1848 | base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); | 1849 | base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); |
1849 | else | 1850 | else |
@@ -1871,27 +1872,44 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1871 | time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 1872 | time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1872 | if (mode == 0) { | 1873 | if (mode == 0) { |
1873 | /* data, ev */ | 1874 | /* data, ev */ |
1874 | trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); | 1875 | if (bufsz) { |
1875 | IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev); | 1876 | pos += scnprintf(*buf + pos, bufsz - pos, |
1877 | "EVT_LOG:0x%08x:%04u\n", | ||
1878 | time, ev); | ||
1879 | } else { | ||
1880 | trace_iwlwifi_dev_ucode_event(priv, 0, | ||
1881 | time, ev); | ||
1882 | IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", | ||
1883 | time, ev); | ||
1884 | } | ||
1876 | } else { | 1885 | } else { |
1877 | data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 1886 | data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1878 | IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", | 1887 | if (bufsz) { |
1888 | pos += scnprintf(*buf + pos, bufsz - pos, | ||
1889 | "EVT_LOGT:%010u:0x%08x:%04u\n", | ||
1890 | time, data, ev); | ||
1891 | } else { | ||
1892 | IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", | ||
1879 | time, data, ev); | 1893 | time, data, ev); |
1880 | trace_iwlwifi_dev_ucode_event(priv, time, data, ev); | 1894 | trace_iwlwifi_dev_ucode_event(priv, time, |
1895 | data, ev); | ||
1896 | } | ||
1881 | } | 1897 | } |
1882 | } | 1898 | } |
1883 | 1899 | ||
1884 | /* Allow device to power down */ | 1900 | /* Allow device to power down */ |
1885 | iwl_release_nic_access(priv); | 1901 | iwl_release_nic_access(priv); |
1886 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | 1902 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); |
1903 | return pos; | ||
1887 | } | 1904 | } |
1888 | 1905 | ||
1889 | /** | 1906 | /** |
1890 | * iwl_print_last_event_logs - Dump the newest # of event log to syslog | 1907 | * iwl_print_last_event_logs - Dump the newest # of event log to syslog |
1891 | */ | 1908 | */ |
1892 | static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | 1909 | static int iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, |
1893 | u32 num_wraps, u32 next_entry, | 1910 | u32 num_wraps, u32 next_entry, |
1894 | u32 size, u32 mode) | 1911 | u32 size, u32 mode, |
1912 | int pos, char **buf, size_t bufsz) | ||
1895 | { | 1913 | { |
1896 | /* | 1914 | /* |
1897 | * display the newest DEFAULT_LOG_ENTRIES entries | 1915 | * display the newest DEFAULT_LOG_ENTRIES entries |
@@ -1899,21 +1917,26 @@ static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | |||
1899 | */ | 1917 | */ |
1900 | if (num_wraps) { | 1918 | if (num_wraps) { |
1901 | if (next_entry < size) { | 1919 | if (next_entry < size) { |
1902 | iwl_print_event_log(priv, | 1920 | pos = iwl_print_event_log(priv, |
1903 | capacity - (size - next_entry), | 1921 | capacity - (size - next_entry), |
1904 | size - next_entry, mode); | 1922 | size - next_entry, mode, |
1905 | iwl_print_event_log(priv, 0, | 1923 | pos, buf, bufsz); |
1906 | next_entry, mode); | 1924 | pos = iwl_print_event_log(priv, 0, |
1925 | next_entry, mode, | ||
1926 | pos, buf, bufsz); | ||
1907 | } else | 1927 | } else |
1908 | iwl_print_event_log(priv, next_entry - size, | 1928 | pos = iwl_print_event_log(priv, next_entry - size, |
1909 | size, mode); | 1929 | size, mode, pos, buf, bufsz); |
1910 | } else { | 1930 | } else { |
1911 | if (next_entry < size) | 1931 | if (next_entry < size) { |
1912 | iwl_print_event_log(priv, 0, next_entry, mode); | 1932 | pos = iwl_print_event_log(priv, 0, next_entry, |
1913 | else | 1933 | mode, pos, buf, bufsz); |
1914 | iwl_print_event_log(priv, next_entry - size, | 1934 | } else { |
1915 | size, mode); | 1935 | pos = iwl_print_event_log(priv, next_entry - size, |
1936 | size, mode, pos, buf, bufsz); | ||
1937 | } | ||
1916 | } | 1938 | } |
1939 | return pos; | ||
1917 | } | 1940 | } |
1918 | 1941 | ||
1919 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ | 1942 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ |
@@ -1921,7 +1944,8 @@ static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | |||
1921 | 1944 | ||
1922 | #define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) | 1945 | #define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) |
1923 | 1946 | ||
1924 | void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | 1947 | int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, |
1948 | char **buf, bool display) | ||
1925 | { | 1949 | { |
1926 | u32 base; /* SRAM byte address of event log header */ | 1950 | u32 base; /* SRAM byte address of event log header */ |
1927 | u32 capacity; /* event log capacity in # entries */ | 1951 | u32 capacity; /* event log capacity in # entries */ |
@@ -1929,6 +1953,8 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1929 | u32 num_wraps; /* # times uCode wrapped to top of log */ | 1953 | u32 num_wraps; /* # times uCode wrapped to top of log */ |
1930 | u32 next_entry; /* index of next entry to be written by uCode */ | 1954 | u32 next_entry; /* index of next entry to be written by uCode */ |
1931 | u32 size; /* # entries that we'll print */ | 1955 | u32 size; /* # entries that we'll print */ |
1956 | int pos = 0; | ||
1957 | size_t bufsz = 0; | ||
1932 | 1958 | ||
1933 | if (priv->ucode_type == UCODE_INIT) | 1959 | if (priv->ucode_type == UCODE_INIT) |
1934 | base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); | 1960 | base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); |
@@ -1939,7 +1965,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1939 | IWL_ERR(priv, | 1965 | IWL_ERR(priv, |
1940 | "Invalid event log pointer 0x%08X for %s uCode\n", | 1966 | "Invalid event log pointer 0x%08X for %s uCode\n", |
1941 | base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); | 1967 | base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); |
1942 | return; | 1968 | return pos; |
1943 | } | 1969 | } |
1944 | 1970 | ||
1945 | /* event log header */ | 1971 | /* event log header */ |
@@ -1965,7 +1991,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1965 | /* bail out if nothing in log */ | 1991 | /* bail out if nothing in log */ |
1966 | if (size == 0) { | 1992 | if (size == 0) { |
1967 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); | 1993 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); |
1968 | return; | 1994 | return pos; |
1969 | } | 1995 | } |
1970 | 1996 | ||
1971 | #ifdef CONFIG_IWLWIFI_DEBUG | 1997 | #ifdef CONFIG_IWLWIFI_DEBUG |
@@ -1980,6 +2006,15 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1980 | size); | 2006 | size); |
1981 | 2007 | ||
1982 | #ifdef CONFIG_IWLWIFI_DEBUG | 2008 | #ifdef CONFIG_IWLWIFI_DEBUG |
2009 | if (display) { | ||
2010 | if (full_log) | ||
2011 | bufsz = capacity * 48; | ||
2012 | else | ||
2013 | bufsz = size * 48; | ||
2014 | *buf = kmalloc(bufsz, GFP_KERNEL); | ||
2015 | if (!*buf) | ||
2016 | return pos; | ||
2017 | } | ||
1983 | if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { | 2018 | if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { |
1984 | /* | 2019 | /* |
1985 | * if uCode has wrapped back to top of log, | 2020 | * if uCode has wrapped back to top of log, |
@@ -1987,17 +2022,22 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1987 | * i.e the next one that uCode would fill. | 2022 | * i.e the next one that uCode would fill. |
1988 | */ | 2023 | */ |
1989 | if (num_wraps) | 2024 | if (num_wraps) |
1990 | iwl_print_event_log(priv, next_entry, | 2025 | pos = iwl_print_event_log(priv, next_entry, |
1991 | capacity - next_entry, mode); | 2026 | capacity - next_entry, mode, |
2027 | pos, buf, bufsz); | ||
1992 | /* (then/else) start at top of log */ | 2028 | /* (then/else) start at top of log */ |
1993 | iwl_print_event_log(priv, 0, next_entry, mode); | 2029 | pos = iwl_print_event_log(priv, 0, |
2030 | next_entry, mode, pos, buf, bufsz); | ||
1994 | } else | 2031 | } else |
1995 | iwl_print_last_event_logs(priv, capacity, num_wraps, | 2032 | pos = iwl_print_last_event_logs(priv, capacity, num_wraps, |
1996 | next_entry, size, mode); | 2033 | next_entry, size, mode, |
2034 | pos, buf, bufsz); | ||
1997 | #else | 2035 | #else |
1998 | iwl_print_last_event_logs(priv, capacity, num_wraps, | 2036 | pos = iwl_print_last_event_logs(priv, capacity, num_wraps, |
1999 | next_entry, size, mode); | 2037 | next_entry, size, mode, |
2038 | pos, buf, bufsz); | ||
2000 | #endif | 2039 | #endif |
2040 | return pos; | ||
2001 | } | 2041 | } |
2002 | 2042 | ||
2003 | /** | 2043 | /** |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 47ece91e4505..c3c31dc9fd4d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1365,7 +1365,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv) | |||
1365 | priv->cfg->ops->lib->dump_nic_error_log(priv); | 1365 | priv->cfg->ops->lib->dump_nic_error_log(priv); |
1366 | if (priv->cfg->ops->lib->dump_csr) | 1366 | if (priv->cfg->ops->lib->dump_csr) |
1367 | priv->cfg->ops->lib->dump_csr(priv); | 1367 | priv->cfg->ops->lib->dump_csr(priv); |
1368 | priv->cfg->ops->lib->dump_nic_event_log(priv, false); | 1368 | priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); |
1369 | #ifdef CONFIG_IWLWIFI_DEBUG | 1369 | #ifdef CONFIG_IWLWIFI_DEBUG |
1370 | if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) | 1370 | if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) |
1371 | iwl_print_rx_config_cmd(priv); | 1371 | iwl_print_rx_config_cmd(priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f5e79cf0a318..650d3808d24a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -169,7 +169,8 @@ struct iwl_lib_ops { | |||
169 | int (*is_valid_rtc_data_addr)(u32 addr); | 169 | int (*is_valid_rtc_data_addr)(u32 addr); |
170 | /* 1st ucode load */ | 170 | /* 1st ucode load */ |
171 | int (*load_ucode)(struct iwl_priv *priv); | 171 | int (*load_ucode)(struct iwl_priv *priv); |
172 | void (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log); | 172 | int (*dump_nic_event_log)(struct iwl_priv *priv, |
173 | bool full_log, char **buf, bool display); | ||
173 | void (*dump_nic_error_log)(struct iwl_priv *priv); | 174 | void (*dump_nic_error_log)(struct iwl_priv *priv); |
174 | void (*dump_csr)(struct iwl_priv *priv); | 175 | void (*dump_csr)(struct iwl_priv *priv); |
175 | int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); | 176 | int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); |
@@ -582,7 +583,8 @@ int iwl_pci_resume(struct pci_dev *pdev); | |||
582 | * Error Handling Debugging | 583 | * Error Handling Debugging |
583 | ******************************************************/ | 584 | ******************************************************/ |
584 | void iwl_dump_nic_error_log(struct iwl_priv *priv); | 585 | void iwl_dump_nic_error_log(struct iwl_priv *priv); |
585 | void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log); | 586 | int iwl_dump_nic_event_log(struct iwl_priv *priv, |
587 | bool full_log, char **buf, bool display); | ||
586 | void iwl_dump_csr(struct iwl_priv *priv); | 588 | void iwl_dump_csr(struct iwl_priv *priv); |
587 | #ifdef CONFIG_IWLWIFI_DEBUG | 589 | #ifdef CONFIG_IWLWIFI_DEBUG |
588 | void iwl_print_rx_config_cmd(struct iwl_priv *priv); | 590 | void iwl_print_rx_config_cmd(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 822de46e4f34..ee5aed12a4b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -420,6 +420,23 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, | |||
420 | return ret; | 420 | return ret; |
421 | } | 421 | } |
422 | 422 | ||
423 | static ssize_t iwl_dbgfs_log_event_read(struct file *file, | ||
424 | char __user *user_buf, | ||
425 | size_t count, loff_t *ppos) | ||
426 | { | ||
427 | struct iwl_priv *priv = file->private_data; | ||
428 | char *buf; | ||
429 | int pos = 0; | ||
430 | ssize_t ret = -ENOMEM; | ||
431 | |||
432 | pos = priv->cfg->ops->lib->dump_nic_event_log(priv, true, &buf, true); | ||
433 | if (pos && buf) { | ||
434 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
435 | kfree(buf); | ||
436 | } | ||
437 | return ret; | ||
438 | } | ||
439 | |||
423 | static ssize_t iwl_dbgfs_log_event_write(struct file *file, | 440 | static ssize_t iwl_dbgfs_log_event_write(struct file *file, |
424 | const char __user *user_buf, | 441 | const char __user *user_buf, |
425 | size_t count, loff_t *ppos) | 442 | size_t count, loff_t *ppos) |
@@ -436,7 +453,8 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, | |||
436 | if (sscanf(buf, "%d", &event_log_flag) != 1) | 453 | if (sscanf(buf, "%d", &event_log_flag) != 1) |
437 | return -EFAULT; | 454 | return -EFAULT; |
438 | if (event_log_flag == 1) | 455 | if (event_log_flag == 1) |
439 | priv->cfg->ops->lib->dump_nic_event_log(priv, true); | 456 | priv->cfg->ops->lib->dump_nic_event_log(priv, true, |
457 | NULL, false); | ||
440 | 458 | ||
441 | return count; | 459 | return count; |
442 | } | 460 | } |
@@ -859,7 +877,7 @@ static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file, | |||
859 | } | 877 | } |
860 | 878 | ||
861 | DEBUGFS_READ_WRITE_FILE_OPS(sram); | 879 | DEBUGFS_READ_WRITE_FILE_OPS(sram); |
862 | DEBUGFS_WRITE_FILE_OPS(log_event); | 880 | DEBUGFS_READ_WRITE_FILE_OPS(log_event); |
863 | DEBUGFS_READ_FILE_OPS(nvm); | 881 | DEBUGFS_READ_FILE_OPS(nvm); |
864 | DEBUGFS_READ_FILE_OPS(stations); | 882 | DEBUGFS_READ_FILE_OPS(stations); |
865 | DEBUGFS_READ_FILE_OPS(channels); | 883 | DEBUGFS_READ_FILE_OPS(channels); |
@@ -1965,7 +1983,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
1965 | DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); | 1983 | DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); |
1966 | DEBUGFS_ADD_FILE(nvm, data, S_IRUSR); | 1984 | DEBUGFS_ADD_FILE(nvm, data, S_IRUSR); |
1967 | DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR); | 1985 | DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR); |
1968 | DEBUGFS_ADD_FILE(log_event, data, S_IWUSR); | 1986 | DEBUGFS_ADD_FILE(log_event, data, S_IWUSR | S_IRUSR); |
1969 | DEBUGFS_ADD_FILE(stations, data, S_IRUSR); | 1987 | DEBUGFS_ADD_FILE(stations, data, S_IRUSR); |
1970 | DEBUGFS_ADD_FILE(channels, data, S_IRUSR); | 1988 | DEBUGFS_ADD_FILE(channels, data, S_IRUSR); |
1971 | DEBUGFS_ADD_FILE(status, data, S_IRUSR); | 1989 | DEBUGFS_ADD_FILE(status, data, S_IRUSR); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 2a28a1f8b1fe..f7c7ff4264fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -1560,8 +1560,9 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv) | |||
1560 | * iwl3945_print_event_log - Dump error event log to syslog | 1560 | * iwl3945_print_event_log - Dump error event log to syslog |
1561 | * | 1561 | * |
1562 | */ | 1562 | */ |
1563 | static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | 1563 | static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, |
1564 | u32 num_events, u32 mode) | 1564 | u32 num_events, u32 mode, |
1565 | int pos, char **buf, size_t bufsz) | ||
1565 | { | 1566 | { |
1566 | u32 i; | 1567 | u32 i; |
1567 | u32 base; /* SRAM byte address of event log header */ | 1568 | u32 base; /* SRAM byte address of event log header */ |
@@ -1571,7 +1572,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1571 | unsigned long reg_flags; | 1572 | unsigned long reg_flags; |
1572 | 1573 | ||
1573 | if (num_events == 0) | 1574 | if (num_events == 0) |
1574 | return; | 1575 | return pos; |
1575 | 1576 | ||
1576 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | 1577 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); |
1577 | 1578 | ||
@@ -1597,26 +1598,43 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1597 | time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 1598 | time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1598 | if (mode == 0) { | 1599 | if (mode == 0) { |
1599 | /* data, ev */ | 1600 | /* data, ev */ |
1600 | IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); | 1601 | if (bufsz) { |
1601 | trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); | 1602 | pos += scnprintf(*buf + pos, bufsz - pos, |
1603 | "0x%08x:%04u\n", | ||
1604 | time, ev); | ||
1605 | } else { | ||
1606 | IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); | ||
1607 | trace_iwlwifi_dev_ucode_event(priv, 0, | ||
1608 | time, ev); | ||
1609 | } | ||
1602 | } else { | 1610 | } else { |
1603 | data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 1611 | data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1604 | IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev); | 1612 | if (bufsz) { |
1605 | trace_iwlwifi_dev_ucode_event(priv, time, data, ev); | 1613 | pos += scnprintf(*buf + pos, bufsz - pos, |
1614 | "%010u:0x%08x:%04u\n", | ||
1615 | time, data, ev); | ||
1616 | } else { | ||
1617 | IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", | ||
1618 | time, data, ev); | ||
1619 | trace_iwlwifi_dev_ucode_event(priv, time, | ||
1620 | data, ev); | ||
1621 | } | ||
1606 | } | 1622 | } |
1607 | } | 1623 | } |
1608 | 1624 | ||
1609 | /* Allow device to power down */ | 1625 | /* Allow device to power down */ |
1610 | iwl_release_nic_access(priv); | 1626 | iwl_release_nic_access(priv); |
1611 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); | 1627 | spin_unlock_irqrestore(&priv->reg_lock, reg_flags); |
1628 | return pos; | ||
1612 | } | 1629 | } |
1613 | 1630 | ||
1614 | /** | 1631 | /** |
1615 | * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog | 1632 | * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog |
1616 | */ | 1633 | */ |
1617 | static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | 1634 | static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, |
1618 | u32 num_wraps, u32 next_entry, | 1635 | u32 num_wraps, u32 next_entry, |
1619 | u32 size, u32 mode) | 1636 | u32 size, u32 mode, |
1637 | int pos, char **buf, size_t bufsz) | ||
1620 | { | 1638 | { |
1621 | /* | 1639 | /* |
1622 | * display the newest DEFAULT_LOG_ENTRIES entries | 1640 | * display the newest DEFAULT_LOG_ENTRIES entries |
@@ -1624,21 +1642,28 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | |||
1624 | */ | 1642 | */ |
1625 | if (num_wraps) { | 1643 | if (num_wraps) { |
1626 | if (next_entry < size) { | 1644 | if (next_entry < size) { |
1627 | iwl3945_print_event_log(priv, | 1645 | pos = iwl3945_print_event_log(priv, |
1628 | capacity - (size - next_entry), | 1646 | capacity - (size - next_entry), |
1629 | size - next_entry, mode); | 1647 | size - next_entry, mode, |
1630 | iwl3945_print_event_log(priv, 0, | 1648 | pos, buf, bufsz); |
1631 | next_entry, mode); | 1649 | pos = iwl3945_print_event_log(priv, 0, |
1650 | next_entry, mode, | ||
1651 | pos, buf, bufsz); | ||
1632 | } else | 1652 | } else |
1633 | iwl3945_print_event_log(priv, next_entry - size, | 1653 | pos = iwl3945_print_event_log(priv, next_entry - size, |
1634 | size, mode); | 1654 | size, mode, |
1655 | pos, buf, bufsz); | ||
1635 | } else { | 1656 | } else { |
1636 | if (next_entry < size) | 1657 | if (next_entry < size) |
1637 | iwl3945_print_event_log(priv, 0, next_entry, mode); | 1658 | pos = iwl3945_print_event_log(priv, 0, |
1659 | next_entry, mode, | ||
1660 | pos, buf, bufsz); | ||
1638 | else | 1661 | else |
1639 | iwl3945_print_event_log(priv, next_entry - size, | 1662 | pos = iwl3945_print_event_log(priv, next_entry - size, |
1640 | size, mode); | 1663 | size, mode, |
1664 | pos, buf, bufsz); | ||
1641 | } | 1665 | } |
1666 | return pos; | ||
1642 | } | 1667 | } |
1643 | 1668 | ||
1644 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ | 1669 | /* For sanity check only. Actual size is determined by uCode, typ. 512 */ |
@@ -1646,7 +1671,8 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, | |||
1646 | 1671 | ||
1647 | #define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) | 1672 | #define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) |
1648 | 1673 | ||
1649 | void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | 1674 | int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, |
1675 | char **buf, bool display) | ||
1650 | { | 1676 | { |
1651 | u32 base; /* SRAM byte address of event log header */ | 1677 | u32 base; /* SRAM byte address of event log header */ |
1652 | u32 capacity; /* event log capacity in # entries */ | 1678 | u32 capacity; /* event log capacity in # entries */ |
@@ -1654,11 +1680,13 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1654 | u32 num_wraps; /* # times uCode wrapped to top of log */ | 1680 | u32 num_wraps; /* # times uCode wrapped to top of log */ |
1655 | u32 next_entry; /* index of next entry to be written by uCode */ | 1681 | u32 next_entry; /* index of next entry to be written by uCode */ |
1656 | u32 size; /* # entries that we'll print */ | 1682 | u32 size; /* # entries that we'll print */ |
1683 | int pos = 0; | ||
1684 | size_t bufsz = 0; | ||
1657 | 1685 | ||
1658 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | 1686 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); |
1659 | if (!iwl3945_hw_valid_rtc_data_addr(base)) { | 1687 | if (!iwl3945_hw_valid_rtc_data_addr(base)) { |
1660 | IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); | 1688 | IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); |
1661 | return; | 1689 | return pos; |
1662 | } | 1690 | } |
1663 | 1691 | ||
1664 | /* event log header */ | 1692 | /* event log header */ |
@@ -1684,7 +1712,7 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1684 | /* bail out if nothing in log */ | 1712 | /* bail out if nothing in log */ |
1685 | if (size == 0) { | 1713 | if (size == 0) { |
1686 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); | 1714 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); |
1687 | return; | 1715 | return pos; |
1688 | } | 1716 | } |
1689 | 1717 | ||
1690 | #ifdef CONFIG_IWLWIFI_DEBUG | 1718 | #ifdef CONFIG_IWLWIFI_DEBUG |
@@ -1700,25 +1728,38 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) | |||
1700 | size); | 1728 | size); |
1701 | 1729 | ||
1702 | #ifdef CONFIG_IWLWIFI_DEBUG | 1730 | #ifdef CONFIG_IWLWIFI_DEBUG |
1731 | if (display) { | ||
1732 | if (full_log) | ||
1733 | bufsz = capacity * 48; | ||
1734 | else | ||
1735 | bufsz = size * 48; | ||
1736 | *buf = kmalloc(bufsz, GFP_KERNEL); | ||
1737 | if (!*buf) | ||
1738 | return pos; | ||
1739 | } | ||
1703 | if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { | 1740 | if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { |
1704 | /* if uCode has wrapped back to top of log, | 1741 | /* if uCode has wrapped back to top of log, |
1705 | * start at the oldest entry, | 1742 | * start at the oldest entry, |
1706 | * i.e the next one that uCode would fill. | 1743 | * i.e the next one that uCode would fill. |
1707 | */ | 1744 | */ |
1708 | if (num_wraps) | 1745 | if (num_wraps) |
1709 | iwl3945_print_event_log(priv, next_entry, | 1746 | pos = iwl3945_print_event_log(priv, next_entry, |
1710 | capacity - next_entry, mode); | 1747 | capacity - next_entry, mode, |
1748 | pos, buf, bufsz); | ||
1711 | 1749 | ||
1712 | /* (then/else) start at top of log */ | 1750 | /* (then/else) start at top of log */ |
1713 | iwl3945_print_event_log(priv, 0, next_entry, mode); | 1751 | pos = iwl3945_print_event_log(priv, 0, next_entry, mode, |
1752 | pos, buf, bufsz); | ||
1714 | } else | 1753 | } else |
1715 | iwl3945_print_last_event_logs(priv, capacity, num_wraps, | 1754 | pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, |
1716 | next_entry, size, mode); | 1755 | next_entry, size, mode, |
1756 | pos, buf, bufsz); | ||
1717 | #else | 1757 | #else |
1718 | iwl3945_print_last_event_logs(priv, capacity, num_wraps, | 1758 | pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, |
1719 | next_entry, size, mode); | 1759 | next_entry, size, mode, |
1760 | pos, buf, bufsz); | ||
1720 | #endif | 1761 | #endif |
1721 | 1762 | return pos; | |
1722 | } | 1763 | } |
1723 | 1764 | ||
1724 | static void iwl3945_irq_tasklet(struct iwl_priv *priv) | 1765 | static void iwl3945_irq_tasklet(struct iwl_priv *priv) |