Path: blob/main/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_spectral.c
48526 views
/*1* Copyright (c) 2013 Qualcomm Atheros, Inc.2*3* Permission to use, copy, modify, and/or distribute this software for any4* purpose with or without fee is hereby granted, provided that the above5* copyright notice and this permission notice appear in all copies.6*7* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH8* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY9* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,10* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM11* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR12* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR13* PERFORMANCE OF THIS SOFTWARE.14*/15#include "opt_ah.h"1617//#ifdef AH_SUPPORT_AR93001819#include "ah.h"20#include "ah_desc.h"21#include "ah_internal.h"2223#include "ar9300_freebsd_inc.h"2425#include "ar9300/ar9300phy.h"26#include "ar9300/ar9300.h"27#include "ar9300/ar9300reg.h"28#include "ar9300/ar9300desc.h"2930#if ATH_SUPPORT_SPECTRAL3132/*33* Default 9300 spectral scan parameters34*/35#define AR9300_SPECTRAL_SCAN_ENA 036#define AR9300_SPECTRAL_SCAN_ACTIVE 037#define AR9300_SPECTRAL_SCAN_FFT_PERIOD 838#define AR9300_SPECTRAL_SCAN_PERIOD 139#define AR9300_SPECTRAL_SCAN_COUNT 16 /* used to be 128 */40#define AR9300_SPECTRAL_SCAN_SHORT_REPEAT 14142/* constants */43#define MAX_RADAR_DC_PWR_THRESH 12744#define MAX_RADAR_RSSI_THRESH 0x3f45#define MAX_RADAR_HEIGHT 0x3f46#define MAX_CCA_THRESH 12747#define ENABLE_ALL_PHYERR 0xffffffff4849void ar9300_disable_cck(struct ath_hal *ah);50void ar9300_disable_radar(struct ath_hal *ah);51void ar9300_disable_restart(struct ath_hal *ah);52void ar9300_set_radar_dc_thresh(struct ath_hal *ah);53void ar9300_disable_weak_signal(struct ath_hal *ah);54void ar9300_disable_strong_signal(struct ath_hal *ah);55void ar9300_prep_spectral_scan(struct ath_hal *ah);56void ar9300_disable_dc_offset(struct ath_hal *ah);57void ar9300_enable_cck_detect(struct ath_hal *ah);5859void60ar9300_disable_cck(struct ath_hal *ah)61{62u_int32_t val;6364val = OS_REG_READ(ah, AR_PHY_MODE);65val &= ~(AR_PHY_MODE_DYN_CCK_DISABLE);6667OS_REG_WRITE(ah, AR_PHY_MODE, val);68}6970void71ar9300_disable_radar(struct ath_hal *ah)72{73u_int32_t val;7475/* Enable radar FFT */76val = OS_REG_READ(ah, AR_PHY_RADAR_0);77val |= AR_PHY_RADAR_0_FFT_ENA;7879/* set radar detect thresholds to max to effectively disable radar */80val &= ~AR_PHY_RADAR_0_RRSSI;81val |= SM(MAX_RADAR_RSSI_THRESH, AR_PHY_RADAR_0_RRSSI);8283val &= ~AR_PHY_RADAR_0_HEIGHT;84val |= SM(MAX_RADAR_HEIGHT, AR_PHY_RADAR_0_HEIGHT);8586val &= ~(AR_PHY_RADAR_0_ENA);87OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);8889/* disable extension radar detect */90val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);91OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA);9293val = OS_REG_READ(ah, AR_RX_FILTER);94val |= (1 << 13);95OS_REG_WRITE(ah, AR_RX_FILTER, val);96}9798void ar9300_disable_restart(struct ath_hal *ah)99{100u_int32_t val;101val = OS_REG_READ(ah, AR_PHY_RESTART);102val &= ~AR_PHY_RESTART_ENA;103OS_REG_WRITE(ah, AR_PHY_RESTART, val);104105val = OS_REG_READ(ah, AR_PHY_RESTART);106}107108void ar9300_set_radar_dc_thresh(struct ath_hal *ah)109{110u_int32_t val;111val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);112val &= ~AR_PHY_RADAR_DC_PWR_THRESH;113val |= SM(MAX_RADAR_DC_PWR_THRESH, AR_PHY_RADAR_DC_PWR_THRESH);114OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val);115116val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);117}118119void120ar9300_disable_weak_signal(struct ath_hal *ah)121{122/* set firpwr to max (signed) */123OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR, 0x7f);124OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR_SIGN_BIT);125126/* set firstep to max */127OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRSTEP, 0x3f);128129/* set relpwr to max (signed) */130OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELPWR, 0x1f);131OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELPWR_SIGN_BIT);132133/* set relstep to max (signed) */134OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELSTEP, 0x1f);135OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELSTEP_SIGN_BIT);136137/* set firpwr_low to max (signed) */138OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRPWR, 0x7f);139OS_REG_CLR_BIT(140ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRPWR_SIGN_BIT);141142/* set firstep_low to max */143OS_REG_RMW_FIELD(144ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, 0x3f);145146/* set relstep_low to max (signed) */147OS_REG_RMW_FIELD(148ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_RELSTEP, 0x1f);149OS_REG_CLR_BIT(150ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_RELSTEP_SIGN_BIT);151}152153void154ar9300_disable_strong_signal(struct ath_hal *ah)155{156u_int32_t val;157158val = OS_REG_READ(ah, AR_PHY_TIMING5);159val |= AR_PHY_TIMING5_RSSI_THR1A_ENA;160OS_REG_WRITE(ah, AR_PHY_TIMING5, val);161162OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_RSSI_THR1A, 0x7f);163164}165void166ar9300_set_cca_threshold(struct ath_hal *ah, u_int8_t thresh62)167{168OS_REG_RMW_FIELD(ah, AR_PHY_CCA_0, AR_PHY_CCA_THRESH62, thresh62);169OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, thresh62);170/*171OS_REG_RMW_FIELD(ah,172AR_PHY_EXTCHN_PWRTHR1, AR_PHY_EXT_CCA0_THRESH62, thresh62);173*/174OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, AR_PHY_EXT_CCA_THRESH62, thresh62);175}176177static void ar9300_classify_strong_bins(struct ath_hal *ah)178{179OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH, 0x1);180}181182void ar9300_disable_dc_offset(struct ath_hal *ah)183{184OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET, 0);185}186187void ar9300_enable_cck_detect(struct ath_hal *ah)188{189OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK, 0);190OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DYNAMIC, 1);191}192193void ar9300_prep_spectral_scan(struct ath_hal *ah)194{195ar9300_disable_radar(ah);196ar9300_classify_strong_bins(ah);197ar9300_disable_dc_offset(ah);198if (AH_PRIVATE(ah)->ah_curchan &&199IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan))200{ /* fast clock */201ar9300_enable_cck_detect(ah);202}203#ifdef DEMO_MODE204ar9300_disable_strong_signal(ah);205ar9300_disable_weak_signal(ah);206ar9300_set_radar_dc_thresh(ah);207ar9300_set_cca_threshold(ah, MAX_CCA_THRESH);208/*ar9300_disable_restart(ah);*/209#endif210OS_REG_WRITE(ah, AR_PHY_ERR, HAL_PHYERR_SPECTRAL);211}212213214//#define TEST_NOISE_PWR_WITHOUT_EEPROM 1215#ifdef TEST_NOISE_PWR_WITHOUT_EEPROM216struct nf_cal {217int cal;218int pwr;219};220struct nf_cal_table_t {221int freq;222struct nf_cal chain[AH_MAX_CHAINS];223};224225static const struct nf_cal_table_t nf_cal_table[] =226{227/* ch 1 */ {2412, { {N2DBM(-101, 00), N2DBM( -94, 25)},228{N2DBM(-107, 75), N2DBM( -99, 75)},229} },230/* ch 6 */ {2437, { {N2DBM(-102, 25), N2DBM( -94, 25)},231{N2DBM(-106, 00), N2DBM( -97, 25)},232} },233/* ch 11 */ {2462, { {N2DBM(-101, 50), N2DBM( -95, 00)},234{N2DBM(-105, 50), N2DBM( -98, 00)},235} },236/* ch 36 */ {5180, { {N2DBM(-114, 25), N2DBM( -95, 00)},237{N2DBM(-114, 75), N2DBM( -94, 00)},238} },239/* ch 44 */ {5220, { {N2DBM(-113, 00), N2DBM( -95, 00)},240{N2DBM(-115, 00), N2DBM( -94, 50)},241} },242/* ch 64 */ {5320, { {N2DBM(-113, 00), N2DBM( -95, 00)}, // not cal'ed243{N2DBM(-115, 00), N2DBM( -94, 50)},244} },245/* ch 100*/ {5500, { {N2DBM(-111, 50), N2DBM( -93, 75)},246{N2DBM(-112, 00), N2DBM( -95, 25)},247} },248/* ch 120*/ {5600, { {N2DBM(-111, 50), N2DBM( -93, 75)},249{N2DBM(-112, 00), N2DBM( -95, 25)},250} },251/* ch 140*/ {5700, { {N2DBM(-111, 75), N2DBM( -95, 00)},252{N2DBM(-111, 75), N2DBM( -96, 00)},253} },254/* ch 157*/ {5785, { {N2DBM(-112, 50), N2DBM( -94, 75)},255{N2DBM(-111, 75), N2DBM( -95, 50)},256} },257/* ch 165*/ {5825, { {N2DBM(-111, 50), N2DBM( -95, 00)},258{N2DBM(-112, 00), N2DBM( -95, 00)},259} },260{0}261};262263static int264ar9300_noise_floor_get(struct ath_hal *ah, int freq_mhz, int ch)265{266int i;267for (i = 0; nf_cal_table[i].freq != 0; i++) {268if (nf_cal_table[i + 0].freq == freq_mhz ||269nf_cal_table[i + 1].freq > freq_mhz ||270nf_cal_table[i + 1].freq == 0) {271return nf_cal_table[i].chain[ch].cal;272}273}274275ath_hal_printf(ah,276"%s: **Warning: device %d.%d: "277"no nf cal offset found for freq %d chain %d\n",278__func__, (AH_PRIVATE(ah))->ah_macVersion,279(AH_PRIVATE(ah))->ah_macRev, freq_mhz, ch);280return 0;281}282283static int284ar9300_noise_floor_power_get(struct ath_hal *ah, int freq_mhz, int ch)285{286int i;287for (i = 0; nf_cal_table[i].freq != 0; i++) {288if (nf_cal_table[i + 0].freq == freq_mhz ||289nf_cal_table[i + 1].freq > freq_mhz ||290nf_cal_table[i + 1].freq == 0) {291return nf_cal_table[i].chain[ch].pwr;292}293}294295ath_hal_printf(ah,296"%s: **Warning: device %d.%d: "297"no nf pwr offset found for freq %d chain %d\n",298__func__, (AH_PRIVATE(ah))->ah_macVersion,299(AH_PRIVATE(ah))->ah_macRev, freq_mhz, ch);300return 0;301}302#else303#define ar9300_noise_floor_get(_ah,_f,_ich) ar9300_noise_floor_cal_or_power_get((_ah), (_f), (_ich), 1/*use_cal*/)304#define ar9300_noise_floor_power_get(_ah,_f,_ich) ar9300_noise_floor_cal_or_power_get((_ah), (_f), (_ich), 0/*use_cal*/)305#endif306307308void309ar9300_configure_spectral_scan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)310{311u_int32_t val;312//uint32_t i;313struct ath_hal_9300 *ahp = AH9300(ah);314HAL_BOOL asleep = ahp->ah_chip_full_sleep;315//int16_t nf_buf[HAL_NUM_NF_READINGS];316317if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {318ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);319}320321HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "%s: called\n", __func__);322323HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_fft_period=%d\n", ss->ss_fft_period);324HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_period=%d\n", ss->ss_period);325HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_count=%d\n", ss->ss_count);326HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_short_report=%d\n", ss->ss_short_report);327HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_spectral_pri=%d\n", ss->ss_spectral_pri);328329ar9300_prep_spectral_scan(ah);330331#if 0332if (ss->ss_spectral_pri) {333for (i = 0; i < HAL_NUM_NF_READINGS; i++) {334nf_buf[i] = NOISE_PWR_DBM_2_INT(ss->ss_nf_cal[i]);335}336ar9300_load_nf(ah, nf_buf);337#ifdef DEMO_MODE338ar9300_disable_strong_signal(ah);339ar9300_disable_weak_signal(ah);340ar9300_set_radar_dc_thresh(ah);341ar9300_set_cca_threshold(ah, MAX_CCA_THRESH);342/*ar9300_disable_restart(ah);*/343#endif344}345#endif346347val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);348349if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) {350val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD;351val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);352}353354if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {355val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;356val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);357}358359if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) {360val &= ~AR_PHY_SPECTRAL_SCAN_COUNT;361/* Remnants of a Merlin bug, 128 translates to 0 for362* continuous scanning. Instead we do piecemeal captures363* of 64 samples for Osprey.364*/365if (ss->ss_count == 128) {366val |= SM(0, AR_PHY_SPECTRAL_SCAN_COUNT);367} else {368val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT);369}370}371372if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {373val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;374val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);375}376377if (ss->ss_short_report != HAL_SPECTRAL_PARAM_NOVAL) {378if (ss->ss_short_report == AH_TRUE) {379val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;380} else {381val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;382}383}384385/* if noise power cal, force high priority */386if (ss->ss_spectral_pri != HAL_SPECTRAL_PARAM_NOVAL) {387if (ss->ss_spectral_pri) {388val |= AR_PHY_SPECTRAL_SCAN_PRIORITY_HI;389} else {390val &= ~AR_PHY_SPECTRAL_SCAN_PRIORITY_HI;391}392}393394/* enable spectral scan */395OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENABLE);396397if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {398ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);399}400}401402/*403* Get the spectral parameter values and return them in the pe404* structure405*/406407void408ar9300_get_spectral_params(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)409{410u_int32_t val;411HAL_CHANNEL_INTERNAL *chan = NULL;412const struct ieee80211_channel *c;413int i, ichain, rx_chain_status;414struct ath_hal_9300 *ahp = AH9300(ah);415HAL_BOOL asleep = ahp->ah_chip_full_sleep;416417HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "%s: called\n", __func__);418419c = AH_PRIVATE(ah)->ah_curchan;420if (c != NULL)421chan = ath_hal_checkchannel(ah, c);422423// XXX TODO: just always wake up all chips?424if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {425ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);426}427428val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);429430ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);431ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD);432ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT);433ss->ss_short_report = (val & AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT) ? 1:0;434ss->ss_spectral_pri = ( val & AR_PHY_SPECTRAL_SCAN_PRIORITY_HI) ? 1:0;435ss->ss_enabled = !! (val & AR_PHY_SPECTRAL_SCAN_ENABLE);436ss->ss_active = !! (val & AR_PHY_SPECTRAL_SCAN_ACTIVE);437438HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_fft_period=%d\n", ss->ss_fft_period);439HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_period=%d\n", ss->ss_period);440HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_count=%d\n", ss->ss_count);441HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_short_report=%d\n", ss->ss_short_report);442HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_spectral_pri=%d\n", ss->ss_spectral_pri);443HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_enabled=%d\n", ss->ss_enabled);444HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "ss_active=%d\n", ss->ss_active);445446OS_MEMZERO(ss->ss_nf_cal, sizeof(ss->ss_nf_cal));447OS_MEMZERO(ss->ss_nf_pwr, sizeof(ss->ss_nf_cal));448ss->ss_nf_temp_data = 0;449450if (chan != NULL) {451rx_chain_status = OS_REG_READ(ah, AR_PHY_RX_CHAINMASK) & 0x7;452for (i = 0; i < HAL_NUM_NF_READINGS; i++) {453ichain = i % 3;454if (rx_chain_status & (1 << ichain)) {455ss->ss_nf_cal[i] =456ar9300_noise_floor_get(ah, chan->channel, ichain);457ss->ss_nf_pwr[i] =458ar9300_noise_floor_power_get(ah, chan->channel, ichain);459}460}461ss->ss_nf_temp_data = OS_REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, AR_PHY_BB_THERM_ADC_4_LATEST_THERM);462} else {463HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,464"%s: chan is NULL - no ss nf values\n", __func__);465}466467if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {468ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);469}470}471472HAL_BOOL473ar9300_is_spectral_active(struct ath_hal *ah)474{475u_int32_t val;476477val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);478return MS(val, AR_PHY_SPECTRAL_SCAN_ACTIVE);479}480481HAL_BOOL482ar9300_is_spectral_enabled(struct ath_hal *ah)483{484u_int32_t val;485486val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);487return MS(val, AR_PHY_SPECTRAL_SCAN_ENABLE);488}489490void ar9300_start_spectral_scan(struct ath_hal *ah)491{492u_int32_t val;493struct ath_hal_9300 *ahp = AH9300(ah);494HAL_BOOL asleep = ahp->ah_chip_full_sleep;495496if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {497ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);498}499500HALDEBUG(ah, HAL_DEBUG_SPECTRAL, "%s: called\n", __func__);501502ar9300_prep_spectral_scan(ah);503504/* activate spectral scan */505val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);506/* This is a hardware bug fix, the enable and active bits should507* not be set/reset in the same write operation to the register508*/509if (!(val & AR_PHY_SPECTRAL_SCAN_ENABLE)) {510val |= AR_PHY_SPECTRAL_SCAN_ENABLE;511OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);512val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);513}514val |= AR_PHY_SPECTRAL_SCAN_ACTIVE;515OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);516517/* Reset the PHY_ERR_MASK */518val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG);519OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR);520521if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {522ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);523}524}525526void ar9300_stop_spectral_scan(struct ath_hal *ah)527{528u_int32_t val;529struct ath_hal_9300 *ahp = AH9300(ah);530HAL_BOOL asleep = ahp->ah_chip_full_sleep;531532if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {533ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);534}535val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);536537/* deactivate spectral scan */538/* HW Bug fix -- Do not disable the spectral scan539* only turn off the active bit540*/541//val &= ~AR_PHY_SPECTRAL_SCAN_ENABLE;542val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE;543OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);544val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);545546OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH,547ahp->ah_radar1);548OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET,549ahp->ah_dc_offset);550OS_REG_WRITE(ah, AR_PHY_ERR, 0);551552if (AH_PRIVATE(ah)->ah_curchan &&553IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan))554{ /* fast clock */555OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK,556ahp->ah_disable_cck);557}558559val = OS_REG_READ(ah, AR_PHY_ERR);560561val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR);562OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val);563564if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {565ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);566}567}568569u_int32_t ar9300_get_spectral_config(struct ath_hal *ah)570{571u_int32_t val;572struct ath_hal_9300 *ahp = AH9300(ah);573HAL_BOOL asleep = ahp->ah_chip_full_sleep;574575if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {576ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);577}578579val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);580581if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {582ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);583}584return val;585}586587int16_t ar9300_get_ctl_chan_nf(struct ath_hal *ah)588{589int16_t nf;590#if 0591struct ath_hal_private *ahpriv = AH_PRIVATE(ah);592#endif593594if ( (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) {595/* Noise floor calibration value is ready */596nf = MS(OS_REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);597} else {598/* NF calibration is not done, return nominal value */599nf = AH9300(ah)->nfp->nominal;600}601if (nf & 0x100) {602nf = (0 - ((nf ^ 0x1ff) + 1));603}604return nf;605}606607int16_t ar9300_get_ext_chan_nf(struct ath_hal *ah)608{609int16_t nf;610#if 0611struct ath_hal_private *ahpriv = AH_PRIVATE(ah);612#endif613614if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) {615/* Noise floor calibration value is ready */616nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);617} else {618/* NF calibration is not done, return nominal value */619nf = AH9300(ah)->nfp->nominal;620}621if (nf & 0x100) {622nf = (0 - ((nf ^ 0x1ff) + 1));623}624return nf;625}626627#endif /* ATH_SUPPORT_SPECTRAL */628//#endif629630631632