diff options
Diffstat (limited to 'sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c')
-rw-r--r-- | sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c b/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c new file mode 100644 index 000000000000..df951c325312 --- /dev/null +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c @@ -0,0 +1,243 @@ +/*- + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2012 Qualcomm Atheros, All Rights Reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "opt_ah.h" + +#include "ah.h" +#include "ah_internal.h" +#include "ah_devid.h" +#include "ah_desc.h" /* NB: for HAL_PHYERR* */ + +#include "ar5416/ar5416.h" +#include "ar5416/ar5416reg.h" +#include "ar5416/ar5416phy.h" + +/* + * Default AR9280 spectral scan parameters + */ +#define AR5416_SPECTRAL_SCAN_ENA 0 +#define AR5416_SPECTRAL_SCAN_ACTIVE 0 +#define AR5416_SPECTRAL_SCAN_FFT_PERIOD 8 +#define AR5416_SPECTRAL_SCAN_PERIOD 1 +#define AR5416_SPECTRAL_SCAN_COUNT 16 //used to be 128 +#define AR5416_SPECTRAL_SCAN_SHORT_REPEAT 1 + +/* constants */ +#define MAX_RADAR_RSSI_THRESH 0x3f +#define MAX_RADAR_HEIGHT 0x3f +#define ENABLE_ALL_PHYERR 0xffffffff + +static void ar5416DisableRadar(struct ath_hal *ah); +static void ar5416PrepSpectralScan(struct ath_hal *ah); + +static void +ar5416DisableRadar(struct ath_hal *ah) +{ + uint32_t val; + + // Enable radar FFT + val = OS_REG_READ(ah, AR_PHY_RADAR_0); + val |= AR_PHY_RADAR_0_FFT_ENA; + + // set radar detect thresholds to max to effectively disable radar + val &= ~AR_PHY_RADAR_0_RRSSI; + val |= SM(MAX_RADAR_RSSI_THRESH, AR_PHY_RADAR_0_RRSSI); + + val &= ~AR_PHY_RADAR_0_HEIGHT; + val |= SM(MAX_RADAR_HEIGHT, AR_PHY_RADAR_0_HEIGHT); + + val &= ~(AR_PHY_RADAR_0_ENA); + OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); + + // disable extension radar detect + val = OS_REG_READ(ah, AR_PHY_RADAR_EXT); + OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA); + + val = OS_REG_READ(ah, AR_RX_FILTER); + val |= (1<<13); + OS_REG_WRITE(ah, AR_RX_FILTER, val); +} + +static void +ar5416PrepSpectralScan(struct ath_hal *ah) +{ + + ar5416DisableRadar(ah); + OS_REG_WRITE(ah, AR_PHY_ERR, ENABLE_ALL_PHYERR); +} + +void +ar5416ConfigureSpectralScan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) +{ + uint32_t val; + + ar5416PrepSpectralScan(ah); + + val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); + + if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) { + val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD; + val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); + } + + if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { + val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; + val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); + } + + if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { + val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; + val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); + } + + /* This section is different for Kiwi and Merlin */ + if (AR_SREV_MERLIN(ah) ) { + if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) { + val &= ~AR_PHY_SPECTRAL_SCAN_COUNT; + val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT); + } + + if (ss->ss_short_report == AH_TRUE) { + val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; + } else if (ss->ss_short_report != HAL_SPECTRAL_PARAM_NOVAL) { + val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; + } + } else { + if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) { + /* + * In Merlin, for continuous scan, scan_count = 128. + * In case of Kiwi, this value should be 0 + */ + if (ss->ss_count == 128) + ss->ss_count = 0; + val &= ~AR_PHY_SPECTRAL_SCAN_COUNT_KIWI; + val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI); + } + + if (ss->ss_short_report == AH_TRUE) { + val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI; + } else if (ss->ss_short_report != HAL_SPECTRAL_PARAM_NOVAL) { + val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI; + } + + //Select the mask to be same as before + val |= AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT_KIWI; + } + // Enable spectral scan + OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENA); + + ar5416GetSpectralParams(ah, ss); +} + +/* + * Get the spectral parameter values and return them in the pe + * structure + */ +void +ar5416GetSpectralParams(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) +{ + uint32_t val; + + val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); + + ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); + ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD); + if (AR_SREV_MERLIN(ah) ) { + ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT); + ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); + } else { + ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI); + ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI); + } + val = OS_REG_READ(ah, AR_PHY_RADAR_1); + ss->radar_bin_thresh_sel = MS(val, AR_PHY_RADAR_1_BIN_THRESH_SELECT); +} + +HAL_BOOL +ar5416IsSpectralActive(struct ath_hal *ah) +{ + uint32_t val; + + val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); + return MS(val, AR_PHY_SPECTRAL_SCAN_ACTIVE); +} + +HAL_BOOL +ar5416IsSpectralEnabled(struct ath_hal *ah) +{ + uint32_t val; + + val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); + return MS(val,AR_PHY_SPECTRAL_SCAN_ENA); +} + +void +ar5416StartSpectralScan(struct ath_hal *ah) +{ + uint32_t val; + + ar5416PrepSpectralScan(ah); + + // Activate spectral scan + val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); + val |= AR_PHY_SPECTRAL_SCAN_ENA; + val |= AR_PHY_SPECTRAL_SCAN_ACTIVE; + OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); + val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); + val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG); + OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR); +} + +void +ar5416StopSpectralScan(struct ath_hal *ah) +{ + uint32_t val; + val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); + + // Deactivate spectral scan + val &= ~AR_PHY_SPECTRAL_SCAN_ENA; + val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE; + OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); + val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); + val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR); + OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val); +} + +uint32_t +ar5416GetSpectralConfig(struct ath_hal *ah) +{ + uint32_t val; + + val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); + return val; +} + +void +ar5416RestoreSpectralConfig(struct ath_hal *ah, uint32_t restoreval) +{ + uint32_t curval; + + ar5416PrepSpectralScan(ah); + + curval = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); + + if (restoreval != curval) { + restoreval |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; + OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, restoreval); + } + return; +} |