1/*- 2 * SPDX-License-Identifier: ISC 3 * 4 * Copyright (c) 2012 Qualcomm Atheros, All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $FreeBSD: releng/12.0/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c 326695 2017-12-08 15:57:29Z pfg $ 19 */ 20#include "opt_ah.h" 21 22#include "ah.h" 23#include "ah_internal.h" 24#include "ah_devid.h" 25#include "ah_desc.h" /* NB: for HAL_PHYERR* */ 26 27#include "ar5416/ar5416.h" 28#include "ar5416/ar5416reg.h" 29#include "ar5416/ar5416phy.h" 30 31/* 32 * Default AR9280 spectral scan parameters 33 */ 34#define AR5416_SPECTRAL_SCAN_ENA 0 35#define AR5416_SPECTRAL_SCAN_ACTIVE 0 36#define AR5416_SPECTRAL_SCAN_FFT_PERIOD 8 37#define AR5416_SPECTRAL_SCAN_PERIOD 1 38#define AR5416_SPECTRAL_SCAN_COUNT 16 //used to be 128 39#define AR5416_SPECTRAL_SCAN_SHORT_REPEAT 1 40 41/* constants */ 42#define MAX_RADAR_RSSI_THRESH 0x3f 43#define MAX_RADAR_HEIGHT 0x3f 44#define ENABLE_ALL_PHYERR 0xffffffff 45 46static void ar5416DisableRadar(struct ath_hal *ah); 47static void ar5416PrepSpectralScan(struct ath_hal *ah); 48 49static void 50ar5416DisableRadar(struct ath_hal *ah) 51{ 52 uint32_t val; 53 54 // Enable radar FFT 55 val = OS_REG_READ(ah, AR_PHY_RADAR_0); 56 val |= AR_PHY_RADAR_0_FFT_ENA; 57 58 // set radar detect thresholds to max to effectively disable radar 59 val &= ~AR_PHY_RADAR_0_RRSSI; 60 val |= SM(MAX_RADAR_RSSI_THRESH, AR_PHY_RADAR_0_RRSSI); 61 62 val &= ~AR_PHY_RADAR_0_HEIGHT; 63 val |= SM(MAX_RADAR_HEIGHT, AR_PHY_RADAR_0_HEIGHT); 64 65 val &= ~(AR_PHY_RADAR_0_ENA); 66 OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); 67 68 // disable extension radar detect 69 val = OS_REG_READ(ah, AR_PHY_RADAR_EXT); 70 OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA); 71 72 val = OS_REG_READ(ah, AR_RX_FILTER); 73 val |= (1<<13); 74 OS_REG_WRITE(ah, AR_RX_FILTER, val); 75} 76 77static void 78ar5416PrepSpectralScan(struct ath_hal *ah) 79{ 80 81 ar5416DisableRadar(ah); 82 OS_REG_WRITE(ah, AR_PHY_ERR, ENABLE_ALL_PHYERR); 83} 84 85void 86ar5416ConfigureSpectralScan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) 87{ 88 uint32_t val; 89 90 ar5416PrepSpectralScan(ah); 91 92 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 93 94 if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) { 95 val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD; 96 val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); 97 } 98 99 if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { 100 val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; 101 val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); 102 } 103 104 if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { 105 val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; 106 val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); 107 } 108 109 /* This section is different for Kiwi and Merlin */ 110 if (AR_SREV_MERLIN(ah) ) { 111 if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) { 112 val &= ~AR_PHY_SPECTRAL_SCAN_COUNT; 113 val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT); 114 } 115 116 if (ss->ss_short_report == AH_TRUE) { 117 val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; 118 } else if (ss->ss_short_report != HAL_SPECTRAL_PARAM_NOVAL) { 119 val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; 120 } 121 } else { 122 if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) { 123 /* 124 * In Merlin, for continuous scan, scan_count = 128. 125 * In case of Kiwi, this value should be 0 126 */ 127 if (ss->ss_count == 128) 128 ss->ss_count = 0; 129 val &= ~AR_PHY_SPECTRAL_SCAN_COUNT_KIWI; 130 val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI); 131 } 132 133 if (ss->ss_short_report == AH_TRUE) { 134 val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI; 135 } else if (ss->ss_short_report != HAL_SPECTRAL_PARAM_NOVAL) { 136 val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI; 137 } 138 139 //Select the mask to be same as before 140 val |= AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT_KIWI; 141 } 142 // Enable spectral scan 143 OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENA); 144 145 ar5416GetSpectralParams(ah, ss); 146} 147 148/* 149 * Get the spectral parameter values and return them in the pe 150 * structure 151 */ 152void 153ar5416GetSpectralParams(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) 154{ 155 uint32_t val; 156 157 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 158 159 ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); 160 ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD); 161 if (AR_SREV_MERLIN(ah) ) { 162 ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT); 163 ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); 164 } else { 165 ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI); 166 ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI); 167 } 168 val = OS_REG_READ(ah, AR_PHY_RADAR_1); 169 ss->radar_bin_thresh_sel = MS(val, AR_PHY_RADAR_1_BIN_THRESH_SELECT); 170} 171 172HAL_BOOL 173ar5416IsSpectralActive(struct ath_hal *ah) 174{ 175 uint32_t val; 176 177 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 178 return MS(val, AR_PHY_SPECTRAL_SCAN_ACTIVE); 179} 180 181HAL_BOOL 182ar5416IsSpectralEnabled(struct ath_hal *ah) 183{ 184 uint32_t val; 185 186 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 187 return MS(val,AR_PHY_SPECTRAL_SCAN_ENA); 188} 189 190void 191ar5416StartSpectralScan(struct ath_hal *ah) 192{ 193 uint32_t val; 194 195 ar5416PrepSpectralScan(ah); 196 197 // Activate spectral scan 198 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 199 val |= AR_PHY_SPECTRAL_SCAN_ENA; 200 val |= AR_PHY_SPECTRAL_SCAN_ACTIVE; 201 OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); 202 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 203 val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG); 204 OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR); 205} 206 207void 208ar5416StopSpectralScan(struct ath_hal *ah) 209{ 210 uint32_t val; 211 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 212 213 // Deactivate spectral scan 214 val &= ~AR_PHY_SPECTRAL_SCAN_ENA; 215 val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE; 216 OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); 217 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 218 val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR); 219 OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val); 220} 221 222uint32_t 223ar5416GetSpectralConfig(struct ath_hal *ah) 224{ 225 uint32_t val; 226 227 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 228 return val; 229} 230 231void 232ar5416RestoreSpectralConfig(struct ath_hal *ah, uint32_t restoreval) 233{ 234 uint32_t curval; 235 236 ar5416PrepSpectralScan(ah); 237 238 curval = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 239 240 if (restoreval != curval) { 241 restoreval |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; 242 OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, restoreval); 243 } 244 return; 245} 246