aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/hw.c
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2010-06-21 18:38:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-23 15:14:00 -0400
commit9a658d2b5c222b62919ab47b11c907c731ac180a (patch)
tree80d12299df8955d526c1103f2e3a7f6d9882c1c2 /drivers/net/wireless/ath/ath9k/hw.c
parent1047d5edd4838f27dc86f24676178f2249c446ea (diff)
ath9k_hw: fix ASPM setting for AR9003
The AR_WA register should not be read when in sleep state so add a variable we can stash its value into for when we need to set it. Additionally the AR_WA_D3_TO_L1_DISABLE_REAL (bit 16) needs to be removed. Cc: Aeolus Yang <aeolus.yang@atheros.com> Cc: Madhan Jaganathan <madhan.jaganathan@atheros.com> signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/hw.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 62597f4ca319..fb09042e2889 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -575,14 +575,8 @@ static int __ath9k_hw_init(struct ath_hw *ah)
575 * This enables PCIe low power mode. 575 * This enables PCIe low power mode.
576 */ 576 */
577 if (AR_SREV_9300_20_OR_LATER(ah)) { 577 if (AR_SREV_9300_20_OR_LATER(ah)) {
578 u32 regval;
579 unsigned int i; 578 unsigned int i;
580 579
581 /* Set Bits 16 and 17 in the AR_WA register. */
582 regval = REG_READ(ah, AR_WA);
583 regval |= 0x00030000;
584 REG_WRITE(ah, AR_WA, regval);
585
586 for (i = 0; i < ah->iniPcieSerdesLowPower.ia_rows; i++) { 580 for (i = 0; i < ah->iniPcieSerdesLowPower.ia_rows; i++) {
587 REG_WRITE(ah, 581 REG_WRITE(ah,
588 INI_RA(&ah->iniPcieSerdesLowPower, i, 0), 582 INI_RA(&ah->iniPcieSerdesLowPower, i, 0),
@@ -590,6 +584,15 @@ static int __ath9k_hw_init(struct ath_hw *ah)
590 } 584 }
591 } 585 }
592 586
587 /*
588 * Read back AR_WA into a permanent copy and set bits 14 and 17.
589 * We need to do this to avoid RMW of this register. We cannot
590 * read the reg when chip is asleep.
591 */
592 ah->WARegVal = REG_READ(ah, AR_WA);
593 ah->WARegVal |= (AR_WA_D3_L1_DISABLE |
594 AR_WA_ASPM_TIMER_BASED_DISABLE);
595
593 if (ah->is_pciexpress) 596 if (ah->is_pciexpress)
594 ath9k_hw_configpcipowersave(ah, 0, 0); 597 ath9k_hw_configpcipowersave(ah, 0, 0);
595 else 598 else
@@ -1009,6 +1012,11 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1009 1012
1010 ENABLE_REGWRITE_BUFFER(ah); 1013 ENABLE_REGWRITE_BUFFER(ah);
1011 1014
1015 if (AR_SREV_9300_20_OR_LATER(ah)) {
1016 REG_WRITE(ah, AR_WA, ah->WARegVal);
1017 udelay(10);
1018 }
1019
1012 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 1020 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1013 AR_RTC_FORCE_WAKE_ON_INT); 1021 AR_RTC_FORCE_WAKE_ON_INT);
1014 1022
@@ -1063,6 +1071,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
1063{ 1071{
1064 ENABLE_REGWRITE_BUFFER(ah); 1072 ENABLE_REGWRITE_BUFFER(ah);
1065 1073
1074 if (AR_SREV_9300_20_OR_LATER(ah)) {
1075 REG_WRITE(ah, AR_WA, ah->WARegVal);
1076 udelay(10);
1077 }
1078
1066 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 1079 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1067 AR_RTC_FORCE_WAKE_ON_INT); 1080 AR_RTC_FORCE_WAKE_ON_INT);
1068 1081
@@ -1099,6 +1112,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
1099 1112
1100static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) 1113static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
1101{ 1114{
1115 if (AR_SREV_9300_20_OR_LATER(ah)) {
1116 REG_WRITE(ah, AR_WA, ah->WARegVal);
1117 udelay(10);
1118 }
1119
1102 REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1120 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1103 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1121 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1104 1122
@@ -1768,6 +1786,11 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
1768 REG_CLR_BIT(ah, (AR_RTC_RESET), 1786 REG_CLR_BIT(ah, (AR_RTC_RESET),
1769 AR_RTC_RESET_EN); 1787 AR_RTC_RESET_EN);
1770 } 1788 }
1789
1790 /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */
1791 if (AR_SREV_9300_20_OR_LATER(ah))
1792 REG_WRITE(ah, AR_WA,
1793 ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
1771} 1794}
1772 1795
1773/* 1796/*
@@ -1794,6 +1817,10 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
1794 AR_RTC_FORCE_WAKE_EN); 1817 AR_RTC_FORCE_WAKE_EN);
1795 } 1818 }
1796 } 1819 }
1820
1821 /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */
1822 if (AR_SREV_9300_20_OR_LATER(ah))
1823 REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
1797} 1824}
1798 1825
1799static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) 1826static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
@@ -1801,6 +1828,12 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
1801 u32 val; 1828 u32 val;
1802 int i; 1829 int i;
1803 1830
1831 /* Set Bits 14 and 17 of AR_WA before powering on the chip. */
1832 if (AR_SREV_9300_20_OR_LATER(ah)) {
1833 REG_WRITE(ah, AR_WA, ah->WARegVal);
1834 udelay(10);
1835 }
1836
1804 if (setChip) { 1837 if (setChip) {
1805 if ((REG_READ(ah, AR_RTC_STATUS) & 1838 if ((REG_READ(ah, AR_RTC_STATUS) &
1806 AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { 1839 AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {