diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2008-07-23 07:17:35 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-08-22 16:29:49 -0400 |
commit | d7dc100374df0c21afd8a198336ecd7999697159 (patch) | |
tree | fadb0ec2eccbd8c9c21d6f29af8fa10747ee56b8 /drivers | |
parent | b9740c2396851178b99c03c2260a0adfe7f52e36 (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')
-rw-r--r-- | drivers/net/wireless/ath5k/base.c | 124 |
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 | */ |
164 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | 164 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); |
165 | static int ath5k_reset(struct ieee80211_hw *hw); | 165 | static int ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel); |
166 | static int ath5k_reset_wake(struct ath5k_softc *sc); | ||
166 | static int ath5k_start(struct ieee80211_hw *hw); | 167 | static int ath5k_start(struct ieee80211_hw *hw); |
167 | static void ath5k_stop(struct ieee80211_hw *hw); | 168 | static void ath5k_stop(struct ieee80211_hw *hw); |
168 | static int ath5k_add_interface(struct ieee80211_hw *hw, | 169 | static int ath5k_add_interface(struct ieee80211_hw *hw, |
@@ -977,9 +978,6 @@ ath5k_getchannels(struct ieee80211_hw *hw) | |||
977 | static int | 978 | static int |
978 | ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | 979 | ath5k_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 | ||
2672 | static int | 2613 | static int |
2673 | ath5k_reset(struct ieee80211_hw *hw) | 2614 | ath5k_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; |
2711 | err: | 2659 | err: |
2712 | return ret; | 2660 | return ret; |
2713 | } | 2661 | } |
2714 | 2662 | ||
2663 | static int | ||
2664 | ath5k_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 | |||
2715 | static int ath5k_start(struct ieee80211_hw *hw) | 2675 | static 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); |
2824 | unlock: | 2784 | unlock: |
2825 | mutex_unlock(&sc->lock); | 2785 | mutex_unlock(&sc->lock); |
2826 | return ret; | 2786 | return ret; |