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