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