mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-25 19:07:46 +00:00
iwlwifi: implement apm reset flow
This patch implements apm reset flow for 4965 and 5000. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
8f0618914e
commit
7f066108d1
@ -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 |
|
||||
APMG_CLK_VAL_BSM_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);
|
||||
udelay(10);
|
||||
|
||||
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
|
||||
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
|
||||
/* disable L1A */
|
||||
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
|
||||
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
|
||||
|
||||
iwl_release_nic_access(priv);
|
||||
}
|
||||
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,
|
||||
},
|
||||
|
@ -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,
|
||||
},
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user