1b7d5e03cSMatthew Dillon /*
2b7d5e03cSMatthew Dillon  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3b7d5e03cSMatthew Dillon  *
4b7d5e03cSMatthew Dillon  * Permission to use, copy, modify, and/or distribute this software for any
5b7d5e03cSMatthew Dillon  * purpose with or without fee is hereby granted, provided that the above
6b7d5e03cSMatthew Dillon  * copyright notice and this permission notice appear in all copies.
7b7d5e03cSMatthew Dillon  *
8b7d5e03cSMatthew Dillon  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9b7d5e03cSMatthew Dillon  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10b7d5e03cSMatthew Dillon  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11b7d5e03cSMatthew Dillon  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12b7d5e03cSMatthew Dillon  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13b7d5e03cSMatthew Dillon  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14b7d5e03cSMatthew Dillon  * PERFORMANCE OF THIS SOFTWARE.
15b7d5e03cSMatthew Dillon  */
16b7d5e03cSMatthew Dillon #include "opt_ah.h"
17b7d5e03cSMatthew Dillon 
18*a20e5e51SMatthew Dillon //#ifdef AH_SUPPORT_AR9300
19b7d5e03cSMatthew Dillon 
20b7d5e03cSMatthew Dillon #include "ah.h"
21b7d5e03cSMatthew Dillon #include "ah_desc.h"
22b7d5e03cSMatthew Dillon #include "ah_internal.h"
23b7d5e03cSMatthew Dillon 
24*a20e5e51SMatthew Dillon #include "ar9300_freebsd_inc.h"
25*a20e5e51SMatthew Dillon 
26b7d5e03cSMatthew Dillon #include "ar9300/ar9300phy.h"
27b7d5e03cSMatthew Dillon #include "ar9300/ar9300.h"
28b7d5e03cSMatthew Dillon #include "ar9300/ar9300reg.h"
29b7d5e03cSMatthew Dillon #include "ar9300/ar9300desc.h"
30b7d5e03cSMatthew Dillon 
31b7d5e03cSMatthew Dillon #if ATH_SUPPORT_SPECTRAL
32b7d5e03cSMatthew Dillon 
33b7d5e03cSMatthew Dillon /*
34b7d5e03cSMatthew Dillon  * Default 9300 spectral scan parameters
35b7d5e03cSMatthew Dillon  */
36b7d5e03cSMatthew Dillon #define AR9300_SPECTRAL_SCAN_ENA                0
37b7d5e03cSMatthew Dillon #define AR9300_SPECTRAL_SCAN_ACTIVE             0
38b7d5e03cSMatthew Dillon #define AR9300_SPECTRAL_SCAN_FFT_PERIOD         8
39b7d5e03cSMatthew Dillon #define AR9300_SPECTRAL_SCAN_PERIOD             1
40b7d5e03cSMatthew Dillon #define AR9300_SPECTRAL_SCAN_COUNT              16 /* used to be 128 */
41b7d5e03cSMatthew Dillon #define AR9300_SPECTRAL_SCAN_SHORT_REPEAT       1
42b7d5e03cSMatthew Dillon 
43b7d5e03cSMatthew Dillon /* constants */
44b7d5e03cSMatthew Dillon #define MAX_RADAR_DC_PWR_THRESH 127
45b7d5e03cSMatthew Dillon #define MAX_RADAR_RSSI_THRESH 0x3f
46b7d5e03cSMatthew Dillon #define MAX_RADAR_HEIGHT 0x3f
47b7d5e03cSMatthew Dillon #define MAX_CCA_THRESH 127
48b7d5e03cSMatthew Dillon #define ENABLE_ALL_PHYERR 0xffffffff
49b7d5e03cSMatthew Dillon 
50b7d5e03cSMatthew Dillon void ar9300_disable_cck(struct ath_hal *ah);
51b7d5e03cSMatthew Dillon void ar9300_disable_radar(struct ath_hal *ah);
52b7d5e03cSMatthew Dillon void ar9300_disable_restart(struct ath_hal *ah);
53b7d5e03cSMatthew Dillon void ar9300_set_radar_dc_thresh(struct ath_hal *ah);
54b7d5e03cSMatthew Dillon void ar9300_disable_weak_signal(struct ath_hal *ah);
55b7d5e03cSMatthew Dillon void ar9300_disable_strong_signal(struct ath_hal *ah);
56b7d5e03cSMatthew Dillon void ar9300_prep_spectral_scan(struct ath_hal *ah);
57b7d5e03cSMatthew Dillon void ar9300_disable_dc_offset(struct ath_hal *ah);
58b7d5e03cSMatthew Dillon void ar9300_enable_cck_detect(struct ath_hal *ah);
59b7d5e03cSMatthew Dillon 
60b7d5e03cSMatthew Dillon void
ar9300_disable_cck(struct ath_hal * ah)61b7d5e03cSMatthew Dillon ar9300_disable_cck(struct ath_hal *ah)
62b7d5e03cSMatthew Dillon {
63b7d5e03cSMatthew Dillon     u_int32_t val;
64b7d5e03cSMatthew Dillon 
65b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_MODE);
66b7d5e03cSMatthew Dillon     val &= ~(AR_PHY_MODE_DYN_CCK_DISABLE);
67b7d5e03cSMatthew Dillon 
68b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_MODE, val);
69b7d5e03cSMatthew Dillon }
70b7d5e03cSMatthew Dillon 
71b7d5e03cSMatthew Dillon void
ar9300_disable_radar(struct ath_hal * ah)72b7d5e03cSMatthew Dillon ar9300_disable_radar(struct ath_hal *ah)
73b7d5e03cSMatthew Dillon {
74b7d5e03cSMatthew Dillon     u_int32_t val;
75b7d5e03cSMatthew Dillon 
76b7d5e03cSMatthew Dillon     /* Enable radar FFT */
77b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_RADAR_0);
78b7d5e03cSMatthew Dillon     val |= AR_PHY_RADAR_0_FFT_ENA;
79b7d5e03cSMatthew Dillon 
80b7d5e03cSMatthew Dillon     /* set radar detect thresholds to max to effectively disable radar */
81b7d5e03cSMatthew Dillon     val &= ~AR_PHY_RADAR_0_RRSSI;
82b7d5e03cSMatthew Dillon     val |= SM(MAX_RADAR_RSSI_THRESH, AR_PHY_RADAR_0_RRSSI);
83b7d5e03cSMatthew Dillon 
84b7d5e03cSMatthew Dillon     val &= ~AR_PHY_RADAR_0_HEIGHT;
85b7d5e03cSMatthew Dillon     val |= SM(MAX_RADAR_HEIGHT, AR_PHY_RADAR_0_HEIGHT);
86b7d5e03cSMatthew Dillon 
87b7d5e03cSMatthew Dillon     val &= ~(AR_PHY_RADAR_0_ENA);
88b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
89b7d5e03cSMatthew Dillon 
90b7d5e03cSMatthew Dillon     /* disable extension radar detect */
91b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
92b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA);
93b7d5e03cSMatthew Dillon 
94b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_RX_FILTER);
95b7d5e03cSMatthew Dillon     val |= (1 << 13);
96b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_RX_FILTER, val);
97b7d5e03cSMatthew Dillon }
98b7d5e03cSMatthew Dillon 
ar9300_disable_restart(struct ath_hal * ah)99b7d5e03cSMatthew Dillon void ar9300_disable_restart(struct ath_hal *ah)
100b7d5e03cSMatthew Dillon {
101b7d5e03cSMatthew Dillon     u_int32_t val;
102b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_RESTART);
103b7d5e03cSMatthew Dillon     val &= ~AR_PHY_RESTART_ENA;
104b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_RESTART, val);
105b7d5e03cSMatthew Dillon 
106b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_RESTART);
107b7d5e03cSMatthew Dillon }
108b7d5e03cSMatthew Dillon 
ar9300_set_radar_dc_thresh(struct ath_hal * ah)109b7d5e03cSMatthew Dillon void ar9300_set_radar_dc_thresh(struct ath_hal *ah)
110b7d5e03cSMatthew Dillon {
111b7d5e03cSMatthew Dillon     u_int32_t val;
112b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
113b7d5e03cSMatthew Dillon     val &= ~AR_PHY_RADAR_DC_PWR_THRESH;
114b7d5e03cSMatthew Dillon     val |= SM(MAX_RADAR_DC_PWR_THRESH, AR_PHY_RADAR_DC_PWR_THRESH);
115b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val);
116b7d5e03cSMatthew Dillon 
117b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
118b7d5e03cSMatthew Dillon }
119b7d5e03cSMatthew Dillon 
120b7d5e03cSMatthew Dillon void
ar9300_disable_weak_signal(struct ath_hal * ah)121b7d5e03cSMatthew Dillon ar9300_disable_weak_signal(struct ath_hal *ah)
122b7d5e03cSMatthew Dillon {
123b7d5e03cSMatthew Dillon     /* set firpwr to max (signed) */
124b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR, 0x7f);
125b7d5e03cSMatthew Dillon     OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR_SIGN_BIT);
126b7d5e03cSMatthew Dillon 
127b7d5e03cSMatthew Dillon     /* set firstep to max */
128b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRSTEP, 0x3f);
129b7d5e03cSMatthew Dillon 
130b7d5e03cSMatthew Dillon     /* set relpwr to max (signed) */
131b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELPWR, 0x1f);
132b7d5e03cSMatthew Dillon     OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELPWR_SIGN_BIT);
133b7d5e03cSMatthew Dillon 
134b7d5e03cSMatthew Dillon     /* set relstep to max (signed) */
135b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELSTEP, 0x1f);
136b7d5e03cSMatthew Dillon     OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELSTEP_SIGN_BIT);
137b7d5e03cSMatthew Dillon 
138b7d5e03cSMatthew Dillon     /* set firpwr_low to max (signed) */
139b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRPWR, 0x7f);
140b7d5e03cSMatthew Dillon     OS_REG_CLR_BIT(
141b7d5e03cSMatthew Dillon         ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRPWR_SIGN_BIT);
142b7d5e03cSMatthew Dillon 
143b7d5e03cSMatthew Dillon     /* set firstep_low to max */
144b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(
145b7d5e03cSMatthew Dillon         ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, 0x3f);
146b7d5e03cSMatthew Dillon 
147b7d5e03cSMatthew Dillon     /* set relstep_low to max (signed) */
148b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(
149b7d5e03cSMatthew Dillon         ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_RELSTEP, 0x1f);
150b7d5e03cSMatthew Dillon     OS_REG_CLR_BIT(
151b7d5e03cSMatthew Dillon         ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_RELSTEP_SIGN_BIT);
152b7d5e03cSMatthew Dillon }
153b7d5e03cSMatthew Dillon 
154b7d5e03cSMatthew Dillon void
ar9300_disable_strong_signal(struct ath_hal * ah)155b7d5e03cSMatthew Dillon ar9300_disable_strong_signal(struct ath_hal *ah)
156b7d5e03cSMatthew Dillon {
157b7d5e03cSMatthew Dillon     u_int32_t val;
158b7d5e03cSMatthew Dillon 
159b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_TIMING5);
160b7d5e03cSMatthew Dillon     val |= AR_PHY_TIMING5_RSSI_THR1A_ENA;
161b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_TIMING5, val);
162b7d5e03cSMatthew Dillon 
163b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_RSSI_THR1A, 0x7f);
164b7d5e03cSMatthew Dillon 
165b7d5e03cSMatthew Dillon }
166b7d5e03cSMatthew Dillon void
ar9300_set_cca_threshold(struct ath_hal * ah,u_int8_t thresh62)167b7d5e03cSMatthew Dillon ar9300_set_cca_threshold(struct ath_hal *ah, u_int8_t thresh62)
168b7d5e03cSMatthew Dillon {
169b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_CCA_0, AR_PHY_CCA_THRESH62, thresh62);
170b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, thresh62);
171b7d5e03cSMatthew Dillon     /*
172b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah,
173b7d5e03cSMatthew Dillon         AR_PHY_EXTCHN_PWRTHR1, AR_PHY_EXT_CCA0_THRESH62, thresh62);
174b7d5e03cSMatthew Dillon      */
175b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, AR_PHY_EXT_CCA_THRESH62, thresh62);
176b7d5e03cSMatthew Dillon }
177b7d5e03cSMatthew Dillon 
ar9300_classify_strong_bins(struct ath_hal * ah)178b7d5e03cSMatthew Dillon static void ar9300_classify_strong_bins(struct ath_hal *ah)
179b7d5e03cSMatthew Dillon {
180b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH, 0x1);
181b7d5e03cSMatthew Dillon }
182b7d5e03cSMatthew Dillon 
ar9300_disable_dc_offset(struct ath_hal * ah)183b7d5e03cSMatthew Dillon void ar9300_disable_dc_offset(struct ath_hal *ah)
184b7d5e03cSMatthew Dillon {
185b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET, 0);
186b7d5e03cSMatthew Dillon }
187b7d5e03cSMatthew Dillon 
ar9300_enable_cck_detect(struct ath_hal * ah)188b7d5e03cSMatthew Dillon void ar9300_enable_cck_detect(struct ath_hal *ah)
189b7d5e03cSMatthew Dillon {
190b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK, 0);
191b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DYNAMIC, 1);
192b7d5e03cSMatthew Dillon }
193b7d5e03cSMatthew Dillon 
ar9300_prep_spectral_scan(struct ath_hal * ah)194b7d5e03cSMatthew Dillon void ar9300_prep_spectral_scan(struct ath_hal *ah)
195b7d5e03cSMatthew Dillon {
196b7d5e03cSMatthew Dillon     ar9300_disable_radar(ah);
197b7d5e03cSMatthew Dillon     ar9300_classify_strong_bins(ah);
198b7d5e03cSMatthew Dillon     ar9300_disable_dc_offset(ah);
199b7d5e03cSMatthew Dillon     if (AH_PRIVATE(ah)->ah_curchan &&
200b7d5e03cSMatthew Dillon         IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan))
201b7d5e03cSMatthew Dillon     { /* fast clock */
202b7d5e03cSMatthew Dillon         ar9300_enable_cck_detect(ah);
203b7d5e03cSMatthew Dillon     }
204b7d5e03cSMatthew Dillon #ifdef DEMO_MODE
205b7d5e03cSMatthew Dillon     ar9300_disable_strong_signal(ah);
206b7d5e03cSMatthew Dillon     ar9300_disable_weak_signal(ah);
207b7d5e03cSMatthew Dillon     ar9300_set_radar_dc_thresh(ah);
208b7d5e03cSMatthew Dillon     ar9300_set_cca_threshold(ah, MAX_CCA_THRESH);
209b7d5e03cSMatthew Dillon     /*ar9300_disable_restart(ah);*/
210b7d5e03cSMatthew Dillon #endif
211b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_ERR, HAL_PHYERR_SPECTRAL);
212b7d5e03cSMatthew Dillon }
213b7d5e03cSMatthew Dillon 
214b7d5e03cSMatthew Dillon 
215b7d5e03cSMatthew Dillon //#define TEST_NOISE_PWR_WITHOUT_EEPROM 1
216b7d5e03cSMatthew Dillon #ifdef TEST_NOISE_PWR_WITHOUT_EEPROM
217b7d5e03cSMatthew Dillon struct nf_cal {
218b7d5e03cSMatthew Dillon     int cal;
219b7d5e03cSMatthew Dillon     int pwr;
220b7d5e03cSMatthew Dillon };
221b7d5e03cSMatthew Dillon struct nf_cal_table_t {
222b7d5e03cSMatthew Dillon     int freq;
223b7d5e03cSMatthew Dillon     struct nf_cal chain[AH_MAX_CHAINS];
224b7d5e03cSMatthew Dillon };
225b7d5e03cSMatthew Dillon 
226b7d5e03cSMatthew Dillon static const struct nf_cal_table_t nf_cal_table[] =
227b7d5e03cSMatthew Dillon {
228b7d5e03cSMatthew Dillon /* ch 1  */ {2412, { {N2DBM(-101, 00),  N2DBM( -94, 25)},
229b7d5e03cSMatthew Dillon                      {N2DBM(-107, 75),  N2DBM( -99, 75)},
230b7d5e03cSMatthew Dillon                    } },
231b7d5e03cSMatthew Dillon /* ch 6  */ {2437, { {N2DBM(-102, 25),  N2DBM( -94, 25)},
232b7d5e03cSMatthew Dillon                      {N2DBM(-106, 00),  N2DBM( -97, 25)},
233b7d5e03cSMatthew Dillon                    } },
234b7d5e03cSMatthew Dillon /* ch 11 */ {2462, { {N2DBM(-101, 50),  N2DBM( -95, 00)},
235b7d5e03cSMatthew Dillon                      {N2DBM(-105, 50),  N2DBM( -98, 00)},
236b7d5e03cSMatthew Dillon                    } },
237b7d5e03cSMatthew Dillon /* ch 36 */ {5180, { {N2DBM(-114, 25),  N2DBM( -95, 00)},
238b7d5e03cSMatthew Dillon                      {N2DBM(-114, 75),  N2DBM( -94, 00)},
239b7d5e03cSMatthew Dillon                    } },
240b7d5e03cSMatthew Dillon /* ch 44 */ {5220, { {N2DBM(-113, 00),  N2DBM( -95, 00)},
241b7d5e03cSMatthew Dillon                      {N2DBM(-115, 00),  N2DBM( -94, 50)},
242b7d5e03cSMatthew Dillon                    } },
243b7d5e03cSMatthew Dillon /* ch 64 */ {5320, { {N2DBM(-113, 00),  N2DBM( -95, 00)}, // not cal'ed
244b7d5e03cSMatthew Dillon                      {N2DBM(-115, 00),  N2DBM( -94, 50)},
245b7d5e03cSMatthew Dillon                    } },
246b7d5e03cSMatthew Dillon /* ch 100*/ {5500, { {N2DBM(-111, 50),  N2DBM( -93, 75)},
247b7d5e03cSMatthew Dillon                      {N2DBM(-112, 00),  N2DBM( -95, 25)},
248b7d5e03cSMatthew Dillon                    } },
249b7d5e03cSMatthew Dillon /* ch 120*/ {5600, { {N2DBM(-111, 50),  N2DBM( -93, 75)},
250b7d5e03cSMatthew Dillon                      {N2DBM(-112, 00),  N2DBM( -95, 25)},
251b7d5e03cSMatthew Dillon                    } },
252b7d5e03cSMatthew Dillon /* ch 140*/ {5700, { {N2DBM(-111, 75),  N2DBM( -95, 00)},
253b7d5e03cSMatthew Dillon                      {N2DBM(-111, 75),  N2DBM( -96, 00)},
254b7d5e03cSMatthew Dillon                    } },
255b7d5e03cSMatthew Dillon /* ch 157*/ {5785, { {N2DBM(-112, 50),  N2DBM( -94, 75)},
256b7d5e03cSMatthew Dillon                      {N2DBM(-111, 75),  N2DBM( -95, 50)},
257b7d5e03cSMatthew Dillon                    } },
258b7d5e03cSMatthew Dillon /* ch 165*/ {5825, { {N2DBM(-111, 50),  N2DBM( -95, 00)},
259b7d5e03cSMatthew Dillon                      {N2DBM(-112, 00),  N2DBM( -95, 00)},
260b7d5e03cSMatthew Dillon                    } },
261b7d5e03cSMatthew Dillon                    {0}
262b7d5e03cSMatthew Dillon };
263b7d5e03cSMatthew Dillon 
264b7d5e03cSMatthew Dillon static int
ar9300_noise_floor_get(struct ath_hal * ah,int freq_mhz,int ch)265b7d5e03cSMatthew Dillon ar9300_noise_floor_get(struct ath_hal *ah, int freq_mhz, int ch)
266b7d5e03cSMatthew Dillon {
267b7d5e03cSMatthew Dillon     int i;
268b7d5e03cSMatthew Dillon     for (i = 0; nf_cal_table[i].freq != 0; i++) {
269b7d5e03cSMatthew Dillon         if (nf_cal_table[i + 0].freq == freq_mhz ||
270b7d5e03cSMatthew Dillon             nf_cal_table[i + 1].freq > freq_mhz ||
271b7d5e03cSMatthew Dillon             nf_cal_table[i + 1].freq == 0) {
272b7d5e03cSMatthew Dillon             return nf_cal_table[i].chain[ch].cal;
273b7d5e03cSMatthew Dillon         }
274b7d5e03cSMatthew Dillon     }
275b7d5e03cSMatthew Dillon 
276b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
277b7d5e03cSMatthew Dillon         "%s: **Warning: device %d.%d: "
278b7d5e03cSMatthew Dillon         "no nf cal offset found for freq %d chain %d\n",
279b7d5e03cSMatthew Dillon         __func__, (AH_PRIVATE(ah))->ah_macVersion,
280b7d5e03cSMatthew Dillon         (AH_PRIVATE(ah))->ah_macRev, freq_mhz, ch);
281b7d5e03cSMatthew Dillon     return 0;
282b7d5e03cSMatthew Dillon }
283b7d5e03cSMatthew Dillon 
284b7d5e03cSMatthew Dillon static int
ar9300_noise_floor_power_get(struct ath_hal * ah,int freq_mhz,int ch)285b7d5e03cSMatthew Dillon ar9300_noise_floor_power_get(struct ath_hal *ah, int freq_mhz, int ch)
286b7d5e03cSMatthew Dillon {
287b7d5e03cSMatthew Dillon     int i;
288b7d5e03cSMatthew Dillon     for (i = 0; nf_cal_table[i].freq != 0; i++) {
289b7d5e03cSMatthew Dillon         if (nf_cal_table[i + 0].freq == freq_mhz ||
290b7d5e03cSMatthew Dillon             nf_cal_table[i + 1].freq > freq_mhz ||
291b7d5e03cSMatthew Dillon             nf_cal_table[i + 1].freq == 0) {
292b7d5e03cSMatthew Dillon             return nf_cal_table[i].chain[ch].pwr;
293b7d5e03cSMatthew Dillon         }
294b7d5e03cSMatthew Dillon     }
295b7d5e03cSMatthew Dillon 
296b7d5e03cSMatthew Dillon     ath_hal_printf(ah,
297b7d5e03cSMatthew Dillon         "%s: **Warning: device %d.%d: "
298b7d5e03cSMatthew Dillon         "no nf pwr offset found for freq %d chain %d\n",
299b7d5e03cSMatthew Dillon         __func__, (AH_PRIVATE(ah))->ah_macVersion,
300b7d5e03cSMatthew Dillon         (AH_PRIVATE(ah))->ah_macRev, freq_mhz, ch);
301b7d5e03cSMatthew Dillon     return 0;
302b7d5e03cSMatthew Dillon }
303b7d5e03cSMatthew Dillon #else
304b7d5e03cSMatthew Dillon #define ar9300_noise_floor_get(_ah,_f,_ich)          ar9300_noise_floor_cal_or_power_get((_ah), (_f), (_ich), 1/*use_cal*/)
305b7d5e03cSMatthew Dillon #define ar9300_noise_floor_power_get(_ah,_f,_ich)    ar9300_noise_floor_cal_or_power_get((_ah), (_f), (_ich), 0/*use_cal*/)
306b7d5e03cSMatthew Dillon #endif
307b7d5e03cSMatthew Dillon 
308b7d5e03cSMatthew Dillon 
309b7d5e03cSMatthew Dillon void
ar9300_configure_spectral_scan(struct ath_hal * ah,HAL_SPECTRAL_PARAM * ss)310b7d5e03cSMatthew Dillon ar9300_configure_spectral_scan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)
311b7d5e03cSMatthew Dillon {
312b7d5e03cSMatthew Dillon     u_int32_t val, i;
313b7d5e03cSMatthew Dillon     struct ath_hal_9300 *ahp = AH9300(ah);
314b7d5e03cSMatthew Dillon     HAL_BOOL asleep = ahp->ah_chip_full_sleep;
315*a20e5e51SMatthew Dillon     int16_t nf_buf[HAL_NUM_NF_READINGS];
316b7d5e03cSMatthew Dillon 
317b7d5e03cSMatthew Dillon     if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
318b7d5e03cSMatthew Dillon         ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);
319b7d5e03cSMatthew Dillon     }
320b7d5e03cSMatthew Dillon 
321b7d5e03cSMatthew Dillon     ar9300_prep_spectral_scan(ah);
322b7d5e03cSMatthew Dillon 
323b7d5e03cSMatthew Dillon     if (ss->ss_spectral_pri) {
324*a20e5e51SMatthew Dillon         for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
325b7d5e03cSMatthew Dillon             nf_buf[i] = NOISE_PWR_DBM_2_INT(ss->ss_nf_cal[i]);
326b7d5e03cSMatthew Dillon         }
327b7d5e03cSMatthew Dillon         ar9300_load_nf(ah, nf_buf);
328b7d5e03cSMatthew Dillon #ifdef DEMO_MODE
329b7d5e03cSMatthew Dillon         ar9300_disable_strong_signal(ah);
330b7d5e03cSMatthew Dillon         ar9300_disable_weak_signal(ah);
331b7d5e03cSMatthew Dillon         ar9300_set_radar_dc_thresh(ah);
332b7d5e03cSMatthew Dillon         ar9300_set_cca_threshold(ah, MAX_CCA_THRESH);
333b7d5e03cSMatthew Dillon         /*ar9300_disable_restart(ah);*/
334b7d5e03cSMatthew Dillon #endif
335b7d5e03cSMatthew Dillon     }
336b7d5e03cSMatthew Dillon 
337b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
338b7d5e03cSMatthew Dillon 
339b7d5e03cSMatthew Dillon     if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) {
340b7d5e03cSMatthew Dillon         val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD;
341b7d5e03cSMatthew Dillon         val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);
342b7d5e03cSMatthew Dillon     }
343b7d5e03cSMatthew Dillon 
344b7d5e03cSMatthew Dillon     if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {
345b7d5e03cSMatthew Dillon         val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;
346b7d5e03cSMatthew Dillon         val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);
347b7d5e03cSMatthew Dillon     }
348b7d5e03cSMatthew Dillon 
349b7d5e03cSMatthew Dillon     if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) {
350b7d5e03cSMatthew Dillon         val &= ~AR_PHY_SPECTRAL_SCAN_COUNT;
351b7d5e03cSMatthew Dillon         /* Remnants of a Merlin bug, 128 translates to 0 for
352b7d5e03cSMatthew Dillon          * continuous scanning. Instead we do piecemeal captures
353b7d5e03cSMatthew Dillon          * of 64 samples for Osprey.
354b7d5e03cSMatthew Dillon          */
355b7d5e03cSMatthew Dillon         if (ss->ss_count == 128) {
356b7d5e03cSMatthew Dillon             val |= SM(0, AR_PHY_SPECTRAL_SCAN_COUNT);
357b7d5e03cSMatthew Dillon         } else {
358b7d5e03cSMatthew Dillon             val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT);
359b7d5e03cSMatthew Dillon         }
360b7d5e03cSMatthew Dillon     }
361b7d5e03cSMatthew Dillon 
362b7d5e03cSMatthew Dillon     if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {
363b7d5e03cSMatthew Dillon         val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;
364b7d5e03cSMatthew Dillon         val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);
365b7d5e03cSMatthew Dillon     }
366b7d5e03cSMatthew Dillon 
367b7d5e03cSMatthew Dillon     if (ss->ss_short_report == AH_TRUE) {
368b7d5e03cSMatthew Dillon         val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
369b7d5e03cSMatthew Dillon     } else {
370b7d5e03cSMatthew Dillon         val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
371b7d5e03cSMatthew Dillon     }
372b7d5e03cSMatthew Dillon 
373b7d5e03cSMatthew Dillon     /* if noise power cal, force high priority */
374b7d5e03cSMatthew Dillon     if (ss->ss_spectral_pri) {
375b7d5e03cSMatthew Dillon         val |= AR_PHY_SPECTRAL_SCAN_PRIORITY_HI;
376b7d5e03cSMatthew Dillon     } else {
377b7d5e03cSMatthew Dillon         val &= ~AR_PHY_SPECTRAL_SCAN_PRIORITY_HI;
378b7d5e03cSMatthew Dillon     }
379b7d5e03cSMatthew Dillon 
380b7d5e03cSMatthew Dillon     /* enable spectral scan */
381b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENABLE);
382b7d5e03cSMatthew Dillon 
383b7d5e03cSMatthew Dillon     if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
384b7d5e03cSMatthew Dillon         ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
385b7d5e03cSMatthew Dillon     }
386b7d5e03cSMatthew Dillon }
387b7d5e03cSMatthew Dillon 
388b7d5e03cSMatthew Dillon /*
389b7d5e03cSMatthew Dillon  * Get the spectral parameter values and return them in the pe
390b7d5e03cSMatthew Dillon  * structure
391b7d5e03cSMatthew Dillon  */
392b7d5e03cSMatthew Dillon 
393b7d5e03cSMatthew Dillon void
ar9300_get_spectral_params(struct ath_hal * ah,HAL_SPECTRAL_PARAM * ss)394b7d5e03cSMatthew Dillon ar9300_get_spectral_params(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)
395b7d5e03cSMatthew Dillon {
396b7d5e03cSMatthew Dillon     u_int32_t val;
397*a20e5e51SMatthew Dillon     HAL_CHANNEL_INTERNAL *chan = NULL;
398*a20e5e51SMatthew Dillon     const struct ieee80211_channel *c;
399b7d5e03cSMatthew Dillon     int i, ichain, rx_chain_status;
400b7d5e03cSMatthew Dillon     struct ath_hal_9300 *ahp = AH9300(ah);
401b7d5e03cSMatthew Dillon     HAL_BOOL asleep = ahp->ah_chip_full_sleep;
402b7d5e03cSMatthew Dillon 
403*a20e5e51SMatthew Dillon     c = AH_PRIVATE(ah)->ah_curchan;
404*a20e5e51SMatthew Dillon     if (c != NULL)
405*a20e5e51SMatthew Dillon         chan = ath_hal_checkchannel(ah, c);
406*a20e5e51SMatthew Dillon 
407*a20e5e51SMatthew Dillon     // XXX TODO: just always wake up all chips?
408b7d5e03cSMatthew Dillon     if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
409b7d5e03cSMatthew Dillon         ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);
410b7d5e03cSMatthew Dillon     }
411b7d5e03cSMatthew Dillon 
412b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
413b7d5e03cSMatthew Dillon 
414b7d5e03cSMatthew Dillon     ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);
415b7d5e03cSMatthew Dillon     ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD);
416b7d5e03cSMatthew Dillon     ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT);
417b7d5e03cSMatthew Dillon     ss->ss_short_report = (val & AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT) ? 1:0;
418b7d5e03cSMatthew Dillon     ss->ss_spectral_pri = ( val & AR_PHY_SPECTRAL_SCAN_PRIORITY_HI) ? 1:0;
419b7d5e03cSMatthew Dillon     OS_MEMZERO(ss->ss_nf_cal, sizeof(ss->ss_nf_cal));
420b7d5e03cSMatthew Dillon     OS_MEMZERO(ss->ss_nf_pwr, sizeof(ss->ss_nf_cal));
421b7d5e03cSMatthew Dillon     ss->ss_nf_temp_data = 0;
422b7d5e03cSMatthew Dillon 
423b7d5e03cSMatthew Dillon     if (chan != NULL) {
424b7d5e03cSMatthew Dillon         rx_chain_status = OS_REG_READ(ah, AR_PHY_RX_CHAINMASK) & 0x7;
425*a20e5e51SMatthew Dillon         for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
426b7d5e03cSMatthew Dillon             ichain = i % 3;
427b7d5e03cSMatthew Dillon             if (rx_chain_status & (1 << ichain)) {
428b7d5e03cSMatthew Dillon                 ss->ss_nf_cal[i] =
429b7d5e03cSMatthew Dillon                     ar9300_noise_floor_get(ah, chan->channel, ichain);
430b7d5e03cSMatthew Dillon                 ss->ss_nf_pwr[i] =
431b7d5e03cSMatthew Dillon                     ar9300_noise_floor_power_get(ah, chan->channel, ichain);
432b7d5e03cSMatthew Dillon             }
433b7d5e03cSMatthew Dillon         }
434b7d5e03cSMatthew Dillon         ss->ss_nf_temp_data = OS_REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, AR_PHY_BB_THERM_ADC_4_LATEST_THERM);
435b7d5e03cSMatthew Dillon     } else {
436b7d5e03cSMatthew Dillon         HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,
437b7d5e03cSMatthew Dillon             "%s: chan is NULL - no ss nf values\n", __func__);
438b7d5e03cSMatthew Dillon     }
439b7d5e03cSMatthew Dillon 
440b7d5e03cSMatthew Dillon     if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
441b7d5e03cSMatthew Dillon         ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
442b7d5e03cSMatthew Dillon     }
443b7d5e03cSMatthew Dillon }
444b7d5e03cSMatthew Dillon 
445b7d5e03cSMatthew Dillon HAL_BOOL
ar9300_is_spectral_active(struct ath_hal * ah)446b7d5e03cSMatthew Dillon ar9300_is_spectral_active(struct ath_hal *ah)
447b7d5e03cSMatthew Dillon {
448b7d5e03cSMatthew Dillon     u_int32_t val;
449b7d5e03cSMatthew Dillon 
450b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
451b7d5e03cSMatthew Dillon     return MS(val, AR_PHY_SPECTRAL_SCAN_ACTIVE);
452b7d5e03cSMatthew Dillon }
453b7d5e03cSMatthew Dillon 
454b7d5e03cSMatthew Dillon HAL_BOOL
ar9300_is_spectral_enabled(struct ath_hal * ah)455b7d5e03cSMatthew Dillon ar9300_is_spectral_enabled(struct ath_hal *ah)
456b7d5e03cSMatthew Dillon {
457b7d5e03cSMatthew Dillon     u_int32_t val;
458b7d5e03cSMatthew Dillon 
459b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
460b7d5e03cSMatthew Dillon     return MS(val, AR_PHY_SPECTRAL_SCAN_ENABLE);
461b7d5e03cSMatthew Dillon }
462b7d5e03cSMatthew Dillon 
ar9300_start_spectral_scan(struct ath_hal * ah)463b7d5e03cSMatthew Dillon void ar9300_start_spectral_scan(struct ath_hal *ah)
464b7d5e03cSMatthew Dillon {
465b7d5e03cSMatthew Dillon     u_int32_t val;
466b7d5e03cSMatthew Dillon     struct ath_hal_9300 *ahp = AH9300(ah);
467b7d5e03cSMatthew Dillon     HAL_BOOL asleep = ahp->ah_chip_full_sleep;
468b7d5e03cSMatthew Dillon 
469b7d5e03cSMatthew Dillon     if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
470b7d5e03cSMatthew Dillon         ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);
471b7d5e03cSMatthew Dillon     }
472b7d5e03cSMatthew Dillon 
473b7d5e03cSMatthew Dillon     ar9300_prep_spectral_scan(ah);
474b7d5e03cSMatthew Dillon 
475b7d5e03cSMatthew Dillon     /* activate spectral scan */
476b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
477b7d5e03cSMatthew Dillon     /* This is a hardware bug fix, the enable and active bits should
478b7d5e03cSMatthew Dillon      * not be set/reset in the same write operation to the register
479b7d5e03cSMatthew Dillon      */
480b7d5e03cSMatthew Dillon     if (!(val & AR_PHY_SPECTRAL_SCAN_ENABLE)) {
481b7d5e03cSMatthew Dillon         val |= AR_PHY_SPECTRAL_SCAN_ENABLE;
482b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
483b7d5e03cSMatthew Dillon         val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
484b7d5e03cSMatthew Dillon     }
485b7d5e03cSMatthew Dillon     val |= AR_PHY_SPECTRAL_SCAN_ACTIVE;
486b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
487b7d5e03cSMatthew Dillon 
488b7d5e03cSMatthew Dillon     /* Reset the PHY_ERR_MASK */
489b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG);
490b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR);
491b7d5e03cSMatthew Dillon 
492b7d5e03cSMatthew Dillon     if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
493b7d5e03cSMatthew Dillon         ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
494b7d5e03cSMatthew Dillon     }
495b7d5e03cSMatthew Dillon }
496b7d5e03cSMatthew Dillon 
ar9300_stop_spectral_scan(struct ath_hal * ah)497b7d5e03cSMatthew Dillon void ar9300_stop_spectral_scan(struct ath_hal *ah)
498b7d5e03cSMatthew Dillon {
499b7d5e03cSMatthew Dillon     u_int32_t val;
500b7d5e03cSMatthew Dillon     struct ath_hal_9300 *ahp = AH9300(ah);
501b7d5e03cSMatthew Dillon     HAL_BOOL asleep = ahp->ah_chip_full_sleep;
502b7d5e03cSMatthew Dillon 
503b7d5e03cSMatthew Dillon     if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
504b7d5e03cSMatthew Dillon         ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);
505b7d5e03cSMatthew Dillon     }
506b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
507b7d5e03cSMatthew Dillon 
508b7d5e03cSMatthew Dillon     /* deactivate spectral scan */
509b7d5e03cSMatthew Dillon     /* HW Bug fix -- Do not disable the spectral scan
510b7d5e03cSMatthew Dillon      * only turn off the active bit
511b7d5e03cSMatthew Dillon      */
512b7d5e03cSMatthew Dillon     //val &= ~AR_PHY_SPECTRAL_SCAN_ENABLE;
513b7d5e03cSMatthew Dillon     val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE;
514b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
515b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
516b7d5e03cSMatthew Dillon 
517b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH,
518b7d5e03cSMatthew Dillon                      ahp->ah_radar1);
519b7d5e03cSMatthew Dillon     OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET,
520b7d5e03cSMatthew Dillon                      ahp->ah_dc_offset);
521b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_ERR, 0);
522b7d5e03cSMatthew Dillon 
523b7d5e03cSMatthew Dillon     if (AH_PRIVATE(ah)->ah_curchan &&
524b7d5e03cSMatthew Dillon         IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan))
525b7d5e03cSMatthew Dillon     { /* fast clock */
526b7d5e03cSMatthew Dillon         OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK,
527b7d5e03cSMatthew Dillon                          ahp->ah_disable_cck);
528b7d5e03cSMatthew Dillon     }
529b7d5e03cSMatthew Dillon 
530b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_ERR);
531b7d5e03cSMatthew Dillon 
532b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR);
533b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val);
534b7d5e03cSMatthew Dillon 
535b7d5e03cSMatthew Dillon     if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
536b7d5e03cSMatthew Dillon         ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
537b7d5e03cSMatthew Dillon     }
538b7d5e03cSMatthew Dillon }
539b7d5e03cSMatthew Dillon 
ar9300_get_spectral_config(struct ath_hal * ah)540b7d5e03cSMatthew Dillon u_int32_t ar9300_get_spectral_config(struct ath_hal *ah)
541b7d5e03cSMatthew Dillon {
542b7d5e03cSMatthew Dillon     u_int32_t val;
543b7d5e03cSMatthew Dillon     struct ath_hal_9300 *ahp = AH9300(ah);
544b7d5e03cSMatthew Dillon     HAL_BOOL asleep = ahp->ah_chip_full_sleep;
545b7d5e03cSMatthew Dillon 
546b7d5e03cSMatthew Dillon     if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
547b7d5e03cSMatthew Dillon         ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE);
548b7d5e03cSMatthew Dillon     }
549b7d5e03cSMatthew Dillon 
550b7d5e03cSMatthew Dillon     val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
551b7d5e03cSMatthew Dillon 
552b7d5e03cSMatthew Dillon     if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) {
553b7d5e03cSMatthew Dillon         ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
554b7d5e03cSMatthew Dillon     }
555b7d5e03cSMatthew Dillon     return val;
556b7d5e03cSMatthew Dillon }
557b7d5e03cSMatthew Dillon 
ar9300_get_ctl_chan_nf(struct ath_hal * ah)558b7d5e03cSMatthew Dillon int16_t ar9300_get_ctl_chan_nf(struct ath_hal *ah)
559b7d5e03cSMatthew Dillon {
560b7d5e03cSMatthew Dillon     int16_t nf;
561*a20e5e51SMatthew Dillon #if 0
562b7d5e03cSMatthew Dillon     struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
563*a20e5e51SMatthew Dillon #endif
564b7d5e03cSMatthew Dillon 
565b7d5e03cSMatthew Dillon     if ( (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) {
566b7d5e03cSMatthew Dillon         /* Noise floor calibration value is ready */
567b7d5e03cSMatthew Dillon         nf = MS(OS_REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
568b7d5e03cSMatthew Dillon     } else {
569b7d5e03cSMatthew Dillon         /* NF calibration is not done, return nominal value */
570*a20e5e51SMatthew Dillon         nf = AH9300(ah)->nfp->nominal;
571b7d5e03cSMatthew Dillon     }
572b7d5e03cSMatthew Dillon     if (nf & 0x100) {
573b7d5e03cSMatthew Dillon         nf = (0 - ((nf ^ 0x1ff) + 1));
574b7d5e03cSMatthew Dillon     }
575b7d5e03cSMatthew Dillon     return nf;
576b7d5e03cSMatthew Dillon }
577b7d5e03cSMatthew Dillon 
ar9300_get_ext_chan_nf(struct ath_hal * ah)578b7d5e03cSMatthew Dillon int16_t ar9300_get_ext_chan_nf(struct ath_hal *ah)
579b7d5e03cSMatthew Dillon {
580b7d5e03cSMatthew Dillon     int16_t nf;
581*a20e5e51SMatthew Dillon #if 0
582b7d5e03cSMatthew Dillon     struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
583*a20e5e51SMatthew Dillon #endif
584b7d5e03cSMatthew Dillon 
585b7d5e03cSMatthew Dillon     if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) {
586b7d5e03cSMatthew Dillon         /* Noise floor calibration value is ready */
587b7d5e03cSMatthew Dillon         nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
588b7d5e03cSMatthew Dillon     } else {
589b7d5e03cSMatthew Dillon         /* NF calibration is not done, return nominal value */
590*a20e5e51SMatthew Dillon         nf = AH9300(ah)->nfp->nominal;
591b7d5e03cSMatthew Dillon     }
592b7d5e03cSMatthew Dillon     if (nf & 0x100) {
593b7d5e03cSMatthew Dillon         nf = (0 - ((nf ^ 0x1ff) + 1));
594b7d5e03cSMatthew Dillon     }
595b7d5e03cSMatthew Dillon     return nf;
596b7d5e03cSMatthew Dillon }
597b7d5e03cSMatthew Dillon 
598b7d5e03cSMatthew Dillon #endif /* ATH_SUPPORT_SPECTRAL */
599*a20e5e51SMatthew Dillon //#endif
600b7d5e03cSMatthew Dillon 
601