]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / ath / ath_hal / ar5416 / ar5416_spectral.c
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
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
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
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 continous 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
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
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
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
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
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
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
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