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