1 /*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
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 WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
17
18
19 #include "opt_ah.h"
20
21 #include "ah.h"
22 #include "ah_internal.h"
23 #include "ah_devid.h"
24 #include "ah_desc.h"
25
26 #include "ar9300.h"
27 #include "ar9300reg.h"
28 #include "ar9300phy.h"
29 #include "ar9300desc.h"
30
31 #define FIX_NOISE_FLOOR 1
32
33
34 /* Additional Time delay to wait after activiting the Base band */
35 #define BASE_ACTIVATE_DELAY 100 /* usec */
36 #define RTC_PLL_SETTLE_DELAY 100 /* usec */
37 #define COEF_SCALE_S 24
38 #define HT40_CHANNEL_CENTER_SHIFT 10 /* MHz */
39
40 #define DELPT 32
41
42 /* XXX Duplicates! (in ar9300desc.h) */
43 #if 0
44 extern HAL_BOOL ar9300_reset_tx_queue(struct ath_hal *ah, u_int q);
45 extern u_int32_t ar9300_num_tx_pending(struct ath_hal *ah, u_int q);
46 #endif
47
48
49 #define MAX_MEASUREMENT 8
50 #define MAXIQCAL 3
51 struct coeff_t {
52 int32_t mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
53 int32_t phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
54 int32_t iqc_coeff[2];
55 int last_nmeasurement;
56 HAL_BOOL last_cal;
57 };
58
59 static HAL_BOOL ar9300_tx_iq_cal_hw_run(struct ath_hal *ah);
60 static void ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
61 int iqcal_idx, int max_iqcal, HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr);
62 static void ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
63 u_int32_t num_chains, struct coeff_t *coeff, HAL_BOOL is_cal_reusable);
64 #if ATH_SUPPORT_CAL_REUSE
65 static void ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan);
66 #endif
67
68
69 static inline void ar9300_prog_ini(struct ath_hal *ah, struct ar9300_ini_array *ini_arr, int column);
70 static inline void ar9300_set_rf_mode(struct ath_hal *ah, struct ieee80211_channel *chan);
71 static inline HAL_BOOL ar9300_init_cal(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL skip_if_none, HAL_BOOL apply_last_corr);
72 static inline void ar9300_init_user_settings(struct ath_hal *ah);
73
74 #ifdef HOST_OFFLOAD
75 /*
76 * For usb offload solution, some USB registers must be tuned
77 * to gain better stability/performance but these registers
78 * might be changed while doing wlan reset so do this here
79 */
80 #define WAR_USB_DISABLE_PLL_LOCK_DETECT(__ah) \
81 do { \
82 if (AR_SREV_HORNET(__ah) || AR_SREV_WASP(__ah)) { \
83 volatile u_int32_t *usb_ctrl_r1 = (u_int32_t *) 0xb8116c84; \
84 volatile u_int32_t *usb_ctrl_r2 = (u_int32_t *) 0xb8116c88; \
85 *usb_ctrl_r1 = (*usb_ctrl_r1 & 0xffefffff); \
86 *usb_ctrl_r2 = (*usb_ctrl_r2 & 0xfc1fffff) | (1 << 21) | (3 << 22); \
87 } \
88 } while (0)
89 #else
90 #define WAR_USB_DISABLE_PLL_LOCK_DETECT(__ah)
91 #endif
92
93 /*
94 * Note: the below is the version that ships with ath9k.
95 * The original HAL version is above.
96 */
97
98 static void
ar9300_disable_pll_lock_detect(struct ath_hal * ah)99 ar9300_disable_pll_lock_detect(struct ath_hal *ah)
100 {
101 /*
102 * On AR9330 and AR9340 devices, some PHY registers must be
103 * tuned to gain better stability/performance. These registers
104 * might be changed while doing wlan reset so the registers must
105 * be reprogrammed after each reset.
106 */
107 if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah)) {
108 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: called\n", __func__);
109 OS_REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, (1 << 20));
110 OS_REG_RMW(ah, AR_PHY_USB_CTRL2,
111 (1 << 21) | (0xf << 22),
112 (1 << 21) | (0x3 << 22));
113 }
114 }
115
116 static inline void
ar9300_attach_hw_platform(struct ath_hal * ah)117 ar9300_attach_hw_platform(struct ath_hal *ah)
118 {
119 struct ath_hal_9300 *ahp = AH9300(ah);
120
121 ahp->ah_hwp = HAL_TRUE_CHIP;
122 return;
123 }
124
125 /* Adjust various register settings based on half/quarter rate clock setting.
126 * This includes: +USEC, TX/RX latency,
127 * + IFS params: slot, eifs, misc etc.
128 * SIFS stays the same.
129 */
130 static void
ar9300_set_ifs_timing(struct ath_hal * ah,struct ieee80211_channel * chan)131 ar9300_set_ifs_timing(struct ath_hal *ah, struct ieee80211_channel *chan)
132 {
133 u_int32_t tx_lat, rx_lat, usec, slot, regval, eifs;
134
135 regval = OS_REG_READ(ah, AR_USEC);
136 regval &= ~(AR_USEC_RX_LATENCY | AR_USEC_TX_LATENCY | AR_USEC_USEC);
137 if (IEEE80211_IS_CHAN_HALF(chan)) { /* half rates */
138 slot = ar9300_mac_to_clks(ah, AR_SLOT_HALF);
139 eifs = ar9300_mac_to_clks(ah, AR_EIFS_HALF);
140 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { /* fast clock */
141 rx_lat = SM(AR_RX_LATENCY_HALF_FAST_CLOCK, AR_USEC_RX_LATENCY);
142 tx_lat = SM(AR_TX_LATENCY_HALF_FAST_CLOCK, AR_USEC_TX_LATENCY);
143 usec = SM(AR_USEC_HALF_FAST_CLOCK, AR_USEC_USEC);
144 } else {
145 rx_lat = SM(AR_RX_LATENCY_HALF, AR_USEC_RX_LATENCY);
146 tx_lat = SM(AR_TX_LATENCY_HALF, AR_USEC_TX_LATENCY);
147 usec = SM(AR_USEC_HALF, AR_USEC_USEC);
148 }
149 } else { /* quarter rate */
150 slot = ar9300_mac_to_clks(ah, AR_SLOT_QUARTER);
151 eifs = ar9300_mac_to_clks(ah, AR_EIFS_QUARTER);
152 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { /* fast clock */
153 rx_lat = SM(AR_RX_LATENCY_QUARTER_FAST_CLOCK, AR_USEC_RX_LATENCY);
154 tx_lat = SM(AR_TX_LATENCY_QUARTER_FAST_CLOCK, AR_USEC_TX_LATENCY);
155 usec = SM(AR_USEC_QUARTER_FAST_CLOCK, AR_USEC_USEC);
156 } else {
157 rx_lat = SM(AR_RX_LATENCY_QUARTER, AR_USEC_RX_LATENCY);
158 tx_lat = SM(AR_TX_LATENCY_QUARTER, AR_USEC_TX_LATENCY);
159 usec = SM(AR_USEC_QUARTER, AR_USEC_USEC);
160 }
161 }
162
163 OS_REG_WRITE(ah, AR_USEC, (usec | regval | tx_lat | rx_lat));
164 OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot);
165 OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);
166 }
167
168
169 /*
170 * This inline function configures the chip either
171 * to encrypt/decrypt management frames or pass thru
172 */
173 static inline void
ar9300_init_mfp(struct ath_hal * ah)174 ar9300_init_mfp(struct ath_hal * ah)
175 {
176 u_int32_t mfpcap, mfp_qos;
177
178 ath_hal_getcapability(ah, HAL_CAP_MFP, 0, &mfpcap);
179
180 if (mfpcap == HAL_MFP_QOSDATA) {
181 /* Treat like legacy hardware. Do not touch the MFP registers. */
182 HALDEBUG(ah, HAL_DEBUG_RESET, "%s forced to use QOSDATA\n", __func__);
183 return;
184 }
185
186 /* MFP support (Sowl 1.0 or greater) */
187 if (mfpcap == HAL_MFP_HW_CRYPTO) {
188 /* configure hardware MFP support */
189 HALDEBUG(ah, HAL_DEBUG_RESET, "%s using HW crypto\n", __func__);
190 OS_REG_RMW_FIELD(ah,
191 AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT, AR_AES_MUTE_MASK1_FC_MGMT_MFP);
192 OS_REG_RMW(ah,
193 AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE,
194 AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
195 /*
196 * Mask used to construct AAD for CCMP-AES
197 * Cisco spec defined bits 0-3 as mask
198 * IEEE802.11w defined as bit 4.
199 */
200 if (ath_hal_get_mfp_qos(ah)) {
201 mfp_qos = AR_MFP_QOS_MASK_IEEE;
202 } else {
203 mfp_qos = AR_MFP_QOS_MASK_CISCO;
204 }
205 OS_REG_RMW_FIELD(ah,
206 AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_MGMT_QOS, mfp_qos);
207 } else if (mfpcap == HAL_MFP_PASSTHRU) {
208 /* Disable en/decrypt by hardware */
209 HALDEBUG(ah, HAL_DEBUG_RESET, "%s using passthru\n", __func__);
210 OS_REG_RMW(ah,
211 AR_PCU_MISC_MODE2,
212 AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT,
213 AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
214 }
215 }
216
217 void
ar9300_get_channel_centers(struct ath_hal * ah,const struct ieee80211_channel * chan,CHAN_CENTERS * centers)218 ar9300_get_channel_centers(struct ath_hal *ah, const struct ieee80211_channel *chan,
219 CHAN_CENTERS *centers)
220 {
221 int8_t extoff;
222 struct ath_hal_9300 *ahp = AH9300(ah);
223 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
224
225 if (!IEEE80211_IS_CHAN_HT40(chan)) {
226 centers->ctl_center = centers->ext_center =
227 centers->synth_center = ichan->channel;
228 return;
229 }
230
231 HALASSERT(IEEE80211_IS_CHAN_HT40(chan));
232
233 /*
234 * In 20/40 phy mode, the center frequency is
235 * "between" the primary and extension channels.
236 */
237 if (IEEE80211_IS_CHAN_HT40U(chan)) {
238 centers->synth_center = ichan->channel + HT40_CHANNEL_CENTER_SHIFT;
239 extoff = 1;
240 } else {
241 centers->synth_center = ichan->channel - HT40_CHANNEL_CENTER_SHIFT;
242 extoff = -1;
243 }
244
245 centers->ctl_center =
246 centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
247 centers->ext_center =
248 centers->synth_center +
249 (extoff * ((ahp->ah_ext_prot_spacing == HAL_HT_EXTPROTSPACING_20) ?
250 HT40_CHANNEL_CENTER_SHIFT : 15));
251 }
252
253 /*
254 * Read the noise-floor values from the HW.
255 * Specifically, read the minimum clear-channel assessment value for
256 * each chain, for both the control and extension channels.
257 * (The received power level during clear-channel periods is the
258 * noise floor.)
259 * These noise floor values computed by the HW will be stored in the
260 * NF history buffer.
261 * The HW sometimes produces bogus NF values. To avoid using these
262 * bogus values, the NF data is (a) range-limited, and (b) filtered.
263 * However, this data-processing is done when reading the NF values
264 * out of the history buffer. The history buffer stores the raw values.
265 * This allows the NF history buffer to be used to check for interference.
266 * A single high NF reading might be a bogus HW value, but if the NF
267 * readings are consistently high, it must be due to interference.
268 * This is the purpose of storing raw NF values in the history buffer,
269 * rather than processed values. By looking at a history of NF values
270 * that have not been range-limited, we can check if they are consistently
271 * high (due to interference).
272 */
273 #define AH_NF_SIGN_EXTEND(nf) \
274 ((nf) & 0x100) ? \
275 0 - (((nf) ^ 0x1ff) + 1) : \
276 (nf)
277 void
ar9300_upload_noise_floor(struct ath_hal * ah,int is_2g,int16_t nfarray[HAL_NUM_NF_READINGS])278 ar9300_upload_noise_floor(struct ath_hal *ah, int is_2g,
279 int16_t nfarray[HAL_NUM_NF_READINGS])
280 {
281 int16_t nf;
282 int chan, chain;
283 u_int32_t regs[HAL_NUM_NF_READINGS] = {
284 /* control channel */
285 AR_PHY_CCA_0, /* chain 0 */
286 AR_PHY_CCA_1, /* chain 1 */
287 AR_PHY_CCA_2, /* chain 2 */
288 /* extension channel */
289 AR_PHY_EXT_CCA, /* chain 0 */
290 AR_PHY_EXT_CCA_1, /* chain 1 */
291 AR_PHY_EXT_CCA_2, /* chain 2 */
292 };
293 u_int8_t chainmask;
294
295 /*
296 * Within a given channel (ctl vs. ext), the CH0, CH1, and CH2
297 * masks and shifts are the same, though they differ for the
298 * control vs. extension channels.
299 */
300 u_int32_t masks[2] = {
301 AR_PHY_MINCCA_PWR, /* control channel */
302 AR_PHY_EXT_MINCCA_PWR, /* extention channel */
303 };
304 u_int8_t shifts[2] = {
305 AR_PHY_MINCCA_PWR_S, /* control channel */
306 AR_PHY_EXT_MINCCA_PWR_S, /* extention channel */
307 };
308
309 /*
310 * Force NF calibration for all chains.
311 */
312 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
313 chainmask = 0x01;
314 } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_HONEYBEE(ah)) {
315 chainmask = 0x03;
316 } else {
317 chainmask = 0x07;
318 }
319
320 for (chan = 0; chan < 2 /*ctl,ext*/; chan++) {
321 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
322 int i;
323
324 if (!((chainmask >> chain) & 0x1)) {
325 continue;
326 }
327 i = chan * AR9300_MAX_CHAINS + chain;
328 nf = (OS_REG_READ(ah, regs[i]) & masks[chan]) >> shifts[chan];
329 nfarray[i] = AH_NF_SIGN_EXTEND(nf);
330 }
331 }
332 }
333
334 /* ar9300_get_min_cca_pwr -
335 * Used by the scan function for a quick read of the noise floor.
336 * This is used to detect presence of CW interference such as video bridge.
337 * The noise floor is assumed to have been already started during reset
338 * called during channel change. The function checks if the noise floor
339 * reading is done. In case it has been done, it reads the noise floor value.
340 * If the noise floor calibration has not been finished, it assumes this is
341 * due to presence of CW interference an returns a high value for noise floor,
342 * derived from the CW interference threshold + margin fudge factor.
343 */
344 #define BAD_SCAN_NF_MARGIN (30)
ar9300_get_min_cca_pwr(struct ath_hal * ah)345 int16_t ar9300_get_min_cca_pwr(struct ath_hal *ah)
346 {
347 int16_t nf;
348 // struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
349
350
351 if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) {
352 nf = MS(OS_REG_READ(ah, AR_PHY_CCA_0), AR9280_PHY_MINCCA_PWR);
353 if (nf & 0x100) {
354 nf = 0 - ((nf ^ 0x1ff) + 1);
355 }
356 } else {
357 /* NF calibration is not done, assume CW interference */
358 nf = AH9300(ah)->nfp->nominal + AH9300(ah)->nf_cw_int_delta +
359 BAD_SCAN_NF_MARGIN;
360 }
361 return nf;
362 }
363
364
365 /*
366 * Noise Floor values for all chains.
367 * Most recently updated values from the NF history buffer are used.
368 */
ar9300_chain_noise_floor(struct ath_hal * ah,int16_t * nf_buf,struct ieee80211_channel * chan,int is_scan)369 void ar9300_chain_noise_floor(struct ath_hal *ah, int16_t *nf_buf,
370 struct ieee80211_channel *chan, int is_scan)
371 {
372 struct ath_hal_9300 *ahp = AH9300(ah);
373 int i, nf_hist_len, recent_nf_index = 0;
374 HAL_NFCAL_HIST_FULL *h;
375 u_int8_t rx_chainmask = ahp->ah_rx_chainmask | (ahp->ah_rx_chainmask << 3);
376 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
377 HALASSERT(ichan);
378
379 #ifdef ATH_NF_PER_CHAN
380 /* Fill 0 if valid internal channel is not found */
381 if (ichan == AH_NULL) {
382 OS_MEMZERO(nf_buf, sizeof(nf_buf[0])*HAL_NUM_NF_READINGS);
383 return;
384 }
385 h = &ichan->nf_cal_hist;
386 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
387 #else
388 /*
389 * If a scan is not in progress, then the most recent value goes
390 * into ahpriv->nf_cal_hist. If a scan is in progress, then
391 * the most recent value goes into ichan->nf_cal_hist.
392 * Thus, return the value from ahpriv->nf_cal_hist if there's
393 * no scan, and if the specified channel is the current channel.
394 * Otherwise, return the noise floor from ichan->nf_cal_hist.
395 */
396 if ((!is_scan) && chan == AH_PRIVATE(ah)->ah_curchan) {
397 h = &AH_PRIVATE(ah)->nf_cal_hist;
398 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
399 } else {
400 /* Fill 0 if valid internal channel is not found */
401 if (ichan == AH_NULL) {
402 OS_MEMZERO(nf_buf, sizeof(nf_buf[0])*HAL_NUM_NF_READINGS);
403 return;
404 }
405 /*
406 * It is okay to treat a HAL_NFCAL_HIST_SMALL struct as if it were a
407 * HAL_NFCAL_HIST_FULL struct, as long as only the index 0 of the
408 * nf_cal_buffer is used (nf_cal_buffer[0][0:HAL_NUM_NF_READINGS-1])
409 */
410 h = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
411 nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
412 }
413 #endif
414 /* Get most recently updated values from nf cal history buffer */
415 recent_nf_index =
416 (h->base.curr_index) ? h->base.curr_index - 1 : nf_hist_len - 1;
417
418 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
419 /* Fill 0 for unsupported chains */
420 if (!(rx_chainmask & (1 << i))) {
421 nf_buf[i] = 0;
422 continue;
423 }
424 nf_buf[i] = h->nf_cal_buffer[recent_nf_index][i];
425 }
426 }
427
428 /*
429 * Return the current NF value in register.
430 * If the current NF cal is not completed, return 0.
431 */
ar9300_get_nf_from_reg(struct ath_hal * ah,struct ieee80211_channel * chan,int wait_time)432 int16_t ar9300_get_nf_from_reg(struct ath_hal *ah, struct ieee80211_channel *chan, int wait_time)
433 {
434 int16_t nfarray[HAL_NUM_NF_READINGS] = {0};
435 int is_2g = 0;
436 HAL_CHANNEL_INTERNAL *ichan = NULL;
437
438 ichan = ath_hal_checkchannel(ah, chan);
439 if (ichan == NULL)
440 return (0);
441
442 if (wait_time <= 0) {
443 return 0;
444 }
445
446 if (!ath_hal_waitfor(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF, 0, wait_time)) {
447 ath_hal_printf(ah, "%s: NF cal is not complete in %dus", __func__, wait_time);
448 return 0;
449 }
450 is_2g = !! (IS_CHAN_2GHZ(ichan));
451 ar9300_upload_noise_floor(ah, is_2g, nfarray);
452
453 return nfarray[0];
454 }
455
456 /*
457 * Pick up the medium one in the noise floor buffer and update the
458 * corresponding range for valid noise floor values
459 */
460 static int16_t
ar9300_get_nf_hist_mid(struct ath_hal * ah,HAL_NFCAL_HIST_FULL * h,int reading,int hist_len)461 ar9300_get_nf_hist_mid(struct ath_hal *ah, HAL_NFCAL_HIST_FULL *h, int reading,
462 int hist_len)
463 {
464 int16_t nfval;
465 int16_t sort[HAL_NF_CAL_HIST_LEN_FULL]; /* upper bound for hist_len */
466 int i, j;
467
468
469 for (i = 0; i < hist_len; i++) {
470 sort[i] = h->nf_cal_buffer[i][reading];
471 HALDEBUG(ah, HAL_DEBUG_NFCAL,
472 "nf_cal_buffer[%d][%d] = %d\n", i, reading, (int)sort[i]);
473 }
474 for (i = 0; i < hist_len - 1; i++) {
475 for (j = 1; j < hist_len - i; j++) {
476 if (sort[j] > sort[j - 1]) {
477 nfval = sort[j];
478 sort[j] = sort[j - 1];
479 sort[j - 1] = nfval;
480 }
481 }
482 }
483 nfval = sort[(hist_len - 1) >> 1];
484
485 return nfval;
486 }
487
ar9300_limit_nf_range(struct ath_hal * ah,int16_t nf)488 static int16_t ar9300_limit_nf_range(struct ath_hal *ah, int16_t nf)
489 {
490 if (nf < AH9300(ah)->nfp->min) {
491 return AH9300(ah)->nfp->nominal;
492 } else if (nf > AH9300(ah)->nfp->max) {
493 return AH9300(ah)->nfp->max;
494 }
495 return nf;
496 }
497
498 #ifndef ATH_NF_PER_CHAN
499 inline static void
ar9300_reset_nf_hist_buff(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan)500 ar9300_reset_nf_hist_buff(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
501 {
502 HAL_CHAN_NFCAL_HIST *h = &ichan->nf_cal_hist;
503 HAL_NFCAL_HIST_FULL *home = &AH_PRIVATE(ah)->nf_cal_hist;
504 int i;
505
506 /*
507 * Copy the value for the channel in question into the home-channel
508 * NF history buffer. The channel NF is probably a value filled in by
509 * a prior background channel scan, but if no scan has been done then
510 * it is the nominal noise floor filled in by ath_hal_init_NF_buffer
511 * for this chip and the channel's band.
512 * Replicate this channel NF into all entries of the home-channel NF
513 * history buffer.
514 * If the channel NF was filled in by a channel scan, it has not had
515 * bounds limits applied to it yet - do so now. It is important to
516 * apply bounds limits to the priv_nf value that gets loaded into the
517 * WLAN chip's min_cca_pwr register field. It is also necessary to
518 * apply bounds limits to the nf_cal_buffer[] elements. Since we are
519 * replicating a single NF reading into all nf_cal_buffer elements,
520 * if the single reading were above the CW_INT threshold, the CW_INT
521 * check in ar9300_get_nf would immediately conclude that CW interference
522 * is present, even though we're not supposed to set CW_INT unless
523 * NF values are _consistently_ above the CW_INT threshold.
524 * Applying the bounds limits to the nf_cal_buffer contents fixes this
525 * problem.
526 */
527 for (i = 0; i < HAL_NUM_NF_READINGS; i ++) {
528 int j;
529 int16_t nf;
530 /*
531 * No need to set curr_index, since it already has a value in
532 * the range [0..HAL_NF_CAL_HIST_LEN_FULL), and all nf_cal_buffer
533 * values will be the same.
534 */
535 nf = ar9300_limit_nf_range(ah, h->nf_cal_buffer[0][i]);
536 for (j = 0; j < HAL_NF_CAL_HIST_LEN_FULL; j++) {
537 home->nf_cal_buffer[j][i] = nf;
538 }
539 AH_PRIVATE(ah)->nf_cal_hist.base.priv_nf[i] = nf;
540 }
541 }
542 #endif
543
544 /*
545 * Update the noise floor buffer as a ring buffer
546 */
547 static int16_t
ar9300_update_nf_hist_buff(struct ath_hal * ah,HAL_NFCAL_HIST_FULL * h,int16_t * nfarray,int hist_len)548 ar9300_update_nf_hist_buff(struct ath_hal *ah, HAL_NFCAL_HIST_FULL *h,
549 int16_t *nfarray, int hist_len)
550 {
551 int i, nr;
552 int16_t nf_no_lim_chain0;
553
554 nf_no_lim_chain0 = ar9300_get_nf_hist_mid(ah, h, 0, hist_len);
555
556 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%s[%d] BEFORE\n", __func__, __LINE__);
557 for (nr = 0; nr < HAL_NF_CAL_HIST_LEN_FULL; nr++) {
558 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
559 HALDEBUG(ah, HAL_DEBUG_NFCAL,
560 "nf_cal_buffer[%d][%d] = %d\n",
561 nr, i, (int)h->nf_cal_buffer[nr][i]);
562 }
563 }
564 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
565 h->nf_cal_buffer[h->base.curr_index][i] = nfarray[i];
566 h->base.priv_nf[i] = ar9300_limit_nf_range(
567 ah, ar9300_get_nf_hist_mid(ah, h, i, hist_len));
568 }
569 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%s[%d] AFTER\n", __func__, __LINE__);
570 for (nr = 0; nr < HAL_NF_CAL_HIST_LEN_FULL; nr++) {
571 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
572 HALDEBUG(ah, HAL_DEBUG_NFCAL,
573 "nf_cal_buffer[%d][%d] = %d\n",
574 nr, i, (int)h->nf_cal_buffer[nr][i]);
575 }
576 }
577
578 if (++h->base.curr_index >= hist_len) {
579 h->base.curr_index = 0;
580 }
581
582 return nf_no_lim_chain0;
583 }
584
585 #ifdef UNUSED
586 static HAL_BOOL
get_noise_floor_thresh(struct ath_hal * ah,const HAL_CHANNEL_INTERNAL * chan,int16_t * nft)587 get_noise_floor_thresh(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *chan,
588 int16_t *nft)
589 {
590 struct ath_hal_9300 *ahp = AH9300(ah);
591
592
593 switch (chan->channel_flags & CHANNEL_ALL_NOTURBO) {
594 case CHANNEL_A:
595 case CHANNEL_A_HT20:
596 case CHANNEL_A_HT40PLUS:
597 case CHANNEL_A_HT40MINUS:
598 *nft = (int8_t)ar9300_eeprom_get(ahp, EEP_NFTHRESH_5);
599 break;
600 case CHANNEL_B:
601 case CHANNEL_G:
602 case CHANNEL_G_HT20:
603 case CHANNEL_G_HT40PLUS:
604 case CHANNEL_G_HT40MINUS:
605 *nft = (int8_t)ar9300_eeprom_get(ahp, EEP_NFTHRESH_2);
606 break;
607 default:
608 HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel flags 0x%x\n",
609 __func__, chan->channel_flags);
610 return AH_FALSE;
611 }
612 return AH_TRUE;
613 }
614 #endif
615
616 /*
617 * Read the NF and check it against the noise floor threshhold
618 */
619 #define IS(_c, _f) (((_c)->channel_flags & _f) || 0)
620 static int
ar9300_store_new_nf(struct ath_hal * ah,struct ieee80211_channel * chan,int is_scan)621 ar9300_store_new_nf(struct ath_hal *ah, struct ieee80211_channel *chan,
622 int is_scan)
623 {
624 // struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
625 int nf_hist_len;
626 int16_t nf_no_lim;
627 int16_t nfarray[HAL_NUM_NF_READINGS] = {0};
628 HAL_NFCAL_HIST_FULL *h;
629 int is_2g = 0;
630 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
631 struct ath_hal_9300 *ahp = AH9300(ah);
632
633 if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
634 u_int32_t tsf32, nf_cal_dur_tsf;
635 /*
636 * The reason the NF calibration did not complete may just be that
637 * not enough time has passed since the NF calibration was started,
638 * because under certain conditions (when first moving to a new
639 * channel) the NF calibration may be checked very repeatedly.
640 * Or, there may be CW interference keeping the NF calibration
641 * from completing. Check the delta time between when the NF
642 * calibration was started and now to see whether the NF calibration
643 * should have already completed (but hasn't, probably due to CW
644 * interference), or hasn't had enough time to finish yet.
645 */
646 /*
647 * AH_NF_CAL_DUR_MAX_TSF - A conservative maximum time that the
648 * HW should need to finish a NF calibration. If the HW
649 * does not complete a NF calibration within this time period,
650 * there must be a problem - probably CW interference.
651 * AH_NF_CAL_PERIOD_MAX_TSF - A conservative maximum time between
652 * check of the HW's NF calibration being finished.
653 * If the difference between the current TSF and the TSF
654 * recorded when the NF calibration started is larger than this
655 * value, the TSF must have been reset.
656 * In general, we expect the TSF to only be reset during
657 * regular operation for STAs, not for APs. However, an
658 * AP's TSF could be reset when joining an IBSS.
659 * There's an outside chance that this could result in the
660 * CW_INT flag being erroneously set, if the TSF adjustment
661 * is smaller than AH_NF_CAL_PERIOD_MAX_TSF but larger than
662 * AH_NF_CAL_DUR_TSF. However, even if this does happen,
663 * it shouldn't matter, as the IBSS case shouldn't be
664 * concerned about CW_INT.
665 */
666 /* AH_NF_CAL_DUR_TSF - 90 sec in usec units */
667 #define AH_NF_CAL_DUR_TSF (90 * 1000 * 1000)
668 /* AH_NF_CAL_PERIOD_MAX_TSF - 180 sec in usec units */
669 #define AH_NF_CAL_PERIOD_MAX_TSF (180 * 1000 * 1000)
670 /* wraparound handled by using unsigned values */
671 tsf32 = ar9300_get_tsf32(ah);
672 nf_cal_dur_tsf = tsf32 - AH9300(ah)->nf_tsf32;
673 if (nf_cal_dur_tsf > AH_NF_CAL_PERIOD_MAX_TSF) {
674 /*
675 * The TSF must have gotten reset during the NF cal -
676 * just reset the NF TSF timestamp, so the next time
677 * this function is called, the timestamp comparison
678 * will be valid.
679 */
680 AH9300(ah)->nf_tsf32 = tsf32;
681 } else if (nf_cal_dur_tsf > AH_NF_CAL_DUR_TSF) {
682 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
683 "%s: NF did not complete in calibration window\n", __func__);
684 /* the NF incompletion is probably due to CW interference */
685 chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
686 }
687 return 0; /* HW's NF measurement not finished */
688 }
689 HALDEBUG(ah, HAL_DEBUG_NFCAL,
690 "%s[%d] chan %d\n", __func__, __LINE__, ichan->channel);
691 is_2g = !! IS_CHAN_2GHZ(ichan);
692 ar9300_upload_noise_floor(ah, is_2g, nfarray);
693
694 /* Update the NF buffer for each chain masked by chainmask */
695 #ifdef ATH_NF_PER_CHAN
696 h = &ichan->nf_cal_hist;
697 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
698 #else
699 if (is_scan) {
700 /*
701 * This channel's NF cal info is just a HAL_NFCAL_HIST_SMALL struct
702 * rather than a HAL_NFCAL_HIST_FULL struct.
703 * As long as we only use the first history element of nf_cal_buffer
704 * (nf_cal_buffer[0][0:HAL_NUM_NF_READINGS-1]), we can use
705 * HAL_NFCAL_HIST_SMALL and HAL_NFCAL_HIST_FULL interchangeably.
706 */
707 h = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
708 nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
709 } else {
710 h = &AH_PRIVATE(ah)->nf_cal_hist;
711 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
712 }
713 #endif
714
715 /*
716 * nf_no_lim = median value from NF history buffer without bounds limits,
717 * priv_nf = median value from NF history buffer with bounds limits.
718 */
719 nf_no_lim = ar9300_update_nf_hist_buff(ah, h, nfarray, nf_hist_len);
720 ichan->rawNoiseFloor = h->base.priv_nf[0];
721
722 /* check if there is interference */
723 // ichan->channel_flags &= (~CHANNEL_CW_INT);
724 /*
725 * Use AR9300_EMULATION to check for emulation purpose as PCIE Device ID
726 * 0xABCD is recognized as valid Osprey as WAR in some EVs.
727 */
728 if (nf_no_lim > ahp->nfp->nominal + ahp->nf_cw_int_delta) {
729 /*
730 * Since this CW interference check is being applied to the
731 * median element of the NF history buffer, this indicates that
732 * the CW interference is persistent. A single high NF reading
733 * will not show up in the median, and thus will not cause the
734 * CW_INT flag to be set.
735 */
736 HALDEBUG(ah, HAL_DEBUG_NFCAL,
737 "%s: NF Cal: CW interferer detected through NF: %d\n",
738 __func__, nf_no_lim);
739 chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
740 }
741 return 1; /* HW's NF measurement finished */
742 }
743 #undef IS
744
745 static inline void
ar9300_get_delta_slope_values(struct ath_hal * ah,u_int32_t coef_scaled,u_int32_t * coef_mantissa,u_int32_t * coef_exponent)746 ar9300_get_delta_slope_values(struct ath_hal *ah, u_int32_t coef_scaled,
747 u_int32_t *coef_mantissa, u_int32_t *coef_exponent)
748 {
749 u_int32_t coef_exp, coef_man;
750
751 /*
752 * ALGO -> coef_exp = 14-floor(log2(coef));
753 * floor(log2(x)) is the highest set bit position
754 */
755 for (coef_exp = 31; coef_exp > 0; coef_exp--) {
756 if ((coef_scaled >> coef_exp) & 0x1) {
757 break;
758 }
759 }
760 /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */
761 HALASSERT(coef_exp);
762 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
763
764
765 /*
766 * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5);
767 * The coefficient is already shifted up for scaling
768 */
769 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
770
771 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
772 *coef_exponent = coef_exp - 16;
773 }
774
775 #define MAX_ANALOG_START 319 /* XXX */
776
777 /*
778 * Delta slope coefficient computation.
779 * Required for OFDM operation.
780 */
781 static void
ar9300_set_delta_slope(struct ath_hal * ah,struct ieee80211_channel * chan)782 ar9300_set_delta_slope(struct ath_hal *ah, struct ieee80211_channel *chan)
783 {
784 u_int32_t coef_scaled, ds_coef_exp, ds_coef_man;
785 u_int32_t fclk = COEFF; /* clock * 2.5 */
786
787 u_int32_t clock_mhz_scaled = 0x1000000 * fclk;
788 CHAN_CENTERS centers;
789
790 /*
791 * half and quarter rate can divide the scaled clock by 2 or 4
792 * scale for selected channel bandwidth
793 */
794 if (IEEE80211_IS_CHAN_HALF(chan)) {
795 clock_mhz_scaled = clock_mhz_scaled >> 1;
796 } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
797 clock_mhz_scaled = clock_mhz_scaled >> 2;
798 }
799
800 /*
801 * ALGO -> coef = 1e8/fcarrier*fclock/40;
802 * scaled coef to provide precision for this floating calculation
803 */
804 ar9300_get_channel_centers(ah, chan, ¢ers);
805 coef_scaled = clock_mhz_scaled / centers.synth_center;
806
807 ar9300_get_delta_slope_values(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
808
809 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
810 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
811
812 /*
813 * For Short GI,
814 * scaled coeff is 9/10 that of normal coeff
815 */
816 coef_scaled = (9 * coef_scaled) / 10;
817
818 ar9300_get_delta_slope_values(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
819
820 /* for short gi */
821 OS_REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, AR_PHY_SGI_DSC_MAN, ds_coef_man);
822 OS_REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, AR_PHY_SGI_DSC_EXP, ds_coef_exp);
823 }
824
825 #define IS(_c, _f) (IEEE80211_IS_ ## _f(_c))
826
827 /*
828 * XXX FreeBSD: This should be turned into something generic in ath_hal!
829 */
830 HAL_CHANNEL_INTERNAL *
ar9300_check_chan(struct ath_hal * ah,const struct ieee80211_channel * chan)831 ar9300_check_chan(struct ath_hal *ah, const struct ieee80211_channel *chan)
832 {
833
834 if (chan == NULL) {
835 return AH_NULL;
836 }
837
838 if ((IS(chan, CHAN_2GHZ) ^ IS(chan, CHAN_5GHZ)) == 0) {
839 HALDEBUG(ah, HAL_DEBUG_CHANNEL,
840 "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
841 __func__, chan->ic_freq , chan->ic_flags);
842 return AH_NULL;
843 }
844
845 /*
846 * FreeBSD sets multiple flags, so this will fail.
847 */
848 #if 0
849 if ((IS(chan, CHAN_OFDM) ^ IS(chan, CHAN_CCK) ^ IS(chan, CHAN_DYN) ^
850 IS(chan, CHAN_HT20) ^ IS(chan, CHAN_HT40U) ^
851 IS(chan, CHAN_HT40D)) == 0)
852 {
853 HALDEBUG(ah, HAL_DEBUG_CHANNEL,
854 "%s: invalid channel %u/0x%x; not marked as "
855 "OFDM or CCK or DYN or HT20 or HT40PLUS or HT40MINUS\n",
856 __func__, chan->ic_freq , chan->ic_flags);
857 return AH_NULL;
858 }
859 #endif
860
861 return (ath_hal_checkchannel(ah, chan));
862 }
863 #undef IS
864
865 static void
ar9300_set_11n_regs(struct ath_hal * ah,struct ieee80211_channel * chan,HAL_HT_MACMODE macmode)866 ar9300_set_11n_regs(struct ath_hal *ah, struct ieee80211_channel *chan,
867 HAL_HT_MACMODE macmode)
868 {
869 u_int32_t phymode;
870 // struct ath_hal_9300 *ahp = AH9300(ah);
871 u_int32_t enable_dac_fifo;
872
873 /* XXX */
874 enable_dac_fifo =
875 OS_REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO;
876
877 /* Enable 11n HT, 20 MHz */
878 phymode =
879 AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_SHORT_GI_40
880 | enable_dac_fifo;
881 /* Configure baseband for dynamic 20/40 operation */
882 if (IEEE80211_IS_CHAN_HT40(chan)) {
883 phymode |= AR_PHY_GC_DYN2040_EN;
884 /* Configure control (primary) channel at +-10MHz */
885 if (IEEE80211_IS_CHAN_HT40U(chan)) {
886 phymode |= AR_PHY_GC_DYN2040_PRI_CH;
887 }
888
889 #if 0
890 /* Configure 20/25 spacing */
891 if (ahp->ah_ext_prot_spacing == HAL_HT_EXTPROTSPACING_25) {
892 phymode |= AR_PHY_GC_DYN2040_EXT_CH;
893 }
894 #endif
895 }
896
897 /* make sure we preserve INI settings */
898 phymode |= OS_REG_READ(ah, AR_PHY_GEN_CTRL);
899
900 /* EV 62881/64991 - turn off Green Field detection for Maverick STA beta */
901 phymode &= ~AR_PHY_GC_GF_DETECT_EN;
902
903 OS_REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode);
904
905 /* Set IFS timing for half/quarter rates */
906 if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan)) {
907 u_int32_t modeselect = OS_REG_READ(ah, AR_PHY_MODE);
908
909 if (IEEE80211_IS_CHAN_HALF(chan)) {
910 modeselect |= AR_PHY_MS_HALF_RATE;
911 } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
912 modeselect |= AR_PHY_MS_QUARTER_RATE;
913 }
914 OS_REG_WRITE(ah, AR_PHY_MODE, modeselect);
915
916 ar9300_set_ifs_timing(ah, chan);
917 OS_REG_RMW_FIELD(
918 ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW, 0x3);
919 }
920
921 /* Configure MAC for 20/40 operation */
922 ar9300_set_11n_mac2040(ah, macmode);
923
924 /* global transmit timeout (25 TUs default)*/
925 /* XXX - put this elsewhere??? */
926 OS_REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
927
928 /* carrier sense timeout */
929 OS_REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
930 }
931
932 /*
933 * Spur mitigation for MRC CCK
934 */
935 static void
ar9300_spur_mitigate_mrc_cck(struct ath_hal * ah,struct ieee80211_channel * chan)936 ar9300_spur_mitigate_mrc_cck(struct ath_hal *ah, struct ieee80211_channel *chan)
937 {
938 int i;
939 /* spur_freq_for_osprey - hardcoded by Systems team for now. */
940 u_int32_t spur_freq_for_osprey[4] = { 2420, 2440, 2464, 2480 };
941 u_int32_t spur_freq_for_jupiter[2] = { 2440, 2464};
942 int cur_bb_spur, negative = 0, cck_spur_freq;
943 u_int8_t* spur_fbin_ptr = NULL;
944 int synth_freq;
945 int range = 10;
946 int max_spurcounts = OSPREY_EEPROM_MODAL_SPURS;
947 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
948
949 /*
950 * Need to verify range +/- 10 MHz in control channel, otherwise spur
951 * is out-of-band and can be ignored.
952 */
953 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
954 AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
955 spur_fbin_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 1);
956 if (spur_fbin_ptr[0] == 0) {
957 return; /* No spur in the mode */
958 }
959 if (IEEE80211_IS_CHAN_HT40(chan)) {
960 range = 19;
961 if (OS_REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH)
962 == 0x0)
963 {
964 synth_freq = ichan->channel + 10;
965 } else {
966 synth_freq = ichan->channel - 10;
967 }
968 } else {
969 range = 10;
970 synth_freq = ichan->channel;
971 }
972 } else if(AR_SREV_JUPITER(ah)) {
973 range = 5;
974 max_spurcounts = 2; /* Hardcoded by Jupiter Systems team for now. */
975 synth_freq = ichan->channel;
976 } else {
977 range = 10;
978 max_spurcounts = 4; /* Hardcoded by Osprey Systems team for now. */
979 synth_freq = ichan->channel;
980 }
981
982 for (i = 0; i < max_spurcounts; i++) {
983 negative = 0;
984
985 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
986 AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
987 cur_bb_spur =
988 FBIN2FREQ(spur_fbin_ptr[i], HAL_FREQ_BAND_2GHZ) - synth_freq;
989 } else if(AR_SREV_JUPITER(ah)) {
990 cur_bb_spur = spur_freq_for_jupiter[i] - synth_freq;
991 } else {
992 cur_bb_spur = spur_freq_for_osprey[i] - synth_freq;
993 }
994
995 if (cur_bb_spur < 0) {
996 negative = 1;
997 cur_bb_spur = -cur_bb_spur;
998 }
999 if (cur_bb_spur < range) {
1000 cck_spur_freq = (int)((cur_bb_spur << 19) / 11);
1001 if (negative == 1) {
1002 cck_spur_freq = -cck_spur_freq;
1003 }
1004 cck_spur_freq = cck_spur_freq & 0xfffff;
1005 /*OS_REG_WRITE_field(ah, BB_agc_control.ycok_max, 0x7);*/
1006 OS_REG_RMW_FIELD(ah,
1007 AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7);
1008 /*OS_REG_WRITE_field(ah, BB_cck_spur_mit.spur_rssi_thr, 0x7f);*/
1009 OS_REG_RMW_FIELD(ah,
1010 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f);
1011 /*OS_REG_WRITE(ah, BB_cck_spur_mit.spur_filter_type, 0x2);*/
1012 OS_REG_RMW_FIELD(ah,
1013 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE, 0x2);
1014 /*OS_REG_WRITE(ah, BB_cck_spur_mit.use_cck_spur_mit, 0x1);*/
1015 OS_REG_RMW_FIELD(ah,
1016 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x1);
1017 /*OS_REG_WRITE(ah, BB_cck_spur_mit.cck_spur_freq, cck_spur_freq);*/
1018 OS_REG_RMW_FIELD(ah,
1019 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ,
1020 cck_spur_freq);
1021 return;
1022 }
1023 }
1024
1025 /*OS_REG_WRITE(ah, BB_agc_control.ycok_max, 0x5);*/
1026 OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5);
1027 /*OS_REG_WRITE(ah, BB_cck_spur_mit.use_cck_spur_mit, 0x0);*/
1028 OS_REG_RMW_FIELD(ah,
1029 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x0);
1030 /*OS_REG_WRITE(ah, BB_cck_spur_mit.cck_spur_freq, 0x0);*/
1031 OS_REG_RMW_FIELD(ah,
1032 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0);
1033 }
1034
1035 /* Spur mitigation for OFDM */
1036 static void
ar9300_spur_mitigate_ofdm(struct ath_hal * ah,struct ieee80211_channel * chan)1037 ar9300_spur_mitigate_ofdm(struct ath_hal *ah, struct ieee80211_channel *chan)
1038 {
1039 int synth_freq;
1040 int range = 10;
1041 int freq_offset = 0;
1042 int spur_freq_sd = 0;
1043 int spur_subchannel_sd = 0;
1044 int spur_delta_phase = 0;
1045 int mask_index = 0;
1046 int i;
1047 int mode;
1048 u_int8_t* spur_chans_ptr;
1049 struct ath_hal_9300 *ahp;
1050 ahp = AH9300(ah);
1051 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
1052
1053 if (IS_CHAN_5GHZ(ichan)) {
1054 spur_chans_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 0);
1055 mode = 0;
1056 } else {
1057 spur_chans_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 1);
1058 mode = 1;
1059 }
1060
1061 if (IEEE80211_IS_CHAN_HT40(chan)) {
1062 range = 19;
1063 if (OS_REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH)
1064 == 0x0)
1065 {
1066 synth_freq = ichan->channel - 10;
1067 } else {
1068 synth_freq = ichan->channel + 10;
1069 }
1070 } else {
1071 range = 10;
1072 synth_freq = ichan->channel;
1073 }
1074
1075 /* Clean all spur register fields */
1076 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0);
1077 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_FREQ_SD, 0);
1078 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0);
1079 OS_REG_RMW_FIELD(ah,
1080 AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, 0);
1081 OS_REG_RMW_FIELD(ah,
1082 AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0);
1083 OS_REG_RMW_FIELD(ah,
1084 AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0);
1085 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0);
1086 OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 0);
1087 OS_REG_RMW_FIELD(ah,
1088 AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 0);
1089 OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0);
1090 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0);
1091 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0);
1092 OS_REG_RMW_FIELD(ah,
1093 AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, 0);
1094 OS_REG_RMW_FIELD(ah,
1095 AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, 0);
1096 OS_REG_RMW_FIELD(ah,
1097 AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, 0);
1098 OS_REG_RMW_FIELD(ah,
1099 AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0);
1100 OS_REG_RMW_FIELD(ah,
1101 AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0);
1102 OS_REG_RMW_FIELD(ah,
1103 AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0);
1104 OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0);
1105
1106 i = 0;
1107 while (spur_chans_ptr[i] && i < 5) {
1108 freq_offset = FBIN2FREQ(spur_chans_ptr[i], mode) - synth_freq;
1109 if (abs(freq_offset) < range) {
1110 /*
1111 printf(
1112 "Spur Mitigation for OFDM: Synth Frequency = %d, "
1113 "Spur Frequency = %d\n",
1114 synth_freq, FBIN2FREQ(spur_chans_ptr[i], mode));
1115 */
1116 if (IEEE80211_IS_CHAN_HT40(chan)) {
1117 if (freq_offset < 0) {
1118 if (OS_REG_READ_FIELD(
1119 ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
1120 {
1121 spur_subchannel_sd = 1;
1122 } else {
1123 spur_subchannel_sd = 0;
1124 }
1125 spur_freq_sd = ((freq_offset + 10) << 9) / 11;
1126 } else {
1127 if (OS_REG_READ_FIELD(ah,
1128 AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
1129 {
1130 spur_subchannel_sd = 0;
1131 } else {
1132 spur_subchannel_sd = 1;
1133 }
1134 spur_freq_sd = ((freq_offset - 10) << 9) / 11;
1135 }
1136 spur_delta_phase = (freq_offset << 17) / 5;
1137 } else {
1138 spur_subchannel_sd = 0;
1139 spur_freq_sd = (freq_offset << 9) / 11;
1140 spur_delta_phase = (freq_offset << 18) / 5;
1141 }
1142 spur_freq_sd = spur_freq_sd & 0x3ff;
1143 spur_delta_phase = spur_delta_phase & 0xfffff;
1144 /*
1145 printf(
1146 "spur_subchannel_sd = %d, spur_freq_sd = 0x%x, "
1147 "spur_delta_phase = 0x%x\n", spur_subchannel_sd,
1148 spur_freq_sd, spur_delta_phase);
1149 */
1150
1151 /* OFDM Spur mitigation */
1152 OS_REG_RMW_FIELD(ah,
1153 AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0x1);
1154 OS_REG_RMW_FIELD(ah,
1155 AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd);
1156 OS_REG_RMW_FIELD(ah,
1157 AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_DELTA_PHASE,
1158 spur_delta_phase);
1159 OS_REG_RMW_FIELD(ah,
1160 AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD,
1161 spur_subchannel_sd);
1162 OS_REG_RMW_FIELD(ah,
1163 AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1);
1164 OS_REG_RMW_FIELD(ah,
1165 AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR,
1166 0x1);
1167 OS_REG_RMW_FIELD(ah,
1168 AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1);
1169 OS_REG_RMW_FIELD(ah,
1170 AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34);
1171 OS_REG_RMW_FIELD(ah,
1172 AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
1173
1174 /*
1175 * Do not subtract spur power from noise floor for wasp.
1176 * This causes the maximum client test (on Veriwave) to fail
1177 * when run on spur channel (2464 MHz).
1178 * Refer to ev#82746 and ev#82744.
1179 */
1180 if (!AR_SREV_WASP(ah) && (OS_REG_READ_FIELD(ah, AR_PHY_MODE,
1181 AR_PHY_MODE_DYNAMIC) == 0x1)) {
1182 OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
1183 AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
1184 }
1185
1186 mask_index = (freq_offset << 4) / 5;
1187 if (mask_index < 0) {
1188 mask_index = mask_index - 1;
1189 }
1190 mask_index = mask_index & 0x7f;
1191 /*printf("Bin 0x%x\n", mask_index);*/
1192
1193 OS_REG_RMW_FIELD(ah,
1194 AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0x1);
1195 OS_REG_RMW_FIELD(ah,
1196 AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0x1);
1197 OS_REG_RMW_FIELD(ah,
1198 AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0x1);
1199 OS_REG_RMW_FIELD(ah,
1200 AR_PHY_PILOT_SPUR_MASK,
1201 AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, mask_index);
1202 OS_REG_RMW_FIELD(ah,
1203 AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A,
1204 mask_index);
1205 OS_REG_RMW_FIELD(ah,
1206 AR_PHY_CHAN_SPUR_MASK,
1207 AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, mask_index);
1208 OS_REG_RMW_FIELD(ah,
1209 AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A,
1210 0xc);
1211 OS_REG_RMW_FIELD(ah,
1212 AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A,
1213 0xc);
1214 OS_REG_RMW_FIELD(ah,
1215 AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0);
1216 OS_REG_RMW_FIELD(ah,
1217 AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff);
1218 /*
1219 printf("BB_timing_control_4 = 0x%x\n",
1220 OS_REG_READ(ah, AR_PHY_TIMING4));
1221 printf("BB_timing_control_11 = 0x%x\n",
1222 OS_REG_READ(ah, AR_PHY_TIMING11));
1223 printf("BB_ext_chan_scorr_thr = 0x%x\n",
1224 OS_REG_READ(ah, AR_PHY_SFCORR_EXT));
1225 printf("BB_spur_mask_controls = 0x%x\n",
1226 OS_REG_READ(ah, AR_PHY_SPUR_REG));
1227 printf("BB_pilot_spur_mask = 0x%x\n",
1228 OS_REG_READ(ah, AR_PHY_PILOT_SPUR_MASK));
1229 printf("BB_chan_spur_mask = 0x%x\n",
1230 OS_REG_READ(ah, AR_PHY_CHAN_SPUR_MASK));
1231 printf("BB_vit_spur_mask_A = 0x%x\n",
1232 OS_REG_READ(ah, AR_PHY_SPUR_MASK_A));
1233 */
1234 break;
1235 }
1236 i++;
1237 }
1238 }
1239
1240
1241 /*
1242 * Convert to baseband spur frequency given input channel frequency
1243 * and compute register settings below.
1244 */
1245 static void
ar9300_spur_mitigate(struct ath_hal * ah,struct ieee80211_channel * chan)1246 ar9300_spur_mitigate(struct ath_hal *ah, struct ieee80211_channel *chan)
1247 {
1248 ar9300_spur_mitigate_ofdm(ah, chan);
1249 ar9300_spur_mitigate_mrc_cck(ah, chan);
1250 }
1251
1252 /**************************************************************
1253 * ar9300_channel_change
1254 * Assumes caller wants to change channel, and not reset.
1255 */
1256 static inline HAL_BOOL
ar9300_channel_change(struct ath_hal * ah,struct ieee80211_channel * chan,HAL_CHANNEL_INTERNAL * ichan,HAL_HT_MACMODE macmode)1257 ar9300_channel_change(struct ath_hal *ah, struct ieee80211_channel *chan,
1258 HAL_CHANNEL_INTERNAL *ichan, HAL_HT_MACMODE macmode)
1259 {
1260
1261 u_int32_t synth_delay, qnum;
1262 struct ath_hal_9300 *ahp = AH9300(ah);
1263
1264 /* TX must be stopped by now */
1265 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
1266 if (ar9300_num_tx_pending(ah, qnum)) {
1267 HALDEBUG(ah, HAL_DEBUG_QUEUE,
1268 "%s: Transmit frames pending on queue %d\n", __func__, qnum);
1269 HALASSERT(0);
1270 return AH_FALSE;
1271 }
1272 }
1273
1274
1275 /*
1276 * Kill last Baseband Rx Frame - Request analog bus grant
1277 */
1278 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
1279 if (!ath_hal_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
1280 AR_PHY_RFBUS_GRANT_EN))
1281 {
1282 HALDEBUG(ah, HAL_DEBUG_PHYIO,
1283 "%s: Could not kill baseband RX\n", __func__);
1284 return AH_FALSE;
1285 }
1286
1287
1288 /* Setup 11n MAC/Phy mode registers */
1289 ar9300_set_11n_regs(ah, chan, macmode);
1290
1291 /*
1292 * Change the synth
1293 */
1294 if (!ahp->ah_rf_hal.set_channel(ah, chan)) {
1295 HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: failed to set channel\n", __func__);
1296 return AH_FALSE;
1297 }
1298
1299 /*
1300 * Some registers get reinitialized during ATH_INI_POST INI programming.
1301 */
1302 ar9300_init_user_settings(ah);
1303
1304 /*
1305 * Setup the transmit power values.
1306 *
1307 * After the public to private hal channel mapping, ichan contains the
1308 * valid regulatory power value.
1309 * ath_hal_getctl and ath_hal_getantennaallowed look up ichan from chan.
1310 */
1311 if (ar9300_eeprom_set_transmit_power(
1312 ah, &ahp->ah_eeprom, chan, ath_hal_getctl(ah, chan),
1313 ath_hal_getantennaallowed(ah, chan),
1314 ath_hal_get_twice_max_regpower(AH_PRIVATE(ah), ichan, chan),
1315 AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit)) != HAL_OK)
1316 {
1317 HALDEBUG(ah, HAL_DEBUG_EEPROM,
1318 "%s: error init'ing transmit power\n", __func__);
1319 return AH_FALSE;
1320 }
1321
1322 /*
1323 * Release the RFBus Grant.
1324 */
1325 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
1326
1327 /*
1328 * Write spur immunity and delta slope for OFDM enabled modes (A, G, Turbo)
1329 */
1330 if (IEEE80211_IS_CHAN_OFDM(chan) || IEEE80211_IS_CHAN_HT(chan)) {
1331 ar9300_set_delta_slope(ah, chan);
1332 } else {
1333 /* Set to Ini default */
1334 OS_REG_WRITE(ah, AR_PHY_TIMING3, 0x9c0a9f6b);
1335 OS_REG_WRITE(ah, AR_PHY_SGI_DELTA, 0x00046384);
1336 }
1337
1338 ar9300_spur_mitigate(ah, chan);
1339
1340
1341 /*
1342 * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).
1343 * Read the phy active delay register. Value is in 100ns increments.
1344 */
1345 synth_delay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
1346 if (IEEE80211_IS_CHAN_CCK(chan)) {
1347 synth_delay = (4 * synth_delay) / 22;
1348 } else {
1349 synth_delay /= 10;
1350 }
1351
1352 OS_DELAY(synth_delay + BASE_ACTIVATE_DELAY);
1353
1354 /*
1355 * Do calibration.
1356 */
1357
1358 return AH_TRUE;
1359 }
1360
1361 void
ar9300_set_operating_mode(struct ath_hal * ah,int opmode)1362 ar9300_set_operating_mode(struct ath_hal *ah, int opmode)
1363 {
1364 u_int32_t val;
1365
1366 val = OS_REG_READ(ah, AR_STA_ID1);
1367 val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
1368 switch (opmode) {
1369 case HAL_M_HOSTAP:
1370 OS_REG_WRITE(ah, AR_STA_ID1,
1371 val | AR_STA_ID1_STA_AP | AR_STA_ID1_KSRCH_MODE);
1372 OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1373 break;
1374 case HAL_M_IBSS:
1375 OS_REG_WRITE(ah, AR_STA_ID1,
1376 val | AR_STA_ID1_ADHOC | AR_STA_ID1_KSRCH_MODE);
1377 OS_REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1378 break;
1379 case HAL_M_STA:
1380 case HAL_M_MONITOR:
1381 OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
1382 break;
1383 }
1384 }
1385
1386 /* XXX need the logic for Osprey */
1387 void
ar9300_init_pll(struct ath_hal * ah,struct ieee80211_channel * chan)1388 ar9300_init_pll(struct ath_hal *ah, struct ieee80211_channel *chan)
1389 {
1390 u_int32_t pll;
1391 u_int8_t clk_25mhz = AH9300(ah)->clk_25mhz;
1392 HAL_CHANNEL_INTERNAL *ichan = NULL;
1393
1394 if (chan)
1395 ichan = ath_hal_checkchannel(ah, chan);
1396
1397 if (AR_SREV_HORNET(ah)) {
1398 if (clk_25mhz) {
1399 /* Hornet uses PLL_CONTROL_2. Xtal is 25MHz for Hornet.
1400 * REFDIV set to 0x1.
1401 * $xtal_freq = 25;
1402 * $PLL2_div = (704/$xtal_freq); # 176 * 4 = 704.
1403 * MAC and BB run at 176 MHz.
1404 * $PLL2_divint = int($PLL2_div);
1405 * $PLL2_divfrac = $PLL2_div - $PLL2_divint;
1406 * $PLL2_divfrac = int($PLL2_divfrac * 0x4000); # 2^14
1407 * $PLL2_Val = ($PLL2_divint & 0x3f) << 19 | (0x1) << 14 |
1408 * $PLL2_divfrac & 0x3fff;
1409 * Therefore, $PLL2_Val = 0xe04a3d
1410 */
1411 #define DPLL2_KD_VAL 0x1D
1412 #define DPLL2_KI_VAL 0x06
1413 #define DPLL3_PHASE_SHIFT_VAL 0x1
1414
1415 /* Rewrite DDR PLL2 and PLL3 */
1416 /* program DDR PLL ki and kd value, ki=0x6, kd=0x1d */
1417 OS_REG_WRITE(ah, AR_HORNET_CH0_DDR_DPLL2, 0x18e82f01);
1418
1419 /* program DDR PLL phase_shift to 0x1 */
1420 OS_REG_RMW_FIELD(ah, AR_HORNET_CH0_DDR_DPLL3,
1421 AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1422
1423 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
1424 OS_DELAY(1000);
1425
1426 /* program refdiv, nint, frac to RTC register */
1427 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0xe04a3d);
1428
1429 /* program BB PLL ki and kd value, ki=0x6, kd=0x1d */
1430 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1431 AR_PHY_BB_DPLL2_KD, DPLL2_KD_VAL);
1432 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1433 AR_PHY_BB_DPLL2_KI, DPLL2_KI_VAL);
1434
1435 /* program BB PLL phase_shift to 0x1 */
1436 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1437 AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1438 } else { /* 40MHz */
1439 #undef DPLL2_KD_VAL
1440 #undef DPLL2_KI_VAL
1441 #define DPLL2_KD_VAL 0x3D
1442 #define DPLL2_KI_VAL 0x06
1443 /* Rewrite DDR PLL2 and PLL3 */
1444 /* program DDR PLL ki and kd value, ki=0x6, kd=0x3d */
1445 OS_REG_WRITE(ah, AR_HORNET_CH0_DDR_DPLL2, 0x19e82f01);
1446
1447 /* program DDR PLL phase_shift to 0x1 */
1448 OS_REG_RMW_FIELD(ah, AR_HORNET_CH0_DDR_DPLL3,
1449 AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1450
1451 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
1452 OS_DELAY(1000);
1453
1454 /* program refdiv, nint, frac to RTC register */
1455 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666);
1456
1457 /* program BB PLL ki and kd value, ki=0x6, kd=0x3d */
1458 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1459 AR_PHY_BB_DPLL2_KD, DPLL2_KD_VAL);
1460 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1461 AR_PHY_BB_DPLL2_KI, DPLL2_KI_VAL);
1462
1463 /* program BB PLL phase_shift to 0x1 */
1464 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1465 AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1466 }
1467 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1468 OS_DELAY(1000);
1469 } else if (AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
1470 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2, AR_PHY_BB_DPLL2_PLL_PWD, 0x1);
1471
1472 /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
1473 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1474 AR_PHY_BB_DPLL2_KD, 0x40);
1475 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1476 AR_PHY_BB_DPLL2_KI, 0x4);
1477
1478 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1479 AR_PHY_BB_DPLL1_REFDIV, 0x5);
1480 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1481 AR_PHY_BB_DPLL1_NINI, 0x58);
1482 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1483 AR_PHY_BB_DPLL1_NFRAC, 0x0);
1484
1485 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1486 AR_PHY_BB_DPLL2_OUTDIV, 0x1);
1487 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1488 AR_PHY_BB_DPLL2_LOCAL_PLL, 0x1);
1489 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1490 AR_PHY_BB_DPLL2_EN_NEGTRIG, 0x1);
1491
1492 /* program BB PLL phase_shift to 0x6 */
1493 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1494 AR_PHY_BB_DPLL3_PHASE_SHIFT, 0x6);
1495
1496 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1497 AR_PHY_BB_DPLL2_PLL_PWD, 0x0);
1498 OS_DELAY(1000);
1499
1500 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1501 OS_DELAY(1000);
1502 } else if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) {
1503 #define SRIF_PLL 1
1504 u_int32_t regdata, pll2_divint, pll2_divfrac;
1505
1506 #ifndef SRIF_PLL
1507 u_int32_t pll2_clkmode;
1508 #endif
1509
1510 #ifdef SRIF_PLL
1511 u_int32_t refdiv;
1512 #endif
1513 if (clk_25mhz) {
1514 #ifndef SRIF_PLL
1515 pll2_divint = 0x1c;
1516 pll2_divfrac = 0xa3d7;
1517 #else
1518 if (AR_SREV_HONEYBEE(ah)) {
1519 pll2_divint = 0x1c;
1520 pll2_divfrac = 0xa3d2;
1521 refdiv = 1;
1522 } else {
1523 pll2_divint = 0x54;
1524 pll2_divfrac = 0x1eb85;
1525 refdiv = 3;
1526 }
1527 #endif
1528 } else {
1529 #ifndef SRIF_PLL
1530 pll2_divint = 0x11;
1531 pll2_divfrac = 0x26666;
1532 #else
1533 if (AR_SREV_WASP(ah)) {
1534 pll2_divint = 88;
1535 pll2_divfrac = 0;
1536 refdiv = 5;
1537 } else {
1538 pll2_divint = 0x11;
1539 pll2_divfrac = 0x26666;
1540 refdiv = 1;
1541 }
1542 #endif
1543 }
1544 #ifndef SRIF_PLL
1545 pll2_clkmode = 0x3d;
1546 #endif
1547 /* PLL programming through SRIF Local Mode */
1548 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); /* Bypass mode */
1549 OS_DELAY(1000);
1550 do {
1551 regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1552 if (AR_SREV_HONEYBEE(ah)) {
1553 regdata = regdata | (0x1 << 22);
1554 } else {
1555 regdata = regdata | (0x1 << 16);
1556 }
1557 OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata); /* PWD_PLL set to 1 */
1558 OS_DELAY(100);
1559 /* override int, frac, refdiv */
1560 #ifndef SRIF_PLL
1561 OS_REG_WRITE(ah, AR_PHY_PLL_CONTROL,
1562 ((1 << 27) | (pll2_divint << 18) | pll2_divfrac));
1563 #else
1564 OS_REG_WRITE(ah, AR_PHY_PLL_CONTROL,
1565 ((refdiv << 27) | (pll2_divint << 18) | pll2_divfrac));
1566 #endif
1567 OS_DELAY(100);
1568 regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1569 #ifndef SRIF_PLL
1570 regdata = (regdata & 0x80071fff) |
1571 (0x1 << 30) | (0x1 << 13) | (0x6 << 26) | (pll2_clkmode << 19);
1572 #else
1573 if (AR_SREV_WASP(ah)) {
1574 regdata = (regdata & 0x80071fff) |
1575 (0x1 << 30) | (0x1 << 13) | (0x4 << 26) | (0x18 << 19);
1576 } else if (AR_SREV_HONEYBEE(ah)) {
1577 /*
1578 * Kd=10, Ki=2, Outdiv=1, Local PLL=0, Phase Shift=4
1579 */
1580 regdata = (regdata & 0x01c00fff) |
1581 (0x1 << 31) | (0x2 << 29) | (0xa << 25) | (0x1 << 19) | (0x6 << 12);
1582 } else {
1583 regdata = (regdata & 0x80071fff) |
1584 (0x3 << 30) | (0x1 << 13) | (0x4 << 26) | (0x60 << 19);
1585 }
1586 #endif
1587 /* Ki, Kd, Local PLL, Outdiv */
1588 OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata);
1589 regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1590 if (AR_SREV_HONEYBEE(ah)) {
1591 regdata = (regdata & 0xffbfffff);
1592 } else {
1593 regdata = (regdata & 0xfffeffff);
1594 }
1595 OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata); /* PWD_PLL set to 0 */
1596 OS_DELAY(1000);
1597 if (AR_SREV_WASP(ah)) {
1598 /* clear do measure */
1599 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1600 regdata &= ~(1 << 30);
1601 OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1602 OS_DELAY(100);
1603
1604 /* set do measure */
1605 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1606 regdata |= (1 << 30);
1607 OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1608
1609 /* wait for measure done */
1610 do {
1611 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL4);
1612 } while ((regdata & (1 << 3)) == 0);
1613
1614 /* clear do measure */
1615 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1616 regdata &= ~(1 << 30);
1617 OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1618
1619 /* get measure sqsum dvc */
1620 regdata = (OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3) & 0x007FFFF8) >> 3;
1621 } else {
1622 break;
1623 }
1624 } while (regdata >= 0x40000);
1625
1626 /* Remove from Bypass mode */
1627 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1628 OS_DELAY(1000);
1629 } else {
1630 pll = SM(0x5, AR_RTC_PLL_REFDIV);
1631
1632 /* Supposedly not needed on Osprey */
1633 #if 0
1634 if (chan && IS_CHAN_HALF_RATE(chan)) {
1635 pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1636 } else if (chan && IS_CHAN_QUARTER_RATE(chan)) {
1637 pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1638 }
1639 #endif
1640 if (ichan && IS_CHAN_5GHZ(ichan)) {
1641 pll |= SM(0x28, AR_RTC_PLL_DIV);
1642 /*
1643 * When doing fast clock, set PLL to 0x142c
1644 */
1645 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
1646 pll = 0x142c;
1647 }
1648 } else {
1649 pll |= SM(0x2c, AR_RTC_PLL_DIV);
1650 }
1651
1652 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
1653 }
1654
1655 /* TODO:
1656 * For multi-band owl, switch between bands by reiniting the PLL.
1657 */
1658 OS_DELAY(RTC_PLL_SETTLE_DELAY);
1659
1660 OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK,
1661 AR_RTC_FORCE_DERIVED_CLK | AR_RTC_PCIE_RST_PWDN_EN);
1662
1663 /* XXX TODO: honeybee? */
1664 if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
1665 if (clk_25mhz) {
1666 OS_REG_WRITE(ah,
1667 AR_RTC_DERIVED_RTC_CLK, (0x17c << 1)); /* 32KHz sleep clk */
1668 OS_REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
1669 OS_REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
1670 } else {
1671 OS_REG_WRITE(ah,
1672 AR_RTC_DERIVED_RTC_CLK, (0x261 << 1)); /* 32KHz sleep clk */
1673 OS_REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
1674 OS_REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
1675 }
1676 OS_DELAY(100);
1677 }
1678 }
1679
1680 static inline HAL_BOOL
ar9300_set_reset(struct ath_hal * ah,int type)1681 ar9300_set_reset(struct ath_hal *ah, int type)
1682 {
1683 u_int32_t rst_flags;
1684 u_int32_t tmp_reg;
1685 struct ath_hal_9300 *ahp = AH9300(ah);
1686
1687 HALASSERT(type == HAL_RESET_WARM || type == HAL_RESET_COLD);
1688
1689 /*
1690 * RTC Force wake should be done before resetting the MAC.
1691 * MDK/ART does it that way.
1692 */
1693 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1694 OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1695 OS_REG_WRITE(ah,
1696 AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1697
1698 /* Reset AHB */
1699 /* Bug26871 */
1700 tmp_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE));
1701 if (AR_SREV_WASP(ah)) {
1702 if (tmp_reg & (AR9340_INTR_SYNC_LOCAL_TIMEOUT)) {
1703 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0);
1704 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF);
1705 }
1706 } else {
1707 if (tmp_reg & (AR9300_INTR_SYNC_LOCAL_TIMEOUT | AR9300_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1708 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0);
1709 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF);
1710 }
1711 else {
1712 /* NO AR_RC_AHB in Osprey */
1713 /*OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_AHB);*/
1714 }
1715 }
1716
1717 rst_flags = AR_RTC_RC_MAC_WARM;
1718 if (type == HAL_RESET_COLD) {
1719 rst_flags |= AR_RTC_RC_MAC_COLD;
1720 }
1721
1722 #ifdef AH_SUPPORT_HORNET
1723 /* Hornet WAR: trigger SoC to reset WMAC if ...
1724 * (1) doing cold reset. Ref: EV 69254
1725 * (2) beacon pending. Ref: EV 70983
1726 */
1727 if (AR_SREV_HORNET(ah) &&
1728 (ar9300_num_tx_pending(
1729 ah, AH_PRIVATE(ah)->ah_caps.halTotalQueues - 1) != 0 ||
1730 type == HAL_RESET_COLD))
1731 {
1732 u_int32_t time_out;
1733 #define AR_SOC_RST_RESET 0xB806001C
1734 #define AR_SOC_BOOT_STRAP 0xB80600AC
1735 #define AR_SOC_WLAN_RST 0x00000800 /* WLAN reset */
1736 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
1737 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
1738 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Hornet SoC reset WMAC.\n", __func__);
1739
1740 REG_WRITE(AR_SOC_RST_RESET,
1741 REG_READ(AR_SOC_RST_RESET) | AR_SOC_WLAN_RST);
1742 REG_WRITE(AR_SOC_RST_RESET,
1743 REG_READ(AR_SOC_RST_RESET) & (~AR_SOC_WLAN_RST));
1744
1745 time_out = 0;
1746
1747 while (1) {
1748 tmp_reg = REG_READ(AR_SOC_BOOT_STRAP);
1749 if ((tmp_reg & 0x10) == 0) {
1750 break;
1751 }
1752 if (time_out > 20) {
1753 break;
1754 }
1755 OS_DELAY(10000);
1756 time_out++;
1757 }
1758
1759 OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1760 #undef REG_READ
1761 #undef REG_WRITE
1762 #undef AR_SOC_WLAN_RST
1763 #undef AR_SOC_RST_RESET
1764 #undef AR_SOC_BOOT_STRAP
1765 }
1766 #endif /* AH_SUPPORT_HORNET */
1767
1768 #ifdef AH_SUPPORT_SCORPION
1769 if (AR_SREV_SCORPION(ah)) {
1770 #define DDR_CTL_CONFIG_ADDRESS 0xb8000000
1771 #define DDR_CTL_CONFIG_OFFSET 0x0108
1772 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_MSB 29
1773 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB 21
1774 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK 0x3fe00000
1775 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_GET(x) (((x) & DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK) >> DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB)
1776 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_SET(x) (((x) << DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB) & DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK)
1777 #define MAC_DMA_CFG_ADDRESS 0xb8100000
1778 #define MAC_DMA_CFG_OFFSET 0x0014
1779
1780 #define MAC_DMA_CFG_HALT_REQ_MSB 11
1781 #define MAC_DMA_CFG_HALT_REQ_LSB 11
1782 #define MAC_DMA_CFG_HALT_REQ_MASK 0x00000800
1783 #define MAC_DMA_CFG_HALT_REQ_GET(x) (((x) & MAC_DMA_CFG_HALT_REQ_MASK) >> MAC_DMA_CFG_HALT_REQ_LSB)
1784 #define MAC_DMA_CFG_HALT_REQ_SET(x) (((x) << MAC_DMA_CFG_HALT_REQ_LSB) & MAC_DMA_CFG_HALT_REQ_MASK)
1785 #define MAC_DMA_CFG_HALT_ACK_MSB 12
1786 #define MAC_DMA_CFG_HALT_ACK_LSB 12
1787 #define MAC_DMA_CFG_HALT_ACK_MASK 0x00001000
1788 #define MAC_DMA_CFG_HALT_ACK_GET(x) (((x) & MAC_DMA_CFG_HALT_ACK_MASK) >> MAC_DMA_CFG_HALT_ACK_LSB)
1789 #define MAC_DMA_CFG_HALT_ACK_SET(x) (((x) << MAC_DMA_CFG_HALT_ACK_LSB) & MAC_DMA_CFG_HALT_ACK_MASK)
1790
1791 #define RST_RESET 0xB806001c
1792 #define RTC_RESET (1<<27)
1793
1794 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
1795 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
1796
1797 #define DDR_REG_READ(_ah, _reg) \
1798 *((volatile u_int32_t *)( DDR_CTL_CONFIG_ADDRESS + (_reg)))
1799 #define DDR_REG_WRITE(_ah, _reg, _val) \
1800 *((volatile u_int32_t *)(DDR_CTL_CONFIG_ADDRESS + (_reg))) = (_val)
1801
1802 OS_REG_WRITE(ah,MAC_DMA_CFG_OFFSET, (OS_REG_READ(ah,MAC_DMA_CFG_OFFSET) & ~MAC_DMA_CFG_HALT_REQ_MASK) |
1803 MAC_DMA_CFG_HALT_REQ_SET(1));
1804
1805 {
1806 int count;
1807 u_int32_t data;
1808
1809 count = 0;
1810 while (!MAC_DMA_CFG_HALT_ACK_GET(OS_REG_READ(ah, MAC_DMA_CFG_OFFSET) ))
1811 {
1812 count++;
1813 if (count > 10) {
1814 ath_hal_printf(ah, "Halt ACK timeout\n");
1815 break;
1816 }
1817 OS_DELAY(10);
1818 }
1819
1820 data = DDR_REG_READ(ah,DDR_CTL_CONFIG_OFFSET);
1821 HALDEBUG(ah, HAL_DEBUG_RESET, "check DDR Activity - HIGH\n");
1822
1823 count = 0;
1824 while (DDR_CTL_CONFIG_CLIENT_ACTIVITY_GET(data)) {
1825 // AVE_DEBUG(0,"DDR Activity - HIGH\n");
1826 HALDEBUG(ah, HAL_DEBUG_RESET, "DDR Activity - HIGH\n");
1827 count++;
1828 OS_DELAY(10);
1829 data = DDR_REG_READ(ah,DDR_CTL_CONFIG_OFFSET);
1830 if (count > 10) {
1831 ath_hal_printf(ah, "DDR Activity timeout\n");
1832 break;
1833 }
1834 }
1835 }
1836
1837
1838 {
1839 //Force RTC reset
1840 REG_WRITE(RST_RESET, (REG_READ(RST_RESET) | RTC_RESET));
1841 OS_DELAY(10);
1842 REG_WRITE(RST_RESET, (REG_READ(RST_RESET) & ~RTC_RESET));
1843 OS_DELAY(10);
1844 OS_REG_WRITE(ah, AR_RTC_RESET, 0);
1845 OS_DELAY(10);
1846 OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1847 OS_DELAY(10);
1848 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Scorpion SoC RTC reset done.\n", __func__);
1849 }
1850 #undef REG_READ
1851 #undef REG_WRITE
1852 }
1853 #endif /* AH_SUPPORT_SCORPION */
1854
1855 /*
1856 * Set Mac(BB,Phy) Warm Reset
1857 */
1858 OS_REG_WRITE(ah, AR_RTC_RC, rst_flags);
1859
1860 OS_DELAY(50); /* XXX 50 usec */
1861
1862 /*
1863 * Clear resets and force wakeup
1864 */
1865 OS_REG_WRITE(ah, AR_RTC_RC, 0);
1866 if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) {
1867 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1868 "%s: RTC stuck in MAC reset\n", __FUNCTION__);
1869 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1870 "%s: AR_RTC_RC = 0x%x\n", __func__, OS_REG_READ(ah, AR_RTC_RC));
1871 return AH_FALSE;
1872 }
1873
1874 /* Clear AHB reset */
1875 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), 0);
1876 ar9300_disable_pll_lock_detect(ah);
1877
1878 ar9300_attach_hw_platform(ah);
1879
1880 ahp->ah_chip_reset_done = 1;
1881 return AH_TRUE;
1882 }
1883
1884 static inline HAL_BOOL
ar9300_set_reset_power_on(struct ath_hal * ah)1885 ar9300_set_reset_power_on(struct ath_hal *ah)
1886 {
1887 /* Force wake */
1888 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1889 OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1890 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1891 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1892 /*
1893 * RTC reset and clear. Some delay in between is needed
1894 * to give the chip time to settle.
1895 */
1896 OS_REG_WRITE(ah, AR_RTC_RESET, 0);
1897 OS_DELAY(2);
1898 OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1899
1900 /*
1901 * Poll till RTC is ON
1902 */
1903 if (!ath_hal_wait(ah,
1904 AR_RTC_STATUS, AR_RTC_STATUS_M,
1905 AR_RTC_STATUS_ON))
1906 {
1907 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1908 "%s: RTC not waking up for %d\n", __FUNCTION__, 1000);
1909 return AH_FALSE;
1910 }
1911
1912 /*
1913 * Read Revisions from Chip right after RTC is on for the first time.
1914 * This helps us detect the chip type early and initialize it accordingly.
1915 */
1916 ar9300_read_revisions(ah);
1917
1918 /*
1919 * Warm reset if we aren't really powering on,
1920 * just restarting the driver.
1921 */
1922 return ar9300_set_reset(ah, HAL_RESET_WARM);
1923 }
1924
1925 /*
1926 * Write the given reset bit mask into the reset register
1927 */
1928 HAL_BOOL
ar9300_set_reset_reg(struct ath_hal * ah,u_int32_t type)1929 ar9300_set_reset_reg(struct ath_hal *ah, u_int32_t type)
1930 {
1931 HAL_BOOL ret = AH_FALSE;
1932
1933 /*
1934 * Set force wake
1935 */
1936 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1937 OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1938 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1939 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1940
1941 switch (type) {
1942 case HAL_RESET_POWER_ON:
1943 ret = ar9300_set_reset_power_on(ah);
1944 break;
1945 case HAL_RESET_WARM:
1946 case HAL_RESET_COLD:
1947 ret = ar9300_set_reset(ah, type);
1948 break;
1949 default:
1950 break;
1951 }
1952
1953 #if ATH_SUPPORT_MCI
1954 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
1955 OS_REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
1956 }
1957 #endif
1958
1959 return ret;
1960 }
1961
1962 /*
1963 * Places the PHY and Radio chips into reset. A full reset
1964 * must be called to leave this state. The PCI/MAC/PCU are
1965 * not placed into reset as we must receive interrupt to
1966 * re-enable the hardware.
1967 */
1968 HAL_BOOL
ar9300_phy_disable(struct ath_hal * ah)1969 ar9300_phy_disable(struct ath_hal *ah)
1970 {
1971 if (!ar9300_set_reset_reg(ah, HAL_RESET_WARM)) {
1972 return AH_FALSE;
1973 }
1974
1975 #ifdef ATH_SUPPORT_LED
1976 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
1977 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
1978 #define ATH_GPIO_OE 0xB8040000
1979 #define ATH_GPIO_OUT 0xB8040008 /* GPIO Ouput Value reg.*/
1980 if (AR_SREV_WASP(ah)) {
1981 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
1982 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 13)));
1983 }
1984 else {
1985 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12)));
1986 }
1987 }
1988 else if (AR_SREV_SCORPION(ah)) {
1989 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
1990 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 13)));
1991 }
1992 else {
1993 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12)));
1994 }
1995 /* Turn off JMPST led */
1996 REG_WRITE(ATH_GPIO_OUT, (REG_READ(ATH_GPIO_OUT) | (0x1 << 15)));
1997 }
1998 else if (AR_SREV_HONEYBEE(ah)) {
1999 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12)));
2000 }
2001 #undef REG_READ
2002 #undef REG_WRITE
2003 #endif
2004
2005 if ( AR_SREV_OSPREY(ah) ) {
2006 OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1), 0x0, 0x1f);
2007 }
2008
2009
2010 ar9300_init_pll(ah, AH_NULL);
2011 ar9300_disable_pll_lock_detect(ah);
2012
2013 return AH_TRUE;
2014 }
2015
2016 /*
2017 * Places all of hardware into reset
2018 */
2019 HAL_BOOL
ar9300_disable(struct ath_hal * ah)2020 ar9300_disable(struct ath_hal *ah)
2021 {
2022 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
2023 return AH_FALSE;
2024 }
2025 if (!ar9300_set_reset_reg(ah, HAL_RESET_COLD)) {
2026 return AH_FALSE;
2027 }
2028
2029 ar9300_init_pll(ah, AH_NULL);
2030
2031 return AH_TRUE;
2032 }
2033
2034 /*
2035 * TODO: Only write the PLL if we're changing to or from CCK mode
2036 *
2037 * WARNING: The order of the PLL and mode registers must be correct.
2038 */
2039 static inline void
ar9300_set_rf_mode(struct ath_hal * ah,struct ieee80211_channel * chan)2040 ar9300_set_rf_mode(struct ath_hal *ah, struct ieee80211_channel *chan)
2041 {
2042 u_int32_t rf_mode = 0;
2043
2044 if (chan == AH_NULL) {
2045 return;
2046 }
2047 switch (AH9300(ah)->ah_hwp) {
2048 case HAL_TRUE_CHIP:
2049 rf_mode |= (IEEE80211_IS_CHAN_B(chan) || IEEE80211_IS_CHAN_G(chan)) ?
2050 AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
2051 break;
2052 default:
2053 HALASSERT(0);
2054 break;
2055 }
2056 /* Phy mode bits for 5GHz channels requiring Fast Clock */
2057 if ( IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
2058 rf_mode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
2059 }
2060 OS_REG_WRITE(ah, AR_PHY_MODE, rf_mode);
2061 }
2062
2063 /*
2064 * Places the hardware into reset and then pulls it out of reset
2065 */
2066 HAL_BOOL
ar9300_chip_reset(struct ath_hal * ah,struct ieee80211_channel * chan,HAL_RESET_TYPE reset_type)2067 ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_RESET_TYPE reset_type)
2068 {
2069 struct ath_hal_9300 *ahp = AH9300(ah);
2070 int type = HAL_RESET_WARM;
2071
2072 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
2073
2074 /*
2075 * Warm reset is optimistic.
2076 *
2077 * If the TX/RX DMA engines aren't shut down (eg, they're
2078 * wedged) then we're better off doing a full cold reset
2079 * to try and shake that condition.
2080 */
2081 if (ahp->ah_chip_full_sleep ||
2082 (ah->ah_config.ah_force_full_reset == 1) ||
2083 (reset_type == HAL_RESET_FORCE_COLD) ||
2084 (reset_type == HAL_RESET_BBPANIC) ||
2085 OS_REG_READ(ah, AR_Q_TXE) ||
2086 (OS_REG_READ(ah, AR_CR) & AR_CR_RXE)) {
2087 HALDEBUG(ah, HAL_DEBUG_RESET,
2088 "%s: full reset; reset_type=%d, full_sleep=%d\n",
2089 __func__, reset_type, ahp->ah_chip_full_sleep);
2090 type = HAL_RESET_COLD;
2091 }
2092
2093 if (!ar9300_set_reset_reg(ah, type)) {
2094 return AH_FALSE;
2095 }
2096
2097 /* Bring out of sleep mode (AGAIN) */
2098 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
2099 return AH_FALSE;
2100 }
2101
2102 ahp->ah_chip_full_sleep = AH_FALSE;
2103
2104 if (AR_SREV_HORNET(ah)) {
2105 ar9300_internal_regulator_apply(ah);
2106 }
2107
2108 ar9300_init_pll(ah, chan);
2109
2110 /*
2111 * Perform warm reset before the mode/PLL/turbo registers
2112 * are changed in order to deactivate the radio. Mode changes
2113 * with an active radio can result in corrupted shifts to the
2114 * radio device.
2115 */
2116 ar9300_set_rf_mode(ah, chan);
2117
2118 return AH_TRUE;
2119 }
2120
2121 /* ar9300_setup_calibration
2122 * Setup HW to collect samples used for current cal
2123 */
2124 inline static void
ar9300_setup_calibration(struct ath_hal * ah,HAL_CAL_LIST * curr_cal)2125 ar9300_setup_calibration(struct ath_hal *ah, HAL_CAL_LIST *curr_cal)
2126 {
2127 /* Select calibration to run */
2128 switch (curr_cal->cal_data->cal_type) {
2129 case IQ_MISMATCH_CAL:
2130 /* Start calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
2131 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4,
2132 AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
2133 curr_cal->cal_data->cal_count_max);
2134 OS_REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
2135
2136 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2137 "%s: starting IQ Mismatch Calibration\n", __func__);
2138
2139 /* Kick-off cal */
2140 OS_REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
2141
2142 break;
2143 case TEMP_COMP_CAL:
2144 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
2145 AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
2146 OS_REG_RMW_FIELD(ah,
2147 AR_HORNET_CH0_THERM, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2148 OS_REG_RMW_FIELD(ah,
2149 AR_HORNET_CH0_THERM, AR_PHY_65NM_CH0_THERM_START, 1);
2150 } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
2151 OS_REG_RMW_FIELD(ah,
2152 AR_PHY_65NM_CH0_THERM_JUPITER, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2153 OS_REG_RMW_FIELD(ah,
2154 AR_PHY_65NM_CH0_THERM_JUPITER, AR_PHY_65NM_CH0_THERM_START, 1);
2155 } else {
2156 OS_REG_RMW_FIELD(ah,
2157 AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2158 OS_REG_RMW_FIELD(ah,
2159 AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_START, 1);
2160 }
2161
2162 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2163 "%s: starting Temperature Compensation Calibration\n", __func__);
2164 break;
2165 default:
2166 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
2167 "%s called with incorrect calibration type.\n", __func__);
2168 }
2169 }
2170
2171 /* ar9300_reset_calibration
2172 * Initialize shared data structures and prepare a cal to be run.
2173 */
2174 inline static void
ar9300_reset_calibration(struct ath_hal * ah,HAL_CAL_LIST * curr_cal)2175 ar9300_reset_calibration(struct ath_hal *ah, HAL_CAL_LIST *curr_cal)
2176 {
2177 struct ath_hal_9300 *ahp = AH9300(ah);
2178 int i;
2179
2180 /* Setup HW for new calibration */
2181 ar9300_setup_calibration(ah, curr_cal);
2182
2183 /* Change SW state to RUNNING for this calibration */
2184 curr_cal->cal_state = CAL_RUNNING;
2185
2186 /* Reset data structures shared between different calibrations */
2187 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
2188 ahp->ah_meas0.sign[i] = 0;
2189 ahp->ah_meas1.sign[i] = 0;
2190 ahp->ah_meas2.sign[i] = 0;
2191 ahp->ah_meas3.sign[i] = 0;
2192 }
2193
2194 ahp->ah_cal_samples = 0;
2195 }
2196
2197 #ifdef XXX_UNUSED_FUNCTION
2198 /*
2199 * Find out which of the RX chains are enabled
2200 */
2201 static u_int32_t
ar9300_get_rx_chain_mask(struct ath_hal * ah)2202 ar9300_get_rx_chain_mask(struct ath_hal *ah)
2203 {
2204 u_int32_t ret_val = OS_REG_READ(ah, AR_PHY_RX_CHAINMASK);
2205 /* The bits [2:0] indicate the rx chain mask and are to be
2206 * interpreted as follows:
2207 * 00x => Only chain 0 is enabled
2208 * 01x => Chain 1 and 0 enabled
2209 * 1xx => Chain 2,1 and 0 enabled
2210 */
2211 return (ret_val & 0x7);
2212 }
2213 #endif
2214
2215 static void
ar9300_get_nf_hist_base(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * chan,int is_scan,int16_t nf[])2216 ar9300_get_nf_hist_base(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
2217 int is_scan, int16_t nf[])
2218 {
2219 HAL_NFCAL_BASE *h_base;
2220
2221 #ifdef ATH_NF_PER_CHAN
2222 h_base = &chan->nf_cal_hist.base;
2223 #else
2224 if (is_scan) {
2225 /*
2226 * The channel we are currently on is not the home channel,
2227 * so we shouldn't use the home channel NF buffer's values on
2228 * this channel. Instead, use the NF single value already
2229 * read for this channel. (Or, if we haven't read the NF for
2230 * this channel yet, the SW default for this chip/band will
2231 * be used.)
2232 */
2233 h_base = &chan->nf_cal_hist.base;
2234 } else {
2235 /* use the home channel NF info */
2236 h_base = &AH_PRIVATE(ah)->nf_cal_hist.base;
2237 }
2238 #endif
2239 OS_MEMCPY(nf, h_base->priv_nf, sizeof(h_base->priv_nf));
2240 }
2241
2242 HAL_BOOL
ar9300_load_nf(struct ath_hal * ah,int16_t nf[])2243 ar9300_load_nf(struct ath_hal *ah, int16_t nf[])
2244 {
2245 int i, j;
2246 int32_t val;
2247 /* XXX where are EXT regs defined */
2248 const u_int32_t ar9300_cca_regs[] = {
2249 AR_PHY_CCA_0,
2250 AR_PHY_CCA_1,
2251 AR_PHY_CCA_2,
2252 AR_PHY_EXT_CCA,
2253 AR_PHY_EXT_CCA_1,
2254 AR_PHY_EXT_CCA_2,
2255 };
2256 u_int8_t chainmask;
2257
2258 /*
2259 * Force NF calibration for all chains, otherwise Vista station
2260 * would conduct a bad performance
2261 */
2262 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
2263 chainmask = 0x9;
2264 } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_HONEYBEE(ah)) {
2265 chainmask = 0x1b;
2266 } else {
2267 chainmask = 0x3F;
2268 }
2269
2270 /*
2271 * Write filtered NF values into max_cca_pwr register parameter
2272 * so we can load below.
2273 */
2274 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
2275 if (chainmask & (1 << i)) {
2276 val = OS_REG_READ(ah, ar9300_cca_regs[i]);
2277 val &= 0xFFFFFE00;
2278 val |= (((u_int32_t)(nf[i]) << 1) & 0x1ff);
2279 OS_REG_WRITE(ah, ar9300_cca_regs[i], val);
2280 }
2281 }
2282
2283 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%s: load %d %d %d %d %d %d\n",
2284 __func__,
2285 nf[0], nf[1], nf[2],
2286 nf[3], nf[4], nf[5]);
2287
2288 /*
2289 * Load software filtered NF value into baseband internal min_cca_pwr
2290 * variable.
2291 */
2292 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
2293 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
2294 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
2295
2296 /* Wait for load to complete, should be fast, a few 10s of us. */
2297 /* Changed the max delay 250us back to 10000us, since 250us often
2298 * results in NF load timeout and causes deaf condition
2299 * during stress testing 12/12/2009
2300 */
2301 for (j = 0; j < 10000; j++) {
2302 if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){
2303 break;
2304 }
2305 OS_DELAY(10);
2306 }
2307 if (j == 10000) {
2308 /*
2309 * We timed out waiting for the noisefloor to load, probably
2310 * due to an in-progress rx. Simply return here and allow
2311 * the load plenty of time to complete before the next
2312 * calibration interval. We need to avoid trying to load -50
2313 * (which happens below) while the previous load is still in
2314 * progress as this can cause rx deafness (see EV 66368,62830).
2315 * Instead by returning here, the baseband nf cal will
2316 * just be capped by our present noisefloor until the next
2317 * calibration timer.
2318 */
2319 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,
2320 "%s: *** TIMEOUT while waiting for nf to load: "
2321 "AR_PHY_AGC_CONTROL=0x%x ***\n",
2322 __func__, OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
2323 return AH_FALSE;
2324 }
2325
2326 /*
2327 * Restore max_cca_power register parameter again so that we're not capped
2328 * by the median we just loaded. This will be initial (and max) value
2329 * of next noise floor calibration the baseband does.
2330 */
2331 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
2332 if (chainmask & (1 << i)) {
2333 val = OS_REG_READ(ah, ar9300_cca_regs[i]);
2334 val &= 0xFFFFFE00;
2335 val |= (((u_int32_t)(-50) << 1) & 0x1ff);
2336 OS_REG_WRITE(ah, ar9300_cca_regs[i], val);
2337 }
2338 }
2339 return AH_TRUE;
2340 }
2341
2342 /* ar9300_per_calibration
2343 * Generic calibration routine.
2344 * Recalibrate the lower PHY chips to account for temperature/environment
2345 * changes.
2346 */
2347 inline static void
ar9300_per_calibration(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan,u_int8_t rxchainmask,HAL_CAL_LIST * curr_cal,HAL_BOOL * is_cal_done)2348 ar9300_per_calibration(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
2349 u_int8_t rxchainmask, HAL_CAL_LIST *curr_cal, HAL_BOOL *is_cal_done)
2350 {
2351 struct ath_hal_9300 *ahp = AH9300(ah);
2352
2353 /* Cal is assumed not done until explicitly set below */
2354 *is_cal_done = AH_FALSE;
2355
2356 /* Calibration in progress. */
2357 if (curr_cal->cal_state == CAL_RUNNING) {
2358 /* Check to see if it has finished. */
2359 if (!(OS_REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) {
2360 int i, num_chains = 0;
2361 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
2362 if (rxchainmask & (1 << i)) {
2363 num_chains++;
2364 }
2365 }
2366
2367 /*
2368 * Accumulate cal measures for active chains
2369 */
2370 curr_cal->cal_data->cal_collect(ah, num_chains);
2371
2372 ahp->ah_cal_samples++;
2373
2374 if (ahp->ah_cal_samples >= curr_cal->cal_data->cal_num_samples) {
2375 /*
2376 * Process accumulated data
2377 */
2378 curr_cal->cal_data->cal_post_proc(ah, num_chains);
2379
2380 /* Calibration has finished. */
2381 ichan->calValid |= curr_cal->cal_data->cal_type;
2382 curr_cal->cal_state = CAL_DONE;
2383 *is_cal_done = AH_TRUE;
2384 } else {
2385 /* Set-up collection of another sub-sample until we
2386 * get desired number
2387 */
2388 ar9300_setup_calibration(ah, curr_cal);
2389 }
2390 }
2391 } else if (!(ichan->calValid & curr_cal->cal_data->cal_type)) {
2392 /* If current cal is marked invalid in channel, kick it off */
2393 ar9300_reset_calibration(ah, curr_cal);
2394 }
2395 }
2396
2397 static void
ar9300_start_nf_cal(struct ath_hal * ah)2398 ar9300_start_nf_cal(struct ath_hal *ah)
2399 {
2400 struct ath_hal_9300 *ahp = AH9300(ah);
2401 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
2402 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
2403 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
2404 AH9300(ah)->nf_tsf32 = ar9300_get_tsf32(ah);
2405
2406 /*
2407 * We are reading the NF values before we start the NF operation, because
2408 * of that we are getting very high values like -45.
2409 * This triggers the CW_INT detected and EACS module triggers the channel change
2410 * chip_reset_done value is used to fix this issue.
2411 * chip_reset_flag is set during the RTC reset.
2412 * chip_reset_flag is cleared during the starting NF operation.
2413 * if flag is set we will clear the flag and will not read the NF values.
2414 */
2415 ahp->ah_chip_reset_done = 0;
2416 }
2417
2418 /* ar9300_calibration
2419 * Wrapper for a more generic Calibration routine. Primarily to abstract to
2420 * upper layers whether there is 1 or more calibrations to be run.
2421 */
2422 HAL_BOOL
ar9300_calibration(struct ath_hal * ah,struct ieee80211_channel * chan,u_int8_t rxchainmask,HAL_BOOL do_nf_cal,HAL_BOOL * is_cal_done,int is_scan,u_int32_t * sched_cals)2423 ar9300_calibration(struct ath_hal *ah, struct ieee80211_channel *chan, u_int8_t rxchainmask,
2424 HAL_BOOL do_nf_cal, HAL_BOOL *is_cal_done, int is_scan,
2425 u_int32_t *sched_cals)
2426 {
2427 struct ath_hal_9300 *ahp = AH9300(ah);
2428 HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr;
2429 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2430 int16_t nf_buf[HAL_NUM_NF_READINGS];
2431
2432 *is_cal_done = AH_TRUE;
2433
2434
2435 /* XXX: For initial wasp bringup - disable periodic calibration */
2436 /* Invalid channel check */
2437 if (ichan == AH_NULL) {
2438 HALDEBUG(ah, HAL_DEBUG_CHANNEL,
2439 "%s: invalid channel %u/0x%x; no mapping\n",
2440 __func__, chan->ic_freq, chan->ic_flags);
2441 return AH_FALSE;
2442 }
2443
2444 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2445 "%s: Entering, Doing NF Cal = %d\n", __func__, do_nf_cal);
2446 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Chain 0 Rx IQ Cal Correction 0x%08x\n",
2447 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
2448 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah) && !AR_SREV_APHRODITE(ah)) {
2449 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2450 "%s: Chain 1 Rx IQ Cal Correction 0x%08x\n",
2451 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B1));
2452 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah)) {
2453 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2454 "%s: Chain 2 Rx IQ Cal Correction 0x%08x\n",
2455 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B2));
2456 }
2457 }
2458
2459 OS_MARK(ah, AH_MARK_PERCAL, chan->ic_freq);
2460
2461 /* For given calibration:
2462 * 1. Call generic cal routine
2463 * 2. When this cal is done (is_cal_done) if we have more cals waiting
2464 * (eg after reset), mask this to upper layers by not propagating
2465 * is_cal_done if it is set to TRUE.
2466 * Instead, change is_cal_done to FALSE and setup the waiting cal(s)
2467 * to be run.
2468 */
2469 if (curr_cal && (curr_cal->cal_data->cal_type & *sched_cals) &&
2470 (curr_cal->cal_state == CAL_RUNNING ||
2471 curr_cal->cal_state == CAL_WAITING))
2472 {
2473 ar9300_per_calibration(ah, ichan, rxchainmask, curr_cal, is_cal_done);
2474
2475 if (*is_cal_done == AH_TRUE) {
2476 ahp->ah_cal_list_curr = curr_cal = curr_cal->cal_next;
2477
2478 if (curr_cal && curr_cal->cal_state == CAL_WAITING) {
2479 *is_cal_done = AH_FALSE;
2480 ar9300_reset_calibration(ah, curr_cal);
2481 } else {
2482 *sched_cals &= ~IQ_MISMATCH_CAL;
2483 }
2484 }
2485 }
2486
2487 /* Do NF cal only at longer intervals */
2488 if (do_nf_cal) {
2489 int nf_done;
2490
2491 /* Get the value from the previous NF cal and update history buffer */
2492 nf_done = ar9300_store_new_nf(ah, chan, is_scan);
2493 #if 0
2494 if (ichan->channel_flags & CHANNEL_CW_INT) {
2495 chan->channel_flags |= CHANNEL_CW_INT;
2496 }
2497 #endif
2498 chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
2499
2500 if (nf_done) {
2501 int ret;
2502 /*
2503 * Load the NF from history buffer of the current channel.
2504 * NF is slow time-variant, so it is OK to use a historical value.
2505 */
2506 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
2507
2508 ret = ar9300_load_nf(ah, nf_buf);
2509 /* start NF calibration, without updating BB NF register*/
2510 ar9300_start_nf_cal(ah);
2511
2512 /*
2513 * If we failed the NF cal then tell the upper layer that we
2514 * failed so we can do a full reset
2515 */
2516 if (! ret)
2517 return AH_FALSE;
2518 }
2519 }
2520 return AH_TRUE;
2521 }
2522
2523 /* ar9300_iq_cal_collect
2524 * Collect data from HW to later perform IQ Mismatch Calibration
2525 */
2526 void
ar9300_iq_cal_collect(struct ath_hal * ah,u_int8_t num_chains)2527 ar9300_iq_cal_collect(struct ath_hal *ah, u_int8_t num_chains)
2528 {
2529 struct ath_hal_9300 *ahp = AH9300(ah);
2530 int i;
2531
2532 /*
2533 * Accumulate IQ cal measures for active chains
2534 */
2535 for (i = 0; i < num_chains; i++) {
2536 ahp->ah_total_power_meas_i[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
2537 ahp->ah_total_power_meas_q[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
2538 ahp->ah_total_iq_corr_meas[i] =
2539 (int32_t) OS_REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
2540 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2541 "%d: Chn %d "
2542 "Reg Offset(0x%04x)pmi=0x%08x; "
2543 "Reg Offset(0x%04x)pmq=0x%08x; "
2544 "Reg Offset (0x%04x)iqcm=0x%08x;\n",
2545 ahp->ah_cal_samples,
2546 i,
2547 (unsigned) AR_PHY_CAL_MEAS_0(i),
2548 ahp->ah_total_power_meas_i[i],
2549 (unsigned) AR_PHY_CAL_MEAS_1(i),
2550 ahp->ah_total_power_meas_q[i],
2551 (unsigned) AR_PHY_CAL_MEAS_2(i),
2552 ahp->ah_total_iq_corr_meas[i]);
2553 }
2554 }
2555
2556 /* ar9300_iq_calibration
2557 * Use HW data to perform IQ Mismatch Calibration
2558 */
2559 void
ar9300_iq_calibration(struct ath_hal * ah,u_int8_t num_chains)2560 ar9300_iq_calibration(struct ath_hal *ah, u_int8_t num_chains)
2561 {
2562 struct ath_hal_9300 *ahp = AH9300(ah);
2563 u_int32_t power_meas_q, power_meas_i, iq_corr_meas;
2564 u_int32_t q_coff_denom, i_coff_denom;
2565 int32_t q_coff, i_coff;
2566 int iq_corr_neg, i;
2567 HAL_CHANNEL_INTERNAL *ichan;
2568 static const u_int32_t offset_array[3] = {
2569 AR_PHY_RX_IQCAL_CORR_B0,
2570 AR_PHY_RX_IQCAL_CORR_B1,
2571 AR_PHY_RX_IQCAL_CORR_B2,
2572 };
2573
2574 ichan = ath_hal_checkchannel(ah, AH_PRIVATE(ah)->ah_curchan);
2575
2576 for (i = 0; i < num_chains; i++) {
2577 power_meas_i = ahp->ah_total_power_meas_i[i];
2578 power_meas_q = ahp->ah_total_power_meas_q[i];
2579 iq_corr_meas = ahp->ah_total_iq_corr_meas[i];
2580
2581 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2582 "Starting IQ Cal and Correction for Chain %d\n", i);
2583 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2584 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
2585 i, ahp->ah_total_iq_corr_meas[i]);
2586
2587 iq_corr_neg = 0;
2588
2589 /* iq_corr_meas is always negative. */
2590 if (iq_corr_meas > 0x80000000) {
2591 iq_corr_meas = (0xffffffff - iq_corr_meas) + 1;
2592 iq_corr_neg = 1;
2593 }
2594
2595 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2596 "Chn %d pwr_meas_i = 0x%08x\n", i, power_meas_i);
2597 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2598 "Chn %d pwr_meas_q = 0x%08x\n", i, power_meas_q);
2599 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2600 "iq_corr_neg is 0x%08x\n", iq_corr_neg);
2601
2602 i_coff_denom = (power_meas_i / 2 + power_meas_q / 2) / 256;
2603 q_coff_denom = power_meas_q / 64;
2604
2605 /* Protect against divide-by-0 */
2606 if ((i_coff_denom != 0) && (q_coff_denom != 0)) {
2607 /* IQ corr_meas is already negated if iqcorr_neg == 1 */
2608 i_coff = iq_corr_meas / i_coff_denom;
2609 q_coff = power_meas_i / q_coff_denom - 64;
2610 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2611 "Chn %d i_coff = 0x%08x\n", i, i_coff);
2612 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2613 "Chn %d q_coff = 0x%08x\n", i, q_coff);
2614
2615 /* Force bounds on i_coff */
2616 if (i_coff >= 63) {
2617 i_coff = 63;
2618 } else if (i_coff <= -63) {
2619 i_coff = -63;
2620 }
2621
2622 /* Negate i_coff if iq_corr_neg == 0 */
2623 if (iq_corr_neg == 0x0) {
2624 i_coff = -i_coff;
2625 }
2626
2627 /* Force bounds on q_coff */
2628 if (q_coff >= 63) {
2629 q_coff = 63;
2630 } else if (q_coff <= -63) {
2631 q_coff = -63;
2632 }
2633
2634 i_coff = i_coff & 0x7f;
2635 q_coff = q_coff & 0x7f;
2636
2637 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2638 "Chn %d : i_coff = 0x%x q_coff = 0x%x\n", i, i_coff, q_coff);
2639 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2640 "Register offset (0x%04x) before update = 0x%x\n",
2641 offset_array[i], OS_REG_READ(ah, offset_array[i]));
2642
2643 OS_REG_RMW_FIELD(ah, offset_array[i],
2644 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, i_coff);
2645 OS_REG_RMW_FIELD(ah, offset_array[i],
2646 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, q_coff);
2647
2648 /* store the RX cal results */
2649 if (ichan != NULL) {
2650 ahp->ah_rx_cal_corr[i] = OS_REG_READ(ah, offset_array[i]) & 0x7fff;
2651 ahp->ah_rx_cal_complete = AH_TRUE;
2652 ahp->ah_rx_cal_chan = ichan->channel;
2653 // ahp->ah_rx_cal_chan_flag = ichan->channel_flags &~ CHANNEL_PASSIVE;
2654 ahp->ah_rx_cal_chan_flag = 0; /* XXX */
2655 } else {
2656 /* XXX? Is this what I should do? */
2657 ahp->ah_rx_cal_complete = AH_FALSE;
2658
2659 }
2660
2661 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2662 "Register offset (0x%04x) QI COFF (bitfields 0x%08x) "
2663 "after update = 0x%x\n",
2664 offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
2665 OS_REG_READ(ah, offset_array[i]));
2666 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2667 "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) "
2668 "after update = 0x%x\n",
2669 offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
2670 OS_REG_READ(ah, offset_array[i]));
2671 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2672 "IQ Cal and Correction done for Chain %d\n", i);
2673 }
2674 }
2675
2676 OS_REG_SET_BIT(ah,
2677 AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
2678 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2679 "IQ Cal and Correction (offset 0x%04x) enabled "
2680 "(bit position 0x%08x). New Value 0x%08x\n",
2681 (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
2682 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
2683 OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
2684 }
2685
2686 /*
2687 * When coming back from offchan, we do not perform RX IQ Cal.
2688 * But the chip reset will clear all previous results
2689 * We store the previous results and restore here.
2690 */
2691 static void
ar9300_rx_iq_cal_restore(struct ath_hal * ah)2692 ar9300_rx_iq_cal_restore(struct ath_hal *ah)
2693 {
2694 struct ath_hal_9300 *ahp = AH9300(ah);
2695 u_int32_t i_coff, q_coff;
2696 HAL_BOOL is_restore = AH_FALSE;
2697 int i;
2698 static const u_int32_t offset_array[3] = {
2699 AR_PHY_RX_IQCAL_CORR_B0,
2700 AR_PHY_RX_IQCAL_CORR_B1,
2701 AR_PHY_RX_IQCAL_CORR_B2,
2702 };
2703
2704 for (i=0; i<AR9300_MAX_CHAINS; i++) {
2705 if (ahp->ah_rx_cal_corr[i]) {
2706 i_coff = (ahp->ah_rx_cal_corr[i] &
2707 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF) >>
2708 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF_S;
2709 q_coff = (ahp->ah_rx_cal_corr[i] &
2710 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF) >>
2711 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF_S;
2712
2713 OS_REG_RMW_FIELD(ah, offset_array[i],
2714 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, i_coff);
2715 OS_REG_RMW_FIELD(ah, offset_array[i],
2716 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, q_coff);
2717
2718 is_restore = AH_TRUE;
2719 }
2720 }
2721
2722 if (is_restore)
2723 OS_REG_SET_BIT(ah,
2724 AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
2725
2726 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2727 "%s: IQ Cal and Correction (offset 0x%04x) enabled "
2728 "(bit position 0x%08x). New Value 0x%08x\n",
2729 __func__,
2730 (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
2731 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
2732 OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
2733 }
2734
2735 /*
2736 * Set a limit on the overall output power. Used for dynamic
2737 * transmit power control and the like.
2738 *
2739 * NB: limit is in units of 0.5 dbM.
2740 */
2741 HAL_BOOL
ar9300_set_tx_power_limit(struct ath_hal * ah,u_int32_t limit,u_int16_t extra_txpow,u_int16_t tpc_in_db)2742 ar9300_set_tx_power_limit(struct ath_hal *ah, u_int32_t limit,
2743 u_int16_t extra_txpow, u_int16_t tpc_in_db)
2744 {
2745 struct ath_hal_9300 *ahp = AH9300(ah);
2746 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
2747 const struct ieee80211_channel *chan = ahpriv->ah_curchan;
2748 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2749
2750 if (NULL == chan) {
2751 return AH_FALSE;
2752 }
2753
2754 ahpriv->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);
2755 ahpriv->ah_extraTxPow = extra_txpow;
2756
2757 if(chan == NULL) {
2758 return AH_FALSE;
2759 }
2760 if (ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan,
2761 ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
2762 ath_hal_get_twice_max_regpower(ahpriv, ichan, chan),
2763 AH_MIN(MAX_RATE_POWER, ahpriv->ah_powerLimit)) != HAL_OK)
2764 {
2765 return AH_FALSE;
2766 }
2767 return AH_TRUE;
2768 }
2769
2770 /*
2771 * Exported call to check for a recent gain reading and return
2772 * the current state of the thermal calibration gain engine.
2773 */
2774 HAL_RFGAIN
ar9300_get_rfgain(struct ath_hal * ah)2775 ar9300_get_rfgain(struct ath_hal *ah)
2776 {
2777 return HAL_RFGAIN_INACTIVE;
2778 }
2779
2780 #define HAL_GREEN_AP_RX_MASK 0x1
2781
2782 static inline void
ar9300_init_chain_masks(struct ath_hal * ah,int rx_chainmask,int tx_chainmask)2783 ar9300_init_chain_masks(struct ath_hal *ah, int rx_chainmask, int tx_chainmask)
2784 {
2785 if (AH9300(ah)->green_ap_ps_on) {
2786 rx_chainmask = HAL_GREEN_AP_RX_MASK;
2787 }
2788 if (rx_chainmask == 0x5) {
2789 OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
2790 }
2791 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
2792 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
2793
2794 /*
2795 * Adaptive Power Management:
2796 * Some 3 stream chips exceed the PCIe power requirements.
2797 * This workaround will reduce power consumption by using 2 tx chains
2798 * for 1 and 2 stream rates (5 GHz only).
2799 *
2800 * Set the self gen mask to 2 tx chains when APM is enabled.
2801 *
2802 */
2803 if (AH_PRIVATE(ah)->ah_caps.halApmEnable && (tx_chainmask == 0x7)) {
2804 OS_REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
2805 }
2806 else {
2807 OS_REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
2808 }
2809
2810 if (tx_chainmask == 0x5) {
2811 OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
2812 }
2813 }
2814
2815 /*
2816 * Override INI values with chip specific configuration.
2817 */
2818 static inline void
ar9300_override_ini(struct ath_hal * ah,struct ieee80211_channel * chan)2819 ar9300_override_ini(struct ath_hal *ah, struct ieee80211_channel *chan)
2820 {
2821 u_int32_t val;
2822 HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
2823
2824 /*
2825 * Set the RX_ABORT and RX_DIS and clear it only after
2826 * RXE is set for MAC. This prevents frames with
2827 * corrupted descriptor status.
2828 */
2829 OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
2830 /*
2831 * For Merlin and above, there is a new feature that allows Multicast
2832 * search based on both MAC Address and Key ID.
2833 * By default, this feature is enabled.
2834 * But since the driver is not using this feature, we switch it off;
2835 * otherwise multicast search based on MAC addr only will fail.
2836 */
2837 val = OS_REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE);
2838 OS_REG_WRITE(ah, AR_PCU_MISC_MODE2,
2839 val | AR_BUG_58603_FIX_ENABLE | AR_AGG_WEP_ENABLE);
2840
2841
2842 /* Osprey revision specific configuration */
2843
2844 /* Osprey 2.0+ - if SW RAC support is disabled, must also disable
2845 * the Osprey 2.0 hardware RAC fix.
2846 */
2847 if (p_cap->halIsrRacSupport == AH_FALSE) {
2848 OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_MISSING_TX_INTR_FIX_ENABLE);
2849 }
2850
2851 /* try to enable old pal if it is needed for h/w green tx */
2852 ar9300_hwgreentx_set_pal_spare(ah, 1);
2853 }
2854
2855 static inline void
ar9300_prog_ini(struct ath_hal * ah,struct ar9300_ini_array * ini_arr,int column)2856 ar9300_prog_ini(struct ath_hal *ah, struct ar9300_ini_array *ini_arr,
2857 int column)
2858 {
2859 int i, reg_writes = 0;
2860
2861 /* New INI format: Array may be undefined (pre, core, post arrays) */
2862 if (ini_arr->ia_array == NULL) {
2863 return;
2864 }
2865
2866 /*
2867 * New INI format: Pre, core, and post arrays for a given subsystem may be
2868 * modal (> 2 columns) or non-modal (2 columns).
2869 * Determine if the array is non-modal and force the column to 1.
2870 */
2871 if (column >= ini_arr->ia_columns) {
2872 column = 1;
2873 }
2874
2875 for (i = 0; i < ini_arr->ia_rows; i++) {
2876 u_int32_t reg = INI_RA(ini_arr, i, 0);
2877 u_int32_t val = INI_RA(ini_arr, i, column);
2878
2879 /*
2880 ** Determine if this is a shift register value
2881 ** (reg >= 0x16000 && reg < 0x17000 for Osprey) ,
2882 ** and insert the configured delay if so.
2883 ** -this delay is not required for Osprey (EV#71410)
2884 */
2885 OS_REG_WRITE(ah, reg, val);
2886 WAR_6773(reg_writes);
2887
2888 }
2889 }
2890
2891 static inline HAL_STATUS
ar9300_process_ini(struct ath_hal * ah,struct ieee80211_channel * chan,HAL_CHANNEL_INTERNAL * ichan,HAL_HT_MACMODE macmode)2892 ar9300_process_ini(struct ath_hal *ah, struct ieee80211_channel *chan,
2893 HAL_CHANNEL_INTERNAL *ichan, HAL_HT_MACMODE macmode)
2894 {
2895 int reg_writes = 0;
2896 struct ath_hal_9300 *ahp = AH9300(ah);
2897 u_int modes_index, modes_txgaintable_index = 0;
2898 int i;
2899 HAL_STATUS status;
2900 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
2901 /* Setup the indices for the next set of register array writes */
2902 /* TODO:
2903 * If the channel marker is indicative of the current mode rather
2904 * than capability, we do not need to check the phy mode below.
2905 */
2906 #if 0
2907 switch (chan->channel_flags & CHANNEL_ALL) {
2908 case CHANNEL_A:
2909 case CHANNEL_A_HT20:
2910 if (AR_SREV_SCORPION(ah)){
2911 if (chan->channel <= 5350){
2912 modes_txgaintable_index = 1;
2913 }else if ((chan->channel > 5350) && (chan->channel <= 5600)){
2914 modes_txgaintable_index = 3;
2915 }else if (chan->channel > 5600){
2916 modes_txgaintable_index = 5;
2917 }
2918 }
2919 modes_index = 1;
2920 freq_index = 1;
2921 break;
2922
2923 case CHANNEL_A_HT40PLUS:
2924 case CHANNEL_A_HT40MINUS:
2925 if (AR_SREV_SCORPION(ah)){
2926 if (chan->channel <= 5350){
2927 modes_txgaintable_index = 2;
2928 }else if ((chan->channel > 5350) && (chan->channel <= 5600)){
2929 modes_txgaintable_index = 4;
2930 }else if (chan->channel > 5600){
2931 modes_txgaintable_index = 6;
2932 }
2933 }
2934 modes_index = 2;
2935 freq_index = 1;
2936 break;
2937
2938 case CHANNEL_PUREG:
2939 case CHANNEL_G_HT20:
2940 case CHANNEL_B:
2941 if (AR_SREV_SCORPION(ah)){
2942 modes_txgaintable_index = 8;
2943 }else if (AR_SREV_HONEYBEE(ah)){
2944 modes_txgaintable_index = 1;
2945 }
2946 modes_index = 4;
2947 freq_index = 2;
2948 break;
2949
2950 case CHANNEL_G_HT40PLUS:
2951 case CHANNEL_G_HT40MINUS:
2952 if (AR_SREV_SCORPION(ah)){
2953 modes_txgaintable_index = 7;
2954 }else if (AR_SREV_HONEYBEE(ah)){
2955 modes_txgaintable_index = 1;
2956 }
2957 modes_index = 3;
2958 freq_index = 2;
2959 break;
2960
2961 case CHANNEL_108G:
2962 modes_index = 5;
2963 freq_index = 2;
2964 break;
2965
2966 default:
2967 HALASSERT(0);
2968 return HAL_EINVAL;
2969 }
2970 #endif
2971
2972 /* FreeBSD */
2973 if (IS_CHAN_5GHZ(ichan)) {
2974 if (IEEE80211_IS_CHAN_HT40U(chan) || IEEE80211_IS_CHAN_HT40D(chan)) {
2975 if (AR_SREV_SCORPION(ah)){
2976 if (ichan->channel <= 5350){
2977 modes_txgaintable_index = 2;
2978 }else if ((ichan->channel > 5350) && (ichan->channel <= 5600)){
2979 modes_txgaintable_index = 4;
2980 }else if (ichan->channel > 5600){
2981 modes_txgaintable_index = 6;
2982 }
2983 }
2984 modes_index = 2;
2985 } else if (IEEE80211_IS_CHAN_A(chan) || IEEE80211_IS_CHAN_HT20(chan)) {
2986 if (AR_SREV_SCORPION(ah)){
2987 if (ichan->channel <= 5350){
2988 modes_txgaintable_index = 1;
2989 }else if ((ichan->channel > 5350) && (ichan->channel <= 5600)){
2990 modes_txgaintable_index = 3;
2991 }else if (ichan->channel > 5600){
2992 modes_txgaintable_index = 5;
2993 }
2994 }
2995 modes_index = 1;
2996 } else
2997 return HAL_EINVAL;
2998 } else if (IS_CHAN_2GHZ(ichan)) {
2999 if (IEEE80211_IS_CHAN_108G(chan)) {
3000 modes_index = 5;
3001 } else if (IEEE80211_IS_CHAN_HT40U(chan) || IEEE80211_IS_CHAN_HT40D(chan)) {
3002 if (AR_SREV_SCORPION(ah)){
3003 modes_txgaintable_index = 7;
3004 } else if (AR_SREV_HONEYBEE(ah)){
3005 modes_txgaintable_index = 1;
3006 }
3007 modes_index = 3;
3008 } else if (IEEE80211_IS_CHAN_HT20(chan) || IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_B(chan) || IEEE80211_IS_CHAN_PUREG(chan)) {
3009 if (AR_SREV_SCORPION(ah)){
3010 modes_txgaintable_index = 8;
3011 } else if (AR_SREV_HONEYBEE(ah)){
3012 modes_txgaintable_index = 1;
3013 }
3014 modes_index = 4;
3015 } else
3016 return HAL_EINVAL;
3017 } else
3018 return HAL_EINVAL;
3019
3020 #if 0
3021 /* Set correct Baseband to analog shift setting to access analog chips. */
3022 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
3023 #endif
3024
3025 HALDEBUG(ah, HAL_DEBUG_RESET,
3026 "ar9300_process_ini: "
3027 "Skipping OS-REG-WRITE(ah, AR-PHY(0), 0x00000007)\n");
3028 HALDEBUG(ah, HAL_DEBUG_RESET,
3029 "ar9300_process_ini: no ADDac programming\n");
3030
3031
3032 /*
3033 * Osprey 2.0+ - new INI format.
3034 * Each subsystem has a pre, core, and post array.
3035 */
3036 for (i = 0; i < ATH_INI_NUM_SPLIT; i++) {
3037 ar9300_prog_ini(ah, &ahp->ah_ini_soc[i], modes_index);
3038 ar9300_prog_ini(ah, &ahp->ah_ini_mac[i], modes_index);
3039 ar9300_prog_ini(ah, &ahp->ah_ini_bb[i], modes_index);
3040 ar9300_prog_ini(ah, &ahp->ah_ini_radio[i], modes_index);
3041 if ((i == ATH_INI_POST) && (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah))) {
3042 ar9300_prog_ini(ah, &ahp->ah_ini_radio_post_sys2ant, modes_index);
3043 }
3044
3045 }
3046
3047 if (!(AR_SREV_SOC(ah))) {
3048 /* Doubler issue : Some board doesn't work well with MCS15. Turn off doubler after freq locking is complete*/
3049 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
3050 OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3051 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
3052 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
3053
3054 OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3055 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
3056 OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3057 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
3058 OS_DELAY(200);
3059
3060 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
3061 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
3062 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
3063 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
3064 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
3065
3066 OS_DELAY(1);
3067
3068 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
3069 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
3070 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
3071 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
3072 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
3073
3074 OS_DELAY(200);
3075
3076 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_SYNTH12, OS_REG_READ(ah, AR_PHY_65NM_CH0_SYNTH12));
3077 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH12, AR_PHY_65NM_CH0_SYNTH12_VREFMUL3, 0xf);
3078 //OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_SYNTH12, 1<< 16); /* clr charge pump */
3079 //ath_hal_printf(ah, "%s[%d] ==== After reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_SYNTH12, OS_REG_READ(ah, AR_PHY_65NM_CH0_SYNTH12));
3080
3081 OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3082 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
3083 OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3084 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
3085 OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3086 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
3087 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
3088 }
3089
3090 /* Write rxgain Array Parameters */
3091 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain, 1, reg_writes);
3092 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain programming\n");
3093
3094 if (AR_SREV_JUPITER_20_OR_LATER(ah)) {
3095 /*
3096 * CUS217 mix LNA mode.
3097 */
3098 if (ar9300_rx_gain_index_get(ah) == 2) {
3099 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bb_core, 1, reg_writes);
3100 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bb_postamble,
3101 modes_index, reg_writes);
3102 }
3103
3104 /*
3105 * 5G-XLNA
3106 */
3107 if ((ar9300_rx_gain_index_get(ah) == 2) ||
3108 (ar9300_rx_gain_index_get(ah) == 3)) {
3109 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_xlna, modes_index,
3110 reg_writes);
3111 }
3112 }
3113
3114 if (AR_SREV_SCORPION(ah)) {
3115 /* Write rxgain bounds Array */
3116 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bounds, modes_index, reg_writes);
3117 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain table bounds programming\n");
3118 }
3119 /* UB124 xLNA settings */
3120 if (AR_SREV_WASP(ah) && ar9300_rx_gain_index_get(ah) == 2) {
3121 #define REG_WRITE(_reg,_val) *((volatile u_int32_t *)(_reg)) = (_val);
3122 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
3123 u_int32_t val;
3124 /* B8040000: bit[0]=0, bit[3]=0; */
3125 val = REG_READ(0xB8040000);
3126 val &= 0xfffffff6;
3127 REG_WRITE(0xB8040000, val);
3128 /* B804002c: bit[31:24]=0x2e; bit[7:0]=0x2f; */
3129 val = REG_READ(0xB804002c);
3130 val &= 0x00ffff00;
3131 val |= 0x2e00002f;
3132 REG_WRITE(0xB804002c, val);
3133 /* B804006c: bit[1]=1; */
3134 val = REG_READ(0xB804006c);
3135 val |= 0x2;
3136 REG_WRITE(0xB804006c, val);
3137 #undef REG_READ
3138 #undef REG_WRITE
3139 }
3140
3141
3142 /* Write txgain Array Parameters */
3143 if (AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) {
3144 REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_txgaintable_index,
3145 reg_writes);
3146 }else{
3147 REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_index, reg_writes);
3148 }
3149 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Tx Gain programming\n");
3150
3151
3152 /* For 5GHz channels requiring Fast Clock, apply different modal values */
3153 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
3154 HALDEBUG(ah, HAL_DEBUG_RESET,
3155 "%s: Fast clock enabled, use special ini values\n", __func__);
3156 REG_WRITE_ARRAY(&ahp->ah_ini_modes_additional, modes_index, reg_writes);
3157 }
3158
3159 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
3160 HALDEBUG(ah, HAL_DEBUG_RESET,
3161 "%s: use xtal ini for AH9300(ah)->clk_25mhz: %d\n",
3162 __func__, AH9300(ah)->clk_25mhz);
3163 REG_WRITE_ARRAY(
3164 &ahp->ah_ini_modes_additional, 1/*modes_index*/, reg_writes);
3165 }
3166
3167 if (AR_SREV_WASP(ah) && (AH9300(ah)->clk_25mhz == 0)) {
3168 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Apply 40MHz ini settings\n", __func__);
3169 REG_WRITE_ARRAY(
3170 &ahp->ah_ini_modes_additional_40mhz, 1/*modesIndex*/, reg_writes);
3171 }
3172
3173 /* Handle Japan Channel 14 channel spreading */
3174 if (2484 == ichan->channel) {
3175 ar9300_prog_ini(ah, &ahp->ah_ini_japan2484, 1);
3176 }
3177
3178 #if 0
3179 /* XXX TODO! */
3180 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {
3181 ar9300_prog_ini(ah, &ahp->ah_ini_BTCOEX_MAX_TXPWR, 1);
3182 }
3183 #endif
3184
3185 /* Override INI with chip specific configuration */
3186 ar9300_override_ini(ah, chan);
3187
3188 /* Setup 11n MAC/Phy mode registers */
3189 ar9300_set_11n_regs(ah, chan, macmode);
3190
3191 /*
3192 * Moved ar9300_init_chain_masks() here to ensure the swap bit is set before
3193 * the pdadc table is written. Swap must occur before any radio dependent
3194 * replicated register access. The pdadc curve addressing in particular
3195 * depends on the consistent setting of the swap bit.
3196 */
3197 ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
3198
3199 /*
3200 * Setup the transmit power values.
3201 *
3202 * After the public to private hal channel mapping, ichan contains the
3203 * valid regulatory power value.
3204 * ath_hal_getctl and ath_hal_getantennaallowed look up ichan from chan.
3205 */
3206 status = ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan,
3207 ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
3208 ath_hal_get_twice_max_regpower(ahpriv, ichan, chan),
3209 AH_MIN(MAX_RATE_POWER, ahpriv->ah_powerLimit));
3210 if (status != HAL_OK) {
3211 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
3212 "%s: error init'ing transmit power\n", __func__);
3213 return HAL_EIO;
3214 }
3215
3216
3217 return HAL_OK;
3218 #undef N
3219 }
3220
3221 /* ar9300_is_cal_supp
3222 * Determine if calibration is supported by device and channel flags
3223 */
3224 inline static HAL_BOOL
ar9300_is_cal_supp(struct ath_hal * ah,const struct ieee80211_channel * chan,HAL_CAL_TYPES cal_type)3225 ar9300_is_cal_supp(struct ath_hal *ah, const struct ieee80211_channel *chan,
3226 HAL_CAL_TYPES cal_type)
3227 {
3228 struct ath_hal_9300 *ahp = AH9300(ah);
3229 HAL_BOOL retval = AH_FALSE;
3230
3231 switch (cal_type & ahp->ah_supp_cals) {
3232 case IQ_MISMATCH_CAL:
3233 /* Run IQ Mismatch for non-CCK only */
3234 if (!IEEE80211_IS_CHAN_B(chan)) {
3235 retval = AH_TRUE;
3236 }
3237 break;
3238 case TEMP_COMP_CAL:
3239 retval = AH_TRUE;
3240 break;
3241 }
3242
3243 return retval;
3244 }
3245
3246
3247 #if 0
3248 /* ar9285_pa_cal
3249 * PA Calibration for Kite 1.1 and later versions of Kite.
3250 * - from system's team.
3251 */
3252 static inline void
3253 ar9285_pa_cal(struct ath_hal *ah)
3254 {
3255 u_int32_t reg_val;
3256 int i, lo_gn, offs_6_1, offs_0;
3257 u_int8_t reflo;
3258 u_int32_t phy_test2_reg_val, phy_adc_ctl_reg_val;
3259 u_int32_t an_top2_reg_val, phy_tst_dac_reg_val;
3260
3261
3262 /* Kite 1.1 WAR for Bug 35666
3263 * Increase the LDO value to 1.28V before accessing analog Reg */
3264 if (AR_SREV_KITE_11(ah)) {
3265 OS_REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14) );
3266 }
3267 an_top2_reg_val = OS_REG_READ(ah, AR9285_AN_TOP2);
3268
3269 /* set pdv2i pdrxtxbb */
3270 reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
3271 reg_val |= ((0x1 << 5) | (0x1 << 7));
3272 OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
3273
3274 /* clear pwddb */
3275 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G7);
3276 reg_val &= 0xfffffffd;
3277 OS_REG_WRITE(ah, AR9285_AN_RF2G7, reg_val);
3278
3279 /* clear enpacal */
3280 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3281 reg_val &= 0xfffff7ff;
3282 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3283
3284 /* set offcal */
3285 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
3286 reg_val |= (0x1 << 12);
3287 OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
3288
3289 /* set pdpadrv1=pdpadrv2=pdpaout=1 */
3290 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3291 reg_val |= (0x7 << 23);
3292 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3293
3294 /* Read back reflo, increase it by 1 and write it. */
3295 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3296 reflo = ((reg_val >> 26) & 0x7);
3297
3298 if (reflo < 0x7) {
3299 reflo++;
3300 }
3301 reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3302 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3303
3304 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3305 reflo = ((reg_val >> 26) & 0x7);
3306
3307 /* use TX single carrier to transmit
3308 * dac const
3309 * reg. 15
3310 */
3311 phy_tst_dac_reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3312 OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, ((0x7ff << 11) | 0x7ff));
3313 reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3314
3315 /* source is dac const
3316 * reg. 2
3317 */
3318 phy_test2_reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3319 OS_REG_WRITE(ah, AR_PHY_TEST2, ((0x1 << 7) | (0x1 << 1)));
3320 reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3321
3322 /* set dac on
3323 * reg. 11
3324 */
3325 phy_adc_ctl_reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3326 OS_REG_WRITE(ah, AR_PHY_ADC_CTL, 0x80008000);
3327 reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3328
3329 OS_REG_WRITE(ah, AR9285_AN_TOP2, (0x1 << 27) | (0x1 << 17) | (0x1 << 16) |
3330 (0x1 << 14) | (0x1 << 12) | (0x1 << 11) |
3331 (0x1 << 7) | (0x1 << 5));
3332
3333 OS_DELAY(10); /* 10 usec */
3334
3335 /* clear off[6:0] */
3336 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3337 reg_val &= 0xfc0fffff;
3338 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3339 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3340 reg_val &= 0xfdffffff;
3341 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3342
3343 offs_6_1 = 0;
3344 for (i = 6; i > 0; i--) {
3345 /* sef off[$k]==1 */
3346 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3347 reg_val &= 0xfc0fffff;
3348 reg_val = reg_val | (0x1 << (19 + i)) | ((offs_6_1) << 20);
3349 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3350 lo_gn = (OS_REG_READ(ah, AR9285_AN_RF2G9)) & 0x1;
3351 offs_6_1 = offs_6_1 | (lo_gn << (i - 1));
3352 }
3353
3354 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3355 reg_val &= 0xfc0fffff;
3356 reg_val = reg_val | ((offs_6_1 - 1) << 20);
3357 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3358
3359 /* set off_0=1; */
3360 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3361 reg_val &= 0xfdffffff;
3362 reg_val = reg_val | (0x1 << 25);
3363 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3364
3365 lo_gn = OS_REG_READ(ah, AR9285_AN_RF2G9) & 0x1;
3366 offs_0 = lo_gn;
3367
3368 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3369 reg_val &= 0xfdffffff;
3370 reg_val = reg_val | (offs_0 << 25);
3371 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3372
3373 /* clear pdv2i */
3374 reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
3375 reg_val &= 0xffffff5f;
3376 OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
3377
3378 /* set enpacal */
3379 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3380 reg_val |= (0x1 << 11);
3381 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3382
3383 /* clear offcal */
3384 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
3385 reg_val &= 0xffffefff;
3386 OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
3387
3388 /* set pdpadrv1=pdpadrv2=pdpaout=0 */
3389 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3390 reg_val &= 0xfc7fffff;
3391 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3392
3393 /* Read back reflo, decrease it by 1 and write it. */
3394 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3395 reflo = (reg_val >> 26) & 0x7;
3396 if (reflo) {
3397 reflo--;
3398 }
3399 reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3400 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3401 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3402 reflo = (reg_val >> 26) & 0x7;
3403
3404 /* write back registers */
3405 OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, phy_tst_dac_reg_val);
3406 OS_REG_WRITE(ah, AR_PHY_TEST2, phy_test2_reg_val);
3407 OS_REG_WRITE(ah, AR_PHY_ADC_CTL, phy_adc_ctl_reg_val);
3408 OS_REG_WRITE(ah, AR9285_AN_TOP2, an_top2_reg_val);
3409
3410 /* Kite 1.1 WAR for Bug 35666
3411 * Decrease the LDO value back to 1.20V */
3412 if (AR_SREV_KITE_11(ah)) {
3413 OS_REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
3414 }
3415 }
3416 #endif
3417
3418 /* ar9300_run_init_cals
3419 * Runs non-periodic calibrations
3420 */
3421 inline static HAL_BOOL
ar9300_run_init_cals(struct ath_hal * ah,int init_cal_count)3422 ar9300_run_init_cals(struct ath_hal *ah, int init_cal_count)
3423 {
3424 struct ath_hal_9300 *ahp = AH9300(ah);
3425 HAL_CHANNEL_INTERNAL ichan; /* bogus */
3426 HAL_BOOL is_cal_done;
3427 HAL_CAL_LIST *curr_cal;
3428 const HAL_PERCAL_DATA *cal_data;
3429 int i;
3430
3431 curr_cal = ahp->ah_cal_list_curr;
3432 if (curr_cal == AH_NULL) {
3433 return AH_FALSE;
3434 }
3435 cal_data = curr_cal->cal_data;
3436 ichan.calValid = 0;
3437
3438 for (i = 0; i < init_cal_count; i++) {
3439 /* Reset this Cal */
3440 ar9300_reset_calibration(ah, curr_cal);
3441 /* Poll for offset calibration complete */
3442 if (!ath_hal_wait(
3443 ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL, 0))
3444 {
3445 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3446 "%s: Cal %d failed to complete in 100ms.\n",
3447 __func__, curr_cal->cal_data->cal_type);
3448 /* Re-initialize list pointers for periodic cals */
3449 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr
3450 = AH_NULL;
3451 return AH_FALSE;
3452 }
3453 /* Run this cal */
3454 ar9300_per_calibration(
3455 ah, &ichan, ahp->ah_rx_chainmask, curr_cal, &is_cal_done);
3456 if (is_cal_done == AH_FALSE) {
3457 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3458 "%s: Not able to run Init Cal %d.\n", __func__,
3459 curr_cal->cal_data->cal_type);
3460 }
3461 if (curr_cal->cal_next) {
3462 curr_cal = curr_cal->cal_next;
3463 }
3464 }
3465
3466 /* Re-initialize list pointers for periodic cals */
3467 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3468 return AH_TRUE;
3469 }
3470
3471 #if 0
3472 static void
3473 ar9300_tx_carrier_leak_war(struct ath_hal *ah)
3474 {
3475 unsigned long tx_gain_table_max;
3476 unsigned long reg_bb_cl_map_0_b0 = 0xffffffff;
3477 unsigned long reg_bb_cl_map_1_b0 = 0xffffffff;
3478 unsigned long reg_bb_cl_map_2_b0 = 0xffffffff;
3479 unsigned long reg_bb_cl_map_3_b0 = 0xffffffff;
3480 unsigned long tx_gain, cal_run = 0;
3481 unsigned long cal_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3482 unsigned long cal_gain_index[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3483 unsigned long new_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3484 int i, j;
3485
3486 OS_MEMSET(new_gain, 0, sizeof(new_gain));
3487 /*printf(" Running TxCarrierLeakWAR\n");*/
3488
3489 /* process tx gain table, we use cl_map_hw_gen=0. */
3490 OS_REG_RMW_FIELD(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_MAP_HW_GEN, 0);
3491
3492 //the table we used is txbb_gc[2:0], 1dB[2:1].
3493 tx_gain_table_max = OS_REG_READ_FIELD(ah,
3494 AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX);
3495
3496 for (i = 0; i <= tx_gain_table_max; i++) {
3497 tx_gain = OS_REG_READ(ah, AR_PHY_TXGAIN_TAB(1) + i * 4);
3498 cal_gain[i] = (((tx_gain >> 5)& 0x7) << 2) |
3499 (((tx_gain >> 1) & 0x3) << 0);
3500 if (i == 0) {
3501 cal_gain_index[i] = cal_run;
3502 new_gain[i] = 1;
3503 cal_run++;
3504 } else {
3505 new_gain[i] = 1;
3506 for (j = 0; j < i; j++) {
3507 /*
3508 printf("i=%d, j=%d cal_gain[$i]=0x%04x\n", i, j, cal_gain[i]);
3509 */
3510 if (new_gain[i]) {
3511 if ((cal_gain[i] != cal_gain[j])) {
3512 new_gain[i] = 1;
3513 } else {
3514 /* if old gain found, use old cal_run value. */
3515 new_gain[i] = 0;
3516 cal_gain_index[i] = cal_gain_index[j];
3517 }
3518 }
3519 }
3520 /* if new gain found, increase cal_run */
3521 if (new_gain[i] == 1) {
3522 cal_gain_index[i] = cal_run;
3523 cal_run++;
3524 }
3525 }
3526
3527 reg_bb_cl_map_0_b0 = (reg_bb_cl_map_0_b0 & ~(0x1 << i)) |
3528 ((cal_gain_index[i] >> 0 & 0x1) << i);
3529 reg_bb_cl_map_1_b0 = (reg_bb_cl_map_1_b0 & ~(0x1 << i)) |
3530 ((cal_gain_index[i] >> 1 & 0x1) << i);
3531 reg_bb_cl_map_2_b0 = (reg_bb_cl_map_2_b0 & ~(0x1 << i)) |
3532 ((cal_gain_index[i] >> 2 & 0x1) << i);
3533 reg_bb_cl_map_3_b0 = (reg_bb_cl_map_3_b0 & ~(0x1 << i)) |
3534 ((cal_gain_index[i] >> 3 & 0x1) << i);
3535
3536 /*
3537 printf("i=%2d, cal_gain[$i]= 0x%04x, cal_run= %d, "
3538 "cal_gain_index[i]=%d, new_gain[i] = %d\n",
3539 i, cal_gain[i], cal_run, cal_gain_index[i], new_gain[i]);
3540 */
3541 }
3542 OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B0, reg_bb_cl_map_0_b0);
3543 OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B0, reg_bb_cl_map_1_b0);
3544 OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B0, reg_bb_cl_map_2_b0);
3545 OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B0, reg_bb_cl_map_3_b0);
3546 if (AR_SREV_WASP(ah)) {
3547 OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B1, reg_bb_cl_map_0_b0);
3548 OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B1, reg_bb_cl_map_1_b0);
3549 OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B1, reg_bb_cl_map_2_b0);
3550 OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B1, reg_bb_cl_map_3_b0);
3551 }
3552 }
3553 #endif
3554
3555
3556 static inline void
ar9300_invalidate_saved_cals(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan)3557 ar9300_invalidate_saved_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3558 {
3559 #if ATH_SUPPORT_CAL_REUSE
3560 if (AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3561 ATH_CAL_REUSE_REDO_IN_FULL_RESET)
3562 {
3563 ichan->one_time_txiqcal_done = AH_FALSE;
3564 ichan->one_time_txclcal_done = AH_FALSE;
3565 }
3566 #endif
3567 }
3568
3569 static inline HAL_BOOL
ar9300_restore_rtt_cals(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan)3570 ar9300_restore_rtt_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3571 {
3572 HAL_BOOL restore_status = AH_FALSE;
3573
3574 return restore_status;
3575 }
3576
3577 /* ar9300_init_cal
3578 * Initialize Calibration infrastructure
3579 */
3580 static inline HAL_BOOL
ar9300_init_cal_internal(struct ath_hal * ah,struct ieee80211_channel * chan,HAL_CHANNEL_INTERNAL * ichan,HAL_BOOL enable_rtt,HAL_BOOL do_rtt_cal,HAL_BOOL skip_if_none,HAL_BOOL apply_last_iqcorr)3581 ar9300_init_cal_internal(struct ath_hal *ah, struct ieee80211_channel *chan,
3582 HAL_CHANNEL_INTERNAL *ichan,
3583 HAL_BOOL enable_rtt, HAL_BOOL do_rtt_cal, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3584 {
3585 struct ath_hal_9300 *ahp = AH9300(ah);
3586 HAL_BOOL txiqcal_success_flag = AH_FALSE;
3587 HAL_BOOL cal_done = AH_FALSE;
3588 int iqcal_idx = 0;
3589 HAL_BOOL do_sep_iq_cal = AH_FALSE;
3590 HAL_BOOL do_agc_cal = do_rtt_cal;
3591 HAL_BOOL is_cal_reusable = AH_TRUE;
3592 #if ATH_SUPPORT_CAL_REUSE
3593 HAL_BOOL cal_reuse_enable = AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3594 ATH_CAL_REUSE_ENABLE;
3595 HAL_BOOL clc_success = AH_FALSE;
3596 int32_t ch_idx, j, cl_tab_reg;
3597 u_int32_t BB_cl_tab_entry = MAX_BB_CL_TABLE_ENTRY;
3598 u_int32_t BB_cl_tab_b[AR9300_MAX_CHAINS] = {
3599 AR_PHY_CL_TAB_0,
3600 AR_PHY_CL_TAB_1,
3601 AR_PHY_CL_TAB_2
3602 };
3603 #endif
3604
3605 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
3606 /* Hornet: 1 x 1 */
3607 ahp->ah_rx_cal_chainmask = 0x1;
3608 ahp->ah_tx_cal_chainmask = 0x1;
3609 } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_HONEYBEE(ah)) {
3610 /* Wasp/Jupiter: 2 x 2 */
3611 ahp->ah_rx_cal_chainmask = 0x3;
3612 ahp->ah_tx_cal_chainmask = 0x3;
3613 } else {
3614 /*
3615 * Osprey needs to be configured for the correct chain mode
3616 * before running AGC/TxIQ cals.
3617 */
3618 if (ahp->ah_enterprise_mode & AR_ENT_OTP_CHAIN2_DISABLE) {
3619 /* chain 2 disabled - 2 chain mode */
3620 ahp->ah_rx_cal_chainmask = 0x3;
3621 ahp->ah_tx_cal_chainmask = 0x3;
3622 } else {
3623 ahp->ah_rx_cal_chainmask = 0x7;
3624 ahp->ah_tx_cal_chainmask = 0x7;
3625 }
3626 }
3627 ar9300_init_chain_masks(ah, ahp->ah_rx_cal_chainmask, ahp->ah_tx_cal_chainmask);
3628
3629
3630 if (ahp->tx_cl_cal_enable) {
3631 #if ATH_SUPPORT_CAL_REUSE
3632 /* disable Carrie Leak or set do_agc_cal accordingly */
3633 if (cal_reuse_enable && ichan->one_time_txclcal_done)
3634 {
3635 OS_REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3636 } else
3637 #endif /* ATH_SUPPORT_CAL_REUSE */
3638 {
3639 OS_REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3640 do_agc_cal = AH_TRUE;
3641 }
3642 }
3643
3644 /* Do Tx IQ Calibration here for osprey hornet and wasp */
3645 /* XXX: For initial wasp bringup - check and enable this */
3646 /* EV 74233: Tx IQ fails to complete for half/quarter rates */
3647 if (!(IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) {
3648 if (ahp->tx_iq_cal_enable) {
3649 /* this should be eventually moved to INI file */
3650 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1(ah),
3651 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
3652
3653 /*
3654 * For poseidon and later chips,
3655 * Tx IQ cal HW run will be a part of AGC calibration
3656 */
3657 if (ahp->tx_iq_cal_during_agc_cal) {
3658 /*
3659 * txiqcal_success_flag always set to 1 to run
3660 * ar9300_tx_iq_cal_post_proc
3661 * if following AGC cal passes
3662 */
3663 #if ATH_SUPPORT_CAL_REUSE
3664 if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3665 {
3666 txiqcal_success_flag = AH_TRUE;
3667 OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3668 OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) |
3669 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3670 } else {
3671 OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3672 OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) &
3673 (~AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL));
3674 }
3675 #else
3676 if (OS_REG_READ_FIELD(ah,
3677 AR_PHY_TX_IQCAL_CONTROL_0(ah),
3678 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)){
3679 if (apply_last_iqcorr == AH_TRUE) {
3680 OS_REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3681 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3682 txiqcal_success_flag = AH_FALSE;
3683 } else {
3684 txiqcal_success_flag = AH_TRUE;
3685 }
3686 }else{
3687 txiqcal_success_flag = AH_FALSE;
3688 }
3689 #endif
3690 if (txiqcal_success_flag) {
3691 do_agc_cal = AH_TRUE;
3692 }
3693 } else
3694 #if ATH_SUPPORT_CAL_REUSE
3695 if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3696 #endif
3697 {
3698 do_sep_iq_cal = AH_TRUE;
3699 do_agc_cal = AH_TRUE;
3700 }
3701 }
3702 }
3703
3704 #if ATH_SUPPORT_MCI
3705 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
3706 IS_CHAN_2GHZ(ichan) &&
3707 (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3708 do_agc_cal &&
3709 !(ah->ah_config.ath_hal_mci_config &
3710 ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3711 {
3712 u_int32_t payload[4] = {0, 0, 0, 0};
3713
3714 /* Send CAL_REQ only when BT is AWAKE. */
3715 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_REQ 0x%X\n",
3716 __func__, ahp->ah_mci_wlan_cal_seq);
3717 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_REQ);
3718 payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_seq++;
3719 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3720
3721 /* Wait BT_CAL_GRANT for 50ms */
3722 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3723 "(MCI) %s: Wait for BT_CAL_GRANT\n", __func__);
3724 if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000))
3725 {
3726 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3727 "(MCI) %s: Got BT_CAL_GRANT.\n", __func__);
3728 }
3729 else {
3730 is_cal_reusable = AH_FALSE;
3731 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3732 "(MCI) %s: BT is not responding.\n", __func__);
3733 }
3734 }
3735 #endif /* ATH_SUPPORT_MCI */
3736
3737 if (do_sep_iq_cal)
3738 {
3739 /* enable Tx IQ Calibration HW for osprey/hornet/wasp */
3740 txiqcal_success_flag = ar9300_tx_iq_cal_hw_run(ah);
3741 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
3742 OS_DELAY(5);
3743 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
3744 }
3745 #if 0
3746 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
3747 ar9300_tx_carrier_leak_war(ah);
3748 }
3749 #endif
3750 /*
3751 * Calibrate the AGC
3752 *
3753 * Tx IQ cal is a part of AGC cal for Jupiter/Poseidon, etc.
3754 * please enable the bit of txiqcal_control_0[31] in INI file
3755 * for Jupiter/Poseidon/etc.
3756 */
3757 if(!AR_SREV_SCORPION(ah)) {
3758 if (do_agc_cal || !skip_if_none) {
3759 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3760 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3761
3762 /* Poll for offset calibration complete */
3763 cal_done = ath_hal_wait(ah,
3764 AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0);
3765 if (!cal_done) {
3766 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3767 "(FCS) CAL NOT DONE!!! - %d\n", ichan->channel);
3768 }
3769 } else {
3770 cal_done = AH_TRUE;
3771 }
3772 /*
3773 * Tx IQ cal post-processing in SW
3774 * This part of code should be common to all chips,
3775 * no chip specific code for Jupiter/Posdeion except for register names.
3776 */
3777 if (txiqcal_success_flag) {
3778 ar9300_tx_iq_cal_post_proc(ah,ichan, 1, 1,is_cal_reusable, AH_FALSE);
3779 }
3780 } else {
3781 if (!txiqcal_success_flag) {
3782 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3783 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3784 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
3785 0)) {
3786 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3787 "%s: offset calibration failed to complete in 1ms; "
3788 "noisy environment?\n", __func__);
3789 return AH_FALSE;
3790 }
3791 if (apply_last_iqcorr == AH_TRUE) {
3792 ar9300_tx_iq_cal_post_proc(ah, ichan, 0, 0, is_cal_reusable, AH_TRUE);
3793 }
3794 } else {
3795 for (iqcal_idx=0;iqcal_idx<MAXIQCAL;iqcal_idx++) {
3796 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3797 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3798
3799 /* Poll for offset calibration complete */
3800 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL,
3801 AR_PHY_AGC_CONTROL_CAL, 0)) {
3802 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3803 "%s: offset calibration failed to complete in 1ms; "
3804 "noisy environment?\n", __func__);
3805 return AH_FALSE;
3806 }
3807 /*
3808 * Tx IQ cal post-processing in SW
3809 * This part of code should be common to all chips,
3810 * no chip specific code for Jupiter/Posdeion except for register names.
3811 */
3812 ar9300_tx_iq_cal_post_proc(ah, ichan, iqcal_idx+1, MAXIQCAL, is_cal_reusable, AH_FALSE);
3813 }
3814 }
3815 }
3816
3817
3818 #if ATH_SUPPORT_MCI
3819 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
3820 IS_CHAN_2GHZ(ichan) &&
3821 (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3822 do_agc_cal &&
3823 !(ah->ah_config.ath_hal_mci_config &
3824 ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3825 {
3826 u_int32_t payload[4] = {0, 0, 0, 0};
3827
3828 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_DONE 0x%X\n",
3829 __func__, ahp->ah_mci_wlan_cal_done);
3830 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE);
3831 payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_done++;
3832 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3833 }
3834 #endif /* ATH_SUPPORT_MCI */
3835
3836
3837 if (!cal_done && !AR_SREV_SCORPION(ah) )
3838 {
3839 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3840 "%s: offset calibration failed to complete in 1ms; "
3841 "noisy environment?\n", __func__);
3842 return AH_FALSE;
3843 }
3844
3845 #if 0
3846 /* Beacon stuck fix, refer to EV 120056 */
3847 if(IS_CHAN_2GHZ(chan) && AR_SREV_SCORPION(ah))
3848 OS_REG_WRITE(ah, AR_PHY_TIMING5, OS_REG_READ(ah,AR_PHY_TIMING5) & ~AR_PHY_TIMING5_CYCPWR_THR1_ENABLE);
3849 #endif
3850
3851 #if 0
3852 /* Do PA Calibration */
3853 if (AR_SREV_KITE(ah) && AR_SREV_KITE_11_OR_LATER(ah)) {
3854 ar9285_pa_cal(ah);
3855 }
3856 #endif
3857
3858 #if ATH_SUPPORT_CAL_REUSE
3859 if (ichan->one_time_txiqcal_done) {
3860 ar9300_tx_iq_cal_apply(ah, ichan);
3861 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3862 "(FCS) TXIQCAL applied - %d\n", ichan->channel);
3863 }
3864 #endif /* ATH_SUPPORT_CAL_REUSE */
3865
3866 #if ATH_SUPPORT_CAL_REUSE
3867 if (cal_reuse_enable && ahp->tx_cl_cal_enable)
3868 {
3869 clc_success = (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) &
3870 AR_PHY_AGC_CONTROL_CLC_SUCCESS) ? 1 : 0;
3871
3872 if (ichan->one_time_txclcal_done)
3873 {
3874 /* reapply CL cal results */
3875 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3876 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3877 continue;
3878 }
3879 cl_tab_reg = BB_cl_tab_b[ch_idx];
3880 for (j = 0; j < BB_cl_tab_entry; j++) {
3881 OS_REG_WRITE(ah, cl_tab_reg, ichan->tx_clcal[ch_idx][j]);
3882 cl_tab_reg += 4;
3883 }
3884 }
3885 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3886 "(FCS) TX CL CAL applied - %d\n", ichan->channel);
3887 }
3888 else if (is_cal_reusable && clc_success) {
3889 /* save CL cal results */
3890 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3891 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3892 continue;
3893 }
3894 cl_tab_reg = BB_cl_tab_b[ch_idx];
3895 for (j = 0; j < BB_cl_tab_entry; j++) {
3896 ichan->tx_clcal[ch_idx][j] = OS_REG_READ(ah, cl_tab_reg);
3897 cl_tab_reg += 4;
3898 }
3899 }
3900 ichan->one_time_txclcal_done = AH_TRUE;
3901 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3902 "(FCS) TX CL CAL saved - %d\n", ichan->channel);
3903 }
3904 }
3905 #endif /* ATH_SUPPORT_CAL_REUSE */
3906
3907 /* Revert chainmasks to their original values before NF cal */
3908 ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
3909
3910 #if !FIX_NOISE_FLOOR
3911 /*
3912 * Do NF calibration after DC offset and other CALs.
3913 * Per system engineers, noise floor value can sometimes be 20 dB
3914 * higher than normal value if DC offset and noise floor cal are
3915 * triggered at the same time.
3916 */
3917 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3918 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
3919 #endif
3920
3921 /* Initialize list pointers */
3922 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3923
3924 /*
3925 * Enable IQ, ADC Gain, ADC DC Offset Cals
3926 */
3927 /* Setup all non-periodic, init time only calibrations */
3928 /* XXX: Init DC Offset not working yet */
3929 #ifdef not_yet
3930 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, ADC_DC_INIT_CAL)) {
3931 INIT_CAL(&ahp->ah_adc_dc_cal_init_data);
3932 INSERT_CAL(ahp, &ahp->ah_adc_dc_cal_init_data);
3933 }
3934
3935 /* Initialize current pointer to first element in list */
3936 ahp->ah_cal_list_curr = ahp->ah_cal_list;
3937
3938 if (ahp->ah_cal_list_curr) {
3939 if (ar9300_run_init_cals(ah, 0) == AH_FALSE) {
3940 return AH_FALSE;
3941 }
3942 }
3943 #endif
3944 /* end - Init time calibrations */
3945
3946 /* Do not do RX cal in case of offchan, or cal data already exists on same channel*/
3947 if (ahp->ah_skip_rx_iq_cal) {
3948 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3949 "Skip RX IQ Cal\n");
3950 return AH_TRUE;
3951 }
3952
3953 /* If Cals are supported, add them to list via INIT/INSERT_CAL */
3954 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, IQ_MISMATCH_CAL)) {
3955 INIT_CAL(&ahp->ah_iq_cal_data);
3956 INSERT_CAL(ahp, &ahp->ah_iq_cal_data);
3957 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3958 "%s: enabling IQ Calibration.\n", __func__);
3959 }
3960 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, TEMP_COMP_CAL)) {
3961 INIT_CAL(&ahp->ah_temp_comp_cal_data);
3962 INSERT_CAL(ahp, &ahp->ah_temp_comp_cal_data);
3963 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3964 "%s: enabling Temperature Compensation Calibration.\n", __func__);
3965 }
3966
3967 /* Initialize current pointer to first element in list */
3968 ahp->ah_cal_list_curr = ahp->ah_cal_list;
3969
3970 /* Reset state within current cal */
3971 if (ahp->ah_cal_list_curr) {
3972 ar9300_reset_calibration(ah, ahp->ah_cal_list_curr);
3973 }
3974
3975 /* Mark all calibrations on this channel as being invalid */
3976 ichan->calValid = 0;
3977
3978 return AH_TRUE;
3979 }
3980
3981 static inline HAL_BOOL
ar9300_init_cal(struct ath_hal * ah,struct ieee80211_channel * chan,HAL_BOOL skip_if_none,HAL_BOOL apply_last_iqcorr)3982 ar9300_init_cal(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3983 {
3984 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
3985 HAL_BOOL do_rtt_cal = AH_TRUE;
3986 HAL_BOOL enable_rtt = AH_FALSE;
3987
3988 HALASSERT(ichan);
3989
3990 return ar9300_init_cal_internal(ah, chan, ichan, enable_rtt, do_rtt_cal, skip_if_none, apply_last_iqcorr);
3991 }
3992
3993 /* ar9300_reset_cal_valid
3994 * Entry point for upper layers to restart current cal.
3995 * Reset the calibration valid bit in channel.
3996 */
3997 void
ar9300_reset_cal_valid(struct ath_hal * ah,const struct ieee80211_channel * chan,HAL_BOOL * is_cal_done,u_int32_t cal_type)3998 ar9300_reset_cal_valid(struct ath_hal *ah, const struct ieee80211_channel *chan,
3999 HAL_BOOL *is_cal_done, u_int32_t cal_type)
4000 {
4001 struct ath_hal_9300 *ahp = AH9300(ah);
4002 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
4003 HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr;
4004
4005 *is_cal_done = AH_TRUE;
4006
4007 if (curr_cal == AH_NULL) {
4008 return;
4009 }
4010 if (ichan == AH_NULL) {
4011 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4012 "%s: invalid channel %u/0x%x; no mapping\n",
4013 __func__, chan->ic_freq, chan->ic_flags);
4014 return;
4015 }
4016
4017 if (!(cal_type & IQ_MISMATCH_CAL)) {
4018 *is_cal_done = AH_FALSE;
4019 return;
4020 }
4021
4022 /* Expected that this calibration has run before, post-reset.
4023 * Current state should be done
4024 */
4025 if (curr_cal->cal_state != CAL_DONE) {
4026 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4027 "%s: Calibration state incorrect, %d\n",
4028 __func__, curr_cal->cal_state);
4029 return;
4030 }
4031
4032 /* Verify Cal is supported on this channel */
4033 if (ar9300_is_cal_supp(ah, chan, curr_cal->cal_data->cal_type) == AH_FALSE) {
4034 return;
4035 }
4036
4037 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4038 "%s: Resetting Cal %d state for channel %u/0x%x\n", __func__,
4039 curr_cal->cal_data->cal_type, chan->ic_freq, chan->ic_flags);
4040
4041 /* Disable cal validity in channel */
4042 ichan->calValid &= ~curr_cal->cal_data->cal_type;
4043 curr_cal->cal_state = CAL_WAITING;
4044 /* Indicate to upper layers that we need polling */
4045 *is_cal_done = AH_FALSE;
4046 }
4047
4048 static inline void
ar9300_set_dma(struct ath_hal * ah)4049 ar9300_set_dma(struct ath_hal *ah)
4050 {
4051 u_int32_t regval;
4052 struct ath_hal_9300 *ahp = AH9300(ah);
4053 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
4054 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
4055
4056 #if 0
4057 /*
4058 * set AHB_MODE not to do cacheline prefetches
4059 */
4060 regval = OS_REG_READ(ah, AR_AHB_MODE);
4061 OS_REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
4062 #endif
4063
4064 /*
4065 * let mac dma reads be in 128 byte chunks
4066 */
4067 regval = OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
4068 OS_REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
4069
4070 /*
4071 * Restore TX Trigger Level to its pre-reset value.
4072 * The initial value depends on whether aggregation is enabled, and is
4073 * adjusted whenever underruns are detected.
4074 */
4075 /*
4076 OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, AH_PRIVATE(ah)->ah_tx_trig_level);
4077 */
4078 /*
4079 * Osprey 1.0 bug (EV 61936). Don't change trigger level from .ini default.
4080 * Osprey 2.0 - hardware recommends using the default INI settings.
4081 */
4082 #if 0
4083 OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, 0x3f);
4084 #endif
4085 /*
4086 * let mac dma writes be in 128 byte chunks
4087 */
4088 regval = OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
4089 OS_REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
4090
4091 /*
4092 * Setup receive FIFO threshold to hold off TX activities
4093 */
4094 OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
4095
4096 /*
4097 * reduce the number of usable entries in PCU TXBUF to avoid
4098 * wrap around bugs. (bug 20428)
4099 */
4100
4101 if (AR_SREV_WASP(ah) &&
4102 (AH_PRIVATE((ah))->ah_macRev > AR_SREV_REVISION_WASP_12)) {
4103 /* Wasp 1.3 fix for EV#85395 requires usable entries
4104 * to be set to 0x500
4105 */
4106 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 0x500);
4107 } else {
4108 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE);
4109 }
4110
4111 /*
4112 * Enable HPQ for UAPSD
4113 */
4114 if (pCap->halHwUapsdTrig == AH_TRUE) {
4115 /* Only enable this if HAL capabilities says it is OK */
4116 if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) {
4117 OS_REG_WRITE(ah, AR_HP_Q_CONTROL,
4118 AR_HPQ_ENABLE | AR_HPQ_UAPSD | AR_HPQ_UAPSD_TRIGGER_EN);
4119 }
4120 } else {
4121 /* use default value from ini file - which disable HPQ queue usage */
4122 }
4123
4124 /*
4125 * set the transmit status ring
4126 */
4127 ar9300_reset_tx_status_ring(ah);
4128
4129 /*
4130 * set rxbp threshold. Must be non-zero for RX_EOL to occur.
4131 * For Osprey 2.0+, keep the original thresholds
4132 * otherwise performance is lost due to excessive RX EOL interrupts.
4133 */
4134 OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1);
4135 OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1);
4136
4137 /*
4138 * set receive buffer size.
4139 */
4140 if (ahp->rx_buf_size) {
4141 OS_REG_WRITE(ah, AR_DATABUF, ahp->rx_buf_size);
4142 }
4143 }
4144
4145 static inline void
ar9300_init_bb(struct ath_hal * ah,struct ieee80211_channel * chan)4146 ar9300_init_bb(struct ath_hal *ah, struct ieee80211_channel *chan)
4147 {
4148 u_int32_t synth_delay;
4149
4150 /*
4151 * Wait for the frequency synth to settle (synth goes on
4152 * via AR_PHY_ACTIVE_EN). Read the phy active delay register.
4153 * Value is in 100ns increments.
4154 */
4155 synth_delay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
4156 if (IEEE80211_IS_CHAN_CCK(chan)) {
4157 synth_delay = (4 * synth_delay) / 22;
4158 } else {
4159 synth_delay /= 10;
4160 }
4161
4162 /* Activate the PHY (includes baseband activate + synthesizer on) */
4163 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
4164
4165 /*
4166 * There is an issue if the AP starts the calibration before
4167 * the base band timeout completes. This could result in the
4168 * rx_clear false triggering. As a workaround we add delay an
4169 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
4170 * does not happen.
4171 */
4172 OS_DELAY(synth_delay + BASE_ACTIVATE_DELAY);
4173 }
4174
4175 static inline void
ar9300_init_interrupt_masks(struct ath_hal * ah,HAL_OPMODE opmode)4176 ar9300_init_interrupt_masks(struct ath_hal *ah, HAL_OPMODE opmode)
4177 {
4178 struct ath_hal_9300 *ahp = AH9300(ah);
4179 u_int32_t msi_cfg = 0;
4180 u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
4181
4182 /*
4183 * Setup interrupt handling. Note that ar9300_reset_tx_queue
4184 * manipulates the secondary IMR's as queues are enabled
4185 * and disabled. This is done with RMW ops to insure the
4186 * settings we make here are preserved.
4187 */
4188 ahp->ah_mask_reg =
4189 AR_IMR_TXERR | AR_IMR_TXURN |
4190 AR_IMR_RXERR | AR_IMR_RXORN |
4191 AR_IMR_BCNMISC;
4192
4193 if (ahp->ah_intr_mitigation_rx) {
4194 /* enable interrupt mitigation for rx */
4195 ahp->ah_mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR | AR_IMR_RXOK_HP;
4196 msi_cfg |= AR_INTCFG_MSI_RXINTM | AR_INTCFG_MSI_RXMINTR;
4197 } else {
4198 ahp->ah_mask_reg |= AR_IMR_RXOK_LP | AR_IMR_RXOK_HP;
4199 msi_cfg |= AR_INTCFG_MSI_RXOK;
4200 }
4201 if (ahp->ah_intr_mitigation_tx) {
4202 /* enable interrupt mitigation for tx */
4203 ahp->ah_mask_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR;
4204 msi_cfg |= AR_INTCFG_MSI_TXINTM | AR_INTCFG_MSI_TXMINTR;
4205 } else {
4206 ahp->ah_mask_reg |= AR_IMR_TXOK;
4207 msi_cfg |= AR_INTCFG_MSI_TXOK;
4208 }
4209 if (opmode == HAL_M_HOSTAP) {
4210 ahp->ah_mask_reg |= AR_IMR_MIB;
4211 }
4212
4213 OS_REG_WRITE(ah, AR_IMR, ahp->ah_mask_reg);
4214 OS_REG_WRITE(ah, AR_IMR_S2, OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
4215 ahp->ah_mask2Reg = OS_REG_READ(ah, AR_IMR_S2);
4216
4217 if (ah->ah_config.ath_hal_enable_msi) {
4218 /* Cache MSI register value */
4219 ahp->ah_msi_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI));
4220 ahp->ah_msi_reg |= AR_PCIE_MSI_HW_DBI_WR_EN;
4221 if (AR_SREV_POSEIDON(ah)) {
4222 ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
4223 } else {
4224 ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR;
4225 }
4226 /* Program MSI configuration */
4227 OS_REG_WRITE(ah, AR_INTCFG, msi_cfg);
4228 }
4229
4230 /*
4231 * debug - enable to see all synchronous interrupts status
4232 */
4233 /* Clear any pending sync cause interrupts */
4234 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE), 0xFFFFFFFF);
4235
4236 /* Allow host interface sync interrupt sources to set cause bit */
4237 if (AR_SREV_POSEIDON(ah)) {
4238 sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
4239 }
4240 else if (AR_SREV_WASP(ah)) {
4241 sync_en_def = AR9340_INTR_SYNC_DEFAULT;
4242 }
4243 OS_REG_WRITE(ah,
4244 AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), sync_en_def);
4245
4246 /* _Disable_ host interface sync interrupt when cause bits set */
4247 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK), 0);
4248
4249 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE), 0);
4250 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_MASK), 0);
4251 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_ENABLE), 0);
4252 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_MASK), 0);
4253 }
4254
4255 static inline void
ar9300_init_qos(struct ath_hal * ah)4256 ar9300_init_qos(struct ath_hal *ah)
4257 {
4258 OS_REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); /* XXX magic */
4259 OS_REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); /* XXX magic */
4260
4261 /* Turn on NOACK Support for QoS packets */
4262 OS_REG_WRITE(ah, AR_QOS_NO_ACK,
4263 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
4264 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
4265 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
4266
4267 /*
4268 * initialize TXOP for all TIDs
4269 */
4270 OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
4271 OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
4272 OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
4273 OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
4274 OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
4275 }
4276
4277 static inline void
ar9300_init_user_settings(struct ath_hal * ah)4278 ar9300_init_user_settings(struct ath_hal *ah)
4279 {
4280 struct ath_hal_9300 *ahp = AH9300(ah);
4281
4282 /* Restore user-specified settings */
4283 HALDEBUG(ah, HAL_DEBUG_RESET,
4284 "--AP %s ahp->ah_misc_mode 0x%x\n", __func__, ahp->ah_misc_mode);
4285 if (ahp->ah_misc_mode != 0) {
4286 OS_REG_WRITE(ah,
4287 AR_PCU_MISC, OS_REG_READ(ah, AR_PCU_MISC) | ahp->ah_misc_mode);
4288 }
4289 if (ahp->ah_get_plcp_hdr) {
4290 OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM);
4291 }
4292 if (ahp->ah_slot_time != (u_int) -1) {
4293 ar9300_set_slot_time(ah, ahp->ah_slot_time);
4294 }
4295 if (ahp->ah_ack_timeout != (u_int) -1) {
4296 ar9300_set_ack_timeout(ah, ahp->ah_ack_timeout);
4297 }
4298 if (AH_PRIVATE(ah)->ah_diagreg != 0) {
4299 OS_REG_SET_BIT(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
4300 }
4301 if (ahp->ah_beacon_rssi_threshold != 0) {
4302 ar9300_set_hw_beacon_rssi_threshold(ah, ahp->ah_beacon_rssi_threshold);
4303 }
4304 //#ifdef ATH_SUPPORT_DFS
4305 if (ahp->ah_cac_quiet_enabled) {
4306 ar9300_cac_tx_quiet(ah, 1);
4307 }
4308 //#endif /* ATH_SUPPORT_DFS */
4309 }
4310
4311 int
ar9300_get_spur_info(struct ath_hal * ah,int * enable,int len,u_int16_t * freq)4312 ar9300_get_spur_info(struct ath_hal * ah, int *enable, int len, u_int16_t *freq)
4313 {
4314 // struct ath_hal_private *ap = AH_PRIVATE(ah);
4315 int i, j;
4316
4317 for (i = 0; i < len; i++) {
4318 freq[i] = 0;
4319 }
4320
4321 *enable = ah->ah_config.ath_hal_spur_mode;
4322 for (i = 0, j = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4323 if (AH9300(ah)->ath_hal_spur_chans[i][0] != AR_NO_SPUR) {
4324 freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][0];
4325 HALDEBUG(ah, HAL_DEBUG_ANI,
4326 "1. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][0]);
4327 }
4328 if (AH9300(ah)->ath_hal_spur_chans[i][1] != AR_NO_SPUR) {
4329 freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][1];
4330 HALDEBUG(ah, HAL_DEBUG_ANI,
4331 "2. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][1]);
4332 }
4333 }
4334
4335 return 0;
4336 }
4337
4338 #define ATH_HAL_2GHZ_FREQ_MIN 20000
4339 #define ATH_HAL_2GHZ_FREQ_MAX 29999
4340 #define ATH_HAL_5GHZ_FREQ_MIN 50000
4341 #define ATH_HAL_5GHZ_FREQ_MAX 59999
4342
4343 #if 0
4344 int
4345 ar9300_set_spur_info(struct ath_hal * ah, int enable, int len, u_int16_t *freq)
4346 {
4347 struct ath_hal_private *ap = AH_PRIVATE(ah);
4348 int i, j, k;
4349
4350 ap->ah_config.ath_hal_spur_mode = enable;
4351
4352 if (ap->ah_config.ath_hal_spur_mode == SPUR_ENABLE_IOCTL) {
4353 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4354 AH9300(ah)->ath_hal_spur_chans[i][0] = AR_NO_SPUR;
4355 AH9300(ah)->ath_hal_spur_chans[i][1] = AR_NO_SPUR;
4356 }
4357 for (i = 0, j = 0, k = 0; i < len; i++) {
4358 if (freq[i] > ATH_HAL_2GHZ_FREQ_MIN &&
4359 freq[i] < ATH_HAL_2GHZ_FREQ_MAX)
4360 {
4361 /* 2GHz Spur */
4362 if (j < AR_EEPROM_MODAL_SPURS) {
4363 AH9300(ah)->ath_hal_spur_chans[j++][1] = freq[i];
4364 HALDEBUG(ah, HAL_DEBUG_ANI, "1 set spur %d\n", freq[i]);
4365 }
4366 } else if (freq[i] > ATH_HAL_5GHZ_FREQ_MIN &&
4367 freq[i] < ATH_HAL_5GHZ_FREQ_MAX)
4368 {
4369 /* 5Ghz Spur */
4370 if (k < AR_EEPROM_MODAL_SPURS) {
4371 AH9300(ah)->ath_hal_spur_chans[k++][0] = freq[i];
4372 HALDEBUG(ah, HAL_DEBUG_ANI, "2 set spur %d\n", freq[i]);
4373 }
4374 }
4375 }
4376 }
4377
4378 return 0;
4379 }
4380 #endif
4381
4382 #define ar9300_check_op_mode(_opmode) \
4383 ((_opmode == HAL_M_STA) || (_opmode == HAL_M_IBSS) ||\
4384 (_opmode == HAL_M_HOSTAP) || (_opmode == HAL_M_MONITOR))
4385
4386
4387
4388
4389 #ifndef ATH_NF_PER_CHAN
4390 /*
4391 * To fixed first reset noise floor value not correct issue
4392 * For ART need it to fixed low rate sens too low issue
4393 */
4394 static int
First_NFCal(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan,int is_scan,struct ieee80211_channel * chan)4395 First_NFCal(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
4396 int is_scan, struct ieee80211_channel *chan)
4397 {
4398 HAL_NFCAL_HIST_FULL *nfh;
4399 int i, j, k;
4400 int16_t nfarray[HAL_NUM_NF_READINGS] = {0};
4401 int is_2g = 0;
4402 int nf_hist_len;
4403 int stats = 0;
4404
4405 int16_t nf_buf[HAL_NUM_NF_READINGS];
4406 #define IS(_c, _f) (((_c)->channel_flags & _f) || 0)
4407
4408
4409 if ((!is_scan) &&
4410 chan->ic_freq == AH_PRIVATE(ah)->ah_curchan->ic_freq)
4411 {
4412 nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4413 } else {
4414 nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4415 }
4416
4417 ar9300_start_nf_cal(ah);
4418 for (j = 0; j < 10000; j++) {
4419 if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){
4420 break;
4421 }
4422 OS_DELAY(10);
4423 }
4424 if (j < 10000) {
4425 is_2g = IEEE80211_IS_CHAN_2GHZ(chan);
4426 ar9300_upload_noise_floor(ah, is_2g, nfarray);
4427
4428 if (is_scan) {
4429 /*
4430 * This channel's NF cal info is just a HAL_NFCAL_HIST_SMALL struct
4431 * rather than a HAL_NFCAL_HIST_FULL struct.
4432 * As long as we only use the first history element of nf_cal_buffer
4433 * (nf_cal_buffer[0][0:HAL_NUM_NF_READINGS-1]), we can use
4434 * HAL_NFCAL_HIST_SMALL and HAL_NFCAL_HIST_FULL interchangeably.
4435 */
4436 nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4437 nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
4438 } else {
4439 nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4440 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
4441 }
4442
4443 for (i = 0; i < HAL_NUM_NF_READINGS; i ++) {
4444 for (k = 0; k < HAL_NF_CAL_HIST_LEN_FULL; k++) {
4445 nfh->nf_cal_buffer[k][i] = nfarray[i];
4446 }
4447 nfh->base.priv_nf[i] = ar9300_limit_nf_range(ah,
4448 ar9300_get_nf_hist_mid(ah, nfh, i, nf_hist_len));
4449 }
4450
4451
4452 //ar9300StoreNewNf(ah, ichan, is_scan);
4453
4454 /*
4455 * See if the NF value from the old channel should be
4456 * retained when switching to a new channel.
4457 * TBD: this may need to be changed, as it wipes out the
4458 * purpose of saving NF values for each channel.
4459 */
4460 for (i = 0; i < HAL_NUM_NF_READINGS; i++)
4461 {
4462 if (IEEE80211_IS_CHAN_2GHZ(chan))
4463 {
4464 if (nfh->nf_cal_buffer[0][i] <
4465 AR_PHY_CCA_MAX_GOOD_VAL_OSPREY_2GHZ)
4466 {
4467 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4468 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4469 }
4470 } else {
4471 if (AR_SREV_AR9580(ah)) {
4472 if (nfh->nf_cal_buffer[0][i] <
4473 AR_PHY_CCA_NOM_VAL_PEACOCK_5GHZ)
4474 {
4475 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4476 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4477 }
4478 } else {
4479 if (nfh->nf_cal_buffer[0][i] <
4480 AR_PHY_CCA_NOM_VAL_OSPREY_5GHZ)
4481 {
4482 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4483 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4484 }
4485 }
4486 }
4487 }
4488 /*
4489 * Copy the channel's NF buffer, which may have been modified
4490 * just above here, to the full NF history buffer.
4491 */
4492 ar9300_reset_nf_hist_buff(ah, ichan);
4493 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
4494 ar9300_load_nf(ah, nf_buf);
4495 /* XXX TODO: handle failure from load_nf */
4496 stats = 0;
4497 } else {
4498 stats = 1;
4499 }
4500 #undef IS
4501 return stats;
4502 }
4503 #endif
4504
4505
4506 /*
4507 * Places the device in and out of reset and then places sane
4508 * values in the registers based on EEPROM config, initialization
4509 * vectors (as determined by the mode), and station configuration
4510 *
4511 * b_channel_change is used to preserve DMA/PCU registers across
4512 * a HW Reset during channel change.
4513 */
4514 HAL_BOOL
ar9300_reset(struct ath_hal * ah,HAL_OPMODE opmode,struct ieee80211_channel * chan,HAL_HT_MACMODE macmode,u_int8_t txchainmask,u_int8_t rxchainmask,HAL_HT_EXTPROTSPACING extprotspacing,HAL_BOOL b_channel_change,HAL_STATUS * status,HAL_RESET_TYPE reset_type,int is_scan)4515 ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan,
4516 HAL_HT_MACMODE macmode, u_int8_t txchainmask, u_int8_t rxchainmask,
4517 HAL_HT_EXTPROTSPACING extprotspacing, HAL_BOOL b_channel_change,
4518 HAL_STATUS *status, HAL_RESET_TYPE reset_type, int is_scan)
4519 {
4520 #define FAIL(_code) do { ecode = _code; goto bad; } while (0)
4521 u_int32_t save_led_state;
4522 struct ath_hal_9300 *ahp = AH9300(ah);
4523 struct ath_hal_private *ap = AH_PRIVATE(ah);
4524 HAL_CHANNEL_INTERNAL *ichan;
4525 //const struct ieee80211_channel *curchan = ap->ah_curchan;
4526 #if ATH_SUPPORT_MCI
4527 HAL_BOOL save_full_sleep = ahp->ah_chip_full_sleep;
4528 #endif
4529 u_int32_t save_def_antenna;
4530 u_int32_t mac_sta_id1;
4531 HAL_STATUS ecode;
4532 int i, rx_chainmask;
4533 int nf_hist_buff_reset = 0;
4534 int16_t nf_buf[HAL_NUM_NF_READINGS];
4535 #ifdef ATH_FORCE_PPM
4536 u_int32_t save_force_val, tmp_reg;
4537 #endif
4538 u_int8_t clk_25mhz = AH9300(ah)->clk_25mhz;
4539 HAL_BOOL stopped, cal_ret;
4540 HAL_BOOL apply_last_iqcorr = AH_FALSE;
4541 uint64_t tsf;
4542
4543 if (OS_REG_READ(ah, AR_IER) == AR_IER_ENABLE) {
4544 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "** Reset called with WLAN "
4545 "interrupt enabled %08x **\n", ar9300_get_interrupts(ah));
4546 }
4547
4548 /*
4549 * Set the status to "ok" by default to cover the cases
4550 * where we return false without going to "bad"
4551 */
4552 HALASSERT(status);
4553 *status = HAL_OK;
4554 if ((ah->ah_config.ath_hal_sta_update_tx_pwr_enable)) {
4555 AH9300(ah)->green_tx_status = HAL_RSSI_TX_POWER_NONE;
4556 }
4557
4558 #if ATH_SUPPORT_MCI
4559 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
4560 (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)))
4561 {
4562 ar9300_mci_2g5g_changed(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4563 }
4564 #endif
4565
4566 ahp->ah_ext_prot_spacing = extprotspacing;
4567 ahp->ah_tx_chainmask = txchainmask & ap->ah_caps.halTxChainMask;
4568 ahp->ah_rx_chainmask = rxchainmask & ap->ah_caps.halRxChainMask;
4569 ahp->ah_tx_cal_chainmask = ap->ah_caps.halTxChainMask;
4570 ahp->ah_rx_cal_chainmask = ap->ah_caps.halRxChainMask;
4571
4572 /*
4573 * Keep the previous optinal txchainmask value
4574 */
4575
4576 HALASSERT(ar9300_check_op_mode(opmode));
4577
4578 OS_MARK(ah, AH_MARK_RESET, b_channel_change);
4579
4580 /*
4581 * Map public channel to private.
4582 */
4583 ichan = ar9300_check_chan(ah, chan);
4584 if (ichan == AH_NULL) {
4585 HALDEBUG(ah, HAL_DEBUG_CHANNEL,
4586 "%s: invalid channel %u/0x%x; no mapping\n",
4587 __func__, chan->ic_freq, chan->ic_flags);
4588 FAIL(HAL_EINVAL);
4589 }
4590
4591 ichan->paprd_table_write_done = 0; /* Clear PAPRD table write flag */
4592 #if 0
4593 chan->paprd_table_write_done = 0; /* Clear PAPRD table write flag */
4594 #endif
4595
4596 if (ar9300_get_power_mode(ah) != HAL_PM_FULL_SLEEP) {
4597 /* Need to stop RX DMA before reset otherwise chip might hang */
4598 stopped = ar9300_set_rx_abort(ah, AH_TRUE); /* abort and disable PCU */
4599 ar9300_set_rx_filter(ah, 0);
4600 stopped &= ar9300_stop_dma_receive(ah, 0); /* stop and disable RX DMA */
4601 if (!stopped) {
4602 /*
4603 * During the transition from full sleep to reset,
4604 * recv DMA regs are not available to be read
4605 */
4606 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4607 "%s[%d]: ar9300_stop_dma_receive failed\n", __func__, __LINE__);
4608 b_channel_change = AH_FALSE;
4609 }
4610 } else {
4611 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4612 "%s[%d]: Chip is already in full sleep\n", __func__, __LINE__);
4613 }
4614
4615 #if ATH_SUPPORT_MCI
4616 if ((AH_PRIVATE(ah)->ah_caps.halMciSupport) &&
4617 (ahp->ah_mci_bt_state == MCI_BT_CAL_START))
4618 {
4619 u_int32_t payload[4] = {0, 0, 0, 0};
4620
4621 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4622 "(MCI) %s: Stop rx for BT cal.\n", __func__);
4623 ahp->ah_mci_bt_state = MCI_BT_CAL;
4624
4625 /*
4626 * MCIFIX: disable mci interrupt here. This is to avoid SW_MSG_DONE or
4627 * RX_MSG bits to trigger MCI_INT and lead to mci_intr reentry.
4628 */
4629 ar9300_mci_disable_interrupt(ah);
4630
4631 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4632 "(MCI) %s: Send WLAN_CAL_GRANT\n", __func__);
4633 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
4634 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
4635
4636 /* Wait BT calibration to be completed for 25ms */
4637 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4638 "(MCI) %s: BT is calibrating.\n", __func__);
4639 if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE, 0, 25000)) {
4640 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4641 "(MCI) %s: Got BT_CAL_DONE.\n", __func__);
4642 }
4643 else {
4644 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4645 "(MCI) %s: ### BT cal takes too long. Force bt_state to be bt_awake.\n",
4646 __func__);
4647 }
4648 ahp->ah_mci_bt_state = MCI_BT_AWAKE;
4649 /* MCIFIX: enable mci interrupt here */
4650 ar9300_mci_enable_interrupt(ah);
4651
4652 return AH_TRUE;
4653 }
4654 #endif
4655
4656 /* Bring out of sleep mode */
4657 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
4658 *status = HAL_INV_PMODE;
4659 return AH_FALSE;
4660 }
4661
4662 /* Check the Rx mitigation config again, it might have changed
4663 * during attach in ath_vap_attach.
4664 */
4665 if (ah->ah_config.ath_hal_intr_mitigation_rx != 0) {
4666 ahp->ah_intr_mitigation_rx = AH_TRUE;
4667 } else {
4668 ahp->ah_intr_mitigation_rx = AH_FALSE;
4669 }
4670
4671 /*
4672 * XXX TODO FreeBSD:
4673 *
4674 * This is painful because we don't have a non-const channel pointer
4675 * at this stage.
4676 *
4677 * Make sure this gets fixed!
4678 */
4679 #if 0
4680 /* Get the value from the previous NF cal and update history buffer */
4681 if (curchan && (ahp->ah_chip_full_sleep != AH_TRUE)) {
4682
4683 if(ahp->ah_chip_reset_done){
4684 ahp->ah_chip_reset_done = 0;
4685 } else {
4686 /*
4687 * is_scan controls updating NF for home channel or off channel.
4688 * Home -> Off, update home channel
4689 * Off -> Home, update off channel
4690 * Home -> Home, uppdate home channel
4691 */
4692 if (ap->ah_curchan->channel != chan->channel)
4693 ar9300_store_new_nf(ah, curchan, !is_scan);
4694 else
4695 ar9300_store_new_nf(ah, curchan, is_scan);
4696 }
4697 }
4698 #endif
4699
4700 /*
4701 * Account for the effect of being in either the 2 GHz or 5 GHz band
4702 * on the nominal, max allowable, and min allowable noise floor values.
4703 */
4704 AH9300(ah)->nfp = IS_CHAN_2GHZ(ichan) ? &ahp->nf_2GHz : &ahp->nf_5GHz;
4705
4706 /*
4707 * XXX FreeBSD For now, don't apply the last IQ correction.
4708 *
4709 * This should be done when scorpion is enabled on FreeBSD; just be
4710 * sure to fix this channel match code so it uses net80211 flags
4711 * instead.
4712 */
4713 #if 0
4714 if (AR_SREV_SCORPION(ah) && curchan && (chan->channel == curchan->channel) &&
4715 ((chan->channel_flags & (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)) ==
4716 (curchan->channel_flags &
4717 (CHANNEL_ALL | CHANNEL_HALF | CHANNEL_QUARTER)))) {
4718 apply_last_iqcorr = AH_TRUE;
4719 }
4720 #endif
4721 apply_last_iqcorr = AH_FALSE;
4722
4723
4724 #ifndef ATH_NF_PER_CHAN
4725 /*
4726 * If there's only one full-size home-channel NF history buffer
4727 * rather than a full-size NF history buffer per channel, decide
4728 * whether to (re)initialize the home-channel NF buffer.
4729 * If this is just a channel change for a scan, or if the channel
4730 * is not being changed, don't mess up the home channel NF history
4731 * buffer with NF values from this scanned channel. If we're
4732 * changing the home channel to a new channel, reset the home-channel
4733 * NF history buffer with the most accurate NF known for the new channel.
4734 */
4735 if (!is_scan && (!ap->ah_curchan ||
4736 ap->ah_curchan->ic_freq != chan->ic_freq)) // ||
4737 // ap->ah_curchan->channel_flags != chan->channel_flags))
4738 {
4739 nf_hist_buff_reset = 1;
4740 ar9300_reset_nf_hist_buff(ah, ichan);
4741 }
4742 #endif
4743 /*
4744 * In case of
4745 * - offchan scan, or
4746 * - same channel and RX IQ Cal already available
4747 * disable RX IQ Cal.
4748 */
4749 if (is_scan) {
4750 ahp->ah_skip_rx_iq_cal = AH_TRUE;
4751 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4752 "Skip RX IQ Cal due to scanning\n");
4753 } else {
4754 #if 0
4755 /* XXX FreeBSD: always just do the RX IQ cal */
4756 /* XXX I think it's just going to speed things up; I don't think it's to avoid chan bugs */
4757 if (ahp->ah_rx_cal_complete &&
4758 ahp->ah_rx_cal_chan == ichan->channel &&
4759 ahp->ah_rx_cal_chan_flag == chan->channel_flags) {
4760 ahp->ah_skip_rx_iq_cal = AH_TRUE;
4761 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4762 "Skip RX IQ Cal due to same channel with completed RX IQ Cal\n");
4763 } else
4764 #endif
4765 ahp->ah_skip_rx_iq_cal = AH_FALSE;
4766 }
4767
4768 /* FreeBSD: clear the channel survey data */
4769 ath_hal_survey_clear(ah);
4770
4771 /*
4772 * Fast channel change (Change synthesizer based on channel freq
4773 * without resetting chip)
4774 * Don't do it when
4775 * - Flag is not set
4776 * - Chip is just coming out of full sleep
4777 * - Channel to be set is same as current channel
4778 * - Channel flags are different, like when moving from 2GHz to 5GHz
4779 * channels
4780 * - Merlin: Switching in/out of fast clock enabled channels
4781 * (not currently coded, since fast clock is enabled
4782 * across the 5GHz band
4783 * and we already do a full reset when switching in/out
4784 * of 5GHz channels)
4785 */
4786 #if 0
4787 if (b_channel_change &&
4788 (ahp->ah_chip_full_sleep != AH_TRUE) &&
4789 (AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4790 ((chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
4791 (((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & chan->channel_flags) ==
4792 ((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & AH_PRIVATE(ah)->ah_curchan->channel_flags))))
4793 {
4794 if (ar9300_channel_change(ah, chan, ichan, macmode)) {
4795 chan->channel_flags = ichan->channel_flags;
4796 chan->priv_flags = ichan->priv_flags;
4797 AH_PRIVATE(ah)->ah_curchan->ah_channel_time = 0;
4798 AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar9300_get_tsf64(ah);
4799
4800 /*
4801 * Load the NF from history buffer of the current channel.
4802 * NF is slow time-variant, so it is OK to use a historical value.
4803 */
4804 ar9300_get_nf_hist_base(ah,
4805 AH_PRIVATE(ah)->ah_curchan, is_scan, nf_buf);
4806 ar9300_load_nf(ah, nf_buf);
4807
4808 /* start NF calibration, without updating BB NF register*/
4809 ar9300_start_nf_cal(ah);
4810
4811 /*
4812 * If channel_change completed and DMA was stopped
4813 * successfully - skip the rest of reset
4814 */
4815 if (AH9300(ah)->ah_dma_stuck != AH_TRUE) {
4816 ar9300_disable_pll_lock_detect(ah);
4817 #if ATH_SUPPORT_MCI
4818 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready)
4819 {
4820 ar9300_mci_2g5g_switch(ah, AH_TRUE);
4821 }
4822 #endif
4823 return HAL_OK;
4824 }
4825 }
4826 }
4827 #endif /* #if 0 */
4828
4829 #if ATH_SUPPORT_MCI
4830 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4831 ar9300_mci_disable_interrupt(ah);
4832 if (ahp->ah_mci_ready && !save_full_sleep) {
4833 ar9300_mci_mute_bt(ah);
4834 OS_DELAY(20);
4835 OS_REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
4836 }
4837
4838 ahp->ah_mci_bt_state = MCI_BT_SLEEP;
4839 ahp->ah_mci_ready = AH_FALSE;
4840 }
4841 #endif
4842
4843 AH9300(ah)->ah_dma_stuck = AH_FALSE;
4844 #ifdef ATH_FORCE_PPM
4845 /* Preserve force ppm state */
4846 save_force_val =
4847 OS_REG_READ(ah, AR_PHY_TIMING2) &
4848 (AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4849 #endif
4850 /*
4851 * Preserve the antenna on a channel change
4852 */
4853 save_def_antenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
4854 if (0 == ahp->ah_smartantenna_enable )
4855 {
4856 if (save_def_antenna == 0) {
4857 save_def_antenna = 1;
4858 }
4859 }
4860
4861 /* Save hardware flag before chip reset clears the register */
4862 mac_sta_id1 = OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
4863
4864 /* Save led state from pci config register */
4865 save_led_state = OS_REG_READ(ah, AR_CFG_LED) &
4866 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
4867 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
4868
4869 /* Mark PHY inactive prior to reset, to be undone in ar9300_init_bb () */
4870 ar9300_mark_phy_inactive(ah);
4871
4872 /* Save/restore TSF across a potentially full reset */
4873 /* XXX TODO: only do this if we do a cold reset */
4874 tsf = ar9300_get_tsf64(ah);
4875 if (!ar9300_chip_reset(ah, chan, reset_type)) {
4876 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: chip reset failed\n", __func__);
4877 FAIL(HAL_EIO);
4878 }
4879 if (tsf != 0)
4880 ar9300_set_tsf64(ah, tsf);
4881
4882 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4883
4884
4885 /* Disable JTAG */
4886 OS_REG_SET_BIT(ah,
4887 AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
4888
4889 /*
4890 * Note that ar9300_init_chain_masks() is called from within
4891 * ar9300_process_ini() to ensure the swap bit is set before
4892 * the pdadc table is written.
4893 */
4894 ecode = ar9300_process_ini(ah, chan, ichan, macmode);
4895 if (ecode != HAL_OK) {
4896 goto bad;
4897 }
4898
4899 /*
4900 * Configuring WMAC PLL values for 25/40 MHz
4901 */
4902 if(AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah) || AR_SREV_SCORPION(ah) ) {
4903 if(clk_25mhz) {
4904 OS_REG_WRITE(ah, AR_RTC_DERIVED_RTC_CLK, (0x17c << 1)); // 32KHz sleep clk
4905 } else {
4906 OS_REG_WRITE(ah, AR_RTC_DERIVED_RTC_CLK, (0x261 << 1)); // 32KHz sleep clk
4907 }
4908 OS_DELAY(100);
4909 }
4910
4911 ahp->ah_immunity_on = AH_FALSE;
4912
4913 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
4914 ahp->tx_iq_cal_enable = OS_REG_READ_FIELD(ah,
4915 AR_PHY_TX_IQCAL_CONTROL_0(ah),
4916 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL) ?
4917 1 : 0;
4918 }
4919 ahp->tx_cl_cal_enable = (OS_REG_READ(ah, AR_PHY_CL_CAL_CTL) &
4920 AR_PHY_CL_CAL_ENABLE) ? 1 : 0;
4921
4922 /* For devices with full HW RIFS Rx support (Sowl/Howl/Merlin, etc),
4923 * restore register settings from prior to reset.
4924 */
4925 if ((AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4926 (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK))
4927 {
4928 /* Re-program RIFS Rx policy after reset */
4929 ar9300_set_rifs_delay(ah, ahp->ah_rifs_enabled);
4930 }
4931
4932 #if ATH_SUPPORT_MCI
4933 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4934 ar9300_mci_reset(ah, AH_FALSE, IS_CHAN_2GHZ(ichan), save_full_sleep);
4935 }
4936 #endif
4937
4938 /* Initialize Management Frame Protection */
4939 ar9300_init_mfp(ah);
4940
4941 ahp->ah_immunity_vals[0] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4942 AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
4943 ahp->ah_immunity_vals[1] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4944 AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
4945 ahp->ah_immunity_vals[2] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4946 AR_PHY_SFCORR_M1_THRESH);
4947 ahp->ah_immunity_vals[3] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4948 AR_PHY_SFCORR_M2_THRESH);
4949 ahp->ah_immunity_vals[4] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4950 AR_PHY_SFCORR_M2COUNT_THR);
4951 ahp->ah_immunity_vals[5] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4952 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
4953
4954 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
4955 if (IEEE80211_IS_CHAN_OFDM(chan) || IEEE80211_IS_CHAN_HT(chan)) {
4956 ar9300_set_delta_slope(ah, chan);
4957 }
4958
4959 ar9300_spur_mitigate(ah, chan);
4960 if (!ar9300_eeprom_set_board_values(ah, chan)) {
4961 HALDEBUG(ah, HAL_DEBUG_EEPROM,
4962 "%s: error setting board options\n", __func__);
4963 FAIL(HAL_EIO);
4964 }
4965
4966 #ifdef ATH_HAL_WAR_REG16284_APH128
4967 /* temp work around, will be removed. */
4968 if (AR_SREV_WASP(ah)) {
4969 OS_REG_WRITE(ah, 0x16284, 0x1553e000);
4970 }
4971 #endif
4972
4973 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4974
4975 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
4976 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
4977 | mac_sta_id1
4978 | AR_STA_ID1_RTS_USE_DEF
4979 | (ah->ah_config.ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0)
4980 | ahp->ah_sta_id1_defaults
4981 );
4982 ar9300_set_operating_mode(ah, opmode);
4983
4984 /* Set Venice BSSID mask according to current state */
4985 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssid_mask));
4986 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssid_mask + 4));
4987
4988 /* Restore previous antenna */
4989 OS_REG_WRITE(ah, AR_DEF_ANTENNA, save_def_antenna);
4990 #ifdef ATH_FORCE_PPM
4991 /* Restore force ppm state */
4992 tmp_reg = OS_REG_READ(ah, AR_PHY_TIMING2) &
4993 ~(AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4994 OS_REG_WRITE(ah, AR_PHY_TIMING2, tmp_reg | save_force_val);
4995 #endif
4996
4997 /* then our BSSID and assocID */
4998 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
4999 OS_REG_WRITE(ah, AR_BSS_ID1,
5000 LE_READ_2(ahp->ah_bssid + 4) |
5001 ((ahp->ah_assoc_id & 0x3fff) << AR_BSS_ID1_AID_S));
5002
5003 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
5004
5005 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, INIT_RSSI_THR);
5006
5007 /* HW beacon processing */
5008 /*
5009 * XXX what happens if I just leave filter_interval=0?
5010 * it stays disabled?
5011 */
5012 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_BCN_WEIGHT,
5013 INIT_RSSI_BEACON_WEIGHT);
5014 OS_REG_SET_BIT(ah, AR_HWBCNPROC1, AR_HWBCNPROC1_CRC_ENABLE |
5015 AR_HWBCNPROC1_EXCLUDE_TIM_ELM);
5016 if (ah->ah_config.ath_hal_beacon_filter_interval) {
5017 OS_REG_RMW_FIELD(ah, AR_HWBCNPROC2, AR_HWBCNPROC2_FILTER_INTERVAL,
5018 ah->ah_config.ath_hal_beacon_filter_interval);
5019 OS_REG_SET_BIT(ah, AR_HWBCNPROC2,
5020 AR_HWBCNPROC2_FILTER_INTERVAL_ENABLE);
5021 }
5022
5023
5024 /*
5025 * Set Channel now modifies bank 6 parameters for FOWL workaround
5026 * to force rf_pwd_icsyndiv bias current as function of synth
5027 * frequency.Thus must be called after ar9300_process_ini() to ensure
5028 * analog register cache is valid.
5029 */
5030 if (!ahp->ah_rf_hal.set_channel(ah, chan)) {
5031 FAIL(HAL_EIO);
5032 }
5033
5034
5035 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
5036
5037 /* Set 1:1 QCU to DCU mapping for all queues */
5038 for (i = 0; i < AR_NUM_DCU; i++) {
5039 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
5040 }
5041
5042 ahp->ah_intr_txqs = 0;
5043 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) {
5044 ar9300_reset_tx_queue(ah, i);
5045 }
5046
5047 ar9300_init_interrupt_masks(ah, opmode);
5048
5049 /* Reset ier reference count to disabled */
5050 // OS_ATOMIC_SET(&ahp->ah_ier_ref_count, 1);
5051 if (ath_hal_isrfkillenabled(ah)) {
5052 ar9300_enable_rf_kill(ah);
5053 }
5054
5055 /* must be called AFTER ini is processed */
5056 ar9300_ani_init_defaults(ah, macmode);
5057
5058 ar9300_init_qos(ah);
5059
5060 ar9300_init_user_settings(ah);
5061
5062
5063 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
5064
5065 OS_MARK(ah, AH_MARK_RESET_DONE, 0);
5066
5067 /*
5068 * disable seq number generation in hw
5069 */
5070 OS_REG_WRITE(ah, AR_STA_ID1,
5071 OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
5072
5073 ar9300_set_dma(ah);
5074
5075 /*
5076 * program OBS bus to see MAC interrupts
5077 */
5078 #if ATH_SUPPORT_MCI
5079 if (!AH_PRIVATE(ah)->ah_caps.halMciSupport) {
5080 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
5081 }
5082 #else
5083 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
5084 #endif
5085
5086
5087 /* enabling AR_GTTM_IGNORE_IDLE in GTTM register so that
5088 GTT timer will not increment if the channel idle indicates
5089 the air is busy or NAV is still counting down */
5090 OS_REG_WRITE(ah, AR_GTTM, AR_GTTM_IGNORE_IDLE);
5091
5092 /*
5093 * GTT debug mode setting
5094 */
5095 /*
5096 OS_REG_WRITE(ah, 0x64, 0x00320000);
5097 OS_REG_WRITE(ah, 0x68, 7);
5098 OS_REG_WRITE(ah, 0x4080, 0xC);
5099 */
5100 /*
5101 * Disable general interrupt mitigation by setting MIRT = 0x0
5102 * Rx and tx interrupt mitigation are conditionally enabled below.
5103 */
5104 OS_REG_WRITE(ah, AR_MIRT, 0);
5105 if (ahp->ah_intr_mitigation_rx) {
5106 /*
5107 * Enable Interrupt Mitigation for Rx.
5108 * If no build-specific limits for the rx interrupt mitigation
5109 * timer have been specified, use conservative defaults.
5110 */
5111 #ifndef AH_RIMT_VAL_LAST
5112 #define AH_RIMT_LAST_MICROSEC 500
5113 #endif
5114 #ifndef AH_RIMT_VAL_FIRST
5115 #define AH_RIMT_FIRST_MICROSEC 2000
5116 #endif
5117 #ifndef HOST_OFFLOAD
5118 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, AH_RIMT_LAST_MICROSEC);
5119 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, AH_RIMT_FIRST_MICROSEC);
5120 #else
5121 /* lower mitigation level to reduce latency for offload arch. */
5122 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST,
5123 (AH_RIMT_LAST_MICROSEC >> 2));
5124 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST,
5125 (AH_RIMT_FIRST_MICROSEC >> 2));
5126 #endif
5127 }
5128
5129 if (ahp->ah_intr_mitigation_tx) {
5130 /*
5131 * Enable Interrupt Mitigation for Tx.
5132 * If no build-specific limits for the tx interrupt mitigation
5133 * timer have been specified, use the values preferred for
5134 * the carrier group's products.
5135 */
5136 #ifndef AH_TIMT_LAST
5137 #define AH_TIMT_LAST_MICROSEC 300
5138 #endif
5139 #ifndef AH_TIMT_FIRST
5140 #define AH_TIMT_FIRST_MICROSEC 750
5141 #endif
5142 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, AH_TIMT_LAST_MICROSEC);
5143 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, AH_TIMT_FIRST_MICROSEC);
5144 }
5145
5146 rx_chainmask = ahp->ah_rx_chainmask;
5147
5148 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5149 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5150
5151 ar9300_init_bb(ah, chan);
5152
5153 /* BB Step 7: Calibration */
5154 /*
5155 * Only kick off calibration not on offchan.
5156 * If coming back from offchan, restore prevous Cal results
5157 * since chip reset will clear existings.
5158 */
5159 if (!ahp->ah_skip_rx_iq_cal) {
5160 int i;
5161 /* clear existing RX cal data */
5162 for (i=0; i<AR9300_MAX_CHAINS; i++)
5163 ahp->ah_rx_cal_corr[i] = 0;
5164
5165 ahp->ah_rx_cal_complete = AH_FALSE;
5166 // ahp->ah_rx_cal_chan = chan->channel;
5167 // ahp->ah_rx_cal_chan_flag = ichan->channel_flags;
5168 ahp->ah_rx_cal_chan = 0;
5169 ahp->ah_rx_cal_chan_flag = 0; /* XXX FreeBSD */
5170 }
5171 ar9300_invalidate_saved_cals(ah, ichan);
5172 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr);
5173
5174 #if ATH_SUPPORT_MCI
5175 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {
5176 if (IS_CHAN_2GHZ(ichan) &&
5177 (ahp->ah_mci_bt_state == MCI_BT_SLEEP))
5178 {
5179 if (ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
5180 ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE))
5181 {
5182 /*
5183 * BT is sleeping. Check if BT wakes up duing WLAN
5184 * calibration. If BT wakes up during WLAN calibration, need
5185 * to go through all message exchanges again and recal.
5186 */
5187 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
5188 "(MCI) ### %s: BT wakes up during WLAN calibration.\n",
5189 __func__);
5190 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
5191 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
5192 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
5193 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) send REMOTE_RESET\n");
5194 ar9300_mci_remote_reset(ah, AH_TRUE);
5195 ar9300_mci_send_sys_waking(ah, AH_TRUE);
5196 OS_DELAY(1);
5197 if (IS_CHAN_2GHZ(ichan)) {
5198 ar9300_mci_send_lna_transfer(ah, AH_TRUE);
5199 }
5200 ahp->ah_mci_bt_state = MCI_BT_AWAKE;
5201
5202 /* Redo calibration */
5203 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Re-calibrate.\n",
5204 __func__);
5205 ar9300_invalidate_saved_cals(ah, ichan);
5206 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr);
5207 }
5208 }
5209 ar9300_mci_enable_interrupt(ah);
5210 }
5211 #endif
5212
5213 if (!cal_ret) {
5214 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Init Cal Failed\n", __func__);
5215 FAIL(HAL_ESELFTEST);
5216 }
5217
5218 ar9300_init_txbf(ah);
5219 #if 0
5220 /*
5221 * WAR for owl 1.0 - restore chain mask for 2-chain cfgs after cal
5222 */
5223 rx_chainmask = ahp->ah_rx_chainmask;
5224 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
5225 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5226 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5227 }
5228 #endif
5229
5230 /* Restore previous led state */
5231 OS_REG_WRITE(ah, AR_CFG_LED, save_led_state | AR_CFG_SCLK_32KHZ);
5232
5233 #if ATH_BT_COEX
5234 if (ahp->ah_bt_coex_config_type != HAL_BT_COEX_CFG_NONE) {
5235 ar9300_init_bt_coex(ah);
5236
5237 #if ATH_SUPPORT_MCI
5238 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {
5239 /* Check BT state again to make sure it's not changed. */
5240 ar9300_mci_sync_bt_state(ah);
5241 ar9300_mci_2g5g_switch(ah, AH_TRUE);
5242
5243 if ((ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
5244 (ahp->ah_mci_query_bt == AH_TRUE))
5245 {
5246 ahp->ah_mci_need_flush_btinfo = AH_TRUE;
5247 }
5248 }
5249 #endif
5250 }
5251 #endif
5252
5253 /* Start TSF2 for generic timer 8-15. */
5254 ar9300_start_tsf2(ah);
5255
5256 /* MIMO Power save setting */
5257 if (ar9300_get_capability(ah, HAL_CAP_DYNAMIC_SMPS, 0, AH_NULL) == HAL_OK) {
5258 ar9300_set_sm_power_mode(ah, ahp->ah_sm_power_mode);
5259 }
5260
5261 /*
5262 * For big endian systems turn on swapping for descriptors
5263 */
5264 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
5265 if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) {
5266 OS_REG_RMW(ah, AR_CFG, AR_CFG_SWTB | AR_CFG_SWRB, 0);
5267 } else {
5268 ar9300_init_cfg_reg(ah);
5269 }
5270 #endif
5271
5272 if ( AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah) ) {
5273 OS_REG_RMW(ah, AR_CFG_LED, AR_CFG_LED_ASSOC_CTL, AR_CFG_LED_ASSOC_CTL);
5274 }
5275
5276 #if !(defined(ART_BUILD)) && defined(ATH_SUPPORT_LED)
5277 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
5278 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
5279 #define ATH_GPIO_OUT_FUNCTION3 0xB8040038
5280 #define ATH_GPIO_OE 0xB8040000
5281 if ( AR_SREV_WASP(ah)) {
5282 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
5283 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x33 << 8) );
5284 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )));
5285 }
5286 else {
5287
5288 /* Disable 2G WLAN LED. During ath_open, reset function is called even before channel is set.
5289 So 2GHz is taken as default and it also blinks. Hence
5290 to avoid both from blinking, disable 2G led while in 5G mode */
5291
5292 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) | (1 << 13) ));
5293 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x33) );
5294 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )));
5295 }
5296
5297 }
5298 else if (AR_SREV_SCORPION(ah)) {
5299 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
5300 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x2F << 8) );
5301 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )) | (0x1 << 12)));
5302 } else if (IS_CHAN_5GHZ((AH_PRIVATE(ah)->ah_curchan))) {
5303 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x2F) );
5304 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )) | (0x1 << 13)));
5305 }
5306 }
5307 else if (AR_SREV_HONEYBEE(ah)) {
5308 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x32) );
5309 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) ))));
5310 }
5311 #undef REG_READ
5312 #undef REG_WRITE
5313 #endif
5314
5315 /* XXX FreeBSD What's this? -adrian */
5316 #if 0
5317 chan->channel_flags = ichan->channel_flags;
5318 chan->priv_flags = ichan->priv_flags;
5319 #endif
5320
5321 #if FIX_NOISE_FLOOR
5322 /* XXX FreeBSD is ichan appropariate? It was curchan.. */
5323 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
5324 ar9300_load_nf(ah, nf_buf);
5325 /* XXX TODO: handle NF load failure */
5326 if (nf_hist_buff_reset == 1)
5327 {
5328 nf_hist_buff_reset = 0;
5329 #ifndef ATH_NF_PER_CHAN
5330 if (First_NFCal(ah, ichan, is_scan, chan)){
5331 if (ahp->ah_skip_rx_iq_cal && !is_scan) {
5332 /* restore RX Cal result if existing */
5333 ar9300_rx_iq_cal_restore(ah);
5334 ahp->ah_skip_rx_iq_cal = AH_FALSE;
5335 }
5336 }
5337 #endif /* ATH_NF_PER_CHAN */
5338 }
5339 else{
5340 ar9300_start_nf_cal(ah);
5341 }
5342 #endif
5343
5344 #ifdef AH_SUPPORT_AR9300
5345 /* BB Panic Watchdog */
5346 if (ar9300_get_capability(ah, HAL_CAP_BB_PANIC_WATCHDOG, 0, AH_NULL) ==
5347 HAL_OK)
5348 {
5349 ar9300_config_bb_panic_watchdog(ah);
5350 }
5351 #endif
5352
5353 /* While receiving unsupported rate frame receive state machine
5354 * gets into a state 0xb and if phy_restart happens when rx
5355 * state machine is in 0xb state, BB would go hang, if we
5356 * see 0xb state after first bb panic, make sure that we
5357 * disable the phy_restart.
5358 *
5359 * There may be multiple panics, make sure that we always do
5360 * this if we see this panic at least once. This is required
5361 * because reset seems to be writing from INI file.
5362 */
5363 if ((ar9300_get_capability(ah, HAL_CAP_PHYRESTART_CLR_WAR, 0, AH_NULL)
5364 == HAL_OK) && (((MS((AH9300(ah)->ah_bb_panic_last_status),
5365 AR_PHY_BB_WD_RX_OFDM_SM)) == 0xb) ||
5366 AH9300(ah)->ah_phyrestart_disabled) )
5367 {
5368 ar9300_disable_phy_restart(ah, 1);
5369 }
5370
5371
5372
5373 ahp->ah_radar1 = MS(OS_REG_READ(ah, AR_PHY_RADAR_1),
5374 AR_PHY_RADAR_1_CF_BIN_THRESH);
5375 ahp->ah_dc_offset = MS(OS_REG_READ(ah, AR_PHY_TIMING2),
5376 AR_PHY_TIMING2_DC_OFFSET);
5377 ahp->ah_disable_cck = MS(OS_REG_READ(ah, AR_PHY_MODE),
5378 AR_PHY_MODE_DISABLE_CCK);
5379
5380 if (AH9300(ah)->ah_enable_keysearch_always) {
5381 ar9300_enable_keysearch_always(ah, 1);
5382 }
5383
5384 #if ATH_LOW_POWER_ENABLE
5385 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val)
5386 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
5387 if (AR_SREV_OSPREY(ah)) {
5388 REG_WRITE(0xb4000080, REG_READ(0xb4000080) | 3);
5389 OS_REG_WRITE(ah, AR_RTC_RESET, 1);
5390 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL),
5391 AR_PCIE_PM_CTRL_ENA);
5392 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_SPARE), 0xffffffff);
5393 }
5394 #undef REG_READ
5395 #undef REG_WRITE
5396 #endif /* ATH_LOW_POWER_ENABLE */
5397
5398 ar9300_disable_pll_lock_detect(ah);
5399
5400 /* H/W Green TX */
5401 ar9300_control_signals_for_green_tx_mode(ah);
5402 /* Smart Antenna, only for 5GHz on Scropion */
5403 if (IEEE80211_IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan)) && AR_SREV_SCORPION(ah)) {
5404 ahp->ah_smartantenna_enable = 0;
5405 }
5406
5407 ar9300_set_smart_antenna(ah, ahp->ah_smartantenna_enable);
5408
5409 if (AR_SREV_APHRODITE(ah) && ahp->ah_lna_div_use_bt_ant_enable)
5410 OS_REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
5411
5412 if (ahp->ah_skip_rx_iq_cal && !is_scan) {
5413 /* restore RX Cal result if existing */
5414 ar9300_rx_iq_cal_restore(ah);
5415 ahp->ah_skip_rx_iq_cal = AH_FALSE;
5416 }
5417
5418
5419 return AH_TRUE;
5420 bad:
5421 OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
5422 *status = ecode;
5423
5424 if (ahp->ah_skip_rx_iq_cal && !is_scan) {
5425 /* restore RX Cal result if existing */
5426 ar9300_rx_iq_cal_restore(ah);
5427 ahp->ah_skip_rx_iq_cal = AH_FALSE;
5428 }
5429
5430 return AH_FALSE;
5431 #undef FAIL
5432 }
5433
5434 void
ar9300_green_ap_ps_on_off(struct ath_hal * ah,u_int16_t on_off)5435 ar9300_green_ap_ps_on_off( struct ath_hal *ah, u_int16_t on_off)
5436 {
5437 /* Set/reset the ps flag */
5438 AH9300(ah)->green_ap_ps_on = !!on_off;
5439 }
5440
5441 /*
5442 * This function returns 1, where it is possible to do
5443 * single-chain power save.
5444 */
5445 u_int16_t
ar9300_is_single_ant_power_save_possible(struct ath_hal * ah)5446 ar9300_is_single_ant_power_save_possible(struct ath_hal *ah)
5447 {
5448 return AH_TRUE;
5449 }
5450
5451 /* To avoid compilation warnings. Functions not used when EMULATION. */
5452 /*
5453 * ar9300_find_mag_approx()
5454 */
5455 static int32_t
ar9300_find_mag_approx(struct ath_hal * ah,int32_t in_re,int32_t in_im)5456 ar9300_find_mag_approx(struct ath_hal *ah, int32_t in_re, int32_t in_im)
5457 {
5458 int32_t abs_i = abs(in_re);
5459 int32_t abs_q = abs(in_im);
5460 int32_t max_abs, min_abs;
5461
5462 if (abs_i > abs_q) {
5463 max_abs = abs_i;
5464 min_abs = abs_q;
5465 } else {
5466 max_abs = abs_q;
5467 min_abs = abs_i;
5468 }
5469
5470 return (max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4));
5471 }
5472
5473 /*
5474 * ar9300_solve_iq_cal()
5475 * solve 4x4 linear equation used in loopback iq cal.
5476 */
5477 static HAL_BOOL
ar9300_solve_iq_cal(struct ath_hal * ah,int32_t sin_2phi_1,int32_t cos_2phi_1,int32_t sin_2phi_2,int32_t cos_2phi_2,int32_t mag_a0_d0,int32_t phs_a0_d0,int32_t mag_a1_d0,int32_t phs_a1_d0,int32_t solved_eq[])5478 ar9300_solve_iq_cal(
5479 struct ath_hal *ah,
5480 int32_t sin_2phi_1,
5481 int32_t cos_2phi_1,
5482 int32_t sin_2phi_2,
5483 int32_t cos_2phi_2,
5484 int32_t mag_a0_d0,
5485 int32_t phs_a0_d0,
5486 int32_t mag_a1_d0,
5487 int32_t phs_a1_d0,
5488 int32_t solved_eq[])
5489 {
5490 int32_t f1 = cos_2phi_1 - cos_2phi_2;
5491 int32_t f3 = sin_2phi_1 - sin_2phi_2;
5492 int32_t f2;
5493 int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5494 const int32_t result_shift = 1 << 15;
5495
5496 f2 = (((int64_t)f1 * (int64_t)f1) / result_shift) + (((int64_t)f3 * (int64_t)f3) / result_shift);
5497
5498 if (0 == f2) {
5499 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Divide by 0(%d).\n",
5500 __func__, __LINE__);
5501 return AH_FALSE;
5502 }
5503
5504 /* magnitude mismatch, tx */
5505 mag_tx = f1 * (mag_a0_d0 - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
5506 /* phase mismatch, tx */
5507 phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
5508
5509 mag_tx = (mag_tx / f2);
5510 phs_tx = (phs_tx / f2);
5511
5512 /* magnitude mismatch, rx */
5513 mag_rx =
5514 mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) / result_shift;
5515 /* phase mismatch, rx */
5516 phs_rx =
5517 phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) / result_shift;
5518
5519 solved_eq[0] = mag_tx;
5520 solved_eq[1] = phs_tx;
5521 solved_eq[2] = mag_rx;
5522 solved_eq[3] = phs_rx;
5523
5524 return AH_TRUE;
5525 }
5526
5527 /*
5528 * ar9300_calc_iq_corr()
5529 */
5530 static HAL_BOOL
ar9300_calc_iq_corr(struct ath_hal * ah,int32_t chain_idx,const int32_t iq_res[],int32_t iqc_coeff[])5531 ar9300_calc_iq_corr(struct ath_hal *ah, int32_t chain_idx,
5532 const int32_t iq_res[], int32_t iqc_coeff[])
5533 {
5534 int32_t i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0;
5535 int32_t i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1;
5536 int32_t i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0;
5537 int32_t i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
5538 int32_t mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1;
5539 int32_t phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1;
5540 int32_t sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2;
5541 int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5542 int32_t solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx;
5543 int32_t q_q_coff, q_i_coff;
5544 const int32_t res_scale = 1 << 15;
5545 const int32_t delpt_shift = 1 << 8;
5546 int32_t mag1, mag2;
5547
5548 i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
5549 i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
5550 iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
5551
5552 if (i2_m_q2_a0_d0 > 0x800) {
5553 i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
5554 }
5555 if (iq_corr_a0_d0 > 0x800) {
5556 iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
5557 }
5558
5559 i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
5560 i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
5561 iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
5562
5563 if (i2_m_q2_a0_d1 > 0x800) {
5564 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
5565 }
5566 if (iq_corr_a0_d1 > 0x800) {
5567 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
5568 }
5569
5570 i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
5571 i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
5572 iq_corr_a1_d0 = iq_res[4] & 0xfff;
5573
5574 if (i2_m_q2_a1_d0 > 0x800) {
5575 i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
5576 }
5577 if (iq_corr_a1_d0 > 0x800) {
5578 iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
5579 }
5580
5581 i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
5582 i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
5583 iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
5584
5585 if (i2_m_q2_a1_d1 > 0x800) {
5586 i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
5587 }
5588 if (iq_corr_a1_d1 > 0x800) {
5589 iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
5590 }
5591
5592 if ((i2_p_q2_a0_d0 == 0) ||
5593 (i2_p_q2_a0_d1 == 0) ||
5594 (i2_p_q2_a1_d0 == 0) ||
5595 (i2_p_q2_a1_d1 == 0)) {
5596 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5597 "%s: Divide by 0(%d):\na0_d0=%d\na0_d1=%d\na2_d0=%d\na1_d1=%d\n",
5598 __func__, __LINE__,
5599 i2_p_q2_a0_d0, i2_p_q2_a0_d1, i2_p_q2_a1_d0, i2_p_q2_a1_d1);
5600 return AH_FALSE;
5601 }
5602
5603 if ((i2_p_q2_a0_d0 <= 1024) || (i2_p_q2_a0_d0 > 2047) ||
5604 (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) ||
5605 (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) ||
5606 (i2_p_q2_a0_d0 <= iq_corr_a0_d0) ||
5607 (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) ||
5608 (i2_p_q2_a0_d1 <= iq_corr_a0_d1) ||
5609 (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) ||
5610 (i2_p_q2_a1_d0 <= iq_corr_a1_d0) ||
5611 (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) ||
5612 (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) {
5613 return AH_FALSE;
5614 }
5615
5616 mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5617 phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5618
5619 mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5620 phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5621
5622 mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5623 phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5624
5625 mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5626 phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5627
5628 /* without analog phase shift */
5629 sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
5630 /* without analog phase shift */
5631 cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
5632 /* with analog phase shift */
5633 sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
5634 /* with analog phase shift */
5635 cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
5636
5637 /* force sin^2 + cos^2 = 1; */
5638 /* find magnitude by approximation */
5639 mag1 = ar9300_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
5640 mag2 = ar9300_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
5641
5642 if ((mag1 == 0) || (mag2 == 0)) {
5643 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5644 "%s: Divide by 0(%d): mag1=%d, mag2=%d\n",
5645 __func__, __LINE__, mag1, mag2);
5646 return AH_FALSE;
5647 }
5648
5649 /* normalization sin and cos by mag */
5650 sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
5651 cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
5652 sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
5653 cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
5654
5655 /* calculate IQ mismatch */
5656 if (AH_FALSE == ar9300_solve_iq_cal(ah,
5657 sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2, mag_a0_d0,
5658 phs_a0_d0, mag_a1_d0, phs_a1_d0, solved_eq))
5659 {
5660 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5661 "%s: Call to ar9300_solve_iq_cal failed.\n", __func__);
5662 return AH_FALSE;
5663 }
5664
5665 mag_tx = solved_eq[0];
5666 phs_tx = solved_eq[1];
5667 mag_rx = solved_eq[2];
5668 phs_rx = solved_eq[3];
5669
5670 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5671 "%s: chain %d: mag mismatch=%d phase mismatch=%d\n",
5672 __func__, chain_idx, mag_tx / res_scale, phs_tx / res_scale);
5673
5674 if (res_scale == mag_tx) {
5675 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5676 "%s: Divide by 0(%d): mag_tx=%d, res_scale=%d\n",
5677 __func__, __LINE__, mag_tx, res_scale);
5678 return AH_FALSE;
5679 }
5680
5681 /* calculate and quantize Tx IQ correction factor */
5682 mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
5683 phs_corr_tx = -phs_tx;
5684
5685 q_q_coff = (mag_corr_tx * 128 / res_scale);
5686 q_i_coff = (phs_corr_tx * 256 / res_scale);
5687
5688 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5689 "%s: tx chain %d: mag corr=%d phase corr=%d\n",
5690 __func__, chain_idx, q_q_coff, q_i_coff);
5691
5692 if (q_i_coff < -63) {
5693 q_i_coff = -63;
5694 }
5695 if (q_i_coff > 63) {
5696 q_i_coff = 63;
5697 }
5698 if (q_q_coff < -63) {
5699 q_q_coff = -63;
5700 }
5701 if (q_q_coff > 63) {
5702 q_q_coff = 63;
5703 }
5704
5705 iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
5706
5707 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: tx chain %d: iq corr coeff=%x\n",
5708 __func__, chain_idx, iqc_coeff[0]);
5709
5710 if (-mag_rx == res_scale) {
5711 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5712 "%s: Divide by 0(%d): mag_rx=%d, res_scale=%d\n",
5713 __func__, __LINE__, mag_rx, res_scale);
5714 return AH_FALSE;
5715 }
5716
5717 /* calculate and quantize Rx IQ correction factors */
5718 mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
5719 phs_corr_rx = -phs_rx;
5720
5721 q_q_coff = (mag_corr_rx * 128 / res_scale);
5722 q_i_coff = (phs_corr_rx * 256 / res_scale);
5723
5724 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5725 "%s: rx chain %d: mag corr=%d phase corr=%d\n",
5726 __func__, chain_idx, q_q_coff, q_i_coff);
5727
5728 if (q_i_coff < -63) {
5729 q_i_coff = -63;
5730 }
5731 if (q_i_coff > 63) {
5732 q_i_coff = 63;
5733 }
5734 if (q_q_coff < -63) {
5735 q_q_coff = -63;
5736 }
5737 if (q_q_coff > 63) {
5738 q_q_coff = 63;
5739 }
5740
5741 iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
5742
5743 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: rx chain %d: iq corr coeff=%x\n",
5744 __func__, chain_idx, iqc_coeff[1]);
5745
5746 return AH_TRUE;
5747 }
5748
5749 #define MAX_MAG_DELTA 11 //maximum magnitude mismatch delta across gains
5750 #define MAX_PHS_DELTA 10 //maximum phase mismatch delta across gains
5751 #define ABS(x) ((x) >= 0 ? (x) : (-(x)))
5752
5753 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5754 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5755 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5756 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5757 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5758 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5759 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5760 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5761 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5762 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5763 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5764 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5765 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5766 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5767 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5768 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5769 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5770 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5771 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5772 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5773 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5774 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5775 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5776 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5777 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5778 };
5779
5780 static void
ar9300_tx_iq_cal_outlier_detection(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan,u_int32_t num_chains,struct coeff_t * coeff,HAL_BOOL is_cal_reusable)5781 ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan, u_int32_t num_chains,
5782 struct coeff_t *coeff, HAL_BOOL is_cal_reusable)
5783 {
5784 int nmeasurement, ch_idx, im;
5785 int32_t magnitude, phase;
5786 int32_t magnitude_max, phase_max;
5787 int32_t magnitude_min, phase_min;
5788
5789 int32_t magnitude_max_idx, phase_max_idx;
5790 int32_t magnitude_min_idx, phase_min_idx;
5791
5792 int32_t magnitude_avg, phase_avg;
5793 int32_t outlier_mag_idx = 0;
5794 int32_t outlier_phs_idx = 0;
5795
5796
5797 if (AR_SREV_POSEIDON(ah)) {
5798 HALASSERT(num_chains == 0x1);
5799
5800 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5801 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5802 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5803 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5804 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5805 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5806 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5807 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5808 }
5809
5810 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5811 nmeasurement = OS_REG_READ_FIELD(ah,
5812 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
5813 if (nmeasurement > MAX_MEASUREMENT) {
5814 nmeasurement = MAX_MEASUREMENT;
5815 }
5816
5817 if (!AR_SREV_SCORPION(ah)) {
5818 /*
5819 * reset max/min variable to min/max values so that
5820 * we always start with 1st calibrated gain value
5821 */
5822 magnitude_max = -64;
5823 phase_max = -64;
5824 magnitude_min = 63;
5825 phase_min = 63;
5826 magnitude_avg = 0;
5827 phase_avg = 0;
5828 magnitude_max_idx = 0;
5829 magnitude_min_idx = 0;
5830 phase_max_idx = 0;
5831 phase_min_idx = 0;
5832
5833 /* detect outlier only if nmeasurement > 1 */
5834 if (nmeasurement > 1) {
5835 /* printf("----------- start outlier detection -----------\n"); */
5836 /*
5837 * find max/min and phase/mag mismatch across all calibrated gains
5838 */
5839 for (im = 0; im < nmeasurement; im++) {
5840 magnitude = coeff->mag_coeff[ch_idx][im][0];
5841 phase = coeff->phs_coeff[ch_idx][im][0];
5842
5843 magnitude_avg = magnitude_avg + magnitude;
5844 phase_avg = phase_avg + phase;
5845 if (magnitude > magnitude_max) {
5846 magnitude_max = magnitude;
5847 magnitude_max_idx = im;
5848 }
5849 if (magnitude < magnitude_min) {
5850 magnitude_min = magnitude;
5851 magnitude_min_idx = im;
5852 }
5853 if (phase > phase_max) {
5854 phase_max = phase;
5855 phase_max_idx = im;
5856 }
5857 if (phase < phase_min) {
5858 phase_min = phase;
5859 phase_min_idx = im;
5860 }
5861 }
5862 /* find average (exclude max abs value) */
5863 for (im = 0; im < nmeasurement; im++) {
5864 magnitude = coeff->mag_coeff[ch_idx][im][0];
5865 phase = coeff->phs_coeff[ch_idx][im][0];
5866 if ((ABS(magnitude) < ABS(magnitude_max)) ||
5867 (ABS(magnitude) < ABS(magnitude_min)))
5868 {
5869 magnitude_avg = magnitude_avg + magnitude;
5870 }
5871 if ((ABS(phase) < ABS(phase_max)) ||
5872 (ABS(phase) < ABS(phase_min)))
5873 {
5874 phase_avg = phase_avg + phase;
5875 }
5876 }
5877 magnitude_avg = magnitude_avg / (nmeasurement - 1);
5878 phase_avg = phase_avg / (nmeasurement - 1);
5879
5880 /* detect magnitude outlier */
5881 if (ABS(magnitude_max - magnitude_min) > MAX_MAG_DELTA) {
5882 if (ABS(magnitude_max - magnitude_avg) >
5883 ABS(magnitude_min - magnitude_avg))
5884 {
5885 /* max is outlier, force to avg */
5886 outlier_mag_idx = magnitude_max_idx;
5887 } else {
5888 /* min is outlier, force to avg */
5889 outlier_mag_idx = magnitude_min_idx;
5890 }
5891 coeff->mag_coeff[ch_idx][outlier_mag_idx][0] = magnitude_avg;
5892 coeff->phs_coeff[ch_idx][outlier_mag_idx][0] = phase_avg;
5893 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5894 "[ch%d][outlier mag gain%d]:: "
5895 "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5896 ch_idx, outlier_mag_idx, magnitude_avg, phase_avg);
5897 }
5898 /* detect phase outlier */
5899 if (ABS(phase_max - phase_min) > MAX_PHS_DELTA) {
5900 if (ABS(phase_max-phase_avg) > ABS(phase_min - phase_avg)) {
5901 /* max is outlier, force to avg */
5902 outlier_phs_idx = phase_max_idx;
5903 } else{
5904 /* min is outlier, force to avg */
5905 outlier_phs_idx = phase_min_idx;
5906 }
5907 coeff->mag_coeff[ch_idx][outlier_phs_idx][0] = magnitude_avg;
5908 coeff->phs_coeff[ch_idx][outlier_phs_idx][0] = phase_avg;
5909 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5910 "[ch%d][outlier phs gain%d]:: "
5911 "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5912 ch_idx, outlier_phs_idx, magnitude_avg, phase_avg);
5913 }
5914 }
5915 }
5916
5917 /*printf("------------ after outlier detection -------------\n");*/
5918 for (im = 0; im < nmeasurement; im++) {
5919 magnitude = coeff->mag_coeff[ch_idx][im][0];
5920 phase = coeff->phs_coeff[ch_idx][im][0];
5921
5922 #if 0
5923 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
5924 ch_idx, im, magnitude, phase);
5925 #endif
5926
5927 coeff->iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
5928
5929 if ((im % 2) == 0) {
5930 OS_REG_RMW_FIELD(ah,
5931 tx_corr_coeff[im][ch_idx],
5932 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5933 coeff->iqc_coeff[0]);
5934 } else {
5935 OS_REG_RMW_FIELD(ah,
5936 tx_corr_coeff[im][ch_idx],
5937 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5938 coeff->iqc_coeff[0]);
5939 }
5940 #if ATH_SUPPORT_CAL_REUSE
5941 ichan->tx_corr_coeff[im][ch_idx] = coeff->iqc_coeff[0];
5942 #endif
5943 }
5944 #if ATH_SUPPORT_CAL_REUSE
5945 ichan->num_measures[ch_idx] = nmeasurement;
5946 #endif
5947 }
5948
5949 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5950 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5951 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
5952 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
5953
5954 #if ATH_SUPPORT_CAL_REUSE
5955 if (is_cal_reusable) {
5956 ichan->one_time_txiqcal_done = AH_TRUE;
5957 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
5958 "(FCS) TXIQCAL saved - %d\n", ichan->channel);
5959 }
5960 #endif
5961 }
5962
5963 #if ATH_SUPPORT_CAL_REUSE
5964 static void
ar9300_tx_iq_cal_apply(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan)5965 ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
5966 {
5967 struct ath_hal_9300 *ahp = AH9300(ah);
5968 int nmeasurement, ch_idx, im;
5969
5970 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5971 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5972 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5973 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5974 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5975 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5976 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5977 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5978 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5979 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5980 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5981 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5982 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5983 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5984 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5985 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5986 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5987 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5988 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5989 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5990 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5991 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5992 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5993 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5994 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5995 };
5996
5997 if (AR_SREV_POSEIDON(ah)) {
5998 HALASSERT(ahp->ah_tx_cal_chainmask == 0x1);
5999
6000 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
6001 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
6002 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
6003 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
6004 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
6005 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
6006 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
6007 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
6008 }
6009
6010 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
6011 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
6012 continue;
6013 }
6014 nmeasurement = ichan->num_measures[ch_idx];
6015
6016 for (im = 0; im < nmeasurement; im++) {
6017 if ((im % 2) == 0) {
6018 OS_REG_RMW_FIELD(ah,
6019 tx_corr_coeff[im][ch_idx],
6020 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
6021 ichan->tx_corr_coeff[im][ch_idx]);
6022 } else {
6023 OS_REG_RMW_FIELD(ah,
6024 tx_corr_coeff[im][ch_idx],
6025 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
6026 ichan->tx_corr_coeff[im][ch_idx]);
6027 }
6028 }
6029 }
6030
6031 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
6032 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
6033 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
6034 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
6035 }
6036 #endif
6037
6038 /*
6039 * ar9300_tx_iq_cal_hw_run is only needed for osprey/wasp/hornet
6040 * It is not needed for jupiter/poseidon.
6041 */
6042 HAL_BOOL
ar9300_tx_iq_cal_hw_run(struct ath_hal * ah)6043 ar9300_tx_iq_cal_hw_run(struct ath_hal *ah)
6044 {
6045 int is_tx_gain_forced;
6046
6047 is_tx_gain_forced = OS_REG_READ_FIELD(ah,
6048 AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE);
6049 if (is_tx_gain_forced) {
6050 /*printf("Tx gain can not be forced during tx I/Q cal!\n");*/
6051 OS_REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE, 0);
6052 }
6053
6054 /* enable tx IQ cal */
6055 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START(ah),
6056 AR_PHY_TX_IQCAL_START_DO_CAL, AR_PHY_TX_IQCAL_START_DO_CAL);
6057
6058 if (!ath_hal_wait(ah,
6059 AR_PHY_TX_IQCAL_START(ah), AR_PHY_TX_IQCAL_START_DO_CAL, 0))
6060 {
6061 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6062 "%s: Tx IQ Cal is never completed.\n", __func__);
6063 return AH_FALSE;
6064 }
6065 return AH_TRUE;
6066 }
6067
6068 static void
ar9300_tx_iq_cal_post_proc(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan,int iqcal_idx,int max_iqcal,HAL_BOOL is_cal_reusable,HAL_BOOL apply_last_corr)6069 ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
6070 int iqcal_idx, int max_iqcal,HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr)
6071 {
6072 int nmeasurement=0, im, ix, iy, temp;
6073 struct ath_hal_9300 *ahp = AH9300(ah);
6074 u_int32_t txiqcal_status[AR9300_MAX_CHAINS] = {
6075 AR_PHY_TX_IQCAL_STATUS_B0(ah),
6076 AR_PHY_TX_IQCAL_STATUS_B1,
6077 AR_PHY_TX_IQCAL_STATUS_B2,
6078 };
6079 const u_int32_t chan_info_tab[] = {
6080 AR_PHY_CHAN_INFO_TAB_0,
6081 AR_PHY_CHAN_INFO_TAB_1,
6082 AR_PHY_CHAN_INFO_TAB_2,
6083 };
6084 int32_t iq_res[6];
6085 int32_t ch_idx, j;
6086 u_int32_t num_chains = 0;
6087 static struct coeff_t coeff;
6088 txiqcal_status[0] = AR_PHY_TX_IQCAL_STATUS_B0(ah);
6089
6090 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
6091 if (ahp->ah_tx_chainmask & (1 << ch_idx)) {
6092 num_chains++;
6093 }
6094 }
6095
6096 if (apply_last_corr) {
6097 if (coeff.last_cal == AH_TRUE) {
6098 int32_t magnitude, phase;
6099 int ch_idx, im;
6100 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
6101 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
6102 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
6103 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
6104 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
6105 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
6106 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
6107 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
6108 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
6109 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
6110 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
6111 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
6112 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
6113 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
6114 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
6115 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
6116 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
6117 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
6118 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
6119 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
6120 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
6121 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
6122 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
6123 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
6124 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
6125 };
6126 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
6127 for (im = 0; im < coeff.last_nmeasurement; im++) {
6128 magnitude = coeff.mag_coeff[ch_idx][im][0];
6129 phase = coeff.phs_coeff[ch_idx][im][0];
6130
6131 #if 0
6132 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
6133 ch_idx, im, magnitude, phase);
6134 #endif
6135
6136 coeff.iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
6137 if ((im % 2) == 0) {
6138 OS_REG_RMW_FIELD(ah,
6139 tx_corr_coeff[im][ch_idx],
6140 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
6141 coeff.iqc_coeff[0]);
6142 } else {
6143 OS_REG_RMW_FIELD(ah,
6144 tx_corr_coeff[im][ch_idx],
6145 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
6146 coeff.iqc_coeff[0]);
6147 }
6148 }
6149 }
6150 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
6151 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
6152 }
6153 return;
6154 }
6155
6156
6157 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
6158 nmeasurement = OS_REG_READ_FIELD(ah,
6159 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
6160 if (nmeasurement > MAX_MEASUREMENT) {
6161 nmeasurement = MAX_MEASUREMENT;
6162 }
6163
6164 for (im = 0; im < nmeasurement; im++) {
6165 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6166 "%s: Doing Tx IQ Cal for chain %d.\n", __func__, ch_idx);
6167 if (OS_REG_READ(ah, txiqcal_status[ch_idx]) &
6168 AR_PHY_TX_IQCAL_STATUS_FAILED)
6169 {
6170 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6171 "%s: Tx IQ Cal failed for chain %d.\n", __func__, ch_idx);
6172 goto TX_IQ_CAL_FAILED_;
6173 }
6174
6175 for (j = 0; j < 3; j++) {
6176 u_int32_t idx = 2 * j;
6177 /* 3 registers for each calibration result */
6178 u_int32_t offset = 4 * (3 * im + j);
6179
6180 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
6181 AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
6182 /* 32 bits */
6183 iq_res[idx] = OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
6184 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
6185 AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
6186 /* 16 bits */
6187 iq_res[idx + 1] = 0xffff &
6188 OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
6189
6190 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6191 "%s: IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
6192 __func__, idx, iq_res[idx], idx + 1, iq_res[idx + 1]);
6193 }
6194
6195 if (AH_FALSE == ar9300_calc_iq_corr(
6196 ah, ch_idx, iq_res, coeff.iqc_coeff))
6197 {
6198 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6199 "%s: Failed in calculation of IQ correction.\n",
6200 __func__);
6201 goto TX_IQ_CAL_FAILED_;
6202 }
6203
6204 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] = coeff.iqc_coeff[0] & 0x7f;
6205 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] = (coeff.iqc_coeff[0] >> 7) & 0x7f;
6206 if (coeff.mag_coeff[ch_idx][im][iqcal_idx-1] > 63) {
6207 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] -= 128;
6208 }
6209 if (coeff.phs_coeff[ch_idx][im][iqcal_idx-1] > 63) {
6210 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] -= 128;
6211 }
6212 #if 0
6213 ath_hal_printf(ah, "IQCAL::[ch%d][gain%d]:: mag = %d phase = %d \n",
6214 ch_idx, im, coeff.mag_coeff[ch_idx][im][iqcal_idx-1],
6215 coeff.phs_coeff[ch_idx][im][iqcal_idx-1]);
6216 #endif
6217 }
6218 }
6219 //last iteration; calculate mag and phs
6220 if (iqcal_idx == max_iqcal) {
6221 if (max_iqcal>1) {
6222 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
6223 for (im = 0; im < nmeasurement; im++) {
6224 //sort mag and phs
6225 for( ix=0;ix<max_iqcal-1;ix++){
6226 for( iy=ix+1;iy<=max_iqcal-1;iy++){
6227 if(coeff.mag_coeff[ch_idx][im][iy] <
6228 coeff.mag_coeff[ch_idx][im][ix]) {
6229 //swap
6230 temp=coeff.mag_coeff[ch_idx][im][ix];
6231 coeff.mag_coeff[ch_idx][im][ix] = coeff.mag_coeff[ch_idx][im][iy];
6232 coeff.mag_coeff[ch_idx][im][iy] = temp;
6233 }
6234 if(coeff.phs_coeff[ch_idx][im][iy] <
6235 coeff.phs_coeff[ch_idx][im][ix]){
6236 //swap
6237 temp=coeff.phs_coeff[ch_idx][im][ix];
6238 coeff.phs_coeff[ch_idx][im][ix]=coeff.phs_coeff[ch_idx][im][iy];
6239 coeff.phs_coeff[ch_idx][im][iy]=temp;
6240 }
6241 }
6242 }
6243 //select median; 3rd entry in the sorted array
6244 coeff.mag_coeff[ch_idx][im][0] =
6245 coeff.mag_coeff[ch_idx][im][max_iqcal/2];
6246 coeff.phs_coeff[ch_idx][im][0] =
6247 coeff.phs_coeff[ch_idx][im][max_iqcal/2];
6248 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6249 "IQCAL: Median [ch%d][gain%d]:: mag = %d phase = %d \n",
6250 ch_idx, im,coeff.mag_coeff[ch_idx][im][0],
6251 coeff.phs_coeff[ch_idx][im][0]);
6252 }
6253 }
6254 }
6255 ar9300_tx_iq_cal_outlier_detection(ah,ichan, num_chains, &coeff,is_cal_reusable);
6256 }
6257
6258
6259 coeff.last_nmeasurement = nmeasurement;
6260 coeff.last_cal = AH_TRUE;
6261
6262 return;
6263
6264 TX_IQ_CAL_FAILED_:
6265 /* no need to print this, it is AGC failure not chip stuck */
6266 /*ath_hal_printf(ah, "Tx IQ Cal failed(%d)\n", line);*/
6267 coeff.last_cal = AH_FALSE;
6268 return;
6269 }
6270
6271
6272 /*
6273 * ar9300_disable_phy_restart
6274 *
6275 * In some BBpanics, we can disable the phyrestart
6276 * disable_phy_restart
6277 * != 0, disable the phy restart in h/w
6278 * == 0, enable the phy restart in h/w
6279 */
ar9300_disable_phy_restart(struct ath_hal * ah,int disable_phy_restart)6280 void ar9300_disable_phy_restart(struct ath_hal *ah, int disable_phy_restart)
6281 {
6282 u_int32_t val;
6283
6284 val = OS_REG_READ(ah, AR_PHY_RESTART);
6285 if (disable_phy_restart) {
6286 val &= ~AR_PHY_RESTART_ENA;
6287 AH9300(ah)->ah_phyrestart_disabled = 1;
6288 } else {
6289 val |= AR_PHY_RESTART_ENA;
6290 AH9300(ah)->ah_phyrestart_disabled = 0;
6291 }
6292 OS_REG_WRITE(ah, AR_PHY_RESTART, val);
6293
6294 val = OS_REG_READ(ah, AR_PHY_RESTART);
6295 }
6296
6297 HAL_BOOL
ar9300_interference_is_present(struct ath_hal * ah)6298 ar9300_interference_is_present(struct ath_hal *ah)
6299 {
6300 int i;
6301 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6302 const struct ieee80211_channel *chan = ahpriv->ah_curchan;
6303 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
6304
6305 if (ichan == NULL) {
6306 ath_hal_printf(ah, "%s: called with ichan=NULL\n", __func__);
6307 return AH_FALSE;
6308 }
6309
6310 /* This function is called after a stuck beacon, if EACS is enabled.
6311 * If CW interference is severe, then HW goes into a loop of continuous
6312 * stuck beacons and resets. On reset the NF cal history is cleared.
6313 * So the median value of the history cannot be used -
6314 * hence check if any value (Chain 0/Primary Channel)
6315 * is outside the bounds.
6316 */
6317 HAL_NFCAL_HIST_FULL *h = AH_HOME_CHAN_NFCAL_HIST(ah, ichan);
6318 for (i = 0; i < HAL_NF_CAL_HIST_LEN_FULL; i++) {
6319 if (h->nf_cal_buffer[i][0] >
6320 AH9300(ah)->nfp->nominal + AH9300(ah)->nf_cw_int_delta)
6321 {
6322 return AH_TRUE;
6323 }
6324
6325 }
6326 return AH_FALSE;
6327 }
6328
6329 #if ATH_SUPPORT_CRDC
6330 void
ar9300_crdc_rx_notify(struct ath_hal * ah,struct ath_rx_status * rxs)6331 ar9300_crdc_rx_notify(struct ath_hal *ah, struct ath_rx_status *rxs)
6332 {
6333 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6334 int rssi_index;
6335
6336 if ((!AR_SREV_WASP(ah)) ||
6337 (!ahpriv->ah_config.ath_hal_crdc_enable)) {
6338 return;
6339 }
6340
6341 if (rxs->rs_isaggr && rxs->rs_moreaggr) {
6342 return;
6343 }
6344
6345 if ((rxs->rs_rssi_ctl0 >= HAL_RSSI_BAD) ||
6346 (rxs->rs_rssi_ctl1 >= HAL_RSSI_BAD)) {
6347 return;
6348 }
6349
6350 rssi_index = ah->ah_crdc_rssi_ptr % HAL_MAX_CRDC_RSSI_SAMPLE;
6351
6352 ah->ah_crdc_rssi_sample[0][rssi_index] = rxs->rs_rssi_ctl0;
6353 ah->ah_crdc_rssi_sample[1][rssi_index] = rxs->rs_rssi_ctl1;
6354
6355 ah->ah_crdc_rssi_ptr++;
6356 }
6357
6358 static int
ar9300_crdc_avg_rssi(struct ath_hal * ah,int chain)6359 ar9300_crdc_avg_rssi(struct ath_hal *ah, int chain)
6360 {
6361 int crdc_rssi_sum = 0;
6362 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr, i;
6363 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6364 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
6365
6366 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
6367 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
6368 }
6369
6370 for (i = 1; i <= crdc_window; i++) {
6371 crdc_rssi_sum +=
6372 ah->ah_crdc_rssi_sample[chain]
6373 [(crdc_rssi_ptr - i) % HAL_MAX_CRDC_RSSI_SAMPLE];
6374 }
6375
6376 return crdc_rssi_sum / crdc_window;
6377 }
6378
6379 static void
ar9300_crdc_activate(struct ath_hal * ah,int rssi_diff,int enable)6380 ar9300_crdc_activate(struct ath_hal *ah, int rssi_diff, int enable)
6381 {
6382 int val, orig_val;
6383 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6384 int crdc_numerator = ahpriv->ah_config.ath_hal_crdc_numerator;
6385 int crdc_denominator = ahpriv->ah_config.ath_hal_crdc_denominator;
6386 int c = (rssi_diff * crdc_numerator) / crdc_denominator;
6387
6388 val = orig_val = OS_REG_READ(ah, AR_PHY_MULTICHAIN_CTRL);
6389 val &= 0xffffff00;
6390 if (enable) {
6391 val |= 0x1;
6392 val |= ((c << 1) & 0xff);
6393 }
6394 OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_CTRL, val);
6395 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "diff: %02d comp: %02d reg: %08x %08x\n",
6396 rssi_diff, c, orig_val, val);
6397 }
6398
6399
ar9300_chain_rssi_diff_compensation(struct ath_hal * ah)6400 void ar9300_chain_rssi_diff_compensation(struct ath_hal *ah)
6401 {
6402 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6403 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
6404 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr;
6405 int crdc_rssi_thresh = ahpriv->ah_config.ath_hal_crdc_rssithresh;
6406 int crdc_diff_thresh = ahpriv->ah_config.ath_hal_crdc_diffthresh;
6407 int avg_rssi[2], avg_rssi_diff;
6408
6409 if ((!AR_SREV_WASP(ah)) ||
6410 (!ahpriv->ah_config.ath_hal_crdc_enable)) {
6411 if (ah->ah_crdc_rssi_ptr) {
6412 ar9300_crdc_activate(ah, 0, 0);
6413 ah->ah_crdc_rssi_ptr = 0;
6414 }
6415 return;
6416 }
6417
6418 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
6419 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
6420 }
6421
6422 if (crdc_rssi_ptr < crdc_window) {
6423 return;
6424 }
6425
6426 avg_rssi[0] = ar9300_crdc_avg_rssi(ah, 0);
6427 avg_rssi[1] = ar9300_crdc_avg_rssi(ah, 1);
6428 avg_rssi_diff = avg_rssi[1] - avg_rssi[0];
6429
6430 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "crdc: avg: %02d %02d ",
6431 avg_rssi[0], avg_rssi[1]);
6432
6433 if ((avg_rssi[0] < crdc_rssi_thresh) &&
6434 (avg_rssi[1] < crdc_rssi_thresh)) {
6435 ar9300_crdc_activate(ah, 0, 0);
6436 } else {
6437 if (ABS(avg_rssi_diff) >= crdc_diff_thresh) {
6438 ar9300_crdc_activate(ah, avg_rssi_diff, 1);
6439 } else {
6440 ar9300_crdc_activate(ah, 0, 1);
6441 }
6442 }
6443 }
6444 #endif
6445
6446 #if ATH_ANT_DIV_COMB
6447 HAL_BOOL
ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal * ah,HAL_BOOL enable,const struct ieee80211_channel * chan)6448 ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal *ah, HAL_BOOL enable, const struct ieee80211_channel *chan)
6449 {
6450 u_int32_t value;
6451 u_int32_t regval;
6452 struct ath_hal_9300 *ahp = AH9300(ah);
6453 HAL_CHANNEL_INTERNAL *ichan;
6454 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6455 HAL_CAPABILITIES *pcap = &ahpriv->ah_caps;
6456
6457 HALDEBUG(ah, HAL_DEBUG_RESET | HAL_DEBUG_BT_COEX,
6458 "%s: called; enable=%d\n", __func__, enable);
6459
6460 if (AR_SREV_POSEIDON(ah)) {
6461 // Make sure this scheme is only used for WB225(Astra)
6462 ahp->ah_lna_div_use_bt_ant_enable = enable;
6463
6464 ichan = ar9300_check_chan(ah, chan);
6465 if ( ichan == AH_NULL ) {
6466 HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel %u/0x%x; no mapping\n",
6467 __func__, chan->ic_freq, chan->ic_flags);
6468 return AH_FALSE;
6469 }
6470
6471 if ( enable == TRUE ) {
6472 pcap->halAntDivCombSupport = TRUE;
6473 } else {
6474 pcap->halAntDivCombSupport = pcap->halAntDivCombSupportOrg;
6475 }
6476
6477 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
6478 #define AR_SWITCH_TABLE_COM2_ALL_S (0)
6479 value = ar9300_ant_ctrl_common2_get(ah, IS_CHAN_2GHZ(ichan));
6480 if ( enable == TRUE ) {
6481 value &= ~AR_SWITCH_TABLE_COM2_ALL;
6482 value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable;
6483 }
6484 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, value);
6485 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
6486
6487 value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control);
6488 /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6489 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6490 regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */
6491 regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S;
6492 /* enable_lnadiv */
6493 regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK);
6494 regval |= ((value >> 6) & 0x1) <<
6495 MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT;
6496 if ( enable == TRUE ) {
6497 regval |= ANT_DIV_ENABLE;
6498 }
6499 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6500
6501 /* enable fast_div */
6502 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
6503 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
6504 regval |= ((value >> 7) & 0x1) <<
6505 BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT;
6506 if ( enable == TRUE ) {
6507 regval |= FAST_DIV_ENABLE;
6508 }
6509 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
6510
6511 if ( AR_SREV_POSEIDON_11_OR_LATER(ah) ) {
6512 if (pcap->halAntDivCombSupport) {
6513 /* If support DivComb, set MAIN to LNA1 and ALT to LNA2 at the first beginning */
6514 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6515 /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6516 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK |
6517 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK |
6518 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK |
6519 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK));
6520 regval |= (HAL_ANT_DIV_COMB_LNA1 <<
6521 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT);
6522 regval |= (HAL_ANT_DIV_COMB_LNA2 <<
6523 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT);
6524 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6525 }
6526 }
6527
6528 return AH_TRUE;
6529 } else if (AR_SREV_APHRODITE(ah)) {
6530 ahp->ah_lna_div_use_bt_ant_enable = enable;
6531 if (enable) {
6532 OS_REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, ANT_DIV_ENABLE);
6533 OS_REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, (1 << MULTICHAIN_GAIN_CTRL__ENABLE_ANT_SW_RX_PROT__SHIFT));
6534 OS_REG_SET_BIT(ah, AR_PHY_CCK_DETECT, AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
6535 OS_REG_SET_BIT(ah, AR_PHY_RESTART, RESTART__ENABLE_ANT_FAST_DIV_M2FLAG__MASK);
6536 OS_REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
6537 } else {
6538 OS_REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, ANT_DIV_ENABLE);
6539 OS_REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, (1 << MULTICHAIN_GAIN_CTRL__ENABLE_ANT_SW_RX_PROT__SHIFT));
6540 OS_REG_CLR_BIT(ah, AR_PHY_CCK_DETECT, AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
6541 OS_REG_CLR_BIT(ah, AR_PHY_RESTART, RESTART__ENABLE_ANT_FAST_DIV_M2FLAG__MASK);
6542 OS_REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
6543
6544 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6545 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK |
6546 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK |
6547 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK |
6548 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK));
6549 regval |= (HAL_ANT_DIV_COMB_LNA1 <<
6550 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT);
6551 regval |= (HAL_ANT_DIV_COMB_LNA2 <<
6552 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT);
6553
6554 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6555 }
6556 return AH_TRUE;
6557 }
6558 return AH_TRUE;
6559 }
6560 #endif /* ATH_ANT_DIV_COMB */
6561