diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/hw.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 202 |
1 files changed, 121 insertions, 81 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index b6c6cca0781..ca7694caf36 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -842,7 +842,7 @@ static void ath9k_hw_init_mode_regs(struct ath_hw *ah) | |||
842 | 842 | ||
843 | static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) | 843 | static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) |
844 | { | 844 | { |
845 | if (AR_SREV_9287_11(ah)) | 845 | if (AR_SREV_9287_11_OR_LATER(ah)) |
846 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 846 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
847 | ar9287Modes_rx_gain_9287_1_1, | 847 | ar9287Modes_rx_gain_9287_1_1, |
848 | ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6); | 848 | ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6); |
@@ -853,7 +853,7 @@ static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) | |||
853 | else if (AR_SREV_9280_20(ah)) | 853 | else if (AR_SREV_9280_20(ah)) |
854 | ath9k_hw_init_rxgain_ini(ah); | 854 | ath9k_hw_init_rxgain_ini(ah); |
855 | 855 | ||
856 | if (AR_SREV_9287_11(ah)) { | 856 | if (AR_SREV_9287_11_OR_LATER(ah)) { |
857 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 857 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
858 | ar9287Modes_tx_gain_9287_1_1, | 858 | ar9287Modes_tx_gain_9287_1_1, |
859 | ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6); | 859 | ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6); |
@@ -965,7 +965,7 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
965 | ath9k_hw_init_mode_regs(ah); | 965 | ath9k_hw_init_mode_regs(ah); |
966 | 966 | ||
967 | if (ah->is_pciexpress) | 967 | if (ah->is_pciexpress) |
968 | ath9k_hw_configpcipowersave(ah, 0); | 968 | ath9k_hw_configpcipowersave(ah, 0, 0); |
969 | else | 969 | else |
970 | ath9k_hw_disablepcie(ah); | 970 | ath9k_hw_disablepcie(ah); |
971 | 971 | ||
@@ -1273,6 +1273,15 @@ static void ath9k_hw_override_ini(struct ath_hw *ah, | |||
1273 | */ | 1273 | */ |
1274 | REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); | 1274 | REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); |
1275 | 1275 | ||
1276 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1277 | val = REG_READ(ah, AR_PCU_MISC_MODE2) & | ||
1278 | (~AR_PCU_MISC_MODE2_HWWAR1); | ||
1279 | |||
1280 | if (AR_SREV_9287_10_OR_LATER(ah)) | ||
1281 | val = val & (~AR_PCU_MISC_MODE2_HWWAR2); | ||
1282 | |||
1283 | REG_WRITE(ah, AR_PCU_MISC_MODE2, val); | ||
1284 | } | ||
1276 | 1285 | ||
1277 | if (!AR_SREV_5416_20_OR_LATER(ah) || | 1286 | if (!AR_SREV_5416_20_OR_LATER(ah) || |
1278 | AR_SREV_9280_10_OR_LATER(ah)) | 1287 | AR_SREV_9280_10_OR_LATER(ah)) |
@@ -1784,7 +1793,7 @@ static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1784 | static bool ath9k_hw_chip_reset(struct ath_hw *ah, | 1793 | static bool ath9k_hw_chip_reset(struct ath_hw *ah, |
1785 | struct ath9k_channel *chan) | 1794 | struct ath9k_channel *chan) |
1786 | { | 1795 | { |
1787 | if (OLC_FOR_AR9280_20_LATER) { | 1796 | if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) { |
1788 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) | 1797 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) |
1789 | return false; | 1798 | return false; |
1790 | } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) | 1799 | } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) |
@@ -2338,6 +2347,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2338 | struct ath9k_channel *curchan = ah->curchan; | 2347 | struct ath9k_channel *curchan = ah->curchan; |
2339 | u32 saveDefAntenna; | 2348 | u32 saveDefAntenna; |
2340 | u32 macStaId1; | 2349 | u32 macStaId1; |
2350 | u64 tsf = 0; | ||
2341 | int i, rx_chainmask, r; | 2351 | int i, rx_chainmask, r; |
2342 | 2352 | ||
2343 | ah->extprotspacing = sc->ht_extprotspacing; | 2353 | ah->extprotspacing = sc->ht_extprotspacing; |
@@ -2347,7 +2357,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2347 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | 2357 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
2348 | return -EIO; | 2358 | return -EIO; |
2349 | 2359 | ||
2350 | if (curchan) | 2360 | if (curchan && !ah->chip_fullsleep) |
2351 | ath9k_hw_getnf(ah, curchan); | 2361 | ath9k_hw_getnf(ah, curchan); |
2352 | 2362 | ||
2353 | if (bChannelChange && | 2363 | if (bChannelChange && |
@@ -2356,8 +2366,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2356 | (chan->channel != ah->curchan->channel) && | 2366 | (chan->channel != ah->curchan->channel) && |
2357 | ((chan->channelFlags & CHANNEL_ALL) == | 2367 | ((chan->channelFlags & CHANNEL_ALL) == |
2358 | (ah->curchan->channelFlags & CHANNEL_ALL)) && | 2368 | (ah->curchan->channelFlags & CHANNEL_ALL)) && |
2359 | (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) && | 2369 | !(AR_SREV_9280(ah) || IS_CHAN_A_5MHZ_SPACED(chan) || |
2360 | !IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) { | 2370 | IS_CHAN_A_5MHZ_SPACED(ah->curchan))) { |
2361 | 2371 | ||
2362 | if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) { | 2372 | if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) { |
2363 | ath9k_hw_loadnf(ah, ah->curchan); | 2373 | ath9k_hw_loadnf(ah, ah->curchan); |
@@ -2372,6 +2382,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2372 | 2382 | ||
2373 | macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; | 2383 | macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; |
2374 | 2384 | ||
2385 | /* For chips on which RTC reset is done, save TSF before it gets cleared */ | ||
2386 | if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) | ||
2387 | tsf = ath9k_hw_gettsf64(ah); | ||
2388 | |||
2375 | saveLedState = REG_READ(ah, AR_CFG_LED) & | 2389 | saveLedState = REG_READ(ah, AR_CFG_LED) & |
2376 | (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | | 2390 | (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | |
2377 | AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW); | 2391 | AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW); |
@@ -2398,6 +2412,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2398 | udelay(50); | 2412 | udelay(50); |
2399 | } | 2413 | } |
2400 | 2414 | ||
2415 | /* Restore TSF */ | ||
2416 | if (tsf && AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) | ||
2417 | ath9k_hw_settsf64(ah, tsf); | ||
2418 | |||
2401 | if (AR_SREV_9280_10_OR_LATER(ah)) | 2419 | if (AR_SREV_9280_10_OR_LATER(ah)) |
2402 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); | 2420 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); |
2403 | 2421 | ||
@@ -3005,9 +3023,10 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
3005 | * Programming the SerDes must go through the same 288 bit serial shift | 3023 | * Programming the SerDes must go through the same 288 bit serial shift |
3006 | * register as the other analog registers. Hence the 9 writes. | 3024 | * register as the other analog registers. Hence the 9 writes. |
3007 | */ | 3025 | */ |
3008 | void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore) | 3026 | void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off) |
3009 | { | 3027 | { |
3010 | u8 i; | 3028 | u8 i; |
3029 | u32 val; | ||
3011 | 3030 | ||
3012 | if (ah->is_pciexpress != true) | 3031 | if (ah->is_pciexpress != true) |
3013 | return; | 3032 | return; |
@@ -3017,84 +3036,113 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore) | |||
3017 | return; | 3036 | return; |
3018 | 3037 | ||
3019 | /* Nothing to do on restore for 11N */ | 3038 | /* Nothing to do on restore for 11N */ |
3020 | if (restore) | 3039 | if (!restore) { |
3021 | return; | 3040 | if (AR_SREV_9280_20_OR_LATER(ah)) { |
3041 | /* | ||
3042 | * AR9280 2.0 or later chips use SerDes values from the | ||
3043 | * initvals.h initialized depending on chipset during | ||
3044 | * ath9k_hw_init() | ||
3045 | */ | ||
3046 | for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) { | ||
3047 | REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0), | ||
3048 | INI_RA(&ah->iniPcieSerdes, i, 1)); | ||
3049 | } | ||
3050 | } else if (AR_SREV_9280(ah) && | ||
3051 | (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) { | ||
3052 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00); | ||
3053 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | ||
3054 | |||
3055 | /* RX shut off when elecidle is asserted */ | ||
3056 | REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019); | ||
3057 | REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820); | ||
3058 | REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560); | ||
3059 | |||
3060 | /* Shut off CLKREQ active in L1 */ | ||
3061 | if (ah->config.pcie_clock_req) | ||
3062 | REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc); | ||
3063 | else | ||
3064 | REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd); | ||
3022 | 3065 | ||
3023 | if (AR_SREV_9280_20_OR_LATER(ah)) { | 3066 | REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); |
3024 | /* | 3067 | REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); |
3025 | * AR9280 2.0 or later chips use SerDes values from the | 3068 | REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007); |
3026 | * initvals.h initialized depending on chipset during | ||
3027 | * ath9k_hw_init() | ||
3028 | */ | ||
3029 | for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) { | ||
3030 | REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0), | ||
3031 | INI_RA(&ah->iniPcieSerdes, i, 1)); | ||
3032 | } | ||
3033 | } else if (AR_SREV_9280(ah) && | ||
3034 | (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) { | ||
3035 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00); | ||
3036 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | ||
3037 | 3069 | ||
3038 | /* RX shut off when elecidle is asserted */ | 3070 | /* Load the new settings */ |
3039 | REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019); | 3071 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); |
3040 | REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820); | ||
3041 | REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560); | ||
3042 | 3072 | ||
3043 | /* Shut off CLKREQ active in L1 */ | 3073 | } else { |
3044 | if (ah->config.pcie_clock_req) | 3074 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); |
3045 | REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc); | 3075 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); |
3046 | else | ||
3047 | REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd); | ||
3048 | |||
3049 | REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); | ||
3050 | REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); | ||
3051 | REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007); | ||
3052 | 3076 | ||
3053 | /* Load the new settings */ | 3077 | /* RX shut off when elecidle is asserted */ |
3054 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | 3078 | REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039); |
3079 | REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824); | ||
3080 | REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579); | ||
3055 | 3081 | ||
3056 | } else { | 3082 | /* |
3057 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); | 3083 | * Ignore ah->ah_config.pcie_clock_req setting for |
3058 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | 3084 | * pre-AR9280 11n |
3085 | */ | ||
3086 | REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff); | ||
3059 | 3087 | ||
3060 | /* RX shut off when elecidle is asserted */ | 3088 | REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); |
3061 | REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039); | 3089 | REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); |
3062 | REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824); | 3090 | REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007); |
3063 | REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579); | ||
3064 | 3091 | ||
3065 | /* | 3092 | /* Load the new settings */ |
3066 | * Ignore ah->ah_config.pcie_clock_req setting for | 3093 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); |
3067 | * pre-AR9280 11n | 3094 | } |
3068 | */ | ||
3069 | REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff); | ||
3070 | 3095 | ||
3071 | REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); | 3096 | udelay(1000); |
3072 | REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); | ||
3073 | REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007); | ||
3074 | 3097 | ||
3075 | /* Load the new settings */ | 3098 | /* set bit 19 to allow forcing of pcie core into L1 state */ |
3076 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | 3099 | REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); |
3077 | } | ||
3078 | 3100 | ||
3079 | udelay(1000); | 3101 | /* Several PCIe massages to ensure proper behaviour */ |
3102 | if (ah->config.pcie_waen) { | ||
3103 | val = ah->config.pcie_waen; | ||
3104 | if (!power_off) | ||
3105 | val &= (~AR_WA_D3_L1_DISABLE); | ||
3106 | } else { | ||
3107 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || | ||
3108 | AR_SREV_9287(ah)) { | ||
3109 | val = AR9285_WA_DEFAULT; | ||
3110 | if (!power_off) | ||
3111 | val &= (~AR_WA_D3_L1_DISABLE); | ||
3112 | } else if (AR_SREV_9280(ah)) { | ||
3113 | /* | ||
3114 | * On AR9280 chips bit 22 of 0x4004 needs to be | ||
3115 | * set otherwise card may disappear. | ||
3116 | */ | ||
3117 | val = AR9280_WA_DEFAULT; | ||
3118 | if (!power_off) | ||
3119 | val &= (~AR_WA_D3_L1_DISABLE); | ||
3120 | } else | ||
3121 | val = AR_WA_DEFAULT; | ||
3122 | } | ||
3080 | 3123 | ||
3081 | /* set bit 19 to allow forcing of pcie core into L1 state */ | 3124 | REG_WRITE(ah, AR_WA, val); |
3082 | REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); | 3125 | } |
3083 | 3126 | ||
3084 | /* Several PCIe massages to ensure proper behaviour */ | 3127 | if (power_off) { |
3085 | if (ah->config.pcie_waen) { | ||
3086 | REG_WRITE(ah, AR_WA, ah->config.pcie_waen); | ||
3087 | } else { | ||
3088 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || AR_SREV_9287(ah)) | ||
3089 | REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); | ||
3090 | /* | 3128 | /* |
3091 | * On AR9280 chips bit 22 of 0x4004 needs to be set to | 3129 | * Set PCIe workaround bits |
3092 | * otherwise card may disappear. | 3130 | * bit 14 in WA register (disable L1) should only |
3131 | * be set when device enters D3 and be cleared | ||
3132 | * when device comes back to D0. | ||
3093 | */ | 3133 | */ |
3094 | else if (AR_SREV_9280(ah)) | 3134 | if (ah->config.pcie_waen) { |
3095 | REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT); | 3135 | if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE) |
3096 | else | 3136 | REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE); |
3097 | REG_WRITE(ah, AR_WA, AR_WA_DEFAULT); | 3137 | } else { |
3138 | if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) || | ||
3139 | AR_SREV_9287(ah)) && | ||
3140 | (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) || | ||
3141 | (AR_SREV_9280(ah) && | ||
3142 | (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) { | ||
3143 | REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE); | ||
3144 | } | ||
3145 | } | ||
3098 | } | 3146 | } |
3099 | } | 3147 | } |
3100 | 3148 | ||
@@ -3652,15 +3700,7 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
3652 | } | 3700 | } |
3653 | #endif | 3701 | #endif |
3654 | 3702 | ||
3655 | if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || | 3703 | pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; |
3656 | (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) || | ||
3657 | (ah->hw_version.macVersion == AR_SREV_VERSION_9160) || | ||
3658 | (ah->hw_version.macVersion == AR_SREV_VERSION_9100) || | ||
3659 | (ah->hw_version.macVersion == AR_SREV_VERSION_9280) || | ||
3660 | (ah->hw_version.macVersion == AR_SREV_VERSION_9285)) | ||
3661 | pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; | ||
3662 | else | ||
3663 | pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; | ||
3664 | 3704 | ||
3665 | if (AR_SREV_9280(ah) || AR_SREV_9285(ah)) | 3705 | if (AR_SREV_9280(ah) || AR_SREV_9285(ah)) |
3666 | pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; | 3706 | pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; |