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