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);
1990 int type = HAL_RESET_WARM;
1992 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
1995 * Warm reset is optimistic.
1997 * If the TX/RX DMA engines aren't shut down (eg, they're
1998 * wedged) then we're better off doing a full cold reset
1999 * to try and shake that condition.
2001 if (ahp->ah_chip_full_sleep ||
2002 (ah->ah_config.ah_force_full_reset == 1) ||
2003 OS_REG_READ(ah, AR_Q_TXE) ||
2004 (OS_REG_READ(ah, AR_CR) & AR_CR_RXE)) {
2005 type = HAL_RESET_COLD;
2008 if (!ar9300_set_reset_reg(ah, type)) {
2012 /* Bring out of sleep mode (AGAIN) */
2013 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
2017 ahp->ah_chip_full_sleep = AH_FALSE;
2019 if (AR_SREV_HORNET(ah)) {
2020 ar9300_internal_regulator_apply(ah);
2023 ar9300_init_pll(ah, chan);
2026 * Perform warm reset before the mode/PLL/turbo registers
2027 * are changed in order to deactivate the radio. Mode changes
2028 * with an active radio can result in corrupted shifts to the
2031 ar9300_set_rf_mode(ah, chan);
2036 /* ar9300_setup_calibration
2037 * Setup HW to collect samples used for current cal
2040 ar9300_setup_calibration(struct ath_hal *ah, HAL_CAL_LIST *curr_cal)
2042 /* Select calibration to run */
2043 switch (curr_cal->cal_data->cal_type) {
2044 case IQ_MISMATCH_CAL:
2045 /* Start calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
2046 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4,
2047 AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
2048 curr_cal->cal_data->cal_count_max);
2049 OS_REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
2051 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2052 "%s: starting IQ Mismatch Calibration\n", __func__);
2055 OS_REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
2059 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
2060 AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
2061 OS_REG_RMW_FIELD(ah,
2062 AR_HORNET_CH0_THERM, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2063 OS_REG_RMW_FIELD(ah,
2064 AR_HORNET_CH0_THERM, AR_PHY_65NM_CH0_THERM_START, 1);
2065 } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
2066 OS_REG_RMW_FIELD(ah,
2067 AR_PHY_65NM_CH0_THERM_JUPITER, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2068 OS_REG_RMW_FIELD(ah,
2069 AR_PHY_65NM_CH0_THERM_JUPITER, AR_PHY_65NM_CH0_THERM_START, 1);
2071 OS_REG_RMW_FIELD(ah,
2072 AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2073 OS_REG_RMW_FIELD(ah,
2074 AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_START, 1);
2077 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2078 "%s: starting Temperature Compensation Calibration\n", __func__);
2081 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
2082 "%s called with incorrect calibration type.\n", __func__);
2086 /* ar9300_reset_calibration
2087 * Initialize shared data structures and prepare a cal to be run.
2090 ar9300_reset_calibration(struct ath_hal *ah, HAL_CAL_LIST *curr_cal)
2092 struct ath_hal_9300 *ahp = AH9300(ah);
2095 /* Setup HW for new calibration */
2096 ar9300_setup_calibration(ah, curr_cal);
2098 /* Change SW state to RUNNING for this calibration */
2099 curr_cal->cal_state = CAL_RUNNING;
2101 /* Reset data structures shared between different calibrations */
2102 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
2103 ahp->ah_meas0.sign[i] = 0;
2104 ahp->ah_meas1.sign[i] = 0;
2105 ahp->ah_meas2.sign[i] = 0;
2106 ahp->ah_meas3.sign[i] = 0;
2109 ahp->ah_cal_samples = 0;
2112 #ifdef XXX_UNUSED_FUNCTION
2114 * Find out which of the RX chains are enabled
2117 ar9300_get_rx_chain_mask(struct ath_hal *ah)
2119 u_int32_t ret_val = OS_REG_READ(ah, AR_PHY_RX_CHAINMASK);
2120 /* The bits [2:0] indicate the rx chain mask and are to be
2121 * interpreted as follows:
2122 * 00x => Only chain 0 is enabled
2123 * 01x => Chain 1 and 0 enabled
2124 * 1xx => Chain 2,1 and 0 enabled
2126 return (ret_val & 0x7);
2131 ar9300_get_nf_hist_base(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
2132 int is_scan, int16_t nf[])
2134 HAL_NFCAL_BASE *h_base;
2136 #ifdef ATH_NF_PER_CHAN
2137 h_base = &chan->nf_cal_hist.base;
2141 * The channel we are currently on is not the home channel,
2142 * so we shouldn't use the home channel NF buffer's values on
2143 * this channel. Instead, use the NF single value already
2144 * read for this channel. (Or, if we haven't read the NF for
2145 * this channel yet, the SW default for this chip/band will
2148 h_base = &chan->nf_cal_hist.base;
2150 /* use the home channel NF info */
2151 h_base = &AH_PRIVATE(ah)->nf_cal_hist.base;
2154 OS_MEMCPY(nf, h_base->priv_nf, sizeof(h_base->priv_nf));
2158 ar9300_load_nf(struct ath_hal *ah, int16_t nf[])
2162 /* XXX where are EXT regs defined */
2163 const u_int32_t ar9300_cca_regs[] = {
2174 * Force NF calibration for all chains, otherwise Vista station
2175 * would conduct a bad performance
2177 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
2179 } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah)) {
2186 * Write filtered NF values into max_cca_pwr register parameter
2187 * so we can load below.
2189 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
2190 if (chainmask & (1 << i)) {
2191 val = OS_REG_READ(ah, ar9300_cca_regs[i]);
2193 val |= (((u_int32_t)(nf[i]) << 1) & 0x1ff);
2194 OS_REG_WRITE(ah, ar9300_cca_regs[i], val);
2198 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%s: load %d %d %d %d %d %d\n",
2200 nf[0], nf[1], nf[2],
2201 nf[3], nf[4], nf[5]);
2204 * Load software filtered NF value into baseband internal min_cca_pwr
2207 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
2208 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
2209 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
2211 /* Wait for load to complete, should be fast, a few 10s of us. */
2212 /* Changed the max delay 250us back to 10000us, since 250us often
2213 * results in NF load timeout and causes deaf condition
2214 * during stress testing 12/12/2009
2216 for (j = 0; j < 10000; j++) {
2217 if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){
2224 * We timed out waiting for the noisefloor to load, probably
2225 * due to an in-progress rx. Simply return here and allow
2226 * the load plenty of time to complete before the next
2227 * calibration interval. We need to avoid trying to load -50
2228 * (which happens below) while the previous load is still in
2229 * progress as this can cause rx deafness (see EV 66368,62830).
2230 * Instead by returning here, the baseband nf cal will
2231 * just be capped by our present noisefloor until the next
2232 * calibration timer.
2234 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,
2235 "%s: *** TIMEOUT while waiting for nf to load: "
2236 "AR_PHY_AGC_CONTROL=0x%x ***\n",
2237 __func__, OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
2242 * Restore max_cca_power register parameter again so that we're not capped
2243 * by the median we just loaded. This will be initial (and max) value
2244 * of next noise floor calibration the baseband does.
2246 for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
2247 if (chainmask & (1 << i)) {
2248 val = OS_REG_READ(ah, ar9300_cca_regs[i]);
2250 val |= (((u_int32_t)(-50) << 1) & 0x1ff);
2251 OS_REG_WRITE(ah, ar9300_cca_regs[i], val);
2257 /* ar9300_per_calibration
2258 * Generic calibration routine.
2259 * Recalibrate the lower PHY chips to account for temperature/environment
2263 ar9300_per_calibration(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
2264 u_int8_t rxchainmask, HAL_CAL_LIST *curr_cal, HAL_BOOL *is_cal_done)
2266 struct ath_hal_9300 *ahp = AH9300(ah);
2268 /* Cal is assumed not done until explicitly set below */
2269 *is_cal_done = AH_FALSE;
2271 /* Calibration in progress. */
2272 if (curr_cal->cal_state == CAL_RUNNING) {
2273 /* Check to see if it has finished. */
2274 if (!(OS_REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) {
2275 int i, num_chains = 0;
2276 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
2277 if (rxchainmask & (1 << i)) {
2283 * Accumulate cal measures for active chains
2285 curr_cal->cal_data->cal_collect(ah, num_chains);
2287 ahp->ah_cal_samples++;
2289 if (ahp->ah_cal_samples >= curr_cal->cal_data->cal_num_samples) {
2291 * Process accumulated data
2293 curr_cal->cal_data->cal_post_proc(ah, num_chains);
2295 /* Calibration has finished. */
2296 ichan->calValid |= curr_cal->cal_data->cal_type;
2297 curr_cal->cal_state = CAL_DONE;
2298 *is_cal_done = AH_TRUE;
2300 /* Set-up collection of another sub-sample until we
2301 * get desired number
2303 ar9300_setup_calibration(ah, curr_cal);
2306 } else if (!(ichan->calValid & curr_cal->cal_data->cal_type)) {
2307 /* If current cal is marked invalid in channel, kick it off */
2308 ar9300_reset_calibration(ah, curr_cal);
2313 ar9300_start_nf_cal(struct ath_hal *ah)
2315 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
2316 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
2317 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
2318 AH9300(ah)->nf_tsf32 = ar9300_get_tsf32(ah);
2321 /* ar9300_calibration
2322 * Wrapper for a more generic Calibration routine. Primarily to abstract to
2323 * upper layers whether there is 1 or more calibrations to be run.
2326 ar9300_calibration(struct ath_hal *ah, struct ieee80211_channel *chan, u_int8_t rxchainmask,
2327 HAL_BOOL do_nf_cal, HAL_BOOL *is_cal_done, int is_scan,
2328 u_int32_t *sched_cals)
2330 struct ath_hal_9300 *ahp = AH9300(ah);
2331 HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr;
2332 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2333 int16_t nf_buf[HAL_NUM_NF_READINGS];
2335 *is_cal_done = AH_TRUE;
2338 /* XXX: For initial wasp bringup - disable periodic calibration */
2339 /* Invalid channel check */
2340 if (ichan == AH_NULL) {
2341 HALDEBUG(ah, HAL_DEBUG_CHANNEL,
2342 "%s: invalid channel %u/0x%x; no mapping\n",
2343 __func__, chan->ic_freq, chan->ic_flags);
2347 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2348 "%s: Entering, Doing NF Cal = %d\n", __func__, do_nf_cal);
2349 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Chain 0 Rx IQ Cal Correction 0x%08x\n",
2350 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
2351 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah) && !AR_SREV_APHRODITE(ah)) {
2352 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2353 "%s: Chain 1 Rx IQ Cal Correction 0x%08x\n",
2354 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B1));
2355 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
2356 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2357 "%s: Chain 2 Rx IQ Cal Correction 0x%08x\n",
2358 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B2));
2362 OS_MARK(ah, AH_MARK_PERCAL, chan->ic_freq);
2364 /* For given calibration:
2365 * 1. Call generic cal routine
2366 * 2. When this cal is done (is_cal_done) if we have more cals waiting
2367 * (eg after reset), mask this to upper layers by not propagating
2368 * is_cal_done if it is set to TRUE.
2369 * Instead, change is_cal_done to FALSE and setup the waiting cal(s)
2372 if (curr_cal && (curr_cal->cal_data->cal_type & *sched_cals) &&
2373 (curr_cal->cal_state == CAL_RUNNING ||
2374 curr_cal->cal_state == CAL_WAITING))
2376 ar9300_per_calibration(ah, ichan, rxchainmask, curr_cal, is_cal_done);
2378 if (*is_cal_done == AH_TRUE) {
2379 ahp->ah_cal_list_curr = curr_cal = curr_cal->cal_next;
2381 if (curr_cal && curr_cal->cal_state == CAL_WAITING) {
2382 *is_cal_done = AH_FALSE;
2383 ar9300_reset_calibration(ah, curr_cal);
2385 *sched_cals &= ~IQ_MISMATCH_CAL;
2390 /* Do NF cal only at longer intervals */
2394 /* Get the value from the previous NF cal and update history buffer */
2395 nf_done = ar9300_store_new_nf(ah, chan, is_scan);
2397 if (ichan->channel_flags & CHANNEL_CW_INT) {
2398 chan->channel_flags |= CHANNEL_CW_INT;
2401 chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
2405 * Load the NF from history buffer of the current channel.
2406 * NF is slow time-variant, so it is OK to use a historical value.
2408 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
2409 ar9300_load_nf(ah, nf_buf);
2411 /* start NF calibration, without updating BB NF register*/
2412 ar9300_start_nf_cal(ah);
2418 /* ar9300_iq_cal_collect
2419 * Collect data from HW to later perform IQ Mismatch Calibration
2422 ar9300_iq_cal_collect(struct ath_hal *ah, u_int8_t num_chains)
2424 struct ath_hal_9300 *ahp = AH9300(ah);
2428 * Accumulate IQ cal measures for active chains
2430 for (i = 0; i < num_chains; i++) {
2431 ahp->ah_total_power_meas_i[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
2432 ahp->ah_total_power_meas_q[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
2433 ahp->ah_total_iq_corr_meas[i] =
2434 (int32_t) OS_REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
2435 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2437 "Reg Offset(0x%04x)pmi=0x%08x; "
2438 "Reg Offset(0x%04x)pmq=0x%08x; "
2439 "Reg Offset (0x%04x)iqcm=0x%08x;\n",
2440 ahp->ah_cal_samples,
2442 (unsigned) AR_PHY_CAL_MEAS_0(i),
2443 ahp->ah_total_power_meas_i[i],
2444 (unsigned) AR_PHY_CAL_MEAS_1(i),
2445 ahp->ah_total_power_meas_q[i],
2446 (unsigned) AR_PHY_CAL_MEAS_2(i),
2447 ahp->ah_total_iq_corr_meas[i]);
2451 /* ar9300_iq_calibration
2452 * Use HW data to perform IQ Mismatch Calibration
2455 ar9300_iq_calibration(struct ath_hal *ah, u_int8_t num_chains)
2457 struct ath_hal_9300 *ahp = AH9300(ah);
2458 u_int32_t power_meas_q, power_meas_i, iq_corr_meas;
2459 u_int32_t q_coff_denom, i_coff_denom;
2460 int32_t q_coff, i_coff;
2462 static const u_int32_t offset_array[3] = {
2463 AR_PHY_RX_IQCAL_CORR_B0,
2464 AR_PHY_RX_IQCAL_CORR_B1,
2465 AR_PHY_RX_IQCAL_CORR_B2,
2468 for (i = 0; i < num_chains; i++) {
2469 power_meas_i = ahp->ah_total_power_meas_i[i];
2470 power_meas_q = ahp->ah_total_power_meas_q[i];
2471 iq_corr_meas = ahp->ah_total_iq_corr_meas[i];
2473 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2474 "Starting IQ Cal and Correction for Chain %d\n", i);
2475 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2476 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
2477 i, ahp->ah_total_iq_corr_meas[i]);
2481 /* iq_corr_meas is always negative. */
2482 if (iq_corr_meas > 0x80000000) {
2483 iq_corr_meas = (0xffffffff - iq_corr_meas) + 1;
2487 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2488 "Chn %d pwr_meas_i = 0x%08x\n", i, power_meas_i);
2489 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2490 "Chn %d pwr_meas_q = 0x%08x\n", i, power_meas_q);
2491 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2492 "iq_corr_neg is 0x%08x\n", iq_corr_neg);
2494 i_coff_denom = (power_meas_i / 2 + power_meas_q / 2) / 256;
2495 q_coff_denom = power_meas_q / 64;
2497 /* Protect against divide-by-0 */
2498 if ((i_coff_denom != 0) && (q_coff_denom != 0)) {
2499 /* IQ corr_meas is already negated if iqcorr_neg == 1 */
2500 i_coff = iq_corr_meas / i_coff_denom;
2501 q_coff = power_meas_i / q_coff_denom - 64;
2502 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2503 "Chn %d i_coff = 0x%08x\n", i, i_coff);
2504 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2505 "Chn %d q_coff = 0x%08x\n", i, q_coff);
2507 /* Force bounds on i_coff */
2510 } else if (i_coff <= -63) {
2514 /* Negate i_coff if iq_corr_neg == 0 */
2515 if (iq_corr_neg == 0x0) {
2519 /* Force bounds on q_coff */
2522 } else if (q_coff <= -63) {
2526 i_coff = i_coff & 0x7f;
2527 q_coff = q_coff & 0x7f;
2529 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2530 "Chn %d : i_coff = 0x%x q_coff = 0x%x\n", i, i_coff, q_coff);
2531 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2532 "Register offset (0x%04x) before update = 0x%x\n",
2533 offset_array[i], OS_REG_READ(ah, offset_array[i]));
2535 OS_REG_RMW_FIELD(ah, offset_array[i],
2536 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, i_coff);
2537 OS_REG_RMW_FIELD(ah, offset_array[i],
2538 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, q_coff);
2540 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2541 "Register offset (0x%04x) QI COFF (bitfields 0x%08x) "
2542 "after update = 0x%x\n",
2543 offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
2544 OS_REG_READ(ah, offset_array[i]));
2545 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2546 "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) "
2547 "after update = 0x%x\n",
2548 offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
2549 OS_REG_READ(ah, offset_array[i]));
2550 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2551 "IQ Cal and Correction done for Chain %d\n", i);
2556 AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
2557 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2558 "IQ Cal and Correction (offset 0x%04x) enabled "
2559 "(bit position 0x%08x). New Value 0x%08x\n",
2560 (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
2561 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
2562 OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
2566 * Set a limit on the overall output power. Used for dynamic
2567 * transmit power control and the like.
2569 * NB: limit is in units of 0.5 dbM.
2572 ar9300_set_tx_power_limit(struct ath_hal *ah, u_int32_t limit,
2573 u_int16_t extra_txpow, u_int16_t tpc_in_db)
2575 struct ath_hal_9300 *ahp = AH9300(ah);
2576 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
2577 const struct ieee80211_channel *chan = ahpriv->ah_curchan;
2578 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2584 ahpriv->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);
2585 ahpriv->ah_extraTxPow = extra_txpow;
2590 if (ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan,
2591 ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
2592 ath_hal_get_twice_max_regpower(ahpriv, ichan, chan),
2593 AH_MIN(MAX_RATE_POWER, ahpriv->ah_powerLimit)) != HAL_OK)
2601 * Exported call to check for a recent gain reading and return
2602 * the current state of the thermal calibration gain engine.
2605 ar9300_get_rfgain(struct ath_hal *ah)
2607 return HAL_RFGAIN_INACTIVE;
2610 #define HAL_GREEN_AP_RX_MASK 0x1
2613 ar9300_init_chain_masks(struct ath_hal *ah, int rx_chainmask, int tx_chainmask)
2615 if (AH9300(ah)->green_ap_ps_on) {
2616 rx_chainmask = HAL_GREEN_AP_RX_MASK;
2618 if (rx_chainmask == 0x5) {
2619 OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
2621 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
2622 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
2625 * Adaptive Power Management:
2626 * Some 3 stream chips exceed the PCIe power requirements.
2627 * This workaround will reduce power consumption by using 2 tx chains
2628 * for 1 and 2 stream rates (5 GHz only).
2630 * Set the self gen mask to 2 tx chains when APM is enabled.
2633 if (AH_PRIVATE(ah)->ah_caps.halApmEnable && (tx_chainmask == 0x7)) {
2634 OS_REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
2637 OS_REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
2640 if (tx_chainmask == 0x5) {
2641 OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
2646 * Override INI values with chip specific configuration.
2649 ar9300_override_ini(struct ath_hal *ah, struct ieee80211_channel *chan)
2652 HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
2655 * Set the RX_ABORT and RX_DIS and clear it only after
2656 * RXE is set for MAC. This prevents frames with
2657 * corrupted descriptor status.
2659 OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
2661 * For Merlin and above, there is a new feature that allows Multicast
2662 * search based on both MAC Address and Key ID.
2663 * By default, this feature is enabled.
2664 * But since the driver is not using this feature, we switch it off;
2665 * otherwise multicast search based on MAC addr only will fail.
2667 val = OS_REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE);
2668 OS_REG_WRITE(ah, AR_PCU_MISC_MODE2,
2669 val | AR_BUG_58603_FIX_ENABLE | AR_AGG_WEP_ENABLE);
2672 /* Osprey revision specific configuration */
2674 /* Osprey 2.0+ - if SW RAC support is disabled, must also disable
2675 * the Osprey 2.0 hardware RAC fix.
2677 if (p_cap->halIsrRacSupport == AH_FALSE) {
2678 OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_MISSING_TX_INTR_FIX_ENABLE);
2681 /* try to enable old pal if it is needed for h/w green tx */
2682 ar9300_hwgreentx_set_pal_spare(ah, 1);
2686 ar9300_prog_ini(struct ath_hal *ah, struct ar9300_ini_array *ini_arr,
2689 int i, reg_writes = 0;
2691 /* New INI format: Array may be undefined (pre, core, post arrays) */
2692 if (ini_arr->ia_array == NULL) {
2697 * New INI format: Pre, core, and post arrays for a given subsystem may be
2698 * modal (> 2 columns) or non-modal (2 columns).
2699 * Determine if the array is non-modal and force the column to 1.
2701 if (column >= ini_arr->ia_columns) {
2705 for (i = 0; i < ini_arr->ia_rows; i++) {
2706 u_int32_t reg = INI_RA(ini_arr, i, 0);
2707 u_int32_t val = INI_RA(ini_arr, i, column);
2710 ** Determine if this is a shift register value
2711 ** (reg >= 0x16000 && reg < 0x17000 for Osprey) ,
2712 ** and insert the configured delay if so.
2713 ** -this delay is not required for Osprey (EV#71410)
2715 OS_REG_WRITE(ah, reg, val);
2716 WAR_6773(reg_writes);
2721 static inline HAL_STATUS
2722 ar9300_process_ini(struct ath_hal *ah, struct ieee80211_channel *chan,
2723 HAL_CHANNEL_INTERNAL *ichan, HAL_HT_MACMODE macmode)
2726 struct ath_hal_9300 *ahp = AH9300(ah);
2727 u_int modes_index, modes_txgaintable_index = 0;
2730 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
2731 /* Setup the indices for the next set of register array writes */
2733 * If the channel marker is indicative of the current mode rather
2734 * than capability, we do not need to check the phy mode below.
2737 switch (chan->channel_flags & CHANNEL_ALL) {
2739 case CHANNEL_A_HT20:
2740 if (AR_SREV_SCORPION(ah)){
2741 if (chan->channel <= 5350){
2742 modes_txgaintable_index = 1;
2743 }else if ((chan->channel > 5350) && (chan->channel <= 5600)){
2744 modes_txgaintable_index = 3;
2745 }else if (chan->channel > 5600){
2746 modes_txgaintable_index = 5;
2752 case CHANNEL_A_HT40PLUS:
2753 case CHANNEL_A_HT40MINUS:
2754 if (AR_SREV_SCORPION(ah)){
2755 if (chan->channel <= 5350){
2756 modes_txgaintable_index = 2;
2757 }else if ((chan->channel > 5350) && (chan->channel <= 5600)){
2758 modes_txgaintable_index = 4;
2759 }else if (chan->channel > 5600){
2760 modes_txgaintable_index = 6;
2767 case CHANNEL_G_HT20:
2769 if (AR_SREV_SCORPION(ah)){
2770 modes_txgaintable_index = 8;
2775 case CHANNEL_G_HT40PLUS:
2776 case CHANNEL_G_HT40MINUS:
2777 if (AR_SREV_SCORPION(ah)){
2778 modes_txgaintable_index = 7;
2794 if (IS_CHAN_5GHZ(ichan)) {
2795 if (IEEE80211_IS_CHAN_HT40U(chan) || IEEE80211_IS_CHAN_HT40D(chan)) {
2796 if (AR_SREV_SCORPION(ah)){
2797 if (ichan->channel <= 5350){
2798 modes_txgaintable_index = 2;
2799 }else if ((ichan->channel > 5350) && (ichan->channel <= 5600)){
2800 modes_txgaintable_index = 4;
2801 }else if (ichan->channel > 5600){
2802 modes_txgaintable_index = 6;
2806 } else if (IEEE80211_IS_CHAN_A(chan) || IEEE80211_IS_CHAN_HT20(chan)) {
2807 if (AR_SREV_SCORPION(ah)){
2808 if (ichan->channel <= 5350){
2809 modes_txgaintable_index = 1;
2810 }else if ((ichan->channel > 5350) && (ichan->channel <= 5600)){
2811 modes_txgaintable_index = 3;
2812 }else if (ichan->channel > 5600){
2813 modes_txgaintable_index = 5;
2819 } else if (IS_CHAN_2GHZ(ichan)) {
2820 if (IEEE80211_IS_CHAN_108G(chan)) {
2822 } else if (IEEE80211_IS_CHAN_HT40U(chan) || IEEE80211_IS_CHAN_HT40D(chan)) {
2823 if (AR_SREV_SCORPION(ah)){
2824 modes_txgaintable_index = 7;
2827 } else if (IEEE80211_IS_CHAN_HT20(chan) || IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_B(chan) || IEEE80211_IS_CHAN_PUREG(chan)) {
2828 if (AR_SREV_SCORPION(ah)){
2829 modes_txgaintable_index = 8;
2838 /* Set correct Baseband to analog shift setting to access analog chips. */
2839 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
2842 HALDEBUG(ah, HAL_DEBUG_RESET,
2843 "ar9300_process_ini: "
2844 "Skipping OS-REG-WRITE(ah, AR-PHY(0), 0x00000007)\n");
2845 HALDEBUG(ah, HAL_DEBUG_RESET,
2846 "ar9300_process_ini: no ADDac programming\n");
2850 * Osprey 2.0+ - new INI format.
2851 * Each subsystem has a pre, core, and post array.
2853 for (i = 0; i < ATH_INI_NUM_SPLIT; i++) {
2854 ar9300_prog_ini(ah, &ahp->ah_ini_soc[i], modes_index);
2855 ar9300_prog_ini(ah, &ahp->ah_ini_mac[i], modes_index);
2856 ar9300_prog_ini(ah, &ahp->ah_ini_bb[i], modes_index);
2857 ar9300_prog_ini(ah, &ahp->ah_ini_radio[i], modes_index);
2858 if ((i == ATH_INI_POST) && (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah))) {
2859 ar9300_prog_ini(ah, &ahp->ah_ini_radio_post_sys2ant, modes_index);
2864 if (!(AR_SREV_SOC(ah))) {
2865 /* Doubler issue : Some board doesn't work well with MCS15. Turn off doubler after freq locking is complete*/
2866 //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));
2867 OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2868 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
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));
2871 OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2872 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
2873 OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2874 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
2877 //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));
2878 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
2879 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
2880 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
2881 //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));
2885 //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));
2886 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
2887 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
2888 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
2889 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2893 //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));
2894 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH12, AR_PHY_65NM_CH0_SYNTH12_VREFMUL3, 0xf);
2895 //OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_SYNTH12, 1<< 16); /* clr charge pump */
2896 //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));
2898 OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2899 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
2900 OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2901 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
2902 OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2903 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
2904 //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));
2907 /* Write rxgain Array Parameters */
2908 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain, 1, reg_writes);
2909 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain programming\n");
2911 if (AR_SREV_SCORPION(ah)) {
2912 /* Write rxgain bounds Array */
2913 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bounds, modes_index, reg_writes);
2914 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain table bounds programming\n");
2916 /* UB124 xLNA settings */
2917 if (AR_SREV_WASP(ah) && ar9300_rx_gain_index_get(ah) == 2) {
2918 #define REG_WRITE(_reg,_val) *((volatile u_int32_t *)(_reg)) = (_val);
2919 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
2921 /* B8040000: bit[0]=0, bit[3]=0; */
2922 val = REG_READ(0xB8040000);
2924 REG_WRITE(0xB8040000, val);
2925 /* B804002c: bit[31:24]=0x2e; bit[7:0]=0x2f; */
2926 val = REG_READ(0xB804002c);
2929 REG_WRITE(0xB804002c, val);
2930 /* B804006c: bit[1]=1; */
2931 val = REG_READ(0xB804006c);
2933 REG_WRITE(0xB804006c, val);
2939 /* Write txgain Array Parameters */
2940 if (AR_SREV_SCORPION(ah)) {
2941 REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_txgaintable_index,
2944 REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_index, reg_writes);
2946 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Tx Gain programming\n");
2949 /* For 5GHz channels requiring Fast Clock, apply different modal values */
2950 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
2951 HALDEBUG(ah, HAL_DEBUG_RESET,
2952 "%s: Fast clock enabled, use special ini values\n", __func__);
2953 REG_WRITE_ARRAY(&ahp->ah_ini_modes_additional, modes_index, reg_writes);
2956 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
2957 HALDEBUG(ah, HAL_DEBUG_RESET,
2958 "%s: use xtal ini for AH9300(ah)->clk_25mhz: %d\n",
2959 __func__, AH9300(ah)->clk_25mhz);
2961 &ahp->ah_ini_modes_additional, 1/*modes_index*/, reg_writes);
2964 if (AR_SREV_WASP(ah) && (AH9300(ah)->clk_25mhz == 0)) {
2965 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Apply 40MHz ini settings\n", __func__);
2967 &ahp->ah_ini_modes_additional_40mhz, 1/*modesIndex*/, reg_writes);
2970 /* Handle Japan Channel 14 channel spreading */
2971 if (2484 == ichan->channel) {
2972 ar9300_prog_ini(ah, &ahp->ah_ini_japan2484, 1);
2976 if (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)) {
2977 ar9300_prog_ini(ah, &ahp->ah_ini_BTCOEX_MAX_TXPWR, 1);
2981 /* Override INI with chip specific configuration */
2982 ar9300_override_ini(ah, chan);
2984 /* Setup 11n MAC/Phy mode registers */
2985 ar9300_set_11n_regs(ah, chan, macmode);
2988 * Moved ar9300_init_chain_masks() here to ensure the swap bit is set before
2989 * the pdadc table is written. Swap must occur before any radio dependent
2990 * replicated register access. The pdadc curve addressing in particular
2991 * depends on the consistent setting of the swap bit.
2993 ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
2996 * Setup the transmit power values.
2998 * After the public to private hal channel mapping, ichan contains the
2999 * valid regulatory power value.
3000 * ath_hal_getctl and ath_hal_getantennaallowed look up ichan from chan.
3002 status = ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan,
3003 ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
3004 ath_hal_get_twice_max_regpower(ahpriv, ichan, chan),
3005 AH_MIN(MAX_RATE_POWER, ahpriv->ah_powerLimit));
3006 if (status != HAL_OK) {
3007 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
3008 "%s: error init'ing transmit power\n", __func__);
3017 /* ar9300_is_cal_supp
3018 * Determine if calibration is supported by device and channel flags
3020 inline static HAL_BOOL
3021 ar9300_is_cal_supp(struct ath_hal *ah, const struct ieee80211_channel *chan,
3022 HAL_CAL_TYPES cal_type)
3024 struct ath_hal_9300 *ahp = AH9300(ah);
3025 HAL_BOOL retval = AH_FALSE;
3027 switch (cal_type & ahp->ah_supp_cals) {
3028 case IQ_MISMATCH_CAL:
3029 /* Run IQ Mismatch for non-CCK only */
3030 if (!IEEE80211_IS_CHAN_B(chan)) {
3045 * PA Calibration for Kite 1.1 and later versions of Kite.
3046 * - from system's team.
3049 ar9285_pa_cal(struct ath_hal *ah)
3052 int i, lo_gn, offs_6_1, offs_0;
3054 u_int32_t phy_test2_reg_val, phy_adc_ctl_reg_val;
3055 u_int32_t an_top2_reg_val, phy_tst_dac_reg_val;
3058 /* Kite 1.1 WAR for Bug 35666
3059 * Increase the LDO value to 1.28V before accessing analog Reg */
3060 if (AR_SREV_KITE_11(ah)) {
3061 OS_REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14) );
3063 an_top2_reg_val = OS_REG_READ(ah, AR9285_AN_TOP2);
3065 /* set pdv2i pdrxtxbb */
3066 reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
3067 reg_val |= ((0x1 << 5) | (0x1 << 7));
3068 OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
3071 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G7);
3072 reg_val &= 0xfffffffd;
3073 OS_REG_WRITE(ah, AR9285_AN_RF2G7, reg_val);
3076 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3077 reg_val &= 0xfffff7ff;
3078 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3081 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
3082 reg_val |= (0x1 << 12);
3083 OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
3085 /* set pdpadrv1=pdpadrv2=pdpaout=1 */
3086 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3087 reg_val |= (0x7 << 23);
3088 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3090 /* Read back reflo, increase it by 1 and write it. */
3091 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3092 reflo = ((reg_val >> 26) & 0x7);
3097 reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3098 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3100 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3101 reflo = ((reg_val >> 26) & 0x7);
3103 /* use TX single carrier to transmit
3107 phy_tst_dac_reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3108 OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, ((0x7ff << 11) | 0x7ff));
3109 reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3111 /* source is dac const
3114 phy_test2_reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3115 OS_REG_WRITE(ah, AR_PHY_TEST2, ((0x1 << 7) | (0x1 << 1)));
3116 reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3121 phy_adc_ctl_reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3122 OS_REG_WRITE(ah, AR_PHY_ADC_CTL, 0x80008000);
3123 reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3125 OS_REG_WRITE(ah, AR9285_AN_TOP2, (0x1 << 27) | (0x1 << 17) | (0x1 << 16) |
3126 (0x1 << 14) | (0x1 << 12) | (0x1 << 11) |
3127 (0x1 << 7) | (0x1 << 5));
3129 OS_DELAY(10); /* 10 usec */
3131 /* clear off[6:0] */
3132 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3133 reg_val &= 0xfc0fffff;
3134 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3135 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3136 reg_val &= 0xfdffffff;
3137 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3140 for (i = 6; i > 0; i--) {
3141 /* sef off[$k]==1 */
3142 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3143 reg_val &= 0xfc0fffff;
3144 reg_val = reg_val | (0x1 << (19 + i)) | ((offs_6_1) << 20);
3145 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3146 lo_gn = (OS_REG_READ(ah, AR9285_AN_RF2G9)) & 0x1;
3147 offs_6_1 = offs_6_1 | (lo_gn << (i - 1));
3150 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3151 reg_val &= 0xfc0fffff;
3152 reg_val = reg_val | ((offs_6_1 - 1) << 20);
3153 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3156 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3157 reg_val &= 0xfdffffff;
3158 reg_val = reg_val | (0x1 << 25);
3159 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3161 lo_gn = OS_REG_READ(ah, AR9285_AN_RF2G9) & 0x1;
3164 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3165 reg_val &= 0xfdffffff;
3166 reg_val = reg_val | (offs_0 << 25);
3167 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3170 reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
3171 reg_val &= 0xffffff5f;
3172 OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
3175 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3176 reg_val |= (0x1 << 11);
3177 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3180 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
3181 reg_val &= 0xffffefff;
3182 OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
3184 /* set pdpadrv1=pdpadrv2=pdpaout=0 */
3185 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3186 reg_val &= 0xfc7fffff;
3187 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3189 /* Read back reflo, decrease it by 1 and write it. */
3190 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3191 reflo = (reg_val >> 26) & 0x7;
3195 reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3196 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3197 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3198 reflo = (reg_val >> 26) & 0x7;
3200 /* write back registers */
3201 OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, phy_tst_dac_reg_val);
3202 OS_REG_WRITE(ah, AR_PHY_TEST2, phy_test2_reg_val);
3203 OS_REG_WRITE(ah, AR_PHY_ADC_CTL, phy_adc_ctl_reg_val);
3204 OS_REG_WRITE(ah, AR9285_AN_TOP2, an_top2_reg_val);
3206 /* Kite 1.1 WAR for Bug 35666
3207 * Decrease the LDO value back to 1.20V */
3208 if (AR_SREV_KITE_11(ah)) {
3209 OS_REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
3214 /* ar9300_run_init_cals
3215 * Runs non-periodic calibrations
3217 inline static HAL_BOOL
3218 ar9300_run_init_cals(struct ath_hal *ah, int init_cal_count)
3220 struct ath_hal_9300 *ahp = AH9300(ah);
3221 HAL_CHANNEL_INTERNAL ichan; /* bogus */
3222 HAL_BOOL is_cal_done;
3223 HAL_CAL_LIST *curr_cal;
3224 const HAL_PERCAL_DATA *cal_data;
3227 curr_cal = ahp->ah_cal_list_curr;
3228 if (curr_cal == AH_NULL) {
3231 cal_data = curr_cal->cal_data;
3234 for (i = 0; i < init_cal_count; i++) {
3235 /* Reset this Cal */
3236 ar9300_reset_calibration(ah, curr_cal);
3237 /* Poll for offset calibration complete */
3239 ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL, 0))
3241 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3242 "%s: Cal %d failed to complete in 100ms.\n",
3243 __func__, curr_cal->cal_data->cal_type);
3244 /* Re-initialize list pointers for periodic cals */
3245 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr
3250 ar9300_per_calibration(
3251 ah, &ichan, ahp->ah_rx_chainmask, curr_cal, &is_cal_done);
3252 if (is_cal_done == AH_FALSE) {
3253 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3254 "%s: Not able to run Init Cal %d.\n", __func__,
3255 curr_cal->cal_data->cal_type);
3257 if (curr_cal->cal_next) {
3258 curr_cal = curr_cal->cal_next;
3262 /* Re-initialize list pointers for periodic cals */
3263 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3269 ar9300_tx_carrier_leak_war(struct ath_hal *ah)
3271 unsigned long tx_gain_table_max;
3272 unsigned long reg_bb_cl_map_0_b0 = 0xffffffff;
3273 unsigned long reg_bb_cl_map_1_b0 = 0xffffffff;
3274 unsigned long reg_bb_cl_map_2_b0 = 0xffffffff;
3275 unsigned long reg_bb_cl_map_3_b0 = 0xffffffff;
3276 unsigned long tx_gain, cal_run = 0;
3277 unsigned long cal_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3278 unsigned long cal_gain_index[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3279 unsigned long new_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3282 OS_MEMSET(new_gain, 0, sizeof(new_gain));
3283 /*printf(" Running TxCarrierLeakWAR\n");*/
3285 /* process tx gain table, we use cl_map_hw_gen=0. */
3286 OS_REG_RMW_FIELD(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_MAP_HW_GEN, 0);
3288 //the table we used is txbb_gc[2:0], 1dB[2:1].
3289 tx_gain_table_max = OS_REG_READ_FIELD(ah,
3290 AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX);
3292 for (i = 0; i <= tx_gain_table_max; i++) {
3293 tx_gain = OS_REG_READ(ah, AR_PHY_TXGAIN_TAB(1) + i * 4);
3294 cal_gain[i] = (((tx_gain >> 5)& 0x7) << 2) |
3295 (((tx_gain >> 1) & 0x3) << 0);
3297 cal_gain_index[i] = cal_run;
3302 for (j = 0; j < i; j++) {
3304 printf("i=%d, j=%d cal_gain[$i]=0x%04x\n", i, j, cal_gain[i]);
3307 if ((cal_gain[i] != cal_gain[j])) {
3310 /* if old gain found, use old cal_run value. */
3312 cal_gain_index[i] = cal_gain_index[j];
3316 /* if new gain found, increase cal_run */
3317 if (new_gain[i] == 1) {
3318 cal_gain_index[i] = cal_run;
3323 reg_bb_cl_map_0_b0 = (reg_bb_cl_map_0_b0 & ~(0x1 << i)) |
3324 ((cal_gain_index[i] >> 0 & 0x1) << i);
3325 reg_bb_cl_map_1_b0 = (reg_bb_cl_map_1_b0 & ~(0x1 << i)) |
3326 ((cal_gain_index[i] >> 1 & 0x1) << i);
3327 reg_bb_cl_map_2_b0 = (reg_bb_cl_map_2_b0 & ~(0x1 << i)) |
3328 ((cal_gain_index[i] >> 2 & 0x1) << i);
3329 reg_bb_cl_map_3_b0 = (reg_bb_cl_map_3_b0 & ~(0x1 << i)) |
3330 ((cal_gain_index[i] >> 3 & 0x1) << i);
3333 printf("i=%2d, cal_gain[$i]= 0x%04x, cal_run= %d, "
3334 "cal_gain_index[i]=%d, new_gain[i] = %d\n",
3335 i, cal_gain[i], cal_run, cal_gain_index[i], new_gain[i]);
3338 OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B0, reg_bb_cl_map_0_b0);
3339 OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B0, reg_bb_cl_map_1_b0);
3340 OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B0, reg_bb_cl_map_2_b0);
3341 OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B0, reg_bb_cl_map_3_b0);
3342 if (AR_SREV_WASP(ah)) {
3343 OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B1, reg_bb_cl_map_0_b0);
3344 OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B1, reg_bb_cl_map_1_b0);
3345 OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B1, reg_bb_cl_map_2_b0);
3346 OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B1, reg_bb_cl_map_3_b0);
3353 ar9300_invalidate_saved_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3355 #if ATH_SUPPORT_CAL_REUSE
3356 if (AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3357 ATH_CAL_REUSE_REDO_IN_FULL_RESET)
3359 ichan->one_time_txiqcal_done = AH_FALSE;
3360 ichan->one_time_txclcal_done = AH_FALSE;
3365 static inline HAL_BOOL
3366 ar9300_restore_rtt_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3368 HAL_BOOL restore_status = AH_FALSE;
3370 return restore_status;
3374 * Initialize Calibration infrastructure
3376 static inline HAL_BOOL
3377 ar9300_init_cal_internal(struct ath_hal *ah, struct ieee80211_channel *chan,
3378 HAL_CHANNEL_INTERNAL *ichan,
3379 HAL_BOOL enable_rtt, HAL_BOOL do_rtt_cal, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3381 struct ath_hal_9300 *ahp = AH9300(ah);
3382 HAL_BOOL txiqcal_success_flag = AH_FALSE;
3383 HAL_BOOL cal_done = AH_FALSE;
3385 HAL_BOOL do_sep_iq_cal = AH_FALSE;
3386 HAL_BOOL do_agc_cal = do_rtt_cal;
3387 HAL_BOOL is_cal_reusable = AH_TRUE;
3388 #if ATH_SUPPORT_CAL_REUSE
3389 HAL_BOOL cal_reuse_enable = AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3390 ATH_CAL_REUSE_ENABLE;
3391 HAL_BOOL clc_success = AH_FALSE;
3392 int32_t ch_idx, j, cl_tab_reg;
3393 u_int32_t BB_cl_tab_entry = MAX_BB_CL_TABLE_ENTRY;
3394 u_int32_t BB_cl_tab_b[AR9300_MAX_CHAINS] = {
3401 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
3403 ahp->ah_rx_cal_chainmask = 0x1;
3404 ahp->ah_tx_cal_chainmask = 0x1;
3405 } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah)) {
3406 /* Wasp/Jupiter: 2 x 2 */
3407 ahp->ah_rx_cal_chainmask = 0x3;
3408 ahp->ah_tx_cal_chainmask = 0x3;
3411 * Osprey needs to be configured for the correct chain mode
3412 * before running AGC/TxIQ cals.
3414 if (ahp->ah_enterprise_mode & AR_ENT_OTP_CHAIN2_DISABLE) {
3415 /* chain 2 disabled - 2 chain mode */
3416 ahp->ah_rx_cal_chainmask = 0x3;
3417 ahp->ah_tx_cal_chainmask = 0x3;
3419 ahp->ah_rx_cal_chainmask = 0x7;
3420 ahp->ah_tx_cal_chainmask = 0x7;
3423 ar9300_init_chain_masks(ah, ahp->ah_rx_cal_chainmask, ahp->ah_tx_cal_chainmask);
3426 if (ahp->tx_cl_cal_enable) {
3427 #if ATH_SUPPORT_CAL_REUSE
3428 /* disable Carrie Leak or set do_agc_cal accordingly */
3429 if (cal_reuse_enable && ichan->one_time_txclcal_done)
3431 OS_REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3433 #endif /* ATH_SUPPORT_CAL_REUSE */
3435 OS_REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3436 do_agc_cal = AH_TRUE;
3440 /* Do Tx IQ Calibration here for osprey hornet and wasp */
3441 /* XXX: For initial wasp bringup - check and enable this */
3442 /* EV 74233: Tx IQ fails to complete for half/quarter rates */
3443 if (!(IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) {
3444 if (ahp->tx_iq_cal_enable) {
3445 /* this should be eventually moved to INI file */
3446 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1(ah),
3447 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
3450 * For poseidon and later chips,
3451 * Tx IQ cal HW run will be a part of AGC calibration
3453 if (ahp->tx_iq_cal_during_agc_cal) {
3455 * txiqcal_success_flag always set to 1 to run
3456 * ar9300_tx_iq_cal_post_proc
3457 * if following AGC cal passes
3459 #if ATH_SUPPORT_CAL_REUSE
3460 if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3462 txiqcal_success_flag = AH_TRUE;
3463 OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3464 OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) |
3465 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3467 OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3468 OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) &
3469 (~AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL));
3472 if (OS_REG_READ_FIELD(ah,
3473 AR_PHY_TX_IQCAL_CONTROL_0(ah),
3474 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)){
3475 if (apply_last_iqcorr == AH_TRUE) {
3476 OS_REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3477 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3478 txiqcal_success_flag = AH_FALSE;
3480 txiqcal_success_flag = AH_TRUE;
3483 txiqcal_success_flag = AH_FALSE;
3486 if (txiqcal_success_flag) {
3487 do_agc_cal = AH_TRUE;
3490 #if ATH_SUPPORT_CAL_REUSE
3491 if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3494 do_sep_iq_cal = AH_TRUE;
3495 do_agc_cal = AH_TRUE;
3501 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
3502 IS_CHAN_2GHZ(ichan) &&
3503 (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3505 !(ah->ah_config.ath_hal_mci_config &
3506 ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3508 u_int32_t payload[4] = {0, 0, 0, 0};
3510 /* Send CAL_REQ only when BT is AWAKE. */
3511 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_REQ 0x%X\n",
3512 __func__, ahp->ah_mci_wlan_cal_seq);
3513 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_REQ);
3514 payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_seq++;
3515 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3517 /* Wait BT_CAL_GRANT for 50ms */
3518 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3519 "(MCI) %s: Wait for BT_CAL_GRANT\n", __func__);
3520 if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000))
3522 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3523 "(MCI) %s: Got BT_CAL_GRANT.\n", __func__);
3526 is_cal_reusable = AH_FALSE;
3527 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3528 "(MCI) %s: BT is not responding.\n", __func__);
3531 #endif /* ATH_SUPPORT_MCI */
3535 /* enable Tx IQ Calibration HW for osprey/hornet/wasp */
3536 txiqcal_success_flag = ar9300_tx_iq_cal_hw_run(ah);
3537 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
3539 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
3542 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
3543 ar9300_tx_carrier_leak_war(ah);
3549 * Tx IQ cal is a part of AGC cal for Jupiter/Poseidon, etc.
3550 * please enable the bit of txiqcal_control_0[31] in INI file
3551 * for Jupiter/Poseidon/etc.
3553 if(!AR_SREV_SCORPION(ah)) {
3554 if (do_agc_cal || !skip_if_none) {
3555 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3556 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3558 /* Poll for offset calibration complete */
3559 cal_done = ath_hal_wait(ah,
3560 AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0);
3562 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3563 "(FCS) CAL NOT DONE!!! - %d\n", ichan->channel);
3569 * Tx IQ cal post-processing in SW
3570 * This part of code should be common to all chips,
3571 * no chip specific code for Jupiter/Posdeion except for register names.
3573 if (txiqcal_success_flag) {
3574 ar9300_tx_iq_cal_post_proc(ah,ichan, 1, 1,is_cal_reusable, AH_FALSE);
3577 if (!txiqcal_success_flag) {
3578 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3579 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3580 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
3582 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3583 "%s: offset calibration failed to complete in 1ms; "
3584 "noisy environment?\n", __func__);
3587 if (apply_last_iqcorr == AH_TRUE) {
3588 ar9300_tx_iq_cal_post_proc(ah, ichan, 0, 0, is_cal_reusable, AH_TRUE);
3591 for (iqcal_idx=0;iqcal_idx<MAXIQCAL;iqcal_idx++) {
3592 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3593 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3595 /* Poll for offset calibration complete */
3596 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL,
3597 AR_PHY_AGC_CONTROL_CAL, 0)) {
3598 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3599 "%s: offset calibration failed to complete in 1ms; "
3600 "noisy environment?\n", __func__);
3604 * Tx IQ cal post-processing in SW
3605 * This part of code should be common to all chips,
3606 * no chip specific code for Jupiter/Posdeion except for register names.
3608 ar9300_tx_iq_cal_post_proc(ah, ichan, iqcal_idx+1, MAXIQCAL, is_cal_reusable, AH_FALSE);
3615 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
3616 IS_CHAN_2GHZ(ichan) &&
3617 (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3619 !(ah->ah_config.ath_hal_mci_config &
3620 ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3622 u_int32_t payload[4] = {0, 0, 0, 0};
3624 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_DONE 0x%X\n",
3625 __func__, ahp->ah_mci_wlan_cal_done);
3626 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE);
3627 payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_done++;
3628 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3630 #endif /* ATH_SUPPORT_MCI */
3633 if (!cal_done && !AR_SREV_SCORPION(ah) )
3635 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3636 "%s: offset calibration failed to complete in 1ms; "
3637 "noisy environment?\n", __func__);
3642 /* Beacon stuck fix, refer to EV 120056 */
3643 if(IS_CHAN_2GHZ(chan) && AR_SREV_SCORPION(ah))
3644 OS_REG_WRITE(ah, AR_PHY_TIMING5, OS_REG_READ(ah,AR_PHY_TIMING5) & ~AR_PHY_TIMING5_CYCPWR_THR1_ENABLE);
3648 /* Do PA Calibration */
3649 if (AR_SREV_KITE(ah) && AR_SREV_KITE_11_OR_LATER(ah)) {
3654 #if ATH_SUPPORT_CAL_REUSE
3655 if (ichan->one_time_txiqcal_done) {
3656 ar9300_tx_iq_cal_apply(ah, ichan);
3657 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3658 "(FCS) TXIQCAL applied - %d\n", ichan->channel);
3660 #endif /* ATH_SUPPORT_CAL_REUSE */
3662 #if ATH_SUPPORT_CAL_REUSE
3663 if (cal_reuse_enable && ahp->tx_cl_cal_enable)
3665 clc_success = (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) &
3666 AR_PHY_AGC_CONTROL_CLC_SUCCESS) ? 1 : 0;
3668 if (ichan->one_time_txclcal_done)
3670 /* reapply CL cal results */
3671 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3672 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3675 cl_tab_reg = BB_cl_tab_b[ch_idx];
3676 for (j = 0; j < BB_cl_tab_entry; j++) {
3677 OS_REG_WRITE(ah, cl_tab_reg, ichan->tx_clcal[ch_idx][j]);
3681 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3682 "(FCS) TX CL CAL applied - %d\n", ichan->channel);
3684 else if (is_cal_reusable && clc_success) {
3685 /* save CL cal results */
3686 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3687 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3690 cl_tab_reg = BB_cl_tab_b[ch_idx];
3691 for (j = 0; j < BB_cl_tab_entry; j++) {
3692 ichan->tx_clcal[ch_idx][j] = OS_REG_READ(ah, cl_tab_reg);
3696 ichan->one_time_txclcal_done = AH_TRUE;
3697 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3698 "(FCS) TX CL CAL saved - %d\n", ichan->channel);
3701 #endif /* ATH_SUPPORT_CAL_REUSE */
3703 /* Revert chainmasks to their original values before NF cal */
3704 ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
3706 #if !FIX_NOISE_FLOOR
3708 * Do NF calibration after DC offset and other CALs.
3709 * Per system engineers, noise floor value can sometimes be 20 dB
3710 * higher than normal value if DC offset and noise floor cal are
3711 * triggered at the same time.
3713 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3714 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
3717 /* Initialize list pointers */
3718 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3721 * Enable IQ, ADC Gain, ADC DC Offset Cals
3723 /* Setup all non-periodic, init time only calibrations */
3724 /* XXX: Init DC Offset not working yet */
3726 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, ADC_DC_INIT_CAL)) {
3727 INIT_CAL(&ahp->ah_adc_dc_cal_init_data);
3728 INSERT_CAL(ahp, &ahp->ah_adc_dc_cal_init_data);
3731 /* Initialize current pointer to first element in list */
3732 ahp->ah_cal_list_curr = ahp->ah_cal_list;
3734 if (ahp->ah_cal_list_curr) {
3735 if (ar9300_run_init_cals(ah, 0) == AH_FALSE) {
3740 /* end - Init time calibrations */
3742 /* If Cals are supported, add them to list via INIT/INSERT_CAL */
3743 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, IQ_MISMATCH_CAL)) {
3744 INIT_CAL(&ahp->ah_iq_cal_data);
3745 INSERT_CAL(ahp, &ahp->ah_iq_cal_data);
3746 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3747 "%s: enabling IQ Calibration.\n", __func__);
3749 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, TEMP_COMP_CAL)) {
3750 INIT_CAL(&ahp->ah_temp_comp_cal_data);
3751 INSERT_CAL(ahp, &ahp->ah_temp_comp_cal_data);
3752 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3753 "%s: enabling Temperature Compensation Calibration.\n", __func__);
3756 /* Initialize current pointer to first element in list */
3757 ahp->ah_cal_list_curr = ahp->ah_cal_list;
3759 /* Reset state within current cal */
3760 if (ahp->ah_cal_list_curr) {
3761 ar9300_reset_calibration(ah, ahp->ah_cal_list_curr);
3764 /* Mark all calibrations on this channel as being invalid */
3765 ichan->calValid = 0;
3770 static inline HAL_BOOL
3771 ar9300_init_cal(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3773 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
3774 HAL_BOOL do_rtt_cal = AH_TRUE;
3775 HAL_BOOL enable_rtt = AH_FALSE;
3779 return ar9300_init_cal_internal(ah, chan, ichan, enable_rtt, do_rtt_cal, skip_if_none, apply_last_iqcorr);
3782 /* ar9300_reset_cal_valid
3783 * Entry point for upper layers to restart current cal.
3784 * Reset the calibration valid bit in channel.
3787 ar9300_reset_cal_valid(struct ath_hal *ah, const struct ieee80211_channel *chan,
3788 HAL_BOOL *is_cal_done, u_int32_t cal_type)
3790 struct ath_hal_9300 *ahp = AH9300(ah);
3791 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
3792 HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr;
3794 *is_cal_done = AH_TRUE;
3796 if (curr_cal == AH_NULL) {
3799 if (ichan == AH_NULL) {
3800 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3801 "%s: invalid channel %u/0x%x; no mapping\n",
3802 __func__, chan->ic_freq, chan->ic_flags);
3806 if (!(cal_type & IQ_MISMATCH_CAL)) {
3807 *is_cal_done = AH_FALSE;
3811 /* Expected that this calibration has run before, post-reset.
3812 * Current state should be done
3814 if (curr_cal->cal_state != CAL_DONE) {
3815 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3816 "%s: Calibration state incorrect, %d\n",
3817 __func__, curr_cal->cal_state);
3821 /* Verify Cal is supported on this channel */
3822 if (ar9300_is_cal_supp(ah, chan, curr_cal->cal_data->cal_type) == AH_FALSE) {
3826 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3827 "%s: Resetting Cal %d state for channel %u/0x%x\n", __func__,
3828 curr_cal->cal_data->cal_type, chan->ic_freq, chan->ic_flags);
3830 /* Disable cal validity in channel */
3831 ichan->calValid &= ~curr_cal->cal_data->cal_type;
3832 curr_cal->cal_state = CAL_WAITING;
3833 /* Indicate to upper layers that we need polling */
3834 *is_cal_done = AH_FALSE;
3838 ar9300_set_dma(struct ath_hal *ah)
3841 struct ath_hal_9300 *ahp = AH9300(ah);
3845 * set AHB_MODE not to do cacheline prefetches
3847 regval = OS_REG_READ(ah, AR_AHB_MODE);
3848 OS_REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
3852 * let mac dma reads be in 128 byte chunks
3854 regval = OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
3855 OS_REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
3858 * Restore TX Trigger Level to its pre-reset value.
3859 * The initial value depends on whether aggregation is enabled, and is
3860 * adjusted whenever underruns are detected.
3863 OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, AH_PRIVATE(ah)->ah_tx_trig_level);
3866 * Osprey 1.0 bug (EV 61936). Don't change trigger level from .ini default.
3867 * Osprey 2.0 - hardware recommends using the default INI settings.
3870 OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, 0x3f);
3873 * let mac dma writes be in 128 byte chunks
3875 regval = OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
3876 OS_REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
3879 * Setup receive FIFO threshold to hold off TX activities
3881 OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
3884 * reduce the number of usable entries in PCU TXBUF to avoid
3885 * wrap around bugs. (bug 20428)
3888 if (AR_SREV_WASP(ah) &&
3889 (AH_PRIVATE((ah))->ah_macRev > AR_SREV_REVISION_WASP_12)) {
3890 /* Wasp 1.3 fix for EV#85395 requires usable entries
3891 * to be set to 0x500
3893 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 0x500);
3895 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE);
3899 * Enable HPQ for UAPSD
3901 if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) {
3902 OS_REG_WRITE(ah, AR_HP_Q_CONTROL,
3903 AR_HPQ_ENABLE | AR_HPQ_UAPSD | AR_HPQ_UAPSD_TRIGGER_EN);
3907 * set the transmit status ring
3909 ar9300_reset_tx_status_ring(ah);
3912 * set rxbp threshold. Must be non-zero for RX_EOL to occur.
3913 * For Osprey 2.0+, keep the original thresholds
3914 * otherwise performance is lost due to excessive RX EOL interrupts.
3916 OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1);
3917 OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1);
3920 * set receive buffer size.
3922 if (ahp->rx_buf_size) {
3923 OS_REG_WRITE(ah, AR_DATABUF, ahp->rx_buf_size);
3928 ar9300_init_bb(struct ath_hal *ah, struct ieee80211_channel *chan)
3930 u_int32_t synth_delay;
3933 * Wait for the frequency synth to settle (synth goes on
3934 * via AR_PHY_ACTIVE_EN). Read the phy active delay register.
3935 * Value is in 100ns increments.
3937 synth_delay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
3938 if (IEEE80211_IS_CHAN_CCK(chan)) {
3939 synth_delay = (4 * synth_delay) / 22;
3944 /* Activate the PHY (includes baseband activate + synthesizer on) */
3945 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
3948 * There is an issue if the AP starts the calibration before
3949 * the base band timeout completes. This could result in the
3950 * rx_clear AH_FALSE triggering. As a workaround we add delay an
3951 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
3954 OS_DELAY(synth_delay + BASE_ACTIVATE_DELAY);
3958 ar9300_init_interrupt_masks(struct ath_hal *ah, HAL_OPMODE opmode)
3960 struct ath_hal_9300 *ahp = AH9300(ah);
3961 u_int32_t msi_cfg = 0;
3962 u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
3965 * Setup interrupt handling. Note that ar9300_reset_tx_queue
3966 * manipulates the secondary IMR's as queues are enabled
3967 * and disabled. This is done with RMW ops to insure the
3968 * settings we make here are preserved.
3971 AR_IMR_TXERR | AR_IMR_TXURN |
3972 AR_IMR_RXERR | AR_IMR_RXORN |
3975 if (ahp->ah_intr_mitigation_rx) {
3976 /* enable interrupt mitigation for rx */
3977 ahp->ah_mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR | AR_IMR_RXOK_HP;
3978 msi_cfg |= AR_INTCFG_MSI_RXINTM | AR_INTCFG_MSI_RXMINTR;
3980 ahp->ah_mask_reg |= AR_IMR_RXOK_LP | AR_IMR_RXOK_HP;
3981 msi_cfg |= AR_INTCFG_MSI_RXOK;
3983 if (ahp->ah_intr_mitigation_tx) {
3984 /* enable interrupt mitigation for tx */
3985 ahp->ah_mask_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR;
3986 msi_cfg |= AR_INTCFG_MSI_TXINTM | AR_INTCFG_MSI_TXMINTR;
3988 ahp->ah_mask_reg |= AR_IMR_TXOK;
3989 msi_cfg |= AR_INTCFG_MSI_TXOK;
3991 if (opmode == HAL_M_HOSTAP) {
3992 ahp->ah_mask_reg |= AR_IMR_MIB;
3995 OS_REG_WRITE(ah, AR_IMR, ahp->ah_mask_reg);
3996 OS_REG_WRITE(ah, AR_IMR_S2, OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
3997 ahp->ah_mask2Reg = OS_REG_READ(ah, AR_IMR_S2);
3999 if (ah->ah_config.ath_hal_enable_msi) {
4000 /* Cache MSI register value */
4001 ahp->ah_msi_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI));
4002 ahp->ah_msi_reg |= AR_PCIE_MSI_HW_DBI_WR_EN;
4003 if (AR_SREV_POSEIDON(ah)) {
4004 ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
4006 ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR;
4008 /* Program MSI configuration */
4009 OS_REG_WRITE(ah, AR_INTCFG, msi_cfg);
4013 * debug - enable to see all synchronous interrupts status
4015 /* Clear any pending sync cause interrupts */
4016 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE), 0xFFFFFFFF);
4018 /* Allow host interface sync interrupt sources to set cause bit */
4019 if (AR_SREV_POSEIDON(ah)) {
4020 sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
4022 else if (AR_SREV_WASP(ah)) {
4023 sync_en_def = AR9340_INTR_SYNC_DEFAULT;
4026 AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), sync_en_def);
4028 /* _Disable_ host interface sync interrupt when cause bits set */
4029 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK), 0);
4031 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE), 0);
4032 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_MASK), 0);
4033 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_ENABLE), 0);
4034 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_MASK), 0);
4038 ar9300_init_qos(struct ath_hal *ah)
4040 OS_REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); /* XXX magic */
4041 OS_REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); /* XXX magic */
4043 /* Turn on NOACK Support for QoS packets */
4044 OS_REG_WRITE(ah, AR_QOS_NO_ACK,
4045 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
4046 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
4047 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
4050 * initialize TXOP for all TIDs
4052 OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
4053 OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
4054 OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
4055 OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
4056 OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
4060 ar9300_init_user_settings(struct ath_hal *ah)
4062 struct ath_hal_9300 *ahp = AH9300(ah);
4064 /* Restore user-specified settings */
4065 HALDEBUG(ah, HAL_DEBUG_RESET,
4066 "--AP %s ahp->ah_misc_mode 0x%x\n", __func__, ahp->ah_misc_mode);
4067 if (ahp->ah_misc_mode != 0) {
4069 AR_PCU_MISC, OS_REG_READ(ah, AR_PCU_MISC) | ahp->ah_misc_mode);
4071 if (ahp->ah_get_plcp_hdr) {
4072 OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM);
4074 if (ahp->ah_slot_time != (u_int) -1) {
4075 ar9300_set_slot_time(ah, ahp->ah_slot_time);
4077 if (ahp->ah_ack_timeout != (u_int) -1) {
4078 ar9300_set_ack_timeout(ah, ahp->ah_ack_timeout);
4080 if (AH_PRIVATE(ah)->ah_diagreg != 0) {
4081 OS_REG_SET_BIT(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
4083 if (ahp->ah_beacon_rssi_threshold != 0) {
4084 ar9300_set_hw_beacon_rssi_threshold(ah, ahp->ah_beacon_rssi_threshold);
4086 #ifdef ATH_SUPPORT_DFS
4087 if (ahp->ah_cac_quiet_enabled) {
4088 ar9300_cac_tx_quiet(ah, 1);
4090 #endif /* ATH_SUPPORT_DFS */
4094 ar9300_get_spur_info(struct ath_hal * ah, int *enable, int len, u_int16_t *freq)
4096 // struct ath_hal_private *ap = AH_PRIVATE(ah);
4099 for (i = 0; i < len; i++) {
4103 *enable = ah->ah_config.ath_hal_spur_mode;
4104 for (i = 0, j = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4105 if (AH9300(ah)->ath_hal_spur_chans[i][0] != AR_NO_SPUR) {
4106 freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][0];
4107 HALDEBUG(ah, HAL_DEBUG_ANI,
4108 "1. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][0]);
4110 if (AH9300(ah)->ath_hal_spur_chans[i][1] != AR_NO_SPUR) {
4111 freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][1];
4112 HALDEBUG(ah, HAL_DEBUG_ANI,
4113 "2. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][1]);
4120 #define ATH_HAL_2GHZ_FREQ_MIN 20000
4121 #define ATH_HAL_2GHZ_FREQ_MAX 29999
4122 #define ATH_HAL_5GHZ_FREQ_MIN 50000
4123 #define ATH_HAL_5GHZ_FREQ_MAX 59999
4127 ar9300_set_spur_info(struct ath_hal * ah, int enable, int len, u_int16_t *freq)
4129 struct ath_hal_private *ap = AH_PRIVATE(ah);
4132 ap->ah_config.ath_hal_spur_mode = enable;
4134 if (ap->ah_config.ath_hal_spur_mode == SPUR_ENABLE_IOCTL) {
4135 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4136 AH9300(ah)->ath_hal_spur_chans[i][0] = AR_NO_SPUR;
4137 AH9300(ah)->ath_hal_spur_chans[i][1] = AR_NO_SPUR;
4139 for (i = 0, j = 0, k = 0; i < len; i++) {
4140 if (freq[i] > ATH_HAL_2GHZ_FREQ_MIN &&
4141 freq[i] < ATH_HAL_2GHZ_FREQ_MAX)
4144 if (j < AR_EEPROM_MODAL_SPURS) {
4145 AH9300(ah)->ath_hal_spur_chans[j++][1] = freq[i];
4146 HALDEBUG(ah, HAL_DEBUG_ANI, "1 set spur %d\n", freq[i]);
4148 } else if (freq[i] > ATH_HAL_5GHZ_FREQ_MIN &&
4149 freq[i] < ATH_HAL_5GHZ_FREQ_MAX)
4152 if (k < AR_EEPROM_MODAL_SPURS) {
4153 AH9300(ah)->ath_hal_spur_chans[k++][0] = freq[i];
4154 HALDEBUG(ah, HAL_DEBUG_ANI, "2 set spur %d\n", freq[i]);
4164 #define ar9300_check_op_mode(_opmode) \
4165 ((_opmode == HAL_M_STA) || (_opmode == HAL_M_IBSS) ||\
4166 (_opmode == HAL_M_HOSTAP) || (_opmode == HAL_M_MONITOR))
4171 #ifndef ATH_NF_PER_CHAN
4173 * To fixed first reset noise floor value not correct issue
4174 * For ART need it to fixed low rate sens too low issue
4177 First_NFCal(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
4178 int is_scan, struct ieee80211_channel *chan)
4180 HAL_NFCAL_HIST_FULL *nfh;
4182 int16_t nfarray[HAL_NUM_NF_READINGS] = {0};
4187 int16_t nf_buf[HAL_NUM_NF_READINGS];
4188 #define IS(_c, _f) (((_c)->channel_flags & _f) || 0)
4192 chan->ic_freq == AH_PRIVATE(ah)->ah_curchan->ic_freq)
4194 nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4196 nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4199 ar9300_start_nf_cal(ah);
4200 for (j = 0; j < 10000; j++) {
4201 if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){
4207 is_2g = IEEE80211_IS_CHAN_2GHZ(chan);
4208 ar9300_upload_noise_floor(ah, is_2g, nfarray);
4212 * This channel's NF cal info is just a HAL_NFCAL_HIST_SMALL struct
4213 * rather than a HAL_NFCAL_HIST_FULL struct.
4214 * As long as we only use the first history element of nf_cal_buffer
4215 * (nf_cal_buffer[0][0:HAL_NUM_NF_READINGS-1]), we can use
4216 * HAL_NFCAL_HIST_SMALL and HAL_NFCAL_HIST_FULL interchangeably.
4218 nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4219 nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
4221 nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4222 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
4225 for (i = 0; i < HAL_NUM_NF_READINGS; i ++) {
4226 for (k = 0; k < HAL_NF_CAL_HIST_LEN_FULL; k++) {
4227 nfh->nf_cal_buffer[k][i] = nfarray[i];
4229 nfh->base.priv_nf[i] = ar9300_limit_nf_range(ah,
4230 ar9300_get_nf_hist_mid(ah, nfh, i, nf_hist_len));
4234 //ar9300StoreNewNf(ah, ichan, is_scan);
4237 * See if the NF value from the old channel should be
4238 * retained when switching to a new channel.
4239 * TBD: this may need to be changed, as it wipes out the
4240 * purpose of saving NF values for each channel.
4242 for (i = 0; i < HAL_NUM_NF_READINGS; i++)
4244 if (IEEE80211_IS_CHAN_2GHZ(chan))
4246 if (nfh->nf_cal_buffer[0][i] <
4247 AR_PHY_CCA_MAX_GOOD_VAL_OSPREY_2GHZ)
4249 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4250 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4253 if (AR_SREV_AR9580(ah)) {
4254 if (nfh->nf_cal_buffer[0][i] <
4255 AR_PHY_CCA_NOM_VAL_PEACOCK_5GHZ)
4257 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4258 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4261 if (nfh->nf_cal_buffer[0][i] <
4262 AR_PHY_CCA_NOM_VAL_OSPREY_5GHZ)
4264 ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4265 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4271 * Copy the channel's NF buffer, which may have been modified
4272 * just above here, to the full NF history buffer.
4274 ar9300_reset_nf_hist_buff(ah, ichan);
4275 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
4276 ar9300_load_nf(ah, nf_buf);
4288 * Places the device in and out of reset and then places sane
4289 * values in the registers based on EEPROM config, initialization
4290 * vectors (as determined by the mode), and station configuration
4292 * b_channel_change is used to preserve DMA/PCU registers across
4293 * a HW Reset during channel change.
4296 ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan,
4297 HAL_HT_MACMODE macmode, u_int8_t txchainmask, u_int8_t rxchainmask,
4298 HAL_HT_EXTPROTSPACING extprotspacing, HAL_BOOL b_channel_change,
4299 HAL_STATUS *status, int is_scan)
4301 #define FAIL(_code) do { ecode = _code; goto bad; } while (0)
4302 u_int32_t save_led_state;
4303 struct ath_hal_9300 *ahp = AH9300(ah);
4304 struct ath_hal_private *ap = AH_PRIVATE(ah);
4305 HAL_CHANNEL_INTERNAL *ichan;
4306 //const struct ieee80211_channel *curchan = ap->ah_curchan;
4308 HAL_BOOL save_full_sleep = ahp->ah_chip_full_sleep;
4310 u_int32_t save_def_antenna;
4311 u_int32_t mac_sta_id1;
4313 int i, rx_chainmask;
4314 int nf_hist_buff_reset = 0;
4315 int16_t nf_buf[HAL_NUM_NF_READINGS];
4316 #ifdef ATH_FORCE_PPM
4317 u_int32_t save_force_val, tmp_reg;
4319 HAL_BOOL stopped, cal_ret;
4320 HAL_BOOL apply_last_iqcorr = AH_FALSE;
4322 if (OS_REG_READ(ah, AR_IER) == AR_IER_ENABLE) {
4323 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "** Reset called with WLAN "
4324 "interrupt enabled %08x **\n", ar9300_get_interrupts(ah));
4328 * Set the status to "ok" by default to cover the cases
4329 * where we return AH_FALSE without going to "bad"
4333 if ((ah->ah_config.ath_hal_sta_update_tx_pwr_enable)) {
4334 AH9300(ah)->green_tx_status = HAL_RSSI_TX_POWER_NONE;
4338 if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
4339 (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)))
4341 ar9300_mci_2g5g_changed(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4345 ahp->ah_ext_prot_spacing = extprotspacing;
4346 ahp->ah_tx_chainmask = txchainmask & ap->ah_caps.halTxChainMask;
4347 ahp->ah_rx_chainmask = rxchainmask & ap->ah_caps.halRxChainMask;
4348 ahp->ah_tx_cal_chainmask = ap->ah_caps.halTxChainMask;
4349 ahp->ah_rx_cal_chainmask = ap->ah_caps.halRxChainMask;
4350 HALASSERT(ar9300_check_op_mode(opmode));
4352 OS_MARK(ah, AH_MARK_RESET, b_channel_change);
4355 * Map public channel to private.
4357 ichan = ar9300_check_chan(ah, chan);
4358 if (ichan == AH_NULL) {
4359 HALDEBUG(ah, HAL_DEBUG_CHANNEL,
4360 "%s: invalid channel %u/0x%x; no mapping\n",
4361 __func__, chan->ic_freq, chan->ic_flags);
4365 ichan->paprd_table_write_done = 0; /* Clear PAPRD table write flag */
4367 chan->paprd_table_write_done = 0; /* Clear PAPRD table write flag */
4370 if (ar9300_get_power_mode(ah) != HAL_PM_FULL_SLEEP) {
4371 /* Need to stop RX DMA before reset otherwise chip might hang */
4372 stopped = ar9300_set_rx_abort(ah, AH_TRUE); /* abort and disable PCU */
4373 ar9300_set_rx_filter(ah, 0);
4374 stopped &= ar9300_stop_dma_receive(ah, 0); /* stop and disable RX DMA */
4377 * During the transition from full sleep to reset,
4378 * recv DMA regs are not available to be read
4380 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4381 "%s[%d]: ar9300_stop_dma_receive failed\n", __func__, __LINE__);
4382 b_channel_change = AH_FALSE;
4385 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4386 "%s[%d]: Chip is already in full sleep\n", __func__, __LINE__);
4390 if ((AH_PRIVATE(ah)->ah_caps.halMciSupport) &&
4391 (ahp->ah_mci_bt_state == MCI_BT_CAL_START))
4393 u_int32_t payload[4] = {0, 0, 0, 0};
4395 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4396 "(MCI) %s: Stop rx for BT cal.\n", __func__);
4397 ahp->ah_mci_bt_state = MCI_BT_CAL;
4400 * MCIFIX: disable mci interrupt here. This is to avoid SW_MSG_DONE or
4401 * RX_MSG bits to trigger MCI_INT and lead to mci_intr reentry.
4403 ar9300_mci_disable_interrupt(ah);
4405 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4406 "(MCI) %s: Send WLAN_CAL_GRANT\n", __func__);
4407 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
4408 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
4410 /* Wait BT calibration to be completed for 25ms */
4411 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4412 "(MCI) %s: BT is calibrating.\n", __func__);
4413 if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE, 0, 25000)) {
4414 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4415 "(MCI) %s: Got BT_CAL_DONE.\n", __func__);
4418 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4419 "(MCI) %s: ### BT cal takes too long. Force bt_state to be bt_awake.\n",
4422 ahp->ah_mci_bt_state = MCI_BT_AWAKE;
4423 /* MCIFIX: enable mci interrupt here */
4424 ar9300_mci_enable_interrupt(ah);
4430 /* Bring out of sleep mode */
4431 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
4432 *status = HAL_INV_PMODE;
4436 /* Check the Rx mitigation config again, it might have changed
4437 * during attach in ath_vap_attach.
4439 if (ah->ah_config.ath_hal_intr_mitigation_rx != 0) {
4440 ahp->ah_intr_mitigation_rx = AH_TRUE;
4442 ahp->ah_intr_mitigation_rx = AH_FALSE;
4448 * This is painful because we don't have a non-const channel pointer
4451 * Make sure this gets fixed!
4454 /* Get the value from the previous NF cal and update history buffer */
4455 if (curchan && (ahp->ah_chip_full_sleep != AH_TRUE)) {
4456 ar9300_store_new_nf(ah, curchan, is_scan);
4461 * Account for the effect of being in either the 2 GHz or 5 GHz band
4462 * on the nominal, max allowable, and min allowable noise floor values.
4464 AH9300(ah)->nfp = IS_CHAN_2GHZ(ichan) ? &ahp->nf_2GHz : &ahp->nf_5GHz;
4467 * XXX For now, don't apply the last IQ correction.
4469 * This should be done when scorpion is enabled on FreeBSD; just be
4470 * sure to fix this channel match code so it uses net80211 flags
4474 if (AR_SREV_SCORPION(ah) && curchan && (chan->channel == curchan->channel) &&
4475 ((chan->channel_flags & (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)) ==
4476 (curchan->channel_flags &
4477 (CHANNEL_ALL | CHANNEL_HALF | CHANNEL_QUARTER)))) {
4478 apply_last_iqcorr = AH_TRUE;
4481 apply_last_iqcorr = AH_FALSE;
4484 #ifndef ATH_NF_PER_CHAN
4486 * If there's only one full-size home-channel NF history buffer
4487 * rather than a full-size NF history buffer per channel, decide
4488 * whether to (re)initialize the home-channel NF buffer.
4489 * If this is just a channel change for a scan, or if the channel
4490 * is not being changed, don't mess up the home channel NF history
4491 * buffer with NF values from this scanned channel. If we're
4492 * changing the home channel to a new channel, reset the home-channel
4493 * NF history buffer with the most accurate NF known for the new channel.
4495 if (!is_scan && (!ap->ah_curchan ||
4496 ap->ah_curchan->ic_freq != chan->ic_freq)) // ||
4497 // ap->ah_curchan->channel_flags != chan->channel_flags))
4499 nf_hist_buff_reset = 1;
4500 ar9300_reset_nf_hist_buff(ah, ichan);
4504 * Fast channel change (Change synthesizer based on channel freq
4505 * without resetting chip)
4508 * - Chip is just coming out of full sleep
4509 * - Channel to be set is same as current channel
4510 * - Channel flags are different, like when moving from 2GHz to 5GHz
4512 * - Merlin: Switching in/out of fast clock enabled channels
4513 * (not currently coded, since fast clock is enabled
4514 * across the 5GHz band
4515 * and we already do a full reset when switching in/out
4519 if (b_channel_change &&
4520 (ahp->ah_chip_full_sleep != AH_TRUE) &&
4521 (AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4522 ((chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
4523 (((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & chan->channel_flags) ==
4524 ((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & AH_PRIVATE(ah)->ah_curchan->channel_flags))))
4526 if (ar9300_channel_change(ah, chan, ichan, macmode)) {
4527 chan->channel_flags = ichan->channel_flags;
4528 chan->priv_flags = ichan->priv_flags;
4529 AH_PRIVATE(ah)->ah_curchan->ah_channel_time = 0;
4530 AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar9300_get_tsf64(ah);
4533 * Load the NF from history buffer of the current channel.
4534 * NF is slow time-variant, so it is OK to use a historical value.
4536 ar9300_get_nf_hist_base(ah,
4537 AH_PRIVATE(ah)->ah_curchan, is_scan, nf_buf);
4538 ar9300_load_nf(ah, nf_buf);
4540 /* start NF calibration, without updating BB NF register*/
4541 ar9300_start_nf_cal(ah);
4544 * If channel_change completed and DMA was stopped
4545 * successfully - skip the rest of reset
4547 if (AH9300(ah)->ah_dma_stuck != AH_TRUE) {
4548 WAR_USB_DISABLE_PLL_LOCK_DETECT(ah);
4550 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready)
4552 ar9300_mci_2g5g_switch(ah, AH_TRUE);
4562 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4563 ar9300_mci_disable_interrupt(ah);
4564 if (ahp->ah_mci_ready && !save_full_sleep) {
4565 ar9300_mci_mute_bt(ah);
4567 OS_REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
4570 ahp->ah_mci_bt_state = MCI_BT_SLEEP;
4571 ahp->ah_mci_ready = AH_FALSE;
4575 AH9300(ah)->ah_dma_stuck = AH_FALSE;
4576 #ifdef ATH_FORCE_PPM
4577 /* Preserve force ppm state */
4579 OS_REG_READ(ah, AR_PHY_TIMING2) &
4580 (AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4583 * Preserve the antenna on a channel change
4585 save_def_antenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
4586 if (0 == ahp->ah_smartantenna_enable )
4588 if (save_def_antenna == 0) {
4589 save_def_antenna = 1;
4593 /* Save hardware flag before chip reset clears the register */
4594 mac_sta_id1 = OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
4596 /* Save led state from pci config register */
4597 save_led_state = OS_REG_READ(ah, AR_CFG_LED) &
4598 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
4599 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
4601 /* Mark PHY inactive prior to reset, to be undone in ar9300_init_bb () */
4602 ar9300_mark_phy_inactive(ah);
4604 if (!ar9300_chip_reset(ah, chan)) {
4605 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: chip reset failed\n", __func__);
4609 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4614 AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
4617 * Note that ar9300_init_chain_masks() is called from within
4618 * ar9300_process_ini() to ensure the swap bit is set before
4619 * the pdadc table is written.
4621 ecode = ar9300_process_ini(ah, chan, ichan, macmode);
4622 if (ecode != HAL_OK) {
4626 ahp->ah_immunity_on = AH_FALSE;
4628 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
4629 ahp->tx_iq_cal_enable = OS_REG_READ_FIELD(ah,
4630 AR_PHY_TX_IQCAL_CONTROL_0(ah),
4631 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL) ?
4634 ahp->tx_cl_cal_enable = (OS_REG_READ(ah, AR_PHY_CL_CAL_CTL) &
4635 AR_PHY_CL_CAL_ENABLE) ? 1 : 0;
4637 /* For devices with full HW RIFS Rx support (Sowl/Howl/Merlin, etc),
4638 * restore register settings from prior to reset.
4640 if ((AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4641 (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK))
4643 /* Re-program RIFS Rx policy after reset */
4644 ar9300_set_rifs_delay(ah, ahp->ah_rifs_enabled);
4648 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4649 ar9300_mci_reset(ah, AH_FALSE, IS_CHAN_2GHZ(ichan), save_full_sleep);
4653 /* Initialize Management Frame Protection */
4654 ar9300_init_mfp(ah);
4656 ahp->ah_immunity_vals[0] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4657 AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
4658 ahp->ah_immunity_vals[1] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4659 AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
4660 ahp->ah_immunity_vals[2] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4661 AR_PHY_SFCORR_M1_THRESH);
4662 ahp->ah_immunity_vals[3] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4663 AR_PHY_SFCORR_M2_THRESH);
4664 ahp->ah_immunity_vals[4] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4665 AR_PHY_SFCORR_M2COUNT_THR);
4666 ahp->ah_immunity_vals[5] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4667 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
4669 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
4670 if (IEEE80211_IS_CHAN_OFDM(chan) || IEEE80211_IS_CHAN_HT(chan)) {
4671 ar9300_set_delta_slope(ah, chan);
4674 ar9300_spur_mitigate(ah, chan);
4675 if (!ar9300_eeprom_set_board_values(ah, chan)) {
4676 HALDEBUG(ah, HAL_DEBUG_EEPROM,
4677 "%s: error setting board options\n", __func__);
4681 #ifdef ATH_HAL_WAR_REG16284_APH128
4682 /* temp work around, will be removed. */
4683 if (AR_SREV_WASP(ah)) {
4684 OS_REG_WRITE(ah, 0x16284, 0x1553e000);
4688 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4690 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
4691 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
4693 | AR_STA_ID1_RTS_USE_DEF
4694 | (ah->ah_config.ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0)
4695 | ahp->ah_sta_id1_defaults
4697 ar9300_set_operating_mode(ah, opmode);
4699 /* Set Venice BSSID mask according to current state */
4700 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssid_mask));
4701 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssid_mask + 4));
4703 /* Restore previous antenna */
4704 OS_REG_WRITE(ah, AR_DEF_ANTENNA, save_def_antenna);
4705 #ifdef ATH_FORCE_PPM
4706 /* Restore force ppm state */
4707 tmp_reg = OS_REG_READ(ah, AR_PHY_TIMING2) &
4708 ~(AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4709 OS_REG_WRITE(ah, AR_PHY_TIMING2, tmp_reg | save_force_val);
4712 /* then our BSSID and assocID */
4713 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
4714 OS_REG_WRITE(ah, AR_BSS_ID1,
4715 LE_READ_2(ahp->ah_bssid + 4) |
4716 ((ahp->ah_assoc_id & 0x3fff) << AR_BSS_ID1_AID_S));
4718 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
4720 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, INIT_RSSI_THR);
4722 /* HW beacon processing */
4724 * XXX what happens if I just leave filter_interval=0?
4725 * it stays disabled?
4727 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_BCN_WEIGHT,
4728 INIT_RSSI_BEACON_WEIGHT);
4729 OS_REG_SET_BIT(ah, AR_HWBCNPROC1, AR_HWBCNPROC1_CRC_ENABLE |
4730 AR_HWBCNPROC1_EXCLUDE_TIM_ELM);
4731 if (ah->ah_config.ath_hal_beacon_filter_interval) {
4732 OS_REG_RMW_FIELD(ah, AR_HWBCNPROC2, AR_HWBCNPROC2_FILTER_INTERVAL,
4733 ah->ah_config.ath_hal_beacon_filter_interval);
4734 OS_REG_SET_BIT(ah, AR_HWBCNPROC2,
4735 AR_HWBCNPROC2_FILTER_INTERVAL_ENABLE);
4740 * Set Channel now modifies bank 6 parameters for FOWL workaround
4741 * to force rf_pwd_icsyndiv bias current as function of synth
4742 * frequency.Thus must be called after ar9300_process_ini() to ensure
4743 * analog register cache is valid.
4745 if (!ahp->ah_rf_hal.set_channel(ah, chan)) {
4750 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4752 /* Set 1:1 QCU to DCU mapping for all queues */
4753 for (i = 0; i < AR_NUM_DCU; i++) {
4754 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
4757 ahp->ah_intr_txqs = 0;
4758 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) {
4759 ar9300_reset_tx_queue(ah, i);
4762 ar9300_init_interrupt_masks(ah, opmode);
4764 /* Reset ier reference count to disabled */
4765 // OS_ATOMIC_SET(&ahp->ah_ier_ref_count, 1);
4766 if (ath_hal_isrfkillenabled(ah)) {
4767 ar9300_enable_rf_kill(ah);
4770 /* must be called AFTER ini is processed */
4771 ar9300_ani_init_defaults(ah, macmode);
4773 ar9300_init_qos(ah);
4775 ar9300_init_user_settings(ah);
4778 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
4780 OS_MARK(ah, AH_MARK_RESET_DONE, 0);
4783 * disable seq number generation in hw
4785 OS_REG_WRITE(ah, AR_STA_ID1,
4786 OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
4791 * program OBS bus to see MAC interrupts
4794 if (!AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4795 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
4798 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
4802 /* enabling AR_GTTM_IGNORE_IDLE in GTTM register so that
4803 GTT timer will not increment if the channel idle indicates
4804 the air is busy or NAV is still counting down */
4805 OS_REG_WRITE(ah, AR_GTTM, AR_GTTM_IGNORE_IDLE);
4808 * GTT debug mode setting
4811 OS_REG_WRITE(ah, 0x64, 0x00320000);
4812 OS_REG_WRITE(ah, 0x68, 7);
4813 OS_REG_WRITE(ah, 0x4080, 0xC);
4816 * Disable general interrupt mitigation by setting MIRT = 0x0
4817 * Rx and tx interrupt mitigation are conditionally enabled below.
4819 OS_REG_WRITE(ah, AR_MIRT, 0);
4820 if (ahp->ah_intr_mitigation_rx) {
4822 * Enable Interrupt Mitigation for Rx.
4823 * If no build-specific limits for the rx interrupt mitigation
4824 * timer have been specified, use conservative defaults.
4826 #ifndef AH_RIMT_VAL_LAST
4827 #define AH_RIMT_LAST_MICROSEC 500
4829 #ifndef AH_RIMT_VAL_FIRST
4830 #define AH_RIMT_FIRST_MICROSEC 2000
4832 #ifndef HOST_OFFLOAD
4833 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, AH_RIMT_LAST_MICROSEC);
4834 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, AH_RIMT_FIRST_MICROSEC);
4836 /* lower mitigation level to reduce latency for offload arch. */
4837 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST,
4838 (AH_RIMT_LAST_MICROSEC >> 2));
4839 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST,
4840 (AH_RIMT_FIRST_MICROSEC >> 2));
4844 if (ahp->ah_intr_mitigation_tx) {
4846 * Enable Interrupt Mitigation for Tx.
4847 * If no build-specific limits for the tx interrupt mitigation
4848 * timer have been specified, use the values preferred for
4849 * the carrier group's products.
4851 #ifndef AH_TIMT_LAST
4852 #define AH_TIMT_LAST_MICROSEC 300
4854 #ifndef AH_TIMT_FIRST
4855 #define AH_TIMT_FIRST_MICROSEC 750
4857 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, AH_TIMT_LAST_MICROSEC);
4858 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, AH_TIMT_FIRST_MICROSEC);
4861 rx_chainmask = ahp->ah_rx_chainmask;
4863 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
4864 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
4866 ar9300_init_bb(ah, chan);
4868 /* BB Step 7: Calibration */
4869 ar9300_invalidate_saved_cals(ah, ichan);
4870 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr);
4873 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {
4874 if (IS_CHAN_2GHZ(ichan) &&
4875 (ahp->ah_mci_bt_state == MCI_BT_SLEEP))
4877 if (ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
4878 ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE))
4881 * BT is sleeping. Check if BT wakes up duing WLAN
4882 * calibration. If BT wakes up during WLAN calibration, need
4883 * to go through all message exchanges again and recal.
4885 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4886 "(MCI) ### %s: BT wakes up during WLAN calibration.\n",
4888 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
4889 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
4890 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
4891 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) send REMOTE_RESET\n");
4892 ar9300_mci_remote_reset(ah, AH_TRUE);
4893 ar9300_mci_send_sys_waking(ah, AH_TRUE);
4895 if (IS_CHAN_2GHZ(ichan)) {
4896 ar9300_mci_send_lna_transfer(ah, AH_TRUE);
4898 ahp->ah_mci_bt_state = MCI_BT_AWAKE;
4900 /* Redo calibration */
4901 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Re-calibrate.\n",
4903 ar9300_invalidate_saved_cals(ah, ichan);
4904 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr);
4907 ar9300_mci_enable_interrupt(ah);
4912 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Init Cal Failed\n", __func__);
4913 FAIL(HAL_ESELFTEST);
4916 ar9300_init_txbf(ah);
4919 * WAR for owl 1.0 - restore chain mask for 2-chain cfgs after cal
4921 rx_chainmask = ahp->ah_rx_chainmask;
4922 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
4923 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
4924 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
4928 /* Restore previous led state */
4929 OS_REG_WRITE(ah, AR_CFG_LED, save_led_state | AR_CFG_SCLK_32KHZ);
4932 if (ahp->ah_bt_coex_config_type != HAL_BT_COEX_CFG_NONE) {
4933 ar9300_init_bt_coex(ah);
4936 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {
4937 /* Check BT state again to make sure it's not changed. */
4938 ar9300_mci_sync_bt_state(ah);
4939 ar9300_mci_2g5g_switch(ah, AH_TRUE);
4941 if ((ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
4942 (ahp->ah_mci_query_bt == AH_TRUE))
4944 ahp->ah_mci_need_flush_btinfo = AH_TRUE;
4951 /* Start TSF2 for generic timer 8-15. */
4952 ar9300_start_tsf2(ah);
4954 /* MIMO Power save setting */
4955 if (ar9300_get_capability(ah, HAL_CAP_DYNAMIC_SMPS, 0, AH_NULL) == HAL_OK) {
4956 ar9300_set_sm_power_mode(ah, ahp->ah_sm_power_mode);
4960 * For big endian systems turn on swapping for descriptors
4962 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
4963 if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
4964 OS_REG_RMW(ah, AR_CFG, AR_CFG_SWTB | AR_CFG_SWRB, 0);
4966 ar9300_init_cfg_reg(ah);
4970 if ( AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
4971 OS_REG_RMW(ah, AR_CFG_LED, AR_CFG_LED_ASSOC_CTL, AR_CFG_LED_ASSOC_CTL);
4974 #if !(defined(ART_BUILD)) && defined(ATH_SUPPORT_LED)
4975 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
4976 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
4977 #define ATH_GPIO_OUT_FUNCTION3 0xB8040038
4978 #define ATH_GPIO_OE 0xB8040000
4979 if ( AR_SREV_WASP(ah)) {
4980 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
4981 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x33 << 8) );
4982 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )));
4986 /* Disable 2G WLAN LED. During ath_open, reset function is called even before channel is set.
4987 So 2GHz is taken as default and it also blinks. Hence
4988 to avoid both from blinking, disable 2G led while in 5G mode */
4990 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) | (1 << 13) ));
4991 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x33) );
4992 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )));
4996 else if (AR_SREV_SCORPION(ah)) {
4997 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
4998 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x2F << 8) );
4999 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )) | (0x1 << 12)));
5000 } else if (IS_CHAN_5GHZ((AH_PRIVATE(ah)->ah_curchan))) {
5001 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x2F) );
5002 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )) | (0x1 << 13)));
5009 /* XXX FreeBSD What's this? -adrian */
5011 chan->channel_flags = ichan->channel_flags;
5012 chan->priv_flags = ichan->priv_flags;
5016 /* XXX FreeBSD is ichan appropariate? It was curchan.. */
5017 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
5018 ar9300_load_nf(ah, nf_buf);
5019 if (nf_hist_buff_reset == 1)
5021 nf_hist_buff_reset = 0;
5022 #ifndef ATH_NF_PER_CHAN
5023 if (First_NFCal(ah, ichan, is_scan, chan)){
5025 #endif /* ATH_NF_PER_CHAN */
5028 ar9300_start_nf_cal(ah);
5032 #ifdef AH_SUPPORT_AR9300
5033 /* BB Panic Watchdog */
5034 if (ar9300_get_capability(ah, HAL_CAP_BB_PANIC_WATCHDOG, 0, AH_NULL) ==
5037 ar9300_config_bb_panic_watchdog(ah);
5041 /* While receiving unsupported rate frame receive state machine
5042 * gets into a state 0xb and if phy_restart happens when rx
5043 * state machine is in 0xb state, BB would go hang, if we
5044 * see 0xb state after first bb panic, make sure that we
5045 * disable the phy_restart.
5047 * There may be multiple panics, make sure that we always do
5048 * this if we see this panic at least once. This is required
5049 * because reset seems to be writing from INI file.
5051 if ((ar9300_get_capability(ah, HAL_CAP_PHYRESTART_CLR_WAR, 0, AH_NULL)
5052 == HAL_OK) && (((MS((AH9300(ah)->ah_bb_panic_last_status),
5053 AR_PHY_BB_WD_RX_OFDM_SM)) == 0xb) ||
5054 AH9300(ah)->ah_phyrestart_disabled) )
5056 ar9300_disable_phy_restart(ah, 1);
5061 ahp->ah_radar1 = MS(OS_REG_READ(ah, AR_PHY_RADAR_1),
5062 AR_PHY_RADAR_1_CF_BIN_THRESH);
5063 ahp->ah_dc_offset = MS(OS_REG_READ(ah, AR_PHY_TIMING2),
5064 AR_PHY_TIMING2_DC_OFFSET);
5065 ahp->ah_disable_cck = MS(OS_REG_READ(ah, AR_PHY_MODE),
5066 AR_PHY_MODE_DISABLE_CCK);
5068 if (AH9300(ah)->ah_enable_keysearch_always) {
5069 ar9300_enable_keysearch_always(ah, 1);
5072 #if ATH_LOW_POWER_ENABLE
5073 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val)
5074 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
5075 if (AR_SREV_OSPREY(ah)) {
5076 REG_WRITE(0xb4000080, REG_READ(0xb4000080) | 3);
5077 OS_REG_WRITE(ah, AR_RTC_RESET, 1);
5078 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL),
5079 AR_PCIE_PM_CTRL_ENA);
5080 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_SPARE), 0xffffffff);
5084 #endif /* ATH_LOW_POWER_ENABLE */
5086 WAR_USB_DISABLE_PLL_LOCK_DETECT(ah);
5089 ar9300_control_signals_for_green_tx_mode(ah);
5090 /* Smart Antenna, only for 5GHz on Scropion */
5091 if (IEEE80211_IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan)) && AR_SREV_SCORPION(ah)) {
5092 ahp->ah_smartantenna_enable = 0;
5095 ar9300_set_smart_antenna(ah, ahp->ah_smartantenna_enable);
5100 OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
5108 ar9300_green_ap_ps_on_off( struct ath_hal *ah, u_int16_t on_off)
5110 /* Set/reset the ps flag */
5111 AH9300(ah)->green_ap_ps_on = !!on_off;
5115 * This function returns 1, where it is possible to do
5116 * single-chain power save.
5119 ar9300_is_single_ant_power_save_possible(struct ath_hal *ah)
5124 /* To avoid compilation warnings. Functions not used when EMULATION. */
5126 * ar9300_find_mag_approx()
5129 ar9300_find_mag_approx(struct ath_hal *ah, int32_t in_re, int32_t in_im)
5131 int32_t abs_i = abs(in_re);
5132 int32_t abs_q = abs(in_im);
5133 int32_t max_abs, min_abs;
5135 if (abs_i > abs_q) {
5143 return (max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4));
5147 * ar9300_solve_iq_cal()
5148 * solve 4x4 linear equation used in loopback iq cal.
5151 ar9300_solve_iq_cal(
5161 int32_t solved_eq[])
5163 int32_t f1 = cos_2phi_1 - cos_2phi_2;
5164 int32_t f3 = sin_2phi_1 - sin_2phi_2;
5166 int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5167 const int32_t result_shift = 1 << 15;
5169 f2 = (((int64_t)f1 * (int64_t)f1) / result_shift) + (((int64_t)f3 * (int64_t)f3) / result_shift);
5172 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Divide by 0(%d).\n",
5173 __func__, __LINE__);
5177 /* magnitude mismatch, tx */
5178 mag_tx = f1 * (mag_a0_d0 - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
5179 /* phase mismatch, tx */
5180 phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
5182 mag_tx = (mag_tx / f2);
5183 phs_tx = (phs_tx / f2);
5185 /* magnitude mismatch, rx */
5187 mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) / result_shift;
5188 /* phase mismatch, rx */
5190 phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) / result_shift;
5192 solved_eq[0] = mag_tx;
5193 solved_eq[1] = phs_tx;
5194 solved_eq[2] = mag_rx;
5195 solved_eq[3] = phs_rx;
5201 * ar9300_calc_iq_corr()
5204 ar9300_calc_iq_corr(struct ath_hal *ah, int32_t chain_idx,
5205 const int32_t iq_res[], int32_t iqc_coeff[])
5207 int32_t i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0;
5208 int32_t i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1;
5209 int32_t i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0;
5210 int32_t i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
5211 int32_t mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1;
5212 int32_t phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1;
5213 int32_t sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2;
5214 int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5215 int32_t solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx;
5216 int32_t q_q_coff, q_i_coff;
5217 const int32_t res_scale = 1 << 15;
5218 const int32_t delpt_shift = 1 << 8;
5221 i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
5222 i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
5223 iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
5225 if (i2_m_q2_a0_d0 > 0x800) {
5226 i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
5228 if (iq_corr_a0_d0 > 0x800) {
5229 iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
5232 i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
5233 i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
5234 iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
5236 if (i2_m_q2_a0_d1 > 0x800) {
5237 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
5239 if (iq_corr_a0_d1 > 0x800) {
5240 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
5243 i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
5244 i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
5245 iq_corr_a1_d0 = iq_res[4] & 0xfff;
5247 if (i2_m_q2_a1_d0 > 0x800) {
5248 i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
5250 if (iq_corr_a1_d0 > 0x800) {
5251 iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
5254 i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
5255 i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
5256 iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
5258 if (i2_m_q2_a1_d1 > 0x800) {
5259 i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
5261 if (iq_corr_a1_d1 > 0x800) {
5262 iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
5265 if ((i2_p_q2_a0_d0 == 0) ||
5266 (i2_p_q2_a0_d1 == 0) ||
5267 (i2_p_q2_a1_d0 == 0) ||
5268 (i2_p_q2_a1_d1 == 0)) {
5269 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5270 "%s: Divide by 0(%d):\na0_d0=%d\na0_d1=%d\na2_d0=%d\na1_d1=%d\n",
5272 i2_p_q2_a0_d0, i2_p_q2_a0_d1, i2_p_q2_a1_d0, i2_p_q2_a1_d1);
5276 if ((i2_p_q2_a0_d0 <= 1024) || (i2_p_q2_a0_d0 > 2047) ||
5277 (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) ||
5278 (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) ||
5279 (i2_p_q2_a0_d0 <= iq_corr_a0_d0) ||
5280 (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) ||
5281 (i2_p_q2_a0_d1 <= iq_corr_a0_d1) ||
5282 (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) ||
5283 (i2_p_q2_a1_d0 <= iq_corr_a1_d0) ||
5284 (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) ||
5285 (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) {
5289 mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5290 phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5292 mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5293 phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5295 mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5296 phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5298 mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5299 phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5301 /* without analog phase shift */
5302 sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
5303 /* without analog phase shift */
5304 cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
5305 /* with analog phase shift */
5306 sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
5307 /* with analog phase shift */
5308 cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
5310 /* force sin^2 + cos^2 = 1; */
5311 /* find magnitude by approximation */
5312 mag1 = ar9300_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
5313 mag2 = ar9300_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
5315 if ((mag1 == 0) || (mag2 == 0)) {
5316 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5317 "%s: Divide by 0(%d): mag1=%d, mag2=%d\n",
5318 __func__, __LINE__, mag1, mag2);
5322 /* normalization sin and cos by mag */
5323 sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
5324 cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
5325 sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
5326 cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
5328 /* calculate IQ mismatch */
5329 if (AH_FALSE == ar9300_solve_iq_cal(ah,
5330 sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2, mag_a0_d0,
5331 phs_a0_d0, mag_a1_d0, phs_a1_d0, solved_eq))
5333 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5334 "%s: Call to ar9300_solve_iq_cal failed.\n", __func__);
5338 mag_tx = solved_eq[0];
5339 phs_tx = solved_eq[1];
5340 mag_rx = solved_eq[2];
5341 phs_rx = solved_eq[3];
5343 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5344 "%s: chain %d: mag mismatch=%d phase mismatch=%d\n",
5345 __func__, chain_idx, mag_tx / res_scale, phs_tx / res_scale);
5347 if (res_scale == mag_tx) {
5348 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5349 "%s: Divide by 0(%d): mag_tx=%d, res_scale=%d\n",
5350 __func__, __LINE__, mag_tx, res_scale);
5354 /* calculate and quantize Tx IQ correction factor */
5355 mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
5356 phs_corr_tx = -phs_tx;
5358 q_q_coff = (mag_corr_tx * 128 / res_scale);
5359 q_i_coff = (phs_corr_tx * 256 / res_scale);
5361 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5362 "%s: tx chain %d: mag corr=%d phase corr=%d\n",
5363 __func__, chain_idx, q_q_coff, q_i_coff);
5365 if (q_i_coff < -63) {
5368 if (q_i_coff > 63) {
5371 if (q_q_coff < -63) {
5374 if (q_q_coff > 63) {
5378 iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
5380 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: tx chain %d: iq corr coeff=%x\n",
5381 __func__, chain_idx, iqc_coeff[0]);
5383 if (-mag_rx == res_scale) {
5384 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5385 "%s: Divide by 0(%d): mag_rx=%d, res_scale=%d\n",
5386 __func__, __LINE__, mag_rx, res_scale);
5390 /* calculate and quantize Rx IQ correction factors */
5391 mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
5392 phs_corr_rx = -phs_rx;
5394 q_q_coff = (mag_corr_rx * 128 / res_scale);
5395 q_i_coff = (phs_corr_rx * 256 / res_scale);
5397 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5398 "%s: rx chain %d: mag corr=%d phase corr=%d\n",
5399 __func__, chain_idx, q_q_coff, q_i_coff);
5401 if (q_i_coff < -63) {
5404 if (q_i_coff > 63) {
5407 if (q_q_coff < -63) {
5410 if (q_q_coff > 63) {
5414 iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
5416 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: rx chain %d: iq corr coeff=%x\n",
5417 __func__, chain_idx, iqc_coeff[1]);
5422 #define MAX_MAG_DELTA 11 //maximum magnitude mismatch delta across gains
5423 #define MAX_PHS_DELTA 10 //maximum phase mismatch delta across gains
5424 #define ABS(x) ((x) >= 0 ? (x) : (-(x)))
5426 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5427 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5428 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5429 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5430 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5431 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5432 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5433 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5434 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5435 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5436 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5437 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5438 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5439 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5440 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5441 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5442 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5443 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5444 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5445 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5446 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5447 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5448 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5449 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5450 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5454 ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan, u_int32_t num_chains,
5455 struct coeff_t *coeff, HAL_BOOL is_cal_reusable)
5457 int nmeasurement, ch_idx, im;
5458 int32_t magnitude, phase;
5459 int32_t magnitude_max, phase_max;
5460 int32_t magnitude_min, phase_min;
5462 int32_t magnitude_max_idx, phase_max_idx;
5463 int32_t magnitude_min_idx, phase_min_idx;
5465 int32_t magnitude_avg, phase_avg;
5466 int32_t outlier_mag_idx = 0;
5467 int32_t outlier_phs_idx = 0;
5470 if (AR_SREV_POSEIDON(ah)) {
5471 HALASSERT(num_chains == 0x1);
5473 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5474 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5475 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5476 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5477 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5478 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5479 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5480 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5483 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5484 nmeasurement = OS_REG_READ_FIELD(ah,
5485 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
5486 if (nmeasurement > MAX_MEASUREMENT) {
5487 nmeasurement = MAX_MEASUREMENT;
5490 if (!AR_SREV_SCORPION(ah)) {
5492 * reset max/min variable to min/max values so that
5493 * we always start with 1st calibrated gain value
5495 magnitude_max = -64;
5501 magnitude_max_idx = 0;
5502 magnitude_min_idx = 0;
5506 /* detect outlier only if nmeasurement > 1 */
5507 if (nmeasurement > 1) {
5508 /* printf("----------- start outlier detection -----------\n"); */
5510 * find max/min and phase/mag mismatch across all calibrated gains
5512 for (im = 0; im < nmeasurement; im++) {
5513 magnitude = coeff->mag_coeff[ch_idx][im][0];
5514 phase = coeff->phs_coeff[ch_idx][im][0];
5516 magnitude_avg = magnitude_avg + magnitude;
5517 phase_avg = phase_avg + phase;
5518 if (magnitude > magnitude_max) {
5519 magnitude_max = magnitude;
5520 magnitude_max_idx = im;
5522 if (magnitude < magnitude_min) {
5523 magnitude_min = magnitude;
5524 magnitude_min_idx = im;
5526 if (phase > phase_max) {
5530 if (phase < phase_min) {
5535 /* find average (exclude max abs value) */
5536 for (im = 0; im < nmeasurement; im++) {
5537 magnitude = coeff->mag_coeff[ch_idx][im][0];
5538 phase = coeff->phs_coeff[ch_idx][im][0];
5539 if ((ABS(magnitude) < ABS(magnitude_max)) ||
5540 (ABS(magnitude) < ABS(magnitude_min)))
5542 magnitude_avg = magnitude_avg + magnitude;
5544 if ((ABS(phase) < ABS(phase_max)) ||
5545 (ABS(phase) < ABS(phase_min)))
5547 phase_avg = phase_avg + phase;
5550 magnitude_avg = magnitude_avg / (nmeasurement - 1);
5551 phase_avg = phase_avg / (nmeasurement - 1);
5553 /* detect magnitude outlier */
5554 if (ABS(magnitude_max - magnitude_min) > MAX_MAG_DELTA) {
5555 if (ABS(magnitude_max - magnitude_avg) >
5556 ABS(magnitude_min - magnitude_avg))
5558 /* max is outlier, force to avg */
5559 outlier_mag_idx = magnitude_max_idx;
5561 /* min is outlier, force to avg */
5562 outlier_mag_idx = magnitude_min_idx;
5564 coeff->mag_coeff[ch_idx][outlier_mag_idx][0] = magnitude_avg;
5565 coeff->phs_coeff[ch_idx][outlier_mag_idx][0] = phase_avg;
5566 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5567 "[ch%d][outlier mag gain%d]:: "
5568 "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5569 ch_idx, outlier_mag_idx, magnitude_avg, phase_avg);
5571 /* detect phase outlier */
5572 if (ABS(phase_max - phase_min) > MAX_PHS_DELTA) {
5573 if (ABS(phase_max-phase_avg) > ABS(phase_min - phase_avg)) {
5574 /* max is outlier, force to avg */
5575 outlier_phs_idx = phase_max_idx;
5577 /* min is outlier, force to avg */
5578 outlier_phs_idx = phase_min_idx;
5580 coeff->mag_coeff[ch_idx][outlier_phs_idx][0] = magnitude_avg;
5581 coeff->phs_coeff[ch_idx][outlier_phs_idx][0] = phase_avg;
5582 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5583 "[ch%d][outlier phs gain%d]:: "
5584 "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5585 ch_idx, outlier_phs_idx, magnitude_avg, phase_avg);
5590 /*printf("------------ after outlier detection -------------\n");*/
5591 for (im = 0; im < nmeasurement; im++) {
5592 magnitude = coeff->mag_coeff[ch_idx][im][0];
5593 phase = coeff->phs_coeff[ch_idx][im][0];
5596 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
5597 ch_idx, im, magnitude, phase);
5600 coeff->iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
5602 if ((im % 2) == 0) {
5603 OS_REG_RMW_FIELD(ah,
5604 tx_corr_coeff[im][ch_idx],
5605 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5606 coeff->iqc_coeff[0]);
5608 OS_REG_RMW_FIELD(ah,
5609 tx_corr_coeff[im][ch_idx],
5610 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5611 coeff->iqc_coeff[0]);
5613 #if ATH_SUPPORT_CAL_REUSE
5614 ichan->tx_corr_coeff[im][ch_idx] = coeff->iqc_coeff[0];
5617 #if ATH_SUPPORT_CAL_REUSE
5618 ichan->num_measures[ch_idx] = nmeasurement;
5622 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5623 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5624 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
5625 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
5627 #if ATH_SUPPORT_CAL_REUSE
5628 if (is_cal_reusable) {
5629 ichan->one_time_txiqcal_done = AH_TRUE;
5630 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
5631 "(FCS) TXIQCAL saved - %d\n", ichan->channel);
5636 #if ATH_SUPPORT_CAL_REUSE
5638 ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
5640 struct ath_hal_9300 *ahp = AH9300(ah);
5641 int nmeasurement, ch_idx, im;
5643 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5644 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5645 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5646 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5647 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5648 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5649 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5650 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5651 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5652 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5653 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5654 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5655 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5656 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5657 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5658 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5659 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5660 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5661 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5662 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5663 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5664 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5665 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5666 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5667 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5670 if (AR_SREV_POSEIDON(ah)) {
5671 HALASSERT(ahp->ah_tx_cal_chainmask == 0x1);
5673 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5674 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5675 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5676 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5677 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5678 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5679 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5680 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5683 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
5684 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
5687 nmeasurement = ichan->num_measures[ch_idx];
5689 for (im = 0; im < nmeasurement; im++) {
5690 if ((im % 2) == 0) {
5691 OS_REG_RMW_FIELD(ah,
5692 tx_corr_coeff[im][ch_idx],
5693 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5694 ichan->tx_corr_coeff[im][ch_idx]);
5696 OS_REG_RMW_FIELD(ah,
5697 tx_corr_coeff[im][ch_idx],
5698 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5699 ichan->tx_corr_coeff[im][ch_idx]);
5704 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5705 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5706 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
5707 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
5712 * ar9300_tx_iq_cal_hw_run is only needed for osprey/wasp/hornet
5713 * It is not needed for jupiter/poseidon.
5716 ar9300_tx_iq_cal_hw_run(struct ath_hal *ah)
5718 int is_tx_gain_forced;
5720 is_tx_gain_forced = OS_REG_READ_FIELD(ah,
5721 AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE);
5722 if (is_tx_gain_forced) {
5723 /*printf("Tx gain can not be forced during tx I/Q cal!\n");*/
5724 OS_REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE, 0);
5727 /* enable tx IQ cal */
5728 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START(ah),
5729 AR_PHY_TX_IQCAL_START_DO_CAL, AR_PHY_TX_IQCAL_START_DO_CAL);
5731 if (!ath_hal_wait(ah,
5732 AR_PHY_TX_IQCAL_START(ah), AR_PHY_TX_IQCAL_START_DO_CAL, 0))
5734 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5735 "%s: Tx IQ Cal is never completed.\n", __func__);
5742 ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
5743 int iqcal_idx, int max_iqcal,HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr)
5745 int nmeasurement=0, im, ix, iy, temp;
5746 struct ath_hal_9300 *ahp = AH9300(ah);
5747 u_int32_t txiqcal_status[AR9300_MAX_CHAINS] = {
5748 AR_PHY_TX_IQCAL_STATUS_B0(ah),
5749 AR_PHY_TX_IQCAL_STATUS_B1,
5750 AR_PHY_TX_IQCAL_STATUS_B2,
5752 const u_int32_t chan_info_tab[] = {
5753 AR_PHY_CHAN_INFO_TAB_0,
5754 AR_PHY_CHAN_INFO_TAB_1,
5755 AR_PHY_CHAN_INFO_TAB_2,
5759 u_int32_t num_chains = 0;
5760 static struct coeff_t coeff;
5761 txiqcal_status[0] = AR_PHY_TX_IQCAL_STATUS_B0(ah);
5763 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
5764 if (ahp->ah_tx_chainmask & (1 << ch_idx)) {
5769 if (apply_last_corr) {
5770 if (coeff.last_cal == AH_TRUE) {
5771 int32_t magnitude, phase;
5773 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5774 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5775 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5776 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5777 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5778 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5779 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5780 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5781 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5782 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5783 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5784 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5785 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5786 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5787 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5788 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5789 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5790 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5791 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5792 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5793 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5794 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5795 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5796 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5797 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5799 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5800 for (im = 0; im < coeff.last_nmeasurement; im++) {
5801 magnitude = coeff.mag_coeff[ch_idx][im][0];
5802 phase = coeff.phs_coeff[ch_idx][im][0];
5805 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
5806 ch_idx, im, magnitude, phase);
5809 coeff.iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
5810 if ((im % 2) == 0) {
5811 OS_REG_RMW_FIELD(ah,
5812 tx_corr_coeff[im][ch_idx],
5813 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5814 coeff.iqc_coeff[0]);
5816 OS_REG_RMW_FIELD(ah,
5817 tx_corr_coeff[im][ch_idx],
5818 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5819 coeff.iqc_coeff[0]);
5823 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5824 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5830 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5831 nmeasurement = OS_REG_READ_FIELD(ah,
5832 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
5833 if (nmeasurement > MAX_MEASUREMENT) {
5834 nmeasurement = MAX_MEASUREMENT;
5837 for (im = 0; im < nmeasurement; im++) {
5838 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5839 "%s: Doing Tx IQ Cal for chain %d.\n", __func__, ch_idx);
5840 if (OS_REG_READ(ah, txiqcal_status[ch_idx]) &
5841 AR_PHY_TX_IQCAL_STATUS_FAILED)
5843 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5844 "%s: Tx IQ Cal failed for chain %d.\n", __func__, ch_idx);
5845 goto TX_IQ_CAL_FAILED_;
5848 for (j = 0; j < 3; j++) {
5849 u_int32_t idx = 2 * j;
5850 /* 3 registers for each calibration result */
5851 u_int32_t offset = 4 * (3 * im + j);
5853 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
5854 AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
5856 iq_res[idx] = OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
5857 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
5858 AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
5860 iq_res[idx + 1] = 0xffff &
5861 OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
5863 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5864 "%s: IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
5865 __func__, idx, iq_res[idx], idx + 1, iq_res[idx + 1]);
5868 if (AH_FALSE == ar9300_calc_iq_corr(
5869 ah, ch_idx, iq_res, coeff.iqc_coeff))
5871 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5872 "%s: Failed in calculation of IQ correction.\n",
5874 goto TX_IQ_CAL_FAILED_;
5877 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] = coeff.iqc_coeff[0] & 0x7f;
5878 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] = (coeff.iqc_coeff[0] >> 7) & 0x7f;
5879 if (coeff.mag_coeff[ch_idx][im][iqcal_idx-1] > 63) {
5880 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] -= 128;
5882 if (coeff.phs_coeff[ch_idx][im][iqcal_idx-1] > 63) {
5883 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] -= 128;
5886 ath_hal_printf(ah, "IQCAL::[ch%d][gain%d]:: mag = %d phase = %d \n",
5887 ch_idx, im, coeff.mag_coeff[ch_idx][im][iqcal_idx-1],
5888 coeff.phs_coeff[ch_idx][im][iqcal_idx-1]);
5892 //last iteration; calculate mag and phs
5893 if (iqcal_idx == max_iqcal) {
5895 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5896 for (im = 0; im < nmeasurement; im++) {
5898 for( ix=0;ix<max_iqcal-1;ix++){
5899 for( iy=ix+1;iy<=max_iqcal-1;iy++){
5900 if(coeff.mag_coeff[ch_idx][im][iy] <
5901 coeff.mag_coeff[ch_idx][im][ix]) {
5903 temp=coeff.mag_coeff[ch_idx][im][ix];
5904 coeff.mag_coeff[ch_idx][im][ix] = coeff.mag_coeff[ch_idx][im][iy];
5905 coeff.mag_coeff[ch_idx][im][iy] = temp;
5907 if(coeff.phs_coeff[ch_idx][im][iy] <
5908 coeff.phs_coeff[ch_idx][im][ix]){
5910 temp=coeff.phs_coeff[ch_idx][im][ix];
5911 coeff.phs_coeff[ch_idx][im][ix]=coeff.phs_coeff[ch_idx][im][iy];
5912 coeff.phs_coeff[ch_idx][im][iy]=temp;
5916 //select median; 3rd entry in the sorted array
5917 coeff.mag_coeff[ch_idx][im][0] =
5918 coeff.mag_coeff[ch_idx][im][max_iqcal/2];
5919 coeff.phs_coeff[ch_idx][im][0] =
5920 coeff.phs_coeff[ch_idx][im][max_iqcal/2];
5921 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5922 "IQCAL: Median [ch%d][gain%d]:: mag = %d phase = %d \n",
5923 ch_idx, im,coeff.mag_coeff[ch_idx][im][0],
5924 coeff.phs_coeff[ch_idx][im][0]);
5928 ar9300_tx_iq_cal_outlier_detection(ah,ichan, num_chains, &coeff,is_cal_reusable);
5932 coeff.last_nmeasurement = nmeasurement;
5933 coeff.last_cal = AH_TRUE;
5938 /* no need to print this, it is AGC failure not chip stuck */
5939 /*ath_hal_printf(ah, "Tx IQ Cal failed(%d)\n", line);*/
5940 coeff.last_cal = AH_FALSE;
5946 * ar9300_disable_phy_restart
5948 * In some BBpanics, we can disable the phyrestart
5949 * disable_phy_restart
5950 * != 0, disable the phy restart in h/w
5951 * == 0, enable the phy restart in h/w
5953 void ar9300_disable_phy_restart(struct ath_hal *ah, int disable_phy_restart)
5957 val = OS_REG_READ(ah, AR_PHY_RESTART);
5958 if (disable_phy_restart) {
5959 val &= ~AR_PHY_RESTART_ENA;
5960 AH9300(ah)->ah_phyrestart_disabled = 1;
5962 val |= AR_PHY_RESTART_ENA;
5963 AH9300(ah)->ah_phyrestart_disabled = 0;
5965 OS_REG_WRITE(ah, AR_PHY_RESTART, val);
5967 val = OS_REG_READ(ah, AR_PHY_RESTART);
5971 ar9300_interference_is_present(struct ath_hal *ah)
5974 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
5975 const struct ieee80211_channel *chan = ahpriv->ah_curchan;
5976 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
5978 if (ichan == NULL) {
5979 ath_hal_printf(ah, "%s: called with ichan=NULL\n", __func__);
5983 /* This function is called after a stuck beacon, if EACS is enabled.
5984 * If CW interference is severe, then HW goes into a loop of continuous
5985 * stuck beacons and resets. On reset the NF cal history is cleared.
5986 * So the median value of the history cannot be used -
5987 * hence check if any value (Chain 0/Primary Channel)
5988 * is outside the bounds.
5990 HAL_NFCAL_HIST_FULL *h = AH_HOME_CHAN_NFCAL_HIST(ah, ichan);
5991 for (i = 0; i < HAL_NF_CAL_HIST_LEN_FULL; i++) {
5992 if (h->nf_cal_buffer[i][0] >
5993 AH9300(ah)->nfp->nominal + AH9300(ah)->nf_cw_int_delta)
6002 #if ATH_SUPPORT_CRDC
6004 ar9300_crdc_rx_notify(struct ath_hal *ah, struct ath_rx_status *rxs)
6006 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6009 if ((!AR_SREV_WASP(ah)) ||
6010 (!ahpriv->ah_config.ath_hal_crdc_enable)) {
6014 if (rxs->rs_isaggr && rxs->rs_moreaggr) {
6018 if ((rxs->rs_rssi_ctl0 >= HAL_RSSI_BAD) ||
6019 (rxs->rs_rssi_ctl1 >= HAL_RSSI_BAD)) {
6023 rssi_index = ah->ah_crdc_rssi_ptr % HAL_MAX_CRDC_RSSI_SAMPLE;
6025 ah->ah_crdc_rssi_sample[0][rssi_index] = rxs->rs_rssi_ctl0;
6026 ah->ah_crdc_rssi_sample[1][rssi_index] = rxs->rs_rssi_ctl1;
6028 ah->ah_crdc_rssi_ptr++;
6032 ar9300_crdc_avg_rssi(struct ath_hal *ah, int chain)
6034 int crdc_rssi_sum = 0;
6035 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr, i;
6036 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6037 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
6039 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
6040 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
6043 for (i = 1; i <= crdc_window; i++) {
6045 ah->ah_crdc_rssi_sample[chain]
6046 [(crdc_rssi_ptr - i) % HAL_MAX_CRDC_RSSI_SAMPLE];
6049 return crdc_rssi_sum / crdc_window;
6053 ar9300_crdc_activate(struct ath_hal *ah, int rssi_diff, int enable)
6056 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6057 int crdc_numerator = ahpriv->ah_config.ath_hal_crdc_numerator;
6058 int crdc_denominator = ahpriv->ah_config.ath_hal_crdc_denominator;
6059 int c = (rssi_diff * crdc_numerator) / crdc_denominator;
6061 val = orig_val = OS_REG_READ(ah, AR_PHY_MULTICHAIN_CTRL);
6065 val |= ((c << 1) & 0xff);
6067 OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_CTRL, val);
6068 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "diff: %02d comp: %02d reg: %08x %08x\n",
6069 rssi_diff, c, orig_val, val);
6073 void ar9300_chain_rssi_diff_compensation(struct ath_hal *ah)
6075 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6076 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
6077 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr;
6078 int crdc_rssi_thresh = ahpriv->ah_config.ath_hal_crdc_rssithresh;
6079 int crdc_diff_thresh = ahpriv->ah_config.ath_hal_crdc_diffthresh;
6080 int avg_rssi[2], avg_rssi_diff;
6082 if ((!AR_SREV_WASP(ah)) ||
6083 (!ahpriv->ah_config.ath_hal_crdc_enable)) {
6084 if (ah->ah_crdc_rssi_ptr) {
6085 ar9300_crdc_activate(ah, 0, 0);
6086 ah->ah_crdc_rssi_ptr = 0;
6091 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
6092 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
6095 if (crdc_rssi_ptr < crdc_window) {
6099 avg_rssi[0] = ar9300_crdc_avg_rssi(ah, 0);
6100 avg_rssi[1] = ar9300_crdc_avg_rssi(ah, 1);
6101 avg_rssi_diff = avg_rssi[1] - avg_rssi[0];
6103 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "crdc: avg: %02d %02d ",
6104 avg_rssi[0], avg_rssi[1]);
6106 if ((avg_rssi[0] < crdc_rssi_thresh) &&
6107 (avg_rssi[1] < crdc_rssi_thresh)) {
6108 ar9300_crdc_activate(ah, 0, 0);
6110 if (ABS(avg_rssi_diff) >= crdc_diff_thresh) {
6111 ar9300_crdc_activate(ah, avg_rssi_diff, 1);
6113 ar9300_crdc_activate(ah, 0, 1);
6119 #if ATH_ANT_DIV_COMB
6121 ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal *ah, HAL_BOOL enable, const struct ieee80211_channel *chan)
6125 struct ath_hal_9300 *ahp = AH9300(ah);
6126 HAL_CHANNEL_INTERNAL *ichan;
6127 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6128 HAL_CAPABILITIES *pcap = &ahpriv->ah_caps;
6130 if (AR_SREV_POSEIDON(ah)) {
6131 // Make sure this scheme is only used for WB225(Astra)
6132 ahp->ah_lna_div_use_bt_ant_enable = enable;
6134 ichan = ar9300_check_chan(ah, chan);
6135 if ( ichan == AH_NULL ) {
6136 HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel %u/0x%x; no mapping\n",
6137 __func__, chan->ic_freq, chan->ic_flags);
6141 if ( enable == TRUE ) {
6142 pcap->halAntDivCombSupport = TRUE;
6144 pcap->halAntDivCombSupport = pcap->halAntDivCombSupportOrg;
6147 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
6148 #define AR_SWITCH_TABLE_COM2_ALL_S (0)
6149 value = ar9300_ant_ctrl_common2_get(ah, IS_CHAN_2GHZ(ichan));
6150 if ( enable == TRUE ) {
6151 value &= ~AR_SWITCH_TABLE_COM2_ALL;
6152 value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable;
6154 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, value);
6155 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
6157 value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control);
6158 /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6159 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6160 regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */
6161 regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S;
6163 regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK);
6164 regval |= ((value >> 6) & 0x1) <<
6165 MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT;
6166 if ( enable == TRUE ) {
6167 regval |= ANT_DIV_ENABLE;
6169 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6171 /* enable fast_div */
6172 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
6173 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
6174 regval |= ((value >> 7) & 0x1) <<
6175 BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT;
6176 if ( enable == TRUE ) {
6177 regval |= FAST_DIV_ENABLE;
6179 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
6181 if ( AR_SREV_POSEIDON_11_OR_LATER(ah) ) {
6182 if (pcap->halAntDivCombSupport) {
6183 /* If support DivComb, set MAIN to LNA1 and ALT to LNA2 at the first beginning */
6184 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6185 /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6186 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK |
6187 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK |
6188 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK |
6189 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK));
6190 regval |= (HAL_ANT_DIV_COMB_LNA1 <<
6191 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT);
6192 regval |= (HAL_ANT_DIV_COMB_LNA2 <<
6193 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT);
6194 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6203 #endif /* ATH_ANT_DIV_COMB */