#include "opt_ah.h"
#include "ah.h"
#include "ah_internal.h"
#include "ah_devid.h"
#include "ah_desc.h"
#include "ar5416/ar5416.h"
#include "ar5416/ar5416reg.h"
#include "ar5416/ar5416phy.h"
#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
#define AR5416_SPECTRAL_SCAN_SHORT_REPEAT 1
#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;
val = OS_REG_READ(ah, AR_PHY_RADAR_0);
val |= AR_PHY_RADAR_0_FFT_ENA;
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);
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);
}
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) {
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;
}
val |= AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT_KIWI;
}
OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENA);
ar5416GetSpectralParams(ah, ss);
}
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);
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);
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;
}