/** * iwl_print_last_event_logs - Dump the newest # of event log to syslog */ static int iwl_print_last_event_logs(struct iwl_trans *trans, u32 capacity, u32 num_wraps, u32 next_entry, u32 size, u32 mode, int pos, char **buf, size_t bufsz) { /* * 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) { pos = iwl_print_event_log(trans, capacity - (size - next_entry), size - next_entry, mode, pos, buf, bufsz); pos = iwl_print_event_log(trans, 0, next_entry, mode, pos, buf, bufsz); } else pos = iwl_print_event_log(trans, next_entry - size, size, mode, pos, buf, bufsz); } else { if (next_entry < size) { pos = iwl_print_event_log(trans, 0, next_entry, mode, pos, buf, bufsz); } else { pos = iwl_print_event_log(trans, next_entry - size, size, mode, pos, buf, bufsz); } } return pos; }
static int iwl_print_last_event_logs(struct iwl_trans *trans, u32 capacity, u32 num_wraps, u32 next_entry, u32 size, u32 mode, int pos, char **buf, size_t bufsz) { /* */ if (num_wraps) { if (next_entry < size) { pos = iwl_print_event_log(trans, capacity - (size - next_entry), size - next_entry, mode, pos, buf, bufsz); pos = iwl_print_event_log(trans, 0, next_entry, mode, pos, buf, bufsz); } else pos = iwl_print_event_log(trans, next_entry - size, size, mode, pos, buf, bufsz); } else { if (next_entry < size) { pos = iwl_print_event_log(trans, 0, next_entry, mode, pos, buf, bufsz); } else { pos = iwl_print_event_log(trans, next_entry - size, size, mode, pos, buf, bufsz); } } return pos; }
void iwl_dump_nic_event_log(struct iwl_priv *priv) { int ret; u32 base; /* SRAM byte address of event log header */ u32 capacity; /* event log capacity in # entries */ u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ u32 num_wraps; /* # times uCode wrapped to top of log */ u32 next_entry; /* index of next entry to be written by uCode */ u32 size; /* # entries that we'll print */ if (priv->ucode_type == UCODE_INIT) base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); else base = le32_to_cpu(priv->card_alive.log_event_table_ptr); if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { IWL_ERROR("Invalid event log pointer 0x%08X\n", base); return; } ret = iwl_grab_nic_access(priv); if (ret) { IWL_WARNING("Can not read from adapter at this time.\n"); return; } /* event log header */ capacity = iwl_read_targ_mem(priv, base); mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32))); num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); size = num_wraps ? capacity : next_entry; /* bail out if nothing in log */ if (size == 0) { IWL_ERROR("Start IWL Event Log Dump: nothing in log\n"); iwl_release_nic_access(priv); return; } IWL_ERROR("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); iwl_release_nic_access(priv); }
int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, char **buf, bool display) { u32 base; /* SRAM byte address of event log header */ u32 capacity; /* event log capacity in # entries */ u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ u32 num_wraps; /* # times uCode wrapped to top of log */ u32 next_entry; /* index of next entry to be written by uCode */ u32 size; /* # entries that we'll print */ u32 logsize; int pos = 0; size_t bufsz = 0; struct iwl_priv *priv = priv(trans); base = priv->device_pointers.log_event_table; if (priv->ucode_type == IWL_UCODE_INIT) { logsize = priv->init_evtlog_size; if (!base) base = priv->init_evtlog_ptr; } else { logsize = priv->inst_evtlog_size; if (!base) base = priv->inst_evtlog_ptr; } if (!iwlagn_hw_valid_rtc_data_addr(base)) { IWL_ERR(trans, "Invalid event log pointer 0x%08X for %s uCode\n", base, (priv->ucode_type == IWL_UCODE_INIT) ? "Init" : "RT"); return -EINVAL; } /* event log header */ capacity = iwl_read_targ_mem(bus(trans), base); mode = iwl_read_targ_mem(bus(trans), base + (1 * sizeof(u32))); num_wraps = iwl_read_targ_mem(bus(trans), base + (2 * sizeof(u32))); next_entry = iwl_read_targ_mem(bus(trans), base + (3 * sizeof(u32))); if (capacity > logsize) { IWL_ERR(trans, "Log capacity %d is bogus, limit to %d " "entries\n", capacity, logsize); capacity = logsize; } if (next_entry > logsize) { IWL_ERR(trans, "Log write index %d is bogus, limit to %d\n", next_entry, logsize); next_entry = logsize; } size = num_wraps ? capacity : next_entry; /* bail out if nothing in log */ if (size == 0) { IWL_ERR(trans, "Start IWL Event Log Dump: nothing in log\n"); return pos; } #ifdef CONFIG_IWLWIFI_DEBUG if (!(iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) && !full_log) 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(trans, "Start IWL Event Log Dump: display last %u entries\n", size); #ifdef CONFIG_IWLWIFI_DEBUG if (display) { if (full_log) bufsz = capacity * 48; else bufsz = size * 48; *buf = kmalloc(bufsz, GFP_KERNEL); if (!*buf) return -ENOMEM; } if ((iwl_get_debug_level(trans->shrd) & 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) pos = iwl_print_event_log(trans, next_entry, capacity - next_entry, mode, pos, buf, bufsz); /* (then/else) start at top of log */ pos = iwl_print_event_log(trans, 0, next_entry, mode, pos, buf, bufsz); } else pos = iwl_print_last_event_logs(trans, capacity, num_wraps, next_entry, size, mode, pos, buf, bufsz); #else pos = iwl_print_last_event_logs(trans, capacity, num_wraps, next_entry, size, mode, pos, buf, bufsz); #endif return pos; }
int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, char **buf, bool display) { u32 base; /* */ u32 capacity; /* */ u32 mode; /* */ u32 num_wraps; /* */ u32 next_entry; /* */ u32 size; /* */ u32 logsize; int pos = 0; size_t bufsz = 0; base = trans->shrd->device_pointers.log_event_table; if (trans->shrd->ucode_type == IWL_UCODE_INIT) { logsize = trans->shrd->fw->init_evtlog_size; if (!base) base = trans->shrd->fw->init_evtlog_ptr; } else { logsize = trans->shrd->fw->inst_evtlog_size; if (!base) base = trans->shrd->fw->inst_evtlog_ptr; } if (!iwlagn_hw_valid_rtc_data_addr(base)) { IWL_ERR(trans, "Invalid event log pointer 0x%08X for %s uCode\n", base, (trans->shrd->ucode_type == IWL_UCODE_INIT) ? "Init" : "RT"); return -EINVAL; } /* */ capacity = iwl_read_targ_mem(trans, base); mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32))); num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32))); next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32))); if (capacity > logsize) { IWL_ERR(trans, "Log capacity %d is bogus, limit to %d " "entries\n", capacity, logsize); capacity = logsize; } if (next_entry > logsize) { IWL_ERR(trans, "Log write index %d is bogus, limit to %d\n", next_entry, logsize); next_entry = logsize; } size = num_wraps ? capacity : next_entry; /* */ if (size == 0) { IWL_ERR(trans, "Start IWL Event Log Dump: nothing in log\n"); return pos; } #ifdef CONFIG_IWLWIFI_DEBUG if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log) 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(trans, "Start IWL Event Log Dump: display last %u entries\n", size); #ifdef CONFIG_IWLWIFI_DEBUG if (display) { if (full_log) bufsz = capacity * 48; else bufsz = size * 48; *buf = kmalloc(bufsz, GFP_KERNEL); if (!*buf) return -ENOMEM; } if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) { /* */ if (num_wraps) pos = iwl_print_event_log(trans, next_entry, capacity - next_entry, mode, pos, buf, bufsz); /* */ pos = iwl_print_event_log(trans, 0, next_entry, mode, pos, buf, bufsz); } else pos = iwl_print_last_event_logs(trans, capacity, num_wraps, next_entry, size, mode, pos, buf, bufsz); #else pos = iwl_print_last_event_logs(trans, capacity, num_wraps, next_entry, size, mode, pos, buf, bufsz); #endif return pos; }