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 (spur_chans_ptr[i] && i < 5) {
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_OR_LATER(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_JUPITER_20_OR_LATER(ah)) {
3057 /*
3058 * CUS217 mix LNA mode.
3059 */
3060 if (ar9300_rx_gain_index_get(ah) == 2) {
3061 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bb_core, 1, reg_writes);
3062 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bb_postamble,
3063 modes_index, reg_writes);
3064 }
3065
3066 /*
3067 * 5G-XLNA
3068 */
3069 if ((ar9300_rx_gain_index_get(ah) == 2) ||
3070 (ar9300_rx_gain_index_get(ah) == 3)) {
3071 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_xlna, modes_index,
3072 reg_writes);
3073 }
3074 }
3075
3076 if (AR_SREV_SCORPION(ah)) {
3077 /* Write rxgain bounds Array */
3078 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bounds, modes_index, reg_writes);
3079 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain table bounds programming\n");
3080 }
3081 /* UB124 xLNA settings */
3082 if (AR_SREV_WASP(ah) && ar9300_rx_gain_index_get(ah) == 2) {
3083 #define REG_WRITE(_reg,_val) *((volatile u_int32_t *)(_reg)) = (_val);
3084 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
3085 u_int32_t val;
3086 /* B8040000: bit[0]=0, bit[3]=0; */
3087 val = REG_READ(0xB8040000);
3088 val &= 0xfffffff6;
3089 REG_WRITE(0xB8040000, val);
3090 /* B804002c: bit[31:24]=0x2e; bit[7:0]=0x2f; */
3091 val = REG_READ(0xB804002c);
3092 val &= 0x00ffff00;
3093 val |= 0x2e00002f;
3094 REG_WRITE(0xB804002c, val);
3095 /* B804006c: bit[1]=1; */
3096 val = REG_READ(0xB804006c);
3097 val |= 0x2;
3098 REG_WRITE(0xB804006c, val);
3099 #undef REG_READ
3100 #undef REG_WRITE
3101 }
3102
3103
3104 /* Write txgain Array Parameters */
3105 if (AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) {
3106 REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_txgaintable_index,
3107 reg_writes);
3108 }else{
3109 REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_index, reg_writes);
3110 }
3111 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Tx Gain programming\n");
3112
3113
3114 /* For 5GHz channels requiring Fast Clock, apply different modal values */
3115 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
3116 HALDEBUG(ah, HAL_DEBUG_RESET,
3117 "%s: Fast clock enabled, use special ini values\n", __func__);
3118 REG_WRITE_ARRAY(&ahp->ah_ini_modes_additional, modes_index, reg_writes);
3119 }
3120
3121 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
3122 HALDEBUG(ah, HAL_DEBUG_RESET,
3123 "%s: use xtal ini for AH9300(ah)->clk_25mhz: %d\n",
3124 __func__, AH9300(ah)->clk_25mhz);
3125 REG_WRITE_ARRAY(
3126 &ahp->ah_ini_modes_additional, 1/*modes_index*/, reg_writes);
3127 }
3128
3129 if (AR_SREV_WASP(ah) && (AH9300(ah)->clk_25mhz == 0)) {
3130 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Apply 40MHz ini settings\n", __func__);
3131 REG_WRITE_ARRAY(
3132 &ahp->ah_ini_modes_additional_40mhz, 1/*modesIndex*/, reg_writes);
3133 }
3134
3135 /* Handle Japan Channel 14 channel spreading */
3136 if (2484 == ichan->channel) {
3137 ar9300_prog_ini(ah, &ahp->ah_ini_japan2484, 1);
3138 }
3139
3140 #if 0
3141 /* XXX TODO! */
3142 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {
3143 ar9300_prog_ini(ah, &ahp->ah_ini_BTCOEX_MAX_TXPWR, 1);
3144 }
3145 #endif
3146
3147 /* Override INI with chip specific configuration */
3148 ar9300_override_ini(ah, chan);
3149
3150 /* Setup 11n MAC/Phy mode registers */
3151 ar9300_set_11n_regs(ah, chan, macmode);
3152
3153 /*
3154 * Moved ar9300_init_chain_masks() here to ensure the swap bit is set before
3155 * the pdadc table is written. Swap must occur before any radio dependent
3156 * replicated register access. The pdadc curve addressing in particular
3157 * depends on the consistent setting of the swap bit.
3158 */
3159 ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
3160
3161 /*
3162 * Setup the transmit power values.
3163 *
3164 * After the public to private hal channel mapping, ichan contains the
3165 * valid regulatory power value.
3166 * ath_hal_getctl and ath_hal_getantennaallowed look up ichan from chan.
3167 */
3168 status = ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan,
3169 ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
3170 ath_hal_get_twice_max_regpower(ahpriv, ichan, chan),
3171 AH_MIN(MAX_RATE_POWER, ahpriv->ah_powerLimit));
3172 if (status != HAL_OK) {
3173 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
3174 "%s: error init'ing transmit power\n", __func__);
3175 return HAL_EIO;
3176 }
3177
3178
3179 return HAL_OK;
3180 #undef N
3181 }
3182
3183 /* ar9300_is_cal_supp
3184 * Determine if calibration is supported by device and channel flags
3185 */
3186 inline static HAL_BOOL
ar9300_is_cal_supp(struct ath_hal * ah,const struct ieee80211_channel * chan,HAL_CAL_TYPES cal_type)3187 ar9300_is_cal_supp(struct ath_hal *ah, const struct ieee80211_channel *chan,
3188 HAL_CAL_TYPES cal_type)
3189 {
3190 struct ath_hal_9300 *ahp = AH9300(ah);
3191 HAL_BOOL retval = AH_FALSE;
3192
3193 switch (cal_type & ahp->ah_supp_cals) {
3194 case IQ_MISMATCH_CAL:
3195 /* Run IQ Mismatch for non-CCK only */
3196 if (!IEEE80211_IS_CHAN_B(chan)) {
3197 retval = AH_TRUE;
3198 }
3199 break;
3200 case TEMP_COMP_CAL:
3201 retval = AH_TRUE;
3202 break;
3203 }
3204
3205 return retval;
3206 }
3207
3208
3209 #if 0
3210 /* ar9285_pa_cal
3211 * PA Calibration for Kite 1.1 and later versions of Kite.
3212 * - from system's team.
3213 */
3214 static inline void
3215 ar9285_pa_cal(struct ath_hal *ah)
3216 {
3217 u_int32_t reg_val;
3218 int i, lo_gn, offs_6_1, offs_0;
3219 u_int8_t reflo;
3220 u_int32_t phy_test2_reg_val, phy_adc_ctl_reg_val;
3221 u_int32_t an_top2_reg_val, phy_tst_dac_reg_val;
3222
3223
3224 /* Kite 1.1 WAR for Bug 35666
3225 * Increase the LDO value to 1.28V before accessing analog Reg */
3226 if (AR_SREV_KITE_11(ah)) {
3227 OS_REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14) );
3228 }
3229 an_top2_reg_val = OS_REG_READ(ah, AR9285_AN_TOP2);
3230
3231 /* set pdv2i pdrxtxbb */
3232 reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
3233 reg_val |= ((0x1 << 5) | (0x1 << 7));
3234 OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
3235
3236 /* clear pwddb */
3237 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G7);
3238 reg_val &= 0xfffffffd;
3239 OS_REG_WRITE(ah, AR9285_AN_RF2G7, reg_val);
3240
3241 /* clear enpacal */
3242 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3243 reg_val &= 0xfffff7ff;
3244 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3245
3246 /* set offcal */
3247 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
3248 reg_val |= (0x1 << 12);
3249 OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
3250
3251 /* set pdpadrv1=pdpadrv2=pdpaout=1 */
3252 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3253 reg_val |= (0x7 << 23);
3254 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3255
3256 /* Read back reflo, increase it by 1 and write it. */
3257 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3258 reflo = ((reg_val >> 26) & 0x7);
3259
3260 if (reflo < 0x7) {
3261 reflo++;
3262 }
3263 reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3264 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3265
3266 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3267 reflo = ((reg_val >> 26) & 0x7);
3268
3269 /* use TX single carrier to transmit
3270 * dac const
3271 * reg. 15
3272 */
3273 phy_tst_dac_reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3274 OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, ((0x7ff << 11) | 0x7ff));
3275 reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3276
3277 /* source is dac const
3278 * reg. 2
3279 */
3280 phy_test2_reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3281 OS_REG_WRITE(ah, AR_PHY_TEST2, ((0x1 << 7) | (0x1 << 1)));
3282 reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3283
3284 /* set dac on
3285 * reg. 11
3286 */
3287 phy_adc_ctl_reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3288 OS_REG_WRITE(ah, AR_PHY_ADC_CTL, 0x80008000);
3289 reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3290
3291 OS_REG_WRITE(ah, AR9285_AN_TOP2, (0x1 << 27) | (0x1 << 17) | (0x1 << 16) |
3292 (0x1 << 14) | (0x1 << 12) | (0x1 << 11) |
3293 (0x1 << 7) | (0x1 << 5));
3294
3295 OS_DELAY(10); /* 10 usec */
3296
3297 /* clear off[6:0] */
3298 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3299 reg_val &= 0xfc0fffff;
3300 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3301 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3302 reg_val &= 0xfdffffff;
3303 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3304
3305 offs_6_1 = 0;
3306 for (i = 6; i > 0; i--) {
3307 /* sef off[$k]==1 */
3308 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3309 reg_val &= 0xfc0fffff;
3310 reg_val = reg_val | (0x1 << (19 + i)) | ((offs_6_1) << 20);
3311 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3312 lo_gn = (OS_REG_READ(ah, AR9285_AN_RF2G9)) & 0x1;
3313 offs_6_1 = offs_6_1 | (lo_gn << (i - 1));
3314 }
3315
3316 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3317 reg_val &= 0xfc0fffff;
3318 reg_val = reg_val | ((offs_6_1 - 1) << 20);
3319 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3320
3321 /* set off_0=1; */
3322 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3323 reg_val &= 0xfdffffff;
3324 reg_val = reg_val | (0x1 << 25);
3325 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3326
3327 lo_gn = OS_REG_READ(ah, AR9285_AN_RF2G9) & 0x1;
3328 offs_0 = lo_gn;
3329
3330 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3331 reg_val &= 0xfdffffff;
3332 reg_val = reg_val | (offs_0 << 25);
3333 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3334
3335 /* clear pdv2i */
3336 reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
3337 reg_val &= 0xffffff5f;
3338 OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
3339
3340 /* set enpacal */
3341 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3342 reg_val |= (0x1 << 11);
3343 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3344
3345 /* clear offcal */
3346 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
3347 reg_val &= 0xffffefff;
3348 OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
3349
3350 /* set pdpadrv1=pdpadrv2=pdpaout=0 */
3351 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3352 reg_val &= 0xfc7fffff;
3353 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3354
3355 /* Read back reflo, decrease it by 1 and write it. */
3356 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3357 reflo = (reg_val >> 26) & 0x7;
3358 if (reflo) {
3359 reflo--;
3360 }
3361 reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3362 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3363 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3364 reflo = (reg_val >> 26) & 0x7;
3365
3366 /* write back registers */
3367 OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, phy_tst_dac_reg_val);
3368 OS_REG_WRITE(ah, AR_PHY_TEST2, phy_test2_reg_val);
3369 OS_REG_WRITE(ah, AR_PHY_ADC_CTL, phy_adc_ctl_reg_val);
3370 OS_REG_WRITE(ah, AR9285_AN_TOP2, an_top2_reg_val);
3371
3372 /* Kite 1.1 WAR for Bug 35666
3373 * Decrease the LDO value back to 1.20V */
3374 if (AR_SREV_KITE_11(ah)) {
3375 OS_REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
3376 }
3377 }
3378 #endif
3379
3380 /* ar9300_run_init_cals
3381 * Runs non-periodic calibrations
3382 */
3383 inline static HAL_BOOL
ar9300_run_init_cals(struct ath_hal * ah,int init_cal_count)3384 ar9300_run_init_cals(struct ath_hal *ah, int init_cal_count)
3385 {
3386 struct ath_hal_9300 *ahp = AH9300(ah);
3387 HAL_CHANNEL_INTERNAL ichan; /* bogus */
3388 HAL_BOOL is_cal_done;
3389 HAL_CAL_LIST *curr_cal;
3390 const HAL_PERCAL_DATA *cal_data;
3391 int i;
3392
3393 curr_cal = ahp->ah_cal_list_curr;
3394 if (curr_cal == AH_NULL) {
3395 return AH_FALSE;
3396 }
3397 cal_data = curr_cal->cal_data;
3398 ichan.calValid = 0;
3399
3400 for (i = 0; i < init_cal_count; i++) {
3401 /* Reset this Cal */
3402 ar9300_reset_calibration(ah, curr_cal);
3403 /* Poll for offset calibration complete */
3404 if (!ath_hal_wait(
3405 ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL, 0))
3406 {
3407 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3408 "%s: Cal %d failed to complete in 100ms.\n",
3409 __func__, curr_cal->cal_data->cal_type);
3410 /* Re-initialize list pointers for periodic cals */
3411 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr
3412 = AH_NULL;
3413 return AH_FALSE;
3414 }
3415 /* Run this cal */
3416 ar9300_per_calibration(
3417 ah, &ichan, ahp->ah_rx_chainmask, curr_cal, &is_cal_done);
3418 if (is_cal_done == AH_FALSE) {
3419 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3420 "%s: Not able to run Init Cal %d.\n", __func__,
3421 curr_cal->cal_data->cal_type);
3422 }
3423 if (curr_cal->cal_next) {
3424 curr_cal = curr_cal->cal_next;
3425 }
3426 }
3427
3428 /* Re-initialize list pointers for periodic cals */
3429 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3430 return AH_TRUE;
3431 }
3432
3433 #if 0
3434 static void
3435 ar9300_tx_carrier_leak_war(struct ath_hal *ah)
3436 {
3437 unsigned long tx_gain_table_max;
3438 unsigned long reg_bb_cl_map_0_b0 = 0xffffffff;
3439 unsigned long reg_bb_cl_map_1_b0 = 0xffffffff;
3440 unsigned long reg_bb_cl_map_2_b0 = 0xffffffff;
3441 unsigned long reg_bb_cl_map_3_b0 = 0xffffffff;
3442 unsigned long tx_gain, cal_run = 0;
3443 unsigned long cal_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3444 unsigned long cal_gain_index[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3445 unsigned long new_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3446 int i, j;
3447
3448 OS_MEMSET(new_gain, 0, sizeof(new_gain));
3449 /*printf(" Running TxCarrierLeakWAR\n");*/
3450
3451 /* process tx gain table, we use cl_map_hw_gen=0. */
3452 OS_REG_RMW_FIELD(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_MAP_HW_GEN, 0);
3453
3454 //the table we used is txbb_gc[2:0], 1dB[2:1].
3455 tx_gain_table_max = OS_REG_READ_FIELD(ah,
3456 AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX);
3457
3458 for (i = 0; i <= tx_gain_table_max; i++) {
3459 tx_gain = OS_REG_READ(ah, AR_PHY_TXGAIN_TAB(1) + i * 4);
3460 cal_gain[i] = (((tx_gain >> 5)& 0x7) << 2) |
3461 (((tx_gain >> 1) & 0x3) << 0);
3462 if (i == 0) {
3463 cal_gain_index[i] = cal_run;
3464 new_gain[i] = 1;
3465 cal_run++;
3466 } else {
3467 new_gain[i] = 1;
3468 for (j = 0; j < i; j++) {
3469 /*
3470 printf("i=%d, j=%d cal_gain[$i]=0x%04x\n", i, j, cal_gain[i]);
3471 */
3472 if (new_gain[i]) {
3473 if ((cal_gain[i] != cal_gain[j])) {
3474 new_gain[i] = 1;
3475 } else {
3476 /* if old gain found, use old cal_run value. */
3477 new_gain[i] = 0;
3478 cal_gain_index[i] = cal_gain_index[j];
3479 }
3480 }
3481 }
3482 /* if new gain found, increase cal_run */
3483 if (new_gain[i] == 1) {
3484 cal_gain_index[i] = cal_run;
3485 cal_run++;
3486 }
3487 }
3488
3489 reg_bb_cl_map_0_b0 = (reg_bb_cl_map_0_b0 & ~(0x1 << i)) |
3490 ((cal_gain_index[i] >> 0 & 0x1) << i);
3491 reg_bb_cl_map_1_b0 = (reg_bb_cl_map_1_b0 & ~(0x1 << i)) |
3492 ((cal_gain_index[i] >> 1 & 0x1) << i);
3493 reg_bb_cl_map_2_b0 = (reg_bb_cl_map_2_b0 & ~(0x1 << i)) |
3494 ((cal_gain_index[i] >> 2 & 0x1) << i);
3495 reg_bb_cl_map_3_b0 = (reg_bb_cl_map_3_b0 & ~(0x1 << i)) |
3496 ((cal_gain_index[i] >> 3 & 0x1) << i);
3497
3498 /*
3499 printf("i=%2d, cal_gain[$i]= 0x%04x, cal_run= %d, "
3500 "cal_gain_index[i]=%d, new_gain[i] = %d\n",
3501 i, cal_gain[i], cal_run, cal_gain_index[i], new_gain[i]);
3502 */
3503 }
3504 OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B0, reg_bb_cl_map_0_b0);
3505 OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B0, reg_bb_cl_map_1_b0);
3506 OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B0, reg_bb_cl_map_2_b0);
3507 OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B0, reg_bb_cl_map_3_b0);
3508 if (AR_SREV_WASP(ah)) {
3509 OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B1, reg_bb_cl_map_0_b0);
3510 OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B1, reg_bb_cl_map_1_b0);
3511 OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B1, reg_bb_cl_map_2_b0);
3512 OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B1, reg_bb_cl_map_3_b0);
3513 }
3514 }
3515 #endif
3516
3517
3518 static inline void
ar9300_invalidate_saved_cals(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan)3519 ar9300_invalidate_saved_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3520 {
3521 #if ATH_SUPPORT_CAL_REUSE
3522 if (AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3523 ATH_CAL_REUSE_REDO_IN_FULL_RESET)
3524 {
3525 ichan->one_time_txiqcal_done = AH_FALSE;
3526 ichan->one_time_txclcal_done = AH_FALSE;
3527 }
3528 #endif
3529 }
3530
3531 static inline HAL_BOOL
ar9300_restore_rtt_cals(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan)3532 ar9300_restore_rtt_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3533 {
3534 HAL_BOOL restore_status = AH_FALSE;
3535
3536 return restore_status;
3537 }
3538
3539 /* ar9300_init_cal
3540 * Initialize Calibration infrastructure
3541 */
3542 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)3543 ar9300_init_cal_internal(struct ath_hal *ah, struct ieee80211_channel *chan,
3544 HAL_CHANNEL_INTERNAL *ichan,
3545 HAL_BOOL enable_rtt, HAL_BOOL do_rtt_cal, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3546 {
3547 struct ath_hal_9300 *ahp = AH9300(ah);
3548 HAL_BOOL txiqcal_success_flag = AH_FALSE;
3549 HAL_BOOL cal_done = AH_FALSE;
3550 int iqcal_idx = 0;
3551 HAL_BOOL do_sep_iq_cal = AH_FALSE;
3552 HAL_BOOL do_agc_cal = do_rtt_cal;
3553 HAL_BOOL is_cal_reusable = AH_TRUE;
3554 #if ATH_SUPPORT_CAL_REUSE
3555 HAL_BOOL cal_reuse_enable = AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3556 ATH_CAL_REUSE_ENABLE;
3557 HAL_BOOL clc_success = AH_FALSE;
3558 int32_t ch_idx, j, cl_tab_reg;
3559 u_int32_t BB_cl_tab_entry = MAX_BB_CL_TABLE_ENTRY;
3560 u_int32_t BB_cl_tab_b[AR9300_MAX_CHAINS] = {
3561 AR_PHY_CL_TAB_0,
3562 AR_PHY_CL_TAB_1,
3563 AR_PHY_CL_TAB_2
3564 };
3565 #endif
3566
3567 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
3568 /* Hornet: 1 x 1 */
3569 ahp->ah_rx_cal_chainmask = 0x1;
3570 ahp->ah_tx_cal_chainmask = 0x1;
3571 } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_HONEYBEE(ah)) {
3572 /* Wasp/Jupiter: 2 x 2 */
3573 ahp->ah_rx_cal_chainmask = 0x3;
3574 ahp->ah_tx_cal_chainmask = 0x3;
3575 } else {
3576 /*
3577 * Osprey needs to be configured for the correct chain mode
3578 * before running AGC/TxIQ cals.
3579 */
3580 if (ahp->ah_enterprise_mode & AR_ENT_OTP_CHAIN2_DISABLE) {
3581 /* chain 2 disabled - 2 chain mode */
3582 ahp->ah_rx_cal_chainmask = 0x3;
3583 ahp->ah_tx_cal_chainmask = 0x3;
3584 } else {
3585 ahp->ah_rx_cal_chainmask = 0x7;
3586 ahp->ah_tx_cal_chainmask = 0x7;
3587 }
3588 }
3589 ar9300_init_chain_masks(ah, ahp->ah_rx_cal_chainmask, ahp->ah_tx_cal_chainmask);
3590
3591
3592 if (ahp->tx_cl_cal_enable) {
3593 #if ATH_SUPPORT_CAL_REUSE
3594 /* disable Carrie Leak or set do_agc_cal accordingly */
3595 if (cal_reuse_enable && ichan->one_time_txclcal_done)
3596 {
3597 OS_REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3598 } else
3599 #endif /* ATH_SUPPORT_CAL_REUSE */
3600 {
3601 OS_REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3602 do_agc_cal = AH_TRUE;
3603 }
3604 }
3605
3606 /* Do Tx IQ Calibration here for osprey hornet and wasp */
3607 /* XXX: For initial wasp bringup - check and enable this */
3608 /* EV 74233: Tx IQ fails to complete for half/quarter rates */
3609 if (!(IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) {
3610 if (ahp->tx_iq_cal_enable) {
3611 /* this should be eventually moved to INI file */
3612 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1(ah),
3613 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
3614
3615 /*
3616 * For poseidon and later chips,
3617 * Tx IQ cal HW run will be a part of AGC calibration
3618 */
3619 if (ahp->tx_iq_cal_during_agc_cal) {
3620 /*
3621 * txiqcal_success_flag always set to 1 to run
3622 * ar9300_tx_iq_cal_post_proc
3623 * if following AGC cal passes
3624 */
3625 #if ATH_SUPPORT_CAL_REUSE
3626 if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3627 {
3628 txiqcal_success_flag = AH_TRUE;
3629 OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3630 OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) |
3631 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3632 } else {
3633 OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3634 OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) &
3635 (~AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL));
3636 }
3637 #else
3638 if (OS_REG_READ_FIELD(ah,
3639 AR_PHY_TX_IQCAL_CONTROL_0(ah),
3640 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)){
3641 if (apply_last_iqcorr == AH_TRUE) {
3642 OS_REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3643 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3644 txiqcal_success_flag = AH_FALSE;
3645 } else {
3646 txiqcal_success_flag = AH_TRUE;
3647 }
3648 }else{
3649 txiqcal_success_flag = AH_FALSE;
3650 }
3651 #endif
3652 if (txiqcal_success_flag) {
3653 do_agc_cal = AH_TRUE;
3654 }
3655 } else
3656 #if ATH_SUPPORT_CAL_REUSE
3657 if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3658 #endif
3659 {
3660 do_sep_iq_cal = AH_TRUE;
3661 do_agc_cal = AH_TRUE;
3662 }
3663 }
3664 }
3665
3666 #if ATH_SUPPORT_MCI
3667 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
3668 IS_CHAN_2GHZ(ichan) &&
3669 (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3670 do_agc_cal &&
3671 !(ah->ah_config.ath_hal_mci_config &
3672 ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3673 {
3674 u_int32_t payload[4] = {0, 0, 0, 0};
3675
3676 /* Send CAL_REQ only when BT is AWAKE. */
3677 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_REQ 0x%X\n",
3678 __func__, ahp->ah_mci_wlan_cal_seq);
3679 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_REQ);
3680 payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_seq++;
3681 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3682
3683 /* Wait BT_CAL_GRANT for 50ms */
3684 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3685 "(MCI) %s: Wait for BT_CAL_GRANT\n", __func__);
3686 if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000))
3687 {
3688 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3689 "(MCI) %s: Got BT_CAL_GRANT.\n", __func__);
3690 }
3691 else {
3692 is_cal_reusable = AH_FALSE;
3693 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3694 "(MCI) %s: BT is not responding.\n", __func__);
3695 }
3696 }
3697 #endif /* ATH_SUPPORT_MCI */
3698
3699 if (do_sep_iq_cal)
3700 {
3701 /* enable Tx IQ Calibration HW for osprey/hornet/wasp */
3702 txiqcal_success_flag = ar9300_tx_iq_cal_hw_run(ah);
3703 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
3704 OS_DELAY(5);
3705 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
3706 }
3707 #if 0
3708 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
3709 ar9300_tx_carrier_leak_war(ah);
3710 }
3711 #endif
3712 /*
3713 * Calibrate the AGC
3714 *
3715 * Tx IQ cal is a part of AGC cal for Jupiter/Poseidon, etc.
3716 * please enable the bit of txiqcal_control_0[31] in INI file
3717 * for Jupiter/Poseidon/etc.
3718 */
3719 if(!AR_SREV_SCORPION(ah)) {
3720 if (do_agc_cal || !skip_if_none) {
3721 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3722 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3723
3724 /* Poll for offset calibration complete */
3725 cal_done = ath_hal_wait(ah,
3726 AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0);
3727 if (!cal_done) {
3728 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3729 "(FCS) CAL NOT DONE!!! - %d\n", ichan->channel);
3730 }
3731 } else {
3732 cal_done = AH_TRUE;
3733 }
3734 /*
3735 * Tx IQ cal post-processing in SW
3736 * This part of code should be common to all chips,
3737 * no chip specific code for Jupiter/Posdeion except for register names.
3738 */
3739 if (txiqcal_success_flag) {
3740 ar9300_tx_iq_cal_post_proc(ah,ichan, 1, 1,is_cal_reusable, AH_FALSE);
3741 }
3742 } else {
3743 if (!txiqcal_success_flag) {
3744 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3745 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3746 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
3747 0)) {
3748 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3749 "%s: offset calibration failed to complete in 1ms; "
3750 "noisy environment?\n", __func__);
3751 return AH_FALSE;
3752 }
3753 if (apply_last_iqcorr == AH_TRUE) {
3754 ar9300_tx_iq_cal_post_proc(ah, ichan, 0, 0, is_cal_reusable, AH_TRUE);
3755 }
3756 } else {
3757 for (iqcal_idx=0;iqcal_idx<MAXIQCAL;iqcal_idx++) {
3758 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3759 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3760
3761 /* Poll for offset calibration complete */
3762 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL,
3763 AR_PHY_AGC_CONTROL_CAL, 0)) {
3764 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3765 "%s: offset calibration failed to complete in 1ms; "
3766 "noisy environment?\n", __func__);
3767 return AH_FALSE;
3768 }
3769 /*
3770 * Tx IQ cal post-processing in SW
3771 * This part of code should be common to all chips,
3772 * no chip specific code for Jupiter/Posdeion except for register names.
3773 */
3774 ar9300_tx_iq_cal_post_proc(ah, ichan, iqcal_idx+1, MAXIQCAL, is_cal_reusable, AH_FALSE);
3775 }
3776 }
3777 }
3778
3779
3780 #if ATH_SUPPORT_MCI
3781 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
3782 IS_CHAN_2GHZ(ichan) &&
3783 (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3784 do_agc_cal &&
3785 !(ah->ah_config.ath_hal_mci_config &
3786 ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3787 {
3788 u_int32_t payload[4] = {0, 0, 0, 0};
3789
3790 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_DONE 0x%X\n",
3791 __func__, ahp->ah_mci_wlan_cal_done);
3792 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE);
3793 payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_done++;
3794 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3795 }
3796 #endif /* ATH_SUPPORT_MCI */
3797
3798
3799 if (!cal_done && !AR_SREV_SCORPION(ah) )
3800 {
3801 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3802 "%s: offset calibration failed to complete in 1ms; "
3803 "noisy environment?\n", __func__);
3804 return AH_FALSE;
3805 }
3806
3807 #if 0
3808 /* Beacon stuck fix, refer to EV 120056 */
3809 if(IS_CHAN_2GHZ(chan) && AR_SREV_SCORPION(ah))
3810 OS_REG_WRITE(ah, AR_PHY_TIMING5, OS_REG_READ(ah,AR_PHY_TIMING5) & ~AR_PHY_TIMING5_CYCPWR_THR1_ENABLE);
3811 #endif
3812
3813 #if 0
3814 /* Do PA Calibration */
3815 if (AR_SREV_KITE(ah) && AR_SREV_KITE_11_OR_LATER(ah)) {
3816 ar9285_pa_cal(ah);
3817 }
3818 #endif
3819
3820 #if ATH_SUPPORT_CAL_REUSE
3821 if (ichan->one_time_txiqcal_done) {
3822 ar9300_tx_iq_cal_apply(ah, ichan);
3823 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3824 "(FCS) TXIQCAL applied - %d\n", ichan->channel);
3825 }
3826 #endif /* ATH_SUPPORT_CAL_REUSE */
3827
3828 #if ATH_SUPPORT_CAL_REUSE
3829 if (cal_reuse_enable && ahp->tx_cl_cal_enable)
3830 {
3831 clc_success = (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) &
3832 AR_PHY_AGC_CONTROL_CLC_SUCCESS) ? 1 : 0;
3833
3834 if (ichan->one_time_txclcal_done)
3835 {
3836 /* reapply CL cal results */
3837 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3838 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3839 continue;
3840 }
3841 cl_tab_reg = BB_cl_tab_b[ch_idx];
3842 for (j = 0; j < BB_cl_tab_entry; j++) {
3843 OS_REG_WRITE(ah, cl_tab_reg, ichan->tx_clcal[ch_idx][j]);
3844 cl_tab_reg += 4;;
3845 }
3846 }
3847 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3848 "(FCS) TX CL CAL applied - %d\n", ichan->channel);
3849 }
3850 else if (is_cal_reusable && clc_success) {
3851 /* save CL cal results */
3852 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3853 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3854 continue;
3855 }
3856 cl_tab_reg = BB_cl_tab_b[ch_idx];
3857 for (j = 0; j < BB_cl_tab_entry; j++) {
3858 ichan->tx_clcal[ch_idx][j] = OS_REG_READ(ah, cl_tab_reg);
3859 cl_tab_reg += 4;
3860 }
3861 }
3862 ichan->one_time_txclcal_done = AH_TRUE;
3863 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3864 "(FCS) TX CL CAL saved - %d\n", ichan->channel);
3865 }
3866 }
3867 #endif /* ATH_SUPPORT_CAL_REUSE */
3868
3869 /* Revert chainmasks to their original values before NF cal */
3870 ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
3871
3872 #if !FIX_NOISE_FLOOR
3873 /*
3874 * Do NF calibration after DC offset and other CALs.
3875 * Per system engineers, noise floor value can sometimes be 20 dB
3876 * higher than normal value if DC offset and noise floor cal are
3877 * triggered at the same time.
3878 */
3879 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3880 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
3881 #endif
3882
3883 /* Initialize list pointers */
3884 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3885
3886 /*
3887 * Enable IQ, ADC Gain, ADC DC Offset Cals
3888 */
3889 /* Setup all non-periodic, init time only calibrations */
3890 /* XXX: Init DC Offset not working yet */
3891 #ifdef not_yet
3892 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, ADC_DC_INIT_CAL)) {
3893 INIT_CAL(&ahp->ah_adc_dc_cal_init_data);
3894 INSERT_CAL(ahp, &ahp->ah_adc_dc_cal_init_data);
3895 }
3896
3897 /* Initialize current pointer to first element in list */
3898 ahp->ah_cal_list_curr = ahp->ah_cal_list;
3899
3900 if (ahp->ah_cal_list_curr) {
3901 if (ar9300_run_init_cals(ah, 0) == AH_FALSE) {
3902 return AH_FALSE;
3903 }
3904 }
3905 #endif
3906 /* end - Init time calibrations */
3907
3908 /* Do not do RX cal in case of offchan, or cal data already exists on same channel*/
3909 if (ahp->ah_skip_rx_iq_cal) {
3910 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3911 "Skip RX IQ Cal\n");
3912 return AH_TRUE;
3913 }
3914
3915 /* If Cals are supported, add them to list via INIT/INSERT_CAL */
3916 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, IQ_MISMATCH_CAL)) {
3917 INIT_CAL(&ahp->ah_iq_cal_data);
3918 INSERT_CAL(ahp, &ahp->ah_iq_cal_data);
3919 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3920 "%s: enabling IQ Calibration.\n", __func__);
3921 }
3922 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, TEMP_COMP_CAL)) {
3923 INIT_CAL(&ahp->ah_temp_comp_cal_data);
3924 INSERT_CAL(ahp, &ahp->ah_temp_comp_cal_data);
3925 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3926 "%s: enabling Temperature Compensation Calibration.\n", __func__);
3927 }
3928
3929 /* Initialize current pointer to first element in list */
3930 ahp->ah_cal_list_curr = ahp->ah_cal_list;
3931
3932 /* Reset state within current cal */
3933 if (ahp->ah_cal_list_curr) {
3934 ar9300_reset_calibration(ah, ahp->ah_cal_list_curr);
3935 }
3936
3937 /* Mark all calibrations on this channel as being invalid */
3938 ichan->calValid = 0;
3939
3940 return AH_TRUE;
3941 }
3942
3943 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)3944 ar9300_init_cal(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3945 {
3946 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
3947 HAL_BOOL do_rtt_cal = AH_TRUE;
3948 HAL_BOOL enable_rtt = AH_FALSE;
3949
3950 HALASSERT(ichan);
3951
3952 return ar9300_init_cal_internal(ah, chan, ichan, enable_rtt, do_rtt_cal, skip_if_none, apply_last_iqcorr);
3953 }
3954
3955 /* ar9300_reset_cal_valid
3956 * Entry point for upper layers to restart current cal.
3957 * Reset the calibration valid bit in channel.
3958 */
3959 void
ar9300_reset_cal_valid(struct ath_hal * ah,const struct ieee80211_channel * chan,HAL_BOOL * is_cal_done,u_int32_t cal_type)3960 ar9300_reset_cal_valid(struct ath_hal *ah, const struct ieee80211_channel *chan,
3961 HAL_BOOL *is_cal_done, u_int32_t cal_type)
3962 {
3963 struct ath_hal_9300 *ahp = AH9300(ah);
3964 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
3965 HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr;
3966
3967 *is_cal_done = AH_TRUE;
3968
3969 if (curr_cal == AH_NULL) {
3970 return;
3971 }
3972 if (ichan == AH_NULL) {
3973 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3974 "%s: invalid channel %u/0x%x; no mapping\n",
3975 __func__, chan->ic_freq, chan->ic_flags);
3976 return;
3977 }
3978
3979 if (!(cal_type & IQ_MISMATCH_CAL)) {
3980 *is_cal_done = AH_FALSE;
3981 return;
3982 }
3983
3984 /* Expected that this calibration has run before, post-reset.
3985 * Current state should be done
3986 */
3987 if (curr_cal->cal_state != CAL_DONE) {
3988 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3989 "%s: Calibration state incorrect, %d\n",
3990 __func__, curr_cal->cal_state);
3991 return;
3992 }
3993
3994 /* Verify Cal is supported on this channel */
3995 if (ar9300_is_cal_supp(ah, chan, curr_cal->cal_data->cal_type) == AH_FALSE) {
3996 return;
3997 }
3998
3999 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4000 "%s: Resetting Cal %d state for channel %u/0x%x\n", __func__,
4001 curr_cal->cal_data->cal_type, chan->ic_freq, chan->ic_flags);
4002
4003 /* Disable cal validity in channel */
4004 ichan->calValid &= ~curr_cal->cal_data->cal_type;
4005 curr_cal->cal_state = CAL_WAITING;
4006 /* Indicate to upper layers that we need polling */
4007 *is_cal_done = AH_FALSE;
4008 }
4009
4010 static inline void
ar9300_set_dma(struct ath_hal * ah)4011 ar9300_set_dma(struct ath_hal *ah)
4012 {
4013 u_int32_t regval;
4014 struct ath_hal_9300 *ahp = AH9300(ah);
4015 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
4016 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
4017
4018 #if 0
4019 /*
4020 * set AHB_MODE not to do cacheline prefetches
4021 */
4022 regval = OS_REG_READ(ah, AR_AHB_MODE);
4023 OS_REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
4024 #endif
4025
4026 /*
4027 * let mac dma reads be in 128 byte chunks
4028 */
4029 regval = OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
4030 OS_REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
4031
4032 /*
4033 * Restore TX Trigger Level to its pre-reset value.
4034 * The initial value depends on whether aggregation is enabled, and is
4035 * adjusted whenever underruns are detected.
4036 */
4037 /*
4038 OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, AH_PRIVATE(ah)->ah_tx_trig_level);
4039 */
4040 /*
4041 * Osprey 1.0 bug (EV 61936). Don't change trigger level from .ini default.
4042 * Osprey 2.0 - hardware recommends using the default INI settings.
4043 */
4044 #if 0
4045 OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, 0x3f);
4046 #endif
4047 /*
4048 * let mac dma writes be in 128 byte chunks
4049 */
4050 regval = OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
4051 OS_REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
4052
4053 /*
4054 * Setup receive FIFO threshold to hold off TX activities
4055 */
4056 OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
4057
4058 /*
4059 * reduce the number of usable entries in PCU TXBUF to avoid
4060 * wrap around bugs. (bug 20428)
4061 */
4062
4063 if (AR_SREV_WASP(ah) &&
4064 (AH_PRIVATE((ah))->ah_macRev > AR_SREV_REVISION_WASP_12)) {
4065 /* Wasp 1.3 fix for EV#85395 requires usable entries
4066 * to be set to 0x500
4067 */
4068 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 0x500);
4069 } else {
4070 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE);
4071 }
4072
4073 /*
4074 * Enable HPQ for UAPSD
4075 */
4076 if (pCap->halHwUapsdTrig == AH_TRUE) {
4077 /* Only enable this if HAL capabilities says it is OK */
4078 if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) {
4079 OS_REG_WRITE(ah, AR_HP_Q_CONTROL,
4080 AR_HPQ_ENABLE | AR_HPQ_UAPSD | AR_HPQ_UAPSD_TRIGGER_EN);
4081 }
4082 } else {
4083 /* use default value from ini file - which disable HPQ queue usage */
4084 }
4085
4086 /*
4087 * set the transmit status ring
4088 */
4089 ar9300_reset_tx_status_ring(ah);
4090
4091 /*
4092 * set rxbp threshold. Must be non-zero for RX_EOL to occur.
4093 * For Osprey 2.0+, keep the original thresholds
4094 * otherwise performance is lost due to excessive RX EOL interrupts.
4095 */
4096 OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1);
4097 OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1);
4098
4099 /*
4100 * set receive buffer size.
4101 */
4102 if (ahp->rx_buf_size) {
4103 OS_REG_WRITE(ah, AR_DATABUF, ahp->rx_buf_size);
4104 }
4105 }
4106
4107 static inline void
ar9300_init_bb(struct ath_hal * ah,struct ieee80211_channel * chan)4108 ar9300_init_bb(struct ath_hal *ah, struct ieee80211_channel *chan)
4109 {
4110 u_int32_t synth_delay;
4111
4112 /*
4113 * Wait for the frequency synth to settle (synth goes on
4114 * via AR_PHY_ACTIVE_EN). Read the phy active delay register.
4115 * Value is in 100ns increments.
4116 */
4117 synth_delay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
4118 if (IEEE80211_IS_CHAN_CCK(chan)) {
4119 synth_delay = (4 * synth_delay) / 22;
4120 } else {
4121 synth_delay /= 10;
4122 }
4123
4124 /* Activate the PHY (includes baseband activate + synthesizer on) */
4125 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
4126
4127 /*
4128 * There is an issue if the AP starts the calibration before
4129 * the base band timeout completes. This could result in the
4130 * rx_clear false triggering. As a workaround we add delay an
4131 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
4132 * does not happen.
4133 */
4134 OS_DELAY(synth_delay + BASE_ACTIVATE_DELAY);
4135 }
4136
4137 static inline void
ar9300_init_interrupt_masks(struct ath_hal * ah,HAL_OPMODE opmode)4138 ar9300_init_interrupt_masks(struct ath_hal *ah, HAL_OPMODE opmode)
4139 {
4140 struct ath_hal_9300 *ahp = AH9300(ah);
4141 u_int32_t msi_cfg = 0;
4142 u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
4143
4144 /*
4145 * Setup interrupt handling. Note that ar9300_reset_tx_queue
4146 * manipulates the secondary IMR's as queues are enabled
4147 * and disabled. This is done with RMW ops to insure the
4148 * settings we make here are preserved.
4149 */
4150 ahp->ah_mask_reg =
4151 AR_IMR_TXERR | AR_IMR_TXURN |
4152 AR_IMR_RXERR | AR_IMR_RXORN |
4153 AR_IMR_BCNMISC;
4154
4155 if (ahp->ah_intr_mitigation_rx) {
4156 /* enable interrupt mitigation for rx */
4157 ahp->ah_mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR | AR_IMR_RXOK_HP;
4158 msi_cfg |= AR_INTCFG_MSI_RXINTM | AR_INTCFG_MSI_RXMINTR;
4159 } else {
4160 ahp->ah_mask_reg |= AR_IMR_RXOK_LP | AR_IMR_RXOK_HP;
4161 msi_cfg |= AR_INTCFG_MSI_RXOK;
4162 }
4163 if (ahp->ah_intr_mitigation_tx) {
4164 /* enable interrupt mitigation for tx */
4165 ahp->ah_mask_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR;
4166 msi_cfg |= AR_INTCFG_MSI_TXINTM | AR_INTCFG_MSI_TXMINTR;
4167 } else {
4168 ahp->ah_mask_reg |= AR_IMR_TXOK;
4169 msi_cfg |= AR_INTCFG_MSI_TXOK;
4170 }
4171 if (opmode == HAL_M_HOSTAP) {
4172 ahp->ah_mask_reg |= AR_IMR_MIB;
4173 }
4174
4175 OS_REG_WRITE(ah, AR_IMR, ahp->ah_mask_reg);
4176 OS_REG_WRITE(ah, AR_IMR_S2, OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
4177 ahp->ah_mask2Reg = OS_REG_READ(ah, AR_IMR_S2);
4178
4179 if (ah->ah_config.ath_hal_enable_msi) {
4180 /* Cache MSI register value */
4181 ahp->ah_msi_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI));
4182 ahp->ah_msi_reg |= AR_PCIE_MSI_HW_DBI_WR_EN;
4183 if (AR_SREV_POSEIDON(ah)) {
4184 ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
4185 } else {
4186 ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR;
4187 }
4188 /* Program MSI configuration */
4189 OS_REG_WRITE(ah, AR_INTCFG, msi_cfg);
4190 }
4191
4192 /*
4193 * debug - enable to see all synchronous interrupts status
4194 */
4195 /* Clear any pending sync cause interrupts */
4196 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE), 0xFFFFFFFF);
4197
4198 /* Allow host interface sync interrupt sources to set cause bit */
4199 if (AR_SREV_POSEIDON(ah)) {
4200 sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
4201 }
4202 else if (AR_SREV_WASP(ah)) {
4203 sync_en_def = AR9340_INTR_SYNC_DEFAULT;
4204 }
4205 OS_REG_WRITE(ah,
4206 AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), sync_en_def);
4207
4208 /* _Disable_ host interface sync interrupt when cause bits set */
4209 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK), 0);
4210
4211 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE), 0);
4212 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_MASK), 0);
4213 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_ENABLE), 0);
4214 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_MASK), 0);
4215 }
4216
4217 static inline void
ar9300_init_qos(struct ath_hal * ah)4218 ar9300_init_qos(struct ath_hal *ah)
4219 {
4220 OS_REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); /* XXX magic */
4221 OS_REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); /* XXX magic */
4222
4223 /* Turn on NOACK Support for QoS packets */
4224 OS_REG_WRITE(ah, AR_QOS_NO_ACK,
4225 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
4226 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
4227 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
4228
4229 /*
4230 * initialize TXOP for all TIDs
4231 */
4232 OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
4233 OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
4234 OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
4235 OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
4236 OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
4237 }
4238
4239 static inline void
ar9300_init_user_settings(struct ath_hal * ah)4240 ar9300_init_user_settings(struct ath_hal *ah)
4241 {
4242 struct ath_hal_9300 *ahp = AH9300(ah);
4243
4244 /* Restore user-specified settings */
4245 HALDEBUG(ah, HAL_DEBUG_RESET,
4246 "--AP %s ahp->ah_misc_mode 0x%x\n", __func__, ahp->ah_misc_mode);
4247 if (ahp->ah_misc_mode != 0) {
4248 OS_REG_WRITE(ah,
4249 AR_PCU_MISC, OS_REG_READ(ah, AR_PCU_MISC) | ahp->ah_misc_mode);
4250 }
4251 if (ahp->ah_get_plcp_hdr) {
4252 OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM);
4253 }
4254 if (ahp->ah_slot_time != (u_int) -1) {
4255 ar9300_set_slot_time(ah, ahp->ah_slot_time);
4256 }
4257 if (ahp->ah_ack_timeout != (u_int) -1) {
4258 ar9300_set_ack_timeout(ah, ahp->ah_ack_timeout);
4259 }
4260 if (AH_PRIVATE(ah)->ah_diagreg != 0) {
4261 OS_REG_SET_BIT(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
4262 }
4263 if (ahp->ah_beacon_rssi_threshold != 0) {
4264 ar9300_set_hw_beacon_rssi_threshold(ah, ahp->ah_beacon_rssi_threshold);
4265 }
4266 #ifdef ATH_SUPPORT_DFS
4267 if (ahp->ah_cac_quiet_enabled) {
4268 ar9300_cac_tx_quiet(ah, 1);
4269 }
4270 #endif /* ATH_SUPPORT_DFS */
4271 }
4272
4273 int
ar9300_get_spur_info(struct ath_hal * ah,int * enable,int len,u_int16_t * freq)4274 ar9300_get_spur_info(struct ath_hal * ah, int *enable, int len, u_int16_t *freq)
4275 {
4276 // struct ath_hal_private *ap = AH_PRIVATE(ah);
4277 int i, j;
4278
4279 for (i = 0; i < len; i++) {
4280 freq[i] = 0;
4281 }
4282
4283 *enable = ah->ah_config.ath_hal_spur_mode;
4284 for (i = 0, j = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4285 if (AH9300(ah)->ath_hal_spur_chans[i][0] != AR_NO_SPUR) {
4286 freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][0];
4287 HALDEBUG(ah, HAL_DEBUG_ANI,
4288 "1. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][0]);
4289 }
4290 if (AH9300(ah)->ath_hal_spur_chans[i][1] != AR_NO_SPUR) {
4291 freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][1];
4292 HALDEBUG(ah, HAL_DEBUG_ANI,
4293 "2. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][1]);
4294 }
4295 }
4296
4297 return 0;
4298 }
4299
4300 #define ATH_HAL_2GHZ_FREQ_MIN 20000
4301 #define ATH_HAL_2GHZ_FREQ_MAX 29999
4302 #define ATH_HAL_5GHZ_FREQ_MIN 50000
4303 #define ATH_HAL_5GHZ_FREQ_MAX 59999
4304
4305 #if 0
4306 int
4307 ar9300_set_spur_info(struct ath_hal * ah, int enable, int len, u_int16_t *freq)
4308 {
4309 struct ath_hal_private *ap = AH_PRIVATE(ah);
4310 int i, j, k;
4311
4312 ap->ah_config.ath_hal_spur_mode = enable;
4313
4314 if (ap->ah_config.ath_hal_spur_mode == SPUR_ENABLE_IOCTL) {
4315 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4316 AH9300(ah)->ath_hal_spur_chans[i][0] = AR_NO_SPUR;
4317 AH9300(ah)->ath_hal_spur_chans[i][1] = AR_NO_SPUR;
4318 }
4319 for (i = 0, j = 0, k = 0; i < len; i++) {
4320 if (freq[i] > ATH_HAL_2GHZ_FREQ_MIN &&
4321 freq[i] < ATH_HAL_2GHZ_FREQ_MAX)
4322 {
4323 /* 2GHz Spur */
4324 if (j < AR_EEPROM_MODAL_SPURS) {
4325 AH9300(ah)->ath_hal_spur_chans[j++][1] = freq[i];
4326 HALDEBUG(ah, HAL_DEBUG_ANI, "1 set spur %d\n", freq[i]);
4327 }
4328 } else if (freq[i] > ATH_HAL_5GHZ_FREQ_MIN &&
4329 freq[i] < ATH_HAL_5GHZ_FREQ_MAX)
4330 {
4331 /* 5Ghz Spur */
4332 if (k < AR_EEPROM_MODAL_SPURS) {
4333 AH9300(ah)->ath_hal_spur_chans[k++][0] = freq[i];
4334 HALDEBUG(ah, HAL_DEBUG_ANI, "2 set spur %d\n", freq[i]);
4335 }
4336 }
4337 }
4338 }
4339
4340 return 0;
4341 }
4342 #endif
4343
4344 #define ar9300_check_op_mode(_opmode) \
4345 ((_opmode == HAL_M_STA) || (_opmode == HAL_M_IBSS) ||\
4346 (_opmode == HAL_M_HOSTAP) || (_opmode == HAL_M_MONITOR))
4347
4348
4349
4350
4351 #ifndef ATH_NF_PER_CHAN
4352 /*
4353 * To fixed first reset noise floor value not correct issue
4354 * For ART need it to fixed low rate sens too low issue
4355 */
4356 static int
First_NFCal(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan,int is_scan,struct ieee80211_channel * chan)4357 First_NFCal(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
4358 int is_scan, struct ieee80211_channel *chan)
4359 {
4360 HAL_NFCAL_HIST_FULL *nfh;
4361 int i, j, k;
4362 int16_t nfarray[HAL_NUM_NF_READINGS] = {0};
4363 int is_2g = 0;
4364 int nf_hist_len;
4365 int stats = 0;
4366
4367 int16_t nf_buf[HAL_NUM_NF_READINGS];
4368 #define IS(_c, _f) (((_c)->channel_flags & _f) || 0)
4369
4370
4371 if ((!is_scan) &&
4372 chan->ic_freq == AH_PRIVATE(ah)->ah_curchan->ic_freq)
4373 {
4374 nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4375 } else {
4376 nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4377 }
4378
4379 ar9300_start_nf_cal(ah);
4380 for (j = 0; j < 10000; j++) {
4381 if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){
4382 break;
4383 }
4384 OS_DELAY(10);
4385 }
4386 if (j < 10000) {
4387 is_2g = IEEE80211_IS_CHAN_2GHZ(chan);
4388 ar9300_upload_noise_floor(ah, is_2g, nfarray);
4389
4390 if (is_scan) {
4391 /*
4392 * This channel's NF cal info is just a HAL_NFCAL_HIST_SMALL struct
4393 * rather than a HAL_NFCAL_HIST_FULL struct.
4394 * As long as we only use the first history element of nf_cal_buffer
4395 * (nf_cal_buffer[0][0:HAL_NUM_NF_READINGS-1]), we can use
4396 * HAL_NFCAL_HIST_SMALL and HAL_NFCAL_HIST_FULL interchangeably.
4397 */
4398 nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4399 nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
4400 } else {
4401 nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4402 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
4403 }
4404
4405 for (i = 0; i < HAL_NUM_NF_READINGS; i ++) {
4406 for (k = 0; k < HAL_NF_CAL_HIST_LEN_FULL; k++) {
4407 nfh->nf_cal_buffer[k][i] = nfarray[i];
4408 }
4409 nfh->base.priv_nf[i] = ar9300_limit_nf_range(ah,
4410 ar9300_get_nf_hist_mid(ah, nfh, i, nf_hist_len));
4411 }
4412
4413
4414 //ar9300StoreNewNf(ah, ichan, is_scan);
4415
4416 /*
4417 * See if the NF value from the old channel should be
4418 * retained when switching to a new channel.
4419 * TBD: this may need to be changed, as it wipes out the
4420 * purpose of saving NF values for each channel.
4421 */
4422 for (i = 0; i < HAL_NUM_NF_READINGS; i++)
4423 {
4424 if (IEEE80211_IS_CHAN_2GHZ(chan))
4425 {
4426 if (nfh->nf_cal_buffer[0][i] <
4427 AR_PHY_CCA_MAX_GOOD_VAL_OSPREY_2GHZ)
4428 {
4429 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4430 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4431 }
4432 } else {
4433 if (AR_SREV_AR9580(ah)) {
4434 if (nfh->nf_cal_buffer[0][i] <
4435 AR_PHY_CCA_NOM_VAL_PEACOCK_5GHZ)
4436 {
4437 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4438 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4439 }
4440 } else {
4441 if (nfh->nf_cal_buffer[0][i] <
4442 AR_PHY_CCA_NOM_VAL_OSPREY_5GHZ)
4443 {
4444 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4445 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4446 }
4447 }
4448 }
4449 }
4450 /*
4451 * Copy the channel's NF buffer, which may have been modified
4452 * just above here, to the full NF history buffer.
4453 */
4454 ar9300_reset_nf_hist_buff(ah, ichan);
4455 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
4456 ar9300_load_nf(ah, nf_buf);
4457 stats = 0;
4458 } else {
4459 stats = 1;
4460 }
4461 #undef IS
4462 return stats;
4463 }
4464 #endif
4465
4466
4467 /*
4468 * Places the device in and out of reset and then places sane
4469 * values in the registers based on EEPROM config, initialization
4470 * vectors (as determined by the mode), and station configuration
4471 *
4472 * b_channel_change is used to preserve DMA/PCU registers across
4473 * a HW Reset during channel change.
4474 */
4475 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)4476 ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan,
4477 HAL_HT_MACMODE macmode, u_int8_t txchainmask, u_int8_t rxchainmask,
4478 HAL_HT_EXTPROTSPACING extprotspacing, HAL_BOOL b_channel_change,
4479 HAL_STATUS *status, int is_scan)
4480 {
4481 #define FAIL(_code) do { ecode = _code; goto bad; } while (0)
4482 u_int32_t save_led_state;
4483 struct ath_hal_9300 *ahp = AH9300(ah);
4484 struct ath_hal_private *ap = AH_PRIVATE(ah);
4485 HAL_CHANNEL_INTERNAL *ichan;
4486 //const struct ieee80211_channel *curchan = ap->ah_curchan;
4487 #if ATH_SUPPORT_MCI
4488 HAL_BOOL save_full_sleep = ahp->ah_chip_full_sleep;
4489 #endif
4490 u_int32_t save_def_antenna;
4491 u_int32_t mac_sta_id1;
4492 HAL_STATUS ecode;
4493 int i, rx_chainmask;
4494 int nf_hist_buff_reset = 0;
4495 int16_t nf_buf[HAL_NUM_NF_READINGS];
4496 #ifdef ATH_FORCE_PPM
4497 u_int32_t save_force_val, tmp_reg;
4498 #endif
4499 u_int8_t clk_25mhz = AH9300(ah)->clk_25mhz;
4500 HAL_BOOL stopped, cal_ret;
4501 HAL_BOOL apply_last_iqcorr = AH_FALSE;
4502
4503
4504 if (OS_REG_READ(ah, AR_IER) == AR_IER_ENABLE) {
4505 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "** Reset called with WLAN "
4506 "interrupt enabled %08x **\n", ar9300_get_interrupts(ah));
4507 }
4508
4509 /*
4510 * Set the status to "ok" by default to cover the cases
4511 * where we return false without going to "bad"
4512 */
4513 HALASSERT(status);
4514 *status = HAL_OK;
4515 if ((ah->ah_config.ath_hal_sta_update_tx_pwr_enable)) {
4516 AH9300(ah)->green_tx_status = HAL_RSSI_TX_POWER_NONE;
4517 }
4518
4519 #if ATH_SUPPORT_MCI
4520 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
4521 (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)))
4522 {
4523 ar9300_mci_2g5g_changed(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4524 }
4525 #endif
4526
4527 ahp->ah_ext_prot_spacing = extprotspacing;
4528 ahp->ah_tx_chainmask = txchainmask & ap->ah_caps.halTxChainMask;
4529 ahp->ah_rx_chainmask = rxchainmask & ap->ah_caps.halRxChainMask;
4530 ahp->ah_tx_cal_chainmask = ap->ah_caps.halTxChainMask;
4531 ahp->ah_rx_cal_chainmask = ap->ah_caps.halRxChainMask;
4532
4533 /*
4534 * Keep the previous optinal txchainmask value
4535 */
4536
4537 HALASSERT(ar9300_check_op_mode(opmode));
4538
4539 OS_MARK(ah, AH_MARK_RESET, b_channel_change);
4540
4541 /*
4542 * Map public channel to private.
4543 */
4544 ichan = ar9300_check_chan(ah, chan);
4545 if (ichan == AH_NULL) {
4546 HALDEBUG(ah, HAL_DEBUG_CHANNEL,
4547 "%s: invalid channel %u/0x%x; no mapping\n",
4548 __func__, chan->ic_freq, chan->ic_flags);
4549 FAIL(HAL_EINVAL);
4550 }
4551
4552 ichan->paprd_table_write_done = 0; /* Clear PAPRD table write flag */
4553 #if 0
4554 chan->paprd_table_write_done = 0; /* Clear PAPRD table write flag */
4555 #endif
4556
4557 if (ar9300_get_power_mode(ah) != HAL_PM_FULL_SLEEP) {
4558 /* Need to stop RX DMA before reset otherwise chip might hang */
4559 stopped = ar9300_set_rx_abort(ah, AH_TRUE); /* abort and disable PCU */
4560 ar9300_set_rx_filter(ah, 0);
4561 stopped &= ar9300_stop_dma_receive(ah, 0); /* stop and disable RX DMA */
4562 if (!stopped) {
4563 /*
4564 * During the transition from full sleep to reset,
4565 * recv DMA regs are not available to be read
4566 */
4567 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4568 "%s[%d]: ar9300_stop_dma_receive failed\n", __func__, __LINE__);
4569 b_channel_change = AH_FALSE;
4570 }
4571 } else {
4572 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4573 "%s[%d]: Chip is already in full sleep\n", __func__, __LINE__);
4574 }
4575
4576 #if ATH_SUPPORT_MCI
4577 if ((AH_PRIVATE(ah)->ah_caps.halMciSupport) &&
4578 (ahp->ah_mci_bt_state == MCI_BT_CAL_START))
4579 {
4580 u_int32_t payload[4] = {0, 0, 0, 0};
4581
4582 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4583 "(MCI) %s: Stop rx for BT cal.\n", __func__);
4584 ahp->ah_mci_bt_state = MCI_BT_CAL;
4585
4586 /*
4587 * MCIFIX: disable mci interrupt here. This is to avoid SW_MSG_DONE or
4588 * RX_MSG bits to trigger MCI_INT and lead to mci_intr reentry.
4589 */
4590 ar9300_mci_disable_interrupt(ah);
4591
4592 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4593 "(MCI) %s: Send WLAN_CAL_GRANT\n", __func__);
4594 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
4595 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
4596
4597 /* Wait BT calibration to be completed for 25ms */
4598 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4599 "(MCI) %s: BT is calibrating.\n", __func__);
4600 if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE, 0, 25000)) {
4601 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4602 "(MCI) %s: Got BT_CAL_DONE.\n", __func__);
4603 }
4604 else {
4605 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4606 "(MCI) %s: ### BT cal takes too long. Force bt_state to be bt_awake.\n",
4607 __func__);
4608 }
4609 ahp->ah_mci_bt_state = MCI_BT_AWAKE;
4610 /* MCIFIX: enable mci interrupt here */
4611 ar9300_mci_enable_interrupt(ah);
4612
4613 return AH_TRUE;
4614 }
4615 #endif
4616
4617 /* Bring out of sleep mode */
4618 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
4619 *status = HAL_INV_PMODE;
4620 return AH_FALSE;
4621 }
4622
4623 /* Check the Rx mitigation config again, it might have changed
4624 * during attach in ath_vap_attach.
4625 */
4626 if (ah->ah_config.ath_hal_intr_mitigation_rx != 0) {
4627 ahp->ah_intr_mitigation_rx = AH_TRUE;
4628 } else {
4629 ahp->ah_intr_mitigation_rx = AH_FALSE;
4630 }
4631
4632 /*
4633 * XXX TODO FreeBSD:
4634 *
4635 * This is painful because we don't have a non-const channel pointer
4636 * at this stage.
4637 *
4638 * Make sure this gets fixed!
4639 */
4640 #if 0
4641 /* Get the value from the previous NF cal and update history buffer */
4642 if (curchan && (ahp->ah_chip_full_sleep != AH_TRUE)) {
4643
4644 if(ahp->ah_chip_reset_done){
4645 ahp->ah_chip_reset_done = 0;
4646 } else {
4647 /*
4648 * is_scan controls updating NF for home channel or off channel.
4649 * Home -> Off, update home channel
4650 * Off -> Home, update off channel
4651 * Home -> Home, uppdate home channel
4652 */
4653 if (ap->ah_curchan->channel != chan->channel)
4654 ar9300_store_new_nf(ah, curchan, !is_scan);
4655 else
4656 ar9300_store_new_nf(ah, curchan, is_scan);
4657 }
4658 }
4659 #endif
4660
4661 /*
4662 * Account for the effect of being in either the 2 GHz or 5 GHz band
4663 * on the nominal, max allowable, and min allowable noise floor values.
4664 */
4665 AH9300(ah)->nfp = IS_CHAN_2GHZ(ichan) ? &ahp->nf_2GHz : &ahp->nf_5GHz;
4666
4667 /*
4668 * XXX FreeBSD For now, don't apply the last IQ correction.
4669 *
4670 * This should be done when scorpion is enabled on FreeBSD; just be
4671 * sure to fix this channel match code so it uses net80211 flags
4672 * instead.
4673 */
4674 #if 0
4675 if (AR_SREV_SCORPION(ah) && curchan && (chan->channel == curchan->channel) &&
4676 ((chan->channel_flags & (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)) ==
4677 (curchan->channel_flags &
4678 (CHANNEL_ALL | CHANNEL_HALF | CHANNEL_QUARTER)))) {
4679 apply_last_iqcorr = AH_TRUE;
4680 }
4681 #endif
4682 apply_last_iqcorr = AH_FALSE;
4683
4684
4685 #ifndef ATH_NF_PER_CHAN
4686 /*
4687 * If there's only one full-size home-channel NF history buffer
4688 * rather than a full-size NF history buffer per channel, decide
4689 * whether to (re)initialize the home-channel NF buffer.
4690 * If this is just a channel change for a scan, or if the channel
4691 * is not being changed, don't mess up the home channel NF history
4692 * buffer with NF values from this scanned channel. If we're
4693 * changing the home channel to a new channel, reset the home-channel
4694 * NF history buffer with the most accurate NF known for the new channel.
4695 */
4696 if (!is_scan && (!ap->ah_curchan ||
4697 ap->ah_curchan->ic_freq != chan->ic_freq)) // ||
4698 // ap->ah_curchan->channel_flags != chan->channel_flags))
4699 {
4700 nf_hist_buff_reset = 1;
4701 ar9300_reset_nf_hist_buff(ah, ichan);
4702 }
4703 #endif
4704 /*
4705 * In case of
4706 * - offchan scan, or
4707 * - same channel and RX IQ Cal already available
4708 * disable RX IQ Cal.
4709 */
4710 if (is_scan) {
4711 ahp->ah_skip_rx_iq_cal = AH_TRUE;
4712 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4713 "Skip RX IQ Cal due to scanning\n");
4714 } else {
4715 #if 0
4716 /* XXX FreeBSD: always just do the RX IQ cal */
4717 /* XXX I think it's just going to speed things up; I don't think it's to avoid chan bugs */
4718 if (ahp->ah_rx_cal_complete &&
4719 ahp->ah_rx_cal_chan == ichan->channel &&
4720 ahp->ah_rx_cal_chan_flag == chan->channel_flags) {
4721 ahp->ah_skip_rx_iq_cal = AH_TRUE;
4722 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4723 "Skip RX IQ Cal due to same channel with completed RX IQ Cal\n");
4724 } else
4725 #endif
4726 ahp->ah_skip_rx_iq_cal = AH_FALSE;
4727 }
4728
4729 /* FreeBSD: clear the channel survey data */
4730 ath_hal_survey_clear(ah);
4731
4732 /*
4733 * Fast channel change (Change synthesizer based on channel freq
4734 * without resetting chip)
4735 * Don't do it when
4736 * - Flag is not set
4737 * - Chip is just coming out of full sleep
4738 * - Channel to be set is same as current channel
4739 * - Channel flags are different, like when moving from 2GHz to 5GHz
4740 * channels
4741 * - Merlin: Switching in/out of fast clock enabled channels
4742 * (not currently coded, since fast clock is enabled
4743 * across the 5GHz band
4744 * and we already do a full reset when switching in/out
4745 * of 5GHz channels)
4746 */
4747 #if 0
4748 if (b_channel_change &&
4749 (ahp->ah_chip_full_sleep != AH_TRUE) &&
4750 (AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4751 ((chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
4752 (((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & chan->channel_flags) ==
4753 ((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & AH_PRIVATE(ah)->ah_curchan->channel_flags))))
4754 {
4755 if (ar9300_channel_change(ah, chan, ichan, macmode)) {
4756 chan->channel_flags = ichan->channel_flags;
4757 chan->priv_flags = ichan->priv_flags;
4758 AH_PRIVATE(ah)->ah_curchan->ah_channel_time = 0;
4759 AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar9300_get_tsf64(ah);
4760
4761 /*
4762 * Load the NF from history buffer of the current channel.
4763 * NF is slow time-variant, so it is OK to use a historical value.
4764 */
4765 ar9300_get_nf_hist_base(ah,
4766 AH_PRIVATE(ah)->ah_curchan, is_scan, nf_buf);
4767 ar9300_load_nf(ah, nf_buf);
4768
4769 /* start NF calibration, without updating BB NF register*/
4770 ar9300_start_nf_cal(ah);
4771
4772 /*
4773 * If channel_change completed and DMA was stopped
4774 * successfully - skip the rest of reset
4775 */
4776 if (AH9300(ah)->ah_dma_stuck != AH_TRUE) {
4777 WAR_USB_DISABLE_PLL_LOCK_DETECT(ah);
4778 #if ATH_SUPPORT_MCI
4779 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready)
4780 {
4781 ar9300_mci_2g5g_switch(ah, AH_TRUE);
4782 }
4783 #endif
4784 return HAL_OK;
4785 }
4786 }
4787 }
4788 #endif /* #if 0 */
4789
4790 #if ATH_SUPPORT_MCI
4791 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4792 ar9300_mci_disable_interrupt(ah);
4793 if (ahp->ah_mci_ready && !save_full_sleep) {
4794 ar9300_mci_mute_bt(ah);
4795 OS_DELAY(20);
4796 OS_REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
4797 }
4798
4799 ahp->ah_mci_bt_state = MCI_BT_SLEEP;
4800 ahp->ah_mci_ready = AH_FALSE;
4801 }
4802 #endif
4803
4804 AH9300(ah)->ah_dma_stuck = AH_FALSE;
4805 #ifdef ATH_FORCE_PPM
4806 /* Preserve force ppm state */
4807 save_force_val =
4808 OS_REG_READ(ah, AR_PHY_TIMING2) &
4809 (AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4810 #endif
4811 /*
4812 * Preserve the antenna on a channel change
4813 */
4814 save_def_antenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
4815 if (0 == ahp->ah_smartantenna_enable )
4816 {
4817 if (save_def_antenna == 0) {
4818 save_def_antenna = 1;
4819 }
4820 }
4821
4822 /* Save hardware flag before chip reset clears the register */
4823 mac_sta_id1 = OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
4824
4825 /* Save led state from pci config register */
4826 save_led_state = OS_REG_READ(ah, AR_CFG_LED) &
4827 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
4828 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
4829
4830 /* Mark PHY inactive prior to reset, to be undone in ar9300_init_bb () */
4831 ar9300_mark_phy_inactive(ah);
4832
4833 if (!ar9300_chip_reset(ah, chan)) {
4834 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: chip reset failed\n", __func__);
4835 FAIL(HAL_EIO);
4836 }
4837
4838 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4839
4840
4841 /* Disable JTAG */
4842 OS_REG_SET_BIT(ah,
4843 AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
4844
4845 /*
4846 * Note that ar9300_init_chain_masks() is called from within
4847 * ar9300_process_ini() to ensure the swap bit is set before
4848 * the pdadc table is written.
4849 */
4850 ecode = ar9300_process_ini(ah, chan, ichan, macmode);
4851 if (ecode != HAL_OK) {
4852 goto bad;
4853 }
4854
4855 /*
4856 * Configuring WMAC PLL values for 25/40 MHz
4857 */
4858 if(AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah) || AR_SREV_SCORPION(ah) ) {
4859 if(clk_25mhz) {
4860 OS_REG_WRITE(ah, AR_RTC_DERIVED_RTC_CLK, (0x17c << 1)); // 32KHz sleep clk
4861 } else {
4862 OS_REG_WRITE(ah, AR_RTC_DERIVED_RTC_CLK, (0x261 << 1)); // 32KHz sleep clk
4863 }
4864 OS_DELAY(100);
4865 }
4866
4867 ahp->ah_immunity_on = AH_FALSE;
4868
4869 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
4870 ahp->tx_iq_cal_enable = OS_REG_READ_FIELD(ah,
4871 AR_PHY_TX_IQCAL_CONTROL_0(ah),
4872 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL) ?
4873 1 : 0;
4874 }
4875 ahp->tx_cl_cal_enable = (OS_REG_READ(ah, AR_PHY_CL_CAL_CTL) &
4876 AR_PHY_CL_CAL_ENABLE) ? 1 : 0;
4877
4878 /* For devices with full HW RIFS Rx support (Sowl/Howl/Merlin, etc),
4879 * restore register settings from prior to reset.
4880 */
4881 if ((AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4882 (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK))
4883 {
4884 /* Re-program RIFS Rx policy after reset */
4885 ar9300_set_rifs_delay(ah, ahp->ah_rifs_enabled);
4886 }
4887
4888 #if ATH_SUPPORT_MCI
4889 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4890 ar9300_mci_reset(ah, AH_FALSE, IS_CHAN_2GHZ(ichan), save_full_sleep);
4891 }
4892 #endif
4893
4894 /* Initialize Management Frame Protection */
4895 ar9300_init_mfp(ah);
4896
4897 ahp->ah_immunity_vals[0] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4898 AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
4899 ahp->ah_immunity_vals[1] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4900 AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
4901 ahp->ah_immunity_vals[2] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4902 AR_PHY_SFCORR_M1_THRESH);
4903 ahp->ah_immunity_vals[3] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4904 AR_PHY_SFCORR_M2_THRESH);
4905 ahp->ah_immunity_vals[4] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4906 AR_PHY_SFCORR_M2COUNT_THR);
4907 ahp->ah_immunity_vals[5] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4908 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
4909
4910 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
4911 if (IEEE80211_IS_CHAN_OFDM(chan) || IEEE80211_IS_CHAN_HT(chan)) {
4912 ar9300_set_delta_slope(ah, chan);
4913 }
4914
4915 ar9300_spur_mitigate(ah, chan);
4916 if (!ar9300_eeprom_set_board_values(ah, chan)) {
4917 HALDEBUG(ah, HAL_DEBUG_EEPROM,
4918 "%s: error setting board options\n", __func__);
4919 FAIL(HAL_EIO);
4920 }
4921
4922 #ifdef ATH_HAL_WAR_REG16284_APH128
4923 /* temp work around, will be removed. */
4924 if (AR_SREV_WASP(ah)) {
4925 OS_REG_WRITE(ah, 0x16284, 0x1553e000);
4926 }
4927 #endif
4928
4929 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4930
4931 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
4932 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
4933 | mac_sta_id1
4934 | AR_STA_ID1_RTS_USE_DEF
4935 | (ah->ah_config.ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0)
4936 | ahp->ah_sta_id1_defaults
4937 );
4938 ar9300_set_operating_mode(ah, opmode);
4939
4940 /* Set Venice BSSID mask according to current state */
4941 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssid_mask));
4942 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssid_mask + 4));
4943
4944 /* Restore previous antenna */
4945 OS_REG_WRITE(ah, AR_DEF_ANTENNA, save_def_antenna);
4946 #ifdef ATH_FORCE_PPM
4947 /* Restore force ppm state */
4948 tmp_reg = OS_REG_READ(ah, AR_PHY_TIMING2) &
4949 ~(AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4950 OS_REG_WRITE(ah, AR_PHY_TIMING2, tmp_reg | save_force_val);
4951 #endif
4952
4953 /* then our BSSID and assocID */
4954 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
4955 OS_REG_WRITE(ah, AR_BSS_ID1,
4956 LE_READ_2(ahp->ah_bssid + 4) |
4957 ((ahp->ah_assoc_id & 0x3fff) << AR_BSS_ID1_AID_S));
4958
4959 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
4960
4961 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, INIT_RSSI_THR);
4962
4963 /* HW beacon processing */
4964 /*
4965 * XXX what happens if I just leave filter_interval=0?
4966 * it stays disabled?
4967 */
4968 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_BCN_WEIGHT,
4969 INIT_RSSI_BEACON_WEIGHT);
4970 OS_REG_SET_BIT(ah, AR_HWBCNPROC1, AR_HWBCNPROC1_CRC_ENABLE |
4971 AR_HWBCNPROC1_EXCLUDE_TIM_ELM);
4972 if (ah->ah_config.ath_hal_beacon_filter_interval) {
4973 OS_REG_RMW_FIELD(ah, AR_HWBCNPROC2, AR_HWBCNPROC2_FILTER_INTERVAL,
4974 ah->ah_config.ath_hal_beacon_filter_interval);
4975 OS_REG_SET_BIT(ah, AR_HWBCNPROC2,
4976 AR_HWBCNPROC2_FILTER_INTERVAL_ENABLE);
4977 }
4978
4979
4980 /*
4981 * Set Channel now modifies bank 6 parameters for FOWL workaround
4982 * to force rf_pwd_icsyndiv bias current as function of synth
4983 * frequency.Thus must be called after ar9300_process_ini() to ensure
4984 * analog register cache is valid.
4985 */
4986 if (!ahp->ah_rf_hal.set_channel(ah, chan)) {
4987 FAIL(HAL_EIO);
4988 }
4989
4990
4991 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4992
4993 /* Set 1:1 QCU to DCU mapping for all queues */
4994 for (i = 0; i < AR_NUM_DCU; i++) {
4995 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
4996 }
4997
4998 ahp->ah_intr_txqs = 0;
4999 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) {
5000 ar9300_reset_tx_queue(ah, i);
5001 }
5002
5003 ar9300_init_interrupt_masks(ah, opmode);
5004
5005 /* Reset ier reference count to disabled */
5006 // OS_ATOMIC_SET(&ahp->ah_ier_ref_count, 1);
5007 if (ath_hal_isrfkillenabled(ah)) {
5008 ar9300_enable_rf_kill(ah);
5009 }
5010
5011 /* must be called AFTER ini is processed */
5012 ar9300_ani_init_defaults(ah, macmode);
5013
5014 ar9300_init_qos(ah);
5015
5016 ar9300_init_user_settings(ah);
5017
5018
5019 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
5020
5021 OS_MARK(ah, AH_MARK_RESET_DONE, 0);
5022
5023 /*
5024 * disable seq number generation in hw
5025 */
5026 OS_REG_WRITE(ah, AR_STA_ID1,
5027 OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
5028
5029 ar9300_set_dma(ah);
5030
5031 /*
5032 * program OBS bus to see MAC interrupts
5033 */
5034 #if ATH_SUPPORT_MCI
5035 if (!AH_PRIVATE(ah)->ah_caps.halMciSupport) {
5036 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
5037 }
5038 #else
5039 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
5040 #endif
5041
5042
5043 /* enabling AR_GTTM_IGNORE_IDLE in GTTM register so that
5044 GTT timer will not increment if the channel idle indicates
5045 the air is busy or NAV is still counting down */
5046 OS_REG_WRITE(ah, AR_GTTM, AR_GTTM_IGNORE_IDLE);
5047
5048 /*
5049 * GTT debug mode setting
5050 */
5051 /*
5052 OS_REG_WRITE(ah, 0x64, 0x00320000);
5053 OS_REG_WRITE(ah, 0x68, 7);
5054 OS_REG_WRITE(ah, 0x4080, 0xC);
5055 */
5056 /*
5057 * Disable general interrupt mitigation by setting MIRT = 0x0
5058 * Rx and tx interrupt mitigation are conditionally enabled below.
5059 */
5060 OS_REG_WRITE(ah, AR_MIRT, 0);
5061 if (ahp->ah_intr_mitigation_rx) {
5062 /*
5063 * Enable Interrupt Mitigation for Rx.
5064 * If no build-specific limits for the rx interrupt mitigation
5065 * timer have been specified, use conservative defaults.
5066 */
5067 #ifndef AH_RIMT_VAL_LAST
5068 #define AH_RIMT_LAST_MICROSEC 500
5069 #endif
5070 #ifndef AH_RIMT_VAL_FIRST
5071 #define AH_RIMT_FIRST_MICROSEC 2000
5072 #endif
5073 #ifndef HOST_OFFLOAD
5074 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, AH_RIMT_LAST_MICROSEC);
5075 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, AH_RIMT_FIRST_MICROSEC);
5076 #else
5077 /* lower mitigation level to reduce latency for offload arch. */
5078 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST,
5079 (AH_RIMT_LAST_MICROSEC >> 2));
5080 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST,
5081 (AH_RIMT_FIRST_MICROSEC >> 2));
5082 #endif
5083 }
5084
5085 if (ahp->ah_intr_mitigation_tx) {
5086 /*
5087 * Enable Interrupt Mitigation for Tx.
5088 * If no build-specific limits for the tx interrupt mitigation
5089 * timer have been specified, use the values preferred for
5090 * the carrier group's products.
5091 */
5092 #ifndef AH_TIMT_LAST
5093 #define AH_TIMT_LAST_MICROSEC 300
5094 #endif
5095 #ifndef AH_TIMT_FIRST
5096 #define AH_TIMT_FIRST_MICROSEC 750
5097 #endif
5098 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, AH_TIMT_LAST_MICROSEC);
5099 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, AH_TIMT_FIRST_MICROSEC);
5100 }
5101
5102 rx_chainmask = ahp->ah_rx_chainmask;
5103
5104 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5105 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5106
5107 ar9300_init_bb(ah, chan);
5108
5109 /* BB Step 7: Calibration */
5110 /*
5111 * Only kick off calibration not on offchan.
5112 * If coming back from offchan, restore prevous Cal results
5113 * since chip reset will clear existings.
5114 */
5115 if (!ahp->ah_skip_rx_iq_cal) {
5116 int i;
5117 /* clear existing RX cal data */
5118 for (i=0; i<AR9300_MAX_CHAINS; i++)
5119 ahp->ah_rx_cal_corr[i] = 0;
5120
5121 ahp->ah_rx_cal_complete = AH_FALSE;
5122 // ahp->ah_rx_cal_chan = chan->channel;
5123 // ahp->ah_rx_cal_chan_flag = ichan->channel_flags;
5124 ahp->ah_rx_cal_chan = 0;
5125 ahp->ah_rx_cal_chan_flag = 0; /* XXX FreeBSD */
5126 }
5127 ar9300_invalidate_saved_cals(ah, ichan);
5128 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr);
5129
5130 #if ATH_SUPPORT_MCI
5131 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {
5132 if (IS_CHAN_2GHZ(ichan) &&
5133 (ahp->ah_mci_bt_state == MCI_BT_SLEEP))
5134 {
5135 if (ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
5136 ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE))
5137 {
5138 /*
5139 * BT is sleeping. Check if BT wakes up duing WLAN
5140 * calibration. If BT wakes up during WLAN calibration, need
5141 * to go through all message exchanges again and recal.
5142 */
5143 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
5144 "(MCI) ### %s: BT wakes up during WLAN calibration.\n",
5145 __func__);
5146 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
5147 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
5148 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
5149 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) send REMOTE_RESET\n");
5150 ar9300_mci_remote_reset(ah, AH_TRUE);
5151 ar9300_mci_send_sys_waking(ah, AH_TRUE);
5152 OS_DELAY(1);
5153 if (IS_CHAN_2GHZ(ichan)) {
5154 ar9300_mci_send_lna_transfer(ah, AH_TRUE);
5155 }
5156 ahp->ah_mci_bt_state = MCI_BT_AWAKE;
5157
5158 /* Redo calibration */
5159 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Re-calibrate.\n",
5160 __func__);
5161 ar9300_invalidate_saved_cals(ah, ichan);
5162 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr);
5163 }
5164 }
5165 ar9300_mci_enable_interrupt(ah);
5166 }
5167 #endif
5168
5169 if (!cal_ret) {
5170 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Init Cal Failed\n", __func__);
5171 FAIL(HAL_ESELFTEST);
5172 }
5173
5174 ar9300_init_txbf(ah);
5175 #if 0
5176 /*
5177 * WAR for owl 1.0 - restore chain mask for 2-chain cfgs after cal
5178 */
5179 rx_chainmask = ahp->ah_rx_chainmask;
5180 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
5181 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5182 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5183 }
5184 #endif
5185
5186 /* Restore previous led state */
5187 OS_REG_WRITE(ah, AR_CFG_LED, save_led_state | AR_CFG_SCLK_32KHZ);
5188
5189 #if ATH_BT_COEX
5190 if (ahp->ah_bt_coex_config_type != HAL_BT_COEX_CFG_NONE) {
5191 ar9300_init_bt_coex(ah);
5192
5193 #if ATH_SUPPORT_MCI
5194 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {
5195 /* Check BT state again to make sure it's not changed. */
5196 ar9300_mci_sync_bt_state(ah);
5197 ar9300_mci_2g5g_switch(ah, AH_TRUE);
5198
5199 if ((ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
5200 (ahp->ah_mci_query_bt == AH_TRUE))
5201 {
5202 ahp->ah_mci_need_flush_btinfo = AH_TRUE;
5203 }
5204 }
5205 #endif
5206 }
5207 #endif
5208
5209 /* Start TSF2 for generic timer 8-15. */
5210 ar9300_start_tsf2(ah);
5211
5212 /* MIMO Power save setting */
5213 if (ar9300_get_capability(ah, HAL_CAP_DYNAMIC_SMPS, 0, AH_NULL) == HAL_OK) {
5214 ar9300_set_sm_power_mode(ah, ahp->ah_sm_power_mode);
5215 }
5216
5217 /*
5218 * For big endian systems turn on swapping for descriptors
5219 */
5220 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
5221 if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) {
5222 OS_REG_RMW(ah, AR_CFG, AR_CFG_SWTB | AR_CFG_SWRB, 0);
5223 } else {
5224 ar9300_init_cfg_reg(ah);
5225 }
5226 #endif
5227
5228 if ( AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah) ) {
5229 OS_REG_RMW(ah, AR_CFG_LED, AR_CFG_LED_ASSOC_CTL, AR_CFG_LED_ASSOC_CTL);
5230 }
5231
5232 #if !(defined(ART_BUILD)) && defined(ATH_SUPPORT_LED)
5233 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
5234 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
5235 #define ATH_GPIO_OUT_FUNCTION3 0xB8040038
5236 #define ATH_GPIO_OE 0xB8040000
5237 if ( AR_SREV_WASP(ah)) {
5238 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
5239 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x33 << 8) );
5240 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )));
5241 }
5242 else {
5243
5244 /* Disable 2G WLAN LED. During ath_open, reset function is called even before channel is set.
5245 So 2GHz is taken as default and it also blinks. Hence
5246 to avoid both from blinking, disable 2G led while in 5G mode */
5247
5248 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) | (1 << 13) ));
5249 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x33) );
5250 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )));
5251 }
5252
5253 }
5254 else if (AR_SREV_SCORPION(ah)) {
5255 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
5256 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x2F << 8) );
5257 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )) | (0x1 << 12)));
5258 } else if (IS_CHAN_5GHZ((AH_PRIVATE(ah)->ah_curchan))) {
5259 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x2F) );
5260 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )) | (0x1 << 13)));
5261 }
5262 }
5263 else if (AR_SREV_HONEYBEE(ah)) {
5264 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x32) );
5265 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) ))));
5266 }
5267 #undef REG_READ
5268 #undef REG_WRITE
5269 #endif
5270
5271 /* XXX FreeBSD What's this? -adrian */
5272 #if 0
5273 chan->channel_flags = ichan->channel_flags;
5274 chan->priv_flags = ichan->priv_flags;
5275 #endif
5276
5277 #if FIX_NOISE_FLOOR
5278 /* XXX FreeBSD is ichan appropariate? It was curchan.. */
5279 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
5280 ar9300_load_nf(ah, nf_buf);
5281 if (nf_hist_buff_reset == 1)
5282 {
5283 nf_hist_buff_reset = 0;
5284 #ifndef ATH_NF_PER_CHAN
5285 if (First_NFCal(ah, ichan, is_scan, chan)){
5286 if (ahp->ah_skip_rx_iq_cal && !is_scan) {
5287 /* restore RX Cal result if existing */
5288 ar9300_rx_iq_cal_restore(ah);
5289 ahp->ah_skip_rx_iq_cal = AH_FALSE;
5290 }
5291 }
5292 #endif /* ATH_NF_PER_CHAN */
5293 }
5294 else{
5295 ar9300_start_nf_cal(ah);
5296 }
5297 #endif
5298
5299 #ifdef AH_SUPPORT_AR9300
5300 /* BB Panic Watchdog */
5301 if (ar9300_get_capability(ah, HAL_CAP_BB_PANIC_WATCHDOG, 0, AH_NULL) ==
5302 HAL_OK)
5303 {
5304 ar9300_config_bb_panic_watchdog(ah);
5305 }
5306 #endif
5307
5308 /* While receiving unsupported rate frame receive state machine
5309 * gets into a state 0xb and if phy_restart happens when rx
5310 * state machine is in 0xb state, BB would go hang, if we
5311 * see 0xb state after first bb panic, make sure that we
5312 * disable the phy_restart.
5313 *
5314 * There may be multiple panics, make sure that we always do
5315 * this if we see this panic at least once. This is required
5316 * because reset seems to be writing from INI file.
5317 */
5318 if ((ar9300_get_capability(ah, HAL_CAP_PHYRESTART_CLR_WAR, 0, AH_NULL)
5319 == HAL_OK) && (((MS((AH9300(ah)->ah_bb_panic_last_status),
5320 AR_PHY_BB_WD_RX_OFDM_SM)) == 0xb) ||
5321 AH9300(ah)->ah_phyrestart_disabled) )
5322 {
5323 ar9300_disable_phy_restart(ah, 1);
5324 }
5325
5326
5327
5328 ahp->ah_radar1 = MS(OS_REG_READ(ah, AR_PHY_RADAR_1),
5329 AR_PHY_RADAR_1_CF_BIN_THRESH);
5330 ahp->ah_dc_offset = MS(OS_REG_READ(ah, AR_PHY_TIMING2),
5331 AR_PHY_TIMING2_DC_OFFSET);
5332 ahp->ah_disable_cck = MS(OS_REG_READ(ah, AR_PHY_MODE),
5333 AR_PHY_MODE_DISABLE_CCK);
5334
5335 if (AH9300(ah)->ah_enable_keysearch_always) {
5336 ar9300_enable_keysearch_always(ah, 1);
5337 }
5338
5339 #if ATH_LOW_POWER_ENABLE
5340 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val)
5341 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
5342 if (AR_SREV_OSPREY(ah)) {
5343 REG_WRITE(0xb4000080, REG_READ(0xb4000080) | 3);
5344 OS_REG_WRITE(ah, AR_RTC_RESET, 1);
5345 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL),
5346 AR_PCIE_PM_CTRL_ENA);
5347 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_SPARE), 0xffffffff);
5348 }
5349 #undef REG_READ
5350 #undef REG_WRITE
5351 #endif /* ATH_LOW_POWER_ENABLE */
5352
5353 WAR_USB_DISABLE_PLL_LOCK_DETECT(ah);
5354
5355 /* H/W Green TX */
5356 ar9300_control_signals_for_green_tx_mode(ah);
5357 /* Smart Antenna, only for 5GHz on Scropion */
5358 if (IEEE80211_IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan)) && AR_SREV_SCORPION(ah)) {
5359 ahp->ah_smartantenna_enable = 0;
5360 }
5361
5362 ar9300_set_smart_antenna(ah, ahp->ah_smartantenna_enable);
5363
5364 if (AR_SREV_APHRODITE(ah) && ahp->ah_lna_div_use_bt_ant_enable)
5365 OS_REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
5366
5367 if (ahp->ah_skip_rx_iq_cal && !is_scan) {
5368 /* restore RX Cal result if existing */
5369 ar9300_rx_iq_cal_restore(ah);
5370 ahp->ah_skip_rx_iq_cal = AH_FALSE;
5371 }
5372
5373
5374 return AH_TRUE;
5375 bad:
5376 OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
5377 *status = ecode;
5378
5379 if (ahp->ah_skip_rx_iq_cal && !is_scan) {
5380 /* restore RX Cal result if existing */
5381 ar9300_rx_iq_cal_restore(ah);
5382 ahp->ah_skip_rx_iq_cal = AH_FALSE;
5383 }
5384
5385 return AH_FALSE;
5386 #undef FAIL
5387 }
5388
5389 void
ar9300_green_ap_ps_on_off(struct ath_hal * ah,u_int16_t on_off)5390 ar9300_green_ap_ps_on_off( struct ath_hal *ah, u_int16_t on_off)
5391 {
5392 /* Set/reset the ps flag */
5393 AH9300(ah)->green_ap_ps_on = !!on_off;
5394 }
5395
5396 /*
5397 * This function returns 1, where it is possible to do
5398 * single-chain power save.
5399 */
5400 u_int16_t
ar9300_is_single_ant_power_save_possible(struct ath_hal * ah)5401 ar9300_is_single_ant_power_save_possible(struct ath_hal *ah)
5402 {
5403 return AH_TRUE;
5404 }
5405
5406 /* To avoid compilation warnings. Functions not used when EMULATION. */
5407 /*
5408 * ar9300_find_mag_approx()
5409 */
5410 static int32_t
ar9300_find_mag_approx(struct ath_hal * ah,int32_t in_re,int32_t in_im)5411 ar9300_find_mag_approx(struct ath_hal *ah, int32_t in_re, int32_t in_im)
5412 {
5413 int32_t abs_i = abs(in_re);
5414 int32_t abs_q = abs(in_im);
5415 int32_t max_abs, min_abs;
5416
5417 if (abs_i > abs_q) {
5418 max_abs = abs_i;
5419 min_abs = abs_q;
5420 } else {
5421 max_abs = abs_q;
5422 min_abs = abs_i;
5423 }
5424
5425 return (max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4));
5426 }
5427
5428 /*
5429 * ar9300_solve_iq_cal()
5430 * solve 4x4 linear equation used in loopback iq cal.
5431 */
5432 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[])5433 ar9300_solve_iq_cal(
5434 struct ath_hal *ah,
5435 int32_t sin_2phi_1,
5436 int32_t cos_2phi_1,
5437 int32_t sin_2phi_2,
5438 int32_t cos_2phi_2,
5439 int32_t mag_a0_d0,
5440 int32_t phs_a0_d0,
5441 int32_t mag_a1_d0,
5442 int32_t phs_a1_d0,
5443 int32_t solved_eq[])
5444 {
5445 int32_t f1 = cos_2phi_1 - cos_2phi_2;
5446 int32_t f3 = sin_2phi_1 - sin_2phi_2;
5447 int32_t f2;
5448 int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5449 const int32_t result_shift = 1 << 15;
5450
5451 f2 = (((int64_t)f1 * (int64_t)f1) / result_shift) + (((int64_t)f3 * (int64_t)f3) / result_shift);
5452
5453 if (0 == f2) {
5454 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Divide by 0(%d).\n",
5455 __func__, __LINE__);
5456 return AH_FALSE;
5457 }
5458
5459 /* magnitude mismatch, tx */
5460 mag_tx = f1 * (mag_a0_d0 - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
5461 /* phase mismatch, tx */
5462 phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
5463
5464 mag_tx = (mag_tx / f2);
5465 phs_tx = (phs_tx / f2);
5466
5467 /* magnitude mismatch, rx */
5468 mag_rx =
5469 mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) / result_shift;
5470 /* phase mismatch, rx */
5471 phs_rx =
5472 phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) / result_shift;
5473
5474 solved_eq[0] = mag_tx;
5475 solved_eq[1] = phs_tx;
5476 solved_eq[2] = mag_rx;
5477 solved_eq[3] = phs_rx;
5478
5479 return AH_TRUE;
5480 }
5481
5482 /*
5483 * ar9300_calc_iq_corr()
5484 */
5485 static HAL_BOOL
ar9300_calc_iq_corr(struct ath_hal * ah,int32_t chain_idx,const int32_t iq_res[],int32_t iqc_coeff[])5486 ar9300_calc_iq_corr(struct ath_hal *ah, int32_t chain_idx,
5487 const int32_t iq_res[], int32_t iqc_coeff[])
5488 {
5489 int32_t i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0;
5490 int32_t i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1;
5491 int32_t i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0;
5492 int32_t i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
5493 int32_t mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1;
5494 int32_t phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1;
5495 int32_t sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2;
5496 int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5497 int32_t solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx;
5498 int32_t q_q_coff, q_i_coff;
5499 const int32_t res_scale = 1 << 15;
5500 const int32_t delpt_shift = 1 << 8;
5501 int32_t mag1, mag2;
5502
5503 i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
5504 i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
5505 iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
5506
5507 if (i2_m_q2_a0_d0 > 0x800) {
5508 i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
5509 }
5510 if (iq_corr_a0_d0 > 0x800) {
5511 iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
5512 }
5513
5514 i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
5515 i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
5516 iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
5517
5518 if (i2_m_q2_a0_d1 > 0x800) {
5519 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
5520 }
5521 if (iq_corr_a0_d1 > 0x800) {
5522 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
5523 }
5524
5525 i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
5526 i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
5527 iq_corr_a1_d0 = iq_res[4] & 0xfff;
5528
5529 if (i2_m_q2_a1_d0 > 0x800) {
5530 i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
5531 }
5532 if (iq_corr_a1_d0 > 0x800) {
5533 iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
5534 }
5535
5536 i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
5537 i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
5538 iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
5539
5540 if (i2_m_q2_a1_d1 > 0x800) {
5541 i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
5542 }
5543 if (iq_corr_a1_d1 > 0x800) {
5544 iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
5545 }
5546
5547 if ((i2_p_q2_a0_d0 == 0) ||
5548 (i2_p_q2_a0_d1 == 0) ||
5549 (i2_p_q2_a1_d0 == 0) ||
5550 (i2_p_q2_a1_d1 == 0)) {
5551 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5552 "%s: Divide by 0(%d):\na0_d0=%d\na0_d1=%d\na2_d0=%d\na1_d1=%d\n",
5553 __func__, __LINE__,
5554 i2_p_q2_a0_d0, i2_p_q2_a0_d1, i2_p_q2_a1_d0, i2_p_q2_a1_d1);
5555 return AH_FALSE;
5556 }
5557
5558 if ((i2_p_q2_a0_d0 <= 1024) || (i2_p_q2_a0_d0 > 2047) ||
5559 (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) ||
5560 (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) ||
5561 (i2_p_q2_a0_d0 <= iq_corr_a0_d0) ||
5562 (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) ||
5563 (i2_p_q2_a0_d1 <= iq_corr_a0_d1) ||
5564 (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) ||
5565 (i2_p_q2_a1_d0 <= iq_corr_a1_d0) ||
5566 (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) ||
5567 (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) {
5568 return AH_FALSE;
5569 }
5570
5571 mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5572 phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5573
5574 mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5575 phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5576
5577 mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5578 phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5579
5580 mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5581 phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5582
5583 /* without analog phase shift */
5584 sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
5585 /* without analog phase shift */
5586 cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
5587 /* with analog phase shift */
5588 sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
5589 /* with analog phase shift */
5590 cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
5591
5592 /* force sin^2 + cos^2 = 1; */
5593 /* find magnitude by approximation */
5594 mag1 = ar9300_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
5595 mag2 = ar9300_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
5596
5597 if ((mag1 == 0) || (mag2 == 0)) {
5598 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5599 "%s: Divide by 0(%d): mag1=%d, mag2=%d\n",
5600 __func__, __LINE__, mag1, mag2);
5601 return AH_FALSE;
5602 }
5603
5604 /* normalization sin and cos by mag */
5605 sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
5606 cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
5607 sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
5608 cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
5609
5610 /* calculate IQ mismatch */
5611 if (AH_FALSE == ar9300_solve_iq_cal(ah,
5612 sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2, mag_a0_d0,
5613 phs_a0_d0, mag_a1_d0, phs_a1_d0, solved_eq))
5614 {
5615 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5616 "%s: Call to ar9300_solve_iq_cal failed.\n", __func__);
5617 return AH_FALSE;
5618 }
5619
5620 mag_tx = solved_eq[0];
5621 phs_tx = solved_eq[1];
5622 mag_rx = solved_eq[2];
5623 phs_rx = solved_eq[3];
5624
5625 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5626 "%s: chain %d: mag mismatch=%d phase mismatch=%d\n",
5627 __func__, chain_idx, mag_tx / res_scale, phs_tx / res_scale);
5628
5629 if (res_scale == mag_tx) {
5630 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5631 "%s: Divide by 0(%d): mag_tx=%d, res_scale=%d\n",
5632 __func__, __LINE__, mag_tx, res_scale);
5633 return AH_FALSE;
5634 }
5635
5636 /* calculate and quantize Tx IQ correction factor */
5637 mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
5638 phs_corr_tx = -phs_tx;
5639
5640 q_q_coff = (mag_corr_tx * 128 / res_scale);
5641 q_i_coff = (phs_corr_tx * 256 / res_scale);
5642
5643 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5644 "%s: tx chain %d: mag corr=%d phase corr=%d\n",
5645 __func__, chain_idx, q_q_coff, q_i_coff);
5646
5647 if (q_i_coff < -63) {
5648 q_i_coff = -63;
5649 }
5650 if (q_i_coff > 63) {
5651 q_i_coff = 63;
5652 }
5653 if (q_q_coff < -63) {
5654 q_q_coff = -63;
5655 }
5656 if (q_q_coff > 63) {
5657 q_q_coff = 63;
5658 }
5659
5660 iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
5661
5662 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: tx chain %d: iq corr coeff=%x\n",
5663 __func__, chain_idx, iqc_coeff[0]);
5664
5665 if (-mag_rx == res_scale) {
5666 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5667 "%s: Divide by 0(%d): mag_rx=%d, res_scale=%d\n",
5668 __func__, __LINE__, mag_rx, res_scale);
5669 return AH_FALSE;
5670 }
5671
5672 /* calculate and quantize Rx IQ correction factors */
5673 mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
5674 phs_corr_rx = -phs_rx;
5675
5676 q_q_coff = (mag_corr_rx * 128 / res_scale);
5677 q_i_coff = (phs_corr_rx * 256 / res_scale);
5678
5679 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5680 "%s: rx chain %d: mag corr=%d phase corr=%d\n",
5681 __func__, chain_idx, q_q_coff, q_i_coff);
5682
5683 if (q_i_coff < -63) {
5684 q_i_coff = -63;
5685 }
5686 if (q_i_coff > 63) {
5687 q_i_coff = 63;
5688 }
5689 if (q_q_coff < -63) {
5690 q_q_coff = -63;
5691 }
5692 if (q_q_coff > 63) {
5693 q_q_coff = 63;
5694 }
5695
5696 iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
5697
5698 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: rx chain %d: iq corr coeff=%x\n",
5699 __func__, chain_idx, iqc_coeff[1]);
5700
5701 return AH_TRUE;
5702 }
5703
5704 #define MAX_MAG_DELTA 11 //maximum magnitude mismatch delta across gains
5705 #define MAX_PHS_DELTA 10 //maximum phase mismatch delta across gains
5706 #define ABS(x) ((x) >= 0 ? (x) : (-(x)))
5707
5708 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5709 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5710 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5711 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5712 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5713 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5714 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5715 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5716 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5717 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5718 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5719 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5720 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5721 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5722 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5723 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5724 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5725 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5726 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5727 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5728 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5729 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5730 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5731 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5732 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5733 };
5734
5735 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)5736 ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan, u_int32_t num_chains,
5737 struct coeff_t *coeff, HAL_BOOL is_cal_reusable)
5738 {
5739 int nmeasurement, ch_idx, im;
5740 int32_t magnitude, phase;
5741 int32_t magnitude_max, phase_max;
5742 int32_t magnitude_min, phase_min;
5743
5744 int32_t magnitude_max_idx, phase_max_idx;
5745 int32_t magnitude_min_idx, phase_min_idx;
5746
5747 int32_t magnitude_avg, phase_avg;
5748 int32_t outlier_mag_idx = 0;
5749 int32_t outlier_phs_idx = 0;
5750
5751
5752 if (AR_SREV_POSEIDON(ah)) {
5753 HALASSERT(num_chains == 0x1);
5754
5755 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5756 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5757 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5758 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5759 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5760 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5761 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5762 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5763 }
5764
5765 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5766 nmeasurement = OS_REG_READ_FIELD(ah,
5767 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
5768 if (nmeasurement > MAX_MEASUREMENT) {
5769 nmeasurement = MAX_MEASUREMENT;
5770 }
5771
5772 if (!AR_SREV_SCORPION(ah)) {
5773 /*
5774 * reset max/min variable to min/max values so that
5775 * we always start with 1st calibrated gain value
5776 */
5777 magnitude_max = -64;
5778 phase_max = -64;
5779 magnitude_min = 63;
5780 phase_min = 63;
5781 magnitude_avg = 0;
5782 phase_avg = 0;
5783 magnitude_max_idx = 0;
5784 magnitude_min_idx = 0;
5785 phase_max_idx = 0;
5786 phase_min_idx = 0;
5787
5788 /* detect outlier only if nmeasurement > 1 */
5789 if (nmeasurement > 1) {
5790 /* printf("----------- start outlier detection -----------\n"); */
5791 /*
5792 * find max/min and phase/mag mismatch across all calibrated gains
5793 */
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
5798 magnitude_avg = magnitude_avg + magnitude;
5799 phase_avg = phase_avg + phase;
5800 if (magnitude > magnitude_max) {
5801 magnitude_max = magnitude;
5802 magnitude_max_idx = im;
5803 }
5804 if (magnitude < magnitude_min) {
5805 magnitude_min = magnitude;
5806 magnitude_min_idx = im;
5807 }
5808 if (phase > phase_max) {
5809 phase_max = phase;
5810 phase_max_idx = im;
5811 }
5812 if (phase < phase_min) {
5813 phase_min = phase;
5814 phase_min_idx = im;
5815 }
5816 }
5817 /* find average (exclude max abs value) */
5818 for (im = 0; im < nmeasurement; im++) {
5819 magnitude = coeff->mag_coeff[ch_idx][im][0];
5820 phase = coeff->phs_coeff[ch_idx][im][0];
5821 if ((ABS(magnitude) < ABS(magnitude_max)) ||
5822 (ABS(magnitude) < ABS(magnitude_min)))
5823 {
5824 magnitude_avg = magnitude_avg + magnitude;
5825 }
5826 if ((ABS(phase) < ABS(phase_max)) ||
5827 (ABS(phase) < ABS(phase_min)))
5828 {
5829 phase_avg = phase_avg + phase;
5830 }
5831 }
5832 magnitude_avg = magnitude_avg / (nmeasurement - 1);
5833 phase_avg = phase_avg / (nmeasurement - 1);
5834
5835 /* detect magnitude outlier */
5836 if (ABS(magnitude_max - magnitude_min) > MAX_MAG_DELTA) {
5837 if (ABS(magnitude_max - magnitude_avg) >
5838 ABS(magnitude_min - magnitude_avg))
5839 {
5840 /* max is outlier, force to avg */
5841 outlier_mag_idx = magnitude_max_idx;
5842 } else {
5843 /* min is outlier, force to avg */
5844 outlier_mag_idx = magnitude_min_idx;
5845 }
5846 coeff->mag_coeff[ch_idx][outlier_mag_idx][0] = magnitude_avg;
5847 coeff->phs_coeff[ch_idx][outlier_mag_idx][0] = phase_avg;
5848 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5849 "[ch%d][outlier mag gain%d]:: "
5850 "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5851 ch_idx, outlier_mag_idx, magnitude_avg, phase_avg);
5852 }
5853 /* detect phase outlier */
5854 if (ABS(phase_max - phase_min) > MAX_PHS_DELTA) {
5855 if (ABS(phase_max-phase_avg) > ABS(phase_min - phase_avg)) {
5856 /* max is outlier, force to avg */
5857 outlier_phs_idx = phase_max_idx;
5858 } else{
5859 /* min is outlier, force to avg */
5860 outlier_phs_idx = phase_min_idx;
5861 }
5862 coeff->mag_coeff[ch_idx][outlier_phs_idx][0] = magnitude_avg;
5863 coeff->phs_coeff[ch_idx][outlier_phs_idx][0] = phase_avg;
5864 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5865 "[ch%d][outlier phs gain%d]:: "
5866 "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5867 ch_idx, outlier_phs_idx, magnitude_avg, phase_avg);
5868 }
5869 }
5870 }
5871
5872 /*printf("------------ after outlier detection -------------\n");*/
5873 for (im = 0; im < nmeasurement; im++) {
5874 magnitude = coeff->mag_coeff[ch_idx][im][0];
5875 phase = coeff->phs_coeff[ch_idx][im][0];
5876
5877 #if 0
5878 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
5879 ch_idx, im, magnitude, phase);
5880 #endif
5881
5882 coeff->iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
5883
5884 if ((im % 2) == 0) {
5885 OS_REG_RMW_FIELD(ah,
5886 tx_corr_coeff[im][ch_idx],
5887 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5888 coeff->iqc_coeff[0]);
5889 } else {
5890 OS_REG_RMW_FIELD(ah,
5891 tx_corr_coeff[im][ch_idx],
5892 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5893 coeff->iqc_coeff[0]);
5894 }
5895 #if ATH_SUPPORT_CAL_REUSE
5896 ichan->tx_corr_coeff[im][ch_idx] = coeff->iqc_coeff[0];
5897 #endif
5898 }
5899 #if ATH_SUPPORT_CAL_REUSE
5900 ichan->num_measures[ch_idx] = nmeasurement;
5901 #endif
5902 }
5903
5904 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5905 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5906 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
5907 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
5908
5909 #if ATH_SUPPORT_CAL_REUSE
5910 if (is_cal_reusable) {
5911 ichan->one_time_txiqcal_done = AH_TRUE;
5912 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
5913 "(FCS) TXIQCAL saved - %d\n", ichan->channel);
5914 }
5915 #endif
5916 }
5917
5918 #if ATH_SUPPORT_CAL_REUSE
5919 static void
ar9300_tx_iq_cal_apply(struct ath_hal * ah,HAL_CHANNEL_INTERNAL * ichan)5920 ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
5921 {
5922 struct ath_hal_9300 *ahp = AH9300(ah);
5923 int nmeasurement, ch_idx, im;
5924
5925 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5926 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5927 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5928 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5929 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5930 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5931 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5932 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5933 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5934 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5935 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5936 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5937 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5938 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5939 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5940 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5941 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5942 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5943 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5944 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5945 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5946 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5947 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5948 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5949 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5950 };
5951
5952 if (AR_SREV_POSEIDON(ah)) {
5953 HALASSERT(ahp->ah_tx_cal_chainmask == 0x1);
5954
5955 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5956 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5957 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5958 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5959 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5960 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5961 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5962 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5963 }
5964
5965 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
5966 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
5967 continue;
5968 }
5969 nmeasurement = ichan->num_measures[ch_idx];
5970
5971 for (im = 0; im < nmeasurement; im++) {
5972 if ((im % 2) == 0) {
5973 OS_REG_RMW_FIELD(ah,
5974 tx_corr_coeff[im][ch_idx],
5975 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5976 ichan->tx_corr_coeff[im][ch_idx]);
5977 } else {
5978 OS_REG_RMW_FIELD(ah,
5979 tx_corr_coeff[im][ch_idx],
5980 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5981 ichan->tx_corr_coeff[im][ch_idx]);
5982 }
5983 }
5984 }
5985
5986 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5987 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5988 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
5989 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
5990 }
5991 #endif
5992
5993 /*
5994 * ar9300_tx_iq_cal_hw_run is only needed for osprey/wasp/hornet
5995 * It is not needed for jupiter/poseidon.
5996 */
5997 HAL_BOOL
ar9300_tx_iq_cal_hw_run(struct ath_hal * ah)5998 ar9300_tx_iq_cal_hw_run(struct ath_hal *ah)
5999 {
6000 int is_tx_gain_forced;
6001
6002 is_tx_gain_forced = OS_REG_READ_FIELD(ah,
6003 AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE);
6004 if (is_tx_gain_forced) {
6005 /*printf("Tx gain can not be forced during tx I/Q cal!\n");*/
6006 OS_REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE, 0);
6007 }
6008
6009 /* enable tx IQ cal */
6010 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START(ah),
6011 AR_PHY_TX_IQCAL_START_DO_CAL, AR_PHY_TX_IQCAL_START_DO_CAL);
6012
6013 if (!ath_hal_wait(ah,
6014 AR_PHY_TX_IQCAL_START(ah), AR_PHY_TX_IQCAL_START_DO_CAL, 0))
6015 {
6016 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6017 "%s: Tx IQ Cal is never completed.\n", __func__);
6018 return AH_FALSE;
6019 }
6020 return AH_TRUE;
6021 }
6022
6023 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)6024 ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
6025 int iqcal_idx, int max_iqcal,HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr)
6026 {
6027 int nmeasurement=0, im, ix, iy, temp;
6028 struct ath_hal_9300 *ahp = AH9300(ah);
6029 u_int32_t txiqcal_status[AR9300_MAX_CHAINS] = {
6030 AR_PHY_TX_IQCAL_STATUS_B0(ah),
6031 AR_PHY_TX_IQCAL_STATUS_B1,
6032 AR_PHY_TX_IQCAL_STATUS_B2,
6033 };
6034 const u_int32_t chan_info_tab[] = {
6035 AR_PHY_CHAN_INFO_TAB_0,
6036 AR_PHY_CHAN_INFO_TAB_1,
6037 AR_PHY_CHAN_INFO_TAB_2,
6038 };
6039 int32_t iq_res[6];
6040 int32_t ch_idx, j;
6041 u_int32_t num_chains = 0;
6042 static struct coeff_t coeff;
6043 txiqcal_status[0] = AR_PHY_TX_IQCAL_STATUS_B0(ah);
6044
6045 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
6046 if (ahp->ah_tx_chainmask & (1 << ch_idx)) {
6047 num_chains++;
6048 }
6049 }
6050
6051 if (apply_last_corr) {
6052 if (coeff.last_cal == AH_TRUE) {
6053 int32_t magnitude, phase;
6054 int ch_idx, im;
6055 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
6056 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
6057 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
6058 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
6059 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
6060 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
6061 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
6062 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
6063 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
6064 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
6065 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
6066 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
6067 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
6068 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
6069 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
6070 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
6071 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
6072 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
6073 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
6074 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
6075 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
6076 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
6077 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
6078 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
6079 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
6080 };
6081 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
6082 for (im = 0; im < coeff.last_nmeasurement; im++) {
6083 magnitude = coeff.mag_coeff[ch_idx][im][0];
6084 phase = coeff.phs_coeff[ch_idx][im][0];
6085
6086 #if 0
6087 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
6088 ch_idx, im, magnitude, phase);
6089 #endif
6090
6091 coeff.iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
6092 if ((im % 2) == 0) {
6093 OS_REG_RMW_FIELD(ah,
6094 tx_corr_coeff[im][ch_idx],
6095 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
6096 coeff.iqc_coeff[0]);
6097 } else {
6098 OS_REG_RMW_FIELD(ah,
6099 tx_corr_coeff[im][ch_idx],
6100 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
6101 coeff.iqc_coeff[0]);
6102 }
6103 }
6104 }
6105 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
6106 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
6107 }
6108 return;
6109 }
6110
6111
6112 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
6113 nmeasurement = OS_REG_READ_FIELD(ah,
6114 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
6115 if (nmeasurement > MAX_MEASUREMENT) {
6116 nmeasurement = MAX_MEASUREMENT;
6117 }
6118
6119 for (im = 0; im < nmeasurement; im++) {
6120 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6121 "%s: Doing Tx IQ Cal for chain %d.\n", __func__, ch_idx);
6122 if (OS_REG_READ(ah, txiqcal_status[ch_idx]) &
6123 AR_PHY_TX_IQCAL_STATUS_FAILED)
6124 {
6125 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6126 "%s: Tx IQ Cal failed for chain %d.\n", __func__, ch_idx);
6127 goto TX_IQ_CAL_FAILED_;
6128 }
6129
6130 for (j = 0; j < 3; j++) {
6131 u_int32_t idx = 2 * j;
6132 /* 3 registers for each calibration result */
6133 u_int32_t offset = 4 * (3 * im + j);
6134
6135 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
6136 AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
6137 /* 32 bits */
6138 iq_res[idx] = OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
6139 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
6140 AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
6141 /* 16 bits */
6142 iq_res[idx + 1] = 0xffff &
6143 OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
6144
6145 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6146 "%s: IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
6147 __func__, idx, iq_res[idx], idx + 1, iq_res[idx + 1]);
6148 }
6149
6150 if (AH_FALSE == ar9300_calc_iq_corr(
6151 ah, ch_idx, iq_res, coeff.iqc_coeff))
6152 {
6153 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6154 "%s: Failed in calculation of IQ correction.\n",
6155 __func__);
6156 goto TX_IQ_CAL_FAILED_;
6157 }
6158
6159 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] = coeff.iqc_coeff[0] & 0x7f;
6160 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] = (coeff.iqc_coeff[0] >> 7) & 0x7f;
6161 if (coeff.mag_coeff[ch_idx][im][iqcal_idx-1] > 63) {
6162 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] -= 128;
6163 }
6164 if (coeff.phs_coeff[ch_idx][im][iqcal_idx-1] > 63) {
6165 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] -= 128;
6166 }
6167 #if 0
6168 ath_hal_printf(ah, "IQCAL::[ch%d][gain%d]:: mag = %d phase = %d \n",
6169 ch_idx, im, coeff.mag_coeff[ch_idx][im][iqcal_idx-1],
6170 coeff.phs_coeff[ch_idx][im][iqcal_idx-1]);
6171 #endif
6172 }
6173 }
6174 //last iteration; calculate mag and phs
6175 if (iqcal_idx == max_iqcal) {
6176 if (max_iqcal>1) {
6177 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
6178 for (im = 0; im < nmeasurement; im++) {
6179 //sort mag and phs
6180 for( ix=0;ix<max_iqcal-1;ix++){
6181 for( iy=ix+1;iy<=max_iqcal-1;iy++){
6182 if(coeff.mag_coeff[ch_idx][im][iy] <
6183 coeff.mag_coeff[ch_idx][im][ix]) {
6184 //swap
6185 temp=coeff.mag_coeff[ch_idx][im][ix];
6186 coeff.mag_coeff[ch_idx][im][ix] = coeff.mag_coeff[ch_idx][im][iy];
6187 coeff.mag_coeff[ch_idx][im][iy] = temp;
6188 }
6189 if(coeff.phs_coeff[ch_idx][im][iy] <
6190 coeff.phs_coeff[ch_idx][im][ix]){
6191 //swap
6192 temp=coeff.phs_coeff[ch_idx][im][ix];
6193 coeff.phs_coeff[ch_idx][im][ix]=coeff.phs_coeff[ch_idx][im][iy];
6194 coeff.phs_coeff[ch_idx][im][iy]=temp;
6195 }
6196 }
6197 }
6198 //select median; 3rd entry in the sorted array
6199 coeff.mag_coeff[ch_idx][im][0] =
6200 coeff.mag_coeff[ch_idx][im][max_iqcal/2];
6201 coeff.phs_coeff[ch_idx][im][0] =
6202 coeff.phs_coeff[ch_idx][im][max_iqcal/2];
6203 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6204 "IQCAL: Median [ch%d][gain%d]:: mag = %d phase = %d \n",
6205 ch_idx, im,coeff.mag_coeff[ch_idx][im][0],
6206 coeff.phs_coeff[ch_idx][im][0]);
6207 }
6208 }
6209 }
6210 ar9300_tx_iq_cal_outlier_detection(ah,ichan, num_chains, &coeff,is_cal_reusable);
6211 }
6212
6213
6214 coeff.last_nmeasurement = nmeasurement;
6215 coeff.last_cal = AH_TRUE;
6216
6217 return;
6218
6219 TX_IQ_CAL_FAILED_:
6220 /* no need to print this, it is AGC failure not chip stuck */
6221 /*ath_hal_printf(ah, "Tx IQ Cal failed(%d)\n", line);*/
6222 coeff.last_cal = AH_FALSE;
6223 return;
6224 }
6225
6226
6227 /*
6228 * ar9300_disable_phy_restart
6229 *
6230 * In some BBpanics, we can disable the phyrestart
6231 * disable_phy_restart
6232 * != 0, disable the phy restart in h/w
6233 * == 0, enable the phy restart in h/w
6234 */
ar9300_disable_phy_restart(struct ath_hal * ah,int disable_phy_restart)6235 void ar9300_disable_phy_restart(struct ath_hal *ah, int disable_phy_restart)
6236 {
6237 u_int32_t val;
6238
6239 val = OS_REG_READ(ah, AR_PHY_RESTART);
6240 if (disable_phy_restart) {
6241 val &= ~AR_PHY_RESTART_ENA;
6242 AH9300(ah)->ah_phyrestart_disabled = 1;
6243 } else {
6244 val |= AR_PHY_RESTART_ENA;
6245 AH9300(ah)->ah_phyrestart_disabled = 0;
6246 }
6247 OS_REG_WRITE(ah, AR_PHY_RESTART, val);
6248
6249 val = OS_REG_READ(ah, AR_PHY_RESTART);
6250 }
6251
6252 HAL_BOOL
ar9300_interference_is_present(struct ath_hal * ah)6253 ar9300_interference_is_present(struct ath_hal *ah)
6254 {
6255 int i;
6256 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6257 const struct ieee80211_channel *chan = ahpriv->ah_curchan;
6258 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
6259
6260 if (ichan == NULL) {
6261 ath_hal_printf(ah, "%s: called with ichan=NULL\n", __func__);
6262 return AH_FALSE;
6263 }
6264
6265 /* This function is called after a stuck beacon, if EACS is enabled.
6266 * If CW interference is severe, then HW goes into a loop of continuous
6267 * stuck beacons and resets. On reset the NF cal history is cleared.
6268 * So the median value of the history cannot be used -
6269 * hence check if any value (Chain 0/Primary Channel)
6270 * is outside the bounds.
6271 */
6272 HAL_NFCAL_HIST_FULL *h = AH_HOME_CHAN_NFCAL_HIST(ah, ichan);
6273 for (i = 0; i < HAL_NF_CAL_HIST_LEN_FULL; i++) {
6274 if (h->nf_cal_buffer[i][0] >
6275 AH9300(ah)->nfp->nominal + AH9300(ah)->nf_cw_int_delta)
6276 {
6277 return AH_TRUE;
6278 }
6279
6280 }
6281 return AH_FALSE;
6282 }
6283
6284 #if ATH_SUPPORT_CRDC
6285 void
ar9300_crdc_rx_notify(struct ath_hal * ah,struct ath_rx_status * rxs)6286 ar9300_crdc_rx_notify(struct ath_hal *ah, struct ath_rx_status *rxs)
6287 {
6288 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6289 int rssi_index;
6290
6291 if ((!AR_SREV_WASP(ah)) ||
6292 (!ahpriv->ah_config.ath_hal_crdc_enable)) {
6293 return;
6294 }
6295
6296 if (rxs->rs_isaggr && rxs->rs_moreaggr) {
6297 return;
6298 }
6299
6300 if ((rxs->rs_rssi_ctl0 >= HAL_RSSI_BAD) ||
6301 (rxs->rs_rssi_ctl1 >= HAL_RSSI_BAD)) {
6302 return;
6303 }
6304
6305 rssi_index = ah->ah_crdc_rssi_ptr % HAL_MAX_CRDC_RSSI_SAMPLE;
6306
6307 ah->ah_crdc_rssi_sample[0][rssi_index] = rxs->rs_rssi_ctl0;
6308 ah->ah_crdc_rssi_sample[1][rssi_index] = rxs->rs_rssi_ctl1;
6309
6310 ah->ah_crdc_rssi_ptr++;
6311 }
6312
6313 static int
ar9300_crdc_avg_rssi(struct ath_hal * ah,int chain)6314 ar9300_crdc_avg_rssi(struct ath_hal *ah, int chain)
6315 {
6316 int crdc_rssi_sum = 0;
6317 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr, i;
6318 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6319 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
6320
6321 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
6322 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
6323 }
6324
6325 for (i = 1; i <= crdc_window; i++) {
6326 crdc_rssi_sum +=
6327 ah->ah_crdc_rssi_sample[chain]
6328 [(crdc_rssi_ptr - i) % HAL_MAX_CRDC_RSSI_SAMPLE];
6329 }
6330
6331 return crdc_rssi_sum / crdc_window;
6332 }
6333
6334 static void
ar9300_crdc_activate(struct ath_hal * ah,int rssi_diff,int enable)6335 ar9300_crdc_activate(struct ath_hal *ah, int rssi_diff, int enable)
6336 {
6337 int val, orig_val;
6338 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6339 int crdc_numerator = ahpriv->ah_config.ath_hal_crdc_numerator;
6340 int crdc_denominator = ahpriv->ah_config.ath_hal_crdc_denominator;
6341 int c = (rssi_diff * crdc_numerator) / crdc_denominator;
6342
6343 val = orig_val = OS_REG_READ(ah, AR_PHY_MULTICHAIN_CTRL);
6344 val &= 0xffffff00;
6345 if (enable) {
6346 val |= 0x1;
6347 val |= ((c << 1) & 0xff);
6348 }
6349 OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_CTRL, val);
6350 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "diff: %02d comp: %02d reg: %08x %08x\n",
6351 rssi_diff, c, orig_val, val);
6352 }
6353
6354
ar9300_chain_rssi_diff_compensation(struct ath_hal * ah)6355 void ar9300_chain_rssi_diff_compensation(struct ath_hal *ah)
6356 {
6357 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6358 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
6359 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr;
6360 int crdc_rssi_thresh = ahpriv->ah_config.ath_hal_crdc_rssithresh;
6361 int crdc_diff_thresh = ahpriv->ah_config.ath_hal_crdc_diffthresh;
6362 int avg_rssi[2], avg_rssi_diff;
6363
6364 if ((!AR_SREV_WASP(ah)) ||
6365 (!ahpriv->ah_config.ath_hal_crdc_enable)) {
6366 if (ah->ah_crdc_rssi_ptr) {
6367 ar9300_crdc_activate(ah, 0, 0);
6368 ah->ah_crdc_rssi_ptr = 0;
6369 }
6370 return;
6371 }
6372
6373 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
6374 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
6375 }
6376
6377 if (crdc_rssi_ptr < crdc_window) {
6378 return;
6379 }
6380
6381 avg_rssi[0] = ar9300_crdc_avg_rssi(ah, 0);
6382 avg_rssi[1] = ar9300_crdc_avg_rssi(ah, 1);
6383 avg_rssi_diff = avg_rssi[1] - avg_rssi[0];
6384
6385 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "crdc: avg: %02d %02d ",
6386 avg_rssi[0], avg_rssi[1]);
6387
6388 if ((avg_rssi[0] < crdc_rssi_thresh) &&
6389 (avg_rssi[1] < crdc_rssi_thresh)) {
6390 ar9300_crdc_activate(ah, 0, 0);
6391 } else {
6392 if (ABS(avg_rssi_diff) >= crdc_diff_thresh) {
6393 ar9300_crdc_activate(ah, avg_rssi_diff, 1);
6394 } else {
6395 ar9300_crdc_activate(ah, 0, 1);
6396 }
6397 }
6398 }
6399 #endif
6400
6401 #if ATH_ANT_DIV_COMB
6402 HAL_BOOL
ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal * ah,HAL_BOOL enable,const struct ieee80211_channel * chan)6403 ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal *ah, HAL_BOOL enable, const struct ieee80211_channel *chan)
6404 {
6405 u_int32_t value;
6406 u_int32_t regval;
6407 struct ath_hal_9300 *ahp = AH9300(ah);
6408 HAL_CHANNEL_INTERNAL *ichan;
6409 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6410 HAL_CAPABILITIES *pcap = &ahpriv->ah_caps;
6411
6412 HALDEBUG(ah, HAL_DEBUG_RESET | HAL_DEBUG_BT_COEX,
6413 "%s: called; enable=%d\n", __func__, enable);
6414
6415 if (AR_SREV_POSEIDON(ah)) {
6416 // Make sure this scheme is only used for WB225(Astra)
6417 ahp->ah_lna_div_use_bt_ant_enable = enable;
6418
6419 ichan = ar9300_check_chan(ah, chan);
6420 if ( ichan == AH_NULL ) {
6421 HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel %u/0x%x; no mapping\n",
6422 __func__, chan->ic_freq, chan->ic_flags);
6423 return AH_FALSE;
6424 }
6425
6426 if ( enable == TRUE ) {
6427 pcap->halAntDivCombSupport = TRUE;
6428 } else {
6429 pcap->halAntDivCombSupport = pcap->halAntDivCombSupportOrg;
6430 }
6431
6432 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
6433 #define AR_SWITCH_TABLE_COM2_ALL_S (0)
6434 value = ar9300_ant_ctrl_common2_get(ah, IS_CHAN_2GHZ(ichan));
6435 if ( enable == TRUE ) {
6436 value &= ~AR_SWITCH_TABLE_COM2_ALL;
6437 value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable;
6438 }
6439 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, value);
6440 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
6441
6442 value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control);
6443 /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6444 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6445 regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */
6446 regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S;
6447 /* enable_lnadiv */
6448 regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK);
6449 regval |= ((value >> 6) & 0x1) <<
6450 MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT;
6451 if ( enable == TRUE ) {
6452 regval |= ANT_DIV_ENABLE;
6453 }
6454 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6455
6456 /* enable fast_div */
6457 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
6458 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
6459 regval |= ((value >> 7) & 0x1) <<
6460 BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT;
6461 if ( enable == TRUE ) {
6462 regval |= FAST_DIV_ENABLE;
6463 }
6464 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
6465
6466 if ( AR_SREV_POSEIDON_11_OR_LATER(ah) ) {
6467 if (pcap->halAntDivCombSupport) {
6468 /* If support DivComb, set MAIN to LNA1 and ALT to LNA2 at the first beginning */
6469 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6470 /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6471 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK |
6472 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK |
6473 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK |
6474 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK));
6475 regval |= (HAL_ANT_DIV_COMB_LNA1 <<
6476 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT);
6477 regval |= (HAL_ANT_DIV_COMB_LNA2 <<
6478 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT);
6479 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6480 }
6481 }
6482
6483 return AH_TRUE;
6484 } else if (AR_SREV_APHRODITE(ah)) {
6485 ahp->ah_lna_div_use_bt_ant_enable = enable;
6486 if (enable) {
6487 OS_REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, ANT_DIV_ENABLE);
6488 OS_REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, (1 << MULTICHAIN_GAIN_CTRL__ENABLE_ANT_SW_RX_PROT__SHIFT));
6489 OS_REG_SET_BIT(ah, AR_PHY_CCK_DETECT, AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
6490 OS_REG_SET_BIT(ah, AR_PHY_RESTART, RESTART__ENABLE_ANT_FAST_DIV_M2FLAG__MASK);
6491 OS_REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
6492 } else {
6493 OS_REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, ANT_DIV_ENABLE);
6494 OS_REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, (1 << MULTICHAIN_GAIN_CTRL__ENABLE_ANT_SW_RX_PROT__SHIFT));
6495 OS_REG_CLR_BIT(ah, AR_PHY_CCK_DETECT, AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
6496 OS_REG_CLR_BIT(ah, AR_PHY_RESTART, RESTART__ENABLE_ANT_FAST_DIV_M2FLAG__MASK);
6497 OS_REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
6498
6499 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6500 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK |
6501 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK |
6502 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK |
6503 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK));
6504 regval |= (HAL_ANT_DIV_COMB_LNA1 <<
6505 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT);
6506 regval |= (HAL_ANT_DIV_COMB_LNA2 <<
6507 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT);
6508
6509 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6510 }
6511 return AH_TRUE;
6512 }
6513 return AH_TRUE;
6514 }
6515 #endif /* ATH_ANT_DIV_COMB */
6516