1*6e778a7eSPedro F. Giffuni /*-
2*6e778a7eSPedro F. Giffuni * SPDX-License-Identifier: ISC
3*6e778a7eSPedro F. Giffuni *
4973d4077SAdrian Chadd * Copyright (c) 2012 Qualcomm Atheros, All Rights Reserved.
5973d4077SAdrian Chadd *
6973d4077SAdrian Chadd * Permission to use, copy, modify, and/or distribute this software for any
7973d4077SAdrian Chadd * purpose with or without fee is hereby granted, provided that the above
8973d4077SAdrian Chadd * copyright notice and this permission notice appear in all copies.
9973d4077SAdrian Chadd *
10973d4077SAdrian Chadd * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11973d4077SAdrian Chadd * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12973d4077SAdrian Chadd * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13973d4077SAdrian Chadd * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14973d4077SAdrian Chadd * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15973d4077SAdrian Chadd * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16973d4077SAdrian Chadd * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17973d4077SAdrian Chadd */
18973d4077SAdrian Chadd #include "opt_ah.h"
19973d4077SAdrian Chadd
20973d4077SAdrian Chadd #include "ah.h"
21973d4077SAdrian Chadd #include "ah_internal.h"
22973d4077SAdrian Chadd #include "ah_devid.h"
23973d4077SAdrian Chadd #include "ah_desc.h" /* NB: for HAL_PHYERR* */
24973d4077SAdrian Chadd
25973d4077SAdrian Chadd #include "ar5416/ar5416.h"
26973d4077SAdrian Chadd #include "ar5416/ar5416reg.h"
27973d4077SAdrian Chadd #include "ar5416/ar5416phy.h"
28973d4077SAdrian Chadd
29973d4077SAdrian Chadd /*
30973d4077SAdrian Chadd * Default AR9280 spectral scan parameters
31973d4077SAdrian Chadd */
32973d4077SAdrian Chadd #define AR5416_SPECTRAL_SCAN_ENA 0
33973d4077SAdrian Chadd #define AR5416_SPECTRAL_SCAN_ACTIVE 0
34973d4077SAdrian Chadd #define AR5416_SPECTRAL_SCAN_FFT_PERIOD 8
35973d4077SAdrian Chadd #define AR5416_SPECTRAL_SCAN_PERIOD 1
36973d4077SAdrian Chadd #define AR5416_SPECTRAL_SCAN_COUNT 16 //used to be 128
37973d4077SAdrian Chadd #define AR5416_SPECTRAL_SCAN_SHORT_REPEAT 1
38973d4077SAdrian Chadd
39973d4077SAdrian Chadd /* constants */
40973d4077SAdrian Chadd #define MAX_RADAR_RSSI_THRESH 0x3f
41973d4077SAdrian Chadd #define MAX_RADAR_HEIGHT 0x3f
42973d4077SAdrian Chadd #define ENABLE_ALL_PHYERR 0xffffffff
43973d4077SAdrian Chadd
44973d4077SAdrian Chadd static void ar5416DisableRadar(struct ath_hal *ah);
45973d4077SAdrian Chadd static void ar5416PrepSpectralScan(struct ath_hal *ah);
46973d4077SAdrian Chadd
47973d4077SAdrian Chadd static void
ar5416DisableRadar(struct ath_hal * ah)48973d4077SAdrian Chadd ar5416DisableRadar(struct ath_hal *ah)
49973d4077SAdrian Chadd {
50973d4077SAdrian Chadd uint32_t val;
51973d4077SAdrian Chadd
52973d4077SAdrian Chadd // Enable radar FFT
53973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_RADAR_0);
54973d4077SAdrian Chadd val |= AR_PHY_RADAR_0_FFT_ENA;
55973d4077SAdrian Chadd
56973d4077SAdrian Chadd // set radar detect thresholds to max to effectively disable radar
57973d4077SAdrian Chadd val &= ~AR_PHY_RADAR_0_RRSSI;
58973d4077SAdrian Chadd val |= SM(MAX_RADAR_RSSI_THRESH, AR_PHY_RADAR_0_RRSSI);
59973d4077SAdrian Chadd
60973d4077SAdrian Chadd val &= ~AR_PHY_RADAR_0_HEIGHT;
61973d4077SAdrian Chadd val |= SM(MAX_RADAR_HEIGHT, AR_PHY_RADAR_0_HEIGHT);
62973d4077SAdrian Chadd
63973d4077SAdrian Chadd val &= ~(AR_PHY_RADAR_0_ENA);
64973d4077SAdrian Chadd OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
65973d4077SAdrian Chadd
66973d4077SAdrian Chadd // disable extension radar detect
67973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
68973d4077SAdrian Chadd OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA);
69973d4077SAdrian Chadd
70973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_RX_FILTER);
71973d4077SAdrian Chadd val |= (1<<13);
72973d4077SAdrian Chadd OS_REG_WRITE(ah, AR_RX_FILTER, val);
73973d4077SAdrian Chadd }
74973d4077SAdrian Chadd
75973d4077SAdrian Chadd static void
ar5416PrepSpectralScan(struct ath_hal * ah)76973d4077SAdrian Chadd ar5416PrepSpectralScan(struct ath_hal *ah)
77973d4077SAdrian Chadd {
78973d4077SAdrian Chadd
79973d4077SAdrian Chadd ar5416DisableRadar(ah);
80973d4077SAdrian Chadd OS_REG_WRITE(ah, AR_PHY_ERR, ENABLE_ALL_PHYERR);
81973d4077SAdrian Chadd }
82973d4077SAdrian Chadd
83973d4077SAdrian Chadd void
ar5416ConfigureSpectralScan(struct ath_hal * ah,HAL_SPECTRAL_PARAM * ss)84973d4077SAdrian Chadd ar5416ConfigureSpectralScan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)
85973d4077SAdrian Chadd {
86973d4077SAdrian Chadd uint32_t val;
87973d4077SAdrian Chadd
88973d4077SAdrian Chadd ar5416PrepSpectralScan(ah);
89973d4077SAdrian Chadd
90973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
91973d4077SAdrian Chadd
92973d4077SAdrian Chadd if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) {
93973d4077SAdrian Chadd val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD;
94973d4077SAdrian Chadd val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);
95973d4077SAdrian Chadd }
96973d4077SAdrian Chadd
97973d4077SAdrian Chadd if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {
98973d4077SAdrian Chadd val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;
99973d4077SAdrian Chadd val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);
100973d4077SAdrian Chadd }
101973d4077SAdrian Chadd
102973d4077SAdrian Chadd if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {
103973d4077SAdrian Chadd val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;
104973d4077SAdrian Chadd val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);
105973d4077SAdrian Chadd }
106973d4077SAdrian Chadd
107973d4077SAdrian Chadd /* This section is different for Kiwi and Merlin */
108973d4077SAdrian Chadd if (AR_SREV_MERLIN(ah) ) {
109973d4077SAdrian Chadd if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) {
110973d4077SAdrian Chadd val &= ~AR_PHY_SPECTRAL_SCAN_COUNT;
111973d4077SAdrian Chadd val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT);
112973d4077SAdrian Chadd }
113973d4077SAdrian Chadd
114973d4077SAdrian Chadd if (ss->ss_short_report == AH_TRUE) {
115973d4077SAdrian Chadd val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
116bcd2a42fSAdrian Chadd } else if (ss->ss_short_report != HAL_SPECTRAL_PARAM_NOVAL) {
117973d4077SAdrian Chadd val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
118973d4077SAdrian Chadd }
119973d4077SAdrian Chadd } else {
120973d4077SAdrian Chadd if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) {
121973d4077SAdrian Chadd /*
122f6b6084bSPedro F. Giffuni * In Merlin, for continuous scan, scan_count = 128.
123973d4077SAdrian Chadd * In case of Kiwi, this value should be 0
124973d4077SAdrian Chadd */
125973d4077SAdrian Chadd if (ss->ss_count == 128)
126973d4077SAdrian Chadd ss->ss_count = 0;
127973d4077SAdrian Chadd val &= ~AR_PHY_SPECTRAL_SCAN_COUNT_KIWI;
128973d4077SAdrian Chadd val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI);
129973d4077SAdrian Chadd }
130973d4077SAdrian Chadd
131973d4077SAdrian Chadd if (ss->ss_short_report == AH_TRUE) {
132973d4077SAdrian Chadd val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI;
133bcd2a42fSAdrian Chadd } else if (ss->ss_short_report != HAL_SPECTRAL_PARAM_NOVAL) {
134973d4077SAdrian Chadd val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI;
135973d4077SAdrian Chadd }
136973d4077SAdrian Chadd
137973d4077SAdrian Chadd //Select the mask to be same as before
138973d4077SAdrian Chadd val |= AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT_KIWI;
139973d4077SAdrian Chadd }
140973d4077SAdrian Chadd // Enable spectral scan
141973d4077SAdrian Chadd OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENA);
142973d4077SAdrian Chadd
143973d4077SAdrian Chadd ar5416GetSpectralParams(ah, ss);
144973d4077SAdrian Chadd }
145973d4077SAdrian Chadd
146973d4077SAdrian Chadd /*
147973d4077SAdrian Chadd * Get the spectral parameter values and return them in the pe
148973d4077SAdrian Chadd * structure
149973d4077SAdrian Chadd */
150973d4077SAdrian Chadd void
ar5416GetSpectralParams(struct ath_hal * ah,HAL_SPECTRAL_PARAM * ss)151973d4077SAdrian Chadd ar5416GetSpectralParams(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)
152973d4077SAdrian Chadd {
153973d4077SAdrian Chadd uint32_t val;
154973d4077SAdrian Chadd
155973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
156973d4077SAdrian Chadd
157973d4077SAdrian Chadd ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);
158973d4077SAdrian Chadd ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD);
159973d4077SAdrian Chadd if (AR_SREV_MERLIN(ah) ) {
160973d4077SAdrian Chadd ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT);
161973d4077SAdrian Chadd ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
162973d4077SAdrian Chadd } else {
163973d4077SAdrian Chadd ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI);
164973d4077SAdrian Chadd ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI);
165973d4077SAdrian Chadd }
166973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_RADAR_1);
167973d4077SAdrian Chadd ss->radar_bin_thresh_sel = MS(val, AR_PHY_RADAR_1_BIN_THRESH_SELECT);
168973d4077SAdrian Chadd }
169973d4077SAdrian Chadd
170973d4077SAdrian Chadd HAL_BOOL
ar5416IsSpectralActive(struct ath_hal * ah)171973d4077SAdrian Chadd ar5416IsSpectralActive(struct ath_hal *ah)
172973d4077SAdrian Chadd {
173973d4077SAdrian Chadd uint32_t val;
174973d4077SAdrian Chadd
175973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
176973d4077SAdrian Chadd return MS(val, AR_PHY_SPECTRAL_SCAN_ACTIVE);
177973d4077SAdrian Chadd }
178973d4077SAdrian Chadd
179973d4077SAdrian Chadd HAL_BOOL
ar5416IsSpectralEnabled(struct ath_hal * ah)180973d4077SAdrian Chadd ar5416IsSpectralEnabled(struct ath_hal *ah)
181973d4077SAdrian Chadd {
182973d4077SAdrian Chadd uint32_t val;
183973d4077SAdrian Chadd
184973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
185973d4077SAdrian Chadd return MS(val,AR_PHY_SPECTRAL_SCAN_ENA);
186973d4077SAdrian Chadd }
187973d4077SAdrian Chadd
188973d4077SAdrian Chadd void
ar5416StartSpectralScan(struct ath_hal * ah)189973d4077SAdrian Chadd ar5416StartSpectralScan(struct ath_hal *ah)
190973d4077SAdrian Chadd {
191973d4077SAdrian Chadd uint32_t val;
192973d4077SAdrian Chadd
193973d4077SAdrian Chadd ar5416PrepSpectralScan(ah);
194973d4077SAdrian Chadd
195973d4077SAdrian Chadd // Activate spectral scan
196973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
197973d4077SAdrian Chadd val |= AR_PHY_SPECTRAL_SCAN_ENA;
198973d4077SAdrian Chadd val |= AR_PHY_SPECTRAL_SCAN_ACTIVE;
199973d4077SAdrian Chadd OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
200973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
201973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG);
202973d4077SAdrian Chadd OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR);
203973d4077SAdrian Chadd }
204973d4077SAdrian Chadd
205973d4077SAdrian Chadd void
ar5416StopSpectralScan(struct ath_hal * ah)206973d4077SAdrian Chadd ar5416StopSpectralScan(struct ath_hal *ah)
207973d4077SAdrian Chadd {
208973d4077SAdrian Chadd uint32_t val;
209973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
210973d4077SAdrian Chadd
211973d4077SAdrian Chadd // Deactivate spectral scan
212973d4077SAdrian Chadd val &= ~AR_PHY_SPECTRAL_SCAN_ENA;
213973d4077SAdrian Chadd val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE;
214973d4077SAdrian Chadd OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
215973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
216973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR);
217973d4077SAdrian Chadd OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val);
218973d4077SAdrian Chadd }
219973d4077SAdrian Chadd
220973d4077SAdrian Chadd uint32_t
ar5416GetSpectralConfig(struct ath_hal * ah)221973d4077SAdrian Chadd ar5416GetSpectralConfig(struct ath_hal *ah)
222973d4077SAdrian Chadd {
223973d4077SAdrian Chadd uint32_t val;
224973d4077SAdrian Chadd
225973d4077SAdrian Chadd val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
226973d4077SAdrian Chadd return val;
227973d4077SAdrian Chadd }
228973d4077SAdrian Chadd
229973d4077SAdrian Chadd void
ar5416RestoreSpectralConfig(struct ath_hal * ah,uint32_t restoreval)230973d4077SAdrian Chadd ar5416RestoreSpectralConfig(struct ath_hal *ah, uint32_t restoreval)
231973d4077SAdrian Chadd {
232973d4077SAdrian Chadd uint32_t curval;
233973d4077SAdrian Chadd
234973d4077SAdrian Chadd ar5416PrepSpectralScan(ah);
235973d4077SAdrian Chadd
236973d4077SAdrian Chadd curval = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
237973d4077SAdrian Chadd
238973d4077SAdrian Chadd if (restoreval != curval) {
239973d4077SAdrian Chadd restoreval |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
240973d4077SAdrian Chadd OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, restoreval);
241973d4077SAdrian Chadd }
242973d4077SAdrian Chadd return;
243973d4077SAdrian Chadd }
244