aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c45
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h5
4 files changed, 52 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 82c3ab756cd0..b4a9441a5ac7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -295,6 +295,8 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
295 /* Several PCIe massages to ensure proper behaviour */ 295 /* Several PCIe massages to ensure proper behaviour */
296 if (ah->config.pcie_waen) 296 if (ah->config.pcie_waen)
297 REG_WRITE(ah, AR_WA, ah->config.pcie_waen); 297 REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
298 else
299 REG_WRITE(ah, AR_WA, ah->WARegVal);
298 } 300 }
299} 301}
300 302
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) {
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 5ecbfcf7470a..6c6d47b0ed1b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -819,6 +819,12 @@ struct ath_hw {
819 819
820 u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; 820 u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
821 u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; 821 u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
822 /*
823 * Store the permanent value of Reg 0x4004in WARegVal
824 * so we dont have to R/M/W. We should not be reading
825 * this register when in sleep states.
826 */
827 u32 WARegVal;
822}; 828};
823 829
824static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) 830static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 3e3ccef438db..47be667fe4ff 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -704,6 +704,11 @@
704#define AR_WA_BIT7 (1 << 7) 704#define AR_WA_BIT7 (1 << 7)
705#define AR_WA_BIT23 (1 << 23) 705#define AR_WA_BIT23 (1 << 23)
706#define AR_WA_D3_L1_DISABLE (1 << 14) 706#define AR_WA_D3_L1_DISABLE (1 << 14)
707#define AR_WA_D3_TO_L1_DISABLE_REAL (1 << 16)
708#define AR_WA_ASPM_TIMER_BASED_DISABLE (1 << 17)
709#define AR_WA_RESET_EN (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */
710#define AR_WA_ANALOG_SHIFT (1 << 20)
711#define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */
707#define AR9285_WA_DEFAULT 0x004a050b 712#define AR9285_WA_DEFAULT 0x004a050b
708#define AR9280_WA_DEFAULT 0x0040073b 713#define AR9280_WA_DEFAULT 0x0040073b
709#define AR_WA_DEFAULT 0x0000073f 714#define AR_WA_DEFAULT 0x0000073f