forked from Minki/linux
iwlwifi: print limited number of event log when uCode error
To help iwlagn uCode debugging, event log will dump to syslog when driver detect uCode error occurred, but this only happen when compile with CONFIG_IWLWIFI_DEBUG and debug flag is enabled; which is not always the case. Also, there is another problem, if the flag is set, the entire event log buffer will be dump to syslog, it can flood the syslog and make it very difficult to debug the problem. Change the default to only dump last 20 entries of event log to syslog unless the following condition meets: 1. both compile with CONFIG_IWLWIFI_DEBUG and debug flag is enabled, and then dump the entire event buffer to syslog. 2. dump event log request from debugfs Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Acked-by: Ben Cahill <ben.m.cahill@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
644c77f0cf
commit
c341ddb283
@ -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 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,
|
extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
|
||||||
struct ieee80211_hdr *hdr,int left);
|
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);
|
extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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))
|
#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);
|
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 */
|
/* For sanity check only. Actual size is determined by uCode, typ. 512 */
|
||||||
#define MAX_EVENT_LOG_SIZE (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 base; /* SRAM byte address of event log header */
|
||||||
u32 capacity; /* event log capacity in # entries */
|
u32 capacity; /* event log capacity in # entries */
|
||||||
@ -1806,19 +1836,37 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
|
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||||
size, num_wraps);
|
if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS))
|
||||||
|
size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
|
||||||
/* if uCode has wrapped back to top of log, start at the oldest entry,
|
? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
|
||||||
* i.e the next one that uCode would fill. */
|
#else
|
||||||
if (num_wraps)
|
size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
|
||||||
iwl_print_event_log(priv, next_entry,
|
? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
|
||||||
capacity - next_entry, mode);
|
|
||||||
/* (then/else) start at top of log */
|
|
||||||
iwl_print_event_log(priv, 0, next_entry, mode);
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
#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
|
* iwl_alive_start - called after REPLY_ALIVE notification received
|
||||||
|
@ -1362,11 +1362,10 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
|
|||||||
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
|
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
|
||||||
|
|
||||||
priv->cfg->ops->lib->dump_nic_error_log(priv);
|
priv->cfg->ops->lib->dump_nic_error_log(priv);
|
||||||
|
priv->cfg->ops->lib->dump_nic_event_log(priv, false);
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||||
if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) {
|
if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
|
||||||
priv->cfg->ops->lib->dump_nic_event_log(priv);
|
|
||||||
iwl_print_rx_config_cmd(priv);
|
iwl_print_rx_config_cmd(priv);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wake_up_interruptible(&priv->wait_command_queue);
|
wake_up_interruptible(&priv->wait_command_queue);
|
||||||
|
@ -167,7 +167,7 @@ struct iwl_lib_ops {
|
|||||||
int (*is_valid_rtc_data_addr)(u32 addr);
|
int (*is_valid_rtc_data_addr)(u32 addr);
|
||||||
/* 1st ucode load */
|
/* 1st ucode load */
|
||||||
int (*load_ucode)(struct iwl_priv *priv);
|
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);
|
void (*dump_nic_error_log)(struct iwl_priv *priv);
|
||||||
int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
|
int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
|
||||||
/* power management */
|
/* power management */
|
||||||
@ -579,14 +579,10 @@ int iwl_pci_resume(struct pci_dev *pdev);
|
|||||||
* Error Handling Debugging
|
* Error Handling Debugging
|
||||||
******************************************************/
|
******************************************************/
|
||||||
void iwl_dump_nic_error_log(struct iwl_priv *priv);
|
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
|
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||||
void iwl_dump_nic_event_log(struct iwl_priv *priv);
|
|
||||||
void iwl_print_rx_config_cmd(struct iwl_priv *priv);
|
void iwl_print_rx_config_cmd(struct iwl_priv *priv);
|
||||||
#else
|
#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)
|
static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -436,7 +436,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
|
|||||||
if (sscanf(buf, "%d", &event_log_flag) != 1)
|
if (sscanf(buf, "%d", &event_log_flag) != 1)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (event_log_flag == 1)
|
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;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -1482,7 +1482,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
|
|||||||
tasklet_kill(&priv->irq_tasklet);
|
tasklet_kill(&priv->irq_tasklet);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
|
||||||
static const char *desc_lookup(int i)
|
static const char *desc_lookup(int i)
|
||||||
{
|
{
|
||||||
switch (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);
|
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 */
|
/* For sanity check only. Actual size is determined by uCode, typ. 512 */
|
||||||
#define IWL3945_MAX_EVENT_LOG_SIZE (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 base; /* SRAM byte address of event log header */
|
||||||
u32 capacity; /* event log capacity in # entries */
|
u32 capacity; /* event log capacity in # entries */
|
||||||
@ -1657,8 +1688,17 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
|
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||||
size, num_wraps);
|
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,
|
/* if uCode has wrapped back to top of log, start at the oldest entry,
|
||||||
* i.e the next one that uCode would fill. */
|
* 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 */
|
/* (then/else) start at top of log */
|
||||||
iwl3945_print_event_log(priv, 0, next_entry, mode);
|
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
|
#else
|
||||||
void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
|
iwl3945_print_last_event_logs(priv, capacity, num_wraps,
|
||||||
{
|
next_entry, size, mode);
|
||||||
}
|
|
||||||
|
|
||||||
void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void iwl3945_irq_tasklet(struct iwl_priv *priv)
|
static void iwl3945_irq_tasklet(struct iwl_priv *priv)
|
||||||
{
|
{
|
||||||
u32 inta, handled = 0;
|
u32 inta, handled = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user