Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f066108 authored by Tomas Winkler's avatar Tomas Winkler Committed by John W. Linville
Browse files

iwlwifi: implement apm reset flow



This patch implements apm reset flow for 4965 and 5000.

Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 8f061891
Loading
Loading
Loading
Loading
+22 −14
Original line number Diff line number Diff line
@@ -642,9 +642,9 @@ void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv)
	iwl_hw_txq_ctx_free(priv);
}

int iwl4965_hw_nic_reset(struct iwl_priv *priv)
static int iwl4965_apm_reset(struct iwl_priv *priv)
{
	int rc = 0;
	int ret = 0;
	unsigned long flags;

	iwl4965_hw_nic_stop_master(priv);
@@ -655,33 +655,40 @@ int iwl4965_hw_nic_reset(struct iwl_priv *priv)

	udelay(10);

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

	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
	rc = iwl_poll_bit(priv, CSR_RESET,
	ret = iwl_poll_bit(priv, CSR_RESET,
			  CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
			  CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25);

	if (ret)
		goto out;

	udelay(10);

	rc = iwl_grab_nic_access(priv);
	if (!rc) {
		iwl_write_prph(priv, APMG_CLK_EN_REG,
				APMG_CLK_VAL_DMA_CLK_RQT |
	ret = iwl_grab_nic_access(priv);
	if (ret)
		goto out;
	/* Enable DMA and BSM Clock */
	iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT |
					      APMG_CLK_VAL_BSM_CLK_RQT);

	udelay(10);

	/* disable L1A */
	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);

	iwl_release_nic_access(priv);
	}

	clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
	wake_up_interruptible(&priv->wait_command_queue);

out:
	spin_unlock_irqrestore(&priv->lock, flags);

	return rc;
	return ret;

}

@@ -3617,6 +3624,7 @@ static struct iwl_lib_ops iwl4965_lib = {
	.load_ucode = iwl4965_load_bsm,
	.apm_ops = {
		.init = iwl4965_apm_init,
		.reset = iwl4965_apm_reset,
		.config = iwl4965_nic_config,
		.set_pwr_src = iwl4965_set_pwr_src,
	},
+54 −0
Original line number Diff line number Diff line
@@ -100,6 +100,59 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
	return ret;
}

static int iwl5000_apm_reset(struct iwl_priv *priv)
{
	int ret = 0;
	unsigned long flags;

	iwl4965_hw_nic_stop_master(priv);

	spin_lock_irqsave(&priv->lock, flags);

	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);

	udelay(10);


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

	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_bit(priv, CSR_GP_CNTRL,
			  CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
			  CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
	if (ret < 0) {
		IWL_DEBUG_INFO("Failed to init the card\n");
		goto out;
	}

	ret = iwl_grab_nic_access(priv);
	if (ret)
		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);

	iwl_release_nic_access(priv);

out:
	spin_unlock_irqrestore(&priv->lock, flags);

	return ret;
}


static void iwl5000_nic_config(struct iwl_priv *priv)
{
	unsigned long flags;
@@ -805,6 +858,7 @@ static struct iwl_lib_ops iwl5000_lib = {
	.alive_notify = iwl5000_alive_notify,
	.apm_ops = {
		.init =	iwl5000_apm_init,
		.reset = iwl5000_apm_reset,
		.config = iwl5000_nic_config,
		.set_pwr_src = iwl4965_set_pwr_src,
	},
+1 −0
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ struct iwl_lib_ops {
	 /* power management */
	struct {
		int (*init)(struct iwl_priv *priv);
		int (*reset)(struct iwl_priv *priv);
		void (*config)(struct iwl_priv *priv);
		int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
	} apm_ops;
+0 −1
Original line number Diff line number Diff line
@@ -688,7 +688,6 @@ extern int iwl4965_hw_rxq_stop(struct iwl_priv *priv);
extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv);
extern int iwl4965_hw_nic_stop_master(struct iwl_priv *priv);
extern void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv);
extern int iwl4965_hw_nic_reset(struct iwl_priv *priv);
extern int iwl4965_hw_get_temperature(struct iwl_priv *priv);
extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
				 struct iwl_frame *frame, u8 rate);
+2 −3
Original line number Diff line number Diff line
@@ -3417,9 +3417,8 @@ static void __iwl4965_down(struct iwl_priv *priv)

	udelay(5);

	iwl4965_hw_nic_stop_master(priv);
	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
	iwl4965_hw_nic_reset(priv);
	/* FIXME: apm_ops.suspend(priv) */
	priv->cfg->ops->lib->apm_ops.reset(priv);
	priv->cfg->ops->lib->free_shared_mem(priv);

 exit: