diff options
author | Senthil Balasubramanian <senthilkumar@atheros.com> | 2011-04-22 02:02:12 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-04-25 14:50:19 -0400 |
commit | b84628eb574f04db714d34276383edbe6d8bfd96 (patch) | |
tree | 485e166a6f1266348b8ae2eef83b869e0e53f7a6 /drivers | |
parent | 9eab61c2bff2f769ee771a7a9301fb720cec9b56 (diff) |
ath9k: Add power save wrappers and modularize hw_pll handler
We should protect hw_pll handler with power save wrappers and
also modularize hw_pll handler properly for better readability.
Also add a debug message to track chip resets on pll hang condition.
Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 34 |
3 files changed, 26 insertions, 12 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6166ba0bca54..2b4e7c0225ab 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -673,7 +673,7 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) | |||
673 | REGWRITE_BUFFER_FLUSH(ah); | 673 | REGWRITE_BUFFER_FLUSH(ah); |
674 | } | 674 | } |
675 | 675 | ||
676 | unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | 676 | u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) |
677 | { | 677 | { |
678 | REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); | 678 | REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); |
679 | udelay(100); | 679 | udelay(100); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 29a745c59e63..6a028bd67116 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -932,7 +932,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); | |||
932 | void ath9k_hw_reset_tsf(struct ath_hw *ah); | 932 | void ath9k_hw_reset_tsf(struct ath_hw *ah); |
933 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); | 933 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); |
934 | void ath9k_hw_init_global_settings(struct ath_hw *ah); | 934 | void ath9k_hw_init_global_settings(struct ath_hw *ah); |
935 | unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); | 935 | u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); |
936 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); | 936 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); |
937 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); | 937 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); |
938 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | 938 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 94d73c3f4458..20a2cf731d83 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -624,23 +624,37 @@ out: | |||
624 | ath9k_ps_restore(sc); | 624 | ath9k_ps_restore(sc); |
625 | } | 625 | } |
626 | 626 | ||
627 | static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) | ||
628 | { | ||
629 | static int count; | ||
630 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
631 | |||
632 | if (pll_sqsum >= 0x40000) { | ||
633 | count++; | ||
634 | if (count == 3) { | ||
635 | /* Rx is hung for more than 500ms. Reset it */ | ||
636 | ath_dbg(common, ATH_DBG_RESET, | ||
637 | "Possible RX hang, resetting"); | ||
638 | ath_reset(sc, true); | ||
639 | count = 0; | ||
640 | } | ||
641 | } else | ||
642 | count = 0; | ||
643 | } | ||
644 | |||
627 | void ath_hw_pll_work(struct work_struct *work) | 645 | void ath_hw_pll_work(struct work_struct *work) |
628 | { | 646 | { |
629 | struct ath_softc *sc = container_of(work, struct ath_softc, | 647 | struct ath_softc *sc = container_of(work, struct ath_softc, |
630 | hw_pll_work.work); | 648 | hw_pll_work.work); |
631 | static int count; | 649 | u32 pll_sqsum; |
632 | 650 | ||
633 | if (AR_SREV_9485(sc->sc_ah)) { | 651 | if (AR_SREV_9485(sc->sc_ah)) { |
634 | if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) { | ||
635 | count++; | ||
636 | 652 | ||
637 | if (count == 3) { | 653 | ath9k_ps_wakeup(sc); |
638 | /* Rx is hung for more than 500ms. Reset it */ | 654 | pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); |
639 | ath_reset(sc, true); | 655 | ath9k_ps_restore(sc); |
640 | count = 0; | 656 | |
641 | } | 657 | ath_hw_pll_rx_hang_check(sc, pll_sqsum); |
642 | } else | ||
643 | count = 0; | ||
644 | 658 | ||
645 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | 659 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); |
646 | } | 660 | } |