Commit 3e14c1fd authored by Johannes Berg's avatar Johannes Berg Committed by Wey-Yi Guy

iwlagn: refactor up path

Starting the device consists of many things,
refactor out enabling the hardware and also
return -ERFKILL when the rfkill signal is
found to be asserted (which makes more sense
anyway, but is also required now to make the
__iwl_up function return right away.)
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent bc4f8ada
...@@ -2294,6 +2294,52 @@ void iwlagn_remove_notification(struct iwl_priv *priv, ...@@ -2294,6 +2294,52 @@ void iwlagn_remove_notification(struct iwl_priv *priv,
spin_unlock_bh(&priv->_agn.notif_wait_lock); spin_unlock_bh(&priv->_agn.notif_wait_lock);
} }
int iwlagn_start_device(struct iwl_priv *priv)
{
int ret;
iwl_prepare_card_hw(priv);
if (!priv->hw_ready) {
IWL_WARN(priv, "Exit HW not ready\n");
return -EIO;
}
/* If platform's RF_KILL switch is NOT set to KILL */
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(STATUS_RF_KILL_HW, &priv->status);
else
set_bit(STATUS_RF_KILL_HW, &priv->status);
if (iwl_is_rfkill(priv)) {
wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
iwl_enable_interrupts(priv);
return -ERFKILL;
}
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
ret = iwlagn_hw_nic_init(priv);
if (ret) {
IWL_ERR(priv, "Unable to init nic\n");
return ret;
}
/* make sure rfkill handshake bits are cleared */
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
/* clear (again), then enable host interrupts */
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
iwl_enable_interrupts(priv);
/* really make sure rfkill handshake bits are cleared */
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
return 0;
}
void iwlagn_stop_device(struct iwl_priv *priv) void iwlagn_stop_device(struct iwl_priv *priv)
{ {
unsigned long flags; unsigned long flags;
......
...@@ -2416,7 +2416,7 @@ static int iwl_set_hw_ready(struct iwl_priv *priv) ...@@ -2416,7 +2416,7 @@ static int iwl_set_hw_ready(struct iwl_priv *priv)
return ret; return ret;
} }
static int iwl_prepare_card_hw(struct iwl_priv *priv) int iwl_prepare_card_hw(struct iwl_priv *priv)
{ {
int ret = 0; int ret = 0;
...@@ -2462,47 +2462,9 @@ static int __iwl_up(struct iwl_priv *priv) ...@@ -2462,47 +2462,9 @@ static int __iwl_up(struct iwl_priv *priv)
} }
} }
iwl_prepare_card_hw(priv); ret = iwlagn_start_device(priv);
if (ret)
if (!priv->hw_ready) {
IWL_WARN(priv, "Exit HW not ready\n");
return -EIO;
}
/* If platform's RF_KILL switch is NOT set to KILL */
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(STATUS_RF_KILL_HW, &priv->status);
else
set_bit(STATUS_RF_KILL_HW, &priv->status);
if (iwl_is_rfkill(priv)) {
wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
iwl_enable_interrupts(priv);
IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
return 0;
}
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
ret = iwlagn_hw_nic_init(priv);
if (ret) {
IWL_ERR(priv, "Unable to init nic\n");
return ret; return ret;
}
/* make sure rfkill handshake bits are cleared */
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
/* clear (again), then enable host interrupts */
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
iwl_enable_interrupts(priv);
/* really make sure rfkill handshake bits are cleared */
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
for (i = 0; i < MAX_HW_RESTARTS; i++) { for (i = 0; i < MAX_HW_RESTARTS; i++) {
......
...@@ -128,7 +128,9 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv) ...@@ -128,7 +128,9 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
tasklet_kill(&priv->irq_tasklet); tasklet_kill(&priv->irq_tasklet);
} }
int iwl_prepare_card_hw(struct iwl_priv *priv);
int iwlagn_start_device(struct iwl_priv *priv);
void iwlagn_stop_device(struct iwl_priv *priv); void iwlagn_stop_device(struct iwl_priv *priv);
/* tx queue */ /* tx queue */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment