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