diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/hw.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 125 |
1 files changed, 93 insertions, 32 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 045abd557840..58f3d4210338 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -247,6 +247,17 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) | |||
247 | { | 247 | { |
248 | u32 val; | 248 | u32 val; |
249 | 249 | ||
250 | switch (ah->hw_version.devid) { | ||
251 | case AR5416_AR9100_DEVID: | ||
252 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; | ||
253 | break; | ||
254 | case AR9300_DEVID_AR9340: | ||
255 | ah->hw_version.macVersion = AR_SREV_VERSION_9340; | ||
256 | val = REG_READ(ah, AR_SREV); | ||
257 | ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); | ||
258 | return; | ||
259 | } | ||
260 | |||
250 | val = REG_READ(ah, AR_SREV) & AR_SREV_ID; | 261 | val = REG_READ(ah, AR_SREV) & AR_SREV_ID; |
251 | 262 | ||
252 | if (val == 0xFF) { | 263 | if (val == 0xFF) { |
@@ -462,7 +473,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah) | |||
462 | return ecode; | 473 | return ecode; |
463 | } | 474 | } |
464 | 475 | ||
465 | if (!AR_SREV_9100(ah)) { | 476 | if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) { |
466 | ath9k_hw_ani_setup(ah); | 477 | ath9k_hw_ani_setup(ah); |
467 | ath9k_hw_ani_init(ah); | 478 | ath9k_hw_ani_init(ah); |
468 | } | 479 | } |
@@ -484,9 +495,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
484 | struct ath_common *common = ath9k_hw_common(ah); | 495 | struct ath_common *common = ath9k_hw_common(ah); |
485 | int r = 0; | 496 | int r = 0; |
486 | 497 | ||
487 | if (ah->hw_version.devid == AR5416_AR9100_DEVID) | ||
488 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; | ||
489 | |||
490 | ath9k_hw_read_revisions(ah); | 498 | ath9k_hw_read_revisions(ah); |
491 | 499 | ||
492 | /* | 500 | /* |
@@ -544,6 +552,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
544 | case AR_SREV_VERSION_9271: | 552 | case AR_SREV_VERSION_9271: |
545 | case AR_SREV_VERSION_9300: | 553 | case AR_SREV_VERSION_9300: |
546 | case AR_SREV_VERSION_9485: | 554 | case AR_SREV_VERSION_9485: |
555 | case AR_SREV_VERSION_9340: | ||
547 | break; | 556 | break; |
548 | default: | 557 | default: |
549 | ath_err(common, | 558 | ath_err(common, |
@@ -552,7 +561,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
552 | return -EOPNOTSUPP; | 561 | return -EOPNOTSUPP; |
553 | } | 562 | } |
554 | 563 | ||
555 | if (AR_SREV_9271(ah) || AR_SREV_9100(ah)) | 564 | if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah)) |
556 | ah->is_pciexpress = false; | 565 | ah->is_pciexpress = false; |
557 | 566 | ||
558 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); | 567 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); |
@@ -621,6 +630,7 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
621 | case AR2427_DEVID_PCIE: | 630 | case AR2427_DEVID_PCIE: |
622 | case AR9300_DEVID_PCIE: | 631 | case AR9300_DEVID_PCIE: |
623 | case AR9300_DEVID_AR9485_PCIE: | 632 | case AR9300_DEVID_AR9485_PCIE: |
633 | case AR9300_DEVID_AR9340: | ||
624 | break; | 634 | break; |
625 | default: | 635 | default: |
626 | if (common->bus_ops->ath_bus_type == ATH_USB) | 636 | if (common->bus_ops->ath_bus_type == ATH_USB) |
@@ -663,7 +673,7 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) | |||
663 | REGWRITE_BUFFER_FLUSH(ah); | 673 | REGWRITE_BUFFER_FLUSH(ah); |
664 | } | 674 | } |
665 | 675 | ||
666 | unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | 676 | u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) |
667 | { | 677 | { |
668 | REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); | 678 | REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); |
669 | udelay(100); | 679 | udelay(100); |
@@ -676,7 +686,6 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | |||
676 | } | 686 | } |
677 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); | 687 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); |
678 | 688 | ||
679 | #define DPLL3_PHASE_SHIFT_VAL 0x1 | ||
680 | static void ath9k_hw_init_pll(struct ath_hw *ah, | 689 | static void ath9k_hw_init_pll(struct ath_hw *ah, |
681 | struct ath9k_channel *chan) | 690 | struct ath9k_channel *chan) |
682 | { | 691 | { |
@@ -713,16 +722,48 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
713 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | 722 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, |
714 | AR_CH0_BB_DPLL2_PLL_PWD, 0x0); | 723 | AR_CH0_BB_DPLL2_PLL_PWD, 0x0); |
715 | udelay(1000); | 724 | udelay(1000); |
725 | } else if (AR_SREV_9340(ah)) { | ||
726 | u32 regval, pll2_divint, pll2_divfrac, refdiv; | ||
716 | 727 | ||
717 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | 728 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); |
718 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | 729 | udelay(1000); |
730 | |||
731 | REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16); | ||
732 | udelay(100); | ||
733 | |||
734 | if (ah->is_clk_25mhz) { | ||
735 | pll2_divint = 0x54; | ||
736 | pll2_divfrac = 0x1eb85; | ||
737 | refdiv = 3; | ||
738 | } else { | ||
739 | pll2_divint = 88; | ||
740 | pll2_divfrac = 0; | ||
741 | refdiv = 5; | ||
742 | } | ||
743 | |||
744 | regval = REG_READ(ah, AR_PHY_PLL_MODE); | ||
745 | regval |= (0x1 << 16); | ||
746 | REG_WRITE(ah, AR_PHY_PLL_MODE, regval); | ||
747 | udelay(100); | ||
748 | |||
749 | REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) | | ||
750 | (pll2_divint << 18) | pll2_divfrac); | ||
751 | udelay(100); | ||
752 | |||
753 | regval = REG_READ(ah, AR_PHY_PLL_MODE); | ||
754 | regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) | | ||
755 | (0x4 << 26) | (0x18 << 19); | ||
756 | REG_WRITE(ah, AR_PHY_PLL_MODE, regval); | ||
757 | REG_WRITE(ah, AR_PHY_PLL_MODE, | ||
758 | REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff); | ||
759 | udelay(1000); | ||
719 | } | 760 | } |
720 | 761 | ||
721 | pll = ath9k_hw_compute_pll_control(ah, chan); | 762 | pll = ath9k_hw_compute_pll_control(ah, chan); |
722 | 763 | ||
723 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | 764 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); |
724 | 765 | ||
725 | if (AR_SREV_9485(ah)) | 766 | if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) |
726 | udelay(1000); | 767 | udelay(1000); |
727 | 768 | ||
728 | /* Switch the core clock for ar9271 to 117Mhz */ | 769 | /* Switch the core clock for ar9271 to 117Mhz */ |
@@ -734,17 +775,34 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
734 | udelay(RTC_PLL_SETTLE_DELAY); | 775 | udelay(RTC_PLL_SETTLE_DELAY); |
735 | 776 | ||
736 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); | 777 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); |
778 | |||
779 | if (AR_SREV_9340(ah)) { | ||
780 | if (ah->is_clk_25mhz) { | ||
781 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1); | ||
782 | REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7); | ||
783 | REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae); | ||
784 | } else { | ||
785 | REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1); | ||
786 | REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400); | ||
787 | REG_WRITE(ah, AR_SLP32_INC, 0x0001e800); | ||
788 | } | ||
789 | udelay(100); | ||
790 | } | ||
737 | } | 791 | } |
738 | 792 | ||
739 | static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | 793 | static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, |
740 | enum nl80211_iftype opmode) | 794 | enum nl80211_iftype opmode) |
741 | { | 795 | { |
796 | u32 sync_default = AR_INTR_SYNC_DEFAULT; | ||
742 | u32 imr_reg = AR_IMR_TXERR | | 797 | u32 imr_reg = AR_IMR_TXERR | |
743 | AR_IMR_TXURN | | 798 | AR_IMR_TXURN | |
744 | AR_IMR_RXERR | | 799 | AR_IMR_RXERR | |
745 | AR_IMR_RXORN | | 800 | AR_IMR_RXORN | |
746 | AR_IMR_BCNMISC; | 801 | AR_IMR_BCNMISC; |
747 | 802 | ||
803 | if (AR_SREV_9340(ah)) | ||
804 | sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; | ||
805 | |||
748 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 806 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
749 | imr_reg |= AR_IMR_RXOK_HP; | 807 | imr_reg |= AR_IMR_RXOK_HP; |
750 | if (ah->config.rx_intr_mitigation) | 808 | if (ah->config.rx_intr_mitigation) |
@@ -775,7 +833,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
775 | 833 | ||
776 | if (!AR_SREV_9100(ah)) { | 834 | if (!AR_SREV_9100(ah)) { |
777 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); | 835 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); |
778 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT); | 836 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default); |
779 | REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); | 837 | REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); |
780 | } | 838 | } |
781 | 839 | ||
@@ -1487,7 +1545,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1487 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | 1545 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); |
1488 | } | 1546 | } |
1489 | #ifdef __BIG_ENDIAN | 1547 | #ifdef __BIG_ENDIAN |
1490 | else | 1548 | else if (AR_SREV_9340(ah)) |
1549 | REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); | ||
1550 | else | ||
1491 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | 1551 | REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); |
1492 | #endif | 1552 | #endif |
1493 | } | 1553 | } |
@@ -1793,7 +1853,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1793 | struct ath_common *common = ath9k_hw_common(ah); | 1853 | struct ath_common *common = ath9k_hw_common(ah); |
1794 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 1854 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
1795 | 1855 | ||
1796 | u16 capField = 0, eeval; | 1856 | u16 eeval; |
1797 | u8 ant_div_ctl1, tx_chainmask, rx_chainmask; | 1857 | u8 ant_div_ctl1, tx_chainmask, rx_chainmask; |
1798 | 1858 | ||
1799 | eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); | 1859 | eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); |
@@ -1804,8 +1864,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1804 | eeval |= AR9285_RDEXT_DEFAULT; | 1864 | eeval |= AR9285_RDEXT_DEFAULT; |
1805 | regulatory->current_rd_ext = eeval; | 1865 | regulatory->current_rd_ext = eeval; |
1806 | 1866 | ||
1807 | capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP); | ||
1808 | |||
1809 | if (ah->opmode != NL80211_IFTYPE_AP && | 1867 | if (ah->opmode != NL80211_IFTYPE_AP && |
1810 | ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { | 1868 | ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { |
1811 | if (regulatory->current_rd == 0x64 || | 1869 | if (regulatory->current_rd == 0x64 || |
@@ -1898,15 +1956,23 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
1898 | else | 1956 | else |
1899 | pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; | 1957 | pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; |
1900 | 1958 | ||
1901 | if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) { | 1959 | if (common->btcoex_enabled) { |
1902 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; | 1960 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
1903 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; | ||
1904 | |||
1905 | if (AR_SREV_9285(ah)) { | ||
1906 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; | 1961 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; |
1907 | btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO; | 1962 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300; |
1908 | } else { | 1963 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300; |
1909 | btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; | 1964 | btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300; |
1965 | } else if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
1966 | btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280; | ||
1967 | btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280; | ||
1968 | |||
1969 | if (AR_SREV_9285(ah)) { | ||
1970 | btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; | ||
1971 | btcoex_hw->btpriority_gpio = | ||
1972 | ATH_BTPRIORITY_GPIO_9285; | ||
1973 | } else { | ||
1974 | btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; | ||
1975 | } | ||
1910 | } | 1976 | } |
1911 | } else { | 1977 | } else { |
1912 | btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; | 1978 | btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; |
@@ -2359,11 +2425,11 @@ EXPORT_SYMBOL(ath_gen_timer_alloc); | |||
2359 | 2425 | ||
2360 | void ath9k_hw_gen_timer_start(struct ath_hw *ah, | 2426 | void ath9k_hw_gen_timer_start(struct ath_hw *ah, |
2361 | struct ath_gen_timer *timer, | 2427 | struct ath_gen_timer *timer, |
2362 | u32 timer_next, | 2428 | u32 trig_timeout, |
2363 | u32 timer_period) | 2429 | u32 timer_period) |
2364 | { | 2430 | { |
2365 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | 2431 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; |
2366 | u32 tsf; | 2432 | u32 tsf, timer_next; |
2367 | 2433 | ||
2368 | BUG_ON(!timer_period); | 2434 | BUG_ON(!timer_period); |
2369 | 2435 | ||
@@ -2371,18 +2437,13 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah, | |||
2371 | 2437 | ||
2372 | tsf = ath9k_hw_gettsf32(ah); | 2438 | tsf = ath9k_hw_gettsf32(ah); |
2373 | 2439 | ||
2440 | timer_next = tsf + trig_timeout; | ||
2441 | |||
2374 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER, | 2442 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER, |
2375 | "current tsf %x period %x timer_next %x\n", | 2443 | "current tsf %x period %x timer_next %x\n", |
2376 | tsf, timer_period, timer_next); | 2444 | tsf, timer_period, timer_next); |
2377 | 2445 | ||
2378 | /* | 2446 | /* |
2379 | * Pull timer_next forward if the current TSF already passed it | ||
2380 | * because of software latency | ||
2381 | */ | ||
2382 | if (timer_next < tsf) | ||
2383 | timer_next = tsf + timer_period; | ||
2384 | |||
2385 | /* | ||
2386 | * Program generic timer registers | 2447 | * Program generic timer registers |
2387 | */ | 2448 | */ |
2388 | REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr, | 2449 | REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr, |