diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index a41f0e098cf6..ecc23ec1f6a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -227,7 +227,7 @@ extern void iwl3945_rx_replenish(void *data); extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, struct ieee80211_hdr *hdr,int left); -extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv); +extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log); extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); /* diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 927131192572..9b04b25f0e57 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1696,8 +1696,6 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) } -#ifdef CONFIG_IWLWIFI_DEBUG - #define EVENT_START_OFFSET (4 * sizeof(u32)) /** @@ -1758,10 +1756,42 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, spin_unlock_irqrestore(&priv->reg_lock, reg_flags); } +/** + * iwl_print_last_event_logs - Dump the newest # of event log to syslog + */ +static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, + u32 num_wraps, u32 next_entry, + u32 size, u32 mode) +{ + /* + * display the newest DEFAULT_LOG_ENTRIES entries + * i.e the entries just before the next ont that uCode would fill. + */ + if (num_wraps) { + if (next_entry < size) { + iwl_print_event_log(priv, + capacity - (size - next_entry), + size - next_entry, mode); + iwl_print_event_log(priv, 0, + next_entry, mode); + } else + iwl_print_event_log(priv, next_entry - size, + size, mode); + } else { + if (next_entry < size) + iwl_print_event_log(priv, 0, next_entry, mode); + else + iwl_print_event_log(priv, next_entry - size, + size, mode); + } +} + /* For sanity check only. Actual size is determined by uCode, typ. 512 */ #define MAX_EVENT_LOG_SIZE (512) -void iwl_dump_nic_event_log(struct iwl_priv *priv) +#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) + +void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) { u32 base; /* SRAM byte address of event log header */ u32 capacity; /* event log capacity in # entries */ @@ -1806,19 +1836,37 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv) return; } - IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n", - size, num_wraps); - - /* if uCode has wrapped back to top of log, start at the oldest entry, - * i.e the next one that uCode would fill. */ - if (num_wraps) - iwl_print_event_log(priv, next_entry, - capacity - next_entry, mode); - /* (then/else) start at top of log */ - iwl_print_event_log(priv, 0, next_entry, mode); - -} +#ifdef CONFIG_IWLWIFI_DEBUG + if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)) + size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; +#else + size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; #endif + IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n", + size); + +#ifdef CONFIG_IWLWIFI_DEBUG + if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { + /* + * if uCode has wrapped back to top of log, + * start at the oldest entry, + * i.e the next one that uCode would fill. + */ + if (num_wraps) + iwl_print_event_log(priv, next_entry, + capacity - next_entry, mode); + /* (then/else) start at top of log */ + iwl_print_event_log(priv, 0, next_entry, mode); + } else + iwl_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode); +#else + iwl_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode); +#endif +} /** * iwl_alive_start - called after REPLY_ALIVE notification received diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 2e0fb2804ad0..3629aea250ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1362,11 +1362,10 @@ void iwl_irq_handle_error(struct iwl_priv *priv) clear_bit(STATUS_HCMD_ACTIVE, &priv->status); priv->cfg->ops->lib->dump_nic_error_log(priv); + priv->cfg->ops->lib->dump_nic_event_log(priv, false); #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) { - priv->cfg->ops->lib->dump_nic_event_log(priv); + if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) iwl_print_rx_config_cmd(priv); - } #endif wake_up_interruptible(&priv->wait_command_queue); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index ecba0f46bac5..cf7d3df0744e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -167,7 +167,7 @@ struct iwl_lib_ops { int (*is_valid_rtc_data_addr)(u32 addr); /* 1st ucode load */ int (*load_ucode)(struct iwl_priv *priv); - void (*dump_nic_event_log)(struct iwl_priv *priv); + void (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log); void (*dump_nic_error_log)(struct iwl_priv *priv); int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); /* power management */ @@ -579,14 +579,10 @@ int iwl_pci_resume(struct pci_dev *pdev); * Error Handling Debugging ******************************************************/ void iwl_dump_nic_error_log(struct iwl_priv *priv); +void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log); #ifdef CONFIG_IWLWIFI_DEBUG -void iwl_dump_nic_event_log(struct iwl_priv *priv); void iwl_print_rx_config_cmd(struct iwl_priv *priv); #else -static inline void iwl_dump_nic_event_log(struct iwl_priv *priv) -{ -} - static inline 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 5adf0b606202..21e0f6699daf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -436,7 +436,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, if (sscanf(buf, "%d", &event_log_flag) != 1) return -EFAULT; if (event_log_flag == 1) - priv->cfg->ops->lib->dump_nic_event_log(priv); + priv->cfg->ops->lib->dump_nic_event_log(priv, true); return count; } diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 5b7e80e5bab4..5e3c35314ffe 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1482,7 +1482,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv) tasklet_kill(&priv->irq_tasklet); } -#ifdef CONFIG_IWLWIFI_DEBUG static const char *desc_lookup(int i) { switch (i) { @@ -1613,10 +1612,42 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, spin_unlock_irqrestore(&priv->reg_lock, reg_flags); } +/** + * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog + */ +static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, + u32 num_wraps, u32 next_entry, + u32 size, u32 mode) +{ + /* + * display the newest DEFAULT_LOG_ENTRIES entries + * i.e the entries just before the next ont that uCode would fill. + */ + if (num_wraps) { + if (next_entry < size) { + iwl3945_print_event_log(priv, + capacity - (size - next_entry), + size - next_entry, mode); + iwl3945_print_event_log(priv, 0, + next_entry, mode); + } else + iwl3945_print_event_log(priv, next_entry - size, + size, mode); + } else { + if (next_entry < size) + iwl3945_print_event_log(priv, 0, next_entry, mode); + else + iwl3945_print_event_log(priv, next_entry - size, + size, mode); + } +} + /* For sanity check only. Actual size is determined by uCode, typ. 512 */ #define IWL3945_MAX_EVENT_LOG_SIZE (512) -void iwl3945_dump_nic_event_log(struct iwl_priv *priv) +#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) + +void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) { u32 base; /* SRAM byte address of event log header */ u32 capacity; /* event log capacity in # entries */ @@ -1657,8 +1688,17 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv) return; } - IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n", - size, num_wraps); +#ifdef CONFIG_IWLWIFI_DEBUG + if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)) + size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; +#else + size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; +#endif + + IWL_ERR(priv, "Start IWL Event Log Dump: display last %d count\n", + size); /* if uCode has wrapped back to top of log, start at the oldest entry, * i.e the next one that uCode would fill. */ @@ -1669,18 +1709,28 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv) /* (then/else) start at top of log */ iwl3945_print_event_log(priv, 0, next_entry, mode); -} +#ifdef CONFIG_IWLWIFI_DEBUG + if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { + /* if uCode has wrapped back to top of log, + * start at the oldest entry, + * i.e the next one that uCode would fill. + */ + if (num_wraps) + iwl3945_print_event_log(priv, next_entry, + capacity - next_entry, mode); + + /* (then/else) start at top of log */ + iwl3945_print_event_log(priv, 0, next_entry, mode); + } else + iwl3945_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode); #else -void iwl3945_dump_nic_event_log(struct iwl_priv *priv) -{ -} - -void iwl3945_dump_nic_error_log(struct iwl_priv *priv) -{ -} - + iwl3945_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode); #endif +} + static void iwl3945_irq_tasklet(struct iwl_priv *priv) { u32 inta, handled = 0;