Ath5k: unify resets
authorJiri Slaby <jirislaby@gmail.com>
Wed, 23 Jul 2008 11:17:35 +0000 (13:17 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 22 Aug 2008 20:29:49 +0000 (16:29 -0400)
There were 3 code copy and pastes of reset. Unify the resets and place
in separate function.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Nick Kossifidis <mickflemm@gmail.com>
Cc: Luis R. Rodriguez <mcgrof@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath5k/base.c

index 8bc9b92ad6aa0bb7469ee90bef4352f790b5ea4f..e8564095b2f87ecc61556b0622d769d36cabaca2 100644 (file)
@@ -162,7 +162,8 @@ static struct pci_driver ath5k_pci_driver = {
  * Prototypes - MAC 802.11 stack related functions
  */
 static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-static int ath5k_reset(struct ieee80211_hw *hw);
+static int ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel);
+static int ath5k_reset_wake(struct ath5k_softc *sc);
 static int ath5k_start(struct ieee80211_hw *hw);
 static void ath5k_stop(struct ieee80211_hw *hw);
 static int ath5k_add_interface(struct ieee80211_hw *hw,
@@ -977,9 +978,6 @@ ath5k_getchannels(struct ieee80211_hw *hw)
 static int
 ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
 {
-       struct ath5k_hw *ah = sc->ah;
-       int ret;
-
        ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n",
                sc->curchan->center_freq, chan->center_freq);
 
@@ -995,41 +993,7 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
                 * hardware at the new frequency, and then re-enable
                 * the relevant bits of the h/w.
                 */
-               ath5k_hw_set_intr(ah, 0);       /* disable interrupts */
-               ath5k_txq_cleanup(sc);          /* clear pending tx frames */
-               ath5k_rx_stop(sc);              /* turn off frame recv */
-               ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
-               if (ret) {
-                       ATH5K_ERR(sc, "%s: unable to reset channel "
-                               "(%u Mhz)\n", __func__, chan->center_freq);
-                       return ret;
-               }
-
-               ath5k_hw_set_txpower_limit(sc->ah, 0);
-
-               /*
-                * Re-enable rx framework.
-                */
-               ret = ath5k_rx_start(sc);
-               if (ret) {
-                       ATH5K_ERR(sc, "%s: unable to restart recv logic\n",
-                                       __func__);
-                       return ret;
-               }
-
-               /*
-                * Change channels and update the h/w rate map
-                * if we're switching; e.g. 11a to 11b/g.
-                *
-                * XXX needed?
-                */
-/*             ath5k_chan_change(sc, chan); */
-
-               ath5k_beacon_config(sc);
-               /*
-                * Re-enable interrupts.
-                */
-               ath5k_hw_set_intr(ah, sc->imask);
+               return ath5k_reset(sc, true, true);
        }
 
        return 0;
@@ -2217,36 +2181,13 @@ ath5k_init(struct ath5k_softc *sc)
         */
        sc->curchan = sc->hw->conf.channel;
        sc->curband = &sc->sbands[sc->curchan->band];
-       ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false);
-       if (ret) {
-               ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret);
-               goto done;
-       }
-       /*
-        * This is needed only to setup initial state
-        * but it's best done after a reset.
-        */
-       ath5k_hw_set_txpower_limit(sc->ah, 0);
-
-       /*
-        * Setup the hardware after reset: the key cache
-        * is filled as needed and the receive engine is
-        * set going.  Frame transmit is handled entirely
-        * in the frame output path; there's nothing to do
-        * here except setup the interrupt mask.
-        */
-       ret = ath5k_rx_start(sc);
-       if (ret)
-               goto done;
-
-       /*
-        * Enable interrupts.
-        */
        sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL |
                AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL |
                AR5K_INT_MIB;
+       ret = ath5k_reset(sc, false, false);
+       if (ret)
+               goto done;
 
-       ath5k_hw_set_intr(sc->ah, sc->imask);
        /* Set ack to be sent at low bit-rates */
        ath5k_hw_set_ack_bitrate_high(sc->ah, false);
 
@@ -2446,7 +2387,7 @@ ath5k_tasklet_reset(unsigned long data)
 {
        struct ath5k_softc *sc = (void *)data;
 
-       ath5k_reset(sc->hw);
+       ath5k_reset_wake(sc);
 }
 
 /*
@@ -2469,7 +2410,7 @@ ath5k_calibrate(unsigned long data)
                 * to load new gain values.
                 */
                ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n");
-               ath5k_reset(sc->hw);
+               ath5k_reset_wake(sc);
        }
        if (ath5k_hw_phy_calibrate(ah, sc->curchan))
                ATH5K_ERR(sc, "calibration of channel %u failed\n",
@@ -2670,48 +2611,67 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 }
 
 static int
-ath5k_reset(struct ieee80211_hw *hw)
+ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel)
 {
-       struct ath5k_softc *sc = hw->priv;
        struct ath5k_hw *ah = sc->ah;
        int ret;
 
        ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
 
-       ath5k_hw_set_intr(ah, 0);
-       ath5k_txq_cleanup(sc);
-       ath5k_rx_stop(sc);
-
+       if (stop) {
+               ath5k_hw_set_intr(ah, 0);
+               ath5k_txq_cleanup(sc);
+               ath5k_rx_stop(sc);
+       }
        ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
-       if (unlikely(ret)) {
+       if (ret) {
                ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
                goto err;
        }
+
+       /*
+        * This is needed only to setup initial state
+        * but it's best done after a reset.
+        */
        ath5k_hw_set_txpower_limit(sc->ah, 0);
 
        ret = ath5k_rx_start(sc);
-       if (unlikely(ret)) {
+       if (ret) {
                ATH5K_ERR(sc, "can't start recv logic\n");
                goto err;
        }
+
        /*
-        * We may be doing a reset in response to an ioctl
-        * that changes the channel so update any state that
-        * might change as a result.
+        * Change channels and update the h/w rate map if we're switching;
+        * e.g. 11a to 11b/g.
+        *
+        * We may be doing a reset in response to an ioctl that changes the
+        * channel so update any state that might change as a result.
         *
         * XXX needed?
         */
 /*     ath5k_chan_change(sc, c); */
-       ath5k_beacon_config(sc);
-       /* intrs are started by ath5k_beacon_config */
 
-       ieee80211_wake_queues(hw);
+       ath5k_beacon_config(sc);
+       /* intrs are enabled by ath5k_beacon_config */
 
        return 0;
 err:
        return ret;
 }
 
+static int
+ath5k_reset_wake(struct ath5k_softc *sc)
+{
+       int ret;
+
+       ret = ath5k_reset(sc, true, true);
+       if (!ret)
+               ieee80211_wake_queues(sc->hw);
+
+       return ret;
+}
+
 static int ath5k_start(struct ieee80211_hw *hw)
 {
        return ath5k_init(hw->priv);
@@ -2820,7 +2780,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
        mutex_unlock(&sc->lock);
 
-       return ath5k_reset(hw);
+       return ath5k_reset_wake(sc);
 unlock:
        mutex_unlock(&sc->lock);
        return ret;