Commit ceb26a60 authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville

ath9k: improve suspend/resume reliability

Ensure that drv_start() always returns true, as a failing hw start usually
eventually leads to crashes when there's still a station entry present.
Call a power-on reset after a resume and after a hw reset failure to bring
the hardware back to life again.
Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 93170516
...@@ -1450,9 +1450,14 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) ...@@ -1450,9 +1450,14 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
REG_WRITE(ah, AR_RTC_FORCE_WAKE, REG_WRITE(ah, AR_RTC_FORCE_WAKE,
AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
if (!ah->reset_power_on)
type = ATH9K_RESET_POWER_ON;
switch (type) { switch (type) {
case ATH9K_RESET_POWER_ON: case ATH9K_RESET_POWER_ON:
ret = ath9k_hw_set_reset_power_on(ah); ret = ath9k_hw_set_reset_power_on(ah);
if (!ret)
ah->reset_power_on = true;
break; break;
case ATH9K_RESET_WARM: case ATH9K_RESET_WARM:
case ATH9K_RESET_COLD: case ATH9K_RESET_COLD:
......
...@@ -741,6 +741,7 @@ struct ath_hw { ...@@ -741,6 +741,7 @@ struct ath_hw {
u32 rfkill_polarity; u32 rfkill_polarity;
u32 ah_flags; u32 ah_flags;
bool reset_power_on;
bool htc_reset_init; bool htc_reset_init;
enum nl80211_iftype opmode; enum nl80211_iftype opmode;
......
...@@ -639,8 +639,7 @@ static int ath9k_start(struct ieee80211_hw *hw) ...@@ -639,8 +639,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
ath_err(common, ath_err(common,
"Unable to reset hardware; reset status %d (freq %u MHz)\n", "Unable to reset hardware; reset status %d (freq %u MHz)\n",
r, curchan->center_freq); r, curchan->center_freq);
spin_unlock_bh(&sc->sc_pcu_lock); ah->reset_power_on = false;
goto mutex_unlock;
} }
/* Setup our intr mask. */ /* Setup our intr mask. */
...@@ -665,11 +664,8 @@ static int ath9k_start(struct ieee80211_hw *hw) ...@@ -665,11 +664,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
clear_bit(SC_OP_INVALID, &sc->sc_flags); clear_bit(SC_OP_INVALID, &sc->sc_flags);
sc->sc_ah->is_monitoring = false; sc->sc_ah->is_monitoring = false;
if (!ath_complete_reset(sc, false)) { if (!ath_complete_reset(sc, false))
r = -EIO; ah->reset_power_on = false;
spin_unlock_bh(&sc->sc_pcu_lock);
goto mutex_unlock;
}
if (ah->led_pin >= 0) { if (ah->led_pin >= 0) {
ath9k_hw_cfg_output(ah, ah->led_pin, ath9k_hw_cfg_output(ah, ah->led_pin,
...@@ -688,12 +684,11 @@ static int ath9k_start(struct ieee80211_hw *hw) ...@@ -688,12 +684,11 @@ static int ath9k_start(struct ieee80211_hw *hw)
if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
common->bus_ops->extn_synch_en(common); common->bus_ops->extn_synch_en(common);
mutex_unlock:
mutex_unlock(&sc->mutex); mutex_unlock(&sc->mutex);
ath9k_ps_restore(sc); ath9k_ps_restore(sc);
return r; return 0;
} }
static void ath9k_tx(struct ieee80211_hw *hw, static void ath9k_tx(struct ieee80211_hw *hw,
......
...@@ -326,7 +326,8 @@ static int ath_pci_resume(struct device *device) ...@@ -326,7 +326,8 @@ static int ath_pci_resume(struct device *device)
struct pci_dev *pdev = to_pci_dev(device); struct pci_dev *pdev = to_pci_dev(device);
struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
u32 val; u32 val;
/* /*
...@@ -339,6 +340,7 @@ static int ath_pci_resume(struct device *device) ...@@ -339,6 +340,7 @@ static int ath_pci_resume(struct device *device)
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
ath_pci_aspm_init(common); ath_pci_aspm_init(common);
ah->reset_power_on = false;
return 0; return 0;
} }
......
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