X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fath5k%2Fbase.c;h=cfd4d052d666ea8cbda45b37c541cb2592dad3a0;hb=4bab0ea1d42dd1927af9df6fbf0003fc00617c50;hp=9b95c4049b313492055198077de7d3f6458c2fbc;hpb=e3d2f927f788adcdabc42f8a1616f6cc56c53bbe;p=linux-2.6-omap-h63xx.git diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 9b95c4049b3..cfd4d052d66 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -340,9 +340,9 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) } /* Interrupt handling */ -static int ath5k_init(struct ath5k_softc *sc); +static int ath5k_init(struct ath5k_softc *sc, bool is_resume); static int ath5k_stop_locked(struct ath5k_softc *sc); -static int ath5k_stop_hw(struct ath5k_softc *sc); +static int ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend); static irqreturn_t ath5k_intr(int irq, void *dev_id); static void ath5k_tasklet_reset(unsigned long data); @@ -646,7 +646,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state) ath5k_led_off(sc); - ath5k_stop_hw(sc); + ath5k_stop_hw(sc, true); free_irq(pdev->irq, sc); pci_save_state(pdev); @@ -661,8 +661,7 @@ ath5k_pci_resume(struct pci_dev *pdev) { struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - int i, err; + int err; pci_restore_state(pdev); @@ -683,21 +682,11 @@ ath5k_pci_resume(struct pci_dev *pdev) goto err_no_irq; } - err = ath5k_init(sc); + err = ath5k_init(sc, true); if (err) goto err_irq; ath5k_led_enable(sc); - /* - * Reset the key cache since some parts do not - * reset the contents on initial power up or resume. - * - * FIXME: This may need to be revisited when mac80211 becomes - * aware of suspend/resume. - */ - for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) - ath5k_hw_reset_key(ah, i); - return 0; err_irq: free_irq(pdev->irq, sc); @@ -718,7 +707,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; u8 mac[ETH_ALEN]; - unsigned int i; int ret; ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); @@ -736,13 +724,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) if (ret > 0) __set_bit(ATH_STAT_MRRETRY, sc->status); - /* - * Reset the key cache since some parts do not - * reset the contents on initial power up. - */ - for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) - ath5k_hw_reset_key(ah, i); - /* * Collect the channel list. The 802.11 layer * is resposible for filtering this list based @@ -2200,12 +2181,18 @@ ath5k_beacon_config(struct ath5k_softc *sc) \********************/ static int -ath5k_init(struct ath5k_softc *sc) +ath5k_init(struct ath5k_softc *sc, bool is_resume) { - int ret; + struct ath5k_hw *ah = sc->ah; + int ret, i; mutex_lock(&sc->lock); + if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status)) + goto out_ok; + + __clear_bit(ATH_STAT_STARTED, sc->status); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); /* @@ -2230,12 +2217,22 @@ ath5k_init(struct ath5k_softc *sc) if (ret) goto done; + /* + * Reset the key cache since some parts do not reset the + * contents on initial power up or resume from suspend. + */ + for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) + ath5k_hw_reset_key(ah, i); + + __set_bit(ATH_STAT_STARTED, sc->status); + /* Set ack to be sent at low bit-rates */ - ath5k_hw_set_ack_bitrate_high(sc->ah, false); + ath5k_hw_set_ack_bitrate_high(ah, false); mod_timer(&sc->calib_tim, round_jiffies(jiffies + msecs_to_jiffies(ath5k_calinterval * 1000))); +out_ok: ret = 0; done: mmiowb(); @@ -2290,7 +2287,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) * stop is preempted). */ static int -ath5k_stop_hw(struct ath5k_softc *sc) +ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend) { int ret; @@ -2321,6 +2318,9 @@ ath5k_stop_hw(struct ath5k_softc *sc) } } ath5k_txbuf_free(sc, sc->bbuf); + if (!is_suspend) + __clear_bit(ATH_STAT_STARTED, sc->status); + mmiowb(); mutex_unlock(&sc->lock); @@ -2718,12 +2718,12 @@ ath5k_reset_wake(struct ath5k_softc *sc) static int ath5k_start(struct ieee80211_hw *hw) { - return ath5k_init(hw->priv); + return ath5k_init(hw->priv, false); } static void ath5k_stop(struct ieee80211_hw *hw) { - ath5k_stop_hw(hw->priv); + ath5k_stop_hw(hw->priv, false); } static int ath5k_add_interface(struct ieee80211_hw *hw,