hw.c revision 9dd9b0dc1de8031a31b3eaebc6a9c0ab60612026
194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* 294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Copyright (c) 2008-2011 Atheros Communications Inc. 394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Permission to use, copy, modify, and/or distribute this software for any 594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * purpose with or without fee is hereby granted, provided that the above 694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * copyright notice and this permission notice appear in all copies. 794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 1694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 17559a4c318ca303880fc9f26d50711791c16ae2f3Andrea Merello#include <linux/io.h> 1894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include <linux/slab.h> 1994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include <linux/module.h> 2094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include <asm/unaligned.h> 2194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 2294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "hw.h" 2394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "hw-ops.h" 2494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "rc.h" 2594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "ar9003_mac.h" 2694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "ar9003_mci.h" 2794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "debug.h" 2894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#include "ath9k.h" 2994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 3094a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); 3194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 3294a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerMODULE_AUTHOR("Atheros Communications"); 33939161571c01670ecc7e33a6b880ed812a17bbc6Randy DunlapMODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); 3494a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerMODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); 3594a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerMODULE_LICENSE("Dual BSD/GPL"); 3694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 3794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic int __init ath9k_init(void) 38ea74fedced8235fb01fc317bcb8cd98d8aa71436Sean MacLennan{ 3994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return 0; 4094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 4194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingermodule_init(ath9k_init); 4294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 4394a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void __exit ath9k_exit(void) 4494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 45184f1938b29310a0df4298b57a7241832cb0813cSean MacLennan return; 4694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 472eed3dee92453c1798f0932613b1b66f0763ab2eLarry Fingermodule_exit(ath9k_exit); 482eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger 492eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger/* Private hardware callbacks */ 502eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger 5194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_init_cal_settings(struct ath_hw *ah) 5294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 5394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_private_ops(ah)->init_cal_settings(ah); 5494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 5594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 5694a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_init_mode_regs(struct ath_hw *ah) 5794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 5894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_private_ops(ah)->init_mode_regs(ah); 5994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 6094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 6194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic u32 ath9k_hw_compute_pll_control(struct ath_hw *ah, 6294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath9k_channel *chan) 6394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 6494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan); 6594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 6694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 6794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) 6894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 6994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_private_ops(ah)->init_mode_gain_regs) 7094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 7194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 7294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah); 738567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 7494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 7594a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah) 7694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 7794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* You will not have this callback if using the old ANI */ 788567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (!ath9k_hw_private_ops(ah)->ani_cache_ini_regs) 798567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return; 808567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 8194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_private_ops(ah)->ani_cache_ini_regs(ah); 8294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 8394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 8494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/********************/ 85cb76215448947ddcc133c4b1c2ff2d4a77e851e0Mike McCormack/* Helper Functions */ 8694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/********************/ 8794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 888567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger#ifdef CONFIG_ATH9K_DEBUGFS 898567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 9094a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause) 918567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 928567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger struct ath_softc *sc = common->priv; 9394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sync_cause) 948567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger sc->debug.stats.istats.sync_cause_all++; 958567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (sync_cause & AR_INTR_SYNC_RTC_IRQ) 968567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger sc->debug.stats.istats.sync_rtc_irq++; 9794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sync_cause & AR_INTR_SYNC_MAC_IRQ) 988567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger sc->debug.stats.istats.sync_mac_irq++; 998567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (sync_cause & AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS) 10094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sc->debug.stats.istats.eeprom_illegal_access++; 1018567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (sync_cause & AR_INTR_SYNC_APB_TIMEOUT) 1028567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger sc->debug.stats.istats.apb_timeout++; 10394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sync_cause & AR_INTR_SYNC_PCI_MODE_CONFLICT) 1048567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger sc->debug.stats.istats.pci_mode_conflict++; 1058567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) 10694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sc->debug.stats.istats.host1_fatal++; 10794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sync_cause & AR_INTR_SYNC_HOST1_PERR) 10894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sc->debug.stats.istats.host1_perr++; 10994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sync_cause & AR_INTR_SYNC_TRCV_FIFO_PERR) 11094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sc->debug.stats.istats.trcv_fifo_perr++; 11194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sync_cause & AR_INTR_SYNC_RADM_CPL_EP) 11294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sc->debug.stats.istats.radm_cpl_ep++; 11394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sync_cause & AR_INTR_SYNC_RADM_CPL_DLLP_ABORT) 11494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sc->debug.stats.istats.radm_cpl_dllp_abort++; 11594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sync_cause & AR_INTR_SYNC_RADM_CPL_TLP_ABORT) 11694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sc->debug.stats.istats.radm_cpl_tlp_abort++; 11794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sync_cause & AR_INTR_SYNC_RADM_CPL_ECRC_ERR) 11894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sc->debug.stats.istats.radm_cpl_ecrc_err++; 11994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) 1208567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger sc->debug.stats.istats.radm_cpl_timeout++; 1218567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) 1228567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger sc->debug.stats.istats.local_timeout++; 1238567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (sync_cause & AR_INTR_SYNC_PM_ACCESS) 1248567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger sc->debug.stats.istats.pm_access++; 1258567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (sync_cause & AR_INTR_SYNC_MAC_AWAKE) 1268567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger sc->debug.stats.istats.mac_awake++; 1278567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (sync_cause & AR_INTR_SYNC_MAC_ASLEEP) 1288567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger sc->debug.stats.istats.mac_asleep++; 12994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sync_cause & AR_INTR_SYNC_MAC_SLEEP_ACCESS) 1308567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger sc->debug.stats.istats.mac_sleep_access++; 1318567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 13294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#endif 13394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 13494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 13594a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_set_clockrate(struct ath_hw *ah) 13694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 13794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 13894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 13994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger unsigned int clockrate; 14094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 14194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* AR9287 v1.3+ uses async FIFO and runs the MAC at 117 MHz */ 14294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) 14394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger clockrate = 117; 14494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (!ah->curchan) /* should really check for CCK instead */ 14594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger clockrate = ATH9K_CLOCK_RATE_CCK; 14694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (conf->channel->band == IEEE80211_BAND_2GHZ) 14794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM; 14894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) 14994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; 15094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 1518567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM; 1528567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 1538567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (conf_is_ht40(conf)) 1548567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger clockrate *= 2; 15594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 15694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->curchan) { 15794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (IS_CHAN_HALF_RATE(ah->curchan)) 15894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger clockrate /= 2; 1593b83db43ccbb26863f38caccc1e7fae370f31e57Larry Finger if (IS_CHAN_QUARTER_RATE(ah->curchan)) 16094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger clockrate /= 4; 16194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 16294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 16394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger common->clockrate = clockrate; 16494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 16594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 16694a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) 16794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 16894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 16994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 17094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return usecs * common->clockrate; 17194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 172cd01712397ad428f443c05add5d7435e899c0ef1Justin P. Mattock 17394a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerbool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) 17494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 17594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int i; 17694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 17794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger BUG_ON(timeout < AH_TIME_QUANTUM); 17894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 17994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) { 18094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if ((REG_READ(ah, reg) & mask) == val) 18194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return true; 18294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 18394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(AH_TIME_QUANTUM); 18494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 18594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 18694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(ath9k_hw_common(ah), ANY, 18794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", 18894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger timeout, reg, REG_READ(ah, reg), mask, val); 18994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 19094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 19194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 19294a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_wait); 19394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 19494a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan, 19594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int hw_delay) 19694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 19794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (IS_CHAN_B(chan)) 19894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger hw_delay = (4 * hw_delay) / 22; 19994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 20094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger hw_delay /= 10; 20194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 20294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (IS_CHAN_HALF_RATE(chan)) 20394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger hw_delay *= 2; 20494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (IS_CHAN_QUARTER_RATE(chan)) 20594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger hw_delay *= 4; 20694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 20794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(hw_delay + BASE_ACTIVATE_DELAY); 20894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 20994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 21094a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, 21194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int column, unsigned int *writecnt) 21294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 21394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int r; 214d3b2c172518dceed0d1d68f5b90dde5a2f6a438dLarry Finger 21594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ENABLE_REGWRITE_BUFFER(ah); 2162eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger for (r = 0; r < array->ia_rows; r++) { 2172eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger REG_WRITE(ah, INI_RA(array, r, 0), 2182eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger INI_RA(array, r, column)); 2192eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger DO_DELAY(*writecnt); 2202eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger } 2212eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger REGWRITE_BUFFER_FLUSH(ah); 2222eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger} 2232eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger 2242eed3dee92453c1798f0932613b1b66f0763ab2eLarry Fingeru32 ath9k_hw_reverse_bits(u32 val, u32 n) 2252eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger{ 2262eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger u32 retval; 2272eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger int i; 2282eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger 2292eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger for (i = 0, retval = 0; i < n; i++) { 2302eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger retval = (retval << 1) | (val & 1); 2312eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger val >>= 1; 2322eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger } 23394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return retval; 2348567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 2358567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 2368567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingeru16 ath9k_hw_computetxtime(struct ath_hw *ah, 2378567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u8 phy, int kbps, 2388567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 frameLen, u16 rateix, 2398567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger bool shortPreamble) 2408567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 2418567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime; 2428567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 2438567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (kbps == 0) 2448567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return 0; 2458567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 2468567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger switch (phy) { 2478567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case WLAN_RC_PHY_CCK: 2488567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; 2498567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (shortPreamble) 2508567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger phyTime >>= 1; 2518567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger numBits = frameLen << 3; 2528567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps); 2538567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger break; 2548567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case WLAN_RC_PHY_OFDM: 2558567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) { 2568567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000; 2578567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger numBits = OFDM_PLCP_BITS + (frameLen << 3); 2588567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); 2598567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger txTime = OFDM_SIFS_TIME_QUARTER 2608567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger + OFDM_PREAMBLE_TIME_QUARTER 2618567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger + (numSymbols * OFDM_SYMBOL_TIME_QUARTER); 2628567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } else if (ah->curchan && 2638567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger IS_CHAN_HALF_RATE(ah->curchan)) { 26494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000; 26594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger numBits = OFDM_PLCP_BITS + (frameLen << 3); 26694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); 26794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger txTime = OFDM_SIFS_TIME_HALF + 26894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger OFDM_PREAMBLE_TIME_HALF 26994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger + (numSymbols * OFDM_SYMBOL_TIME_HALF); 27094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 27194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000; 27294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger numBits = OFDM_PLCP_BITS + (frameLen << 3); 27394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); 27494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME 27594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger + (numSymbols * OFDM_SYMBOL_TIME); 27694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 27794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 27894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger default: 27994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(ath9k_hw_common(ah), 28094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "Unknown phy %u (rate ix %u)\n", phy, rateix); 28194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger txTime = 0; 2828567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger break; 28394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 28494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 28594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return txTime; 28694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 28794a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_computetxtime); 28894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 28994a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_get_channel_centers(struct ath_hw *ah, 29094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath9k_channel *chan, 29194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct chan_centers *centers) 29294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 29394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int8_t extoff; 29494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 29594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!IS_CHAN_HT40(chan)) { 29694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger centers->ctl_center = centers->ext_center = 29794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger centers->synth_center = chan->channel; 29894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 29994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 30094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 30194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if ((chan->chanmode == CHANNEL_A_HT40PLUS) || 30294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (chan->chanmode == CHANNEL_G_HT40PLUS)) { 30394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger centers->synth_center = 3048567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger chan->channel + HT40_CHANNEL_CENTER_SHIFT; 30594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger extoff = 1; 30694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 30794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger centers->synth_center = 30894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger chan->channel - HT40_CHANNEL_CENTER_SHIFT; 30994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger extoff = -1; 31094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 31194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 31294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger centers->ctl_center = 3138567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT); 31494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 25 MHz spacing is supported by hw but not on upper layers */ 31594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger centers->ext_center = 31694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT); 31794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 31894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 31994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/******************/ 320839370c5723a42cde6537fced66af1d2736054aaLarry Finger/* Chip Revisions */ 32194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/******************/ 32294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 32394a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_read_revisions(struct ath_hw *ah) 32494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 32594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 val; 32694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 32794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger switch (ah->hw_version.devid) { 32894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR5416_AR9100_DEVID: 32994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.macVersion = AR_SREV_VERSION_9100; 33094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 33194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR9300_DEVID_AR9330: 33294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.macVersion = AR_SREV_VERSION_9330; 33394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->get_mac_revision) { 33494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.macRev = ah->get_mac_revision(); 33594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 33694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val = REG_READ(ah, AR_SREV); 33794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); 33894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 3398567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return; 340839370c5723a42cde6537fced66af1d2736054aaLarry Finger case AR9300_DEVID_AR9340: 34194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.macVersion = AR_SREV_VERSION_9340; 342bb5e482246e0f41c3b39f758c61bdf75f191cbccLarry Finger val = REG_READ(ah, AR_SREV); 34394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); 34494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 34594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 34694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 34794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val = REG_READ(ah, AR_SREV) & AR_SREV_ID; 34894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 34994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (val == 0xFF) { 35094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val = REG_READ(ah, AR_SREV); 35194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.macVersion = 35294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S; 35394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); 35494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 35594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9462(ah)) 35694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->is_pciexpress = true; 35794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 35894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->is_pciexpress = (val & 35994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_SREV_TYPE2_HOST_MODE) ? 0 : 1; 36094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 36194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!AR_SREV_9100(ah)) 36294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.macVersion = MS(val, AR_SREV_VERSION); 36394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 36494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.macRev = val & AR_SREV_REVISION; 36594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 36694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) 36794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->is_pciexpress = true; 36894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 36994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 37094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 37194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/************************************/ 37294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* HW Attach, Detach, Init Routines */ 37394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/************************************/ 37494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 37594a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_disablepcie(struct ath_hw *ah) 37694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 37794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!AR_SREV_5416(ah)) 37894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 37994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 38094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); 38194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); 38294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029); 38394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824); 38494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579); 3858567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000); 38694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); 38794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); 38894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007); 38994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 39094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 39194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 3928567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 39394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* This should work for all families including legacy */ 39494a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic bool ath9k_hw_chip_test(struct ath_hw *ah) 39594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 39694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 39794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 regAddr[2] = { AR_STA_ID0 }; 39894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 regHold[2]; 39994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger static const u32 patternData[4] = { 40094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999 40194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger }; 40294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int i, j, loop_max; 40394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 40494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!AR_SREV_9300_20_OR_LATER(ah)) { 40594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger loop_max = 2; 40694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger regAddr[1] = AR_PHY_BASE + (8 << 2); 40794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else 40894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger loop_max = 1; 40994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 41094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (i = 0; i < loop_max; i++) { 41194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 addr = regAddr[i]; 41294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 wrData, rdData; 41394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 41494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger regHold[i] = REG_READ(ah, addr); 41594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (j = 0; j < 0x100; j++) { 41694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger wrData = (j << 16) | j; 41794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, addr, wrData); 41894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rdData = REG_READ(ah, addr); 41994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (rdData != wrData) { 42094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(common, 42194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", 42294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger addr, wrData, rdData); 42394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 42494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 42594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 42694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (j = 0; j < 4; j++) { 42794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger wrData = patternData[j]; 42894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, addr, wrData); 42994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rdData = REG_READ(ah, addr); 4308567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (wrData != rdData) { 431bb5e482246e0f41c3b39f758c61bdf75f191cbccLarry Finger ath_err(common, 43294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", 433e93e0f6aabd51652fcfa943ca8e8ec2f4947156eLarry Finger addr, wrData, rdData); 43494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 43594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 43694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 43794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, regAddr[i], regHold[i]); 438e93e0f6aabd51652fcfa943ca8e8ec2f4947156eLarry Finger } 43994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(100); 44094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 4418567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return true; 4428567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 4438567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 4448567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerstatic void ath9k_hw_init_config(struct ath_hw *ah) 44594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 44694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int i; 44794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 44894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.dma_beacon_response_time = 1; 44994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.sw_beacon_response_time = 6; 45094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.additional_swba_backoff = 0; 45194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.ack_6mb = 0x0; 45294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.cwm_ignore_extcca = 0; 45394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.pcie_clock_req = 0; 45494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.pcie_waen = 0; 45594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.analog_shiftreg = 1; 45694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.enable_ani = true; 45794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 45894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 45994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.spurchans[i][0] = AR_NO_SPUR; 46094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.spurchans[i][1] = AR_NO_SPUR; 46194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 46294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 46394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* PAPRD needs some more work to be enabled */ 46494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.paprd_disable = 1; 46594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 46694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.rx_intr_mitigation = true; 46794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.pcieSerDesWrite = true; 46894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 46994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 47094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * We need this for PCI devices only (Cardbus, PCI, miniPCI) 47194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * _and_ if on non-uniprocessor systems (Multiprocessor/HT). 47294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * This means we use it for all AR5416 devices, and the few 47394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * minor PCI AR9280 devices out there. 47494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 47594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Serialization is required because these devices do not handle 47694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * well the case of two concurrent reads/writes due to the latency 47794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * involved. During one read/write another read/write can be issued 47894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * on another CPU while the previous read/write may still be working 47994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * on our hardware, if we hit this case the hardware poops in a loop. 48094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * We prevent this by serializing reads and writes. 48194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 48294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * This issue is not present on PCI-Express devices or pre-AR5416 48394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * devices (legacy, 802.11abg). 48494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 4858567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (num_possible_cpus() > 1) 4868567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->config.serialize_regmode = SER_REG_MODE_AUTO; 4878567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 48894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 48965dab9a0e1672b97feb9a44d75e88a263b8db575Larry Fingerstatic void ath9k_hw_init_defaults(struct ath_hw *ah) 49094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 49194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 4928567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 49394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger regulatory->country_code = CTRY_DEFAULT; 49494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger regulatory->power_limit = MAX_RATE_POWER; 49594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 49694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.magic = AR5416_MAGIC; 49794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.subvendorid = 0; 49894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 49994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->atim_window = 0; 50094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->sta_id1_defaults = 50194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_STA_ID1_CRPT_MIC_ENABLE | 5028567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_STA_ID1_MCAST_KSRCH; 50394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9100(ah)) 50494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; 50594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->slottime = ATH9K_SLOT_TIME_9; 50694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->globaltxtimeout = (u32) -1; 50794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->power_mode = ATH9K_PM_UNDEFINED; 50894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->htc_reset_init = true; 50994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 51094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 51194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic int ath9k_hw_init_macaddr(struct ath_hw *ah) 51294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 51394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 51494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 sum; 51594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int i; 516d3b2c172518dceed0d1d68f5b90dde5a2f6a438dLarry Finger u16 eeval; 51794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger static const u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW }; 51894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 51994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sum = 0; 52094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (i = 0; i < 3; i++) { 52194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]); 52294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sum += eeval; 52394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger common->macaddr[2 * i] = eeval >> 8; 52494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger common->macaddr[2 * i + 1] = eeval & 0xff; 52594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 52694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (sum == 0 || sum == 0xffff * 3) 52794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return -EADDRNOTAVAIL; 52894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 52994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return 0; 53094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 53194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 53294a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic int ath9k_hw_post_init(struct ath_hw *ah) 53394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 53494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 53594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int ecode; 53694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 53794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (common->bus_ops->ath_bus_type != ATH_USB) { 53894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_chip_test(ah)) 53994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return -ENODEV; 54094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 54194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 54294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!AR_SREV_9300_20_OR_LATER(ah)) { 54394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ecode = ar9002_hw_rf_claim(ah); 5448567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (ecode != 0) 5458567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return ecode; 54694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 54794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 54894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ecode = ath9k_hw_eeprom_init(ah); 54994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ecode != 0) 55094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return ecode; 55194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 55294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(ath9k_hw_common(ah), CONFIG, "Eeprom VER: %d, REV: %d\n", 55394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->eep_ops->get_eeprom_ver(ah), 55494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->eep_ops->get_eeprom_rev(ah)); 55594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 55694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ecode = ath9k_hw_rf_alloc_ext_banks(ah); 55794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ecode) { 55894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(ath9k_hw_common(ah), 55994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "Failed allocating banks for external radio\n"); 56094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_rf_free_ext_banks(ah); 56194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return ecode; 56294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 56394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 56494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->config.enable_ani) { 56594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_ani_setup(ah); 56694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_ani_init(ah); 56794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 56894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 56994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return 0; 57094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 57194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 57294a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_attach_ops(struct ath_hw *ah) 57394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 57494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) 57594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ar9003_hw_attach_ops(ah); 57694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 57794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ar9002_hw_attach_ops(ah); 57894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 57994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 58094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* Called for all hardware families */ 58194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic int __ath9k_hw_init(struct ath_hw *ah) 58294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 58394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 58494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int r = 0; 58594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 58694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_read_revisions(ah); 58794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 58894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 58994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Read back AR_WA into a permanent copy and set bits 14 and 17. 59094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * We need to do this to avoid RMW of this register. We cannot 59194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * read the reg when chip is asleep. 59294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 59394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->WARegVal = REG_READ(ah, AR_WA); 59494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->WARegVal |= (AR_WA_D3_L1_DISABLE | 59594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_WA_ASPM_TIMER_BASED_DISABLE); 59694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 59794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { 59894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(common, "Couldn't reset chip\n"); 59994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return -EIO; 60094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 60194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 60294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9462(ah)) 60394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->WARegVal &= ~AR_WA_D3_L1_DISABLE; 60494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 60594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_defaults(ah); 60694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_config(ah); 60794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 60894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_attach_ops(ah); 60994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 61094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { 61194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(common, "Couldn't wakeup chip\n"); 61294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return -EIO; 61394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 61494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 61594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { 61694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || 6178567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && 61894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger !ah->is_pciexpress)) { 61994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.serialize_regmode = 6208567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger SER_REG_MODE_ON; 6218567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } else { 6228567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->config.serialize_regmode = 6238567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger SER_REG_MODE_OFF; 6248567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 6258567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 6268567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 62794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(common, RESET, "serialize_regmode is %d\n", 62894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.serialize_regmode); 62994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 63009ced23df6a3345f1923b70d0e799105777f1546Larry Finger if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) 6318567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1; 6328567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger else 6338567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; 6348567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 6358567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger switch (ah->hw_version.macVersion) { 63609ced23df6a3345f1923b70d0e799105777f1546Larry Finger case AR_SREV_VERSION_5416_PCI: 63794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR_SREV_VERSION_5416_PCIE: 6385a604053a9ae947bf9b2e265e74f2ec65e64a77fLarry Finger case AR_SREV_VERSION_9160: 6398567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case AR_SREV_VERSION_9100: 6408567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case AR_SREV_VERSION_9280: 6418567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case AR_SREV_VERSION_9285: 6428567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case AR_SREV_VERSION_9287: 6435a604053a9ae947bf9b2e265e74f2ec65e64a77fLarry Finger case AR_SREV_VERSION_9271: 64494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR_SREV_VERSION_9300: 64507276bac0f49a1fc94799ff840b9a98bc6b01133Larry Finger case AR_SREV_VERSION_9330: 6468567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case AR_SREV_VERSION_9485: 6478567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case AR_SREV_VERSION_9340: 6488567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case AR_SREV_VERSION_9462: 64907276bac0f49a1fc94799ff840b9a98bc6b01133Larry Finger break; 65094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger default: 651062de0a9dfd996a37f0053886e9eff4c509133e2Larry Finger ath_err(common, 6528567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger "Mac Chip Rev 0x%02x.%x is not supported by this driver\n", 65394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.macVersion, ah->hw_version.macRev); 65494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return -EOPNOTSUPP; 655062de0a9dfd996a37f0053886e9eff4c509133e2Larry Finger } 656d3b2c172518dceed0d1d68f5b90dde5a2f6a438dLarry Finger 6574fd7cedc5135a7cc5df3c0d9348b1c32b33bdb96Larry Finger if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah) || 6588567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_SREV_9330(ah)) 6598567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->is_pciexpress = false; 6608567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 6618567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); 6628567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath9k_hw_init_cal_settings(ah); 6638567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 6648567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->ani_function = ATH9K_ANI_ALL; 6658567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_SREV_9280_20_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah)) 6668567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; 6678567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (!AR_SREV_9300_20_OR_LATER(ah)) 6688567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->ani_function &= ~ATH9K_ANI_MRC_CCK; 6698567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 67094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* disable ANI for 9340 */ 6714fd7cedc5135a7cc5df3c0d9348b1c32b33bdb96Larry Finger if (AR_SREV_9340(ah)) 67294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->config.enable_ani = false; 673e608063303979ae4241455bd4752f2c6928e1219Larry Finger 67494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_mode_regs(ah); 67594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 67694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ah->is_pciexpress) 67794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_disablepcie(ah); 67894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 67994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger r = ath9k_hw_post_init(ah); 680e608063303979ae4241455bd4752f2c6928e1219Larry Finger if (r) 68194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return r; 682dc20a3265e242a307810a5f327206d934e4552fcLarry Finger 68394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_mode_gain_regs(ah); 68494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger r = ath9k_hw_fill_cap_info(ah); 68594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (r) 68694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return r; 68794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 68894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger r = ath9k_hw_init_macaddr(ah); 68994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (r) { 690dc20a3265e242a307810a5f327206d934e4552fcLarry Finger ath_err(common, "Failed to initialize MAC address\n"); 69194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return r; 69280f839d43960c7f1dbd4dbcda63efaaa8cffc2b2Larry Finger } 69394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 69494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) 69594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S); 69694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 69780f839d43960c7f1dbd4dbcda63efaaa8cffc2b2Larry Finger ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); 69894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 69994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9330(ah)) 70094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->bb_watchdog_timeout_ms = 85; 70194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 70294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->bb_watchdog_timeout_ms = 25; 70394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 70494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger common->state = ATH_HW_INITIALIZED; 70594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 7068567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return 0; 7078567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 7088567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 7098567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerint ath9k_hw_init(struct ath_hw *ah) 7108567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 71194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int ret; 7128567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger struct ath_common *common = ath9k_hw_common(ah); 7138567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 71494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* These are all the AR5008/AR9001/AR9002 hardware family of chipsets */ 7158567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger switch (ah->hw_version.devid) { 71694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR5416_DEVID_PCI: 7178567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case AR5416_DEVID_PCIE: 71894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR5416_AR9100_DEVID: 7198567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case AR9160_DEVID_PCI: 7208567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case AR9280_DEVID_PCI: 72194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR9280_DEVID_PCIE: 72294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR9285_DEVID_PCIE: 72394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR9287_DEVID_PCI: 72494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR9287_DEVID_PCIE: 72594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR2427_DEVID_PCIE: 72694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR9300_DEVID_PCIE: 72794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR9300_DEVID_AR9485_PCIE: 72894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR9300_DEVID_AR9330: 72994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR9300_DEVID_AR9340: 73094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR9300_DEVID_AR9580: 73194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR9300_DEVID_AR9462: 73294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 73394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger default: 73494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (common->bus_ops->ath_bus_type == ATH_USB) 73594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 73694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(common, "Hardware device ID 0x%04x not supported\n", 73794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.devid); 73894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return -EOPNOTSUPP; 73994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 74094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 74194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ret = __ath9k_hw_init(ah); 74294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ret) { 74394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(common, 74494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "Unable to initialize hardware; initialization status: %d\n", 74594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ret); 74694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return ret; 74794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 74894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 74994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return 0; 7508567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 7518567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry FingerEXPORT_SYMBOL(ath9k_hw_init); 7528567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 7538567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerstatic void ath9k_hw_init_qos(struct ath_hw *ah) 7548567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 7558567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ENABLE_REGWRITE_BUFFER(ah); 7568567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 7578567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); 75894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); 7598567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 7608567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_QOS_NO_ACK, 76194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger SM(2, AR_QOS_NO_ACK_TWO_BIT) | 76294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger SM(5, AR_QOS_NO_ACK_BIT_OFF) | 76394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger SM(0, AR_QOS_NO_ACK_BYTE_OFF)); 76494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 7658567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL); 76694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF); 76794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); 76894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); 76994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 77094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 77194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REGWRITE_BUFFER_FLUSH(ah); 77294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 77394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 77494a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingeru32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) 77594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 77694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); 77794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(100); 77894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); 77994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 78094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) 78194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(100); 78294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 78394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; 78494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 78594a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); 78694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 78794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_init_pll(struct ath_hw *ah, 78894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath9k_channel *chan) 7898567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 7908567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 pll; 7918567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 7928567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_SREV_9485(ah)) { 7938567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 7948567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */ 7958567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, 7968567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_CH0_BB_DPLL2_PLL_PWD, 0x1); 7978567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, 7988567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_CH0_DPLL2_KD, 0x40); 7998567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, 8008567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_CH0_DPLL2_KI, 0x4); 8018567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 8028567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, 8038567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_CH0_BB_DPLL1_REFDIV, 0x5); 8048567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, 8058567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_CH0_BB_DPLL1_NINI, 0x58); 8068567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1, 80794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_CH0_BB_DPLL1_NFRAC, 0x0); 80894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 80994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, 81094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_CH0_BB_DPLL2_OUTDIV, 0x1); 81194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, 81294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_CH0_BB_DPLL2_LOCAL_PLL, 0x1); 81394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, 81494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_CH0_BB_DPLL2_EN_NEGTRIG, 0x1); 81594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 81694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* program BB PLL phase_shift to 0x6 */ 81794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, 81894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x6); 81994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 82094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, 82194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_CH0_BB_DPLL2_PLL_PWD, 0x0); 82294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(1000); 82394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else if (AR_SREV_9330(ah)) { 82494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 ddr_dpll2, pll_control2, kd; 8258567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 8268567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (ah->is_clk_25mhz) { 8278567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ddr_dpll2 = 0x18e82f01; 8288567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pll_control2 = 0xe04a3d; 82994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger kd = 0x1d; 8308567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } else { 83194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ddr_dpll2 = 0x19e82f01; 8328567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pll_control2 = 0x886666; 83394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger kd = 0x3d; 83494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 8358567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 83694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* program DDR PLL ki and kd value */ 83794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_CH0_DDR_DPLL2, ddr_dpll2); 83894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 83994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* program DDR PLL phase_shift */ 84094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, 84194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_CH0_DPLL3_PHASE_SHIFT, 0x1); 84294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 84394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); 84494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(1000); 84594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 84694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* program refdiv, nint, frac to RTC register */ 84794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_PLL_CONTROL2, pll_control2); 84894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 84994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* program BB PLL kd and ki value */ 85094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, AR_CH0_DPLL2_KD, kd); 85194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, AR_CH0_DPLL2_KI, 0x06); 85294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 85394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* program BB PLL phase_shift */ 85494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, 85594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1); 85694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else if (AR_SREV_9340(ah)) { 85794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 regval, pll2_divint, pll2_divfrac, refdiv; 85894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 85994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); 86094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(1000); 86194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 86294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16); 86394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(100); 86494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 86594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->is_clk_25mhz) { 86694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pll2_divint = 0x54; 86794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pll2_divfrac = 0x1eb85; 86894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger refdiv = 3; 86994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 87094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pll2_divint = 88; 87194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pll2_divfrac = 0; 87294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger refdiv = 5; 87394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 87494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 87594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger regval = REG_READ(ah, AR_PHY_PLL_MODE); 87694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger regval |= (0x1 << 16); 87794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PHY_PLL_MODE, regval); 87894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(100); 87994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 88094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) | 88194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (pll2_divint << 18) | pll2_divfrac); 88294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(100); 88394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 88494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger regval = REG_READ(ah, AR_PHY_PLL_MODE); 88594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) | 88694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (0x4 << 26) | (0x18 << 19); 8878567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_PHY_PLL_MODE, regval); 8888567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_PHY_PLL_MODE, 8898567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff); 8908567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger udelay(1000); 89194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 8928567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 8938567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pll = ath9k_hw_compute_pll_control(ah, chan); 89494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 89594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); 89694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 89794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) 89894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(1000); 89994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 90094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Switch the core clock for ar9271 to 117Mhz */ 90194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9271(ah)) { 90294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(500); 90394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, 0x50040, 0x304); 90494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 90594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 90694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(RTC_PLL_SETTLE_DELAY); 90794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 90894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); 90994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 91094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9340(ah)) { 91194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->is_clk_25mhz) { 91294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1); 91394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7); 91494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae); 9158567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } else { 91694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1); 91794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400); 91894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_SLP32_INC, 0x0001e800); 9198567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 9208567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger udelay(100); 92194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 92294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 92394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 92494a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, 92594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger enum nl80211_iftype opmode) 92694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 92794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 sync_default = AR_INTR_SYNC_DEFAULT; 92894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 imr_reg = AR_IMR_TXERR | 92994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_IMR_TXURN | 93094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_IMR_RXERR | 93194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_IMR_RXORN | 93294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_IMR_BCNMISC; 9338567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 93494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9340(ah)) 93594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; 9368567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 9378567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_SREV_9300_20_OR_LATER(ah)) { 93894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger imr_reg |= AR_IMR_RXOK_HP; 93994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->config.rx_intr_mitigation) 94094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; 94194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 94294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger imr_reg |= AR_IMR_RXOK_LP; 94394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 94494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 94594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->config.rx_intr_mitigation) 94694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; 94794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 94894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger imr_reg |= AR_IMR_RXOK; 94994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 95094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 95194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->config.tx_intr_mitigation) 95294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger imr_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR; 95394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 95494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger imr_reg |= AR_IMR_TXOK; 95594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 95694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (opmode == NL80211_IFTYPE_AP) 95794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger imr_reg |= AR_IMR_MIB; 95894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 95994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ENABLE_REGWRITE_BUFFER(ah); 96094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 96194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_IMR, imr_reg); 96294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->imrs2_reg |= AR_IMR_S2_GTT; 96394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); 9640dd565069b21ae20f4916cf305b64268bb3f9d3fLarry Finger 96594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!AR_SREV_9100(ah)) { 96694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); 96794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default); 96894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); 96994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 97094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 97194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REGWRITE_BUFFER_FLUSH(ah); 97294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 97394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) { 97494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0); 97594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_INTR_PRIO_ASYNC_MASK, 0); 97694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_INTR_PRIO_SYNC_ENABLE, 0); 97794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_INTR_PRIO_SYNC_MASK, 0); 97894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 97994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 98094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 98194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_set_sifs_time(struct ath_hw *ah, u32 us) 98294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 98394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 val = ath9k_hw_mac_to_clks(ah, us - 2); 98494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val = min(val, (u32) 0xFFFF); 98594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_D_GBL_IFS_SIFS, val); 98694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 98794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 98894a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) 98994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 99094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 val = ath9k_hw_mac_to_clks(ah, us); 99194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val = min(val, (u32) 0xFFFF); 99294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val); 99394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 99494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 99594a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) 99694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 99794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 val = ath9k_hw_mac_to_clks(ah, us); 99894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK)); 99994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val); 100094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 100194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 100294a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) 100394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 100494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 val = ath9k_hw_mac_to_clks(ah, us); 100594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS)); 100694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val); 100794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 100894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 10098567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerstatic bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) 101094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 101194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (tu > 0xFFFF) { 101294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(ath9k_hw_common(ah), XMIT, "bad global tx timeout %u\n", 101394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tu); 101494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->globaltxtimeout = (u32) -1; 101594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 101694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 101794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu); 101894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->globaltxtimeout = tu; 101994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return true; 102094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 102194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 102294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 102394a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_init_global_settings(struct ath_hw *ah) 102494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 102594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 102694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ieee80211_conf *conf = &common->hw->conf; 102794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger const struct ath9k_channel *chan = ah->curchan; 102894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int acktimeout, ctstimeout, ack_offset = 0; 102994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int slottime; 103094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int sifstime; 103194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int rx_lat = 0, tx_lat = 0, eifs = 0; 103294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 reg; 103394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 103494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(ath9k_hw_common(ah), RESET, "ah->misc_mode 0x%x\n", 103594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->misc_mode); 103694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 103794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!chan) 103894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 103994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 104094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->misc_mode != 0) 104194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode); 104294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 104394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (IS_CHAN_A_FAST_CLOCK(ah, chan)) 104494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rx_lat = 41; 104594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 104694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rx_lat = 37; 104794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tx_lat = 54; 104894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 104994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (IS_CHAN_5GHZ(chan)) 105094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sifstime = 16; 105194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 105294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sifstime = 10; 105394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 105494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (IS_CHAN_HALF_RATE(chan)) { 105594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger eifs = 175; 105694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rx_lat *= 2; 105794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tx_lat *= 2; 105894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (IS_CHAN_A_FAST_CLOCK(ah, chan)) 105994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tx_lat += 11; 106094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 106194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sifstime *= 2; 106294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ack_offset = 16; 10638567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger slottime = 13; 10648567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } else if (IS_CHAN_QUARTER_RATE(chan)) { 10658567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger eifs = 340; 10668567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger rx_lat = (rx_lat * 4) - 1; 106794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tx_lat *= 4; 106894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (IS_CHAN_A_FAST_CLOCK(ah, chan)) 106994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tx_lat += 22; 10708567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 107194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger sifstime *= 4; 107294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ack_offset = 32; 107394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger slottime = 21; 107494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 107594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) { 107694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger eifs = AR_D_GBL_IFS_EIFS_ASYNC_FIFO; 107794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger reg = AR_USEC_ASYNC_FIFO; 107894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 107994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger eifs = REG_READ(ah, AR_D_GBL_IFS_EIFS)/ 10808567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger common->clockrate; 10818567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger reg = REG_READ(ah, AR_USEC); 10828567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 10838567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger rx_lat = MS(reg, AR_USEC_RX_LAT); 108494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tx_lat = MS(reg, AR_USEC_TX_LAT); 108594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 10868567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger slottime = ah->slottime; 108794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 108894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 108994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* As defined by IEEE 802.11-2007 17.3.8.6 */ 109094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger acktimeout = slottime + sifstime + 3 * ah->coverage_class + ack_offset; 10918567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ctstimeout = acktimeout; 109294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 10938567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger /* 10948567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * Workaround for early ACK timeouts, add an offset to match the 109594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * initval's 64us ack timeout value. Use 48us for the CTS timeout. 1096184f1938b29310a0df4298b57a7241832cb0813cSean MacLennan * This was initially only meant to work around an issue with delayed 1097184f1938b29310a0df4298b57a7241832cb0813cSean MacLennan * BA frames in some implementations, but it has been found to fix ACK 109894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * timeout issues in other cases as well. 109994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 11008567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ && 110194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger !IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) { 110294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger acktimeout += 64 - sifstime - ah->slottime; 110394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ctstimeout += 48 - sifstime - ah->slottime; 110494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 110594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 110694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 110794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_sifs_time(ah, sifstime); 110894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_setslottime(ah, slottime); 11098567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath9k_hw_set_ack_timeout(ah, acktimeout); 111094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_cts_timeout(ah, ctstimeout); 111194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->globaltxtimeout != (u32) -1) 111294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); 111394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 111494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_D_GBL_IFS_EIFS, ath9k_hw_mac_to_clks(ah, eifs)); 111594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW(ah, AR_USEC, 11168567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger (common->clockrate - 1) | 11178567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger SM(rx_lat, AR_USEC_RX_LAT) | 11188567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger SM(tx_lat, AR_USEC_TX_LAT), 11198567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_USEC_TX_LAT | AR_USEC_RX_LAT | AR_USEC_USEC); 11208567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11218567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 11228567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry FingerEXPORT_SYMBOL(ath9k_hw_init_global_settings); 11238567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11248567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingervoid ath9k_hw_deinit(struct ath_hw *ah) 11258567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 11268567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger struct ath_common *common = ath9k_hw_common(ah); 11278567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11288567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (common->state < ATH_HW_INITIALIZED) 11298567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger goto free_hw; 11308567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11318567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); 11328567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11338567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerfree_hw: 11348567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath9k_hw_rf_free_ext_banks(ah); 11358567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 11368567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry FingerEXPORT_SYMBOL(ath9k_hw_deinit); 11378567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11388567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger/*******/ 11398567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger/* INI */ 114094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/*******/ 114194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 11428567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingeru32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan) 11438567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 114494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band); 11458567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 114694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (IS_CHAN_B(chan)) 114794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ctl |= CTL_11B; 114894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (IS_CHAN_G(chan)) 114994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ctl |= CTL_11G; 115094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 115194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ctl |= CTL_11A; 11528567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11538567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return ctl; 115494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 11558567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11568567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger/****************************************/ 115794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* Reset and Channel Switching Routines */ 115894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/****************************************/ 11598567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11608567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerstatic inline void ath9k_hw_set_dma(struct ath_hw *ah) 11618567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 11628567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger struct ath_common *common = ath9k_hw_common(ah); 116394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 116494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ENABLE_REGWRITE_BUFFER(ah); 11658567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11668567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger /* 11678567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * set AHB_MODE not to do cacheline prefetches 11688567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger */ 11698567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (!AR_SREV_9300_20_OR_LATER(ah)) 117094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN); 117194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 11728567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger /* 11738567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * let mac dma reads be in 128 byte chunks 11748567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger */ 11758567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW(ah, AR_TXCFG, AR_TXCFG_DMASZ_128B, AR_TXCFG_DMASZ_MASK); 11768567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11778567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REGWRITE_BUFFER_FLUSH(ah); 117894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 117994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 118094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Restore TX Trigger Level to its pre-reset value. 118194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * The initial value depends on whether aggregation is enabled, and is 118294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * adjusted whenever underruns are detected. 118394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 118494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!AR_SREV_9300_20_OR_LATER(ah)) 118594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level); 11868567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 11878567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ENABLE_REGWRITE_BUFFER(ah); 118894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 118994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 119094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * let mac dma writes be in 128 byte chunks 119194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 119294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW(ah, AR_RXCFG, AR_RXCFG_DMASZ_128B, AR_RXCFG_DMASZ_MASK); 119394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 119494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 119594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Setup receive FIFO threshold to hold off TX activities 119694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 11978567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); 11988567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 119994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) { 120094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1); 120194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1); 120294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 120394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize - 120494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->caps.rx_status_len); 120594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 120694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 120794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 120894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * reduce the number of usable entries in PCU TXBUF to avoid 12098567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * wrap around issues. 121094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 121194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9285(ah)) { 121294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* For AR9285 the number of Fifos are reduced to half. 121394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * So set the usable tx buf size also to half to 121494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * avoid data/delimiter underruns 121594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 121694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 121794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE); 121894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else if (!AR_SREV_9271(ah)) { 121994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 122094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_PCU_TXBUF_CTRL_USABLE_SIZE); 12218567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 122294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 122394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REGWRITE_BUFFER_FLUSH(ah); 122494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 122594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) 122694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_reset_txstatus_ring(ah); 12278567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 122894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 122994a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) 123094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 123194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC; 123294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 set = AR_STA_ID1_KSRCH_MODE; 123394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 123494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger switch (opmode) { 123594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case NL80211_IFTYPE_ADHOC: 12368567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case NL80211_IFTYPE_MESH_POINT: 123794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger set |= AR_STA_ID1_ADHOC; 123894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); 12398567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger break; 12408567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case NL80211_IFTYPE_AP: 12418567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger set |= AR_STA_ID1_STA_AP; 124294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* fall through */ 124394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case NL80211_IFTYPE_STATION: 12448567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); 12458567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger break; 12468567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger default: 124794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ah->is_monitoring) 124894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger set = 0; 124994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 125094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 12518567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW(ah, AR_STA_ID1, set, mask); 12528567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 125394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 125494a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, 125594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 *coef_mantissa, u32 *coef_exponent) 125694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 125794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 coef_exp, coef_man; 125894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 12598567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger for (coef_exp = 31; coef_exp > 0; coef_exp--) 12608567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if ((coef_scaled >> coef_exp) & 0x1) 12618567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger break; 12628567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 126394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger coef_exp = 14 - (coef_exp - COEF_SCALE_S); 126494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 126594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1)); 126694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 126794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp); 126894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *coef_exponent = coef_exp - 16; 126994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 127094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 127194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic bool ath9k_hw_set_reset(struct ath_hw *ah, int type) 12728567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 12738567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 rst_flags; 127494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 tmpReg; 127594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 127694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9100(ah)) { 127794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_RTC_DERIVED_CLK, 127894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_RTC_DERIVED_CLK_PERIOD, 1); 127994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (void)REG_READ(ah, AR_RTC_DERIVED_CLK); 128094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 12818567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 12828567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ENABLE_REGWRITE_BUFFER(ah); 128394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 128494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) { 128594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_WA, ah->WARegVal); 128694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(10); 128794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 128894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 128994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 12908567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_RTC_FORCE_WAKE_ON_INT); 129194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 129294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9100(ah)) { 129394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD | 129494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET; 129594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 129694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE); 129794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (tmpReg & 129894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (AR_INTR_SYNC_LOCAL_TIMEOUT | 129994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { 130094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 val; 130194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); 130294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 130394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val = AR_RC_HOSTIF; 130494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!AR_SREV_9300_20_OR_LATER(ah)) 130594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val |= AR_RC_AHB; 130694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RC, val); 13078567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 130894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else if (!AR_SREV_9300_20_OR_LATER(ah)) 130994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RC, AR_RC_AHB); 131094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 131194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rst_flags = AR_RTC_RC_MAC_WARM; 131294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (type == ATH9K_RESET_COLD) 131394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rst_flags |= AR_RTC_RC_MAC_COLD; 131494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 13158567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 131694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9330(ah)) { 131766ba443abf111ab8e8df86e6eb0fb8d87fd5dc21Larry Finger int npend = 0; 131894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int i; 131994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 132094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* AR9330 WAR: 132194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * call external reset function to reset WMAC if: 132294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * - doing a cold reset 132394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * - we have pending frames in the TX queues 132494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 132594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 13268567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger for (i = 0; i < AR_NUM_QCU; i++) { 132766ba443abf111ab8e8df86e6eb0fb8d87fd5dc21Larry Finger npend = ath9k_hw_numtxpending(ah, i); 132894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (npend) 132994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 133094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 133194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 133294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->external_reset && 133394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (npend || type == ATH9K_RESET_COLD)) { 133494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int reset_err = 0; 133594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 13368567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath_dbg(ath9k_hw_common(ah), RESET, 13378567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger "reset MAC via external reset\n"); 13388567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 133994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger reset_err = ah->external_reset(); 13408567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (reset_err) { 134194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(ath9k_hw_common(ah), 134294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "External reset failed, err=%d\n", 134394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger reset_err); 13448567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return false; 134594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 134694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 134794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_RESET, 1); 134894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 134994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 135094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 135194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_RC, rst_flags); 135294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 135394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REGWRITE_BUFFER_FLUSH(ah); 135494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 135594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(50); 13568567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 13578567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_RTC_RC, 0); 135894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) { 135994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(ath9k_hw_common(ah), RESET, "RTC stuck in MAC reset\n"); 13608567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return false; 13618567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 13628567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 13638567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (!AR_SREV_9100(ah)) 13648567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_RC, 0); 13658567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 13668567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_SREV_9100(ah)) 13678567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger udelay(50); 13688567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 13698567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return true; 13708567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 13718567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 13728567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerstatic bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) 13738567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 13748567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ENABLE_REGWRITE_BUFFER(ah); 13758567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 137694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) { 13778567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_WA, ah->WARegVal); 13788567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger udelay(10); 13798567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 13808567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 13818567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 13828567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_RTC_FORCE_WAKE_ON_INT); 13838567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 13848567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) 138594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RC, AR_RC_AHB); 138694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 13878567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_RTC_RESET, 0); 13888567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 13898567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REGWRITE_BUFFER_FLUSH(ah); 13908567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 139194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!AR_SREV_9300_20_OR_LATER(ah)) 139294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(2); 13938567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 13948567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) 13958567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_RC, 0); 13968567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 139794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_RESET, 1); 139894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 13998567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (!ath9k_hw_wait(ah, 14008567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_RTC_STATUS, 14018567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_RTC_STATUS_M, 14028567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_RTC_STATUS_ON, 14038567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AH_WAIT_TIMEOUT)) { 14048567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath_dbg(ath9k_hw_common(ah), RESET, "RTC not waking up\n"); 140594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 140694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 14078567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 140894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM); 14098567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 14108567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 14118567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerstatic bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) 14128567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 141394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bool ret = false; 141494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 141594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) { 14168567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_WA, ah->WARegVal); 14178567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger udelay(10); 14188567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 141994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 142094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_FORCE_WAKE, 142194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 142294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 142394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger switch (type) { 142494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case ATH9K_RESET_POWER_ON: 142594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ret = ath9k_hw_set_reset_power_on(ah); 142694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 142794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case ATH9K_RESET_WARM: 142894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case ATH9K_RESET_COLD: 142994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ret = ath9k_hw_set_reset(ah, type); 14308567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger break; 143194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger default: 143294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 143394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 143494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 143594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return ret; 143694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 143794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 143894a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic bool ath9k_hw_chip_reset(struct ath_hw *ah, 143994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath9k_channel *chan) 144094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 144194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int reset_type = ATH9K_RESET_WARM; 144294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 144394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9280(ah)) { 144494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) 144594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger reset_type = ATH9K_RESET_POWER_ON; 144694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 144794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger reset_type = ATH9K_RESET_COLD; 144894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 14498567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 14508567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (!ath9k_hw_set_reset_reg(ah, reset_type)) 145194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 145294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 145394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 145494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 145594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 145694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->chip_fullsleep = false; 145794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 145894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9330(ah)) 145984780ecdf6c46909c6a4f06635c953f8d8d635f7Melike Yurtoglu ar9003_hw_internal_regulator_apply(ah); 146094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_pll(ah, chan); 146194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_rfmode(ah, chan); 146294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 146394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return true; 146494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 146594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 146694a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic bool ath9k_hw_channel_change(struct ath_hw *ah, 146794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath9k_channel *chan) 146894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 14698567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger struct ath_common *common = ath9k_hw_common(ah); 14708567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 qnum; 147194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int r; 14728567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); 147394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bool band_switch, mode_diff; 147494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u8 ini_reloaded; 147594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 14763a6b70c3f3558a2e47d2ca82752f0aed0f3c33c6Matthew Casey band_switch = (chan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ)) != 147794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (ah->curchan->channelFlags & (CHANNEL_2GHZ | 147894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger CHANNEL_5GHZ)); 14798567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger mode_diff = (chan->chanmode != ah->curchan->chanmode); 14808567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 148194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { 148294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_numtxpending(ah, qnum)) { 148394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(common, QUEUE, 148494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "Transmit frames pending on queue %d\n", qnum); 148594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 148694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 148794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 148894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 148994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_rfbus_req(ah)) { 14908567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath_err(common, "Could not kill baseband RX\n"); 149194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 14928567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 149394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 149494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (edma && (band_switch || mode_diff)) { 149594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_mark_phy_inactive(ah); 149694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(5); 149794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 149894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_pll(ah, NULL); 149994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 150094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_fast_chan_change(ah, chan, &ini_reloaded)) { 150194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(common, "Failed to do fast channel change\n"); 150294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 150394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 150494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 150594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 150694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_channel_regs(ah, chan); 150794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 150894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger r = ath9k_hw_rf_set_freq(ah, chan); 150994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (r) { 151094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(common, "Failed to set channel\n"); 151194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 151294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 151394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_clockrate(ah); 151494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_apply_txpower(ah, chan, false); 151594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_rfbus_done(ah); 151694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 151794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) 151894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_delta_slope(ah, chan); 151994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 15208567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath9k_hw_spur_mitigate_freq(ah, chan); 152194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 152294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (edma && (band_switch || mode_diff)) { 152394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->ah_flags |= AH_FASTCC; 152494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (band_switch || ini_reloaded) 152594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->eep_ops->set_board_values(ah, chan); 152694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 152794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_bb(ah, chan); 152894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 152994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (band_switch || ini_reloaded) 153094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_cal(ah, chan); 153194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->ah_flags &= ~AH_FASTCC; 153294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 15338567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 153494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return true; 153594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 153694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 153794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_apply_gpio_override(struct ath_hw *ah) 153894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 153994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 gpio_mask = ah->gpio_mask; 154094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int i; 154194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 154294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (i = 0; gpio_mask; i++, gpio_mask >>= 1) { 154394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!(gpio_mask & 1)) 154494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger continue; 154594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 154694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_cfg_output(ah, i, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 154794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i))); 154894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 154994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 155094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 155194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic bool ath9k_hw_check_dcs(u32 dma_dbg, u32 num_dcu_states, 155294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int *hang_state, int *hang_pos) 155394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 155494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger static u32 dcu_chain_state[] = {5, 6, 9}; /* DCU chain stuck states */ 155594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 chain_state, dcs_pos, i; 155694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 155794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (dcs_pos = 0; dcs_pos < num_dcu_states; dcs_pos++) { 155894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger chain_state = (dma_dbg >> (5 * dcs_pos)) & 0x1f; 155994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (i = 0; i < 3; i++) { 156094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (chain_state == dcu_chain_state[i]) { 156194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *hang_state = chain_state; 156294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *hang_pos = dcs_pos; 156394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return true; 156494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 156594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 156694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 156794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 156894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 156994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 157094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#define DCU_COMPLETE_STATE 1 157194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#define DCU_COMPLETE_STATE_MASK 0x3 1572eccf634fc84c2e441b34a2c0bc4706616b8ff005Larry Finger#define NUM_STATUS_READS 50 157394a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic bool ath9k_hw_detect_mac_hang(struct ath_hw *ah) 157494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 157594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 chain_state, comp_state, dcs_reg = AR_DMADBG_4; 157694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 i, hang_pos, hang_state, num_state = 6; 157794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 157894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger comp_state = REG_READ(ah, AR_DMADBG_6); 157994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 15808567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if ((comp_state & DCU_COMPLETE_STATE_MASK) != DCU_COMPLETE_STATE) { 15818567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath_dbg(ath9k_hw_common(ah), RESET, 158294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "MAC Hang signature not found at DCU complete\n"); 158394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 158494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 158594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 158694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger chain_state = REG_READ(ah, dcs_reg); 15878567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos)) 158894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto hang_check_iter; 158994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 159094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger dcs_reg = AR_DMADBG_5; 159194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger num_state = 4; 159294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger chain_state = REG_READ(ah, dcs_reg); 159394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_check_dcs(chain_state, num_state, &hang_state, &hang_pos)) 159494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto hang_check_iter; 159594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 159694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(ath9k_hw_common(ah), RESET, 15973b45eb8309ab7e31c31ca046e36033ff9b90a336Larry Finger "MAC Hang signature 1 not found\n"); 159894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 159994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 160094a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerhang_check_iter: 16013b45eb8309ab7e31c31ca046e36033ff9b90a336Larry Finger ath_dbg(ath9k_hw_common(ah), RESET, 160294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "DCU registers: chain %08x complete %08x Hang: state %d pos %d\n", 160394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger chain_state, comp_state, hang_state, hang_pos); 160494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 160594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (i = 0; i < NUM_STATUS_READS; i++) { 160694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger chain_state = REG_READ(ah, dcs_reg); 160794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger chain_state = (chain_state >> (5 * hang_pos)) & 0x1f; 160894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger comp_state = REG_READ(ah, AR_DMADBG_6); 160994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 161094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (((comp_state & DCU_COMPLETE_STATE_MASK) != 161194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger DCU_COMPLETE_STATE) || 161294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (chain_state != hang_state)) 161394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 161494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 161594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 161694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(ath9k_hw_common(ah), RESET, "MAC Hang signature 1 found\n"); 161794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 161894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return true; 161994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 162094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 162194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerbool ath9k_hw_check_alive(struct ath_hw *ah) 162294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 162394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int count = 50; 162494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 reg; 162594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 162694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300(ah)) 162794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return !ath9k_hw_detect_mac_hang(ah); 162894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 162994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9285_12_OR_LATER(ah)) 163094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return true; 163194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 163294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger do { 163394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger reg = REG_READ(ah, AR_OBS_BUS_1); 163494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 163594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if ((reg & 0x7E7FFFEF) == 0x00702400) 163694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger continue; 163794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 163894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger switch (reg & 0x7E000B00) { 163994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case 0x1E000000: 164094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case 0x52000B00: 164194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case 0x18000B00: 164294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger continue; 164394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger default: 164494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return true; 164594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 16468567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } while (count-- > 0); 164794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 164894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 16490dd565069b21ae20f4916cf305b64268bb3f9d3fLarry Finger} 165094a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_check_alive); 16518567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 16528567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger/* 165394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Fast channel change: 165494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * (Change synthesizer based on channel freq without resetting chip) 165594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 1656a15e76ad063248ec1d06baee423881e7aa73066bLarry Finger * Don't do FCC when 165794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * - Flag is not set 165894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * - Chip is just coming out of full sleep 165994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * - Channel to be set is same as current channel 166094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * - Channel flags are different, (eg.,moving from 2GHz to 5GHz channel) 166194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 166294a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) 166394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 166494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 166594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int ret; 166694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 166794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) 166894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto fail; 166994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 167094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->chip_fullsleep) 167194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto fail; 167294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 167394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ah->curchan) 167494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto fail; 167594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 167694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (chan->channel == ah->curchan->channel) 167794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto fail; 167894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 167994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if ((ah->curchan->channelFlags | chan->channelFlags) & 168094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (CHANNEL_HALF | CHANNEL_QUARTER)) 168194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto fail; 168294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 168394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if ((chan->channelFlags & CHANNEL_ALL) != 168494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (ah->curchan->channelFlags & CHANNEL_ALL)) 168594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto fail; 168694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 168794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_check_alive(ah)) 168894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto fail; 168994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 169094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 169194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * For AR9462, make sure that calibration data for 169294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * re-using are present. 169394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 1694cd01712397ad428f443c05add5d7435e899c0ef1Justin P. Mattock if (AR_SREV_9462(ah) && (ah->caldata && 169594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (!ah->caldata->done_txiqcal_once || 169694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger !ah->caldata->done_txclcal_once || 169794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger !ah->caldata->rtt_done))) 169894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto fail; 169994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 170094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", 170194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->curchan->channel, chan->channel); 170294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 170394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ret = ath9k_hw_channel_change(ah, chan); 170494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ret) 170594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger goto fail; 170694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 170794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_loadnf(ah, ah->curchan); 170894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_start_nfcal(ah, true); 170994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 171094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_mci_is_enabled(ah)) 171194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ar9003_mci_2g5g_switch(ah, true); 171294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 17138567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_SREV_9271(ah)) 17148567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ar9002_hw_load_ani_reg(ah, chan); 17158567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 17168567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return 0; 17178567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerfail: 17188567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return -EINVAL; 17198567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 172094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 172194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerint ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 172294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath9k_hw_cal_data *caldata, bool fastcc) 172394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 172494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 172594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 saveLedState; 172694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 saveDefAntenna; 172794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 macStaId1; 172894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u64 tsf = 0; 172994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int i, r; 173094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bool start_mci_reset = false; 173194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bool save_fullsleep = ah->chip_fullsleep; 173294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 17338567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (ath9k_hw_mci_is_enabled(ah)) { 173494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger start_mci_reset = ar9003_mci_start_reset(ah, chan); 173594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (start_mci_reset) 173694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return 0; 173794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 17388567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 173994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 17408567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return -EIO; 17418567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 17428567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (ah->curchan && !ah->chip_fullsleep) 174394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_getnf(ah, ah->curchan); 17440ce600451d9d5543cba5b4c0478ecd02ffd3e399Larry Finger 174594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->caldata = caldata; 174694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (caldata && 1747d3b2c172518dceed0d1d68f5b90dde5a2f6a438dLarry Finger (chan->channel != caldata->channel || 174894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (chan->channelFlags & ~CHANNEL_CW_INT) != 1749dca0eb1e15fa7cf1f4e5fae3d2c32512e24f1742Larry Finger (caldata->channelFlags & ~CHANNEL_CW_INT))) { 175094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Operating channel changed, reset channel calibration data */ 175194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger memset(caldata, 0, sizeof(*caldata)); 175294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_init_nfcal_hist_buffer(ah, chan); 175394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 1754d3b2c172518dceed0d1d68f5b90dde5a2f6a438dLarry Finger ah->noise = ath9k_hw_getchan_noise(ah, chan); 175594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 175694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (fastcc) { 175794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger r = ath9k_hw_do_fastcc(ah, chan); 175894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!r) 175994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return r; 17608cba1432cee4c88668160750f1892aa09a2ba56aLarry Finger } 176194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 176294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_mci_is_enabled(ah)) 17638567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ar9003_mci_stop_bt(ah, save_fullsleep); 17648cba1432cee4c88668160750f1892aa09a2ba56aLarry Finger 17653c093c2ba168ec4a4bfd638c4c35cf748ea329a9Larry Finger saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA); 176694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (saveDefAntenna == 0) 176794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger saveDefAntenna = 1; 176894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 17693c093c2ba168ec4a4bfd638c4c35cf748ea329a9Larry Finger macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; 177094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 1771f6e3d4f4c2fd00a58561db35d6fc6e060ebbebffLarry Finger /* For chips on which RTC reset is done, save TSF before it gets cleared */ 177294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9100(ah) || 177394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))) 177494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tsf = ath9k_hw_gettsf64(ah); 177594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 1776f6e3d4f4c2fd00a58561db35d6fc6e060ebbebffLarry Finger saveLedState = REG_READ(ah, AR_CFG_LED) & 177794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | 17788304cc64dc242f4b410899256c929b9a93108a92Larry Finger AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW); 177994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 178094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_mark_phy_inactive(ah); 178194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 17828304cc64dc242f4b410899256c929b9a93108a92Larry Finger ah->paprd_table_write_done = false; 178394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 1784f6ce577e381e248fbcdad0d9d7e51e5337b6a6a0Larry Finger /* Only required on the first reset */ 178594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9271(ah) && ah->htc_reset_init) { 178694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, 178794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR9271_RESET_POWER_DOWN_CONTROL, 178894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR9271_RADIO_RF_RST); 1789f6ce577e381e248fbcdad0d9d7e51e5337b6a6a0Larry Finger udelay(50); 179094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 17917152e7ec339bf187109d559089712f882291fb98Larry Finger 179294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_chip_reset(ah, chan)) { 1793d3b2c172518dceed0d1d68f5b90dde5a2f6a438dLarry Finger ath_err(common, "Chip reset failed\n"); 179494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return -EINVAL; 179594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 1796de7c885a248ad79380bf1b3425738e436a7790ffLarry Finger 179794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Only required on the first reset */ 179894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9271(ah) && ah->htc_reset_init) { 179994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->htc_reset_init = false; 1800de7c885a248ad79380bf1b3425738e436a7790ffLarry Finger REG_WRITE(ah, 180194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR9271_RESET_POWER_DOWN_CONTROL, 180294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR9271_GATE_MAC_CTL); 180394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(50); 180494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 180594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 180694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Restore TSF */ 1807d45c88a63b1142ef88b732c48c9ed49838b670daLarry Finger if (tsf) 180894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_settsf64(ah, tsf); 180994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 181094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9280_20_OR_LATER(ah)) 181194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 181294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 1813d45c88a63b1142ef88b732c48c9ed49838b670daLarry Finger if (!AR_SREV_9300_20_OR_LATER(ah)) 181494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ar9002_hw_enable_async_fifo(ah); 1815628c30e852e775d98ebce006f51e64a58e3fd76bLarry Finger 181694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger r = ath9k_hw_process_ini(ah, chan); 181794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (r) 181894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return r; 181994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 1820d45c88a63b1142ef88b732c48c9ed49838b670daLarry Finger if (ath9k_hw_mci_is_enabled(ah)) 1821d3b2c172518dceed0d1d68f5b90dde5a2f6a438dLarry Finger ar9003_mci_reset(ah, false, IS_CHAN_2GHZ(chan), save_fullsleep); 182294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 1823ca9900116fb3b758d226d08c1f5c792285941fb9Larry Finger /* 182494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Some AR91xx SoC devices frequently fail to accept TSF writes 182594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * right after the chip reset. When that happens, write a new 182694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * value after the initvals have been applied, with an offset 182794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * based on measured time difference 182894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 1829de7c885a248ad79380bf1b3425738e436a7790ffLarry Finger if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) { 1830edc4b2c5708547de030ff73ffc771ad498209206Larry Finger tsf += 1500; 183194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_settsf64(ah, tsf); 183294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 18338304cc64dc242f4b410899256c929b9a93108a92Larry Finger 183494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Setup MFP options for CCMP */ 183594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9280_20_OR_LATER(ah)) { 1836f6ce577e381e248fbcdad0d9d7e51e5337b6a6a0Larry Finger /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt 183794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * frames when constructing CCMP AAD. */ 183894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT, 183994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 0xc7ff); 184094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->sw_mgmt_crypto = false; 184194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else if (AR_SREV_9160_10_OR_LATER(ah)) { 184294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Disable hardware crypto for management frames */ 184394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_CLR_BIT(ah, AR_PCU_MISC_MODE2, 18448310b6c05c65dfe699dd62be5d71c246ddaefd96Larry Finger AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE); 184594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_PCU_MISC_MODE2, 184694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT); 184794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->sw_mgmt_crypto = true; 184894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else 184994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->sw_mgmt_crypto = true; 185094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 18518310b6c05c65dfe699dd62be5d71c246ddaefd96Larry Finger if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) 185294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_delta_slope(ah, chan); 185394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 18547152e7ec339bf187109d559089712f882291fb98Larry Finger ath9k_hw_spur_mitigate_freq(ah, chan); 185594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->eep_ops->set_board_values(ah, chan); 185694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 185794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ENABLE_REGWRITE_BUFFER(ah); 185894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 185994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); 186094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) 186194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger | macStaId1 186294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger | AR_STA_ID1_RTS_USE_DEF 186394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger | (ah->config. 186494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) 186594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger | ah->sta_id1_defaults); 186694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_hw_setbssidmask(common); 186794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); 186894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_write_associd(ah); 186994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_ISR, ~0); 187094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); 187194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 187294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REGWRITE_BUFFER_FLUSH(ah); 187394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 187494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_operating_mode(ah, ah->opmode); 187594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 187694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger r = ath9k_hw_rf_set_freq(ah, chan); 187794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (r) 1878628c30e852e775d98ebce006f51e64a58e3fd76bLarry Finger return r; 187994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 1880d3b2c172518dceed0d1d68f5b90dde5a2f6a438dLarry Finger ath9k_hw_set_clockrate(ah); 188194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 18829de9f962c71ad2c512c40e30b84aca5392a89630Larry Finger ENABLE_REGWRITE_BUFFER(ah); 18839de9f962c71ad2c512c40e30b84aca5392a89630Larry Finger 188494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (i = 0; i < AR_NUM_DCU; i++) 188594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 188694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 188794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REGWRITE_BUFFER_FLUSH(ah); 188894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 188994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->intr_txqs = 0; 1890569e59595541ee4721eed7a5cb6c13a4ef525beaLarry Finger for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) 189194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_resettxqueue(ah, i); 189294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 189394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_interrupt_masks(ah, ah->opmode); 189494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_ani_cache_ini_regs(ah); 189594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_qos(ah); 189694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 189794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 189894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); 189994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 190094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_global_settings(ah); 190194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 190294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) { 190394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER, 190494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768); 1905569e59595541ee4721eed7a5cb6c13a4ef525beaLarry Finger REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN, 190694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL); 1907472ba3265503203f70012d2decff4007fed270dbLarry Finger REG_SET_BIT(ah, AR_PCU_MISC_MODE2, 19088567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_PCU_MISC_MODE2_ENABLE_AGGWEP); 190994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 191094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 1911472ba3265503203f70012d2decff4007fed270dbLarry Finger REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); 191294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 191374082c929d07ced0d7cad5ce94230a97880ed0bcLarry Finger ath9k_hw_set_dma(ah); 191494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 191594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_OBS, 8); 191694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 191794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->config.rx_intr_mitigation) { 191894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 191994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 192094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 19218567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 19228567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (ah->config.tx_intr_mitigation) { 19238567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, 300); 19248567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, 750); 192594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 192694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 192794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_bb(ah, chan); 192894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 192994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (caldata) { 193094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger caldata->done_txiqcal_once = false; 193194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger caldata->done_txclcal_once = false; 193294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 193394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_init_cal(ah, chan)) 193494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return -EIO; 193594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 193694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_loadnf(ah, chan); 193794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_start_nfcal(ah, true); 193894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 193994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_mci_is_enabled(ah) && ar9003_mci_end_reset(ah, chan, caldata)) 194094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return -EIO; 194194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 194294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ENABLE_REGWRITE_BUFFER(ah); 194394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 194494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_restore_chainmask(ah); 194574082c929d07ced0d7cad5ce94230a97880ed0bcLarry Finger REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ); 194694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 194794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REGWRITE_BUFFER_FLUSH(ah); 19480e86753fe3faae9c24ca52218678b614ccf04f03Larry Finger 194994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 195094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * For big endian systems turn on swapping for descriptors 195194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 195294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9100(ah)) { 195394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 mask; 195494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger mask = REG_READ(ah, AR_CFG); 195594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { 195694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(common, RESET, "CFG Byte Swap Set 0x%x\n", 195794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger mask); 195894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 195994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger mask = 196094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; 196194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_CFG, mask); 196294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(common, RESET, "Setting CFG 0x%x\n", 196394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_READ(ah, AR_CFG)); 196494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 196594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 196694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (common->bus_ops->ath_bus_type == ATH_USB) { 196794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Configure AR9271 target WLAN */ 1968d3b2c172518dceed0d1d68f5b90dde5a2f6a438dLarry Finger if (AR_SREV_9271(ah)) 196994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB); 19705ea0448047ce05da0ee10775510a581b5f71cc82Larry Finger else 197194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); 197294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 197394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#ifdef __BIG_ENDIAN 197494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) 197594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); 197694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 197794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); 197894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#endif 1979d3b2c172518dceed0d1d68f5b90dde5a2f6a438dLarry Finger } 198094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 19819be6f10ed3867b1b89c34e4cd3cb5c00c0bc5282Larry Finger if (ath9k_hw_btcoex_is_enabled(ah)) 198294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_btcoex_enable(ah); 198394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 198494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_mci_is_enabled(ah)) 198594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ar9003_mci_check_bt(ah); 198694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 198794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) { 198894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ar9003_hw_bb_watchdog_config(ah); 198994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 199094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ar9003_hw_disable_phy_restart(ah); 199194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 199294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 199394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_apply_gpio_override(ah); 199494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 199594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return 0; 199694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 199794a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_reset); 199894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 199994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/******************************/ 200094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* Power Management (Chipset) */ 200194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/******************************/ 200294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 20039be6f10ed3867b1b89c34e4cd3cb5c00c0bc5282Larry Finger/* 2004d0df281309e40f21f7a9d9633c2dd78f55edd5f4Larry Finger * Notify Power Mgt is disabled in self-generated frames. 200594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * If requested, force chip to sleep. 200694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 200794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_set_power_sleep(struct ath_hw *ah) 200894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 200994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 201094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 201194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9462(ah)) { 201294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_CLR_BIT(ah, AR_TIMER_MODE, 0xff); 201394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_CLR_BIT(ah, AR_NDP2_TIMER_MODE, 0xff); 2014d0df281309e40f21f7a9d9633c2dd78f55edd5f4Larry Finger REG_CLR_BIT(ah, AR_SLP32_INC, 0xfffff); 201594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* xxx Required for WLAN only case ? */ 201694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); 201774d0497b84280ff5278fc7f12047a1e1421af443Larry Finger udelay(100); 20188567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 20198567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 20208567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger /* 20218567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * Clear the RTC force wake bit to allow the 20228567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * mac to go to sleep. 20238567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger */ 202474d0497b84280ff5278fc7f12047a1e1421af443Larry Finger REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); 202594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 2026ca39405519df5c53f2b2c1c635e638085538086cLarry Finger if (ath9k_hw_mci_is_enabled(ah)) 20278567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger udelay(100); 20288567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 2029ca39405519df5c53f2b2c1c635e638085538086cLarry Finger if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) 203094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); 203194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 203294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Shutdown chip. Active low */ 203394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) { 203494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); 203594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(2); 203694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 203794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 203894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ 203994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) 204094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); 204194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 20428567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 204394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* 204494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Notify Power Management is enabled in self-generating 204594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * frames. If request, set power mode of chip to 204694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * auto/normal. Duration in units of 128us (1/8 TU). 204794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 204894a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_set_power_network_sleep(struct ath_hw *ah) 20498567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 205094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath9k_hw_capabilities *pCap = &ah->caps; 205194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 205294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 205394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 205494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { 205594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Set WakeOnInterrupt bit; clear ForceWake bit */ 205694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RTC_FORCE_WAKE, 205794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_RTC_FORCE_WAKE_ON_INT); 205894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 205994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 206094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* When chip goes into network sleep, it could be waken 2061b678bd1ff579f9e6233911fe5ce5fce31c5242e0Larry Finger * up by MCI_INT interrupt caused by BT's HW messages 20626e579119b104967e91e506de2c7ac7ec1ac4d213Larry Finger * (LNA_xxx, CONT_xxx) which chould be in a very fast 206394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * rate (~100us). This will cause chip to leave and 206494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * re-enter network sleep mode frequently, which in 206594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * consequence will have WLAN MCI HW to generate lots of 2066e93e0f6aabd51652fcfa943ca8e8ec2f4947156eLarry Finger * SYS_WAKING and SYS_SLEEPING messages which will make 206794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * BT CPU to busy to process. 206894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 206994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_mci_is_enabled(ah)) 207094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_CLR_BIT(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 207194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_MCI_INTERRUPT_RX_HW_MSG_MASK); 207294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 207394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Clear the RTC force wake bit to allow the 207494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * mac to go to sleep. 207594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 207694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); 207794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 207894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_mci_is_enabled(ah)) 207994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(30); 208094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 208194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 208294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */ 208394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) 208494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); 20858567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 208694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 208794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic bool ath9k_hw_set_power_awake(struct ath_hw *ah) 208894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 208994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 val; 2090f6e3d4f4c2fd00a58561db35d6fc6e060ebbebffLarry Finger int i; 209194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 209294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Set Bits 14 and 17 of AR_WA before powering on the chip. */ 209394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) { 209494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_WA, ah->WARegVal); 2095de7c885a248ad79380bf1b3425738e436a7790ffLarry Finger udelay(10); 209694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 209794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 209894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if ((REG_READ(ah, AR_RTC_STATUS) & 20997796d93eae46054d5a3bb5411fde735801998dc5Larry Finger AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { 210094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { 210194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 210294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 210394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!AR_SREV_9300_20_OR_LATER(ah)) 210494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_pll(ah, NULL); 210594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 210694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9100(ah)) 21078567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_SET_BIT(ah, AR_RTC_RESET, 21088567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_RTC_RESET_EN); 21098567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 21108567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, 211194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_RTC_FORCE_WAKE_EN); 211294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(50); 211394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 211494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_mci_is_enabled(ah)) 211594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ar9003_mci_set_power_awake(ah); 211694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 211794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (i = POWER_UP_TIME / 50; i > 0; i--) { 211894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; 211994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (val == AR_RTC_STATUS_ON) 212060554f2bdb1579ca54631e99642025797f860eb7Larry Finger break; 212194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger udelay(50); 212294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, 212394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_RTC_FORCE_WAKE_EN); 21242c47ae282a4bbaebfdbba614fb6133db520212baLarry Finger } 21258cba1432cee4c88668160750f1892aa09a2ba56aLarry Finger if (i == 0) { 212694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(ath9k_hw_common(ah), 212794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "Failed to wakeup in %uus\n", 212894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger POWER_UP_TIME / 20); 212994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 213094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 213194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 213294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 213394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 213494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return true; 213594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 213694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 213794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerbool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) 213894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 213994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 214094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int status = true; 214194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger static const char *modes[] = { 214294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "AWAKE", 214394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "FULL-SLEEP", 2144ca39405519df5c53f2b2c1c635e638085538086cLarry Finger "NETWORK SLEEP", 214594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "UNDEFINED" 214694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger }; 214794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 214894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->power_mode == mode) 214994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return status; 215094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 215194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(common, RESET, "%s -> %s\n", 215294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger modes[ah->power_mode], modes[mode]); 215394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 215494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger switch (mode) { 215594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case ATH9K_PM_AWAKE: 215694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger status = ath9k_hw_set_power_awake(ah); 215794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 215894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case ATH9K_PM_FULL_SLEEP: 215994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_mci_is_enabled(ah)) 216094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ar9003_mci_set_full_sleep(ah); 216194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 216294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_set_power_sleep(ah); 216394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->chip_fullsleep = true; 216494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 21658567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger case ATH9K_PM_NETWORK_SLEEP: 21668567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath9k_set_power_network_sleep(ah); 216794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 21688567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger default: 21698567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath_err(common, "Unknown power mode %u\n", mode); 21708567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return false; 217194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 21728567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->power_mode = mode; 21738567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 217494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 217594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * XXX: If this warning never comes up after a while then 217694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * simply keep the ATH_DBG_WARN_ON_ONCE() but make 217794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * ath9k_hw_setpower() return type void. 217894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 217994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 218094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!(ah->ah_flags & AH_UNPLUGGED)) 218194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ATH_DBG_WARN_ON_ONCE(!status); 218294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 218394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return status; 218494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 218594a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_setpower); 218694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 218794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/*******************/ 218894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* Beacon Handling */ 218994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/*******************/ 219094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 21910ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennanvoid ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) 219294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 21930ddcf5fdfac6bd80e153ee5c405bdfc9cb868b95Sean MacLennan int flags = 0; 219494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 219594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ENABLE_REGWRITE_BUFFER(ah); 219694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 219774d0497b84280ff5278fc7f12047a1e1421af443Larry Finger switch (ah->opmode) { 219894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case NL80211_IFTYPE_ADHOC: 219994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case NL80211_IFTYPE_MESH_POINT: 220094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_TXCFG, 220194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); 220294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon + 220394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger TU_TO_USEC(ah->atim_window ? ah->atim_window : 1)); 220494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger flags |= AR_NDP_TIMER_EN; 220594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case NL80211_IFTYPE_AP: 22068567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon); 220794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon - 22088567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger TU_TO_USEC(ah->config.dma_beacon_response_time)); 22098567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_NEXT_SWBA, next_beacon - 221094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger TU_TO_USEC(ah->config.sw_beacon_response_time)); 221194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger flags |= 221294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; 221394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 221494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger default: 221594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(ath9k_hw_common(ah), BEACON, 221694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "%s: unsupported opmode: %d\n", __func__, ah->opmode); 221794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 221894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger break; 221994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 222094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 222194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period); 222294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period); 222394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period); 222494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_NDP_PERIOD, beacon_period); 222594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 222694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REGWRITE_BUFFER_FLUSH(ah); 222794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 22288567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_SET_BIT(ah, AR_TIMER_MODE, flags); 222994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 223094a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_beaconinit); 223194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 223294a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, 223394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger const struct ath9k_beacon_state *bs) 223494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 22358567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 nextTbtt, beaconintval, dtimperiod, beacontimeout; 22368567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger struct ath9k_hw_capabilities *pCap = &ah->caps; 223794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 22388567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 223994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ENABLE_REGWRITE_BUFFER(ah); 224094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 22418567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); 224294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 224394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_BEACON_PERIOD, 224494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger TU_TO_USEC(bs->bs_intval)); 224594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_DMA_BEACON_PERIOD, 224694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger TU_TO_USEC(bs->bs_intval)); 224794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 224894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REGWRITE_BUFFER_FLUSH(ah); 224994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 225094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW_FIELD(ah, AR_RSSI_THR, 225194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); 225294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 225394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger beaconintval = bs->bs_intval; 225494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 225594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (bs->bs_sleepduration > beaconintval) 225694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger beaconintval = bs->bs_sleepduration; 225794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 225894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger dtimperiod = bs->bs_dtimperiod; 225994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (bs->bs_sleepduration > dtimperiod) 226094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger dtimperiod = bs->bs_sleepduration; 226194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 226294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (beaconintval == dtimperiod) 226394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger nextTbtt = bs->bs_nextdtim; 226494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 226594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger nextTbtt = bs->bs_nexttbtt; 226694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 226794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(common, BEACON, "next DTIM %d\n", bs->bs_nextdtim); 226894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(common, BEACON, "next beacon %d\n", nextTbtt); 226994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(common, BEACON, "beacon period %d\n", beaconintval); 227094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(common, BEACON, "DTIM period %d\n", dtimperiod); 227194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 227294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ENABLE_REGWRITE_BUFFER(ah); 22730dd565069b21ae20f4916cf305b64268bb3f9d3fLarry Finger 227494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_NEXT_DTIM, 227594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); 227694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP)); 227794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 227894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_SLEEP1, 227994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT) 228094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger | AR_SLEEP1_ASSUME_DTIM); 228194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 228294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP) 228394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger beacontimeout = (BEACON_TIMEOUT_VAL << 3); 228494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 228594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger beacontimeout = MIN_BEACON_TIMEOUT_VAL; 228694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 228794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_SLEEP2, 228894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT)); 228994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 229094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval)); 229194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod)); 229294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 229394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REGWRITE_BUFFER_FLUSH(ah); 229494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 229594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_TIMER_MODE, 229694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN | 229794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_DTIM_TIMER_EN); 229894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 229994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* TSF Out of Range Threshold */ 230094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold); 230194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 230294a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_set_sta_beacon_timers); 230394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 230494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/*******************/ 230594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* HW Capabilities */ 230694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/*******************/ 230794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 230894a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic u8 fixup_chainmask(u8 chip_chainmask, u8 eeprom_chainmask) 230994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 231094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger eeprom_chainmask &= chip_chainmask; 231194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (eeprom_chainmask) 231294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return eeprom_chainmask; 231394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 231494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return chip_chainmask; 231594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 231694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 231794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/** 231894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * ath9k_hw_dfs_tested - checks if DFS has been tested with used chipset 231994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * @ah: the atheros hardware data structure 232094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 232194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * We enable DFS support upstream on chipsets which have passed a series 232294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * of tests. The testing requirements are going to be documented. Desired 232394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * test requirements are documented at: 232494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 232594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * http://wireless.kernel.org/en/users/Drivers/ath9k/dfs 232694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 232794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Once a new chipset gets properly tested an individual commit can be used 232894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * to document the testing for DFS for that chipset. 232994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 233094a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic bool ath9k_hw_dfs_tested(struct ath_hw *ah) 233194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 233294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 233394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger switch (ah->hw_version.macVersion) { 233494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* AR9580 will likely be our first target to get testing on */ 233594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger case AR_SREV_VERSION_9580: 233694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger default: 233794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 233894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 233994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 23403c093c2ba168ec4a4bfd638c4c35cf748ea329a9Larry Finger 234194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerint ath9k_hw_fill_cap_info(struct ath_hw *ah) 2342dca0eb1e15fa7cf1f4e5fae3d2c32512e24f1742Larry Finger{ 234394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath9k_hw_capabilities *pCap = &ah->caps; 234494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 23450e86753fe3faae9c24ca52218678b614ccf04f03Larry Finger struct ath_common *common = ath9k_hw_common(ah); 234694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger unsigned int chip_chainmask; 2347ca9900116fb3b758d226d08c1f5c792285941fb9Larry Finger 234894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u16 eeval; 234994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u8 ant_div_ctl1, tx_chainmask, rx_chainmask; 235094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 23510ce600451d9d5543cba5b4c0478ecd02ffd3e399Larry Finger eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); 235294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger regulatory->current_rd = eeval; 235394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 235494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ah->opmode != NL80211_IFTYPE_AP && 235594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { 235694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (regulatory->current_rd == 0x64 || 235794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger regulatory->current_rd == 0x65) 235894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger regulatory->current_rd += 5; 2359edc4b2c5708547de030ff73ffc771ad498209206Larry Finger else if (regulatory->current_rd == 0x41) 2360edc4b2c5708547de030ff73ffc771ad498209206Larry Finger regulatory->current_rd = 0x43; 2361edc4b2c5708547de030ff73ffc771ad498209206Larry Finger ath_dbg(common, REGULATORY, "regdomain mapped to 0x%x\n", 2362edc4b2c5708547de030ff73ffc771ad498209206Larry Finger regulatory->current_rd); 2363edc4b2c5708547de030ff73ffc771ad498209206Larry Finger } 2364edc4b2c5708547de030ff73ffc771ad498209206Larry Finger 2365edc4b2c5708547de030ff73ffc771ad498209206Larry Finger eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); 2366edc4b2c5708547de030ff73ffc771ad498209206Larry Finger if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) { 2367edc4b2c5708547de030ff73ffc771ad498209206Larry Finger ath_err(common, 2368edc4b2c5708547de030ff73ffc771ad498209206Larry Finger "no band has been marked as supported in EEPROM\n"); 2369edc4b2c5708547de030ff73ffc771ad498209206Larry Finger return -EINVAL; 237094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 237194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 23722eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger if (eeval & AR5416_OPFLAGS_11A) 23732eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger pCap->hw_caps |= ATH9K_HW_CAP_5GHZ; 23742eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger 23752eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger if (eeval & AR5416_OPFLAGS_11G) 23762eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger pCap->hw_caps |= ATH9K_HW_CAP_2GHZ; 23772eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger 23782eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger if (AR_SREV_9485(ah) || AR_SREV_9285(ah) || AR_SREV_9330(ah)) 23792eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger chip_chainmask = 1; 23802eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger else if (AR_SREV_9462(ah)) 23812eed3dee92453c1798f0932613b1b66f0763ab2eLarry Finger chip_chainmask = 3; 238294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (!AR_SREV_9280_20_OR_LATER(ah)) 238394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger chip_chainmask = 7; 238494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9340(ah)) 238594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger chip_chainmask = 3; 238694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 238794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger chip_chainmask = 7; 238894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 238994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK); 239094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 239194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * For AR9271 we will temporarilly uses the rx chainmax as read from 239294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * the EEPROM. 239394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 239494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if ((ah->hw_version.devid == AR5416_DEVID_PCI) && 23958567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger !(eeval & AR5416_OPFLAGS_11A) && 239694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger !(AR_SREV_9271(ah))) 23978567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger /* CB71: GPIO 0 is pulled down to indicate 3 rx chains */ 23988567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7; 23998567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger else if (AR_SREV_9100(ah)) 240094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->rx_chainmask = 0x7; 2401db2c8da02a2175fe2d129aa55fb0b790ec07a1acMasanari Iida else 240294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Use rx_chainmask from EEPROM. */ 240394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); 240494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 240594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->tx_chainmask = fixup_chainmask(chip_chainmask, pCap->tx_chainmask); 2406db2c8da02a2175fe2d129aa55fb0b790ec07a1acMasanari Iida pCap->rx_chainmask = fixup_chainmask(chip_chainmask, pCap->rx_chainmask); 240794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->txchainmask = pCap->tx_chainmask; 240894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->rxchainmask = pCap->rx_chainmask; 240994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 241094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA; 241194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 241294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* enable key search for every frame in an aggregate */ 2413cd01712397ad428f443c05add5d7435e899c0ef1Justin P. Mattock if (AR_SREV_9300_20_OR_LATER(ah)) 241494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->misc_mode |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH; 241594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 241694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; 241794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 24188567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (ah->hw_version.devid != AR2427_DEVID_PCIE) 241994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps |= ATH9K_HW_CAP_HT; 242094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 242194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps &= ~ATH9K_HW_CAP_HT; 242294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 242394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9271(ah)) 242494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->num_gpio_pins = AR9271_NUM_GPIO; 242594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (AR_DEVID_7010(ah)) 2426cd01712397ad428f443c05add5d7435e899c0ef1Justin P. Mattock pCap->num_gpio_pins = AR7010_NUM_GPIO; 242794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (AR_SREV_9300_20_OR_LATER(ah)) 242894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->num_gpio_pins = AR9300_NUM_GPIO; 242994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (AR_SREV_9287_11_OR_LATER(ah)) 243094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->num_gpio_pins = AR9287_NUM_GPIO; 2431cd01712397ad428f443c05add5d7435e899c0ef1Justin P. Mattock else if (AR_SREV_9285_12_OR_LATER(ah)) 243294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->num_gpio_pins = AR9285_NUM_GPIO; 24338567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger else if (AR_SREV_9280_20_OR_LATER(ah)) 243494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->num_gpio_pins = AR928X_NUM_GPIO; 243594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 243694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->num_gpio_pins = AR_NUM_GPIO; 243794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 243894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) 243994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX; 244094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 244194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->rts_aggr_limit = (8 * 1024); 2442cd01712397ad428f443c05add5d7435e899c0ef1Justin P. Mattock 244394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 244494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT); 2445db2c8da02a2175fe2d129aa55fb0b790ec07a1acMasanari Iida if (ah->rfsilent & EEP_RFSILENT_ENABLED) { 244694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->rfkill_gpio = 2447db2c8da02a2175fe2d129aa55fb0b790ec07a1acMasanari Iida MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL); 244894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->rfkill_polarity = 244994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger MS(ah->rfsilent, EEP_RFSILENT_POLARITY); 245094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 245194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT; 245294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 245394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#endif 245494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9271(ah) || AR_SREV_9300_20_OR_LATER(ah)) 245594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; 245694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 245794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; 245894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 245994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9280(ah) || AR_SREV_9285(ah)) 246094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; 246194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 246294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; 246394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 246494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) { 246594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK; 246694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah)) 246794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps |= ATH9K_HW_CAP_LDPC; 246894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 246994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; 24708567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH; 24718567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pCap->rx_status_len = sizeof(struct ar9003_rxs); 247294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->tx_desc_len = sizeof(struct ar9003_txc); 247394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->txs_len = sizeof(struct ar9003_txs); 24748567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (!ah->config.paprd_disable && 24758567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) 24768567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; 24778567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } else { 24788567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pCap->tx_desc_len = sizeof(struct ath_desc); 24798567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_SREV_9280_20(ah)) 24808567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pCap->hw_caps |= ATH9K_HW_CAP_FASTCLOCK; 24818567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 24828567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 248394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) 248494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED; 2485cd01712397ad428f443c05add5d7435e899c0ef1Justin P. Mattock 248694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) 248794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->ent_mode = REG_READ(ah, AR_ENT_OTP); 24888567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 24898567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah)) 24908567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pCap->hw_caps |= ATH9K_HW_CAP_SGI_20; 24918567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 24928567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_SREV_9285(ah)) 24938567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (ah->eep_ops->get_eeprom(ah, EEP_MODAL_VER) >= 3) { 249494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ant_div_ctl1 = 249594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); 249694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1)) 24978567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; 24988567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 24998567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_SREV_9300_20_OR_LATER(ah)) { 25008567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (ah->eep_ops->get_eeprom(ah, EEP_CHAIN_MASK_REDUCE)) 25018567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pCap->hw_caps |= ATH9K_HW_CAP_APM; 25028567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 25038567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 25048567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 25058567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { 250694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); 25078567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger /* 25088567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * enable the diversity-combining algorithm only when 25098567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * both enable_lna_div and enable_fast_div are set 25108567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * Table for Diversity 25118567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * ant_div_alt_lnaconf bit 0-1 25128567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * ant_div_main_lnaconf bit 2-3 25138567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * ant_div_alt_gaintb bit 4 25148567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * ant_div_main_gaintb bit 5 25158567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * enable_ant_div_lnadiv bit 6 25168567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger * enable_ant_fast_div bit 7 2517042b623cf57a7c381326bdfe1db046e9b0b8517fMelike Yurtoglu */ 25188567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if ((ant_div_ctl1 >> 0x6) == 0x3) 251994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; 252094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 252194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 252294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9485_10(ah)) { 252394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->pcie_lcr_extsync_en = true; 252494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->pcie_lcr_offset = 0x80; 252594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 252694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 25278567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (ath9k_hw_dfs_tested(ah)) 25288567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger pCap->hw_caps |= ATH9K_HW_CAP_DFS; 25298567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 253094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tx_chainmask = pCap->tx_chainmask; 253194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rx_chainmask = pCap->rx_chainmask; 253294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger while (tx_chainmask || rx_chainmask) { 253394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (tx_chainmask & BIT(0)) 253494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->max_txchains++; 253594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (rx_chainmask & BIT(0)) 253694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->max_rxchains++; 253794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 253894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tx_chainmask >>= 1; 253994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger rx_chainmask >>= 1; 254094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 254194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 254294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9300_20_OR_LATER(ah)) { 254394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->enabled_cals |= TX_IQ_CAL; 254494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9485_OR_LATER(ah)) 254594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->enabled_cals |= TX_IQ_ON_AGC_CAL; 254694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 2547cd01712397ad428f443c05add5d7435e899c0ef1Justin P. Mattock 254894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9462(ah)) { 254994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 2550cd01712397ad428f443c05add5d7435e899c0ef1Justin P. Mattock if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) 255194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps |= ATH9K_HW_CAP_MCI; 255294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 255394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9462_20(ah)) 255494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger pCap->hw_caps |= ATH9K_HW_CAP_RTT; 255594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 255694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 255794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 255894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 255994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return 0; 256094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 256194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 256294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/****************************/ 256394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* GPIO / RFKILL / Antennae */ 256494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/****************************/ 256594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 256694a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah, 256794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 gpio, u32 type) 256894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 256994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger int addr; 257094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 gpio_shift, tmp; 25719d8a20a52cd760d1a8739fc408e68617f9d6577bPeter Huewe 257294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (gpio > 11) 257394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger addr = AR_GPIO_OUTPUT_MUX3; 257494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (gpio > 5) 257594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger addr = AR_GPIO_OUTPUT_MUX2; 257694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 257794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger addr = AR_GPIO_OUTPUT_MUX1; 257894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 257994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger gpio_shift = (gpio % 6) * 5; 258094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 258194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9280_20_OR_LATER(ah) 258294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger || (addr != AR_GPIO_OUTPUT_MUX1)) { 258394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW(ah, addr, (type << gpio_shift), 258494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (0x1f << gpio_shift)); 258594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else { 258694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tmp = REG_READ(ah, addr); 25879d8a20a52cd760d1a8739fc408e68617f9d6577bPeter Huewe tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0); 258894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tmp &= ~(0x1f << gpio_shift); 258994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tmp |= (type << gpio_shift); 259094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, addr, tmp); 259194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 259294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 259394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 259494a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio) 259594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 259694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 gpio_shift; 259794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 259894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger BUG_ON(gpio >= ah->caps.num_gpio_pins); 259994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 260094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_DEVID_7010(ah)) { 260194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger gpio_shift = gpio; 260294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW(ah, AR7010_GPIO_OE, 260394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (AR7010_GPIO_OE_AS_INPUT << gpio_shift), 260494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (AR7010_GPIO_OE_MASK << gpio_shift)); 260594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 260694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 260794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 260894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger gpio_shift = gpio << 1; 260994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW(ah, 261094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_GPIO_OE_OUT, 261194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), 261294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (AR_GPIO_OE_OUT_DRV << gpio_shift)); 26139d8a20a52cd760d1a8739fc408e68617f9d6577bPeter Huewe} 261494a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_cfg_gpio_input); 261594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 261694a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingeru32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) 261794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 261894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger#define MS_REG_READ(x, y) \ 261994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y))) 262094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 262194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (gpio >= ah->caps.num_gpio_pins) 262294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return 0xffffffff; 262394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 262494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_DEVID_7010(ah)) { 262594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 val; 262694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val = REG_READ(ah, AR7010_GPIO_IN); 262794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0; 262894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } else if (AR_SREV_9300_20_OR_LATER(ah)) 262994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) & 263094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_GPIO_BIT(gpio)) != 0; 263194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (AR_SREV_9271(ah)) 263294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return MS_REG_READ(AR9271, gpio) != 0; 263394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (AR_SREV_9287_11_OR_LATER(ah)) 263494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return MS_REG_READ(AR9287, gpio) != 0; 263594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (AR_SREV_9285_12_OR_LATER(ah)) 263694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return MS_REG_READ(AR9285, gpio) != 0; 263794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else if (AR_SREV_9280_20_OR_LATER(ah)) 263894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return MS_REG_READ(AR928X, gpio) != 0; 263994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 264094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return MS_REG_READ(AR, gpio) != 0; 264194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 26428567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry FingerEXPORT_SYMBOL(ath9k_hw_gpio_get); 26438567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 26448567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingervoid ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, 26458567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 ah_signal_type) 26468567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 26478567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 gpio_shift; 26488567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 26498567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_DEVID_7010(ah)) { 26508567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger gpio_shift = gpio; 26518567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW(ah, AR7010_GPIO_OE, 26528567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger (AR7010_GPIO_OE_AS_OUTPUT << gpio_shift), 265394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (AR7010_GPIO_OE_MASK << gpio_shift)); 265494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 265594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 265694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 26578567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type); 26588567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger gpio_shift = 2 * gpio; 26598567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW(ah, 26608567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_GPIO_OE_OUT, 26618567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift), 26628567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger (AR_GPIO_OE_OUT_DRV << gpio_shift)); 26638567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 26648567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry FingerEXPORT_SYMBOL(ath9k_hw_cfg_output); 26658567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 26668567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingervoid ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) 26678567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 26688567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_DEVID_7010(ah)) { 266994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger val = val ? 0 : 1; 267094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_RMW(ah, AR7010_GPIO_OUT, ((val&1) << gpio), 267194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_GPIO_BIT(gpio)); 267294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 26738567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 26748567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 26758567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (AR_SREV_9271(ah)) 26768567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger val = ~val; 26778567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 26788567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), 26798567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_GPIO_BIT(gpio)); 26808567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 268194a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_set_gpio); 268294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 268394a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) 268494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 268594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); 268694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 268794a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_setantenna); 268894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 268994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/*********************/ 269094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/* General Operation */ 269194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger/*********************/ 269294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 269394a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingeru32 ath9k_hw_getrxfilter(struct ath_hw *ah) 269494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 269594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 bits = REG_READ(ah, AR_RX_FILTER); 269694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 phybits = REG_READ(ah, AR_PHY_ERR); 269794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 269894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (phybits & AR_PHY_ERR_RADAR) 269994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bits |= ATH9K_RX_FILTER_PHYRADAR; 270094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING)) 270194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bits |= ATH9K_RX_FILTER_PHYERR; 270294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 270394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return bits; 270494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 270594a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_getrxfilter); 270694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 270794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) 27088567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 2709976d534118219b04277fb6cfcdb71607b730746dSean MacLennan u32 phybits; 271094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 271194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ENABLE_REGWRITE_BUFFER(ah); 271294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 271394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9462(ah)) 271494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bits |= ATH9K_RX_FILTER_CONTROL_WRAPPER; 271594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 271694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RX_FILTER, bits); 271794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 271894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger phybits = 0; 271994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (bits & ATH9K_RX_FILTER_PHYRADAR) 272094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger phybits |= AR_PHY_ERR_RADAR; 272194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (bits & ATH9K_RX_FILTER_PHYERR) 272294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING; 27238567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_PHY_ERR, phybits); 27248567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 272594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (phybits) 27268567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_SET_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA); 27278567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger else 272894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_CLR_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA); 272994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 27308567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REGWRITE_BUFFER_FLUSH(ah); 27318567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 273294a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_setrxfilter); 27338567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 27348567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerbool ath9k_hw_phy_disable(struct ath_hw *ah) 273594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 273694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ath9k_hw_mci_is_enabled(ah)) 273794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ar9003_mci_bt_gain_ctrl(ah); 273894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 27396f03053b6810c7ca315afb30b31b63d9f5863fafJesper Juhl if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) 27408567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return false; 27418567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 27428567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ath9k_hw_init_pll(ah, NULL); 27438567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger ah->htc_reset_init = true; 27448567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return true; 27458567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 274694a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_phy_disable); 274794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 27488567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerbool ath9k_hw_disable(struct ath_hw *ah) 27498567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 275094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) 275194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 275294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 275394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD)) 275494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return false; 275594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 275694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_init_pll(ah, NULL); 275794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return true; 275894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 275994a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_disable); 276094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 276194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstatic int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan) 276294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 276394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger enum eeprom_param gain_param; 276494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 276594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (IS_CHAN_2GHZ(chan)) 276694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger gain_param = EEP_ANTENNA_GAIN_2G; 27678567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger else 27688567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger gain_param = EEP_ANTENNA_GAIN_5G; 276994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 277094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return ah->eep_ops->get_eeprom(ah, gain_param); 277194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 277294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 277394a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, 277494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger bool test) 27758567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 27768567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger struct ath_regulatory *reg = ath9k_hw_regulatory(ah); 27778567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger struct ieee80211_channel *channel; 27788567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger int chan_pwr, new_pwr, max_gain; 27798567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger int ant_gain, ant_reduction = 0; 27808567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 27818567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (!chan) 27828567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return; 278394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 278494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger channel = chan->chan; 27858567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER); 27868567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger new_pwr = min_t(int, chan_pwr, reg->power_limit); 27878567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2; 27888567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 278994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ant_gain = get_antenna_gain(ah, chan); 279094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (ant_gain > max_gain) 279194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ant_reduction = ant_gain - max_gain; 279294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 279394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->eep_ops->set_txpower(ah, chan, 279494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_regd_get_ctl(reg, chan), 279594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ant_reduction, new_pwr, test); 279694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 279794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 27988567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingervoid ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) 27998567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 280094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_regulatory *reg = ath9k_hw_regulatory(ah); 280194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath9k_channel *chan = ah->curchan; 280294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ieee80211_channel *channel = chan->chan; 280394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 28048567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger reg->power_limit = min_t(u32, limit, MAX_RATE_POWER); 28058567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (test) 28068567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger channel->max_power = MAX_RATE_POWER / 2; 28078567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 280894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_apply_txpower(ah, chan, test); 280994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 281094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (test) 281194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2); 281294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 281394a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_set_txpowerlimit); 281494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 281594a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_setopmode(struct ath_hw *ah) 281694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 281794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath9k_hw_set_operating_mode(ah, ah->opmode); 28188567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 28198567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry FingerEXPORT_SYMBOL(ath9k_hw_setopmode); 282094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 282194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1) 28228567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 28238567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_MCAST_FIL0, filter0); 28248567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_MCAST_FIL1, filter1); 282594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 28268567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry FingerEXPORT_SYMBOL(ath9k_hw_setmcastfilter); 28278567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 28288567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingervoid ath9k_hw_write_associd(struct ath_hw *ah) 282994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 283094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_common *common = ath9k_hw_common(ah); 28318567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 28328567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(common->curbssid)); 283394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(common->curbssid + 4) | 283494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ((common->curaid & 0x3fff) << AR_BSS_ID1_AID_S)); 28358567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 28368567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry FingerEXPORT_SYMBOL(ath9k_hw_write_associd); 283794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 28388567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger#define ATH9K_MAX_TSF_READ 10 28398567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 28408567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingeru64 ath9k_hw_gettsf64(struct ath_hw *ah) 284194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 28428567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 tsf_lower, tsf_upper1, tsf_upper2; 28438567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger int i; 28448567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 284594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tsf_upper1 = REG_READ(ah, AR_TSF_U32); 284694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger for (i = 0; i < ATH9K_MAX_TSF_READ; i++) { 284794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tsf_lower = REG_READ(ah, AR_TSF_L32); 284894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tsf_upper2 = REG_READ(ah, AR_TSF_U32); 284994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (tsf_upper2 == tsf_upper1) 28508567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger break; 28518567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger tsf_upper1 = tsf_upper2; 28528567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger } 285394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 28548567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger WARN_ON( i == ATH9K_MAX_TSF_READ ); 28558567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 28568567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return (((u64)tsf_upper1 << 32) | tsf_lower); 285794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 28588567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry FingerEXPORT_SYMBOL(ath9k_hw_gettsf64); 28598567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 28608567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingervoid ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64) 286194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 286294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff); 286394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff); 286494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 286594a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_settsf64); 286694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 286794a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_reset_tsf(struct ath_hw *ah) 286894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 286994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0, 287094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AH_TSF_WRITE_TIMEOUT)) 287194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(ath9k_hw_common(ah), RESET, 287294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n"); 287394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 287494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE); 287594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 287694a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_reset_tsf); 287794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 287894a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting) 287994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 288094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (setting) 288194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->misc_mode |= AR_PCU_TX_ADD_TSF; 288294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 288394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ah->misc_mode &= ~AR_PCU_TX_ADD_TSF; 288494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 288594a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_set_tsfadjust); 288694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 28878567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingervoid ath9k_hw_set11nmac2040(struct ath_hw *ah) 28888567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 28898567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 28908567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 macmode; 28918567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 28928567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger if (conf_is_ht40(conf) && !ah->config.cwm_ignore_extcca) 28938567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger macmode = AR_2040_JOINED_RX_CLEAR; 28948567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger else 28958567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger macmode = 0; 28968567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 28978567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger REG_WRITE(ah, AR_2040_MODE, macmode); 28988567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger} 28998567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 2900a0711c4da327de531a9f4af7a40d7043d06771b4Matthias Schoepe/* HW Generic timers configuration */ 290194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 29028567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerstatic const struct ath_gen_timer_configuration gen_tmr_configuration[] = 2903a15e76ad063248ec1d06baee423881e7aa73066bLarry Finger{ 29048567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080}, 29058567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080}, 2906976d534118219b04277fb6cfcdb71607b730746dSean MacLennan {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080}, 2907976d534118219b04277fb6cfcdb71607b730746dSean MacLennan {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080}, 29088567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080}, 29098567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080}, 291094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080}, 291194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger {AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080}, 29128567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger {AR_NEXT_NDP2_TIMER, AR_NDP2_PERIOD, AR_NDP2_TIMER_MODE, 0x0001}, 29137796d93eae46054d5a3bb5411fde735801998dc5Larry Finger {AR_NEXT_NDP2_TIMER + 1*4, AR_NDP2_PERIOD + 1*4, 29148567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_NDP2_TIMER_MODE, 0x0002}, 29158567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger {AR_NEXT_NDP2_TIMER + 2*4, AR_NDP2_PERIOD + 2*4, 29168567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_NDP2_TIMER_MODE, 0x0004}, 29178567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger {AR_NEXT_NDP2_TIMER + 3*4, AR_NDP2_PERIOD + 3*4, 29188567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_NDP2_TIMER_MODE, 0x0008}, 29198567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger {AR_NEXT_NDP2_TIMER + 4*4, AR_NDP2_PERIOD + 4*4, 29208567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_NDP2_TIMER_MODE, 0x0010}, 29218567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger {AR_NEXT_NDP2_TIMER + 5*4, AR_NDP2_PERIOD + 5*4, 29228567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_NDP2_TIMER_MODE, 0x0020}, 29238567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger {AR_NEXT_NDP2_TIMER + 6*4, AR_NDP2_PERIOD + 6*4, 29248567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger AR_NDP2_TIMER_MODE, 0x0040}, 29258567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger {AR_NEXT_NDP2_TIMER + 7*4, AR_NDP2_PERIOD + 7*4, 292694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger AR_NDP2_TIMER_MODE, 0x0080} 292794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger}; 292894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 29298567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger/* HW generic timer primitives */ 293094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 29318567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger/* compute and clear index of rightmost 1 */ 29328567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Fingerstatic u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask) 29338567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger{ 29348567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 b; 29358567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 29368567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger b = *mask; 29378567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger b &= (0-b); 293894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger *mask &= ~b; 29398567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger b *= debruijn32; 29408567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger b >>= 27; 29418567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 29428567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger return timer_table->gen_timer_index[b]; 294394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 294494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 294594a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingeru32 ath9k_hw_gettsf32(struct ath_hw *ah) 294694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 294794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return REG_READ(ah, AR_TSF_L32); 294894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 294994a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_gettsf32); 295094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 295194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingerstruct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, 295294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger void (*trigger)(void *), 295394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger void (*overflow)(void *), 295494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger void *arg, 295594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u8 timer_index) 295694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 29578567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; 29588567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger struct ath_gen_timer *timer; 295994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 296094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL); 296194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 296294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (timer == NULL) { 296394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_err(ath9k_hw_common(ah), 296494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "Failed to allocate memory for hw timer[%d]\n", 296594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger timer_index); 296650d5e53ddfc0d9cf4707d7d8e22624b26ab9114eAndy Shevchenko return NULL; 296794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 296894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 296994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* allocate a hardware generic timer slot */ 29708567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger timer_table->timers[timer_index] = timer; 29718567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger timer->index = timer_index; 29728567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger timer->trigger = trigger; 297394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger timer->overflow = overflow; 297494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger timer->arg = arg; 29758567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 297694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return timer; 297794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 297894a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath_gen_timer_alloc); 297994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 298094a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_gen_timer_start(struct ath_hw *ah, 298194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_gen_timer *timer, 29828567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 trig_timeout, 29838567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger u32 timer_period) 298494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 298594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; 298694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger u32 tsf, timer_next; 298794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 298894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger BUG_ON(!timer_period); 298994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 299094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger set_bit(timer->index, &timer_table->timer_mask.timer_bits); 29918567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 29928567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger tsf = ath9k_hw_gettsf32(ah); 29938567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 29948567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger timer_next = tsf + trig_timeout; 29958567829a6cfe13e2a8b366794fffa54e5fd06e9fLarry Finger 299694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger ath_dbg(ath9k_hw_common(ah), HWTIMER, 299794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger "current tsf %x period %x timer_next %x\n", 299894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger tsf, timer_period, timer_next); 299994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 300094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 300194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Program generic timer registers 300294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 300394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr, 300494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger timer_next); 300594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_WRITE(ah, gen_tmr_configuration[timer->index].period_addr, 300694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger timer_period); 300794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, gen_tmr_configuration[timer->index].mode_addr, 300894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger gen_tmr_configuration[timer->index].mode_mask); 300994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 301094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if (AR_SREV_9462(ah)) { 301194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* 301294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * Starting from AR9462, each generic timer can select which tsf 301394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * to use. But we still follow the old rule, 0 - 7 use tsf and 301494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger * 8 - 15 use tsf2. 301594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger */ 301694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if ((timer->index < AR_GEN_TIMER_BANK_1_LEN)) 301794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_CLR_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, 301894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (1 << timer->index)); 301994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger else 302094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, 302194a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (1 << timer->index)); 302294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 302394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 302494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Enable both trigger and thresh interrupt masks */ 302594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger REG_SET_BIT(ah, AR_IMR_S5, 302694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) | 302794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG))); 302894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger} 302994a799425eee8225a1e3fbe5f473d2ef04002577Larry FingerEXPORT_SYMBOL(ath9k_hw_gen_timer_start); 303094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 303194a799425eee8225a1e3fbe5f473d2ef04002577Larry Fingervoid ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) 303294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger{ 303394a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; 303494a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 303594a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger if ((timer->index < AR_FIRST_NDP_TIMER) || 303694a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger (timer->index >= ATH_MAX_GEN_TIMER)) { 303794a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger return; 303894a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger } 303994a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger 304094a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger /* Clear generic timer enable bits. */ 30413b148be0df8e45a0259d7e84001cf02e897af614Sean MacLennan REG_CLR_BIT(ah, gen_tmr_configuration[timer->index].mode_addr, 304294a799425eee8225a1e3fbe5f473d2ef04002577Larry Finger gen_tmr_configuration[timer->index].mode_mask); 3043 3044 /* Disable both trigger and thresh interrupt masks */ 3045 REG_CLR_BIT(ah, AR_IMR_S5, 3046 (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) | 3047 SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG))); 3048 3049 clear_bit(timer->index, &timer_table->timer_mask.timer_bits); 3050} 3051EXPORT_SYMBOL(ath9k_hw_gen_timer_stop); 3052 3053void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer) 3054{ 3055 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; 3056 3057 /* free the hardware generic timer slot */ 3058 timer_table->timers[timer->index] = NULL; 3059 kfree(timer); 3060} 3061EXPORT_SYMBOL(ath_gen_timer_free); 3062 3063/* 3064 * Generic Timer Interrupts handling 3065 */ 3066void ath_gen_timer_isr(struct ath_hw *ah) 3067{ 3068 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; 3069 struct ath_gen_timer *timer; 3070 struct ath_common *common = ath9k_hw_common(ah); 3071 u32 trigger_mask, thresh_mask, index; 3072 3073 /* get hardware generic timer interrupt status */ 3074 trigger_mask = ah->intr_gen_timer_trigger; 3075 thresh_mask = ah->intr_gen_timer_thresh; 3076 trigger_mask &= timer_table->timer_mask.val; 3077 thresh_mask &= timer_table->timer_mask.val; 3078 3079 trigger_mask &= ~thresh_mask; 3080 3081 while (thresh_mask) { 3082 index = rightmost_index(timer_table, &thresh_mask); 3083 timer = timer_table->timers[index]; 3084 BUG_ON(!timer); 3085 ath_dbg(common, HWTIMER, "TSF overflow for Gen timer %d\n", 3086 index); 3087 timer->overflow(timer->arg); 3088 } 3089 3090 while (trigger_mask) { 3091 index = rightmost_index(timer_table, &trigger_mask); 3092 timer = timer_table->timers[index]; 3093 BUG_ON(!timer); 3094 ath_dbg(common, HWTIMER, 3095 "Gen timer[%d] trigger\n", index); 3096 timer->trigger(timer->arg); 3097 } 3098} 3099EXPORT_SYMBOL(ath_gen_timer_isr); 3100 3101/********/ 3102/* HTC */ 3103/********/ 3104 3105static struct { 3106 u32 version; 3107 const char * name; 3108} ath_mac_bb_names[] = { 3109 /* Devices with external radios */ 3110 { AR_SREV_VERSION_5416_PCI, "5416" }, 3111 { AR_SREV_VERSION_5416_PCIE, "5418" }, 3112 { AR_SREV_VERSION_9100, "9100" }, 3113 { AR_SREV_VERSION_9160, "9160" }, 3114 /* Single-chip solutions */ 3115 { AR_SREV_VERSION_9280, "9280" }, 3116 { AR_SREV_VERSION_9285, "9285" }, 3117 { AR_SREV_VERSION_9287, "9287" }, 3118 { AR_SREV_VERSION_9271, "9271" }, 3119 { AR_SREV_VERSION_9300, "9300" }, 3120 { AR_SREV_VERSION_9330, "9330" }, 3121 { AR_SREV_VERSION_9340, "9340" }, 3122 { AR_SREV_VERSION_9485, "9485" }, 3123 { AR_SREV_VERSION_9462, "9462" }, 3124}; 3125 3126/* For devices with external radios */ 3127static struct { 3128 u16 version; 3129 const char * name; 3130} ath_rf_names[] = { 3131 { 0, "5133" }, 3132 { AR_RAD5133_SREV_MAJOR, "5133" }, 3133 { AR_RAD5122_SREV_MAJOR, "5122" }, 3134 { AR_RAD2133_SREV_MAJOR, "2133" }, 3135 { AR_RAD2122_SREV_MAJOR, "2122" } 3136}; 3137 3138/* 3139 * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. 3140 */ 3141static const char *ath9k_hw_mac_bb_name(u32 mac_bb_version) 3142{ 3143 int i; 3144 3145 for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) { 3146 if (ath_mac_bb_names[i].version == mac_bb_version) { 3147 return ath_mac_bb_names[i].name; 3148 } 3149 } 3150 3151 return "????"; 3152} 3153 3154/* 3155 * Return the RF name. "????" is returned if the RF is unknown. 3156 * Used for devices with external radios. 3157 */ 3158static const char *ath9k_hw_rf_name(u16 rf_version) 3159{ 3160 int i; 3161 3162 for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) { 3163 if (ath_rf_names[i].version == rf_version) { 3164 return ath_rf_names[i].name; 3165 } 3166 } 3167 3168 return "????"; 3169} 3170 3171void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len) 3172{ 3173 int used; 3174 3175 /* chipsets >= AR9280 are single-chip */ 3176 if (AR_SREV_9280_20_OR_LATER(ah)) { 3177 used = snprintf(hw_name, len, 3178 "Atheros AR%s Rev:%x", 3179 ath9k_hw_mac_bb_name(ah->hw_version.macVersion), 3180 ah->hw_version.macRev); 3181 } 3182 else { 3183 used = snprintf(hw_name, len, 3184 "Atheros AR%s MAC/BB Rev:%x AR%s RF Rev:%x", 3185 ath9k_hw_mac_bb_name(ah->hw_version.macVersion), 3186 ah->hw_version.macRev, 3187 ath9k_hw_rf_name((ah->hw_version.analog5GhzRev & 3188 AR_RADIO_SREV_MAJOR)), 3189 ah->hw_version.phyRev); 3190 } 3191 3192 hw_name[used] = '\0'; 3193} 3194EXPORT_SYMBOL(ath9k_hw_name); 3195