void ar9300StopSpectralScan(struct ath_hal *ah) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); // Deactivate spectral scan // HW Bug fix -- Do not disable the spectral scan // only turn off the active bit //val &= ~AR_PHY_SPECTRAL_SCAN_ENABLE; val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE; OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH, ahp->ah_radar1); OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET, ahp->ah_dc_offset); OS_REG_WRITE(ah, AR_PHY_ERR, 0); if (AH_PRIVATE(ah)->ah_curchan && IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan)) { /* fast clock */ OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK, ahp->ah_disable_cck); } HDPRINTF(ah, HAL_DBG_UNMASKABLE, "%s: AR_PHY_MODE=0x%x\n", __func__, OS_REG_READ(ah, AR_PHY_MODE)); val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR); OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val); val = OS_REG_READ(ah, AR_PHY_ERR); }
/* * ADC GAIN/DC offset calibration is for calibrating two ADCs that * are acting as one by interleaving incoming symbols. This isn't * relevant for 2.4GHz 20MHz wide modes because, as far as I can tell, * the secondary ADC is never enabled. It is enabled however for * 5GHz modes. * * It hasn't been confirmed whether doing this calibration is needed * at all in the above modes and/or whether it's actually harmful. * So for now, let's leave it enabled and just remember to get * confirmation that it needs to be clarified. * * See US Patent No: US 7,541,952 B1: * " Method and Apparatus for Offset and Gain Compensation for * Analog-to-Digital Converters." */ static OS_INLINE HAL_BOOL ar5416IsCalSupp(struct ath_hal *ah, const struct ieee80211_channel *chan, HAL_CAL_TYPE calType) { struct ar5416PerCal *cal = &AH5416(ah)->ah_cal; switch (calType & cal->suppCals) { case IQ_MISMATCH_CAL: /* Run IQ Mismatch for non-CCK only */ return !IEEE80211_IS_CHAN_B(chan); case ADC_GAIN_CAL: case ADC_DC_CAL: /* * Run ADC Gain Cal for either 5ghz any or 2ghz HT40. * * Don't run ADC calibrations for 5ghz fast clock mode * in HT20 - only one ADC is used. */ if (IEEE80211_IS_CHAN_HT20(chan) && (IS_5GHZ_FAST_CLOCK_EN(ah, chan))) return AH_FALSE; if (IEEE80211_IS_CHAN_5GHZ(chan)) return AH_TRUE; if (IEEE80211_IS_CHAN_HT40(chan)) return AH_TRUE; return AH_FALSE; } return AH_FALSE; }
/* * Return whether fast-clock is currently enabled for this * channel. */ HAL_BOOL ar5416IsFastClockEnabled(struct ath_hal *ah) { struct ath_hal_private *ahp = AH_PRIVATE(ah); return IS_5GHZ_FAST_CLOCK_EN(ah, ahp->ah_curchan); }
void ar9300PrepSpectralScan(struct ath_hal *ah) { ar9300DisableRadar(ah); ar9300ClassifyStrongBins(ah); ar9300DisableDcOffset(ah); if (AR_SREV_AR9580_10_OR_LATER(ah)) { /* Peacock+ */ HDPRINTF(ah, HAL_DBG_UNMASKABLE, "%s: chip is AR9580 or later\n", __func__); } else { HDPRINTF(ah, HAL_DBG_UNMASKABLE, "%s: chip is before AR9580\n", __func__); } /* The following addresses Osprey bug and is not required for Peacock+ */ if (AH_PRIVATE(ah)->ah_curchan && IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan) && (!AR_SREV_AR9580_10_OR_LATER(ah))) { /* fast clock and earlier than peacock */ ar9300EnableCckDetect(ah); } #ifdef DEMO_MODE ar9300DisableStrongSignal(ah); ar9300DisableWeakSignal(ah); ar9300SetRadarDcThresh(ah); ar9300SetCcaThreshold(ah, MAX_CCA_THRESH); //ar9300DisableRestart(ah); #endif OS_REG_WRITE(ah, AR_PHY_ERR, HAL_PHYERR_SPECTRAL); }
void ar9300StopSpectralScan(struct ath_hal *ah) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); // Deactivate spectral scan val &= ~AR_PHY_SPECTRAL_SCAN_ENABLE; val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE; OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH, ahp->ah_radar1); OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET, ahp->ah_dc_offset); OS_REG_WRITE(ah, AR_PHY_ERR, 0); if (AH_PRIVATE(ah)->ah_curchan && IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan)) { /* fast clock */ OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK, ahp->ah_disable_cck); } val = OS_REG_READ(ah, AR_PHY_ERR); }
HAL_BOOL ar9300IsFastClockEnabled(struct ath_hal *ah) { struct ath_hal_private *ahp = AH_PRIVATE(ah); if (IS_5GHZ_FAST_CLOCK_EN(ah, ahp->ah_curchan)) { return AH_TRUE; } return AH_FALSE; }
bool ar9300_is_fast_clock_enabled(struct ath_hal *ah) { struct ath_hal_private *ahp = AH_PRIVATE(ah); if (IS_5GHZ_FAST_CLOCK_EN(ah, ahp->ah_curchan)) { return true; } return false; }
static void ar9280WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan) { u_int modesIndex, freqIndex; int regWrites = 0; /* Setup the indices for the next set of register array writes */ /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */ if (IEEE80211_IS_CHAN_2GHZ(chan)) { freqIndex = 2; if (IEEE80211_IS_CHAN_HT40(chan)) modesIndex = 3; else if (IEEE80211_IS_CHAN_108G(chan)) modesIndex = 5; else modesIndex = 4; } else { freqIndex = 1; if (IEEE80211_IS_CHAN_HT40(chan) || IEEE80211_IS_CHAN_TURBO(chan)) modesIndex = 2; else modesIndex = 1; } /* Set correct Baseband to analog shift setting to access analog chips. */ OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); /* XXX Merlin ini fixups */ /* XXX Merlin 100us delay for shift registers */ regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes, modesIndex, regWrites); if (AR_SREV_MERLIN_20_OR_LATER(ah)) { regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_rxgain, modesIndex, regWrites); regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_txgain, modesIndex, regWrites); } /* XXX Merlin 100us delay for shift registers */ regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common, 1, regWrites); if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { /* 5GHz channels w/ Fast Clock use different modal values */ regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_xmodes, modesIndex, regWrites); } }
void ar9300PrepSpectralScan(struct ath_hal *ah) { ar9300DisableRadar(ah); ar9300ClassifyStrongBins(ah); ar9300DisableDcOffset(ah); if (AH_PRIVATE(ah)->ah_curchan && IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan)) { /* fast clock */ ar9300EnableCckDetect(ah); } #ifdef DEMO_MODE ar9300DisableStrongSignal(ah); ar9300DisableWeakSignal(ah); ar9300SetRadarDcThresh(ah); ar9300SetCcaThreshold(ah, MAX_CCA_THRESH); //ar9300DisableRestart(ah); #endif OS_REG_WRITE(ah, AR_PHY_ERR, HAL_PHYERR_SPECTRAL); }
void ar9300_prep_spectral_scan(struct ath_hal *ah) { ar9300_disable_radar(ah); ar9300_classify_strong_bins(ah); ar9300_disable_dc_offset(ah); if (AH_PRIVATE(ah)->ah_curchan && IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan)) { /* fast clock */ ar9300_enable_cck_detect(ah); } #ifdef DEMO_MODE ar9300_disable_strong_signal(ah); ar9300_disable_weak_signal(ah); ar9300_set_radar_dc_thresh(ah); ar9300_set_cca_threshold(ah, MAX_CCA_THRESH); /*ar9300_disable_restart(ah);*/ #endif OS_REG_WRITE(ah, AR_PHY_ERR, HAL_PHYERR_SPECTRAL); }
void ar9300_stop_spectral_scan(struct ath_hal *ah) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); bool asleep = ahp->ah_chip_full_sleep; if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); /* deactivate spectral scan */ /* HW Bug fix -- Do not disable the spectral scan * only turn off the active bit */ //val &= ~AR_PHY_SPECTRAL_SCAN_ENABLE; val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE; OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH, ahp->ah_radar1); OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET, ahp->ah_dc_offset); OS_REG_WRITE(ah, AR_PHY_ERR, 0); if (AH_PRIVATE(ah)->ah_curchan && IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan)) { /* fast clock */ OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK, ahp->ah_disable_cck); } val = OS_REG_READ(ah, AR_PHY_ERR); val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR); OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val); if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } }
static void ar9280AniSetup(struct ath_hal *ah) { /* * These are the parameters from the AR5416 ANI code; * they likely need quite a bit of adjustment for the * AR9280. */ static const struct ar5212AniParams aniparams = { .maxNoiseImmunityLevel = 4, /* levels 0..4 */ .totalSizeDesired = { -55, -55, -55, -55, -62 }, .coarseHigh = { -14, -14, -14, -14, -12 }, .coarseLow = { -64, -64, -64, -64, -70 }, .firpwr = { -78, -78, -78, -78, -80 }, .maxSpurImmunityLevel = 2, .cycPwrThr1 = { 2, 4, 6 }, .maxFirstepLevel = 2, /* levels 0..2 */ .firstep = { 0, 4, 8 }, .ofdmTrigHigh = 500, .ofdmTrigLow = 200, .cckTrigHigh = 200, .cckTrigLow = 100, .rssiThrHigh = 40, .rssiThrLow = 7, .period = 100, }; /* NB: disable ANI noise immmunity for reliable RIFS rx */ AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL); /* NB: ANI is not enabled yet */ ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE); } void ar9280InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan) { uint32_t pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); if (AR_SREV_MERLIN_20(ah) && chan != AH_NULL && IEEE80211_IS_CHAN_5GHZ(chan)) { /* * PLL WAR for Merlin 2.0/2.1 * When doing fast clock, set PLL to 0x142c * Else, set PLL to 0x2850 to prevent reset-to-reset variation */ pll = IS_5GHZ_FAST_CLOCK_EN(ah, chan) ? 0x142c : 0x2850; } else if (AR_SREV_MERLIN_10_OR_LATER(ah)) { pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); if (chan != AH_NULL) { if (IEEE80211_IS_CHAN_HALF(chan)) pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL); else if (IEEE80211_IS_CHAN_QUARTER(chan)) pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL); if (IEEE80211_IS_CHAN_5GHZ(chan)) pll |= SM(0x28, AR_RTC_SOWL_PLL_DIV); else pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV); } else pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV); } OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); OS_DELAY(RTC_PLL_SETTLE_DELAY); OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_SLEEP_DERIVED_CLK); }
static void ar9280WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan) { u_int modesIndex, freqIndex; int regWrites = 0; int i; const HAL_INI_ARRAY *ia; /* Setup the indices for the next set of register array writes */ /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */ if (IEEE80211_IS_CHAN_2GHZ(chan)) { freqIndex = 2; if (IEEE80211_IS_CHAN_HT40(chan)) modesIndex = 3; else if (IEEE80211_IS_CHAN_108G(chan)) modesIndex = 5; else modesIndex = 4; } else { freqIndex = 1; if (IEEE80211_IS_CHAN_HT40(chan) || IEEE80211_IS_CHAN_TURBO(chan)) modesIndex = 2; else modesIndex = 1; } /* Set correct Baseband to analog shift setting to access analog chips. */ OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); /* * This is unwound because at the moment, there's a requirement * for Merlin (and later, perhaps) to have a specific bit fixed * in the AR_AN_TOP2 register before writing it. */ ia = &AH5212(ah)->ah_ini_modes; #if 0 regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes, modesIndex, regWrites); #endif HALASSERT(modesIndex < ia->cols); for (i = 0; i < ia->rows; i++) { uint32_t reg = HAL_INI_VAL(ia, i, 0); uint32_t val = HAL_INI_VAL(ia, i, modesIndex); if (reg == AR_AN_TOP2 && AH5416(ah)->ah_need_an_top2_fixup) val &= ~AR_AN_TOP2_PWDCLKIND; OS_REG_WRITE(ah, reg, val); /* Analog shift register delay seems needed for Merlin - PR kern/154220 */ if (reg >= 0x7800 && reg < 0x7900) OS_DELAY(100); DMA_YIELD(regWrites); } if (AR_SREV_MERLIN_20_OR_LATER(ah)) { regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_rxgain, modesIndex, regWrites); regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_txgain, modesIndex, regWrites); } /* XXX Merlin 100us delay for shift registers */ regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common, 1, regWrites); if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { /* 5GHz channels w/ Fast Clock use different modal values */ regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_xmodes, modesIndex, regWrites); } }