aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath5k
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2008-07-23 07:17:35 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-22 16:29:49 -0400
commitd7dc100374df0c21afd8a198336ecd7999697159 (patch)
treefadb0ec2eccbd8c9c21d6f29af8fa10747ee56b8 /drivers/net/wireless/ath5k
parentb9740c2396851178b99c03c2260a0adfe7f52e36 (diff)
Ath5k: unify resets
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>
Diffstat (limited to 'drivers/net/wireless/ath5k')
-rw-r--r--drivers/net/wireless/ath5k/base.c124
1 files changed, 42 insertions, 82 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 8bc9b92ad6aa..e8564095b2f8 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -162,7 +162,8 @@ static struct pci_driver ath5k_pci_driver = {
162 * Prototypes - MAC 802.11 stack related functions 162 * Prototypes - MAC 802.11 stack related functions
163 */ 163 */
164static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); 164static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
165static int ath5k_reset(struct ieee80211_hw *hw); 165static int ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel);
166static int ath5k_reset_wake(struct ath5k_softc *sc);
166static int ath5k_start(struct ieee80211_hw *hw); 167static int ath5k_start(struct ieee80211_hw *hw);
167static void ath5k_stop(struct ieee80211_hw *hw); 168static void ath5k_stop(struct ieee80211_hw *hw);
168static int ath5k_add_interface(struct ieee80211_hw *hw, 169static int ath5k_add_interface(struct ieee80211_hw *hw,
@@ -977,9 +978,6 @@ ath5k_getchannels(struct ieee80211_hw *hw)
977static int 978static int
978ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) 979ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
979{ 980{
980 struct ath5k_hw *ah = sc->ah;
981 int ret;
982
983 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", 981 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n",
984 sc->curchan->center_freq, chan->center_freq); 982 sc->curchan->center_freq, chan->center_freq);
985 983
@@ -995,41 +993,7 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
995 * hardware at the new frequency, and then re-enable 993 * hardware at the new frequency, and then re-enable
996 * the relevant bits of the h/w. 994 * the relevant bits of the h/w.
997 */ 995 */
998 ath5k_hw_set_intr(ah, 0); /* disable interrupts */ 996 return ath5k_reset(sc, true, true);
999 ath5k_txq_cleanup(sc); /* clear pending tx frames */
1000 ath5k_rx_stop(sc); /* turn off frame recv */
1001 ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
1002 if (ret) {
1003 ATH5K_ERR(sc, "%s: unable to reset channel "
1004 "(%u Mhz)\n", __func__, chan->center_freq);
1005 return ret;
1006 }
1007
1008 ath5k_hw_set_txpower_limit(sc->ah, 0);
1009
1010 /*
1011 * Re-enable rx framework.
1012 */
1013 ret = ath5k_rx_start(sc);
1014 if (ret) {
1015 ATH5K_ERR(sc, "%s: unable to restart recv logic\n",
1016 __func__);
1017 return ret;
1018 }
1019
1020 /*
1021 * Change channels and update the h/w rate map
1022 * if we're switching; e.g. 11a to 11b/g.
1023 *
1024 * XXX needed?
1025 */
1026/* ath5k_chan_change(sc, chan); */
1027
1028 ath5k_beacon_config(sc);
1029 /*
1030 * Re-enable interrupts.
1031 */
1032 ath5k_hw_set_intr(ah, sc->imask);
1033 } 997 }
1034 998
1035 return 0; 999 return 0;
@@ -2217,36 +2181,13 @@ ath5k_init(struct ath5k_softc *sc)
2217 */ 2181 */
2218 sc->curchan = sc->hw->conf.channel; 2182 sc->curchan = sc->hw->conf.channel;
2219 sc->curband = &sc->sbands[sc->curchan->band]; 2183 sc->curband = &sc->sbands[sc->curchan->band];
2220 ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false);
2221 if (ret) {
2222 ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret);
2223 goto done;
2224 }
2225 /*
2226 * This is needed only to setup initial state
2227 * but it's best done after a reset.
2228 */
2229 ath5k_hw_set_txpower_limit(sc->ah, 0);
2230
2231 /*
2232 * Setup the hardware after reset: the key cache
2233 * is filled as needed and the receive engine is
2234 * set going. Frame transmit is handled entirely
2235 * in the frame output path; there's nothing to do
2236 * here except setup the interrupt mask.
2237 */
2238 ret = ath5k_rx_start(sc);
2239 if (ret)
2240 goto done;
2241
2242 /*
2243 * Enable interrupts.
2244 */
2245 sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL | 2184 sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL |
2246 AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL | 2185 AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL |
2247 AR5K_INT_MIB; 2186 AR5K_INT_MIB;
2187 ret = ath5k_reset(sc, false, false);
2188 if (ret)
2189 goto done;
2248 2190
2249 ath5k_hw_set_intr(sc->ah, sc->imask);
2250 /* Set ack to be sent at low bit-rates */ 2191 /* Set ack to be sent at low bit-rates */
2251 ath5k_hw_set_ack_bitrate_high(sc->ah, false); 2192 ath5k_hw_set_ack_bitrate_high(sc->ah, false);
2252 2193
@@ -2446,7 +2387,7 @@ ath5k_tasklet_reset(unsigned long data)
2446{ 2387{
2447 struct ath5k_softc *sc = (void *)data; 2388 struct ath5k_softc *sc = (void *)data;
2448 2389
2449 ath5k_reset(sc->hw); 2390 ath5k_reset_wake(sc);
2450} 2391}
2451 2392
2452/* 2393/*
@@ -2469,7 +2410,7 @@ ath5k_calibrate(unsigned long data)
2469 * to load new gain values. 2410 * to load new gain values.
2470 */ 2411 */
2471 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n"); 2412 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n");
2472 ath5k_reset(sc->hw); 2413 ath5k_reset_wake(sc);
2473 } 2414 }
2474 if (ath5k_hw_phy_calibrate(ah, sc->curchan)) 2415 if (ath5k_hw_phy_calibrate(ah, sc->curchan))
2475 ATH5K_ERR(sc, "calibration of channel %u failed\n", 2416 ATH5K_ERR(sc, "calibration of channel %u failed\n",
@@ -2670,48 +2611,67 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2670} 2611}
2671 2612
2672static int 2613static int
2673ath5k_reset(struct ieee80211_hw *hw) 2614ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel)
2674{ 2615{
2675 struct ath5k_softc *sc = hw->priv;
2676 struct ath5k_hw *ah = sc->ah; 2616 struct ath5k_hw *ah = sc->ah;
2677 int ret; 2617 int ret;
2678 2618
2679 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); 2619 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
2680 2620
2681 ath5k_hw_set_intr(ah, 0); 2621 if (stop) {
2682 ath5k_txq_cleanup(sc); 2622 ath5k_hw_set_intr(ah, 0);
2683 ath5k_rx_stop(sc); 2623 ath5k_txq_cleanup(sc);
2684 2624 ath5k_rx_stop(sc);
2625 }
2685 ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); 2626 ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
2686 if (unlikely(ret)) { 2627 if (ret) {
2687 ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); 2628 ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
2688 goto err; 2629 goto err;
2689 } 2630 }
2631
2632 /*
2633 * This is needed only to setup initial state
2634 * but it's best done after a reset.
2635 */
2690 ath5k_hw_set_txpower_limit(sc->ah, 0); 2636 ath5k_hw_set_txpower_limit(sc->ah, 0);
2691 2637
2692 ret = ath5k_rx_start(sc); 2638 ret = ath5k_rx_start(sc);
2693 if (unlikely(ret)) { 2639 if (ret) {
2694 ATH5K_ERR(sc, "can't start recv logic\n"); 2640 ATH5K_ERR(sc, "can't start recv logic\n");
2695 goto err; 2641 goto err;
2696 } 2642 }
2643
2697 /* 2644 /*
2698 * We may be doing a reset in response to an ioctl 2645 * Change channels and update the h/w rate map if we're switching;
2699 * that changes the channel so update any state that 2646 * e.g. 11a to 11b/g.
2700 * might change as a result. 2647 *
2648 * We may be doing a reset in response to an ioctl that changes the
2649 * channel so update any state that might change as a result.
2701 * 2650 *
2702 * XXX needed? 2651 * XXX needed?
2703 */ 2652 */
2704/* ath5k_chan_change(sc, c); */ 2653/* ath5k_chan_change(sc, c); */
2705 ath5k_beacon_config(sc);
2706 /* intrs are started by ath5k_beacon_config */
2707 2654
2708 ieee80211_wake_queues(hw); 2655 ath5k_beacon_config(sc);
2656 /* intrs are enabled by ath5k_beacon_config */
2709 2657
2710 return 0; 2658 return 0;
2711err: 2659err:
2712 return ret; 2660 return ret;
2713} 2661}
2714 2662
2663static int
2664ath5k_reset_wake(struct ath5k_softc *sc)
2665{
2666 int ret;
2667
2668 ret = ath5k_reset(sc, true, true);
2669 if (!ret)
2670 ieee80211_wake_queues(sc->hw);
2671
2672 return ret;
2673}
2674
2715static int ath5k_start(struct ieee80211_hw *hw) 2675static int ath5k_start(struct ieee80211_hw *hw)
2716{ 2676{
2717 return ath5k_init(hw->priv); 2677 return ath5k_init(hw->priv);
@@ -2820,7 +2780,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2820 2780
2821 mutex_unlock(&sc->lock); 2781 mutex_unlock(&sc->lock);
2822 2782
2823 return ath5k_reset(hw); 2783 return ath5k_reset_wake(sc);
2824unlock: 2784unlock:
2825 mutex_unlock(&sc->lock); 2785 mutex_unlock(&sc->lock);
2826 return ret; 2786 return ret;