diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/hw.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 65 |
1 files changed, 51 insertions, 14 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9f01e50d5cda..338b07502f1a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -495,6 +495,17 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
495 | if (ah->hw_version.devid == AR5416_AR9100_DEVID) | 495 | if (ah->hw_version.devid == AR5416_AR9100_DEVID) |
496 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; | 496 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; |
497 | 497 | ||
498 | ath9k_hw_read_revisions(ah); | ||
499 | |||
500 | /* | ||
501 | * Read back AR_WA into a permanent copy and set bits 14 and 17. | ||
502 | * We need to do this to avoid RMW of this register. We cannot | ||
503 | * read the reg when chip is asleep. | ||
504 | */ | ||
505 | ah->WARegVal = REG_READ(ah, AR_WA); | ||
506 | ah->WARegVal |= (AR_WA_D3_L1_DISABLE | | ||
507 | AR_WA_ASPM_TIMER_BASED_DISABLE); | ||
508 | |||
498 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { | 509 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { |
499 | ath_err(common, "Couldn't reset chip\n"); | 510 | ath_err(common, "Couldn't reset chip\n"); |
500 | return -EIO; | 511 | return -EIO; |
@@ -563,14 +574,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
563 | 574 | ||
564 | ath9k_hw_init_mode_regs(ah); | 575 | ath9k_hw_init_mode_regs(ah); |
565 | 576 | ||
566 | /* | ||
567 | * Read back AR_WA into a permanent copy and set bits 14 and 17. | ||
568 | * We need to do this to avoid RMW of this register. We cannot | ||
569 | * read the reg when chip is asleep. | ||
570 | */ | ||
571 | ah->WARegVal = REG_READ(ah, AR_WA); | ||
572 | ah->WARegVal |= (AR_WA_D3_L1_DISABLE | | ||
573 | AR_WA_ASPM_TIMER_BASED_DISABLE); | ||
574 | 577 | ||
575 | if (ah->is_pciexpress) | 578 | if (ah->is_pciexpress) |
576 | ath9k_hw_configpcipowersave(ah, 0, 0); | 579 | ath9k_hw_configpcipowersave(ah, 0, 0); |
@@ -668,14 +671,51 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) | |||
668 | REGWRITE_BUFFER_FLUSH(ah); | 671 | REGWRITE_BUFFER_FLUSH(ah); |
669 | } | 672 | } |
670 | 673 | ||
674 | unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | ||
675 | { | ||
676 | REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) & ~(PLL3_DO_MEAS_MASK))); | ||
677 | udelay(100); | ||
678 | REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) | PLL3_DO_MEAS_MASK)); | ||
679 | |||
680 | while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) | ||
681 | udelay(100); | ||
682 | |||
683 | return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; | ||
684 | } | ||
685 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); | ||
686 | |||
687 | #define DPLL2_KD_VAL 0x3D | ||
688 | #define DPLL2_KI_VAL 0x06 | ||
689 | #define DPLL3_PHASE_SHIFT_VAL 0x1 | ||
690 | |||
671 | static void ath9k_hw_init_pll(struct ath_hw *ah, | 691 | static void ath9k_hw_init_pll(struct ath_hw *ah, |
672 | struct ath9k_channel *chan) | 692 | struct ath9k_channel *chan) |
673 | { | 693 | { |
674 | u32 pll; | 694 | u32 pll; |
675 | 695 | ||
676 | if (AR_SREV_9485(ah)) | 696 | if (AR_SREV_9485(ah)) { |
697 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); | ||
698 | REG_WRITE(ah, AR_CH0_DDR_DPLL2, 0x19e82f01); | ||
699 | |||
700 | REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, | ||
701 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | ||
702 | |||
703 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); | ||
704 | udelay(1000); | ||
705 | |||
677 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); | 706 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); |
678 | 707 | ||
708 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
709 | AR_CH0_DPLL2_KD, DPLL2_KD_VAL); | ||
710 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
711 | AR_CH0_DPLL2_KI, DPLL2_KI_VAL); | ||
712 | |||
713 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | ||
714 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | ||
715 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c); | ||
716 | udelay(1000); | ||
717 | } | ||
718 | |||
679 | pll = ath9k_hw_compute_pll_control(ah, chan); | 719 | pll = ath9k_hw_compute_pll_control(ah, chan); |
680 | 720 | ||
681 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | 721 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); |
@@ -1060,7 +1100,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) | |||
1060 | REG_WRITE(ah, AR_RC, AR_RC_AHB); | 1100 | REG_WRITE(ah, AR_RC, AR_RC_AHB); |
1061 | 1101 | ||
1062 | REG_WRITE(ah, AR_RTC_RESET, 0); | 1102 | REG_WRITE(ah, AR_RTC_RESET, 0); |
1063 | udelay(2); | ||
1064 | 1103 | ||
1065 | REGWRITE_BUFFER_FLUSH(ah); | 1104 | REGWRITE_BUFFER_FLUSH(ah); |
1066 | 1105 | ||
@@ -1082,8 +1121,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) | |||
1082 | return false; | 1121 | return false; |
1083 | } | 1122 | } |
1084 | 1123 | ||
1085 | ath9k_hw_read_revisions(ah); | ||
1086 | |||
1087 | return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM); | 1124 | return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM); |
1088 | } | 1125 | } |
1089 | 1126 | ||
@@ -1348,8 +1385,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1348 | ath9k_hw_spur_mitigate_freq(ah, chan); | 1385 | ath9k_hw_spur_mitigate_freq(ah, chan); |
1349 | ah->eep_ops->set_board_values(ah, chan); | 1386 | ah->eep_ops->set_board_values(ah, chan); |
1350 | 1387 | ||
1351 | ath9k_hw_set_operating_mode(ah, ah->opmode); | ||
1352 | |||
1353 | ENABLE_REGWRITE_BUFFER(ah); | 1388 | ENABLE_REGWRITE_BUFFER(ah); |
1354 | 1389 | ||
1355 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); | 1390 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); |
@@ -1367,6 +1402,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1367 | 1402 | ||
1368 | REGWRITE_BUFFER_FLUSH(ah); | 1403 | REGWRITE_BUFFER_FLUSH(ah); |
1369 | 1404 | ||
1405 | ath9k_hw_set_operating_mode(ah, ah->opmode); | ||
1406 | |||
1370 | r = ath9k_hw_rf_set_freq(ah, chan); | 1407 | r = ath9k_hw_rf_set_freq(ah, chan); |
1371 | if (r) | 1408 | if (r) |
1372 | return r; | 1409 | return r; |