1244943Sadrian/* 2244943Sadrian * Copyright (c) 2012 Qualcomm Atheros, All Rights Reserved. 3244943Sadrian * 4244943Sadrian * Permission to use, copy, modify, and/or distribute this software for any 5244943Sadrian * purpose with or without fee is hereby granted, provided that the above 6244943Sadrian * copyright notice and this permission notice appear in all copies. 7244943Sadrian * 8244943Sadrian * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9244943Sadrian * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10244943Sadrian * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11244943Sadrian * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12244943Sadrian * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13244943Sadrian * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14244943Sadrian * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15244943Sadrian * 16244943Sadrian * $FreeBSD$ 17244943Sadrian */ 18244943Sadrian#include "opt_ah.h" 19244943Sadrian 20244943Sadrian#include "ah.h" 21244943Sadrian#include "ah_internal.h" 22244943Sadrian#include "ah_devid.h" 23244943Sadrian#include "ah_desc.h" /* NB: for HAL_PHYERR* */ 24244943Sadrian 25244943Sadrian#include "ar5416/ar5416.h" 26244943Sadrian#include "ar5416/ar5416reg.h" 27244943Sadrian#include "ar5416/ar5416phy.h" 28244943Sadrian 29244943Sadrian/* 30244943Sadrian * Default AR9280 spectral scan parameters 31244943Sadrian */ 32244943Sadrian#define AR5416_SPECTRAL_SCAN_ENA 0 33244943Sadrian#define AR5416_SPECTRAL_SCAN_ACTIVE 0 34244943Sadrian#define AR5416_SPECTRAL_SCAN_FFT_PERIOD 8 35244943Sadrian#define AR5416_SPECTRAL_SCAN_PERIOD 1 36244943Sadrian#define AR5416_SPECTRAL_SCAN_COUNT 16 //used to be 128 37244943Sadrian#define AR5416_SPECTRAL_SCAN_SHORT_REPEAT 1 38244943Sadrian 39244943Sadrian/* constants */ 40244943Sadrian#define MAX_RADAR_RSSI_THRESH 0x3f 41244943Sadrian#define MAX_RADAR_HEIGHT 0x3f 42244943Sadrian#define ENABLE_ALL_PHYERR 0xffffffff 43244943Sadrian 44244943Sadrianstatic void ar5416DisableRadar(struct ath_hal *ah); 45244943Sadrianstatic void ar5416PrepSpectralScan(struct ath_hal *ah); 46244943Sadrian 47244943Sadrianstatic void 48244943Sadrianar5416DisableRadar(struct ath_hal *ah) 49244943Sadrian{ 50244943Sadrian uint32_t val; 51244943Sadrian 52244943Sadrian // Enable radar FFT 53244943Sadrian val = OS_REG_READ(ah, AR_PHY_RADAR_0); 54244943Sadrian val |= AR_PHY_RADAR_0_FFT_ENA; 55244943Sadrian 56244943Sadrian // set radar detect thresholds to max to effectively disable radar 57244943Sadrian val &= ~AR_PHY_RADAR_0_RRSSI; 58244943Sadrian val |= SM(MAX_RADAR_RSSI_THRESH, AR_PHY_RADAR_0_RRSSI); 59244943Sadrian 60244943Sadrian val &= ~AR_PHY_RADAR_0_HEIGHT; 61244943Sadrian val |= SM(MAX_RADAR_HEIGHT, AR_PHY_RADAR_0_HEIGHT); 62244943Sadrian 63244943Sadrian val &= ~(AR_PHY_RADAR_0_ENA); 64244943Sadrian OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); 65244943Sadrian 66244943Sadrian // disable extension radar detect 67244943Sadrian val = OS_REG_READ(ah, AR_PHY_RADAR_EXT); 68244943Sadrian OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA); 69244943Sadrian 70244943Sadrian val = OS_REG_READ(ah, AR_RX_FILTER); 71244943Sadrian val |= (1<<13); 72244943Sadrian OS_REG_WRITE(ah, AR_RX_FILTER, val); 73244943Sadrian} 74244943Sadrian 75244943Sadrianstatic void 76244943Sadrianar5416PrepSpectralScan(struct ath_hal *ah) 77244943Sadrian{ 78244943Sadrian 79244943Sadrian ar5416DisableRadar(ah); 80244943Sadrian OS_REG_WRITE(ah, AR_PHY_ERR, ENABLE_ALL_PHYERR); 81244943Sadrian} 82244943Sadrian 83244943Sadrianvoid 84244943Sadrianar5416ConfigureSpectralScan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) 85244943Sadrian{ 86244943Sadrian uint32_t val; 87244943Sadrian 88244943Sadrian ar5416PrepSpectralScan(ah); 89244943Sadrian 90244943Sadrian val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 91244943Sadrian 92244943Sadrian if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) { 93244943Sadrian val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD; 94244943Sadrian val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); 95244943Sadrian } 96244943Sadrian 97244943Sadrian if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { 98244943Sadrian val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; 99244943Sadrian val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); 100244943Sadrian } 101244943Sadrian 102244943Sadrian if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { 103244943Sadrian val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; 104244943Sadrian val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); 105244943Sadrian } 106244943Sadrian 107244943Sadrian /* This section is different for Kiwi and Merlin */ 108244943Sadrian if (AR_SREV_MERLIN(ah) ) { 109244943Sadrian if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) { 110244943Sadrian val &= ~AR_PHY_SPECTRAL_SCAN_COUNT; 111244943Sadrian val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT); 112244943Sadrian } 113244943Sadrian 114244943Sadrian if (ss->ss_short_report == AH_TRUE) { 115244943Sadrian val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; 116244950Sadrian } else if (ss->ss_short_report != HAL_SPECTRAL_PARAM_NOVAL) { 117244943Sadrian val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; 118244943Sadrian } 119244943Sadrian } else { 120244943Sadrian if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) { 121244943Sadrian /* 122244943Sadrian * In Merlin, for continous scan, scan_count = 128. 123244943Sadrian * In case of Kiwi, this value should be 0 124244943Sadrian */ 125244943Sadrian if (ss->ss_count == 128) 126244943Sadrian ss->ss_count = 0; 127244943Sadrian val &= ~AR_PHY_SPECTRAL_SCAN_COUNT_KIWI; 128244943Sadrian val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI); 129244943Sadrian } 130244943Sadrian 131244943Sadrian if (ss->ss_short_report == AH_TRUE) { 132244943Sadrian val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI; 133244950Sadrian } else if (ss->ss_short_report != HAL_SPECTRAL_PARAM_NOVAL) { 134244943Sadrian val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI; 135244943Sadrian } 136244943Sadrian 137244943Sadrian //Select the mask to be same as before 138244943Sadrian val |= AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT_KIWI; 139244943Sadrian } 140244943Sadrian // Enable spectral scan 141244943Sadrian OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENA); 142244943Sadrian 143244943Sadrian ar5416GetSpectralParams(ah, ss); 144244943Sadrian} 145244943Sadrian 146244943Sadrian/* 147244943Sadrian * Get the spectral parameter values and return them in the pe 148244943Sadrian * structure 149244943Sadrian */ 150244943Sadrianvoid 151244943Sadrianar5416GetSpectralParams(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) 152244943Sadrian{ 153244943Sadrian uint32_t val; 154244943Sadrian 155244943Sadrian val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 156244943Sadrian 157244943Sadrian ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); 158244943Sadrian ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD); 159244943Sadrian if (AR_SREV_MERLIN(ah) ) { 160244943Sadrian ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT); 161244943Sadrian ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); 162244943Sadrian } else { 163244943Sadrian ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI); 164244943Sadrian ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI); 165244943Sadrian } 166244943Sadrian val = OS_REG_READ(ah, AR_PHY_RADAR_1); 167244943Sadrian ss->radar_bin_thresh_sel = MS(val, AR_PHY_RADAR_1_BIN_THRESH_SELECT); 168244943Sadrian} 169244943Sadrian 170244943SadrianHAL_BOOL 171244943Sadrianar5416IsSpectralActive(struct ath_hal *ah) 172244943Sadrian{ 173244943Sadrian uint32_t val; 174244943Sadrian 175244943Sadrian val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 176244943Sadrian return MS(val, AR_PHY_SPECTRAL_SCAN_ACTIVE); 177244943Sadrian} 178244943Sadrian 179244943SadrianHAL_BOOL 180244943Sadrianar5416IsSpectralEnabled(struct ath_hal *ah) 181244943Sadrian{ 182244943Sadrian uint32_t val; 183244943Sadrian 184244943Sadrian val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 185244943Sadrian return MS(val,AR_PHY_SPECTRAL_SCAN_ENA); 186244943Sadrian} 187244943Sadrian 188244943Sadrianvoid 189244943Sadrianar5416StartSpectralScan(struct ath_hal *ah) 190244943Sadrian{ 191244943Sadrian uint32_t val; 192244943Sadrian 193244943Sadrian ar5416PrepSpectralScan(ah); 194244943Sadrian 195244943Sadrian // Activate spectral scan 196244943Sadrian val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 197244943Sadrian val |= AR_PHY_SPECTRAL_SCAN_ENA; 198244943Sadrian val |= AR_PHY_SPECTRAL_SCAN_ACTIVE; 199244943Sadrian OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); 200244943Sadrian val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 201244943Sadrian val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG); 202244943Sadrian OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR); 203244943Sadrian} 204244943Sadrian 205244943Sadrianvoid 206244943Sadrianar5416StopSpectralScan(struct ath_hal *ah) 207244943Sadrian{ 208244943Sadrian uint32_t val; 209244943Sadrian val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 210244943Sadrian 211244943Sadrian // Deactivate spectral scan 212244943Sadrian val &= ~AR_PHY_SPECTRAL_SCAN_ENA; 213244943Sadrian val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE; 214244943Sadrian OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); 215244943Sadrian val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 216244943Sadrian val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR); 217244943Sadrian OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val); 218244943Sadrian} 219244943Sadrian 220244943Sadrianuint32_t 221244943Sadrianar5416GetSpectralConfig(struct ath_hal *ah) 222244943Sadrian{ 223244943Sadrian uint32_t val; 224244943Sadrian 225244943Sadrian val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 226244943Sadrian return val; 227244943Sadrian} 228244943Sadrian 229244943Sadrianvoid 230244943Sadrianar5416RestoreSpectralConfig(struct ath_hal *ah, uint32_t restoreval) 231244943Sadrian{ 232244943Sadrian uint32_t curval; 233244943Sadrian 234244943Sadrian ar5416PrepSpectralScan(ah); 235244943Sadrian 236244943Sadrian curval = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 237244943Sadrian 238244943Sadrian if (restoreval != curval) { 239244943Sadrian restoreval |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; 240244943Sadrian OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, restoreval); 241244943Sadrian } 242244943Sadrian return; 243244943Sadrian} 244244943Sadrian 245