Esempio n. 1
0
u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr)
{
    u32 value;

    _iwl_read_targ_mem_words(bus, addr, &value, 1);

    return value;
}
Esempio n. 2
0
/*
 * This function handles the user application commands for SRAM data dump
 *
 * It retrieves the mandatory fields IWL_TM_ATTR_SRAM_ADDR and
 * IWL_TM_ATTR_SRAM_SIZE to decide the memory area for SRAM data reading
 *
 * Several error will be retured, -EBUSY if the SRAM data retrieved by
 * previous command has not been delivered to userspace, or -ENOMSG if
 * the mandatory fields (IWL_TM_ATTR_SRAM_ADDR,IWL_TM_ATTR_SRAM_SIZE)
 * are missing, or -ENOMEM if the buffer allocation fails.
 *
 * Otherwise 0 is replied indicating the success of the SRAM reading.
 *
 * @hw: ieee80211_hw object that represents the device
 * @tb: gnl message fields from the user space
 */
static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb)
{
	struct iwl_priv *priv = hw->priv;
	u32 base, ofs, size, maxsize;

	if (priv->testmode_sram.sram_readed)
		return -EBUSY;

	if (!tb[IWL_TM_ATTR_SRAM_ADDR]) {
		IWL_DEBUG_INFO(priv, "Error finding SRAM offset address\n");
		return -ENOMSG;
	}
	ofs = nla_get_u32(tb[IWL_TM_ATTR_SRAM_ADDR]);
	if (!tb[IWL_TM_ATTR_SRAM_SIZE]) {
		IWL_DEBUG_INFO(priv, "Error finding size for SRAM reading\n");
		return -ENOMSG;
	}
	size = nla_get_u32(tb[IWL_TM_ATTR_SRAM_SIZE]);
	switch (priv->shrd->ucode_type) {
	case IWL_UCODE_REGULAR:
		maxsize = trans(priv)->ucode_rt.data.len;
		break;
	case IWL_UCODE_INIT:
		maxsize = trans(priv)->ucode_init.data.len;
		break;
	case IWL_UCODE_WOWLAN:
		maxsize = trans(priv)->ucode_wowlan.data.len;
		break;
	case IWL_UCODE_NONE:
		IWL_DEBUG_INFO(priv, "Error, uCode does not been loaded\n");
		return -ENOSYS;
	default:
		IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n");
		return -ENOSYS;
	}
	if ((ofs + size) > maxsize) {
		IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n");
		return -EINVAL;
	}
	priv->testmode_sram.buff_size = (size / 4) * 4;
	priv->testmode_sram.buff_addr =
		kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL);
	if (priv->testmode_sram.buff_addr == NULL) {
		IWL_DEBUG_INFO(priv, "Error allocating memory\n");
		return -ENOMEM;
	}
	base = 0x800000;
	_iwl_read_targ_mem_words(bus(priv), base + ofs,
					priv->testmode_sram.buff_addr,
					priv->testmode_sram.buff_size / 4);
	priv->testmode_sram.num_chunks =
		DIV_ROUND_UP(priv->testmode_sram.buff_size, DUMP_CHUNK_SIZE);
	priv->testmode_sram.sram_readed = true;
	return 0;
}
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;

}