Esempio n. 1
0
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);
}
Esempio n. 2
0
/*
 * toggle the bit to wake up uCode and check the temperature
 * if the temperature is below CT, uCode will stay awake and send card
 * state notification with CT_KILL bit clear to inform Thermal Throttling
 * Management to change state. Otherwise, uCode will go back to sleep
 * without doing anything, driver should continue the 5 seconds timer
 * to wake up uCode for temperature check until temperature drop below CT
 */
static void iwl_tt_check_exit_ct_kill(unsigned long data)
{
	struct iwl_priv *priv = (struct iwl_priv *)data;
	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
	unsigned long flags;

	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

	if (tt->state == IWL_TI_CT_KILL) {
		if (priv->thermal_throttle.ct_kill_toggle) {
			iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
				    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
			priv->thermal_throttle.ct_kill_toggle = false;
		} else {
			iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
				    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
			priv->thermal_throttle.ct_kill_toggle = true;
		}
		iwl_read32(priv, CSR_UCODE_DRV_GP1);
		spin_lock_irqsave(&priv->reg_lock, flags);
		if (!iwl_grab_nic_access(priv))
			iwl_release_nic_access(priv);
		spin_unlock_irqrestore(&priv->reg_lock, flags);

		/* Reschedule the ct_kill timer to occur in
		 * CT_KILL_EXIT_DURATION seconds to ensure we get a
		 * thermal update */
		IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n");
		mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, /*jiffies +*/
			  CT_KILL_EXIT_DURATION * HZ);
	}
}
Esempio n. 3
0
void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask)
{
    unsigned long flags;

    spin_lock_irqsave(&bus->reg_lock, flags);
    iwl_grab_nic_access(bus);
    __iwl_write_prph(bus, reg, __iwl_read_prph(bus, reg) | mask);
    iwl_release_nic_access(bus);
    spin_unlock_irqrestore(&bus->reg_lock, flags);
}
Esempio n. 4
0
void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val)
{
    unsigned long flags;

    spin_lock_irqsave(&bus->reg_lock, flags);
    if (!iwl_grab_nic_access(bus)) {
        __iwl_write_prph(bus, addr, val);
        iwl_release_nic_access(bus);
    }
    spin_unlock_irqrestore(&bus->reg_lock, flags);
}
Esempio n. 5
0
void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val)
{
	unsigned long flags;

	spin_lock_irqsave(&trans->reg_lock, flags);
	if (likely(iwl_grab_nic_access(trans))) {
		__iwl_write_prph(trans, addr, val);
		iwl_release_nic_access(trans);
	}
	spin_unlock_irqrestore(&trans->reg_lock, flags);
}
Esempio n. 6
0
void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value)
{
    unsigned long flags;

    spin_lock_irqsave(&bus->reg_lock, flags);
    if (!iwl_grab_nic_access(bus)) {
        iwl_write32(bus, reg, value);
        iwl_release_nic_access(bus);
    }
    spin_unlock_irqrestore(&bus->reg_lock, flags);
}
Esempio n. 7
0
void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
{
	unsigned long flags;

	spin_lock_irqsave(&trans->reg_lock, flags);
	if (likely(iwl_grab_nic_access(trans))) {
		iwl_write32(trans, reg, value);
		iwl_release_nic_access(trans);
	}
	spin_unlock_irqrestore(&trans->reg_lock, flags);
}
Esempio n. 8
0
void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask)
{
	unsigned long flags;

	spin_lock_irqsave(&trans->reg_lock, flags);
	if (likely(iwl_grab_nic_access(trans))) {
		__iwl_write_prph(trans, reg,
				 __iwl_read_prph(trans, reg) | mask);
		iwl_release_nic_access(trans);
	}
	spin_unlock_irqrestore(&trans->reg_lock, flags);
}
Esempio n. 9
0
u32 iwl_read_prph(struct iwl_bus *bus, u32 reg)
{
    unsigned long flags;
    u32 val;

    spin_lock_irqsave(&bus->reg_lock, flags);
    iwl_grab_nic_access(bus);
    val = __iwl_read_prph(bus, reg);
    iwl_release_nic_access(bus);
    spin_unlock_irqrestore(&bus->reg_lock, flags);
    return val;
}
Esempio n. 10
0
void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask)
{
    unsigned long flags;
    u32 val;

    spin_lock_irqsave(&bus->reg_lock, flags);
    iwl_grab_nic_access(bus);
    val = __iwl_read_prph(bus, reg);
    __iwl_write_prph(bus, reg, (val & ~mask));
    iwl_release_nic_access(bus);
    spin_unlock_irqrestore(&bus->reg_lock, flags);
}
Esempio n. 11
0
void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask)
{
	unsigned long flags;
	u32 val;

	spin_lock_irqsave(&trans->reg_lock, flags);
	if (likely(iwl_grab_nic_access(trans))) {
		val = __iwl_read_prph(trans, reg);
		__iwl_write_prph(trans, reg, (val & ~mask));
		iwl_release_nic_access(trans);
	}
	spin_unlock_irqrestore(&trans->reg_lock, flags);
}
Esempio n. 12
0
void iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val)
{
	unsigned long flags;

	spin_lock_irqsave(&bus->reg_lock, flags);
	if (!iwl_grab_nic_access(bus)) {
		iwl_write32(bus, HBUS_TARG_MEM_WADDR, addr);
		wmb();
		iwl_write32(bus, HBUS_TARG_MEM_WDAT, val);
		iwl_release_nic_access(bus);
	}
	spin_unlock_irqrestore(&bus->reg_lock, flags);
}
Esempio n. 13
0
u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg)
{
    u32 value;
    unsigned long flags;

    spin_lock_irqsave(&bus->reg_lock, flags);
    iwl_grab_nic_access(bus);
    value = iwl_read32(bus, reg);
    iwl_release_nic_access(bus);
    spin_unlock_irqrestore(&bus->reg_lock, flags);

    return value;
}
Esempio n. 14
0
void iwl_dump_nic_error_log(struct iwl_priv *priv)
{
	u32 data2, line;
	u32 desc, time, count, base, data1;
	u32 blink1, blink2, ilink1, ilink2;
	int ret;

	if (priv->ucode_type == UCODE_INIT)
		base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
	else
		base = le32_to_cpu(priv->card_alive.error_event_table_ptr);

	if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
		IWL_ERROR("Not valid error 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;
	}

	count = iwl_read_targ_mem(priv, base);

	if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
		IWL_ERROR("Start IWL Error Log Dump:\n");
		IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
	}

	desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
	blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
	blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
	ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
	ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
	data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
	data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
	line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
	time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));

	IWL_ERROR("Desc        Time       "
		"data1      data2      line\n");
	IWL_ERROR("%-13s (#%d) %010u 0x%08X 0x%08X %u\n",
		desc_lookup(desc), desc, time, data1, data2, line);
	IWL_ERROR("blink1  blink2  ilink1  ilink2\n");
	IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
		ilink1, ilink2);

	iwl_release_nic_access(priv);
}
Esempio n. 15
0
int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
{
	u32 stat_flags = 0;
	struct iwl_host_cmd cmd = {
		.id = REPLY_STATISTICS_CMD,
		.meta.flags = flags,
		.len = sizeof(stat_flags),
		.data = (u8 *) &stat_flags,
	};
	return iwl_send_cmd(priv, &cmd);
}
EXPORT_SYMBOL(iwl_send_statistics_request);

/**
 * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
 *   using sample data 100 bytes apart.  If these sample points are good,
 *   it's a pretty good bet that everything between them is good, too.
 */
static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
{
	u32 val;
	int ret = 0;
	u32 errcnt = 0;
	u32 i;

	IWL_DEBUG_INFO("ucode inst image size is %u\n", len);

	ret = iwl_grab_nic_access(priv);
	if (ret)
		return ret;

	for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
		/* read data comes through single port, auto-incr addr */
		/* NOTE: Use the debugless read so we don't flood kernel log
		 * if IWL_DL_IO is set */
		iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
			i + RTC_INST_LOWER_BOUND);
		val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
		if (val != le32_to_cpu(*image)) {
			ret = -EIO;
			errcnt++;
			if (errcnt >= 3)
				break;
		}
	}

	iwl_release_nic_access(priv);

	return ret;
}
Esempio n. 16
0
void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
			       void *buf, int dwords)
{
	unsigned long flags;
	int offs;
	u32 *vals = buf;

	spin_lock_irqsave(&trans->reg_lock, flags);
	if (likely(iwl_grab_nic_access(trans))) {
		iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
		for (offs = 0; offs < dwords; offs++)
			vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
		iwl_release_nic_access(trans);
	}
	spin_unlock_irqrestore(&trans->reg_lock, flags);
}
Esempio n. 17
0
/* Tell nic where to find the "keep warm" buffer */
int iwl_kw_init(struct iwl_priv *priv)
{
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&priv->lock, flags);
	ret = iwl_grab_nic_access(priv);
	if (ret)
		goto out;

	iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG,
			     priv->kw.dma_addr >> 4);
	iwl_release_nic_access(priv);
out:
	spin_unlock_irqrestore(&priv->lock, flags);
	return ret;
}
Esempio n. 18
0
int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
{
	unsigned long flags;

	if (!test_bit(STATUS_RF_KILL_SW, &priv->status))
		return 0;

	IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO ON\n");

	spin_lock_irqsave(&priv->lock, flags);
	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);

	/* If the driver is up it will receive CARD_STATE_NOTIFICATION
	 * notification where it will clear SW rfkill status.
	 * Setting it here would break the handler. Only if the
	 * interface is down we can set here since we don't
	 * receive any further notification.
	 */
	if (!priv->is_open)
		clear_bit(STATUS_RF_KILL_SW, &priv->status);
	spin_unlock_irqrestore(&priv->lock, flags);

	/* wake up ucode */
	msleep(10);

	spin_lock_irqsave(&priv->lock, flags);
	iwl_read32(priv, CSR_UCODE_DRV_GP1);
	if (!iwl_grab_nic_access(priv))
		iwl_release_nic_access(priv);
	spin_unlock_irqrestore(&priv->lock, flags);

	if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
		IWL_DEBUG_RF_KILL("Can not turn radio back on - "
				  "disabled by HW switch\n");
		return 0;
	}

	/* If the driver is already loaded, it will receive
	 * CARD_STATE_NOTIFICATION notifications and the handler will
	 * call restart to reload the driver.
	 */
	return 1;
}
Esempio n. 19
0
int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
			       void *buf, int dwords)
{
	unsigned long flags;
	int offs, result = 0;
	u32 *vals = buf;

	spin_lock_irqsave(&trans->reg_lock, flags);
	if (likely(iwl_grab_nic_access(trans))) {
		iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
		for (offs = 0; offs < dwords; offs++)
			iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]);
		iwl_release_nic_access(trans);
	} else
		result = -EBUSY;
	spin_unlock_irqrestore(&trans->reg_lock, flags);

	return result;
}
Esempio n. 20
0
void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr,
                              void *buf, int words)
{
    unsigned long flags;
    int offs;
    u32 *vals = buf;

    spin_lock_irqsave(&bus->reg_lock, flags);
    iwl_grab_nic_access(bus);

    iwl_write32(bus, HBUS_TARG_MEM_RADDR, addr);
    rmb();

    for (offs = 0; offs < words; offs++)
        vals[offs] = iwl_read32(bus, HBUS_TARG_MEM_RDAT);

    iwl_release_nic_access(bus);
    spin_unlock_irqrestore(&bus->reg_lock, flags);
}
Esempio n. 21
0
/**
 * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host,
 *     looking at all data.
 */
static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
				 u32 len)
{
	u32 val;
	u32 save_len = len;
	int ret = 0;
	u32 errcnt;

	IWL_DEBUG_INFO("ucode inst image size is %u\n", len);

	ret = iwl_grab_nic_access(priv);
	if (ret)
		return ret;

	iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);

	errcnt = 0;
	for (; len > 0; len -= sizeof(u32), image++) {
		/* read data comes through single port, auto-incr addr */
		/* NOTE: Use the debugless read so we don't flood kernel log
		 * if IWL_DL_IO is set */
		val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
		if (val != le32_to_cpu(*image)) {
			IWL_ERROR("uCode INST section is invalid at "
				  "offset 0x%x, is 0x%x, s/b 0x%x\n",
				  save_len - len, val, le32_to_cpu(*image));
			ret = -EIO;
			errcnt++;
			if (errcnt >= 20)
				break;
		}
	}

	iwl_release_nic_access(priv);

	if (!errcnt)
		IWL_DEBUG_INFO
		    ("ucode image in INSTRUCTION memory is good\n");

	return ret;
}
Esempio n. 22
0
static ssize_t iwl_dbgfs_sram_read(struct file *file,
					char __user *user_buf,
					size_t count, loff_t *ppos)
{
	u32 val;
	char buf[1024];
	ssize_t ret;
	int i;
	int pos = 0;
	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
	const size_t bufsz = sizeof(buf);

	printk(KERN_DEBUG "offset is: 0x%x\tlen is: 0x%x\n",
	priv->dbgfs->sram_offset, priv->dbgfs->sram_len);

	iwl_grab_nic_access(priv);
	for (i = priv->dbgfs->sram_len; i > 0; i -= 4) {
		val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \
					priv->dbgfs->sram_len - i);
		if (i < 4) {
			switch (i) {
			case 1:
				val &= BYTE1_MASK;
				break;
			case 2:
				val &= BYTE2_MASK;
				break;
			case 3:
				val &= BYTE3_MASK;
				break;
			}
		}
		pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
	}
	pos += scnprintf(buf + pos, bufsz - pos, "\n");
	iwl_release_nic_access(priv);

	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
	return ret;
}
static int iwl_testmode_indirect_read(struct iwl_priv *priv, u32 addr, u32 size)
{
	struct iwl_trans *trans = trans(priv);
	unsigned long flags;
	int i;

	if (size & 0x3)
		return -EINVAL;
	priv->testmode_mem.buff_size = size;
	priv->testmode_mem.buff_addr =
		kmalloc(priv->testmode_mem.buff_size, GFP_KERNEL);
	if (priv->testmode_mem.buff_addr == NULL)
		return -ENOMEM;

	/* Hard-coded periphery absolute address */
	if (IWL_TM_ABS_PRPH_START <= addr &&
		addr < IWL_TM_ABS_PRPH_START + PRPH_END) {
			spin_lock_irqsave(&trans->reg_lock, flags);
			iwl_grab_nic_access(trans);
			iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
				addr | (3 << 24));
			for (i = 0; i < size; i += 4)
				*(u32 *)(priv->testmode_mem.buff_addr + i) =
					iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
			iwl_release_nic_access(trans);
			spin_unlock_irqrestore(&trans->reg_lock, flags);
	} else { /* target memory (SRAM) */
		_iwl_read_targ_mem_words(trans, addr,
			priv->testmode_mem.buff_addr,
			priv->testmode_mem.buff_size / 4);
	}

	priv->testmode_mem.num_chunks =
		DIV_ROUND_UP(priv->testmode_mem.buff_size, DUMP_CHUNK_SIZE);
	priv->testmode_mem.read_in_progress = true;
	return 0;

}
static int iwl_testmode_indirect_write(struct iwl_priv *priv, u32 addr,
	u32 size, unsigned char *buf)
{
	struct iwl_trans *trans = trans(priv);
	u32 val, i;
	unsigned long flags;

	if (IWL_TM_ABS_PRPH_START <= addr &&
		addr < IWL_TM_ABS_PRPH_START + PRPH_END) {
			/* Periphery writes can be 1-3 bytes long, or DWORDs */
			if (size < 4) {
				memcpy(&val, buf, size);
				spin_lock_irqsave(&trans->reg_lock, flags);
				iwl_grab_nic_access(trans);
				iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
					    (addr & 0x0000FFFF) |
					    ((size - 1) << 24));
				iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
				iwl_release_nic_access(trans);
				/* needed after consecutive writes w/o read */
				mmiowb();
				spin_unlock_irqrestore(&trans->reg_lock, flags);
			} else {
				if (size % 4)
					return -EINVAL;
				for (i = 0; i < size; i += 4)
					iwl_write_prph(trans, addr+i,
						*(u32 *)(buf+i));
			}
	} else if (iwlagn_hw_valid_rtc_data_addr(addr) ||
		(IWLAGN_RTC_INST_LOWER_BOUND <= addr &&
		addr < IWLAGN_RTC_INST_UPPER_BOUND)) {
			_iwl_write_targ_mem_words(trans, addr, buf, size/4);
	} else
		return -EINVAL;
	return 0;
}
/**
 * iwl_print_event_log - Dump error event log to syslog
 *
 */
static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
			       u32 num_events, u32 mode,
			       int pos, char **buf, size_t bufsz)
{
	u32 i;
	u32 base;       /* SRAM byte address of event log header */
	u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
	u32 ptr;        /* SRAM byte address of log data */
	u32 ev, time, data; /* event log data */
	unsigned long reg_flags;
	struct iwl_priv *priv = priv(trans);

	if (num_events == 0)
		return pos;

	base = priv->device_pointers.log_event_table;
	if (priv->ucode_type == IWL_UCODE_INIT) {
		if (!base)
			base = priv->init_evtlog_ptr;
	} else {
		if (!base)
			base = priv->inst_evtlog_ptr;
	}

	if (mode == 0)
		event_size = 2 * sizeof(u32);
	else
		event_size = 3 * sizeof(u32);

	ptr = base + EVENT_START_OFFSET + (start_idx * event_size);

	/* Make sure device is powered up for SRAM reads */
	spin_lock_irqsave(&bus(trans)->reg_lock, reg_flags);
	iwl_grab_nic_access(bus(trans));

	/* Set starting address; reads will auto-increment */
	iwl_write32(bus(trans), HBUS_TARG_MEM_RADDR, ptr);
	rmb();

	/* "time" is actually "data" for mode 0 (no timestamp).
	* place event id # at far right for easier visual parsing. */
	for (i = 0; i < num_events; i++) {
		ev = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
		time = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
		if (mode == 0) {
			/* data, ev */
			if (bufsz) {
				pos += scnprintf(*buf + pos, bufsz - pos,
						"EVT_LOG:0x%08x:%04u\n",
						time, ev);
			} else {
				trace_iwlwifi_dev_ucode_event(priv, 0,
					time, ev);
				IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n",
					time, ev);
			}
		} else {
			data = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
			if (bufsz) {
				pos += scnprintf(*buf + pos, bufsz - pos,
						"EVT_LOGT:%010u:0x%08x:%04u\n",
						 time, data, ev);
			} else {
				IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n",
					time, data, ev);
				trace_iwlwifi_dev_ucode_event(priv, time,
					data, ev);
			}
		}
	}

	/* Allow device to power down */
	iwl_release_nic_access(bus(trans));
	spin_unlock_irqrestore(&bus(trans)->reg_lock, reg_flags);
	return pos;
}
static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
			       u32 num_events, u32 mode,
			       int pos, char **buf, size_t bufsz)
{
	u32 i;
	u32 base;       /*                                       */
	u32 event_size; /*                                         */
	u32 ptr;        /*                               */
	u32 ev, time, data; /*                */
	unsigned long reg_flags;

	if (num_events == 0)
		return pos;

	base = trans->shrd->device_pointers.log_event_table;
	if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
		if (!base)
			base = trans->shrd->fw->init_evtlog_ptr;
	} else {
		if (!base)
			base = trans->shrd->fw->inst_evtlog_ptr;
	}

	if (mode == 0)
		event_size = 2 * sizeof(u32);
	else
		event_size = 3 * sizeof(u32);

	ptr = base + EVENT_START_OFFSET + (start_idx * event_size);

	/*                                               */
	spin_lock_irqsave(&trans->reg_lock, reg_flags);
	if (unlikely(!iwl_grab_nic_access(trans)))
		goto out_unlock;

	/*                                                 */
	iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr);

	/*                                                     
                                                            */
	for (i = 0; i < num_events; i++) {
		ev = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
		time = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
		if (mode == 0) {
			/*          */
			if (bufsz) {
				pos += scnprintf(*buf + pos, bufsz - pos,
						"EVT_LOG:0x%08x:%04u\n",
						time, ev);
			} else {
				trace_iwlwifi_dev_ucode_event(trans->dev, 0,
					time, ev);
				IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n",
					time, ev);
			}
		} else {
			data = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
			if (bufsz) {
				pos += scnprintf(*buf + pos, bufsz - pos,
						"EVT_LOGT:%010u:0x%08x:%04u\n",
						 time, data, ev);
			} else {
				IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n",
					time, data, ev);
				trace_iwlwifi_dev_ucode_event(trans->dev, time,
					data, ev);
			}
		}
	}

	/*                            */
	iwl_release_nic_access(trans);
out_unlock:
	spin_unlock_irqrestore(&trans->reg_lock, reg_flags);
	return pos;
}