2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
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.
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.
22 #include "ah_internal.h"
27 #include "ar9300reg.h"
28 #include "ar9300phy.h"
29 #include "ar9300desc.h"
31 #define FIX_NOISE_FLOOR 1
35 /* Additional Time delay to wait after activiting the Base band */
36 #define BASE_ACTIVATE_DELAY 100 /* usec */
37 #define RTC_PLL_SETTLE_DELAY 100 /* usec */
38 #define COEF_SCALE_S 24
39 #define HT40_CHANNEL_CENTER_SHIFT 10 /* MHz */
43 /* XXX Duplicates! (in ar9300desc.h) */
45 extern HAL_BOOL ar9300_reset_tx_queue(struct ath_hal *ah, u_int q);
46 extern u_int32_t ar9300_num_tx_pending(struct ath_hal *ah, u_int q);
50 #define MAX_MEASUREMENT 8
53 int32_t mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
54 int32_t phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
56 int last_nmeasurement;
60 static HAL_BOOL ar9300_tx_iq_cal_hw_run(struct ath_hal *ah);
61 static void ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
62 int iqcal_idx, int max_iqcal, HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr);
63 static void ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
64 u_int32_t num_chains, struct coeff_t *coeff, HAL_BOOL is_cal_reusable);
65 #if ATH_SUPPORT_CAL_REUSE
66 static void ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan);
70 static inline void ar9300_prog_ini(struct ath_hal *ah, struct ar9300_ini_array *ini_arr, int column);
71 static inline void ar9300_set_rf_mode(struct ath_hal *ah, struct ieee80211_channel *chan);
72 static inline HAL_BOOL ar9300_init_cal(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL skip_if_none, HAL_BOOL apply_last_corr);
73 static inline void ar9300_init_user_settings(struct ath_hal *ah);
77 * For usb offload solution, some USB registers must be tuned
78 * to gain better stability/performance but these registers
79 * might be changed while doing wlan reset so do this here
81 #define WAR_USB_DISABLE_PLL_LOCK_DETECT(__ah) \
83 if (AR_SREV_HORNET(__ah) || AR_SREV_WASP(__ah)) { \
84 volatile u_int32_t *usb_ctrl_r1 = (u_int32_t *) 0xb8116c84; \
85 volatile u_int32_t *usb_ctrl_r2 = (u_int32_t *) 0xb8116c88; \
86 *usb_ctrl_r1 = (*usb_ctrl_r1 & 0xffefffff); \
87 *usb_ctrl_r2 = (*usb_ctrl_r2 & 0xfc1fffff) | (1 << 21) | (3 << 22); \
91 #define WAR_USB_DISABLE_PLL_LOCK_DETECT(__ah)
95 ar9300_attach_hw_platform(struct ath_hal *ah)
97 struct ath_hal_9300 *ahp = AH9300(ah);
99 ahp->ah_hwp = HAL_TRUE_CHIP;
103 /* Adjust various register settings based on half/quarter rate clock setting.
104 * This includes: +USEC, TX/RX latency,
105 * + IFS params: slot, eifs, misc etc.
106 * SIFS stays the same.
109 ar9300_set_ifs_timing(struct ath_hal *ah, struct ieee80211_channel *chan)
111 u_int32_t tx_lat, rx_lat, usec, slot, regval, eifs;
113 regval = OS_REG_READ(ah, AR_USEC);
114 regval &= ~(AR_USEC_RX_LATENCY | AR_USEC_TX_LATENCY | AR_USEC_USEC);
115 if (IEEE80211_IS_CHAN_HALF(chan)) { /* half rates */
116 slot = ar9300_mac_to_clks(ah, AR_SLOT_HALF);
117 eifs = ar9300_mac_to_clks(ah, AR_EIFS_HALF);
118 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { /* fast clock */
119 rx_lat = SM(AR_RX_LATENCY_HALF_FAST_CLOCK, AR_USEC_RX_LATENCY);
120 tx_lat = SM(AR_TX_LATENCY_HALF_FAST_CLOCK, AR_USEC_TX_LATENCY);
121 usec = SM(AR_USEC_HALF_FAST_CLOCK, AR_USEC_USEC);
123 rx_lat = SM(AR_RX_LATENCY_HALF, AR_USEC_RX_LATENCY);
124 tx_lat = SM(AR_TX_LATENCY_HALF, AR_USEC_TX_LATENCY);
125 usec = SM(AR_USEC_HALF, AR_USEC_USEC);
127 } else { /* quarter rate */
128 slot = ar9300_mac_to_clks(ah, AR_SLOT_QUARTER);
129 eifs = ar9300_mac_to_clks(ah, AR_EIFS_QUARTER);
130 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { /* fast clock */
131 rx_lat = SM(AR_RX_LATENCY_QUARTER_FAST_CLOCK, AR_USEC_RX_LATENCY);
132 tx_lat = SM(AR_TX_LATENCY_QUARTER_FAST_CLOCK, AR_USEC_TX_LATENCY);
133 usec = SM(AR_USEC_QUARTER_FAST_CLOCK, AR_USEC_USEC);
135 rx_lat = SM(AR_RX_LATENCY_QUARTER, AR_USEC_RX_LATENCY);
136 tx_lat = SM(AR_TX_LATENCY_QUARTER, AR_USEC_TX_LATENCY);
137 usec = SM(AR_USEC_QUARTER, AR_USEC_USEC);
141 OS_REG_WRITE(ah, AR_USEC, (usec | regval | tx_lat | rx_lat));
142 OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot);
143 OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);
148 * This inline function configures the chip either
149 * to encrypt/decrypt management frames or pass thru
152 ar9300_init_mfp(struct ath_hal * ah)
154 u_int32_t mfpcap, mfp_qos;
156 ath_hal_getcapability(ah, HAL_CAP_MFP, 0, &mfpcap);
158 if (mfpcap == HAL_MFP_QOSDATA) {
159 /* Treat like legacy hardware. Do not touch the MFP registers. */
160 HALDEBUG(ah, HAL_DEBUG_RESET, "%s forced to use QOSDATA\n", __func__);
164 /* MFP support (Sowl 1.0 or greater) */
165 if (mfpcap == HAL_MFP_HW_CRYPTO) {
166 /* configure hardware MFP support */
167 HALDEBUG(ah, HAL_DEBUG_RESET, "%s using HW crypto\n", __func__);
169 AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT, AR_AES_MUTE_MASK1_FC_MGMT_MFP);
171 AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE,
172 AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
174 * Mask used to construct AAD for CCMP-AES
175 * Cisco spec defined bits 0-3 as mask
176 * IEEE802.11w defined as bit 4.
178 if (ath_hal_get_mfp_qos(ah)) {
179 mfp_qos = AR_MFP_QOS_MASK_IEEE;
181 mfp_qos = AR_MFP_QOS_MASK_CISCO;
184 AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_MGMT_QOS, mfp_qos);
185 } else if (mfpcap == HAL_MFP_PASSTHRU) {
186 /* Disable en/decrypt by hardware */
187 HALDEBUG(ah, HAL_DEBUG_RESET, "%s using passthru\n", __func__);
190 AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT,
191 AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
196 ar9300_get_channel_centers(struct ath_hal *ah, const struct ieee80211_channel *chan,
197 CHAN_CENTERS *centers)
200 struct ath_hal_9300 *ahp = AH9300(ah);
201 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
203 if (!IEEE80211_IS_CHAN_HT40(chan)) {
204 centers->ctl_center = centers->ext_center =
205 centers->synth_center = ichan->channel;
209 HALASSERT(IEEE80211_IS_CHAN_HT40(chan));
212 * In 20/40 phy mode, the center frequency is
213 * "between" the primary and extension channels.
215 if (IEEE80211_IS_CHAN_HT40U(chan)) {
216 centers->synth_center = ichan->channel + HT40_CHANNEL_CENTER_SHIFT;
219 centers->synth_center = ichan->channel - HT40_CHANNEL_CENTER_SHIFT;
223 centers->ctl_center =
224 centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
225 centers->ext_center =
226 centers->synth_center +
227 (extoff * ((ahp->ah_ext_prot_spacing == HAL_HT_EXTPROTSPACING_20) ?
228 HT40_CHANNEL_CENTER_SHIFT : 15));
232 * Read the noise-floor values from the HW.
233 * Specifically, read the minimum clear-channel assessment value for
234 * each chain, for both the control and extension channels.
235 * (The received power level during clear-channel periods is the
237 * These noise floor values computed by the HW will be stored in the
239 * The HW sometimes produces bogus NF values. To avoid using these
240 * bogus values, the NF data is (a) range-limited, and (b) filtered.
241 * However, this data-processing is done when reading the NF values
242 * out of the history buffer. The history buffer stores the raw values.
243 * This allows the NF history buffer to be used to check for interference.
244 * A single high NF reading might be a bogus HW value, but if the NF
245 * readings are consistently high, it must be due to interference.
246 * This is the purpose of storing raw NF values in the history buffer,
247 * rather than processed values. By looking at a history of NF values
248 * that have not been range-limited, we can check if they are consistently
249 * high (due to interference).
251 #define AH_NF_SIGN_EXTEND(nf) \
253 0 - (((nf) ^ 0x1ff) + 1) : \
256 ar9300_upload_noise_floor(struct ath_hal *ah, int is_2g,
257 int16_t nfarray[HAL_NUM_NF_READINGS])
261 u_int32_t regs[HAL_NUM_NF_READINGS] = {
262 /* control channel */
263 AR_PHY_CCA_0, /* chain 0 */
264 AR_PHY_CCA_1, /* chain 1 */
265 AR_PHY_CCA_2, /* chain 2 */
266 /* extension channel */
267 AR_PHY_EXT_CCA, /* chain 0 */
268 AR_PHY_EXT_CCA_1, /* chain 1 */
269 AR_PHY_EXT_CCA_2, /* chain 2 */
274 * Within a given channel (ctl vs. ext), the CH0, CH1, and CH2
275 * masks and shifts are the same, though they differ for the
276 * control vs. extension channels.
278 u_int32_t masks[2] = {
279 AR_PHY_MINCCA_PWR, /* control channel */
280 AR_PHY_EXT_MINCCA_PWR, /* extention channel */
282 u_int8_t shifts[2] = {
283 AR_PHY_MINCCA_PWR_S, /* control channel */
284 AR_PHY_EXT_MINCCA_PWR_S, /* extention channel */
288 * Force NF calibration for all chains.
290 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
292 } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah)) {
298 for (chan = 0; chan < 2 /*ctl,ext*/; chan++) {
299 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
302 if (!((chainmask >> chain) & 0x1)) {
305 i = chan * AR9300_MAX_CHAINS + chain;
306 nf = (OS_REG_READ(ah, regs[i]) & masks[chan]) >> shifts[chan];
307 nfarray[i] = AH_NF_SIGN_EXTEND(nf);
312 /* ar9300_get_min_cca_pwr -
313 * Used by the scan function for a quick read of the noise floor.
314 * This is used to detect presence of CW interference such as video bridge.
315 * The noise floor is assumed to have been already started during reset
316 * called during channel change. The function checks if the noise floor
317 * reading is done. In case it has been done, it reads the noise floor value.
318 * If the noise floor calibration has not been finished, it assumes this is
319 * due to presence of CW interference an returns a high value for noise floor,
320 * derived from the CW interference threshold + margin fudge factor.
322 #define BAD_SCAN_NF_MARGIN (30)
323 int16_t ar9300_get_min_cca_pwr(struct ath_hal *ah)
326 // struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
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);
331 nf = 0 - ((nf ^ 0x1ff) + 1);
334 /* NF calibration is not done, assume CW interference */
335 nf = AH9300(ah)->nfp->nominal + AH9300(ah)->nf_cw_int_delta +
343 * Noise Floor values for all chains.
344 * Most recently updated values from the NF history buffer are used.
346 void ar9300_chain_noise_floor(struct ath_hal *ah, int16_t *nf_buf,
347 struct ieee80211_channel *chan, int is_scan)
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);
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);
362 h = &ichan->nf_cal_hist;
363 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
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.
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;
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);
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])
387 h = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
388 nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
391 /* Get most recently updated values from nf cal history buffer */
393 (h->base.curr_index) ? h->base.curr_index - 1 : nf_hist_len - 1;
395 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
396 /* Fill 0 for unsupported chains */
397 if (!(rx_chainmask & (1 << i))) {
401 nf_buf[i] = h->nf_cal_buffer[recent_nf_index][i];
407 * Pick up the medium one in the noise floor buffer and update the
408 * corresponding range for valid noise floor values
411 ar9300_get_nf_hist_mid(struct ath_hal *ah, HAL_NFCAL_HIST_FULL *h, int reading,
415 int16_t sort[HAL_NF_CAL_HIST_LEN_FULL]; /* upper bound for hist_len */
418 for (i = 0; i < hist_len; i++) {
419 sort[i] = h->nf_cal_buffer[i][reading];
420 HALDEBUG(ah, HAL_DEBUG_NFCAL,
421 "nf_cal_buffer[%d][%d] = %d\n", i, reading, (int)sort[i]);
423 for (i = 0; i < hist_len - 1; i++) {
424 for (j = 1; j < hist_len - i; j++) {
425 if (sort[j] > sort[j - 1]) {
427 sort[j] = sort[j - 1];
432 nfval = sort[(hist_len - 1) >> 1];
437 static int16_t ar9300_limit_nf_range(struct ath_hal *ah, int16_t nf)
439 if (nf < AH9300(ah)->nfp->min) {
440 return AH9300(ah)->nfp->nominal;
441 } else if (nf > AH9300(ah)->nfp->max) {
442 return AH9300(ah)->nfp->max;
447 #ifndef ATH_NF_PER_CHAN
449 ar9300_reset_nf_hist_buff(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
451 HAL_CHAN_NFCAL_HIST *h = &ichan->nf_cal_hist;
452 HAL_NFCAL_HIST_FULL *home = &AH_PRIVATE(ah)->nf_cal_hist;
456 * Copy the value for the channel in question into the home-channel
457 * NF history buffer. The channel NF is probably a value filled in by
458 * a prior background channel scan, but if no scan has been done then
459 * it is the nominal noise floor filled in by ath_hal_init_NF_buffer
460 * for this chip and the channel's band.
461 * Replicate this channel NF into all entries of the home-channel NF
463 * If the channel NF was filled in by a channel scan, it has not had
464 * bounds limits applied to it yet - do so now. It is important to
465 * apply bounds limits to the priv_nf value that gets loaded into the
466 * WLAN chip's min_cca_pwr register field. It is also necessary to
467 * apply bounds limits to the nf_cal_buffer[] elements. Since we are
468 * replicating a single NF reading into all nf_cal_buffer elements,
469 * if the single reading were above the CW_INT threshold, the CW_INT
470 * check in ar9300_get_nf would immediately conclude that CW interference
471 * is present, even though we're not supposed to set CW_INT unless
472 * NF values are _consistently_ above the CW_INT threshold.
473 * Applying the bounds limits to the nf_cal_buffer contents fixes this
476 for (i = 0; i < HAL_NUM_NF_READINGS; i ++) {
480 * No need to set curr_index, since it already has a value in
481 * the range [0..HAL_NF_CAL_HIST_LEN_FULL), and all nf_cal_buffer
482 * values will be the same.
484 nf = ar9300_limit_nf_range(ah, h->nf_cal_buffer[0][i]);
485 for (j = 0; j < HAL_NF_CAL_HIST_LEN_FULL; j++) {
486 home->nf_cal_buffer[j][i] = nf;
488 AH_PRIVATE(ah)->nf_cal_hist.base.priv_nf[i] = nf;
494 * Update the noise floor buffer as a ring buffer
497 ar9300_update_nf_hist_buff(struct ath_hal *ah, HAL_NFCAL_HIST_FULL *h,
498 int16_t *nfarray, int hist_len)
501 int16_t nf_no_lim_chain0;
503 nf_no_lim_chain0 = ar9300_get_nf_hist_mid(ah, h, 0, hist_len);
505 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%s[%d] BEFORE\n", __func__, __LINE__);
506 for (nr = 0; nr < HAL_NF_CAL_HIST_LEN_FULL; nr++) {
507 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
508 HALDEBUG(ah, HAL_DEBUG_NFCAL,
509 "nf_cal_buffer[%d][%d] = %d\n",
510 nr, i, (int)h->nf_cal_buffer[nr][i]);
513 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
514 h->nf_cal_buffer[h->base.curr_index][i] = nfarray[i];
515 h->base.priv_nf[i] = ar9300_limit_nf_range(
516 ah, ar9300_get_nf_hist_mid(ah, h, i, hist_len));
518 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%s[%d] AFTER\n", __func__, __LINE__);
519 for (nr = 0; nr < HAL_NF_CAL_HIST_LEN_FULL; nr++) {
520 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
521 HALDEBUG(ah, HAL_DEBUG_NFCAL,
522 "nf_cal_buffer[%d][%d] = %d\n",
523 nr, i, (int)h->nf_cal_buffer[nr][i]);
527 if (++h->base.curr_index >= hist_len) {
528 h->base.curr_index = 0;
531 return nf_no_lim_chain0;
536 get_noise_floor_thresh(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *chan,
539 struct ath_hal_9300 *ahp = AH9300(ah);
541 switch (chan->channel_flags & CHANNEL_ALL_NOTURBO) {
544 case CHANNEL_A_HT40PLUS:
545 case CHANNEL_A_HT40MINUS:
546 *nft = (int8_t)ar9300_eeprom_get(ahp, EEP_NFTHRESH_5);
551 case CHANNEL_G_HT40PLUS:
552 case CHANNEL_G_HT40MINUS:
553 *nft = (int8_t)ar9300_eeprom_get(ahp, EEP_NFTHRESH_2);
556 HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel flags 0x%x\n",
557 __func__, chan->channel_flags);
565 * Read the NF and check it against the noise floor threshhold
567 #define IS(_c, _f) (((_c)->channel_flags & _f) || 0)
569 ar9300_store_new_nf(struct ath_hal *ah, struct ieee80211_channel *chan,
572 // struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
575 int16_t nfarray[HAL_NUM_NF_READINGS] = {0};
576 HAL_NFCAL_HIST_FULL *h;
578 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
579 struct ath_hal_9300 *ahp = AH9300(ah);
581 if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
582 u_int32_t tsf32, nf_cal_dur_tsf;
584 * The reason the NF calibration did not complete may just be that
585 * not enough time has passed since the NF calibration was started,
586 * because under certain conditions (when first moving to a new
587 * channel) the NF calibration may be checked very repeatedly.
588 * Or, there may be CW interference keeping the NF calibration
589 * from completing. Check the delta time between when the NF
590 * calibration was started and now to see whether the NF calibration
591 * should have already completed (but hasn't, probably due to CW
592 * interference), or hasn't had enough time to finish yet.
595 * AH_NF_CAL_DUR_MAX_TSF - A conservative maximum time that the
596 * HW should need to finish a NF calibration. If the HW
597 * does not complete a NF calibration within this time period,
598 * there must be a problem - probably CW interference.
599 * AH_NF_CAL_PERIOD_MAX_TSF - A conservative maximum time between
600 * check of the HW's NF calibration being finished.
601 * If the difference between the current TSF and the TSF
602 * recorded when the NF calibration started is larger than this
603 * value, the TSF must have been reset.
604 * In general, we expect the TSF to only be reset during
605 * regular operation for STAs, not for APs. However, an
606 * AP's TSF could be reset when joining an IBSS.
607 * There's an outside chance that this could result in the
608 * CW_INT flag being erroneously set, if the TSF adjustment
609 * is smaller than AH_NF_CAL_PERIOD_MAX_TSF but larger than
610 * AH_NF_CAL_DUR_TSF. However, even if this does happen,
611 * it shouldn't matter, as the IBSS case shouldn't be
612 * concerned about CW_INT.
614 /* AH_NF_CAL_DUR_TSF - 90 sec in usec units */
615 #define AH_NF_CAL_DUR_TSF (90 * 1000 * 1000)
616 /* AH_NF_CAL_PERIOD_MAX_TSF - 180 sec in usec units */
617 #define AH_NF_CAL_PERIOD_MAX_TSF (180 * 1000 * 1000)
618 /* wraparound handled by using unsigned values */
619 tsf32 = ar9300_get_tsf32(ah);
620 nf_cal_dur_tsf = tsf32 - AH9300(ah)->nf_tsf32;
621 if (nf_cal_dur_tsf > AH_NF_CAL_PERIOD_MAX_TSF) {
623 * The TSF must have gotten reset during the NF cal -
624 * just reset the NF TSF timestamp, so the next time
625 * this function is called, the timestamp comparison
628 AH9300(ah)->nf_tsf32 = tsf32;
629 } else if (nf_cal_dur_tsf > AH_NF_CAL_DUR_TSF) {
630 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
631 "%s: NF did not complete in calibration window\n", __func__);
632 /* the NF incompletion is probably due to CW interference */
633 chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
635 return 0; /* HW's NF measurement not finished */
637 HALDEBUG(ah, HAL_DEBUG_NFCAL,
638 "%s[%d] chan %d\n", __func__, __LINE__, ichan->channel);
639 is_2g = !! IS_CHAN_2GHZ(ichan);
640 ar9300_upload_noise_floor(ah, is_2g, nfarray);
642 /* Update the NF buffer for each chain masked by chainmask */
643 #ifdef ATH_NF_PER_CHAN
644 h = &ichan->nf_cal_hist;
645 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
649 * This channel's NF cal info is just a HAL_NFCAL_HIST_SMALL struct
650 * rather than a HAL_NFCAL_HIST_FULL struct.
651 * As long as we only use the first history element of nf_cal_buffer
652 * (nf_cal_buffer[0][0:HAL_NUM_NF_READINGS-1]), we can use
653 * HAL_NFCAL_HIST_SMALL and HAL_NFCAL_HIST_FULL interchangeably.
655 h = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
656 nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
658 h = &AH_PRIVATE(ah)->nf_cal_hist;
659 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
664 * nf_no_lim = median value from NF history buffer without bounds limits,
665 * priv_nf = median value from NF history buffer with bounds limits.
667 nf_no_lim = ar9300_update_nf_hist_buff(ah, h, nfarray, nf_hist_len);
668 ichan->rawNoiseFloor = h->base.priv_nf[0];
670 /* check if there is interference */
671 // ichan->channel_flags &= (~CHANNEL_CW_INT);
673 * Use AR9300_EMULATION to check for emulation purpose as PCIE Device ID
674 * 0xABCD is recognized as valid Osprey as WAR in some EVs.
676 if (nf_no_lim > ahp->nfp->nominal + ahp->nf_cw_int_delta) {
678 * Since this CW interference check is being applied to the
679 * median element of the NF history buffer, this indicates that
680 * the CW interference is persistent. A single high NF reading
681 * will not show up in the median, and thus will not cause the
682 * CW_INT flag to be set.
684 HALDEBUG(ah, HAL_DEBUG_NFCAL,
685 "%s: NF Cal: CW interferer detected through NF: %d\n",
686 __func__, nf_no_lim);
687 chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
689 return 1; /* HW's NF measurement finished */
694 ar9300_get_delta_slope_values(struct ath_hal *ah, u_int32_t coef_scaled,
695 u_int32_t *coef_mantissa, u_int32_t *coef_exponent)
697 u_int32_t coef_exp, coef_man;
700 * ALGO -> coef_exp = 14-floor(log2(coef));
701 * floor(log2(x)) is the highest set bit position
703 for (coef_exp = 31; coef_exp > 0; coef_exp--) {
704 if ((coef_scaled >> coef_exp) & 0x1) {
708 /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */
710 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
714 * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5);
715 * The coefficient is already shifted up for scaling
717 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
719 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
720 *coef_exponent = coef_exp - 16;
723 #define MAX_ANALOG_START 319 /* XXX */
726 * Delta slope coefficient computation.
727 * Required for OFDM operation.
730 ar9300_set_delta_slope(struct ath_hal *ah, struct ieee80211_channel *chan)
732 u_int32_t coef_scaled, ds_coef_exp, ds_coef_man;
733 u_int32_t fclk = COEFF; /* clock * 2.5 */
735 u_int32_t clock_mhz_scaled = 0x1000000 * fclk;
736 CHAN_CENTERS centers;
739 * half and quarter rate can divide the scaled clock by 2 or 4
740 * scale for selected channel bandwidth
742 if (IEEE80211_IS_CHAN_HALF(chan)) {
743 clock_mhz_scaled = clock_mhz_scaled >> 1;
744 } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
745 clock_mhz_scaled = clock_mhz_scaled >> 2;
749 * ALGO -> coef = 1e8/fcarrier*fclock/40;
750 * scaled coef to provide precision for this floating calculation
752 ar9300_get_channel_centers(ah, chan, ¢ers);
753 coef_scaled = clock_mhz_scaled / centers.synth_center;
755 ar9300_get_delta_slope_values(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
757 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
758 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
762 * scaled coeff is 9/10 that of normal coeff
764 coef_scaled = (9 * coef_scaled) / 10;
766 ar9300_get_delta_slope_values(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
769 OS_REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, AR_PHY_SGI_DSC_MAN, ds_coef_man);
770 OS_REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, AR_PHY_SGI_DSC_EXP, ds_coef_exp);
773 #define IS(_c, _f) (IEEE80211_IS_ ## _f(_c))
776 * XXX FreeBSD: This should be turned into something generic in ath_hal!
778 HAL_CHANNEL_INTERNAL *
779 ar9300_check_chan(struct ath_hal *ah, const struct ieee80211_channel *chan)
786 if ((IS(chan, CHAN_2GHZ) ^ IS(chan, CHAN_5GHZ)) == 0) {
787 HALDEBUG(ah, HAL_DEBUG_CHANNEL,
788 "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
789 __func__, chan->ic_freq , chan->ic_flags);
794 * FreeBSD sets multiple flags, so this will fail.
797 if ((IS(chan, CHAN_OFDM) ^ IS(chan, CHAN_CCK) ^ IS(chan, CHAN_DYN) ^
798 IS(chan, CHAN_HT20) ^ IS(chan, CHAN_HT40U) ^
799 IS(chan, CHAN_HT40D)) == 0)
801 HALDEBUG(ah, HAL_DEBUG_CHANNEL,
802 "%s: invalid channel %u/0x%x; not marked as "
803 "OFDM or CCK or DYN or HT20 or HT40PLUS or HT40MINUS\n",
804 __func__, chan->ic_freq , chan->ic_flags);
809 return (ath_hal_checkchannel(ah, chan));
814 ar9300_set_11n_regs(struct ath_hal *ah, struct ieee80211_channel *chan,
815 HAL_HT_MACMODE macmode)
818 // struct ath_hal_9300 *ahp = AH9300(ah);
819 u_int32_t enable_dac_fifo;
823 OS_REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO;
825 /* Enable 11n HT, 20 MHz */
827 AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_SHORT_GI_40
829 /* Configure baseband for dynamic 20/40 operation */
830 if (IEEE80211_IS_CHAN_HT40(chan)) {
831 phymode |= AR_PHY_GC_DYN2040_EN;
832 /* Configure control (primary) channel at +-10MHz */
833 if (IEEE80211_IS_CHAN_HT40U(chan)) {
834 phymode |= AR_PHY_GC_DYN2040_PRI_CH;
838 /* Configure 20/25 spacing */
839 if (ahp->ah_ext_prot_spacing == HAL_HT_EXTPROTSPACING_25) {
840 phymode |= AR_PHY_GC_DYN2040_EXT_CH;
845 /* make sure we preserve INI settings */
846 phymode |= OS_REG_READ(ah, AR_PHY_GEN_CTRL);
848 /* EV 62881/64991 - turn off Green Field detection for Maverick STA beta */
849 phymode &= ~AR_PHY_GC_GF_DETECT_EN;
851 OS_REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode);
853 /* Set IFS timing for half/quarter rates */
854 if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan)) {
855 u_int32_t modeselect = OS_REG_READ(ah, AR_PHY_MODE);
857 if (IEEE80211_IS_CHAN_HALF(chan)) {
858 modeselect |= AR_PHY_MS_HALF_RATE;
859 } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
860 modeselect |= AR_PHY_MS_QUARTER_RATE;
862 OS_REG_WRITE(ah, AR_PHY_MODE, modeselect);
864 ar9300_set_ifs_timing(ah, chan);
866 ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW, 0x3);
869 /* Configure MAC for 20/40 operation */
870 ar9300_set_11n_mac2040(ah, macmode);
872 /* global transmit timeout (25 TUs default)*/
873 /* XXX - put this elsewhere??? */
874 OS_REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
876 /* carrier sense timeout */
877 OS_REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
881 * Spur mitigation for MRC CCK
884 ar9300_spur_mitigate_mrc_cck(struct ath_hal *ah, struct ieee80211_channel *chan)
887 /* spur_freq_for_osprey - hardcoded by Systems team for now. */
888 u_int32_t spur_freq_for_osprey[4] = { 2420, 2440, 2464, 2480 };
889 u_int32_t spur_freq_for_jupiter[2] = { 2440, 2464};
890 int cur_bb_spur, negative = 0, cck_spur_freq;
891 u_int8_t* spur_fbin_ptr = NULL;
894 int max_spurcounts = OSPREY_EEPROM_MODAL_SPURS;
895 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
898 * Need to verify range +/- 10 MHz in control channel, otherwise spur
899 * is out-of-band and can be ignored.
901 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
902 AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
903 spur_fbin_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 1);
904 if (spur_fbin_ptr[0] == 0) {
905 return; /* No spur in the mode */
907 if (IEEE80211_IS_CHAN_HT40(chan)) {
909 if (OS_REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH)
912 synth_freq = ichan->channel + 10;
914 synth_freq = ichan->channel - 10;
918 synth_freq = ichan->channel;
920 } else if(AR_SREV_JUPITER(ah)) {
922 max_spurcounts = 2; /* Hardcoded by Jupiter Systems team for now. */
923 synth_freq = ichan->channel;
926 max_spurcounts = 4; /* Hardcoded by Osprey Systems team for now. */
927 synth_freq = ichan->channel;
930 for (i = 0; i < max_spurcounts; i++) {
933 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
934 AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
936 FBIN2FREQ(spur_fbin_ptr[i], HAL_FREQ_BAND_2GHZ) - synth_freq;
937 } else if(AR_SREV_JUPITER(ah)) {
938 cur_bb_spur = spur_freq_for_jupiter[i] - synth_freq;
940 cur_bb_spur = spur_freq_for_osprey[i] - synth_freq;
943 if (cur_bb_spur < 0) {
945 cur_bb_spur = -cur_bb_spur;
947 if (cur_bb_spur < range) {
948 cck_spur_freq = (int)((cur_bb_spur << 19) / 11);
950 cck_spur_freq = -cck_spur_freq;
952 cck_spur_freq = cck_spur_freq & 0xfffff;
953 /*OS_REG_WRITE_field(ah, BB_agc_control.ycok_max, 0x7);*/
955 AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7);
956 /*OS_REG_WRITE_field(ah, BB_cck_spur_mit.spur_rssi_thr, 0x7f);*/
958 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f);
959 /*OS_REG_WRITE(ah, BB_cck_spur_mit.spur_filter_type, 0x2);*/
961 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE, 0x2);
962 /*OS_REG_WRITE(ah, BB_cck_spur_mit.use_cck_spur_mit, 0x1);*/
964 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x1);
965 /*OS_REG_WRITE(ah, BB_cck_spur_mit.cck_spur_freq, cck_spur_freq);*/
967 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ,
973 /*OS_REG_WRITE(ah, BB_agc_control.ycok_max, 0x5);*/
974 OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5);
975 /*OS_REG_WRITE(ah, BB_cck_spur_mit.use_cck_spur_mit, 0x0);*/
977 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x0);
978 /*OS_REG_WRITE(ah, BB_cck_spur_mit.cck_spur_freq, 0x0);*/
980 AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0);
983 /* Spur mitigation for OFDM */
985 ar9300_spur_mitigate_ofdm(struct ath_hal *ah, struct ieee80211_channel *chan)
990 int spur_freq_sd = 0;
991 int spur_subchannel_sd = 0;
992 int spur_delta_phase = 0;
996 u_int8_t* spur_chans_ptr;
997 struct ath_hal_9300 *ahp;
999 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
1001 if (IS_CHAN_5GHZ(ichan)) {
1002 spur_chans_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 0);
1005 spur_chans_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 1);
1009 if (IEEE80211_IS_CHAN_HT40(chan)) {
1011 if (OS_REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH)
1014 synth_freq = ichan->channel - 10;
1016 synth_freq = ichan->channel + 10;
1020 synth_freq = ichan->channel;
1023 /* Clean all spur register fields */
1024 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0);
1025 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_FREQ_SD, 0);
1026 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0);
1027 OS_REG_RMW_FIELD(ah,
1028 AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, 0);
1029 OS_REG_RMW_FIELD(ah,
1030 AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0);
1031 OS_REG_RMW_FIELD(ah,
1032 AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0);
1033 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0);
1034 OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 0);
1035 OS_REG_RMW_FIELD(ah,
1036 AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 0);
1037 OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0);
1038 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0);
1039 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0);
1040 OS_REG_RMW_FIELD(ah,
1041 AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, 0);
1042 OS_REG_RMW_FIELD(ah,
1043 AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, 0);
1044 OS_REG_RMW_FIELD(ah,
1045 AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, 0);
1046 OS_REG_RMW_FIELD(ah,
1047 AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0);
1048 OS_REG_RMW_FIELD(ah,
1049 AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0);
1050 OS_REG_RMW_FIELD(ah,
1051 AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0);
1052 OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0);
1055 while (spur_chans_ptr[i] && i < 5) {
1056 freq_offset = FBIN2FREQ(spur_chans_ptr[i], mode) - synth_freq;
1057 if (abs(freq_offset) < range) {
1060 "Spur Mitigation for OFDM: Synth Frequency = %d, "
1061 "Spur Frequency = %d\n",
1062 synth_freq, FBIN2FREQ(spur_chans_ptr[i], mode));
1064 if (IEEE80211_IS_CHAN_HT40(chan)) {
1065 if (freq_offset < 0) {
1066 if (OS_REG_READ_FIELD(
1067 ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
1069 spur_subchannel_sd = 1;
1071 spur_subchannel_sd = 0;
1073 spur_freq_sd = ((freq_offset + 10) << 9) / 11;
1075 if (OS_REG_READ_FIELD(ah,
1076 AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
1078 spur_subchannel_sd = 0;
1080 spur_subchannel_sd = 1;
1082 spur_freq_sd = ((freq_offset - 10) << 9) / 11;
1084 spur_delta_phase = (freq_offset << 17) / 5;
1086 spur_subchannel_sd = 0;
1087 spur_freq_sd = (freq_offset << 9) / 11;
1088 spur_delta_phase = (freq_offset << 18) / 5;
1090 spur_freq_sd = spur_freq_sd & 0x3ff;
1091 spur_delta_phase = spur_delta_phase & 0xfffff;
1094 "spur_subchannel_sd = %d, spur_freq_sd = 0x%x, "
1095 "spur_delta_phase = 0x%x\n", spur_subchannel_sd,
1096 spur_freq_sd, spur_delta_phase);
1099 /* OFDM Spur mitigation */
1100 OS_REG_RMW_FIELD(ah,
1101 AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0x1);
1102 OS_REG_RMW_FIELD(ah,
1103 AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd);
1104 OS_REG_RMW_FIELD(ah,
1105 AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_DELTA_PHASE,
1107 OS_REG_RMW_FIELD(ah,
1108 AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD,
1109 spur_subchannel_sd);
1110 OS_REG_RMW_FIELD(ah,
1111 AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1);
1112 OS_REG_RMW_FIELD(ah,
1113 AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR,
1115 OS_REG_RMW_FIELD(ah,
1116 AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1);
1117 OS_REG_RMW_FIELD(ah,
1118 AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34);
1119 OS_REG_RMW_FIELD(ah,
1120 AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
1123 * Do not subtract spur power from noise floor for wasp.
1124 * This causes the maximum client test (on Veriwave) to fail
1125 * when run on spur channel (2464 MHz).
1126 * Refer to ev#82746 and ev#82744.
1128 if (!AR_SREV_WASP(ah) && (OS_REG_READ_FIELD(ah, AR_PHY_MODE,
1129 AR_PHY_MODE_DYNAMIC) == 0x1)) {
1130 OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
1131 AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
1134 mask_index = (freq_offset << 4) / 5;
1135 if (mask_index < 0) {
1136 mask_index = mask_index - 1;
1138 mask_index = mask_index & 0x7f;
1139 /*printf("Bin 0x%x\n", mask_index);*/
1141 OS_REG_RMW_FIELD(ah,
1142 AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0x1);
1143 OS_REG_RMW_FIELD(ah,
1144 AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0x1);
1145 OS_REG_RMW_FIELD(ah,
1146 AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0x1);
1147 OS_REG_RMW_FIELD(ah,
1148 AR_PHY_PILOT_SPUR_MASK,
1149 AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, mask_index);
1150 OS_REG_RMW_FIELD(ah,
1151 AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A,
1153 OS_REG_RMW_FIELD(ah,
1154 AR_PHY_CHAN_SPUR_MASK,
1155 AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, mask_index);
1156 OS_REG_RMW_FIELD(ah,
1157 AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A,
1159 OS_REG_RMW_FIELD(ah,
1160 AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A,
1162 OS_REG_RMW_FIELD(ah,
1163 AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0);
1164 OS_REG_RMW_FIELD(ah,
1165 AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff);
1167 printf("BB_timing_control_4 = 0x%x\n",
1168 OS_REG_READ(ah, AR_PHY_TIMING4));
1169 printf("BB_timing_control_11 = 0x%x\n",
1170 OS_REG_READ(ah, AR_PHY_TIMING11));
1171 printf("BB_ext_chan_scorr_thr = 0x%x\n",
1172 OS_REG_READ(ah, AR_PHY_SFCORR_EXT));
1173 printf("BB_spur_mask_controls = 0x%x\n",
1174 OS_REG_READ(ah, AR_PHY_SPUR_REG));
1175 printf("BB_pilot_spur_mask = 0x%x\n",
1176 OS_REG_READ(ah, AR_PHY_PILOT_SPUR_MASK));
1177 printf("BB_chan_spur_mask = 0x%x\n",
1178 OS_REG_READ(ah, AR_PHY_CHAN_SPUR_MASK));
1179 printf("BB_vit_spur_mask_A = 0x%x\n",
1180 OS_REG_READ(ah, AR_PHY_SPUR_MASK_A));
1190 * Convert to baseband spur frequency given input channel frequency
1191 * and compute register settings below.
1194 ar9300_spur_mitigate(struct ath_hal *ah, struct ieee80211_channel *chan)
1196 ar9300_spur_mitigate_ofdm(ah, chan);
1197 ar9300_spur_mitigate_mrc_cck(ah, chan);
1200 /**************************************************************
1201 * ar9300_channel_change
1202 * Assumes caller wants to change channel, and not reset.
1204 static inline HAL_BOOL
1205 ar9300_channel_change(struct ath_hal *ah, struct ieee80211_channel *chan,
1206 HAL_CHANNEL_INTERNAL *ichan, HAL_HT_MACMODE macmode)
1209 u_int32_t synth_delay, qnum;
1210 struct ath_hal_9300 *ahp = AH9300(ah);
1212 /* TX must be stopped by now */
1213 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
1214 if (ar9300_num_tx_pending(ah, qnum)) {
1215 HALDEBUG(ah, HAL_DEBUG_QUEUE,
1216 "%s: Transmit frames pending on queue %d\n", __func__, qnum);
1224 * Kill last Baseband Rx Frame - Request analog bus grant
1226 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
1227 if (!ath_hal_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
1228 AR_PHY_RFBUS_GRANT_EN))
1230 HALDEBUG(ah, HAL_DEBUG_PHYIO,
1231 "%s: Could not kill baseband RX\n", __func__);
1236 /* Setup 11n MAC/Phy mode registers */
1237 ar9300_set_11n_regs(ah, chan, macmode);
1242 if (!ahp->ah_rf_hal.set_channel(ah, chan)) {
1243 HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: failed to set channel\n", __func__);
1248 * Some registers get reinitialized during ATH_INI_POST INI programming.
1250 ar9300_init_user_settings(ah);
1253 * Setup the transmit power values.
1255 * After the public to private hal channel mapping, ichan contains the
1256 * valid regulatory power value.
1257 * ath_hal_getctl and ath_hal_getantennaallowed look up ichan from chan.
1259 if (ar9300_eeprom_set_transmit_power(
1260 ah, &ahp->ah_eeprom, chan, ath_hal_getctl(ah, chan),
1261 ath_hal_getantennaallowed(ah, chan),
1262 ath_hal_get_twice_max_regpower(AH_PRIVATE(ah), ichan, chan),
1263 AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit)) != HAL_OK)
1265 HALDEBUG(ah, HAL_DEBUG_EEPROM,
1266 "%s: error init'ing transmit power\n", __func__);
1271 * Release the RFBus Grant.
1273 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
1276 * Write spur immunity and delta slope for OFDM enabled modes (A, G, Turbo)
1278 if (IEEE80211_IS_CHAN_OFDM(chan) || IEEE80211_IS_CHAN_HT(chan)) {
1279 ar9300_set_delta_slope(ah, chan);
1281 /* Set to Ini default */
1282 OS_REG_WRITE(ah, AR_PHY_TIMING3, 0x9c0a9f6b);
1283 OS_REG_WRITE(ah, AR_PHY_SGI_DELTA, 0x00046384);
1286 ar9300_spur_mitigate(ah, chan);
1290 * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).
1291 * Read the phy active delay register. Value is in 100ns increments.
1293 synth_delay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
1294 if (IEEE80211_IS_CHAN_CCK(chan)) {
1295 synth_delay = (4 * synth_delay) / 22;
1300 OS_DELAY(synth_delay + BASE_ACTIVATE_DELAY);
1310 ar9300_set_operating_mode(struct ath_hal *ah, int opmode)
1314 val = OS_REG_READ(ah, AR_STA_ID1);
1315 val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
1318 OS_REG_WRITE(ah, AR_STA_ID1,
1319 val | AR_STA_ID1_STA_AP | AR_STA_ID1_KSRCH_MODE);
1320 OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1323 OS_REG_WRITE(ah, AR_STA_ID1,
1324 val | AR_STA_ID1_ADHOC | AR_STA_ID1_KSRCH_MODE);
1325 OS_REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1329 OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
1334 /* XXX need the logic for Osprey */
1336 ar9300_init_pll(struct ath_hal *ah, struct ieee80211_channel *chan)
1339 u_int8_t clk_25mhz = AH9300(ah)->clk_25mhz;
1340 HAL_CHANNEL_INTERNAL *ichan = NULL;
1343 ichan = ath_hal_checkchannel(ah, chan);
1345 if (AR_SREV_HORNET(ah)) {
1347 /* Hornet uses PLL_CONTROL_2. Xtal is 25MHz for Hornet.
1348 * REFDIV set to 0x1.
1350 * $PLL2_div = (704/$xtal_freq); # 176 * 4 = 704.
1351 * MAC and BB run at 176 MHz.
1352 * $PLL2_divint = int($PLL2_div);
1353 * $PLL2_divfrac = $PLL2_div - $PLL2_divint;
1354 * $PLL2_divfrac = int($PLL2_divfrac * 0x4000); # 2^14
1355 * $PLL2_Val = ($PLL2_divint & 0x3f) << 19 | (0x1) << 14 |
1356 * $PLL2_divfrac & 0x3fff;
1357 * Therefore, $PLL2_Val = 0xe04a3d
1359 #define DPLL2_KD_VAL 0x1D
1360 #define DPLL2_KI_VAL 0x06
1361 #define DPLL3_PHASE_SHIFT_VAL 0x1
1363 /* Rewrite DDR PLL2 and PLL3 */
1364 /* program DDR PLL ki and kd value, ki=0x6, kd=0x1d */
1365 OS_REG_WRITE(ah, AR_HORNET_CH0_DDR_DPLL2, 0x18e82f01);
1367 /* program DDR PLL phase_shift to 0x1 */
1368 OS_REG_RMW_FIELD(ah, AR_HORNET_CH0_DDR_DPLL3,
1369 AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1371 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
1374 /* program refdiv, nint, frac to RTC register */
1375 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0xe04a3d);
1377 /* program BB PLL ki and kd value, ki=0x6, kd=0x1d */
1378 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1379 AR_PHY_BB_DPLL2_KD, DPLL2_KD_VAL);
1380 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1381 AR_PHY_BB_DPLL2_KI, DPLL2_KI_VAL);
1383 /* program BB PLL phase_shift to 0x1 */
1384 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1385 AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1386 } else { /* 40MHz */
1389 #define DPLL2_KD_VAL 0x3D
1390 #define DPLL2_KI_VAL 0x06
1391 /* Rewrite DDR PLL2 and PLL3 */
1392 /* program DDR PLL ki and kd value, ki=0x6, kd=0x3d */
1393 OS_REG_WRITE(ah, AR_HORNET_CH0_DDR_DPLL2, 0x19e82f01);
1395 /* program DDR PLL phase_shift to 0x1 */
1396 OS_REG_RMW_FIELD(ah, AR_HORNET_CH0_DDR_DPLL3,
1397 AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1399 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
1402 /* program refdiv, nint, frac to RTC register */
1403 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666);
1405 /* program BB PLL ki and kd value, ki=0x6, kd=0x3d */
1406 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1407 AR_PHY_BB_DPLL2_KD, DPLL2_KD_VAL);
1408 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1409 AR_PHY_BB_DPLL2_KI, DPLL2_KI_VAL);
1411 /* program BB PLL phase_shift to 0x1 */
1412 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1413 AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1415 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1417 } else if (AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
1418 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2, AR_PHY_BB_DPLL2_PLL_PWD, 0x1);
1420 /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
1421 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1422 AR_PHY_BB_DPLL2_KD, 0x40);
1423 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1424 AR_PHY_BB_DPLL2_KI, 0x4);
1426 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1427 AR_PHY_BB_DPLL1_REFDIV, 0x5);
1428 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1429 AR_PHY_BB_DPLL1_NINI, 0x58);
1430 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1431 AR_PHY_BB_DPLL1_NFRAC, 0x0);
1433 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1434 AR_PHY_BB_DPLL2_OUTDIV, 0x1);
1435 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1436 AR_PHY_BB_DPLL2_LOCAL_PLL, 0x1);
1437 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1438 AR_PHY_BB_DPLL2_EN_NEGTRIG, 0x1);
1440 /* program BB PLL phase_shift to 0x6 */
1441 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1442 AR_PHY_BB_DPLL3_PHASE_SHIFT, 0x6);
1444 OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1445 AR_PHY_BB_DPLL2_PLL_PWD, 0x0);
1448 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1450 } else if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
1452 u_int32_t regdata, pll2_divint, pll2_divfrac;
1455 u_int32_t pll2_clkmode;
1464 pll2_divfrac = 0xa3d7;
1467 pll2_divfrac = 0x1eb85;
1473 pll2_divfrac = 0x26666;
1475 if (AR_SREV_WASP(ah)) {
1481 pll2_divfrac = 0x26666;
1487 pll2_clkmode = 0x3d;
1489 /* PLL programming through SRIF Local Mode */
1490 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); /* Bypass mode */
1493 regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1494 regdata = regdata | (0x1 << 16);
1495 OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata); /* PWD_PLL set to 1 */
1497 /* override int, frac, refdiv */
1499 OS_REG_WRITE(ah, AR_PHY_PLL_CONTROL,
1500 ((1 << 27) | (pll2_divint << 18) | pll2_divfrac));
1502 OS_REG_WRITE(ah, AR_PHY_PLL_CONTROL,
1503 ((refdiv << 27) | (pll2_divint << 18) | pll2_divfrac));
1506 regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1508 regdata = (regdata & 0x80071fff) |
1509 (0x1 << 30) | (0x1 << 13) | (0x6 << 26) | (pll2_clkmode << 19);
1511 if (AR_SREV_WASP(ah)) {
1512 regdata = (regdata & 0x80071fff) |
1513 (0x1 << 30) | (0x1 << 13) | (0x4 << 26) | (0x18 << 19);
1515 regdata = (regdata & 0x80071fff) |
1516 (0x3 << 30) | (0x1 << 13) | (0x4 << 26) | (0x60 << 19);
1519 /* Ki, Kd, Local PLL, Outdiv */
1520 OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata);
1521 regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1522 regdata = (regdata & 0xfffeffff);
1523 OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata); /* PWD_PLL set to 0 */
1525 if (AR_SREV_WASP(ah)) {
1526 /* clear do measure */
1527 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1528 regdata &= ~(1 << 30);
1529 OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1532 /* set do measure */
1533 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1534 regdata |= (1 << 30);
1535 OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1537 /* wait for measure done */
1539 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL4);
1540 } while ((regdata & (1 << 3)) == 0);
1542 /* clear do measure */
1543 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1544 regdata &= ~(1 << 30);
1545 OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1547 /* get measure sqsum dvc */
1548 regdata = (OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3) & 0x007FFFF8) >> 3;
1552 } while (regdata >= 0x40000);
1554 /* Remove from Bypass mode */
1555 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1558 pll = SM(0x5, AR_RTC_PLL_REFDIV);
1560 /* Supposedly not needed on Osprey */
1562 if (chan && IS_CHAN_HALF_RATE(chan)) {
1563 pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1564 } else if (chan && IS_CHAN_QUARTER_RATE(chan)) {
1565 pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1568 if (ichan && IS_CHAN_5GHZ(ichan)) {
1569 pll |= SM(0x28, AR_RTC_PLL_DIV);
1571 * When doing fast clock, set PLL to 0x142c
1573 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
1577 pll |= SM(0x2c, AR_RTC_PLL_DIV);
1580 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
1584 * For multi-band owl, switch between bands by reiniting the PLL.
1586 OS_DELAY(RTC_PLL_SETTLE_DELAY);
1588 OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK,
1589 AR_RTC_FORCE_DERIVED_CLK | AR_RTC_PCIE_RST_PWDN_EN);
1591 if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
1594 AR_RTC_DERIVED_RTC_CLK, (0x17c << 1)); /* 32KHz sleep clk */
1595 OS_REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
1596 OS_REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
1599 AR_RTC_DERIVED_RTC_CLK, (0x261 << 1)); /* 32KHz sleep clk */
1600 OS_REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
1601 OS_REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
1607 static inline HAL_BOOL
1608 ar9300_set_reset(struct ath_hal *ah, int type)
1610 u_int32_t rst_flags;
1613 HALASSERT(type == HAL_RESET_WARM || type == HAL_RESET_COLD);
1616 * RTC Force wake should be done before resetting the MAC.
1617 * MDK/ART does it that way.
1619 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1620 OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1622 AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1626 tmp_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE));
1627 if (AR_SREV_WASP(ah)) {
1628 if (tmp_reg & (AR9340_INTR_SYNC_LOCAL_TIMEOUT)) {
1629 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0);
1630 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF);
1633 if (tmp_reg & (AR9300_INTR_SYNC_LOCAL_TIMEOUT | AR9300_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1634 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0);
1635 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF);
1638 /* NO AR_RC_AHB in Osprey */
1639 /*OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_AHB);*/
1643 rst_flags = AR_RTC_RC_MAC_WARM;
1644 if (type == HAL_RESET_COLD) {
1645 rst_flags |= AR_RTC_RC_MAC_COLD;
1648 #ifdef AH_SUPPORT_HORNET
1649 /* Hornet WAR: trigger SoC to reset WMAC if ...
1650 * (1) doing cold reset. Ref: EV 69254
1651 * (2) beacon pending. Ref: EV 70983
1653 if (AR_SREV_HORNET(ah) &&
1654 (ar9300_num_tx_pending(
1655 ah, AH_PRIVATE(ah)->ah_caps.halTotalQueues - 1) != 0 ||
1656 type == HAL_RESET_COLD))
1659 #define AR_SOC_RST_RESET 0xB806001C
1660 #define AR_SOC_BOOT_STRAP 0xB80600AC
1661 #define AR_SOC_WLAN_RST 0x00000800 /* WLAN reset */
1662 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
1663 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
1664 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Hornet SoC reset WMAC.\n", __func__);
1666 REG_WRITE(AR_SOC_RST_RESET,
1667 REG_READ(AR_SOC_RST_RESET) | AR_SOC_WLAN_RST);
1668 REG_WRITE(AR_SOC_RST_RESET,
1669 REG_READ(AR_SOC_RST_RESET) & (~AR_SOC_WLAN_RST));
1674 tmp_reg = REG_READ(AR_SOC_BOOT_STRAP);
1675 if ((tmp_reg & 0x10) == 0) {
1678 if (time_out > 20) {
1685 OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1688 #undef AR_SOC_WLAN_RST
1689 #undef AR_SOC_RST_RESET
1690 #undef AR_SOC_BOOT_STRAP
1692 #endif /* AH_SUPPORT_HORNET */
1694 #ifdef AH_SUPPORT_SCORPION
1695 if (AR_SREV_SCORPION(ah)) {
1696 #define DDR_CTL_CONFIG_ADDRESS 0xb8000000
1697 #define DDR_CTL_CONFIG_OFFSET 0x0108
1698 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_MSB 29
1699 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB 21
1700 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK 0x3fe00000
1701 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_GET(x) (((x) & DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK) >> DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB)
1702 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_SET(x) (((x) << DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB) & DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK)
1703 #define MAC_DMA_CFG_ADDRESS 0xb8100000
1704 #define MAC_DMA_CFG_OFFSET 0x0014
1706 #define MAC_DMA_CFG_HALT_REQ_MSB 11
1707 #define MAC_DMA_CFG_HALT_REQ_LSB 11
1708 #define MAC_DMA_CFG_HALT_REQ_MASK 0x00000800
1709 #define MAC_DMA_CFG_HALT_REQ_GET(x) (((x) & MAC_DMA_CFG_HALT_REQ_MASK) >> MAC_DMA_CFG_HALT_REQ_LSB)
1710 #define MAC_DMA_CFG_HALT_REQ_SET(x) (((x) << MAC_DMA_CFG_HALT_REQ_LSB) & MAC_DMA_CFG_HALT_REQ_MASK)
1711 #define MAC_DMA_CFG_HALT_ACK_MSB 12
1712 #define MAC_DMA_CFG_HALT_ACK_LSB 12
1713 #define MAC_DMA_CFG_HALT_ACK_MASK 0x00001000
1714 #define MAC_DMA_CFG_HALT_ACK_GET(x) (((x) & MAC_DMA_CFG_HALT_ACK_MASK) >> MAC_DMA_CFG_HALT_ACK_LSB)
1715 #define MAC_DMA_CFG_HALT_ACK_SET(x) (((x) << MAC_DMA_CFG_HALT_ACK_LSB) & MAC_DMA_CFG_HALT_ACK_MASK)
1717 #define RST_RESET 0xB806001c
1718 #define RTC_RESET (1<<27)
1720 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
1721 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
1723 #define DDR_REG_READ(_ah, _reg) \
1724 *((volatile u_int32_t *)( DDR_CTL_CONFIG_ADDRESS + (_reg)))
1725 #define DDR_REG_WRITE(_ah, _reg, _val) \
1726 *((volatile u_int32_t *)(DDR_CTL_CONFIG_ADDRESS + (_reg))) = (_val)
1728 OS_REG_WRITE(ah,MAC_DMA_CFG_OFFSET, (OS_REG_READ(ah,MAC_DMA_CFG_OFFSET) & ~MAC_DMA_CFG_HALT_REQ_MASK) |
1729 MAC_DMA_CFG_HALT_REQ_SET(1));
1736 while (!MAC_DMA_CFG_HALT_ACK_GET(OS_REG_READ(ah, MAC_DMA_CFG_OFFSET) ))
1740 ath_hal_printf(ah, "Halt ACK timeout\n");
1746 data = DDR_REG_READ(ah,DDR_CTL_CONFIG_OFFSET);
1747 ath_hal_printf(ah, "check DDR Activity - HIGH\n");
1750 while (DDR_CTL_CONFIG_CLIENT_ACTIVITY_GET(data)) {
1751 // AVE_DEBUG(0,"DDR Activity - HIGH\n");
1752 ath_hal_printf(ah, "DDR Activity - HIGH\n");
1755 data = DDR_REG_READ(ah,DDR_CTL_CONFIG_OFFSET);
1757 ath_hal_printf(ah, "DDR Activity timeout\n");
1766 REG_WRITE(RST_RESET, (REG_READ(RST_RESET) | RTC_RESET));
1768 REG_WRITE(RST_RESET, (REG_READ(RST_RESET) & ~RTC_RESET));
1770 OS_REG_WRITE(ah, AR_RTC_RESET, 0);
1772 OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1774 ath_hal_printf(ah,"%s: Scorpion SoC RTC reset done.\n", __func__);
1779 #endif /* AH_SUPPORT_SCORPION */
1782 * Set Mac(BB,Phy) Warm Reset
1784 OS_REG_WRITE(ah, AR_RTC_RC, rst_flags);
1786 OS_DELAY(50); /* XXX 50 usec */
1789 * Clear resets and force wakeup
1791 OS_REG_WRITE(ah, AR_RTC_RC, 0);
1792 if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) {
1793 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1794 "%s: RTC stuck in MAC reset\n", __FUNCTION__);
1795 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1796 "%s: AR_RTC_RC = 0x%x\n", __func__, OS_REG_READ(ah, AR_RTC_RC));
1800 /* Clear AHB reset */
1801 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), 0);
1803 ar9300_attach_hw_platform(ah);
1808 static inline HAL_BOOL
1809 ar9300_set_reset_power_on(struct ath_hal *ah)
1812 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1813 OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1814 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1815 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1817 * RTC reset and clear. Some delay in between is needed
1818 * to give the chip time to settle.
1820 OS_REG_WRITE(ah, AR_RTC_RESET, 0);
1822 OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1825 * Poll till RTC is ON
1827 if (!ath_hal_wait(ah,
1828 AR_RTC_STATUS, AR_RTC_STATUS_M,
1831 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1832 "%s: RTC not waking up for %d\n", __FUNCTION__, 1000);
1837 * Read Revisions from Chip right after RTC is on for the first time.
1838 * This helps us detect the chip type early and initialize it accordingly.
1840 ar9300_read_revisions(ah);
1843 * Warm reset if we aren't really powering on,
1844 * just restarting the driver.
1846 return ar9300_set_reset(ah, HAL_RESET_WARM);
1850 * Write the given reset bit mask into the reset register
1853 ar9300_set_reset_reg(struct ath_hal *ah, u_int32_t type)
1855 HAL_BOOL ret = AH_FALSE;
1860 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1861 OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1862 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1863 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1866 case HAL_RESET_POWER_ON:
1867 ret = ar9300_set_reset_power_on(ah);
1869 case HAL_RESET_WARM:
1870 case HAL_RESET_COLD:
1871 ret = ar9300_set_reset(ah, type);
1878 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
1879 OS_REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
1887 * Places the PHY and Radio chips into reset. A full reset
1888 * must be called to leave this state. The PCI/MAC/PCU are
1889 * not placed into reset as we must receive interrupt to
1890 * re-enable the hardware.
1893 ar9300_phy_disable(struct ath_hal *ah)
1895 if (!ar9300_set_reset_reg(ah, HAL_RESET_WARM)) {
1899 #ifdef ATH_SUPPORT_LED
1900 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
1901 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
1902 #define ATH_GPIO_OE 0xB8040000
1903 #define ATH_GPIO_OUT 0xB8040008 /* GPIO Ouput Value reg.*/
1904 if (AR_SREV_WASP(ah)) {
1905 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
1906 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 13)));
1909 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12)));
1912 else if (AR_SREV_SCORPION(ah)) {
1913 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
1914 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 13)));
1917 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12)));
1919 /* Turn off JMPST led */
1920 REG_WRITE(ATH_GPIO_OUT, (REG_READ(ATH_GPIO_OUT) | (0x1 << 15)));
1926 if ( AR_SREV_OSPREY(ah) ) {
1927 OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1), 0x0, 0x1f);
1931 ar9300_init_pll(ah, AH_NULL);
1937 * Places all of hardware into reset
1940 ar9300_disable(struct ath_hal *ah)
1942 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
1945 if (!ar9300_set_reset_reg(ah, HAL_RESET_COLD)) {
1949 ar9300_init_pll(ah, AH_NULL);
1955 * TODO: Only write the PLL if we're changing to or from CCK mode
1957 * WARNING: The order of the PLL and mode registers must be correct.
1960 ar9300_set_rf_mode(struct ath_hal *ah, struct ieee80211_channel *chan)
1962 u_int32_t rf_mode = 0;
1964 if (chan == AH_NULL) {
1967 switch (AH9300(ah)->ah_hwp) {
1969 rf_mode |= (IEEE80211_IS_CHAN_B(chan) || IEEE80211_IS_CHAN_G(chan)) ?
1970 AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
1976 /* Phy mode bits for 5GHz channels requiring Fast Clock */
1977 if ( IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
1978 rf_mode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
1980 OS_REG_WRITE(ah, AR_PHY_MODE, rf_mode);
1984 * Places the hardware into reset and then pulls it out of reset
1987 ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *chan)
1989 struct ath_hal_9300 *ahp = AH9300(ah);
1991 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
1994 * Warm reset is optimistic.
1996 if (!ar9300_set_reset_reg(ah, HAL_RESET_WARM)) {
2000 /* Bring out of sleep mode (AGAIN) */
2001 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
2005 ahp->ah_chip_full_sleep = AH_FALSE;
2007 if (AR_SREV_HORNET(ah)) {
2008 ar9300_internal_regulator_apply(ah);
2011 ar9300_init_pll(ah, chan);
2014 * Perform warm reset before the mode/PLL/turbo registers
2015 * are changed in order to deactivate the radio. Mode changes
2016 * with an active radio can result in corrupted shifts to the
2019 ar9300_set_rf_mode(ah, chan);
2024 /* ar9300_setup_calibration
2025 * Setup HW to collect samples used for current cal
2028 ar9300_setup_calibration(struct ath_hal *ah, HAL_CAL_LIST *curr_cal)
2030 /* Select calibration to run */
2031 switch (curr_cal->cal_data->cal_type) {
2032 case IQ_MISMATCH_CAL:
2033 /* Start calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
2034 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4,
2035 AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
2036 curr_cal->cal_data->cal_count_max);
2037 OS_REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
2039 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2040 "%s: starting IQ Mismatch Calibration\n", __func__);
2043 OS_REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
2047 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
2048 AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
2049 OS_REG_RMW_FIELD(ah,
2050 AR_HORNET_CH0_THERM, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2051 OS_REG_RMW_FIELD(ah,
2052 AR_HORNET_CH0_THERM, AR_PHY_65NM_CH0_THERM_START, 1);
2053 } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
2054 OS_REG_RMW_FIELD(ah,
2055 AR_PHY_65NM_CH0_THERM_JUPITER, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2056 OS_REG_RMW_FIELD(ah,
2057 AR_PHY_65NM_CH0_THERM_JUPITER, AR_PHY_65NM_CH0_THERM_START, 1);
2059 OS_REG_RMW_FIELD(ah,
2060 AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2061 OS_REG_RMW_FIELD(ah,
2062 AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_START, 1);
2065 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2066 "%s: starting Temperature Compensation Calibration\n", __func__);
2069 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
2070 "%s called with incorrect calibration type.\n", __func__);
2074 /* ar9300_reset_calibration
2075 * Initialize shared data structures and prepare a cal to be run.
2078 ar9300_reset_calibration(struct ath_hal *ah, HAL_CAL_LIST *curr_cal)
2080 struct ath_hal_9300 *ahp = AH9300(ah);
2083 /* Setup HW for new calibration */
2084 ar9300_setup_calibration(ah, curr_cal);
2086 /* Change SW state to RUNNING for this calibration */
2087 curr_cal->cal_state = CAL_RUNNING;
2089 /* Reset data structures shared between different calibrations */
2090 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
2091 ahp->ah_meas0.sign[i] = 0;
2092 ahp->ah_meas1.sign[i] = 0;
2093 ahp->ah_meas2.sign[i] = 0;
2094 ahp->ah_meas3.sign[i] = 0;
2097 ahp->ah_cal_samples = 0;
2100 #ifdef XXX_UNUSED_FUNCTION
2102 * Find out which of the RX chains are enabled
2105 ar9300_get_rx_chain_mask(struct ath_hal *ah)
2107 u_int32_t ret_val = OS_REG_READ(ah, AR_PHY_RX_CHAINMASK);
2108 /* The bits [2:0] indicate the rx chain mask and are to be
2109 * interpreted as follows:
2110 * 00x => Only chain 0 is enabled
2111 * 01x => Chain 1 and 0 enabled
2112 * 1xx => Chain 2,1 and 0 enabled
2114 return (ret_val & 0x7);
2119 ar9300_get_nf_hist_base(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
2120 int is_scan, int16_t nf[])
2122 HAL_NFCAL_BASE *h_base;
2124 #ifdef ATH_NF_PER_CHAN
2125 h_base = &chan->nf_cal_hist.base;
2129 * The channel we are currently on is not the home channel,
2130 * so we shouldn't use the home channel NF buffer's values on
2131 * this channel. Instead, use the NF single value already
2132 * read for this channel. (Or, if we haven't read the NF for
2133 * this channel yet, the SW default for this chip/band will
2136 h_base = &chan->nf_cal_hist.base;
2138 /* use the home channel NF info */
2139 h_base = &AH_PRIVATE(ah)->nf_cal_hist.base;
2142 OS_MEMCPY(nf, h_base->priv_nf, sizeof(h_base->priv_nf));
2146 ar9300_load_nf(struct ath_hal *ah, int16_t nf[])
2150 /* XXX where are EXT regs defined */
2151 const u_int32_t ar9300_cca_regs[] = {
2162 * Force NF calibration for all chains, otherwise Vista station
2163 * would conduct a bad performance
2165 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
2167 } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah)) {
2174 * Write filtered NF values into max_cca_pwr register parameter
2175 * so we can load below.
2177 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
2178 if (chainmask & (1 << i)) {
2179 val = OS_REG_READ(ah, ar9300_cca_regs[i]);
2181 val |= (((u_int32_t)(nf[i]) << 1) & 0x1ff);
2182 OS_REG_WRITE(ah, ar9300_cca_regs[i], val);
2186 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%s: load %d %d %d %d %d %d\n",
2188 nf[0], nf[1], nf[2],
2189 nf[3], nf[4], nf[5]);
2192 * Load software filtered NF value into baseband internal min_cca_pwr
2195 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
2196 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
2197 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
2199 /* Wait for load to complete, should be fast, a few 10s of us. */
2200 /* Changed the max delay 250us back to 10000us, since 250us often
2201 * results in NF load timeout and causes deaf condition
2202 * during stress testing 12/12/2009
2204 for (j = 0; j < 10000; j++) {
2205 if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){
2212 * We timed out waiting for the noisefloor to load, probably
2213 * due to an in-progress rx. Simply return here and allow
2214 * the load plenty of time to complete before the next
2215 * calibration interval. We need to avoid trying to load -50
2216 * (which happens below) while the previous load is still in
2217 * progress as this can cause rx deafness (see EV 66368,62830).
2218 * Instead by returning here, the baseband nf cal will
2219 * just be capped by our present noisefloor until the next
2220 * calibration timer.
2222 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,
2223 "%s: *** TIMEOUT while waiting for nf to load: "
2224 "AR_PHY_AGC_CONTROL=0x%x ***\n",
2225 __func__, OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
2230 * Restore max_cca_power register parameter again so that we're not capped
2231 * by the median we just loaded. This will be initial (and max) value
2232 * of next noise floor calibration the baseband does.
2234 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
2235 if (chainmask & (1 << i)) {
2236 val = OS_REG_READ(ah, ar9300_cca_regs[i]);
2238 val |= (((u_int32_t)(-50) << 1) & 0x1ff);
2239 OS_REG_WRITE(ah, ar9300_cca_regs[i], val);
2245 /* ar9300_per_calibration
2246 * Generic calibration routine.
2247 * Recalibrate the lower PHY chips to account for temperature/environment
2251 ar9300_per_calibration(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
2252 u_int8_t rxchainmask, HAL_CAL_LIST *curr_cal, HAL_BOOL *is_cal_done)
2254 struct ath_hal_9300 *ahp = AH9300(ah);
2256 /* Cal is assumed not done until explicitly set below */
2257 *is_cal_done = AH_FALSE;
2259 /* Calibration in progress. */
2260 if (curr_cal->cal_state == CAL_RUNNING) {
2261 /* Check to see if it has finished. */
2262 if (!(OS_REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) {
2263 int i, num_chains = 0;
2264 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
2265 if (rxchainmask & (1 << i)) {
2271 * Accumulate cal measures for active chains
2273 curr_cal->cal_data->cal_collect(ah, num_chains);
2275 ahp->ah_cal_samples++;
2277 if (ahp->ah_cal_samples >= curr_cal->cal_data->cal_num_samples) {
2279 * Process accumulated data
2281 curr_cal->cal_data->cal_post_proc(ah, num_chains);
2283 /* Calibration has finished. */
2284 ichan->calValid |= curr_cal->cal_data->cal_type;
2285 curr_cal->cal_state = CAL_DONE;
2286 *is_cal_done = AH_TRUE;
2288 /* Set-up collection of another sub-sample until we
2289 * get desired number
2291 ar9300_setup_calibration(ah, curr_cal);
2294 } else if (!(ichan->calValid & curr_cal->cal_data->cal_type)) {
2295 /* If current cal is marked invalid in channel, kick it off */
2296 ar9300_reset_calibration(ah, curr_cal);
2301 ar9300_start_nf_cal(struct ath_hal *ah)
2303 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
2304 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
2305 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
2306 AH9300(ah)->nf_tsf32 = ar9300_get_tsf32(ah);
2309 /* ar9300_calibration
2310 * Wrapper for a more generic Calibration routine. Primarily to abstract to
2311 * upper layers whether there is 1 or more calibrations to be run.
2314 ar9300_calibration(struct ath_hal *ah, struct ieee80211_channel *chan, u_int8_t rxchainmask,
2315 HAL_BOOL do_nf_cal, HAL_BOOL *is_cal_done, int is_scan,
2316 u_int32_t *sched_cals)
2318 struct ath_hal_9300 *ahp = AH9300(ah);
2319 HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr;
2320 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2321 int16_t nf_buf[HAL_NUM_NF_READINGS];
2323 *is_cal_done = AH_TRUE;
2326 /* XXX: For initial wasp bringup - disable periodic calibration */
2327 /* Invalid channel check */
2328 if (ichan == AH_NULL) {
2329 HALDEBUG(ah, HAL_DEBUG_CHANNEL,
2330 "%s: invalid channel %u/0x%x; no mapping\n",
2331 __func__, chan->ic_freq, chan->ic_flags);
2335 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2336 "%s: Entering, Doing NF Cal = %d\n", __func__, do_nf_cal);
2337 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Chain 0 Rx IQ Cal Correction 0x%08x\n",
2338 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
2339 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah) && !AR_SREV_APHRODITE(ah)) {
2340 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2341 "%s: Chain 1 Rx IQ Cal Correction 0x%08x\n",
2342 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B1));
2343 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
2344 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2345 "%s: Chain 2 Rx IQ Cal Correction 0x%08x\n",
2346 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B2));
2350 OS_MARK(ah, AH_MARK_PERCAL, chan->ic_freq);
2352 /* For given calibration:
2353 * 1. Call generic cal routine
2354 * 2. When this cal is done (is_cal_done) if we have more cals waiting
2355 * (eg after reset), mask this to upper layers by not propagating
2356 * is_cal_done if it is set to TRUE.
2357 * Instead, change is_cal_done to FALSE and setup the waiting cal(s)
2360 if (curr_cal && (curr_cal->cal_data->cal_type & *sched_cals) &&
2361 (curr_cal->cal_state == CAL_RUNNING ||
2362 curr_cal->cal_state == CAL_WAITING))
2364 ar9300_per_calibration(ah, ichan, rxchainmask, curr_cal, is_cal_done);
2366 if (*is_cal_done == AH_TRUE) {
2367 ahp->ah_cal_list_curr = curr_cal = curr_cal->cal_next;
2369 if (curr_cal && curr_cal->cal_state == CAL_WAITING) {
2370 *is_cal_done = AH_FALSE;
2371 ar9300_reset_calibration(ah, curr_cal);
2373 *sched_cals &= ~IQ_MISMATCH_CAL;
2378 /* Do NF cal only at longer intervals */
2382 /* Get the value from the previous NF cal and update history buffer */
2383 nf_done = ar9300_store_new_nf(ah, chan, is_scan);
2385 if (ichan->channel_flags & CHANNEL_CW_INT) {
2386 chan->channel_flags |= CHANNEL_CW_INT;
2389 chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
2393 * Load the NF from history buffer of the current channel.
2394 * NF is slow time-variant, so it is OK to use a historical value.
2396 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
2397 ar9300_load_nf(ah, nf_buf);
2399 /* start NF calibration, without updating BB NF register*/
2400 ar9300_start_nf_cal(ah);
2406 /* ar9300_iq_cal_collect
2407 * Collect data from HW to later perform IQ Mismatch Calibration
2410 ar9300_iq_cal_collect(struct ath_hal *ah, u_int8_t num_chains)
2412 struct ath_hal_9300 *ahp = AH9300(ah);
2416 * Accumulate IQ cal measures for active chains
2418 for (i = 0; i < num_chains; i++) {
2419 ahp->ah_total_power_meas_i[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
2420 ahp->ah_total_power_meas_q[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
2421 ahp->ah_total_iq_corr_meas[i] =
2422 (int32_t) OS_REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
2423 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2425 "Reg Offset(0x%04x)pmi=0x%08x; "
2426 "Reg Offset(0x%04x)pmq=0x%08x; "
2427 "Reg Offset (0x%04x)iqcm=0x%08x;\n",
2428 ahp->ah_cal_samples,
2430 (unsigned) AR_PHY_CAL_MEAS_0(i),
2431 ahp->ah_total_power_meas_i[i],
2432 (unsigned) AR_PHY_CAL_MEAS_1(i),
2433 ahp->ah_total_power_meas_q[i],
2434 (unsigned) AR_PHY_CAL_MEAS_2(i),
2435 ahp->ah_total_iq_corr_meas[i]);
2439 /* ar9300_iq_calibration
2440 * Use HW data to perform IQ Mismatch Calibration
2443 ar9300_iq_calibration(struct ath_hal *ah, u_int8_t num_chains)
2445 struct ath_hal_9300 *ahp = AH9300(ah);
2446 u_int32_t power_meas_q, power_meas_i, iq_corr_meas;
2447 u_int32_t q_coff_denom, i_coff_denom;
2448 int32_t q_coff, i_coff;
2450 static const u_int32_t offset_array[3] = {
2451 AR_PHY_RX_IQCAL_CORR_B0,
2452 AR_PHY_RX_IQCAL_CORR_B1,
2453 AR_PHY_RX_IQCAL_CORR_B2,
2456 for (i = 0; i < num_chains; i++) {
2457 power_meas_i = ahp->ah_total_power_meas_i[i];
2458 power_meas_q = ahp->ah_total_power_meas_q[i];
2459 iq_corr_meas = ahp->ah_total_iq_corr_meas[i];
2461 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2462 "Starting IQ Cal and Correction for Chain %d\n", i);
2463 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2464 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
2465 i, ahp->ah_total_iq_corr_meas[i]);
2469 /* iq_corr_meas is always negative. */
2470 if (iq_corr_meas > 0x80000000) {
2471 iq_corr_meas = (0xffffffff - iq_corr_meas) + 1;
2475 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2476 "Chn %d pwr_meas_i = 0x%08x\n", i, power_meas_i);
2477 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2478 "Chn %d pwr_meas_q = 0x%08x\n", i, power_meas_q);
2479 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2480 "iq_corr_neg is 0x%08x\n", iq_corr_neg);
2482 i_coff_denom = (power_meas_i / 2 + power_meas_q / 2) / 256;
2483 q_coff_denom = power_meas_q / 64;
2485 /* Protect against divide-by-0 */
2486 if ((i_coff_denom != 0) && (q_coff_denom != 0)) {
2487 /* IQ corr_meas is already negated if iqcorr_neg == 1 */
2488 i_coff = iq_corr_meas / i_coff_denom;
2489 q_coff = power_meas_i / q_coff_denom - 64;
2490 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2491 "Chn %d i_coff = 0x%08x\n", i, i_coff);
2492 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2493 "Chn %d q_coff = 0x%08x\n", i, q_coff);
2495 /* Force bounds on i_coff */
2498 } else if (i_coff <= -63) {
2502 /* Negate i_coff if iq_corr_neg == 0 */
2503 if (iq_corr_neg == 0x0) {
2507 /* Force bounds on q_coff */
2510 } else if (q_coff <= -63) {
2514 i_coff = i_coff & 0x7f;
2515 q_coff = q_coff & 0x7f;
2517 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2518 "Chn %d : i_coff = 0x%x q_coff = 0x%x\n", i, i_coff, q_coff);
2519 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2520 "Register offset (0x%04x) before update = 0x%x\n",
2521 offset_array[i], OS_REG_READ(ah, offset_array[i]));
2523 OS_REG_RMW_FIELD(ah, offset_array[i],
2524 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, i_coff);
2525 OS_REG_RMW_FIELD(ah, offset_array[i],
2526 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, q_coff);
2528 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2529 "Register offset (0x%04x) QI COFF (bitfields 0x%08x) "
2530 "after update = 0x%x\n",
2531 offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
2532 OS_REG_READ(ah, offset_array[i]));
2533 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2534 "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) "
2535 "after update = 0x%x\n",
2536 offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
2537 OS_REG_READ(ah, offset_array[i]));
2538 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2539 "IQ Cal and Correction done for Chain %d\n", i);
2544 AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
2545 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2546 "IQ Cal and Correction (offset 0x%04x) enabled "
2547 "(bit position 0x%08x). New Value 0x%08x\n",
2548 (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
2549 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
2550 OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
2554 * Set a limit on the overall output power. Used for dynamic
2555 * transmit power control and the like.
2557 * NB: limit is in units of 0.5 dbM.
2560 ar9300_set_tx_power_limit(struct ath_hal *ah, u_int32_t limit,
2561 u_int16_t extra_txpow, u_int16_t tpc_in_db)
2563 struct ath_hal_9300 *ahp = AH9300(ah);
2564 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
2565 const struct ieee80211_channel *chan = ahpriv->ah_curchan;
2566 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2572 ahpriv->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);
2573 ahpriv->ah_extraTxPow = extra_txpow;
2578 if (ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan,
2579 ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
2580 ath_hal_get_twice_max_regpower(ahpriv, ichan, chan),
2581 AH_MIN(MAX_RATE_POWER, ahpriv->ah_powerLimit)) != HAL_OK)
2589 * Exported call to check for a recent gain reading and return
2590 * the current state of the thermal calibration gain engine.
2593 ar9300_get_rfgain(struct ath_hal *ah)
2595 return HAL_RFGAIN_INACTIVE;
2598 #define HAL_GREEN_AP_RX_MASK 0x1
2601 ar9300_init_chain_masks(struct ath_hal *ah, int rx_chainmask, int tx_chainmask)
2603 if (AH9300(ah)->green_ap_ps_on) {
2604 rx_chainmask = HAL_GREEN_AP_RX_MASK;
2606 if (rx_chainmask == 0x5) {
2607 OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
2609 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
2610 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
2613 * Adaptive Power Management:
2614 * Some 3 stream chips exceed the PCIe power requirements.
2615 * This workaround will reduce power consumption by using 2 tx chains
2616 * for 1 and 2 stream rates (5 GHz only).
2618 * Set the self gen mask to 2 tx chains when APM is enabled.
2621 if (AH_PRIVATE(ah)->ah_caps.halApmEnable && (tx_chainmask == 0x7)) {
2622 OS_REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
2625 OS_REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
2628 if (tx_chainmask == 0x5) {
2629 OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
2634 * Override INI values with chip specific configuration.
2637 ar9300_override_ini(struct ath_hal *ah, struct ieee80211_channel *chan)
2640 HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
2643 * Set the RX_ABORT and RX_DIS and clear it only after
2644 * RXE is set for MAC. This prevents frames with
2645 * corrupted descriptor status.
2647 OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
2649 * For Merlin and above, there is a new feature that allows Multicast
2650 * search based on both MAC Address and Key ID.
2651 * By default, this feature is enabled.
2652 * But since the driver is not using this feature, we switch it off;
2653 * otherwise multicast search based on MAC addr only will fail.
2655 val = OS_REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE);
2656 OS_REG_WRITE(ah, AR_PCU_MISC_MODE2,
2657 val | AR_BUG_58603_FIX_ENABLE | AR_AGG_WEP_ENABLE);
2660 /* Osprey revision specific configuration */
2662 /* Osprey 2.0+ - if SW RAC support is disabled, must also disable
2663 * the Osprey 2.0 hardware RAC fix.
2665 if (p_cap->halIsrRacSupport == AH_FALSE) {
2666 OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_MISSING_TX_INTR_FIX_ENABLE);
2669 /* try to enable old pal if it is needed for h/w green tx */
2670 ar9300_hwgreentx_set_pal_spare(ah, 1);
2674 ar9300_prog_ini(struct ath_hal *ah, struct ar9300_ini_array *ini_arr,
2677 int i, reg_writes = 0;
2679 /* New INI format: Array may be undefined (pre, core, post arrays) */
2680 if (ini_arr->ia_array == NULL) {
2685 * New INI format: Pre, core, and post arrays for a given subsystem may be
2686 * modal (> 2 columns) or non-modal (2 columns).
2687 * Determine if the array is non-modal and force the column to 1.
2689 if (column >= ini_arr->ia_columns) {
2693 for (i = 0; i < ini_arr->ia_rows; i++) {
2694 u_int32_t reg = INI_RA(ini_arr, i, 0);
2695 u_int32_t val = INI_RA(ini_arr, i, column);
2698 ** Determine if this is a shift register value
2699 ** (reg >= 0x16000 && reg < 0x17000 for Osprey) ,
2700 ** and insert the configured delay if so.
2701 ** -this delay is not required for Osprey (EV#71410)
2703 OS_REG_WRITE(ah, reg, val);
2704 WAR_6773(reg_writes);
2709 static inline HAL_STATUS
2710 ar9300_process_ini(struct ath_hal *ah, struct ieee80211_channel *chan,
2711 HAL_CHANNEL_INTERNAL *ichan, HAL_HT_MACMODE macmode)
2714 struct ath_hal_9300 *ahp = AH9300(ah);
2715 u_int modes_index, modes_txgaintable_index = 0;
2718 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
2719 /* Setup the indices for the next set of register array writes */
2721 * If the channel marker is indicative of the current mode rather
2722 * than capability, we do not need to check the phy mode below.
2725 switch (chan->channel_flags & CHANNEL_ALL) {
2727 case CHANNEL_A_HT20:
2728 if (AR_SREV_SCORPION(ah)){
2729 if (chan->channel <= 5350){
2730 modes_txgaintable_index = 1;
2731 }else if ((chan->channel > 5350) && (chan->channel <= 5600)){
2732 modes_txgaintable_index = 3;
2733 }else if (chan->channel > 5600){
2734 modes_txgaintable_index = 5;
2740 case CHANNEL_A_HT40PLUS:
2741 case CHANNEL_A_HT40MINUS:
2742 if (AR_SREV_SCORPION(ah)){
2743 if (chan->channel <= 5350){
2744 modes_txgaintable_index = 2;
2745 }else if ((chan->channel > 5350) && (chan->channel <= 5600)){
2746 modes_txgaintable_index = 4;
2747 }else if (chan->channel > 5600){
2748 modes_txgaintable_index = 6;
2755 case CHANNEL_G_HT20:
2757 if (AR_SREV_SCORPION(ah)){
2758 modes_txgaintable_index = 8;
2763 case CHANNEL_G_HT40PLUS:
2764 case CHANNEL_G_HT40MINUS:
2765 if (AR_SREV_SCORPION(ah)){
2766 modes_txgaintable_index = 7;
2782 if (IS_CHAN_5GHZ(ichan)) {
2783 if (IEEE80211_IS_CHAN_HT40U(chan) || IEEE80211_IS_CHAN_HT40D(chan)) {
2784 if (AR_SREV_SCORPION(ah)){
2785 if (ichan->channel <= 5350){
2786 modes_txgaintable_index = 2;
2787 }else if ((ichan->channel > 5350) && (ichan->channel <= 5600)){
2788 modes_txgaintable_index = 4;
2789 }else if (ichan->channel > 5600){
2790 modes_txgaintable_index = 6;
2794 } else if (IEEE80211_IS_CHAN_A(chan) || IEEE80211_IS_CHAN_HT20(chan)) {
2795 if (AR_SREV_SCORPION(ah)){
2796 if (ichan->channel <= 5350){
2797 modes_txgaintable_index = 1;
2798 }else if ((ichan->channel > 5350) && (ichan->channel <= 5600)){
2799 modes_txgaintable_index = 3;
2800 }else if (ichan->channel > 5600){
2801 modes_txgaintable_index = 5;
2807 } else if (IS_CHAN_2GHZ(ichan)) {
2808 if (IEEE80211_IS_CHAN_108G(chan)) {
2810 } else if (IEEE80211_IS_CHAN_HT40U(chan) || IEEE80211_IS_CHAN_HT40D(chan)) {
2811 if (AR_SREV_SCORPION(ah)){
2812 modes_txgaintable_index = 7;
2815 } else if (IEEE80211_IS_CHAN_HT20(chan) || IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_B(chan) || IEEE80211_IS_CHAN_PUREG(chan)) {
2816 if (AR_SREV_SCORPION(ah)){
2817 modes_txgaintable_index = 8;
2826 /* Set correct Baseband to analog shift setting to access analog chips. */
2827 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
2830 HALDEBUG(ah, HAL_DEBUG_RESET,
2831 "ar9300_process_ini: "
2832 "Skipping OS-REG-WRITE(ah, AR-PHY(0), 0x00000007)\n");
2833 HALDEBUG(ah, HAL_DEBUG_RESET,
2834 "ar9300_process_ini: no ADDac programming\n");
2838 * Osprey 2.0+ - new INI format.
2839 * Each subsystem has a pre, core, and post array.
2841 for (i = 0; i < ATH_INI_NUM_SPLIT; i++) {
2842 ar9300_prog_ini(ah, &ahp->ah_ini_soc[i], modes_index);
2843 ar9300_prog_ini(ah, &ahp->ah_ini_mac[i], modes_index);
2844 ar9300_prog_ini(ah, &ahp->ah_ini_bb[i], modes_index);
2845 ar9300_prog_ini(ah, &ahp->ah_ini_radio[i], modes_index);
2846 if ((i == ATH_INI_POST) && (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah))) {
2847 ar9300_prog_ini(ah, &ahp->ah_ini_radio_post_sys2ant, modes_index);
2852 if (!(AR_SREV_SOC(ah))) {
2853 /* Doubler issue : Some board doesn't work well with MCS15. Turn off doubler after freq locking is complete*/
2854 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2855 OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2856 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
2857 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2859 OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2860 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
2861 OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2862 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
2865 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2866 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
2867 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
2868 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
2869 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2873 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2874 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
2875 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
2876 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
2877 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2881 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_SYNTH12, OS_REG_READ(ah, AR_PHY_65NM_CH0_SYNTH12));
2882 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH12, AR_PHY_65NM_CH0_SYNTH12_VREFMUL3, 0xf);
2883 //OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_SYNTH12, 1<< 16); /* clr charge pump */
2884 //ath_hal_printf(ah, "%s[%d] ==== After reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_SYNTH12, OS_REG_READ(ah, AR_PHY_65NM_CH0_SYNTH12));
2886 OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2887 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
2888 OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2889 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
2890 OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2891 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
2892 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2895 /* Write rxgain Array Parameters */
2896 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain, 1, reg_writes);
2897 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain programming\n");
2899 if (AR_SREV_SCORPION(ah)) {
2900 /* Write rxgain bounds Array */
2901 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bounds, modes_index, reg_writes);
2902 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain table bounds programming\n");
2904 /* UB124 xLNA settings */
2905 if (AR_SREV_WASP(ah) && ar9300_rx_gain_index_get(ah) == 2) {
2906 #define REG_WRITE(_reg,_val) *((volatile u_int32_t *)(_reg)) = (_val);
2907 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
2909 /* B8040000: bit[0]=0, bit[3]=0; */
2910 val = REG_READ(0xB8040000);
2912 REG_WRITE(0xB8040000, val);
2913 /* B804002c: bit[31:24]=0x2e; bit[7:0]=0x2f; */
2914 val = REG_READ(0xB804002c);
2917 REG_WRITE(0xB804002c, val);
2918 /* B804006c: bit[1]=1; */
2919 val = REG_READ(0xB804006c);
2921 REG_WRITE(0xB804006c, val);
2927 /* Write txgain Array Parameters */
2928 if (AR_SREV_SCORPION(ah)) {
2929 REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_txgaintable_index,
2932 REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_index, reg_writes);
2934 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Tx Gain programming\n");
2937 /* For 5GHz channels requiring Fast Clock, apply different modal values */
2938 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
2939 HALDEBUG(ah, HAL_DEBUG_RESET,
2940 "%s: Fast clock enabled, use special ini values\n", __func__);
2941 REG_WRITE_ARRAY(&ahp->ah_ini_modes_additional, modes_index, reg_writes);
2944 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
2945 HALDEBUG(ah, HAL_DEBUG_RESET,
2946 "%s: use xtal ini for AH9300(ah)->clk_25mhz: %d\n",
2947 __func__, AH9300(ah)->clk_25mhz);
2949 &ahp->ah_ini_modes_additional, 1/*modes_index*/, reg_writes);
2952 if (AR_SREV_WASP(ah) && (AH9300(ah)->clk_25mhz == 0)) {
2953 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Apply 40MHz ini settings\n", __func__);
2955 &ahp->ah_ini_modes_additional_40mhz, 1/*modesIndex*/, reg_writes);
2958 /* Handle Japan Channel 14 channel spreading */
2959 if (2484 == ichan->channel) {
2960 ar9300_prog_ini(ah, &ahp->ah_ini_japan2484, 1);
2964 if (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)) {
2965 ar9300_prog_ini(ah, &ahp->ah_ini_BTCOEX_MAX_TXPWR, 1);
2969 /* Override INI with chip specific configuration */
2970 ar9300_override_ini(ah, chan);
2972 /* Setup 11n MAC/Phy mode registers */
2973 ar9300_set_11n_regs(ah, chan, macmode);
2976 * Moved ar9300_init_chain_masks() here to ensure the swap bit is set before
2977 * the pdadc table is written. Swap must occur before any radio dependent
2978 * replicated register access. The pdadc curve addressing in particular
2979 * depends on the consistent setting of the swap bit.
2981 ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
2984 * Setup the transmit power values.
2986 * After the public to private hal channel mapping, ichan contains the
2987 * valid regulatory power value.
2988 * ath_hal_getctl and ath_hal_getantennaallowed look up ichan from chan.
2990 status = ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan,
2991 ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
2992 ath_hal_get_twice_max_regpower(ahpriv, ichan, chan),
2993 AH_MIN(MAX_RATE_POWER, ahpriv->ah_powerLimit));
2994 if (status != HAL_OK) {
2995 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
2996 "%s: error init'ing transmit power\n", __func__);
3005 /* ar9300_is_cal_supp
3006 * Determine if calibration is supported by device and channel flags
3008 inline static HAL_BOOL
3009 ar9300_is_cal_supp(struct ath_hal *ah, const struct ieee80211_channel *chan,
3010 HAL_CAL_TYPES cal_type)
3012 struct ath_hal_9300 *ahp = AH9300(ah);
3013 HAL_BOOL retval = AH_FALSE;
3015 switch (cal_type & ahp->ah_supp_cals) {
3016 case IQ_MISMATCH_CAL:
3017 /* Run IQ Mismatch for non-CCK only */
3018 if (!IEEE80211_IS_CHAN_B(chan)) {
3033 * PA Calibration for Kite 1.1 and later versions of Kite.
3034 * - from system's team.
3037 ar9285_pa_cal(struct ath_hal *ah)
3040 int i, lo_gn, offs_6_1, offs_0;
3042 u_int32_t phy_test2_reg_val, phy_adc_ctl_reg_val;
3043 u_int32_t an_top2_reg_val, phy_tst_dac_reg_val;
3046 /* Kite 1.1 WAR for Bug 35666
3047 * Increase the LDO value to 1.28V before accessing analog Reg */
3048 if (AR_SREV_KITE_11(ah)) {
3049 OS_REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14) );
3051 an_top2_reg_val = OS_REG_READ(ah, AR9285_AN_TOP2);
3053 /* set pdv2i pdrxtxbb */
3054 reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
3055 reg_val |= ((0x1 << 5) | (0x1 << 7));
3056 OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
3059 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G7);
3060 reg_val &= 0xfffffffd;
3061 OS_REG_WRITE(ah, AR9285_AN_RF2G7, reg_val);
3064 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3065 reg_val &= 0xfffff7ff;
3066 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3069 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
3070 reg_val |= (0x1 << 12);
3071 OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
3073 /* set pdpadrv1=pdpadrv2=pdpaout=1 */
3074 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3075 reg_val |= (0x7 << 23);
3076 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3078 /* Read back reflo, increase it by 1 and write it. */
3079 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3080 reflo = ((reg_val >> 26) & 0x7);
3085 reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3086 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3088 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3089 reflo = ((reg_val >> 26) & 0x7);
3091 /* use TX single carrier to transmit
3095 phy_tst_dac_reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3096 OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, ((0x7ff << 11) | 0x7ff));
3097 reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3099 /* source is dac const
3102 phy_test2_reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3103 OS_REG_WRITE(ah, AR_PHY_TEST2, ((0x1 << 7) | (0x1 << 1)));
3104 reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3109 phy_adc_ctl_reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3110 OS_REG_WRITE(ah, AR_PHY_ADC_CTL, 0x80008000);
3111 reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3113 OS_REG_WRITE(ah, AR9285_AN_TOP2, (0x1 << 27) | (0x1 << 17) | (0x1 << 16) |
3114 (0x1 << 14) | (0x1 << 12) | (0x1 << 11) |
3115 (0x1 << 7) | (0x1 << 5));
3117 OS_DELAY(10); /* 10 usec */
3119 /* clear off[6:0] */
3120 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3121 reg_val &= 0xfc0fffff;
3122 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3123 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3124 reg_val &= 0xfdffffff;
3125 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3128 for (i = 6; i > 0; i--) {
3129 /* sef off[$k]==1 */
3130 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3131 reg_val &= 0xfc0fffff;
3132 reg_val = reg_val | (0x1 << (19 + i)) | ((offs_6_1) << 20);
3133 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3134 lo_gn = (OS_REG_READ(ah, AR9285_AN_RF2G9)) & 0x1;
3135 offs_6_1 = offs_6_1 | (lo_gn << (i - 1));
3138 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3139 reg_val &= 0xfc0fffff;
3140 reg_val = reg_val | ((offs_6_1 - 1) << 20);
3141 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3144 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3145 reg_val &= 0xfdffffff;
3146 reg_val = reg_val | (0x1 << 25);
3147 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3149 lo_gn = OS_REG_READ(ah, AR9285_AN_RF2G9) & 0x1;
3152 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3153 reg_val &= 0xfdffffff;
3154 reg_val = reg_val | (offs_0 << 25);
3155 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3158 reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
3159 reg_val &= 0xffffff5f;
3160 OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
3163 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3164 reg_val |= (0x1 << 11);
3165 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3168 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
3169 reg_val &= 0xffffefff;
3170 OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
3172 /* set pdpadrv1=pdpadrv2=pdpaout=0 */
3173 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3174 reg_val &= 0xfc7fffff;
3175 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3177 /* Read back reflo, decrease it by 1 and write it. */
3178 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3179 reflo = (reg_val >> 26) & 0x7;
3183 reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3184 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3185 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3186 reflo = (reg_val >> 26) & 0x7;
3188 /* write back registers */
3189 OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, phy_tst_dac_reg_val);
3190 OS_REG_WRITE(ah, AR_PHY_TEST2, phy_test2_reg_val);
3191 OS_REG_WRITE(ah, AR_PHY_ADC_CTL, phy_adc_ctl_reg_val);
3192 OS_REG_WRITE(ah, AR9285_AN_TOP2, an_top2_reg_val);
3194 /* Kite 1.1 WAR for Bug 35666
3195 * Decrease the LDO value back to 1.20V */
3196 if (AR_SREV_KITE_11(ah)) {
3197 OS_REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
3202 /* ar9300_run_init_cals
3203 * Runs non-periodic calibrations
3205 inline static HAL_BOOL
3206 ar9300_run_init_cals(struct ath_hal *ah, int init_cal_count)
3208 struct ath_hal_9300 *ahp = AH9300(ah);
3209 HAL_CHANNEL_INTERNAL ichan; /* bogus */
3210 HAL_BOOL is_cal_done;
3211 HAL_CAL_LIST *curr_cal;
3212 const HAL_PERCAL_DATA *cal_data;
3215 curr_cal = ahp->ah_cal_list_curr;
3216 if (curr_cal == AH_NULL) {
3219 cal_data = curr_cal->cal_data;
3222 for (i = 0; i < init_cal_count; i++) {
3223 /* Reset this Cal */
3224 ar9300_reset_calibration(ah, curr_cal);
3225 /* Poll for offset calibration complete */
3227 ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL, 0))
3229 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3230 "%s: Cal %d failed to complete in 100ms.\n",
3231 __func__, curr_cal->cal_data->cal_type);
3232 /* Re-initialize list pointers for periodic cals */
3233 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr
3238 ar9300_per_calibration(
3239 ah, &ichan, ahp->ah_rx_chainmask, curr_cal, &is_cal_done);
3240 if (is_cal_done == AH_FALSE) {
3241 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3242 "%s: Not able to run Init Cal %d.\n", __func__,
3243 curr_cal->cal_data->cal_type);
3245 if (curr_cal->cal_next) {
3246 curr_cal = curr_cal->cal_next;
3250 /* Re-initialize list pointers for periodic cals */
3251 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3257 ar9300_tx_carrier_leak_war(struct ath_hal *ah)
3259 unsigned long tx_gain_table_max;
3260 unsigned long reg_bb_cl_map_0_b0 = 0xffffffff;
3261 unsigned long reg_bb_cl_map_1_b0 = 0xffffffff;
3262 unsigned long reg_bb_cl_map_2_b0 = 0xffffffff;
3263 unsigned long reg_bb_cl_map_3_b0 = 0xffffffff;
3264 unsigned long tx_gain, cal_run = 0;
3265 unsigned long cal_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3266 unsigned long cal_gain_index[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3267 unsigned long new_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3270 OS_MEMSET(new_gain, 0, sizeof(new_gain));
3271 /*printf(" Running TxCarrierLeakWAR\n");*/
3273 /* process tx gain table, we use cl_map_hw_gen=0. */
3274 OS_REG_RMW_FIELD(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_MAP_HW_GEN, 0);
3276 //the table we used is txbb_gc[2:0], 1dB[2:1].
3277 tx_gain_table_max = OS_REG_READ_FIELD(ah,
3278 AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX);
3280 for (i = 0; i <= tx_gain_table_max; i++) {
3281 tx_gain = OS_REG_READ(ah, AR_PHY_TXGAIN_TAB(1) + i * 4);
3282 cal_gain[i] = (((tx_gain >> 5)& 0x7) << 2) |
3283 (((tx_gain >> 1) & 0x3) << 0);
3285 cal_gain_index[i] = cal_run;
3290 for (j = 0; j < i; j++) {
3292 printf("i=%d, j=%d cal_gain[$i]=0x%04x\n", i, j, cal_gain[i]);
3295 if ((cal_gain[i] != cal_gain[j])) {
3298 /* if old gain found, use old cal_run value. */
3300 cal_gain_index[i] = cal_gain_index[j];
3304 /* if new gain found, increase cal_run */
3305 if (new_gain[i] == 1) {
3306 cal_gain_index[i] = cal_run;
3311 reg_bb_cl_map_0_b0 = (reg_bb_cl_map_0_b0 & ~(0x1 << i)) |
3312 ((cal_gain_index[i] >> 0 & 0x1) << i);
3313 reg_bb_cl_map_1_b0 = (reg_bb_cl_map_1_b0 & ~(0x1 << i)) |
3314 ((cal_gain_index[i] >> 1 & 0x1) << i);
3315 reg_bb_cl_map_2_b0 = (reg_bb_cl_map_2_b0 & ~(0x1 << i)) |
3316 ((cal_gain_index[i] >> 2 & 0x1) << i);
3317 reg_bb_cl_map_3_b0 = (reg_bb_cl_map_3_b0 & ~(0x1 << i)) |
3318 ((cal_gain_index[i] >> 3 & 0x1) << i);
3321 printf("i=%2d, cal_gain[$i]= 0x%04x, cal_run= %d, "
3322 "cal_gain_index[i]=%d, new_gain[i] = %d\n",
3323 i, cal_gain[i], cal_run, cal_gain_index[i], new_gain[i]);
3326 OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B0, reg_bb_cl_map_0_b0);
3327 OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B0, reg_bb_cl_map_1_b0);
3328 OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B0, reg_bb_cl_map_2_b0);
3329 OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B0, reg_bb_cl_map_3_b0);
3330 if (AR_SREV_WASP(ah)) {
3331 OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B1, reg_bb_cl_map_0_b0);
3332 OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B1, reg_bb_cl_map_1_b0);
3333 OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B1, reg_bb_cl_map_2_b0);
3334 OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B1, reg_bb_cl_map_3_b0);
3341 ar9300_invalidate_saved_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3343 #if ATH_SUPPORT_CAL_REUSE
3344 if (AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3345 ATH_CAL_REUSE_REDO_IN_FULL_RESET)
3347 ichan->one_time_txiqcal_done = AH_FALSE;
3348 ichan->one_time_txclcal_done = AH_FALSE;
3353 static inline HAL_BOOL
3354 ar9300_restore_rtt_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3356 HAL_BOOL restore_status = AH_FALSE;
3358 return restore_status;
3362 * Initialize Calibration infrastructure
3364 static inline HAL_BOOL
3365 ar9300_init_cal_internal(struct ath_hal *ah, struct ieee80211_channel *chan,
3366 HAL_CHANNEL_INTERNAL *ichan,
3367 HAL_BOOL enable_rtt, HAL_BOOL do_rtt_cal, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3369 struct ath_hal_9300 *ahp = AH9300(ah);
3370 HAL_BOOL txiqcal_success_flag = AH_FALSE;
3371 HAL_BOOL cal_done = AH_FALSE;
3373 HAL_BOOL do_sep_iq_cal = AH_FALSE;
3374 HAL_BOOL do_agc_cal = do_rtt_cal;
3375 HAL_BOOL is_cal_reusable = AH_TRUE;
3376 #if ATH_SUPPORT_CAL_REUSE
3377 HAL_BOOL cal_reuse_enable = AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3378 ATH_CAL_REUSE_ENABLE;
3379 HAL_BOOL clc_success = AH_FALSE;
3380 int32_t ch_idx, j, cl_tab_reg;
3381 u_int32_t BB_cl_tab_entry = MAX_BB_CL_TABLE_ENTRY;
3382 u_int32_t BB_cl_tab_b[AR9300_MAX_CHAINS] = {
3389 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
3391 ahp->ah_rx_cal_chainmask = 0x1;
3392 ahp->ah_tx_cal_chainmask = 0x1;
3393 } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah)) {
3394 /* Wasp/Jupiter: 2 x 2 */
3395 ahp->ah_rx_cal_chainmask = 0x3;
3396 ahp->ah_tx_cal_chainmask = 0x3;
3399 * Osprey needs to be configured for the correct chain mode
3400 * before running AGC/TxIQ cals.
3402 if (ahp->ah_enterprise_mode & AR_ENT_OTP_CHAIN2_DISABLE) {
3403 /* chain 2 disabled - 2 chain mode */
3404 ahp->ah_rx_cal_chainmask = 0x3;
3405 ahp->ah_tx_cal_chainmask = 0x3;
3407 ahp->ah_rx_cal_chainmask = 0x7;
3408 ahp->ah_tx_cal_chainmask = 0x7;
3411 ar9300_init_chain_masks(ah, ahp->ah_rx_cal_chainmask, ahp->ah_tx_cal_chainmask);
3414 if (ahp->tx_cl_cal_enable) {
3415 #if ATH_SUPPORT_CAL_REUSE
3416 /* disable Carrie Leak or set do_agc_cal accordingly */
3417 if (cal_reuse_enable && ichan->one_time_txclcal_done)
3419 OS_REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3421 #endif /* ATH_SUPPORT_CAL_REUSE */
3423 OS_REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3424 do_agc_cal = AH_TRUE;
3428 /* Do Tx IQ Calibration here for osprey hornet and wasp */
3429 /* XXX: For initial wasp bringup - check and enable this */
3430 /* EV 74233: Tx IQ fails to complete for half/quarter rates */
3431 if (!(IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) {
3432 if (ahp->tx_iq_cal_enable) {
3433 /* this should be eventually moved to INI file */
3434 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1(ah),
3435 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
3438 * For poseidon and later chips,
3439 * Tx IQ cal HW run will be a part of AGC calibration
3441 if (ahp->tx_iq_cal_during_agc_cal) {
3443 * txiqcal_success_flag always set to 1 to run
3444 * ar9300_tx_iq_cal_post_proc
3445 * if following AGC cal passes
3447 #if ATH_SUPPORT_CAL_REUSE
3448 if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3450 txiqcal_success_flag = AH_TRUE;
3451 OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3452 OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) |
3453 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3455 OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3456 OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) &
3457 (~AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL));
3460 if (OS_REG_READ_FIELD(ah,
3461 AR_PHY_TX_IQCAL_CONTROL_0(ah),
3462 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)){
3463 if (apply_last_iqcorr == AH_TRUE) {
3464 OS_REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3465 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3466 txiqcal_success_flag = AH_FALSE;
3468 txiqcal_success_flag = AH_TRUE;
3471 txiqcal_success_flag = AH_FALSE;
3474 if (txiqcal_success_flag) {
3475 do_agc_cal = AH_TRUE;
3478 #if ATH_SUPPORT_CAL_REUSE
3479 if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3482 do_sep_iq_cal = AH_TRUE;
3483 do_agc_cal = AH_TRUE;
3489 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
3490 IS_CHAN_2GHZ(ichan) &&
3491 (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3493 !(ah->ah_config.ath_hal_mci_config &
3494 ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3496 u_int32_t payload[4] = {0, 0, 0, 0};
3498 /* Send CAL_REQ only when BT is AWAKE. */
3499 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_REQ 0x%X\n",
3500 __func__, ahp->ah_mci_wlan_cal_seq);
3501 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_REQ);
3502 payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_seq++;
3503 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3505 /* Wait BT_CAL_GRANT for 50ms */
3506 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3507 "(MCI) %s: Wait for BT_CAL_GRANT\n", __func__);
3508 if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000))
3510 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3511 "(MCI) %s: Got BT_CAL_GRANT.\n", __func__);
3514 is_cal_reusable = AH_FALSE;
3515 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3516 "(MCI) %s: BT is not responding.\n", __func__);
3519 #endif /* ATH_SUPPORT_MCI */
3523 /* enable Tx IQ Calibration HW for osprey/hornet/wasp */
3524 txiqcal_success_flag = ar9300_tx_iq_cal_hw_run(ah);
3525 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
3527 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
3530 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
3531 ar9300_tx_carrier_leak_war(ah);
3537 * Tx IQ cal is a part of AGC cal for Jupiter/Poseidon, etc.
3538 * please enable the bit of txiqcal_control_0[31] in INI file
3539 * for Jupiter/Poseidon/etc.
3541 if(!AR_SREV_SCORPION(ah)) {
3542 if (do_agc_cal || !skip_if_none) {
3543 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3544 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3546 /* Poll for offset calibration complete */
3547 cal_done = ath_hal_wait(ah,
3548 AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0);
3550 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3551 "(FCS) CAL NOT DONE!!! - %d\n", ichan->channel);
3557 * Tx IQ cal post-processing in SW
3558 * This part of code should be common to all chips,
3559 * no chip specific code for Jupiter/Posdeion except for register names.
3561 if (txiqcal_success_flag) {
3562 ar9300_tx_iq_cal_post_proc(ah,ichan, 1, 1,is_cal_reusable, AH_FALSE);
3565 if (!txiqcal_success_flag) {
3566 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3567 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3568 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
3570 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3571 "%s: offset calibration failed to complete in 1ms; "
3572 "noisy environment?\n", __func__);
3575 if (apply_last_iqcorr == AH_TRUE) {
3576 ar9300_tx_iq_cal_post_proc(ah, ichan, 0, 0, is_cal_reusable, AH_TRUE);
3579 for (iqcal_idx=0;iqcal_idx<MAXIQCAL;iqcal_idx++) {
3580 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3581 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3583 /* Poll for offset calibration complete */
3584 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL,
3585 AR_PHY_AGC_CONTROL_CAL, 0)) {
3586 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3587 "%s: offset calibration failed to complete in 1ms; "
3588 "noisy environment?\n", __func__);
3592 * Tx IQ cal post-processing in SW
3593 * This part of code should be common to all chips,
3594 * no chip specific code for Jupiter/Posdeion except for register names.
3596 ar9300_tx_iq_cal_post_proc(ah, ichan, iqcal_idx+1, MAXIQCAL, is_cal_reusable, AH_FALSE);
3603 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
3604 IS_CHAN_2GHZ(ichan) &&
3605 (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3607 !(ah->ah_config.ath_hal_mci_config &
3608 ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3610 u_int32_t payload[4] = {0, 0, 0, 0};
3612 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_DONE 0x%X\n",
3613 __func__, ahp->ah_mci_wlan_cal_done);
3614 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE);
3615 payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_done++;
3616 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3618 #endif /* ATH_SUPPORT_MCI */
3621 if (!cal_done && !AR_SREV_SCORPION(ah) )
3623 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3624 "%s: offset calibration failed to complete in 1ms; "
3625 "noisy environment?\n", __func__);
3630 /* Beacon stuck fix, refer to EV 120056 */
3631 if(IS_CHAN_2GHZ(chan) && AR_SREV_SCORPION(ah))
3632 OS_REG_WRITE(ah, AR_PHY_TIMING5, OS_REG_READ(ah,AR_PHY_TIMING5) & ~AR_PHY_TIMING5_CYCPWR_THR1_ENABLE);
3636 /* Do PA Calibration */
3637 if (AR_SREV_KITE(ah) && AR_SREV_KITE_11_OR_LATER(ah)) {
3642 #if ATH_SUPPORT_CAL_REUSE
3643 if (ichan->one_time_txiqcal_done) {
3644 ar9300_tx_iq_cal_apply(ah, ichan);
3645 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3646 "(FCS) TXIQCAL applied - %d\n", ichan->channel);
3648 #endif /* ATH_SUPPORT_CAL_REUSE */
3650 #if ATH_SUPPORT_CAL_REUSE
3651 if (cal_reuse_enable && ahp->tx_cl_cal_enable)
3653 clc_success = (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) &
3654 AR_PHY_AGC_CONTROL_CLC_SUCCESS) ? 1 : 0;
3656 if (ichan->one_time_txclcal_done)
3658 /* reapply CL cal results */
3659 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3660 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3663 cl_tab_reg = BB_cl_tab_b[ch_idx];
3664 for (j = 0; j < BB_cl_tab_entry; j++) {
3665 OS_REG_WRITE(ah, cl_tab_reg, ichan->tx_clcal[ch_idx][j]);
3669 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3670 "(FCS) TX CL CAL applied - %d\n", ichan->channel);
3672 else if (is_cal_reusable && clc_success) {
3673 /* save CL cal results */
3674 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3675 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3678 cl_tab_reg = BB_cl_tab_b[ch_idx];
3679 for (j = 0; j < BB_cl_tab_entry; j++) {
3680 ichan->tx_clcal[ch_idx][j] = OS_REG_READ(ah, cl_tab_reg);
3684 ichan->one_time_txclcal_done = AH_TRUE;
3685 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3686 "(FCS) TX CL CAL saved - %d\n", ichan->channel);
3689 #endif /* ATH_SUPPORT_CAL_REUSE */
3691 /* Revert chainmasks to their original values before NF cal */
3692 ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
3694 #if !FIX_NOISE_FLOOR
3696 * Do NF calibration after DC offset and other CALs.
3697 * Per system engineers, noise floor value can sometimes be 20 dB
3698 * higher than normal value if DC offset and noise floor cal are
3699 * triggered at the same time.
3701 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3702 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
3705 /* Initialize list pointers */
3706 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3709 * Enable IQ, ADC Gain, ADC DC Offset Cals
3711 /* Setup all non-periodic, init time only calibrations */
3712 /* XXX: Init DC Offset not working yet */
3714 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, ADC_DC_INIT_CAL)) {
3715 INIT_CAL(&ahp->ah_adc_dc_cal_init_data);
3716 INSERT_CAL(ahp, &ahp->ah_adc_dc_cal_init_data);
3719 /* Initialize current pointer to first element in list */
3720 ahp->ah_cal_list_curr = ahp->ah_cal_list;
3722 if (ahp->ah_cal_list_curr) {
3723 if (ar9300_run_init_cals(ah, 0) == AH_FALSE) {
3728 /* end - Init time calibrations */
3730 /* If Cals are supported, add them to list via INIT/INSERT_CAL */
3731 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, IQ_MISMATCH_CAL)) {
3732 INIT_CAL(&ahp->ah_iq_cal_data);
3733 INSERT_CAL(ahp, &ahp->ah_iq_cal_data);
3734 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3735 "%s: enabling IQ Calibration.\n", __func__);
3737 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, TEMP_COMP_CAL)) {
3738 INIT_CAL(&ahp->ah_temp_comp_cal_data);
3739 INSERT_CAL(ahp, &ahp->ah_temp_comp_cal_data);
3740 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3741 "%s: enabling Temperature Compensation Calibration.\n", __func__);
3744 /* Initialize current pointer to first element in list */
3745 ahp->ah_cal_list_curr = ahp->ah_cal_list;
3747 /* Reset state within current cal */
3748 if (ahp->ah_cal_list_curr) {
3749 ar9300_reset_calibration(ah, ahp->ah_cal_list_curr);
3752 /* Mark all calibrations on this channel as being invalid */
3753 ichan->calValid = 0;
3758 static inline HAL_BOOL
3759 ar9300_init_cal(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3761 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
3762 HAL_BOOL do_rtt_cal = AH_TRUE;
3763 HAL_BOOL enable_rtt = AH_FALSE;
3767 return ar9300_init_cal_internal(ah, chan, ichan, enable_rtt, do_rtt_cal, skip_if_none, apply_last_iqcorr);
3770 /* ar9300_reset_cal_valid
3771 * Entry point for upper layers to restart current cal.
3772 * Reset the calibration valid bit in channel.
3775 ar9300_reset_cal_valid(struct ath_hal *ah, const struct ieee80211_channel *chan,
3776 HAL_BOOL *is_cal_done, u_int32_t cal_type)
3778 struct ath_hal_9300 *ahp = AH9300(ah);
3779 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
3780 HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr;
3782 *is_cal_done = AH_TRUE;
3784 if (curr_cal == AH_NULL) {
3787 if (ichan == AH_NULL) {
3788 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3789 "%s: invalid channel %u/0x%x; no mapping\n",
3790 __func__, chan->ic_freq, chan->ic_flags);
3794 if (!(cal_type & IQ_MISMATCH_CAL)) {
3795 *is_cal_done = AH_FALSE;
3799 /* Expected that this calibration has run before, post-reset.
3800 * Current state should be done
3802 if (curr_cal->cal_state != CAL_DONE) {
3803 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3804 "%s: Calibration state incorrect, %d\n",
3805 __func__, curr_cal->cal_state);
3809 /* Verify Cal is supported on this channel */
3810 if (ar9300_is_cal_supp(ah, chan, curr_cal->cal_data->cal_type) == AH_FALSE) {
3814 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3815 "%s: Resetting Cal %d state for channel %u/0x%x\n", __func__,
3816 curr_cal->cal_data->cal_type, chan->ic_freq, chan->ic_flags);
3818 /* Disable cal validity in channel */
3819 ichan->calValid &= ~curr_cal->cal_data->cal_type;
3820 curr_cal->cal_state = CAL_WAITING;
3821 /* Indicate to upper layers that we need polling */
3822 *is_cal_done = AH_FALSE;
3826 ar9300_set_dma(struct ath_hal *ah)
3829 struct ath_hal_9300 *ahp = AH9300(ah);
3833 * set AHB_MODE not to do cacheline prefetches
3835 regval = OS_REG_READ(ah, AR_AHB_MODE);
3836 OS_REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
3840 * let mac dma reads be in 128 byte chunks
3842 regval = OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
3843 OS_REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
3846 * Restore TX Trigger Level to its pre-reset value.
3847 * The initial value depends on whether aggregation is enabled, and is
3848 * adjusted whenever underruns are detected.
3851 OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, AH_PRIVATE(ah)->ah_tx_trig_level);
3854 * Osprey 1.0 bug (EV 61936). Don't change trigger level from .ini default.
3855 * Osprey 2.0 - hardware recommends using the default INI settings.
3858 OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, 0x3f);
3861 * let mac dma writes be in 128 byte chunks
3863 regval = OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
3864 OS_REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
3867 * Setup receive FIFO threshold to hold off TX activities
3869 OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
3872 * reduce the number of usable entries in PCU TXBUF to avoid
3873 * wrap around bugs. (bug 20428)
3876 if (AR_SREV_WASP(ah) &&
3877 (AH_PRIVATE((ah))->ah_macRev > AR_SREV_REVISION_WASP_12)) {
3878 /* Wasp 1.3 fix for EV#85395 requires usable entries
3879 * to be set to 0x500
3881 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 0x500);
3883 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE);
3887 * Enable HPQ for UAPSD
3889 if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) {
3890 OS_REG_WRITE(ah, AR_HP_Q_CONTROL,
3891 AR_HPQ_ENABLE | AR_HPQ_UAPSD | AR_HPQ_UAPSD_TRIGGER_EN);
3895 * set the transmit status ring
3897 ar9300_reset_tx_status_ring(ah);
3900 * set rxbp threshold. Must be non-zero for RX_EOL to occur.
3901 * For Osprey 2.0+, keep the original thresholds
3902 * otherwise performance is lost due to excessive RX EOL interrupts.
3904 OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1);
3905 OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1);
3908 * set receive buffer size.
3910 if (ahp->rx_buf_size) {
3911 OS_REG_WRITE(ah, AR_DATABUF, ahp->rx_buf_size);
3916 ar9300_init_bb(struct ath_hal *ah, struct ieee80211_channel *chan)
3918 u_int32_t synth_delay;
3921 * Wait for the frequency synth to settle (synth goes on
3922 * via AR_PHY_ACTIVE_EN). Read the phy active delay register.
3923 * Value is in 100ns increments.
3925 synth_delay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
3926 if (IEEE80211_IS_CHAN_CCK(chan)) {
3927 synth_delay = (4 * synth_delay) / 22;
3932 /* Activate the PHY (includes baseband activate + synthesizer on) */
3933 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
3936 * There is an issue if the AP starts the calibration before
3937 * the base band timeout completes. This could result in the
3938 * rx_clear AH_FALSE triggering. As a workaround we add delay an
3939 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
3942 OS_DELAY(synth_delay + BASE_ACTIVATE_DELAY);
3946 ar9300_init_interrupt_masks(struct ath_hal *ah, HAL_OPMODE opmode)
3948 struct ath_hal_9300 *ahp = AH9300(ah);
3949 u_int32_t msi_cfg = 0;
3950 u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
3953 * Setup interrupt handling. Note that ar9300_reset_tx_queue
3954 * manipulates the secondary IMR's as queues are enabled
3955 * and disabled. This is done with RMW ops to insure the
3956 * settings we make here are preserved.
3959 AR_IMR_TXERR | AR_IMR_TXURN |
3960 AR_IMR_RXERR | AR_IMR_RXORN |
3963 if (ahp->ah_intr_mitigation_rx) {
3964 /* enable interrupt mitigation for rx */
3965 ahp->ah_mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR | AR_IMR_RXOK_HP;
3966 msi_cfg |= AR_INTCFG_MSI_RXINTM | AR_INTCFG_MSI_RXMINTR;
3968 ahp->ah_mask_reg |= AR_IMR_RXOK_LP | AR_IMR_RXOK_HP;
3969 msi_cfg |= AR_INTCFG_MSI_RXOK;
3971 if (ahp->ah_intr_mitigation_tx) {
3972 /* enable interrupt mitigation for tx */
3973 ahp->ah_mask_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR;
3974 msi_cfg |= AR_INTCFG_MSI_TXINTM | AR_INTCFG_MSI_TXMINTR;
3976 ahp->ah_mask_reg |= AR_IMR_TXOK;
3977 msi_cfg |= AR_INTCFG_MSI_TXOK;
3979 if (opmode == HAL_M_HOSTAP) {
3980 ahp->ah_mask_reg |= AR_IMR_MIB;
3983 OS_REG_WRITE(ah, AR_IMR, ahp->ah_mask_reg);
3984 OS_REG_WRITE(ah, AR_IMR_S2, OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
3985 ahp->ah_mask2Reg = OS_REG_READ(ah, AR_IMR_S2);
3987 if (ah->ah_config.ath_hal_enable_msi) {
3988 /* Cache MSI register value */
3989 ahp->ah_msi_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI));
3990 ahp->ah_msi_reg |= AR_PCIE_MSI_HW_DBI_WR_EN;
3991 if (AR_SREV_POSEIDON(ah)) {
3992 ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
3994 ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR;
3996 /* Program MSI configuration */
3997 OS_REG_WRITE(ah, AR_INTCFG, msi_cfg);
4001 * debug - enable to see all synchronous interrupts status
4003 /* Clear any pending sync cause interrupts */
4004 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE), 0xFFFFFFFF);
4006 /* Allow host interface sync interrupt sources to set cause bit */
4007 if (AR_SREV_POSEIDON(ah)) {
4008 sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
4010 else if (AR_SREV_WASP(ah)) {
4011 sync_en_def = AR9340_INTR_SYNC_DEFAULT;
4014 AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), sync_en_def);
4016 /* _Disable_ host interface sync interrupt when cause bits set */
4017 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK), 0);
4019 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE), 0);
4020 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_MASK), 0);
4021 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_ENABLE), 0);
4022 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_MASK), 0);
4026 ar9300_init_qos(struct ath_hal *ah)
4028 OS_REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); /* XXX magic */
4029 OS_REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); /* XXX magic */
4031 /* Turn on NOACK Support for QoS packets */
4032 OS_REG_WRITE(ah, AR_QOS_NO_ACK,
4033 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
4034 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
4035 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
4038 * initialize TXOP for all TIDs
4040 OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
4041 OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
4042 OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
4043 OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
4044 OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
4048 ar9300_init_user_settings(struct ath_hal *ah)
4050 struct ath_hal_9300 *ahp = AH9300(ah);
4052 /* Restore user-specified settings */
4053 HALDEBUG(ah, HAL_DEBUG_RESET,
4054 "--AP %s ahp->ah_misc_mode 0x%x\n", __func__, ahp->ah_misc_mode);
4055 if (ahp->ah_misc_mode != 0) {
4057 AR_PCU_MISC, OS_REG_READ(ah, AR_PCU_MISC) | ahp->ah_misc_mode);
4059 if (ahp->ah_get_plcp_hdr) {
4060 OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM);
4062 if (ahp->ah_slot_time != (u_int) -1) {
4063 ar9300_set_slot_time(ah, ahp->ah_slot_time);
4065 if (ahp->ah_ack_timeout != (u_int) -1) {
4066 ar9300_set_ack_timeout(ah, ahp->ah_ack_timeout);
4068 if (AH_PRIVATE(ah)->ah_diagreg != 0) {
4069 OS_REG_SET_BIT(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
4071 if (ahp->ah_beacon_rssi_threshold != 0) {
4072 ar9300_set_hw_beacon_rssi_threshold(ah, ahp->ah_beacon_rssi_threshold);
4074 #ifdef ATH_SUPPORT_DFS
4075 if (ahp->ah_cac_quiet_enabled) {
4076 ar9300_cac_tx_quiet(ah, 1);
4078 #endif /* ATH_SUPPORT_DFS */
4082 ar9300_get_spur_info(struct ath_hal * ah, int *enable, int len, u_int16_t *freq)
4084 // struct ath_hal_private *ap = AH_PRIVATE(ah);
4087 for (i = 0; i < len; i++) {
4091 *enable = ah->ah_config.ath_hal_spur_mode;
4092 for (i = 0, j = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4093 if (AH9300(ah)->ath_hal_spur_chans[i][0] != AR_NO_SPUR) {
4094 freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][0];
4095 HALDEBUG(ah, HAL_DEBUG_ANI,
4096 "1. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][0]);
4098 if (AH9300(ah)->ath_hal_spur_chans[i][1] != AR_NO_SPUR) {
4099 freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][1];
4100 HALDEBUG(ah, HAL_DEBUG_ANI,
4101 "2. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][1]);
4108 #define ATH_HAL_2GHZ_FREQ_MIN 20000
4109 #define ATH_HAL_2GHZ_FREQ_MAX 29999
4110 #define ATH_HAL_5GHZ_FREQ_MIN 50000
4111 #define ATH_HAL_5GHZ_FREQ_MAX 59999
4115 ar9300_set_spur_info(struct ath_hal * ah, int enable, int len, u_int16_t *freq)
4117 struct ath_hal_private *ap = AH_PRIVATE(ah);
4120 ap->ah_config.ath_hal_spur_mode = enable;
4122 if (ap->ah_config.ath_hal_spur_mode == SPUR_ENABLE_IOCTL) {
4123 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4124 AH9300(ah)->ath_hal_spur_chans[i][0] = AR_NO_SPUR;
4125 AH9300(ah)->ath_hal_spur_chans[i][1] = AR_NO_SPUR;
4127 for (i = 0, j = 0, k = 0; i < len; i++) {
4128 if (freq[i] > ATH_HAL_2GHZ_FREQ_MIN &&
4129 freq[i] < ATH_HAL_2GHZ_FREQ_MAX)
4132 if (j < AR_EEPROM_MODAL_SPURS) {
4133 AH9300(ah)->ath_hal_spur_chans[j++][1] = freq[i];
4134 HALDEBUG(ah, HAL_DEBUG_ANI, "1 set spur %d\n", freq[i]);
4136 } else if (freq[i] > ATH_HAL_5GHZ_FREQ_MIN &&
4137 freq[i] < ATH_HAL_5GHZ_FREQ_MAX)
4140 if (k < AR_EEPROM_MODAL_SPURS) {
4141 AH9300(ah)->ath_hal_spur_chans[k++][0] = freq[i];
4142 HALDEBUG(ah, HAL_DEBUG_ANI, "2 set spur %d\n", freq[i]);
4152 #define ar9300_check_op_mode(_opmode) \
4153 ((_opmode == HAL_M_STA) || (_opmode == HAL_M_IBSS) ||\
4154 (_opmode == HAL_M_HOSTAP) || (_opmode == HAL_M_MONITOR))
4159 #ifndef ATH_NF_PER_CHAN
4161 * To fixed first reset noise floor value not correct issue
4162 * For ART need it to fixed low rate sens too low issue
4165 First_NFCal(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
4166 int is_scan, struct ieee80211_channel *chan)
4168 HAL_NFCAL_HIST_FULL *nfh;
4170 int16_t nfarray[HAL_NUM_NF_READINGS] = {0};
4175 int16_t nf_buf[HAL_NUM_NF_READINGS];
4176 #define IS(_c, _f) (((_c)->channel_flags & _f) || 0)
4180 chan->ic_freq == AH_PRIVATE(ah)->ah_curchan->ic_freq)
4182 nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4184 nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4187 ar9300_start_nf_cal(ah);
4188 for (j = 0; j < 10000; j++) {
4189 if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){
4195 is_2g = IEEE80211_IS_CHAN_2GHZ(chan);
4196 ar9300_upload_noise_floor(ah, is_2g, nfarray);
4200 * This channel's NF cal info is just a HAL_NFCAL_HIST_SMALL struct
4201 * rather than a HAL_NFCAL_HIST_FULL struct.
4202 * As long as we only use the first history element of nf_cal_buffer
4203 * (nf_cal_buffer[0][0:HAL_NUM_NF_READINGS-1]), we can use
4204 * HAL_NFCAL_HIST_SMALL and HAL_NFCAL_HIST_FULL interchangeably.
4206 nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4207 nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
4209 nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4210 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
4213 for (i = 0; i < HAL_NUM_NF_READINGS; i ++) {
4214 for (k = 0; k < HAL_NF_CAL_HIST_LEN_FULL; k++) {
4215 nfh->nf_cal_buffer[k][i] = nfarray[i];
4217 nfh->base.priv_nf[i] = ar9300_limit_nf_range(ah,
4218 ar9300_get_nf_hist_mid(ah, nfh, i, nf_hist_len));
4222 //ar9300StoreNewNf(ah, ichan, is_scan);
4225 * See if the NF value from the old channel should be
4226 * retained when switching to a new channel.
4227 * TBD: this may need to be changed, as it wipes out the
4228 * purpose of saving NF values for each channel.
4230 for (i = 0; i < HAL_NUM_NF_READINGS; i++)
4232 if (IEEE80211_IS_CHAN_2GHZ(chan))
4234 if (nfh->nf_cal_buffer[0][i] <
4235 AR_PHY_CCA_MAX_GOOD_VAL_OSPREY_2GHZ)
4237 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4238 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4241 if (AR_SREV_AR9580(ah)) {
4242 if (nfh->nf_cal_buffer[0][i] <
4243 AR_PHY_CCA_NOM_VAL_PEACOCK_5GHZ)
4245 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4246 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4249 if (nfh->nf_cal_buffer[0][i] <
4250 AR_PHY_CCA_NOM_VAL_OSPREY_5GHZ)
4252 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4253 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4259 * Copy the channel's NF buffer, which may have been modified
4260 * just above here, to the full NF history buffer.
4262 ar9300_reset_nf_hist_buff(ah, ichan);
4263 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
4264 ar9300_load_nf(ah, nf_buf);
4276 * Places the device in and out of reset and then places sane
4277 * values in the registers based on EEPROM config, initialization
4278 * vectors (as determined by the mode), and station configuration
4280 * b_channel_change is used to preserve DMA/PCU registers across
4281 * a HW Reset during channel change.
4284 ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan,
4285 HAL_HT_MACMODE macmode, u_int8_t txchainmask, u_int8_t rxchainmask,
4286 HAL_HT_EXTPROTSPACING extprotspacing, HAL_BOOL b_channel_change,
4287 HAL_STATUS *status, int is_scan)
4289 #define FAIL(_code) do { ecode = _code; goto bad; } while (0)
4290 u_int32_t save_led_state;
4291 struct ath_hal_9300 *ahp = AH9300(ah);
4292 struct ath_hal_private *ap = AH_PRIVATE(ah);
4293 HAL_CHANNEL_INTERNAL *ichan;
4294 //const struct ieee80211_channel *curchan = ap->ah_curchan;
4296 HAL_BOOL save_full_sleep = ahp->ah_chip_full_sleep;
4298 u_int32_t save_def_antenna;
4299 u_int32_t mac_sta_id1;
4301 int i, rx_chainmask;
4302 int nf_hist_buff_reset = 0;
4303 int16_t nf_buf[HAL_NUM_NF_READINGS];
4304 #ifdef ATH_FORCE_PPM
4305 u_int32_t save_force_val, tmp_reg;
4307 HAL_BOOL stopped, cal_ret;
4308 HAL_BOOL apply_last_iqcorr = AH_FALSE;
4310 if (OS_REG_READ(ah, AR_IER) == AR_IER_ENABLE) {
4311 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "** Reset called with WLAN "
4312 "interrupt enabled %08x **\n", ar9300_get_interrupts(ah));
4316 * Set the status to "ok" by default to cover the cases
4317 * where we return AH_FALSE without going to "bad"
4321 if ((ah->ah_config.ath_hal_sta_update_tx_pwr_enable)) {
4322 AH9300(ah)->green_tx_status = HAL_RSSI_TX_POWER_NONE;
4326 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
4327 (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)))
4329 ar9300_mci_2g5g_changed(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4333 ahp->ah_ext_prot_spacing = extprotspacing;
4334 ahp->ah_tx_chainmask = txchainmask & ap->ah_caps.halTxChainMask;
4335 ahp->ah_rx_chainmask = rxchainmask & ap->ah_caps.halRxChainMask;
4336 ahp->ah_tx_cal_chainmask = ap->ah_caps.halTxChainMask;
4337 ahp->ah_rx_cal_chainmask = ap->ah_caps.halRxChainMask;
4338 HALASSERT(ar9300_check_op_mode(opmode));
4340 OS_MARK(ah, AH_MARK_RESET, b_channel_change);
4343 * Map public channel to private.
4345 ichan = ar9300_check_chan(ah, chan);
4346 if (ichan == AH_NULL) {
4347 HALDEBUG(ah, HAL_DEBUG_CHANNEL,
4348 "%s: invalid channel %u/0x%x; no mapping\n",
4349 __func__, chan->ic_freq, chan->ic_flags);
4353 ichan->paprd_table_write_done = 0; /* Clear PAPRD table write flag */
4355 chan->paprd_table_write_done = 0; /* Clear PAPRD table write flag */
4358 if (ar9300_get_power_mode(ah) != HAL_PM_FULL_SLEEP) {
4359 /* Need to stop RX DMA before reset otherwise chip might hang */
4360 stopped = ar9300_set_rx_abort(ah, AH_TRUE); /* abort and disable PCU */
4361 ar9300_set_rx_filter(ah, 0);
4362 stopped &= ar9300_stop_dma_receive(ah, 0); /* stop and disable RX DMA */
4365 * During the transition from full sleep to reset,
4366 * recv DMA regs are not available to be read
4368 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4369 "%s[%d]: ar9300_stop_dma_receive failed\n", __func__, __LINE__);
4370 b_channel_change = AH_FALSE;
4373 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4374 "%s[%d]: Chip is already in full sleep\n", __func__, __LINE__);
4378 if ((AH_PRIVATE(ah)->ah_caps.halMciSupport) &&
4379 (ahp->ah_mci_bt_state == MCI_BT_CAL_START))
4381 u_int32_t payload[4] = {0, 0, 0, 0};
4383 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4384 "(MCI) %s: Stop rx for BT cal.\n", __func__);
4385 ahp->ah_mci_bt_state = MCI_BT_CAL;
4388 * MCIFIX: disable mci interrupt here. This is to avoid SW_MSG_DONE or
4389 * RX_MSG bits to trigger MCI_INT and lead to mci_intr reentry.
4391 ar9300_mci_disable_interrupt(ah);
4393 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4394 "(MCI) %s: Send WLAN_CAL_GRANT\n", __func__);
4395 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
4396 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
4398 /* Wait BT calibration to be completed for 25ms */
4399 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4400 "(MCI) %s: BT is calibrating.\n", __func__);
4401 if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE, 0, 25000)) {
4402 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4403 "(MCI) %s: Got BT_CAL_DONE.\n", __func__);
4406 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4407 "(MCI) %s: ### BT cal takes too long. Force bt_state to be bt_awake.\n",
4410 ahp->ah_mci_bt_state = MCI_BT_AWAKE;
4411 /* MCIFIX: enable mci interrupt here */
4412 ar9300_mci_enable_interrupt(ah);
4418 /* Bring out of sleep mode */
4419 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
4420 *status = HAL_INV_PMODE;
4424 /* Check the Rx mitigation config again, it might have changed
4425 * during attach in ath_vap_attach.
4427 if (ah->ah_config.ath_hal_intr_mitigation_rx != 0) {
4428 ahp->ah_intr_mitigation_rx = AH_TRUE;
4430 ahp->ah_intr_mitigation_rx = AH_FALSE;
4436 * This is painful because we don't have a non-const channel pointer
4439 * Make sure this gets fixed!
4442 /* Get the value from the previous NF cal and update history buffer */
4443 if (curchan && (ahp->ah_chip_full_sleep != AH_TRUE)) {
4444 ar9300_store_new_nf(ah, curchan, is_scan);
4449 * Account for the effect of being in either the 2 GHz or 5 GHz band
4450 * on the nominal, max allowable, and min allowable noise floor values.
4452 AH9300(ah)->nfp = IS_CHAN_2GHZ(ichan) ? &ahp->nf_2GHz : &ahp->nf_5GHz;
4455 * XXX For now, don't apply the last IQ correction.
4457 * This should be done when scorpion is enabled on FreeBSD; just be
4458 * sure to fix this channel match code so it uses net80211 flags
4462 if (AR_SREV_SCORPION(ah) && curchan && (chan->channel == curchan->channel) &&
4463 ((chan->channel_flags & (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)) ==
4464 (curchan->channel_flags &
4465 (CHANNEL_ALL | CHANNEL_HALF | CHANNEL_QUARTER)))) {
4466 apply_last_iqcorr = AH_TRUE;
4469 apply_last_iqcorr = AH_FALSE;
4472 #ifndef ATH_NF_PER_CHAN
4474 * If there's only one full-size home-channel NF history buffer
4475 * rather than a full-size NF history buffer per channel, decide
4476 * whether to (re)initialize the home-channel NF buffer.
4477 * If this is just a channel change for a scan, or if the channel
4478 * is not being changed, don't mess up the home channel NF history
4479 * buffer with NF values from this scanned channel. If we're
4480 * changing the home channel to a new channel, reset the home-channel
4481 * NF history buffer with the most accurate NF known for the new channel.
4483 if (!is_scan && (!ap->ah_curchan ||
4484 ap->ah_curchan->ic_freq != chan->ic_freq)) // ||
4485 // ap->ah_curchan->channel_flags != chan->channel_flags))
4487 nf_hist_buff_reset = 1;
4488 ar9300_reset_nf_hist_buff(ah, ichan);
4492 * Fast channel change (Change synthesizer based on channel freq
4493 * without resetting chip)
4496 * - Chip is just coming out of full sleep
4497 * - Channel to be set is same as current channel
4498 * - Channel flags are different, like when moving from 2GHz to 5GHz
4500 * - Merlin: Switching in/out of fast clock enabled channels
4501 * (not currently coded, since fast clock is enabled
4502 * across the 5GHz band
4503 * and we already do a full reset when switching in/out
4507 if (b_channel_change &&
4508 (ahp->ah_chip_full_sleep != AH_TRUE) &&
4509 (AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4510 ((chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
4511 (((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & chan->channel_flags) ==
4512 ((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & AH_PRIVATE(ah)->ah_curchan->channel_flags))))
4514 if (ar9300_channel_change(ah, chan, ichan, macmode)) {
4515 chan->channel_flags = ichan->channel_flags;
4516 chan->priv_flags = ichan->priv_flags;
4517 AH_PRIVATE(ah)->ah_curchan->ah_channel_time = 0;
4518 AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar9300_get_tsf64(ah);
4521 * Load the NF from history buffer of the current channel.
4522 * NF is slow time-variant, so it is OK to use a historical value.
4524 ar9300_get_nf_hist_base(ah,
4525 AH_PRIVATE(ah)->ah_curchan, is_scan, nf_buf);
4526 ar9300_load_nf(ah, nf_buf);
4528 /* start NF calibration, without updating BB NF register*/
4529 ar9300_start_nf_cal(ah);
4532 * If channel_change completed and DMA was stopped
4533 * successfully - skip the rest of reset
4535 if (AH9300(ah)->ah_dma_stuck != AH_TRUE) {
4536 WAR_USB_DISABLE_PLL_LOCK_DETECT(ah);
4538 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready)
4540 ar9300_mci_2g5g_switch(ah, AH_TRUE);
4550 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4551 ar9300_mci_disable_interrupt(ah);
4552 if (ahp->ah_mci_ready && !save_full_sleep) {
4553 ar9300_mci_mute_bt(ah);
4555 OS_REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
4558 ahp->ah_mci_bt_state = MCI_BT_SLEEP;
4559 ahp->ah_mci_ready = AH_FALSE;
4563 AH9300(ah)->ah_dma_stuck = AH_FALSE;
4564 #ifdef ATH_FORCE_PPM
4565 /* Preserve force ppm state */
4567 OS_REG_READ(ah, AR_PHY_TIMING2) &
4568 (AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4571 * Preserve the antenna on a channel change
4573 save_def_antenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
4574 if (0 == ahp->ah_smartantenna_enable )
4576 if (save_def_antenna == 0) {
4577 save_def_antenna = 1;
4581 /* Save hardware flag before chip reset clears the register */
4582 mac_sta_id1 = OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
4584 /* Save led state from pci config register */
4585 save_led_state = OS_REG_READ(ah, AR_CFG_LED) &
4586 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
4587 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
4589 /* Mark PHY inactive prior to reset, to be undone in ar9300_init_bb () */
4590 ar9300_mark_phy_inactive(ah);
4592 if (!ar9300_chip_reset(ah, chan)) {
4593 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: chip reset failed\n", __func__);
4597 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4602 AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
4605 * Note that ar9300_init_chain_masks() is called from within
4606 * ar9300_process_ini() to ensure the swap bit is set before
4607 * the pdadc table is written.
4609 ecode = ar9300_process_ini(ah, chan, ichan, macmode);
4610 if (ecode != HAL_OK) {
4614 ahp->ah_immunity_on = AH_FALSE;
4616 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
4617 ahp->tx_iq_cal_enable = OS_REG_READ_FIELD(ah,
4618 AR_PHY_TX_IQCAL_CONTROL_0(ah),
4619 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL) ?
4622 ahp->tx_cl_cal_enable = (OS_REG_READ(ah, AR_PHY_CL_CAL_CTL) &
4623 AR_PHY_CL_CAL_ENABLE) ? 1 : 0;
4625 /* For devices with full HW RIFS Rx support (Sowl/Howl/Merlin, etc),
4626 * restore register settings from prior to reset.
4628 if ((AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4629 (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK))
4631 /* Re-program RIFS Rx policy after reset */
4632 ar9300_set_rifs_delay(ah, ahp->ah_rifs_enabled);
4636 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4637 ar9300_mci_reset(ah, AH_FALSE, IS_CHAN_2GHZ(ichan), save_full_sleep);
4641 /* Initialize Management Frame Protection */
4642 ar9300_init_mfp(ah);
4644 ahp->ah_immunity_vals[0] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4645 AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
4646 ahp->ah_immunity_vals[1] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4647 AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
4648 ahp->ah_immunity_vals[2] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4649 AR_PHY_SFCORR_M1_THRESH);
4650 ahp->ah_immunity_vals[3] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4651 AR_PHY_SFCORR_M2_THRESH);
4652 ahp->ah_immunity_vals[4] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4653 AR_PHY_SFCORR_M2COUNT_THR);
4654 ahp->ah_immunity_vals[5] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4655 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
4657 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
4658 if (IEEE80211_IS_CHAN_OFDM(chan) || IEEE80211_IS_CHAN_HT(chan)) {
4659 ar9300_set_delta_slope(ah, chan);
4662 ar9300_spur_mitigate(ah, chan);
4663 if (!ar9300_eeprom_set_board_values(ah, chan)) {
4664 HALDEBUG(ah, HAL_DEBUG_EEPROM,
4665 "%s: error setting board options\n", __func__);
4669 #ifdef ATH_HAL_WAR_REG16284_APH128
4670 /* temp work around, will be removed. */
4671 if (AR_SREV_WASP(ah)) {
4672 OS_REG_WRITE(ah, 0x16284, 0x1553e000);
4676 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4678 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
4679 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
4681 | AR_STA_ID1_RTS_USE_DEF
4682 | (ah->ah_config.ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0)
4683 | ahp->ah_sta_id1_defaults
4685 ar9300_set_operating_mode(ah, opmode);
4687 /* Set Venice BSSID mask according to current state */
4688 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssid_mask));
4689 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssid_mask + 4));
4691 /* Restore previous antenna */
4692 OS_REG_WRITE(ah, AR_DEF_ANTENNA, save_def_antenna);
4693 #ifdef ATH_FORCE_PPM
4694 /* Restore force ppm state */
4695 tmp_reg = OS_REG_READ(ah, AR_PHY_TIMING2) &
4696 ~(AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4697 OS_REG_WRITE(ah, AR_PHY_TIMING2, tmp_reg | save_force_val);
4700 /* then our BSSID and assocID */
4701 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
4702 OS_REG_WRITE(ah, AR_BSS_ID1,
4703 LE_READ_2(ahp->ah_bssid + 4) |
4704 ((ahp->ah_assoc_id & 0x3fff) << AR_BSS_ID1_AID_S));
4706 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
4708 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, INIT_RSSI_THR);
4710 /* HW beacon processing */
4712 * XXX what happens if I just leave filter_interval=0?
4713 * it stays disabled?
4715 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_BCN_WEIGHT,
4716 INIT_RSSI_BEACON_WEIGHT);
4717 OS_REG_SET_BIT(ah, AR_HWBCNPROC1, AR_HWBCNPROC1_CRC_ENABLE |
4718 AR_HWBCNPROC1_EXCLUDE_TIM_ELM);
4719 if (ah->ah_config.ath_hal_beacon_filter_interval) {
4720 OS_REG_RMW_FIELD(ah, AR_HWBCNPROC2, AR_HWBCNPROC2_FILTER_INTERVAL,
4721 ah->ah_config.ath_hal_beacon_filter_interval);
4722 OS_REG_SET_BIT(ah, AR_HWBCNPROC2,
4723 AR_HWBCNPROC2_FILTER_INTERVAL_ENABLE);
4728 * Set Channel now modifies bank 6 parameters for FOWL workaround
4729 * to force rf_pwd_icsyndiv bias current as function of synth
4730 * frequency.Thus must be called after ar9300_process_ini() to ensure
4731 * analog register cache is valid.
4733 if (!ahp->ah_rf_hal.set_channel(ah, chan)) {
4738 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4740 /* Set 1:1 QCU to DCU mapping for all queues */
4741 for (i = 0; i < AR_NUM_DCU; i++) {
4742 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
4745 ahp->ah_intr_txqs = 0;
4746 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) {
4747 ar9300_reset_tx_queue(ah, i);
4750 ar9300_init_interrupt_masks(ah, opmode);
4752 /* Reset ier reference count to disabled */
4753 // OS_ATOMIC_SET(&ahp->ah_ier_ref_count, 1);
4754 if (ath_hal_isrfkillenabled(ah)) {
4755 ar9300_enable_rf_kill(ah);
4758 /* must be called AFTER ini is processed */
4759 ar9300_ani_init_defaults(ah, macmode);
4761 ar9300_init_qos(ah);
4763 ar9300_init_user_settings(ah);
4766 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
4768 OS_MARK(ah, AH_MARK_RESET_DONE, 0);
4771 * disable seq number generation in hw
4773 OS_REG_WRITE(ah, AR_STA_ID1,
4774 OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
4779 * program OBS bus to see MAC interrupts
4782 if (!AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4783 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
4786 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
4790 /* enabling AR_GTTM_IGNORE_IDLE in GTTM register so that
4791 GTT timer will not increment if the channel idle indicates
4792 the air is busy or NAV is still counting down */
4793 OS_REG_WRITE(ah, AR_GTTM, AR_GTTM_IGNORE_IDLE);
4796 * GTT debug mode setting
4799 OS_REG_WRITE(ah, 0x64, 0x00320000);
4800 OS_REG_WRITE(ah, 0x68, 7);
4801 OS_REG_WRITE(ah, 0x4080, 0xC);
4804 * Disable general interrupt mitigation by setting MIRT = 0x0
4805 * Rx and tx interrupt mitigation are conditionally enabled below.
4807 OS_REG_WRITE(ah, AR_MIRT, 0);
4808 if (ahp->ah_intr_mitigation_rx) {
4810 * Enable Interrupt Mitigation for Rx.
4811 * If no build-specific limits for the rx interrupt mitigation
4812 * timer have been specified, use conservative defaults.
4814 #ifndef AH_RIMT_VAL_LAST
4815 #define AH_RIMT_LAST_MICROSEC 500
4817 #ifndef AH_RIMT_VAL_FIRST
4818 #define AH_RIMT_FIRST_MICROSEC 2000
4820 #ifndef HOST_OFFLOAD
4821 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, AH_RIMT_LAST_MICROSEC);
4822 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, AH_RIMT_FIRST_MICROSEC);
4824 /* lower mitigation level to reduce latency for offload arch. */
4825 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST,
4826 (AH_RIMT_LAST_MICROSEC >> 2));
4827 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST,
4828 (AH_RIMT_FIRST_MICROSEC >> 2));
4832 if (ahp->ah_intr_mitigation_tx) {
4834 * Enable Interrupt Mitigation for Tx.
4835 * If no build-specific limits for the tx interrupt mitigation
4836 * timer have been specified, use the values preferred for
4837 * the carrier group's products.
4839 #ifndef AH_TIMT_LAST
4840 #define AH_TIMT_LAST_MICROSEC 300
4842 #ifndef AH_TIMT_FIRST
4843 #define AH_TIMT_FIRST_MICROSEC 750
4845 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, AH_TIMT_LAST_MICROSEC);
4846 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, AH_TIMT_FIRST_MICROSEC);
4849 rx_chainmask = ahp->ah_rx_chainmask;
4851 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
4852 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
4854 ar9300_init_bb(ah, chan);
4856 /* BB Step 7: Calibration */
4857 ar9300_invalidate_saved_cals(ah, ichan);
4858 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr);
4861 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {
4862 if (IS_CHAN_2GHZ(ichan) &&
4863 (ahp->ah_mci_bt_state == MCI_BT_SLEEP))
4865 if (ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
4866 ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE))
4869 * BT is sleeping. Check if BT wakes up duing WLAN
4870 * calibration. If BT wakes up during WLAN calibration, need
4871 * to go through all message exchanges again and recal.
4873 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4874 "(MCI) ### %s: BT wakes up during WLAN calibration.\n",
4876 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
4877 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
4878 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
4879 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) send REMOTE_RESET\n");
4880 ar9300_mci_remote_reset(ah, AH_TRUE);
4881 ar9300_mci_send_sys_waking(ah, AH_TRUE);
4883 if (IS_CHAN_2GHZ(ichan)) {
4884 ar9300_mci_send_lna_transfer(ah, AH_TRUE);
4886 ahp->ah_mci_bt_state = MCI_BT_AWAKE;
4888 /* Redo calibration */
4889 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Re-calibrate.\n",
4891 ar9300_invalidate_saved_cals(ah, ichan);
4892 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr);
4895 ar9300_mci_enable_interrupt(ah);
4900 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Init Cal Failed\n", __func__);
4901 FAIL(HAL_ESELFTEST);
4904 ar9300_init_txbf(ah);
4907 * WAR for owl 1.0 - restore chain mask for 2-chain cfgs after cal
4909 rx_chainmask = ahp->ah_rx_chainmask;
4910 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
4911 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
4912 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
4916 /* Restore previous led state */
4917 OS_REG_WRITE(ah, AR_CFG_LED, save_led_state | AR_CFG_SCLK_32KHZ);
4920 if (ahp->ah_bt_coex_config_type != HAL_BT_COEX_CFG_NONE) {
4921 ar9300_init_bt_coex(ah);
4924 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {
4925 /* Check BT state again to make sure it's not changed. */
4926 ar9300_mci_sync_bt_state(ah);
4927 ar9300_mci_2g5g_switch(ah, AH_TRUE);
4929 if ((ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
4930 (ahp->ah_mci_query_bt == AH_TRUE))
4932 ahp->ah_mci_need_flush_btinfo = AH_TRUE;
4939 /* Start TSF2 for generic timer 8-15. */
4940 ar9300_start_tsf2(ah);
4942 /* MIMO Power save setting */
4943 if (ar9300_get_capability(ah, HAL_CAP_DYNAMIC_SMPS, 0, AH_NULL) == HAL_OK) {
4944 ar9300_set_sm_power_mode(ah, ahp->ah_sm_power_mode);
4948 * For big endian systems turn on swapping for descriptors
4950 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
4951 if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
4952 OS_REG_RMW(ah, AR_CFG, AR_CFG_SWTB | AR_CFG_SWRB, 0);
4954 ar9300_init_cfg_reg(ah);
4958 if ( AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
4959 OS_REG_RMW(ah, AR_CFG_LED, AR_CFG_LED_ASSOC_CTL, AR_CFG_LED_ASSOC_CTL);
4962 #if !(defined(ART_BUILD)) && defined(ATH_SUPPORT_LED)
4963 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
4964 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
4965 #define ATH_GPIO_OUT_FUNCTION3 0xB8040038
4966 #define ATH_GPIO_OE 0xB8040000
4967 if ( AR_SREV_WASP(ah)) {
4968 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
4969 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x33 << 8) );
4970 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )));
4974 /* Disable 2G WLAN LED. During ath_open, reset function is called even before channel is set.
4975 So 2GHz is taken as default and it also blinks. Hence
4976 to avoid both from blinking, disable 2G led while in 5G mode */
4978 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) | (1 << 13) ));
4979 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x33) );
4980 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )));
4984 else if (AR_SREV_SCORPION(ah)) {
4985 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
4986 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x2F << 8) );
4987 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )) | (0x1 << 12)));
4988 } else if (IS_CHAN_5GHZ((AH_PRIVATE(ah)->ah_curchan))) {
4989 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x2F) );
4990 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )) | (0x1 << 13)));
4997 /* XXX FreeBSD What's this? -adrian */
4999 chan->channel_flags = ichan->channel_flags;
5000 chan->priv_flags = ichan->priv_flags;
5004 /* XXX FreeBSD is ichan appropariate? It was curchan.. */
5005 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
5006 ar9300_load_nf(ah, nf_buf);
5007 if (nf_hist_buff_reset == 1)
5009 nf_hist_buff_reset = 0;
5010 #ifndef ATH_NF_PER_CHAN
5011 if (First_NFCal(ah, ichan, is_scan, chan)){
5013 #endif /* ATH_NF_PER_CHAN */
5016 ar9300_start_nf_cal(ah);
5020 #ifdef AH_SUPPORT_AR9300
5021 /* BB Panic Watchdog */
5022 if (ar9300_get_capability(ah, HAL_CAP_BB_PANIC_WATCHDOG, 0, AH_NULL) ==
5025 ar9300_config_bb_panic_watchdog(ah);
5029 /* While receiving unsupported rate frame receive state machine
5030 * gets into a state 0xb and if phy_restart happens when rx
5031 * state machine is in 0xb state, BB would go hang, if we
5032 * see 0xb state after first bb panic, make sure that we
5033 * disable the phy_restart.
5035 * There may be multiple panics, make sure that we always do
5036 * this if we see this panic at least once. This is required
5037 * because reset seems to be writing from INI file.
5039 if ((ar9300_get_capability(ah, HAL_CAP_PHYRESTART_CLR_WAR, 0, AH_NULL)
5040 == HAL_OK) && (((MS((AH9300(ah)->ah_bb_panic_last_status),
5041 AR_PHY_BB_WD_RX_OFDM_SM)) == 0xb) ||
5042 AH9300(ah)->ah_phyrestart_disabled) )
5044 ar9300_disable_phy_restart(ah, 1);
5049 ahp->ah_radar1 = MS(OS_REG_READ(ah, AR_PHY_RADAR_1),
5050 AR_PHY_RADAR_1_CF_BIN_THRESH);
5051 ahp->ah_dc_offset = MS(OS_REG_READ(ah, AR_PHY_TIMING2),
5052 AR_PHY_TIMING2_DC_OFFSET);
5053 ahp->ah_disable_cck = MS(OS_REG_READ(ah, AR_PHY_MODE),
5054 AR_PHY_MODE_DISABLE_CCK);
5056 if (AH9300(ah)->ah_enable_keysearch_always) {
5057 ar9300_enable_keysearch_always(ah, 1);
5060 #if ATH_LOW_POWER_ENABLE
5061 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val)
5062 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
5063 if (AR_SREV_OSPREY(ah)) {
5064 REG_WRITE(0xb4000080, REG_READ(0xb4000080) | 3);
5065 OS_REG_WRITE(ah, AR_RTC_RESET, 1);
5066 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL),
5067 AR_PCIE_PM_CTRL_ENA);
5068 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_SPARE), 0xffffffff);
5072 #endif /* ATH_LOW_POWER_ENABLE */
5074 WAR_USB_DISABLE_PLL_LOCK_DETECT(ah);
5077 ar9300_control_signals_for_green_tx_mode(ah);
5078 /* Smart Antenna, only for 5GHz on Scropion */
5079 if (IEEE80211_IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan)) && AR_SREV_SCORPION(ah)) {
5080 ahp->ah_smartantenna_enable = 0;
5083 ar9300_set_smart_antenna(ah, ahp->ah_smartantenna_enable);
5088 OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
5096 ar9300_green_ap_ps_on_off( struct ath_hal *ah, u_int16_t on_off)
5098 /* Set/reset the ps flag */
5099 AH9300(ah)->green_ap_ps_on = !!on_off;
5103 * This function returns 1, where it is possible to do
5104 * single-chain power save.
5107 ar9300_is_single_ant_power_save_possible(struct ath_hal *ah)
5112 /* To avoid compilation warnings. Functions not used when EMULATION. */
5114 * ar9300_find_mag_approx()
5117 ar9300_find_mag_approx(struct ath_hal *ah, int32_t in_re, int32_t in_im)
5119 int32_t abs_i = abs(in_re);
5120 int32_t abs_q = abs(in_im);
5121 int32_t max_abs, min_abs;
5123 if (abs_i > abs_q) {
5131 return (max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4));
5135 * ar9300_solve_iq_cal()
5136 * solve 4x4 linear equation used in loopback iq cal.
5139 ar9300_solve_iq_cal(
5149 int32_t solved_eq[])
5151 int32_t f1 = cos_2phi_1 - cos_2phi_2;
5152 int32_t f3 = sin_2phi_1 - sin_2phi_2;
5154 int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5155 const int32_t result_shift = 1 << 15;
5157 f2 = (((int64_t)f1 * (int64_t)f1) / result_shift) + (((int64_t)f3 * (int64_t)f3) / result_shift);
5160 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Divide by 0(%d).\n",
5161 __func__, __LINE__);
5165 /* magnitude mismatch, tx */
5166 mag_tx = f1 * (mag_a0_d0 - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
5167 /* phase mismatch, tx */
5168 phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
5170 mag_tx = (mag_tx / f2);
5171 phs_tx = (phs_tx / f2);
5173 /* magnitude mismatch, rx */
5175 mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) / result_shift;
5176 /* phase mismatch, rx */
5178 phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) / result_shift;
5180 solved_eq[0] = mag_tx;
5181 solved_eq[1] = phs_tx;
5182 solved_eq[2] = mag_rx;
5183 solved_eq[3] = phs_rx;
5189 * ar9300_calc_iq_corr()
5192 ar9300_calc_iq_corr(struct ath_hal *ah, int32_t chain_idx,
5193 const int32_t iq_res[], int32_t iqc_coeff[])
5195 int32_t i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0;
5196 int32_t i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1;
5197 int32_t i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0;
5198 int32_t i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
5199 int32_t mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1;
5200 int32_t phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1;
5201 int32_t sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2;
5202 int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5203 int32_t solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx;
5204 int32_t q_q_coff, q_i_coff;
5205 const int32_t res_scale = 1 << 15;
5206 const int32_t delpt_shift = 1 << 8;
5209 i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
5210 i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
5211 iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
5213 if (i2_m_q2_a0_d0 > 0x800) {
5214 i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
5216 if (iq_corr_a0_d0 > 0x800) {
5217 iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
5220 i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
5221 i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
5222 iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
5224 if (i2_m_q2_a0_d1 > 0x800) {
5225 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
5227 if (iq_corr_a0_d1 > 0x800) {
5228 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
5231 i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
5232 i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
5233 iq_corr_a1_d0 = iq_res[4] & 0xfff;
5235 if (i2_m_q2_a1_d0 > 0x800) {
5236 i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
5238 if (iq_corr_a1_d0 > 0x800) {
5239 iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
5242 i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
5243 i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
5244 iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
5246 if (i2_m_q2_a1_d1 > 0x800) {
5247 i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
5249 if (iq_corr_a1_d1 > 0x800) {
5250 iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
5253 if ((i2_p_q2_a0_d0 == 0) ||
5254 (i2_p_q2_a0_d1 == 0) ||
5255 (i2_p_q2_a1_d0 == 0) ||
5256 (i2_p_q2_a1_d1 == 0)) {
5257 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5258 "%s: Divide by 0(%d):\na0_d0=%d\na0_d1=%d\na2_d0=%d\na1_d1=%d\n",
5260 i2_p_q2_a0_d0, i2_p_q2_a0_d1, i2_p_q2_a1_d0, i2_p_q2_a1_d1);
5264 if ((i2_p_q2_a0_d0 <= 1024) || (i2_p_q2_a0_d0 > 2047) ||
5265 (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) ||
5266 (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) ||
5267 (i2_p_q2_a0_d0 <= iq_corr_a0_d0) ||
5268 (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) ||
5269 (i2_p_q2_a0_d1 <= iq_corr_a0_d1) ||
5270 (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) ||
5271 (i2_p_q2_a1_d0 <= iq_corr_a1_d0) ||
5272 (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) ||
5273 (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) {
5277 mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5278 phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5280 mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5281 phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5283 mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5284 phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5286 mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5287 phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5289 /* without analog phase shift */
5290 sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
5291 /* without analog phase shift */
5292 cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
5293 /* with analog phase shift */
5294 sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
5295 /* with analog phase shift */
5296 cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
5298 /* force sin^2 + cos^2 = 1; */
5299 /* find magnitude by approximation */
5300 mag1 = ar9300_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
5301 mag2 = ar9300_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
5303 if ((mag1 == 0) || (mag2 == 0)) {
5304 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5305 "%s: Divide by 0(%d): mag1=%d, mag2=%d\n",
5306 __func__, __LINE__, mag1, mag2);
5310 /* normalization sin and cos by mag */
5311 sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
5312 cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
5313 sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
5314 cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
5316 /* calculate IQ mismatch */
5317 if (AH_FALSE == ar9300_solve_iq_cal(ah,
5318 sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2, mag_a0_d0,
5319 phs_a0_d0, mag_a1_d0, phs_a1_d0, solved_eq))
5321 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5322 "%s: Call to ar9300_solve_iq_cal failed.\n", __func__);
5326 mag_tx = solved_eq[0];
5327 phs_tx = solved_eq[1];
5328 mag_rx = solved_eq[2];
5329 phs_rx = solved_eq[3];
5331 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5332 "%s: chain %d: mag mismatch=%d phase mismatch=%d\n",
5333 __func__, chain_idx, mag_tx / res_scale, phs_tx / res_scale);
5335 if (res_scale == mag_tx) {
5336 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5337 "%s: Divide by 0(%d): mag_tx=%d, res_scale=%d\n",
5338 __func__, __LINE__, mag_tx, res_scale);
5342 /* calculate and quantize Tx IQ correction factor */
5343 mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
5344 phs_corr_tx = -phs_tx;
5346 q_q_coff = (mag_corr_tx * 128 / res_scale);
5347 q_i_coff = (phs_corr_tx * 256 / res_scale);
5349 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5350 "%s: tx chain %d: mag corr=%d phase corr=%d\n",
5351 __func__, chain_idx, q_q_coff, q_i_coff);
5353 if (q_i_coff < -63) {
5356 if (q_i_coff > 63) {
5359 if (q_q_coff < -63) {
5362 if (q_q_coff > 63) {
5366 iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
5368 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: tx chain %d: iq corr coeff=%x\n",
5369 __func__, chain_idx, iqc_coeff[0]);
5371 if (-mag_rx == res_scale) {
5372 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5373 "%s: Divide by 0(%d): mag_rx=%d, res_scale=%d\n",
5374 __func__, __LINE__, mag_rx, res_scale);
5378 /* calculate and quantize Rx IQ correction factors */
5379 mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
5380 phs_corr_rx = -phs_rx;
5382 q_q_coff = (mag_corr_rx * 128 / res_scale);
5383 q_i_coff = (phs_corr_rx * 256 / res_scale);
5385 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5386 "%s: rx chain %d: mag corr=%d phase corr=%d\n",
5387 __func__, chain_idx, q_q_coff, q_i_coff);
5389 if (q_i_coff < -63) {
5392 if (q_i_coff > 63) {
5395 if (q_q_coff < -63) {
5398 if (q_q_coff > 63) {
5402 iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
5404 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: rx chain %d: iq corr coeff=%x\n",
5405 __func__, chain_idx, iqc_coeff[1]);
5410 #define MAX_MAG_DELTA 11 //maximum magnitude mismatch delta across gains
5411 #define MAX_PHS_DELTA 10 //maximum phase mismatch delta across gains
5412 #define ABS(x) ((x) >= 0 ? (x) : (-(x)))
5414 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5415 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5416 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5417 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5418 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5419 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5420 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5421 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5422 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5423 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5424 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5425 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5426 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5427 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5428 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5429 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5430 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5431 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5432 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5433 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5434 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5435 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5436 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5437 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5438 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5442 ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan, u_int32_t num_chains,
5443 struct coeff_t *coeff, HAL_BOOL is_cal_reusable)
5445 int nmeasurement, ch_idx, im;
5446 int32_t magnitude, phase;
5447 int32_t magnitude_max, phase_max;
5448 int32_t magnitude_min, phase_min;
5450 int32_t magnitude_max_idx, phase_max_idx;
5451 int32_t magnitude_min_idx, phase_min_idx;
5453 int32_t magnitude_avg, phase_avg;
5454 int32_t outlier_mag_idx = 0;
5455 int32_t outlier_phs_idx = 0;
5458 if (AR_SREV_POSEIDON(ah)) {
5459 HALASSERT(num_chains == 0x1);
5461 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5462 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5463 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5464 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5465 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5466 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5467 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5468 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5471 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5472 nmeasurement = OS_REG_READ_FIELD(ah,
5473 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
5474 if (nmeasurement > MAX_MEASUREMENT) {
5475 nmeasurement = MAX_MEASUREMENT;
5478 if (!AR_SREV_SCORPION(ah)) {
5480 * reset max/min variable to min/max values so that
5481 * we always start with 1st calibrated gain value
5483 magnitude_max = -64;
5489 magnitude_max_idx = 0;
5490 magnitude_min_idx = 0;
5494 /* detect outlier only if nmeasurement > 1 */
5495 if (nmeasurement > 1) {
5496 /* printf("----------- start outlier detection -----------\n"); */
5498 * find max/min and phase/mag mismatch across all calibrated gains
5500 for (im = 0; im < nmeasurement; im++) {
5501 magnitude = coeff->mag_coeff[ch_idx][im][0];
5502 phase = coeff->phs_coeff[ch_idx][im][0];
5504 magnitude_avg = magnitude_avg + magnitude;
5505 phase_avg = phase_avg + phase;
5506 if (magnitude > magnitude_max) {
5507 magnitude_max = magnitude;
5508 magnitude_max_idx = im;
5510 if (magnitude < magnitude_min) {
5511 magnitude_min = magnitude;
5512 magnitude_min_idx = im;
5514 if (phase > phase_max) {
5518 if (phase < phase_min) {
5523 /* find average (exclude max abs value) */
5524 for (im = 0; im < nmeasurement; im++) {
5525 magnitude = coeff->mag_coeff[ch_idx][im][0];
5526 phase = coeff->phs_coeff[ch_idx][im][0];
5527 if ((ABS(magnitude) < ABS(magnitude_max)) ||
5528 (ABS(magnitude) < ABS(magnitude_min)))
5530 magnitude_avg = magnitude_avg + magnitude;
5532 if ((ABS(phase) < ABS(phase_max)) ||
5533 (ABS(phase) < ABS(phase_min)))
5535 phase_avg = phase_avg + phase;
5538 magnitude_avg = magnitude_avg / (nmeasurement - 1);
5539 phase_avg = phase_avg / (nmeasurement - 1);
5541 /* detect magnitude outlier */
5542 if (ABS(magnitude_max - magnitude_min) > MAX_MAG_DELTA) {
5543 if (ABS(magnitude_max - magnitude_avg) >
5544 ABS(magnitude_min - magnitude_avg))
5546 /* max is outlier, force to avg */
5547 outlier_mag_idx = magnitude_max_idx;
5549 /* min is outlier, force to avg */
5550 outlier_mag_idx = magnitude_min_idx;
5552 coeff->mag_coeff[ch_idx][outlier_mag_idx][0] = magnitude_avg;
5553 coeff->phs_coeff[ch_idx][outlier_mag_idx][0] = phase_avg;
5554 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5555 "[ch%d][outlier mag gain%d]:: "
5556 "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5557 ch_idx, outlier_mag_idx, magnitude_avg, phase_avg);
5559 /* detect phase outlier */
5560 if (ABS(phase_max - phase_min) > MAX_PHS_DELTA) {
5561 if (ABS(phase_max-phase_avg) > ABS(phase_min - phase_avg)) {
5562 /* max is outlier, force to avg */
5563 outlier_phs_idx = phase_max_idx;
5565 /* min is outlier, force to avg */
5566 outlier_phs_idx = phase_min_idx;
5568 coeff->mag_coeff[ch_idx][outlier_phs_idx][0] = magnitude_avg;
5569 coeff->phs_coeff[ch_idx][outlier_phs_idx][0] = phase_avg;
5570 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5571 "[ch%d][outlier phs gain%d]:: "
5572 "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5573 ch_idx, outlier_phs_idx, magnitude_avg, phase_avg);
5578 /*printf("------------ after outlier detection -------------\n");*/
5579 for (im = 0; im < nmeasurement; im++) {
5580 magnitude = coeff->mag_coeff[ch_idx][im][0];
5581 phase = coeff->phs_coeff[ch_idx][im][0];
5584 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
5585 ch_idx, im, magnitude, phase);
5588 coeff->iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
5590 if ((im % 2) == 0) {
5591 OS_REG_RMW_FIELD(ah,
5592 tx_corr_coeff[im][ch_idx],
5593 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5594 coeff->iqc_coeff[0]);
5596 OS_REG_RMW_FIELD(ah,
5597 tx_corr_coeff[im][ch_idx],
5598 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5599 coeff->iqc_coeff[0]);
5601 #if ATH_SUPPORT_CAL_REUSE
5602 ichan->tx_corr_coeff[im][ch_idx] = coeff->iqc_coeff[0];
5605 #if ATH_SUPPORT_CAL_REUSE
5606 ichan->num_measures[ch_idx] = nmeasurement;
5610 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5611 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5612 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
5613 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
5615 #if ATH_SUPPORT_CAL_REUSE
5616 if (is_cal_reusable) {
5617 ichan->one_time_txiqcal_done = AH_TRUE;
5618 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
5619 "(FCS) TXIQCAL saved - %d\n", ichan->channel);
5624 #if ATH_SUPPORT_CAL_REUSE
5626 ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
5628 struct ath_hal_9300 *ahp = AH9300(ah);
5629 int nmeasurement, ch_idx, im;
5631 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5632 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5633 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5634 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5635 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5636 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5637 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5638 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5639 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5640 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5641 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5642 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5643 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5644 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5645 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5646 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5647 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5648 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5649 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5650 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5651 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5652 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5653 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5654 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5655 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5658 if (AR_SREV_POSEIDON(ah)) {
5659 HALASSERT(ahp->ah_tx_cal_chainmask == 0x1);
5661 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5662 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5663 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5664 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5665 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5666 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5667 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5668 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5671 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
5672 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
5675 nmeasurement = ichan->num_measures[ch_idx];
5677 for (im = 0; im < nmeasurement; im++) {
5678 if ((im % 2) == 0) {
5679 OS_REG_RMW_FIELD(ah,
5680 tx_corr_coeff[im][ch_idx],
5681 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5682 ichan->tx_corr_coeff[im][ch_idx]);
5684 OS_REG_RMW_FIELD(ah,
5685 tx_corr_coeff[im][ch_idx],
5686 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5687 ichan->tx_corr_coeff[im][ch_idx]);
5692 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5693 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5694 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
5695 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
5700 * ar9300_tx_iq_cal_hw_run is only needed for osprey/wasp/hornet
5701 * It is not needed for jupiter/poseidon.
5704 ar9300_tx_iq_cal_hw_run(struct ath_hal *ah)
5706 int is_tx_gain_forced;
5708 is_tx_gain_forced = OS_REG_READ_FIELD(ah,
5709 AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE);
5710 if (is_tx_gain_forced) {
5711 /*printf("Tx gain can not be forced during tx I/Q cal!\n");*/
5712 OS_REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE, 0);
5715 /* enable tx IQ cal */
5716 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START(ah),
5717 AR_PHY_TX_IQCAL_START_DO_CAL, AR_PHY_TX_IQCAL_START_DO_CAL);
5719 if (!ath_hal_wait(ah,
5720 AR_PHY_TX_IQCAL_START(ah), AR_PHY_TX_IQCAL_START_DO_CAL, 0))
5722 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5723 "%s: Tx IQ Cal is never completed.\n", __func__);
5730 ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
5731 int iqcal_idx, int max_iqcal,HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr)
5733 int nmeasurement=0, im, ix, iy, temp;
5734 struct ath_hal_9300 *ahp = AH9300(ah);
5735 u_int32_t txiqcal_status[AR9300_MAX_CHAINS] = {
5736 AR_PHY_TX_IQCAL_STATUS_B0(ah),
5737 AR_PHY_TX_IQCAL_STATUS_B1,
5738 AR_PHY_TX_IQCAL_STATUS_B2,
5740 const u_int32_t chan_info_tab[] = {
5741 AR_PHY_CHAN_INFO_TAB_0,
5742 AR_PHY_CHAN_INFO_TAB_1,
5743 AR_PHY_CHAN_INFO_TAB_2,
5747 u_int32_t num_chains = 0;
5748 static struct coeff_t coeff;
5749 txiqcal_status[0] = AR_PHY_TX_IQCAL_STATUS_B0(ah);
5751 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
5752 if (ahp->ah_tx_chainmask & (1 << ch_idx)) {
5757 if (apply_last_corr) {
5758 if (coeff.last_cal == AH_TRUE) {
5759 int32_t magnitude, phase;
5761 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5762 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5763 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5764 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5765 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5766 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5767 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5768 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5769 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5770 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5771 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5772 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5773 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5774 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5775 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5776 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5777 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5778 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5779 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5780 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5781 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5782 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5783 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5784 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5785 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5787 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5788 for (im = 0; im < coeff.last_nmeasurement; im++) {
5789 magnitude = coeff.mag_coeff[ch_idx][im][0];
5790 phase = coeff.phs_coeff[ch_idx][im][0];
5793 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
5794 ch_idx, im, magnitude, phase);
5797 coeff.iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
5798 if ((im % 2) == 0) {
5799 OS_REG_RMW_FIELD(ah,
5800 tx_corr_coeff[im][ch_idx],
5801 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5802 coeff.iqc_coeff[0]);
5804 OS_REG_RMW_FIELD(ah,
5805 tx_corr_coeff[im][ch_idx],
5806 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5807 coeff.iqc_coeff[0]);
5811 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5812 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5818 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5819 nmeasurement = OS_REG_READ_FIELD(ah,
5820 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
5821 if (nmeasurement > MAX_MEASUREMENT) {
5822 nmeasurement = MAX_MEASUREMENT;
5825 for (im = 0; im < nmeasurement; im++) {
5826 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5827 "%s: Doing Tx IQ Cal for chain %d.\n", __func__, ch_idx);
5828 if (OS_REG_READ(ah, txiqcal_status[ch_idx]) &
5829 AR_PHY_TX_IQCAL_STATUS_FAILED)
5831 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5832 "%s: Tx IQ Cal failed for chain %d.\n", __func__, ch_idx);
5833 goto TX_IQ_CAL_FAILED_;
5836 for (j = 0; j < 3; j++) {
5837 u_int32_t idx = 2 * j;
5838 /* 3 registers for each calibration result */
5839 u_int32_t offset = 4 * (3 * im + j);
5841 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
5842 AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
5844 iq_res[idx] = OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
5845 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
5846 AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
5848 iq_res[idx + 1] = 0xffff &
5849 OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
5851 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5852 "%s: IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
5853 __func__, idx, iq_res[idx], idx + 1, iq_res[idx + 1]);
5856 if (AH_FALSE == ar9300_calc_iq_corr(
5857 ah, ch_idx, iq_res, coeff.iqc_coeff))
5859 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5860 "%s: Failed in calculation of IQ correction.\n",
5862 goto TX_IQ_CAL_FAILED_;
5865 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] = coeff.iqc_coeff[0] & 0x7f;
5866 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] = (coeff.iqc_coeff[0] >> 7) & 0x7f;
5867 if (coeff.mag_coeff[ch_idx][im][iqcal_idx-1] > 63) {
5868 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] -= 128;
5870 if (coeff.phs_coeff[ch_idx][im][iqcal_idx-1] > 63) {
5871 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] -= 128;
5874 ath_hal_printf(ah, "IQCAL::[ch%d][gain%d]:: mag = %d phase = %d \n",
5875 ch_idx, im, coeff.mag_coeff[ch_idx][im][iqcal_idx-1],
5876 coeff.phs_coeff[ch_idx][im][iqcal_idx-1]);
5880 //last iteration; calculate mag and phs
5881 if (iqcal_idx == max_iqcal) {
5883 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5884 for (im = 0; im < nmeasurement; im++) {
5886 for( ix=0;ix<max_iqcal-1;ix++){
5887 for( iy=ix+1;iy<=max_iqcal-1;iy++){
5888 if(coeff.mag_coeff[ch_idx][im][iy] <
5889 coeff.mag_coeff[ch_idx][im][ix]) {
5891 temp=coeff.mag_coeff[ch_idx][im][ix];
5892 coeff.mag_coeff[ch_idx][im][ix] = coeff.mag_coeff[ch_idx][im][iy];
5893 coeff.mag_coeff[ch_idx][im][iy] = temp;
5895 if(coeff.phs_coeff[ch_idx][im][iy] <
5896 coeff.phs_coeff[ch_idx][im][ix]){
5898 temp=coeff.phs_coeff[ch_idx][im][ix];
5899 coeff.phs_coeff[ch_idx][im][ix]=coeff.phs_coeff[ch_idx][im][iy];
5900 coeff.phs_coeff[ch_idx][im][iy]=temp;
5904 //select median; 3rd entry in the sorted array
5905 coeff.mag_coeff[ch_idx][im][0] =
5906 coeff.mag_coeff[ch_idx][im][max_iqcal/2];
5907 coeff.phs_coeff[ch_idx][im][0] =
5908 coeff.phs_coeff[ch_idx][im][max_iqcal/2];
5909 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5910 "IQCAL: Median [ch%d][gain%d]:: mag = %d phase = %d \n",
5911 ch_idx, im,coeff.mag_coeff[ch_idx][im][0],
5912 coeff.phs_coeff[ch_idx][im][0]);
5916 ar9300_tx_iq_cal_outlier_detection(ah,ichan, num_chains, &coeff,is_cal_reusable);
5920 coeff.last_nmeasurement = nmeasurement;
5921 coeff.last_cal = AH_TRUE;
5926 /* no need to print this, it is AGC failure not chip stuck */
5927 /*ath_hal_printf(ah, "Tx IQ Cal failed(%d)\n", line);*/
5928 coeff.last_cal = AH_FALSE;
5934 * ar9300_disable_phy_restart
5936 * In some BBpanics, we can disable the phyrestart
5937 * disable_phy_restart
5938 * != 0, disable the phy restart in h/w
5939 * == 0, enable the phy restart in h/w
5941 void ar9300_disable_phy_restart(struct ath_hal *ah, int disable_phy_restart)
5945 val = OS_REG_READ(ah, AR_PHY_RESTART);
5946 if (disable_phy_restart) {
5947 val &= ~AR_PHY_RESTART_ENA;
5948 AH9300(ah)->ah_phyrestart_disabled = 1;
5950 val |= AR_PHY_RESTART_ENA;
5951 AH9300(ah)->ah_phyrestart_disabled = 0;
5953 OS_REG_WRITE(ah, AR_PHY_RESTART, val);
5955 val = OS_REG_READ(ah, AR_PHY_RESTART);
5959 ar9300_interference_is_present(struct ath_hal *ah)
5962 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
5963 const struct ieee80211_channel *chan = ahpriv->ah_curchan;
5964 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
5966 if (ichan == NULL) {
5967 ath_hal_printf(ah, "%s: called with ichan=NULL\n", __func__);
5971 /* This function is called after a stuck beacon, if EACS is enabled.
5972 * If CW interference is severe, then HW goes into a loop of continuous
5973 * stuck beacons and resets. On reset the NF cal history is cleared.
5974 * So the median value of the history cannot be used -
5975 * hence check if any value (Chain 0/Primary Channel)
5976 * is outside the bounds.
5978 HAL_NFCAL_HIST_FULL *h = AH_HOME_CHAN_NFCAL_HIST(ah, ichan);
5979 for (i = 0; i < HAL_NF_CAL_HIST_LEN_FULL; i++) {
5980 if (h->nf_cal_buffer[i][0] >
5981 AH9300(ah)->nfp->nominal + AH9300(ah)->nf_cw_int_delta)
5990 #if ATH_SUPPORT_CRDC
5992 ar9300_crdc_rx_notify(struct ath_hal *ah, struct ath_rx_status *rxs)
5994 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
5997 if ((!AR_SREV_WASP(ah)) ||
5998 (!ahpriv->ah_config.ath_hal_crdc_enable)) {
6002 if (rxs->rs_isaggr && rxs->rs_moreaggr) {
6006 if ((rxs->rs_rssi_ctl0 >= HAL_RSSI_BAD) ||
6007 (rxs->rs_rssi_ctl1 >= HAL_RSSI_BAD)) {
6011 rssi_index = ah->ah_crdc_rssi_ptr % HAL_MAX_CRDC_RSSI_SAMPLE;
6013 ah->ah_crdc_rssi_sample[0][rssi_index] = rxs->rs_rssi_ctl0;
6014 ah->ah_crdc_rssi_sample[1][rssi_index] = rxs->rs_rssi_ctl1;
6016 ah->ah_crdc_rssi_ptr++;
6020 ar9300_crdc_avg_rssi(struct ath_hal *ah, int chain)
6022 int crdc_rssi_sum = 0;
6023 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr, i;
6024 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6025 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
6027 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
6028 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
6031 for (i = 1; i <= crdc_window; i++) {
6033 ah->ah_crdc_rssi_sample[chain]
6034 [(crdc_rssi_ptr - i) % HAL_MAX_CRDC_RSSI_SAMPLE];
6037 return crdc_rssi_sum / crdc_window;
6041 ar9300_crdc_activate(struct ath_hal *ah, int rssi_diff, int enable)
6044 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6045 int crdc_numerator = ahpriv->ah_config.ath_hal_crdc_numerator;
6046 int crdc_denominator = ahpriv->ah_config.ath_hal_crdc_denominator;
6047 int c = (rssi_diff * crdc_numerator) / crdc_denominator;
6049 val = orig_val = OS_REG_READ(ah, AR_PHY_MULTICHAIN_CTRL);
6053 val |= ((c << 1) & 0xff);
6055 OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_CTRL, val);
6056 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "diff: %02d comp: %02d reg: %08x %08x\n",
6057 rssi_diff, c, orig_val, val);
6061 void ar9300_chain_rssi_diff_compensation(struct ath_hal *ah)
6063 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6064 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
6065 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr;
6066 int crdc_rssi_thresh = ahpriv->ah_config.ath_hal_crdc_rssithresh;
6067 int crdc_diff_thresh = ahpriv->ah_config.ath_hal_crdc_diffthresh;
6068 int avg_rssi[2], avg_rssi_diff;
6070 if ((!AR_SREV_WASP(ah)) ||
6071 (!ahpriv->ah_config.ath_hal_crdc_enable)) {
6072 if (ah->ah_crdc_rssi_ptr) {
6073 ar9300_crdc_activate(ah, 0, 0);
6074 ah->ah_crdc_rssi_ptr = 0;
6079 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
6080 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
6083 if (crdc_rssi_ptr < crdc_window) {
6087 avg_rssi[0] = ar9300_crdc_avg_rssi(ah, 0);
6088 avg_rssi[1] = ar9300_crdc_avg_rssi(ah, 1);
6089 avg_rssi_diff = avg_rssi[1] - avg_rssi[0];
6091 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "crdc: avg: %02d %02d ",
6092 avg_rssi[0], avg_rssi[1]);
6094 if ((avg_rssi[0] < crdc_rssi_thresh) &&
6095 (avg_rssi[1] < crdc_rssi_thresh)) {
6096 ar9300_crdc_activate(ah, 0, 0);
6098 if (ABS(avg_rssi_diff) >= crdc_diff_thresh) {
6099 ar9300_crdc_activate(ah, avg_rssi_diff, 1);
6101 ar9300_crdc_activate(ah, 0, 1);
6107 #if ATH_ANT_DIV_COMB
6109 ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal *ah, HAL_BOOL enable, const struct ieee80211_channel *chan)
6113 struct ath_hal_9300 *ahp = AH9300(ah);
6114 HAL_CHANNEL_INTERNAL *ichan;
6115 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6116 HAL_CAPABILITIES *pcap = &ahpriv->ah_caps;
6118 if (AR_SREV_POSEIDON(ah)) {
6119 // Make sure this scheme is only used for WB225(Astra)
6120 ahp->ah_lna_div_use_bt_ant_enable = enable;
6122 ichan = ar9300_check_chan(ah, chan);
6123 if ( ichan == AH_NULL ) {
6124 HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel %u/0x%x; no mapping\n",
6125 __func__, chan->ic_freq, chan->ic_flags);
6129 if ( enable == TRUE ) {
6130 pcap->halAntDivCombSupport = TRUE;
6132 pcap->halAntDivCombSupport = pcap->halAntDivCombSupportOrg;
6135 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
6136 #define AR_SWITCH_TABLE_COM2_ALL_S (0)
6137 value = ar9300_ant_ctrl_common2_get(ah, IS_CHAN_2GHZ(ichan));
6138 if ( enable == TRUE ) {
6139 value &= ~AR_SWITCH_TABLE_COM2_ALL;
6140 value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable;
6142 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
6144 value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control);
6145 /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6146 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6147 regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */
6148 regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S;
6150 regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK);
6151 regval |= ((value >> 6) & 0x1) <<
6152 MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT;
6153 if ( enable == TRUE ) {
6154 regval |= ANT_DIV_ENABLE;
6156 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6158 /* enable fast_div */
6159 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
6160 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
6161 regval |= ((value >> 7) & 0x1) <<
6162 BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT;
6163 if ( enable == TRUE ) {
6164 regval |= FAST_DIV_ENABLE;
6166 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
6168 if ( AR_SREV_POSEIDON_11_OR_LATER(ah) ) {
6169 if (pcap->halAntDivCombSupport) {
6170 /* If support DivComb, set MAIN to LNA1 and ALT to LNA2 at the first beginning */
6171 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6172 /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6173 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK |
6174 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK |
6175 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK |
6176 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK));
6177 regval |= (HAL_ANT_DIV_COMB_LNA1 <<
6178 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT);
6179 regval |= (HAL_ANT_DIV_COMB_LNA2 <<
6180 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT);
6181 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6190 #endif /* ATH_ANT_DIV_COMB */