コード例 #1
0
static int iwl_trans_rx_stop(struct iwl_priv *priv)
{

	/* stop Rx DMA */
	iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
	return iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
			    FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
}
コード例 #2
0
ファイル: iwl-5000.c プロジェクト: AppEngine/linux-2.6
/* FIXME: same implementation as 4965 */
static int iwl5000_apm_stop_master(struct iwl_priv *priv)
{
	unsigned long flags;

	spin_lock_irqsave(&priv->lock, flags);

	/* set stop master bit */
	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);

	iwl_poll_direct_bit(priv, CSR_RESET,
				  CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);

	spin_unlock_irqrestore(&priv->lock, flags);
	IWL_DEBUG_INFO(priv, "stop master\n");

	return 0;
}
コード例 #3
0
ファイル: iwl-5000.c プロジェクト: AppEngine/linux-2.6
static int iwl5000_apm_init(struct iwl_priv *priv)
{
	int ret = 0;

	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
		    CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);

	/* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
		    CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);

	/* Set FH wait threshold to maximum (HW error during stress W/A) */
	iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);

	/* enable HAP INTA to move device L1a -> L0s */
	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
		    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);

	if (priv->cfg->need_pll_cfg)
		iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);

	/* set "initialization complete" bit to move adapter
	 * D0U* --> D0A* state */
	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);

	/* wait for clock stabilization */
	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
	if (ret < 0) {
		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
		return ret;
	}

	/* enable DMA */
	iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);

	udelay(20);

	/* disable L1-Active */
	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);

	return ret;
}
コード例 #4
0
ファイル: iwl-5000.c プロジェクト: AppEngine/linux-2.6
static int iwl5000_apm_reset(struct iwl_priv *priv)
{
	int ret = 0;

	iwl5000_apm_stop_master(priv);

	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);

	udelay(10);


	/* FIXME: put here L1A -L0S w/a */

	if (priv->cfg->need_pll_cfg)
		iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);

	/* set "initialization complete" bit to move adapter
	 * D0U* --> D0A* state */
	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);

	/* wait for clock stabilization */
	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
	if (ret < 0) {
		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
		goto out;
	}

	/* enable DMA */
	iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);

	udelay(20);

	/* disable L1-Active */
	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
out:

	return ret;
}
コード例 #5
0
/*
 * The device's EEPROM semaphore prevents conflicts between driver and uCode
 * when accessing the EEPROM; each access is a series of pulses to/from the
 * EEPROM chip, not a single event, so even reads could conflict if they
 * weren't arbitrated by the semaphore.
 */
int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
{
	u16 count;
	int ret;

	for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
		/* Request semaphore */
		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
			    CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);

		/* See if we got it */
		ret = iwl_poll_direct_bit(priv, CSR_HW_IF_CONFIG_REG,
				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
				EEPROM_SEM_TIMEOUT);
		if (ret >= 0) {
			IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n",
				count+1);
			return ret;
		}
	}

	return ret;
}
コード例 #6
0
static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data)
{
	int ret = 0;
	u32 r;
	u32 otpgp;

	_iwl_write32(priv, CSR_EEPROM_REG,
		     CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
	ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
				  CSR_EEPROM_REG_READ_VALID_MSK,
				  IWL_EEPROM_ACCESS_TIMEOUT);
	if (ret < 0) {
		IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
		return ret;
	}
	r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
	/* check for ECC errors: */
	otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
	if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
		/* stop in this case */
		/* set the uncorrectable OTP ECC bit for acknowledgement */
		iwl_set_bit(priv, CSR_OTP_GP_REG,
			CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
		IWL_ERR(priv, "Uncorrectable OTP ECC error, abort OTP read\n");
		return -EINVAL;
	}
	if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
		/* continue in this case */
		/* set the correctable OTP ECC bit for acknowledgement */
		iwl_set_bit(priv, CSR_OTP_GP_REG,
				CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
		IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
	}
	*eeprom_data = le16_to_cpu((__force __le16)(r >> 16));
	return 0;
}
コード例 #7
0
static int iwl_init_otp_access(struct iwl_priv *priv)
{
	int ret;

	/* Enable 40MHz radio clock */
	_iwl_write32(priv, CSR_GP_CNTRL,
		     _iwl_read32(priv, CSR_GP_CNTRL) |
		     CSR_GP_CNTRL_REG_FLAG_INIT_DONE);

	/* wait for clock to be ready */
	ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
				  CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
				  25000);
	if (ret < 0)
		IWL_ERR(priv, "Time out access OTP\n");
	else {
		iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
				  APMG_PS_CTRL_VAL_RESET_REQ);
		udelay(5);
		iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
				    APMG_PS_CTRL_VAL_RESET_REQ);
	}
	return ret;
}
コード例 #8
0
/**
 * iwl_eeprom_init - read EEPROM contents
 *
 * Load the EEPROM contents from adapter into priv->eeprom
 *
 * NOTE:  This routine uses the non-debug IO access functions.
 */
int iwl_eeprom_init(struct iwl_priv *priv)
{
	u16 *e;
	u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
	int sz;
	int ret;
	u16 addr;
	u16 validblockaddr = 0;
	u16 cache_addr = 0;

	priv->nvm_device_type = iwlcore_get_nvm_type(priv);

	/* allocate eeprom */
	IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size);
	sz = priv->cfg->eeprom_size;
	priv->eeprom = kzalloc(sz, GFP_KERNEL);
	if (!priv->eeprom) {
		ret = -ENOMEM;
		goto alloc_err;
	}
	e = (u16 *)priv->eeprom;

	ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
	if (ret < 0) {
		IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
		ret = -ENOENT;
		goto err;
	}

	/* Make sure driver (instead of uCode) is allowed to read EEPROM */
	ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
	if (ret < 0) {
		IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
		ret = -ENOENT;
		goto err;
	}
	if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
		ret = iwl_init_otp_access(priv);
		if (ret) {
			IWL_ERR(priv, "Failed to initialize OTP access.\n");
			ret = -ENOENT;
			goto done;
		}
		_iwl_write32(priv, CSR_EEPROM_GP,
			     iwl_read32(priv, CSR_EEPROM_GP) &
			     ~CSR_EEPROM_GP_IF_OWNER_MSK);

		iwl_set_bit(priv, CSR_OTP_GP_REG,
			     CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
			     CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
		/* traversing the linked list if no shadow ram supported */
		if (!priv->cfg->shadow_ram_support) {
			if (iwl_find_otp_image(priv, &validblockaddr)) {
				ret = -ENOENT;
				goto done;
			}
		}
		for (addr = validblockaddr; addr < validblockaddr + sz;
		     addr += sizeof(u16)) {
			u16 eeprom_data;

			ret = iwl_read_otp_word(priv, addr, &eeprom_data);
			if (ret)
				goto done;
			e[cache_addr / 2] = eeprom_data;
			cache_addr += sizeof(u16);
		}
	} else {
		/* eeprom is an array of 16bit values */
		for (addr = 0; addr < sz; addr += sizeof(u16)) {
			u32 r;

			_iwl_write32(priv, CSR_EEPROM_REG,
				     CSR_EEPROM_REG_MSK_ADDR & (addr << 1));

			ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
						  CSR_EEPROM_REG_READ_VALID_MSK,
						  IWL_EEPROM_ACCESS_TIMEOUT);
			if (ret < 0) {
				IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
				goto done;
			}
			r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
			e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
		}
	}
	ret = 0;
done:
	priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
err:
	if (ret)
		iwl_eeprom_free(priv);
alloc_err:
	return ret;
}
コード例 #9
0
ファイル: rx.c プロジェクト: Kratos1982/UbuntuTouch
/*
 * iwl_pcie_rx_stop - stops the Rx DMA
 */
int iwl_pcie_rx_stop(struct iwl_trans *trans)
{
	iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
	return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG,
				   FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
}