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 HALDEBUG(ah, HAL_DEBUG_RESET, "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 HALDEBUG(ah, HAL_DEBUG_RESET, "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 HALDEBUG(ah, HAL_DEBUG_RESET, "%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 /* FreeBSD: clear the channel survey data */ 4671 ath_hal_survey_clear(ah); 4672 4673 /* 4674 * Fast channel change (Change synthesizer based on channel freq 4675 * without resetting chip) 4676 * Don't do it when 4677 * - Flag is not set 4678 * - Chip is just coming out of full sleep 4679 * - Channel to be set is same as current channel 4680 * - Channel flags are different, like when moving from 2GHz to 5GHz 4681 * channels 4682 * - Merlin: Switching in/out of fast clock enabled channels 4683 * (not currently coded, since fast clock is enabled 4684 * across the 5GHz band 4685 * and we already do a full reset when switching in/out 4686 * of 5GHz channels) 4687 */ 4688 #if 0 4689 if (b_channel_change && 4690 (ahp->ah_chip_full_sleep != AH_TRUE) && 4691 (AH_PRIVATE(ah)->ah_curchan != AH_NULL) && 4692 ((chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) && 4693 (((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & chan->channel_flags) == 4694 ((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & AH_PRIVATE(ah)->ah_curchan->channel_flags)))) 4695 { 4696 if (ar9300_channel_change(ah, chan, ichan, macmode)) { 4697 chan->channel_flags = ichan->channel_flags; 4698 chan->priv_flags = ichan->priv_flags; 4699 AH_PRIVATE(ah)->ah_curchan->ah_channel_time = 0; 4700 AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar9300_get_tsf64(ah); 4701 4702 /* 4703 * Load the NF from history buffer of the current channel. 4704 * NF is slow time-variant, so it is OK to use a historical value. 4705 */ 4706 ar9300_get_nf_hist_base(ah, 4707 AH_PRIVATE(ah)->ah_curchan, is_scan, nf_buf); 4708 ar9300_load_nf(ah, nf_buf); 4709 4710 /* start NF calibration, without updating BB NF register*/ 4711 ar9300_start_nf_cal(ah); 4712 4713 /* 4714 * If channel_change completed and DMA was stopped 4715 * successfully - skip the rest of reset 4716 */ 4717 if (AH9300(ah)->ah_dma_stuck != AH_TRUE) { 4718 WAR_USB_DISABLE_PLL_LOCK_DETECT(ah); 4719 #if ATH_SUPPORT_MCI 4720 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) 4721 { 4722 ar9300_mci_2g5g_switch(ah, AH_TRUE); 4723 } 4724 #endif 4725 return HAL_OK; 4726 } 4727 } 4728 } 4729 #endif /* #if 0 */ 4730 4731 #if ATH_SUPPORT_MCI 4732 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) { 4733 ar9300_mci_disable_interrupt(ah); 4734 if (ahp->ah_mci_ready && !save_full_sleep) { 4735 ar9300_mci_mute_bt(ah); 4736 OS_DELAY(20); 4737 OS_REG_WRITE(ah, AR_BTCOEX_CTRL, 0); 4738 } 4739 4740 ahp->ah_mci_bt_state = MCI_BT_SLEEP; 4741 ahp->ah_mci_ready = AH_FALSE; 4742 } 4743 #endif 4744 4745 AH9300(ah)->ah_dma_stuck = AH_FALSE; 4746 #ifdef ATH_FORCE_PPM 4747 /* Preserve force ppm state */ 4748 save_force_val = 4749 OS_REG_READ(ah, AR_PHY_TIMING2) & 4750 (AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL); 4751 #endif 4752 /* 4753 * Preserve the antenna on a channel change 4754 */ 4755 save_def_antenna = OS_REG_READ(ah, AR_DEF_ANTENNA); 4756 if (0 == ahp->ah_smartantenna_enable ) 4757 { 4758 if (save_def_antenna == 0) { 4759 save_def_antenna = 1; 4760 } 4761 } 4762 4763 /* Save hardware flag before chip reset clears the register */ 4764 mac_sta_id1 = OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; 4765 4766 /* Save led state from pci config register */ 4767 save_led_state = OS_REG_READ(ah, AR_CFG_LED) & 4768 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | 4769 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW); 4770 4771 /* Mark PHY inactive prior to reset, to be undone in ar9300_init_bb () */ 4772 ar9300_mark_phy_inactive(ah); 4773 4774 if (!ar9300_chip_reset(ah, chan)) { 4775 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: chip reset failed\n", __func__); 4776 FAIL(HAL_EIO); 4777 } 4778 4779 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 4780 4781 4782 /* Disable JTAG */ 4783 OS_REG_SET_BIT(ah, 4784 AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE); 4785 4786 /* 4787 * Note that ar9300_init_chain_masks() is called from within 4788 * ar9300_process_ini() to ensure the swap bit is set before 4789 * the pdadc table is written. 4790 */ 4791 ecode = ar9300_process_ini(ah, chan, ichan, macmode); 4792 if (ecode != HAL_OK) { 4793 goto bad; 4794 } 4795 4796 ahp->ah_immunity_on = AH_FALSE; 4797 4798 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 4799 ahp->tx_iq_cal_enable = OS_REG_READ_FIELD(ah, 4800 AR_PHY_TX_IQCAL_CONTROL_0(ah), 4801 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL) ? 4802 1 : 0; 4803 } 4804 ahp->tx_cl_cal_enable = (OS_REG_READ(ah, AR_PHY_CL_CAL_CTL) & 4805 AR_PHY_CL_CAL_ENABLE) ? 1 : 0; 4806 4807 /* For devices with full HW RIFS Rx support (Sowl/Howl/Merlin, etc), 4808 * restore register settings from prior to reset. 4809 */ 4810 if ((AH_PRIVATE(ah)->ah_curchan != AH_NULL) && 4811 (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK)) 4812 { 4813 /* Re-program RIFS Rx policy after reset */ 4814 ar9300_set_rifs_delay(ah, ahp->ah_rifs_enabled); 4815 } 4816 4817 #if ATH_SUPPORT_MCI 4818 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) { 4819 ar9300_mci_reset(ah, AH_FALSE, IS_CHAN_2GHZ(ichan), save_full_sleep); 4820 } 4821 #endif 4822 4823 /* Initialize Management Frame Protection */ 4824 ar9300_init_mfp(ah); 4825 4826 ahp->ah_immunity_vals[0] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW, 4827 AR_PHY_SFCORR_LOW_M1_THRESH_LOW); 4828 ahp->ah_immunity_vals[1] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW, 4829 AR_PHY_SFCORR_LOW_M2_THRESH_LOW); 4830 ahp->ah_immunity_vals[2] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR, 4831 AR_PHY_SFCORR_M1_THRESH); 4832 ahp->ah_immunity_vals[3] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR, 4833 AR_PHY_SFCORR_M2_THRESH); 4834 ahp->ah_immunity_vals[4] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR, 4835 AR_PHY_SFCORR_M2COUNT_THR); 4836 ahp->ah_immunity_vals[5] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW, 4837 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW); 4838 4839 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 4840 if (IEEE80211_IS_CHAN_OFDM(chan) || IEEE80211_IS_CHAN_HT(chan)) { 4841 ar9300_set_delta_slope(ah, chan); 4842 } 4843 4844 ar9300_spur_mitigate(ah, chan); 4845 if (!ar9300_eeprom_set_board_values(ah, chan)) { 4846 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4847 "%s: error setting board options\n", __func__); 4848 FAIL(HAL_EIO); 4849 } 4850 4851 #ifdef ATH_HAL_WAR_REG16284_APH128 4852 /* temp work around, will be removed. */ 4853 if (AR_SREV_WASP(ah)) { 4854 OS_REG_WRITE(ah, 0x16284, 0x1553e000); 4855 } 4856 #endif 4857 4858 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 4859 4860 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr)); 4861 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4) 4862 | mac_sta_id1 4863 | AR_STA_ID1_RTS_USE_DEF 4864 | (ah->ah_config.ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0) 4865 | ahp->ah_sta_id1_defaults 4866 ); 4867 ar9300_set_operating_mode(ah, opmode); 4868 4869 /* Set Venice BSSID mask according to current state */ 4870 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssid_mask)); 4871 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssid_mask + 4)); 4872 4873 /* Restore previous antenna */ 4874 OS_REG_WRITE(ah, AR_DEF_ANTENNA, save_def_antenna); 4875 #ifdef ATH_FORCE_PPM 4876 /* Restore force ppm state */ 4877 tmp_reg = OS_REG_READ(ah, AR_PHY_TIMING2) & 4878 ~(AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL); 4879 OS_REG_WRITE(ah, AR_PHY_TIMING2, tmp_reg | save_force_val); 4880 #endif 4881 4882 /* then our BSSID and assocID */ 4883 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 4884 OS_REG_WRITE(ah, AR_BSS_ID1, 4885 LE_READ_2(ahp->ah_bssid + 4) | 4886 ((ahp->ah_assoc_id & 0x3fff) << AR_BSS_ID1_AID_S)); 4887 4888 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */ 4889 4890 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, INIT_RSSI_THR); 4891 4892 /* HW beacon processing */ 4893 /* 4894 * XXX what happens if I just leave filter_interval=0? 4895 * it stays disabled? 4896 */ 4897 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_BCN_WEIGHT, 4898 INIT_RSSI_BEACON_WEIGHT); 4899 OS_REG_SET_BIT(ah, AR_HWBCNPROC1, AR_HWBCNPROC1_CRC_ENABLE | 4900 AR_HWBCNPROC1_EXCLUDE_TIM_ELM); 4901 if (ah->ah_config.ath_hal_beacon_filter_interval) { 4902 OS_REG_RMW_FIELD(ah, AR_HWBCNPROC2, AR_HWBCNPROC2_FILTER_INTERVAL, 4903 ah->ah_config.ath_hal_beacon_filter_interval); 4904 OS_REG_SET_BIT(ah, AR_HWBCNPROC2, 4905 AR_HWBCNPROC2_FILTER_INTERVAL_ENABLE); 4906 } 4907 4908 4909 /* 4910 * Set Channel now modifies bank 6 parameters for FOWL workaround 4911 * to force rf_pwd_icsyndiv bias current as function of synth 4912 * frequency.Thus must be called after ar9300_process_ini() to ensure 4913 * analog register cache is valid. 4914 */ 4915 if (!ahp->ah_rf_hal.set_channel(ah, chan)) { 4916 FAIL(HAL_EIO); 4917 } 4918 4919 4920 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 4921 4922 /* Set 1:1 QCU to DCU mapping for all queues */ 4923 for (i = 0; i < AR_NUM_DCU; i++) { 4924 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 4925 } 4926 4927 ahp->ah_intr_txqs = 0; 4928 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) { 4929 ar9300_reset_tx_queue(ah, i); 4930 } 4931 4932 ar9300_init_interrupt_masks(ah, opmode); 4933 4934 /* Reset ier reference count to disabled */ 4935 // OS_ATOMIC_SET(&ahp->ah_ier_ref_count, 1); 4936 if (ath_hal_isrfkillenabled(ah)) { 4937 ar9300_enable_rf_kill(ah); 4938 } 4939 4940 /* must be called AFTER ini is processed */ 4941 ar9300_ani_init_defaults(ah, macmode); 4942 4943 ar9300_init_qos(ah); 4944 4945 ar9300_init_user_settings(ah); 4946 4947 4948 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */ 4949 4950 OS_MARK(ah, AH_MARK_RESET_DONE, 0); 4951 4952 /* 4953 * disable seq number generation in hw 4954 */ 4955 OS_REG_WRITE(ah, AR_STA_ID1, 4956 OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); 4957 4958 ar9300_set_dma(ah); 4959 4960 /* 4961 * program OBS bus to see MAC interrupts 4962 */ 4963 #if ATH_SUPPORT_MCI 4964 if (!AH_PRIVATE(ah)->ah_caps.halMciSupport) { 4965 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8); 4966 } 4967 #else 4968 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8); 4969 #endif 4970 4971 4972 /* enabling AR_GTTM_IGNORE_IDLE in GTTM register so that 4973 GTT timer will not increment if the channel idle indicates 4974 the air is busy or NAV is still counting down */ 4975 OS_REG_WRITE(ah, AR_GTTM, AR_GTTM_IGNORE_IDLE); 4976 4977 /* 4978 * GTT debug mode setting 4979 */ 4980 /* 4981 OS_REG_WRITE(ah, 0x64, 0x00320000); 4982 OS_REG_WRITE(ah, 0x68, 7); 4983 OS_REG_WRITE(ah, 0x4080, 0xC); 4984 */ 4985 /* 4986 * Disable general interrupt mitigation by setting MIRT = 0x0 4987 * Rx and tx interrupt mitigation are conditionally enabled below. 4988 */ 4989 OS_REG_WRITE(ah, AR_MIRT, 0); 4990 if (ahp->ah_intr_mitigation_rx) { 4991 /* 4992 * Enable Interrupt Mitigation for Rx. 4993 * If no build-specific limits for the rx interrupt mitigation 4994 * timer have been specified, use conservative defaults. 4995 */ 4996 #ifndef AH_RIMT_VAL_LAST 4997 #define AH_RIMT_LAST_MICROSEC 500 4998 #endif 4999 #ifndef AH_RIMT_VAL_FIRST 5000 #define AH_RIMT_FIRST_MICROSEC 2000 5001 #endif 5002 #ifndef HOST_OFFLOAD 5003 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, AH_RIMT_LAST_MICROSEC); 5004 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, AH_RIMT_FIRST_MICROSEC); 5005 #else 5006 /* lower mitigation level to reduce latency for offload arch. */ 5007 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 5008 (AH_RIMT_LAST_MICROSEC >> 2)); 5009 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 5010 (AH_RIMT_FIRST_MICROSEC >> 2)); 5011 #endif 5012 } 5013 5014 if (ahp->ah_intr_mitigation_tx) { 5015 /* 5016 * Enable Interrupt Mitigation for Tx. 5017 * If no build-specific limits for the tx interrupt mitigation 5018 * timer have been specified, use the values preferred for 5019 * the carrier group's products. 5020 */ 5021 #ifndef AH_TIMT_LAST 5022 #define AH_TIMT_LAST_MICROSEC 300 5023 #endif 5024 #ifndef AH_TIMT_FIRST 5025 #define AH_TIMT_FIRST_MICROSEC 750 5026 #endif 5027 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, AH_TIMT_LAST_MICROSEC); 5028 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, AH_TIMT_FIRST_MICROSEC); 5029 } 5030 5031 rx_chainmask = ahp->ah_rx_chainmask; 5032 5033 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 5034 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 5035 5036 ar9300_init_bb(ah, chan); 5037 5038 /* BB Step 7: Calibration */ 5039 /* 5040 * Only kick off calibration not on offchan. 5041 * If coming back from offchan, restore prevous Cal results 5042 * since chip reset will clear existings. 5043 */ 5044 if (!ahp->ah_skip_rx_iq_cal) { 5045 int i; 5046 /* clear existing RX cal data */ 5047 for (i=0; i<AR9300_MAX_CHAINS; i++) 5048 ahp->ah_rx_cal_corr[i] = 0; 5049 5050 ahp->ah_rx_cal_complete = AH_FALSE; 5051 // ahp->ah_rx_cal_chan = chan->channel; 5052 // ahp->ah_rx_cal_chan_flag = ichan->channel_flags; 5053 ahp->ah_rx_cal_chan = 0; 5054 ahp->ah_rx_cal_chan_flag = 0; /* XXX FreeBSD */ 5055 } 5056 ar9300_invalidate_saved_cals(ah, ichan); 5057 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr); 5058 5059 #if ATH_SUPPORT_MCI 5060 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) { 5061 if (IS_CHAN_2GHZ(ichan) && 5062 (ahp->ah_mci_bt_state == MCI_BT_SLEEP)) 5063 { 5064 if (ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) || 5065 ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) 5066 { 5067 /* 5068 * BT is sleeping. Check if BT wakes up duing WLAN 5069 * calibration. If BT wakes up during WLAN calibration, need 5070 * to go through all message exchanges again and recal. 5071 */ 5072 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 5073 "(MCI) ### %s: BT wakes up during WLAN calibration.\n", 5074 __func__); 5075 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, 5076 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | 5077 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE); 5078 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) send REMOTE_RESET\n"); 5079 ar9300_mci_remote_reset(ah, AH_TRUE); 5080 ar9300_mci_send_sys_waking(ah, AH_TRUE); 5081 OS_DELAY(1); 5082 if (IS_CHAN_2GHZ(ichan)) { 5083 ar9300_mci_send_lna_transfer(ah, AH_TRUE); 5084 } 5085 ahp->ah_mci_bt_state = MCI_BT_AWAKE; 5086 5087 /* Redo calibration */ 5088 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Re-calibrate.\n", 5089 __func__); 5090 ar9300_invalidate_saved_cals(ah, ichan); 5091 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr); 5092 } 5093 } 5094 ar9300_mci_enable_interrupt(ah); 5095 } 5096 #endif 5097 5098 if (!cal_ret) { 5099 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Init Cal Failed\n", __func__); 5100 FAIL(HAL_ESELFTEST); 5101 } 5102 5103 ar9300_init_txbf(ah); 5104 #if 0 5105 /* 5106 * WAR for owl 1.0 - restore chain mask for 2-chain cfgs after cal 5107 */ 5108 rx_chainmask = ahp->ah_rx_chainmask; 5109 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { 5110 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 5111 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 5112 } 5113 #endif 5114 5115 /* Restore previous led state */ 5116 OS_REG_WRITE(ah, AR_CFG_LED, save_led_state | AR_CFG_SCLK_32KHZ); 5117 5118 #if ATH_BT_COEX 5119 if (ahp->ah_bt_coex_config_type != HAL_BT_COEX_CFG_NONE) { 5120 ar9300_init_bt_coex(ah); 5121 5122 #if ATH_SUPPORT_MCI 5123 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) { 5124 /* Check BT state again to make sure it's not changed. */ 5125 ar9300_mci_sync_bt_state(ah); 5126 ar9300_mci_2g5g_switch(ah, AH_TRUE); 5127 5128 if ((ahp->ah_mci_bt_state == MCI_BT_AWAKE) && 5129 (ahp->ah_mci_query_bt == AH_TRUE)) 5130 { 5131 ahp->ah_mci_need_flush_btinfo = AH_TRUE; 5132 } 5133 } 5134 #endif 5135 } 5136 #endif 5137 5138 /* Start TSF2 for generic timer 8-15. */ 5139 ar9300_start_tsf2(ah); 5140 5141 /* MIMO Power save setting */ 5142 if (ar9300_get_capability(ah, HAL_CAP_DYNAMIC_SMPS, 0, AH_NULL) == HAL_OK) { 5143 ar9300_set_sm_power_mode(ah, ahp->ah_sm_power_mode); 5144 } 5145 5146 /* 5147 * For big endian systems turn on swapping for descriptors 5148 */ 5149 #if AH_BYTE_ORDER == AH_BIG_ENDIAN 5150 if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) { 5151 OS_REG_RMW(ah, AR_CFG, AR_CFG_SWTB | AR_CFG_SWRB, 0); 5152 } else { 5153 ar9300_init_cfg_reg(ah); 5154 } 5155 #endif 5156 5157 if ( AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) { 5158 OS_REG_RMW(ah, AR_CFG_LED, AR_CFG_LED_ASSOC_CTL, AR_CFG_LED_ASSOC_CTL); 5159 } 5160 5161 #if !(defined(ART_BUILD)) && defined(ATH_SUPPORT_LED) 5162 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val); 5163 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg)) 5164 #define ATH_GPIO_OUT_FUNCTION3 0xB8040038 5165 #define ATH_GPIO_OE 0xB8040000 5166 if ( AR_SREV_WASP(ah)) { 5167 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) { 5168 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x33 << 8) ); 5169 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) ))); 5170 } 5171 else { 5172 5173 /* Disable 2G WLAN LED. During ath_open, reset function is called even before channel is set. 5174 So 2GHz is taken as default and it also blinks. Hence 5175 to avoid both from blinking, disable 2G led while in 5G mode */ 5176 5177 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) | (1 << 13) )); 5178 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x33) ); 5179 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) ))); 5180 } 5181 5182 } 5183 else if (AR_SREV_SCORPION(ah)) { 5184 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) { 5185 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x2F << 8) ); 5186 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )) | (0x1 << 12))); 5187 } else if (IS_CHAN_5GHZ((AH_PRIVATE(ah)->ah_curchan))) { 5188 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x2F) ); 5189 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )) | (0x1 << 13))); 5190 } 5191 } 5192 #undef REG_READ 5193 #undef REG_WRITE 5194 #endif 5195 5196 /* XXX FreeBSD What's this? -adrian */ 5197 #if 0 5198 chan->channel_flags = ichan->channel_flags; 5199 chan->priv_flags = ichan->priv_flags; 5200 #endif 5201 5202 #if FIX_NOISE_FLOOR 5203 /* XXX FreeBSD is ichan appropariate? It was curchan.. */ 5204 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf); 5205 ar9300_load_nf(ah, nf_buf); 5206 if (nf_hist_buff_reset == 1) 5207 { 5208 nf_hist_buff_reset = 0; 5209 #ifndef ATH_NF_PER_CHAN 5210 if (First_NFCal(ah, ichan, is_scan, chan)){ 5211 if (ahp->ah_skip_rx_iq_cal && !is_scan) { 5212 /* restore RX Cal result if existing */ 5213 ar9300_rx_iq_cal_restore(ah); 5214 ahp->ah_skip_rx_iq_cal = AH_FALSE; 5215 } 5216 } 5217 #endif /* ATH_NF_PER_CHAN */ 5218 } 5219 else{ 5220 ar9300_start_nf_cal(ah); 5221 } 5222 #endif 5223 5224 #ifdef AH_SUPPORT_AR9300 5225 /* BB Panic Watchdog */ 5226 if (ar9300_get_capability(ah, HAL_CAP_BB_PANIC_WATCHDOG, 0, AH_NULL) == 5227 HAL_OK) 5228 { 5229 ar9300_config_bb_panic_watchdog(ah); 5230 } 5231 #endif 5232 5233 /* While receiving unsupported rate frame receive state machine 5234 * gets into a state 0xb and if phy_restart happens when rx 5235 * state machine is in 0xb state, BB would go hang, if we 5236 * see 0xb state after first bb panic, make sure that we 5237 * disable the phy_restart. 5238 * 5239 * There may be multiple panics, make sure that we always do 5240 * this if we see this panic at least once. This is required 5241 * because reset seems to be writing from INI file. 5242 */ 5243 if ((ar9300_get_capability(ah, HAL_CAP_PHYRESTART_CLR_WAR, 0, AH_NULL) 5244 == HAL_OK) && (((MS((AH9300(ah)->ah_bb_panic_last_status), 5245 AR_PHY_BB_WD_RX_OFDM_SM)) == 0xb) || 5246 AH9300(ah)->ah_phyrestart_disabled) ) 5247 { 5248 ar9300_disable_phy_restart(ah, 1); 5249 } 5250 5251 5252 5253 ahp->ah_radar1 = MS(OS_REG_READ(ah, AR_PHY_RADAR_1), 5254 AR_PHY_RADAR_1_CF_BIN_THRESH); 5255 ahp->ah_dc_offset = MS(OS_REG_READ(ah, AR_PHY_TIMING2), 5256 AR_PHY_TIMING2_DC_OFFSET); 5257 ahp->ah_disable_cck = MS(OS_REG_READ(ah, AR_PHY_MODE), 5258 AR_PHY_MODE_DISABLE_CCK); 5259 5260 if (AH9300(ah)->ah_enable_keysearch_always) { 5261 ar9300_enable_keysearch_always(ah, 1); 5262 } 5263 5264 #if ATH_LOW_POWER_ENABLE 5265 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val) 5266 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg)) 5267 if (AR_SREV_OSPREY(ah)) { 5268 REG_WRITE(0xb4000080, REG_READ(0xb4000080) | 3); 5269 OS_REG_WRITE(ah, AR_RTC_RESET, 1); 5270 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL), 5271 AR_PCIE_PM_CTRL_ENA); 5272 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_SPARE), 0xffffffff); 5273 } 5274 #undef REG_READ 5275 #undef REG_WRITE 5276 #endif /* ATH_LOW_POWER_ENABLE */ 5277 5278 WAR_USB_DISABLE_PLL_LOCK_DETECT(ah); 5279 5280 /* H/W Green TX */ 5281 ar9300_control_signals_for_green_tx_mode(ah); 5282 /* Smart Antenna, only for 5GHz on Scropion */ 5283 if (IEEE80211_IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan)) && AR_SREV_SCORPION(ah)) { 5284 ahp->ah_smartantenna_enable = 0; 5285 } 5286 5287 ar9300_set_smart_antenna(ah, ahp->ah_smartantenna_enable); 5288 5289 if (ahp->ah_skip_rx_iq_cal && !is_scan) { 5290 /* restore RX Cal result if existing */ 5291 ar9300_rx_iq_cal_restore(ah); 5292 ahp->ah_skip_rx_iq_cal = AH_FALSE; 5293 } 5294 5295 5296 return AH_TRUE; 5297 bad: 5298 OS_MARK(ah, AH_MARK_RESET_DONE, ecode); 5299 *status = ecode; 5300 5301 if (ahp->ah_skip_rx_iq_cal && !is_scan) { 5302 /* restore RX Cal result if existing */ 5303 ar9300_rx_iq_cal_restore(ah); 5304 ahp->ah_skip_rx_iq_cal = AH_FALSE; 5305 } 5306 5307 return AH_FALSE; 5308 #undef FAIL 5309 } 5310 5311 void 5312 ar9300_green_ap_ps_on_off( struct ath_hal *ah, u_int16_t on_off) 5313 { 5314 /* Set/reset the ps flag */ 5315 AH9300(ah)->green_ap_ps_on = !!on_off; 5316 } 5317 5318 /* 5319 * This function returns 1, where it is possible to do 5320 * single-chain power save. 5321 */ 5322 u_int16_t 5323 ar9300_is_single_ant_power_save_possible(struct ath_hal *ah) 5324 { 5325 return AH_TRUE; 5326 } 5327 5328 /* To avoid compilation warnings. Functions not used when EMULATION. */ 5329 /* 5330 * ar9300_find_mag_approx() 5331 */ 5332 static int32_t 5333 ar9300_find_mag_approx(struct ath_hal *ah, int32_t in_re, int32_t in_im) 5334 { 5335 int32_t abs_i = abs(in_re); 5336 int32_t abs_q = abs(in_im); 5337 int32_t max_abs, min_abs; 5338 5339 if (abs_i > abs_q) { 5340 max_abs = abs_i; 5341 min_abs = abs_q; 5342 } else { 5343 max_abs = abs_q; 5344 min_abs = abs_i; 5345 } 5346 5347 return (max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4)); 5348 } 5349 5350 /* 5351 * ar9300_solve_iq_cal() 5352 * solve 4x4 linear equation used in loopback iq cal. 5353 */ 5354 static HAL_BOOL 5355 ar9300_solve_iq_cal( 5356 struct ath_hal *ah, 5357 int32_t sin_2phi_1, 5358 int32_t cos_2phi_1, 5359 int32_t sin_2phi_2, 5360 int32_t cos_2phi_2, 5361 int32_t mag_a0_d0, 5362 int32_t phs_a0_d0, 5363 int32_t mag_a1_d0, 5364 int32_t phs_a1_d0, 5365 int32_t solved_eq[]) 5366 { 5367 int32_t f1 = cos_2phi_1 - cos_2phi_2; 5368 int32_t f3 = sin_2phi_1 - sin_2phi_2; 5369 int32_t f2; 5370 int32_t mag_tx, phs_tx, mag_rx, phs_rx; 5371 const int32_t result_shift = 1 << 15; 5372 5373 f2 = (((int64_t)f1 * (int64_t)f1) / result_shift) + (((int64_t)f3 * (int64_t)f3) / result_shift); 5374 5375 if (0 == f2) { 5376 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Divide by 0(%d).\n", 5377 __func__, __LINE__); 5378 return AH_FALSE; 5379 } 5380 5381 /* magnitude mismatch, tx */ 5382 mag_tx = f1 * (mag_a0_d0 - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0); 5383 /* phase mismatch, tx */ 5384 phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0); 5385 5386 mag_tx = (mag_tx / f2); 5387 phs_tx = (phs_tx / f2); 5388 5389 /* magnitude mismatch, rx */ 5390 mag_rx = 5391 mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) / result_shift; 5392 /* phase mismatch, rx */ 5393 phs_rx = 5394 phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) / result_shift; 5395 5396 solved_eq[0] = mag_tx; 5397 solved_eq[1] = phs_tx; 5398 solved_eq[2] = mag_rx; 5399 solved_eq[3] = phs_rx; 5400 5401 return AH_TRUE; 5402 } 5403 5404 /* 5405 * ar9300_calc_iq_corr() 5406 */ 5407 static HAL_BOOL 5408 ar9300_calc_iq_corr(struct ath_hal *ah, int32_t chain_idx, 5409 const int32_t iq_res[], int32_t iqc_coeff[]) 5410 { 5411 int32_t i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0; 5412 int32_t i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1; 5413 int32_t i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0; 5414 int32_t i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1; 5415 int32_t mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1; 5416 int32_t phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1; 5417 int32_t sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2; 5418 int32_t mag_tx, phs_tx, mag_rx, phs_rx; 5419 int32_t solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx; 5420 int32_t q_q_coff, q_i_coff; 5421 const int32_t res_scale = 1 << 15; 5422 const int32_t delpt_shift = 1 << 8; 5423 int32_t mag1, mag2; 5424 5425 i2_m_q2_a0_d0 = iq_res[0] & 0xfff; 5426 i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff; 5427 iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8); 5428 5429 if (i2_m_q2_a0_d0 > 0x800) { 5430 i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1); 5431 } 5432 if (iq_corr_a0_d0 > 0x800) { 5433 iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1); 5434 } 5435 5436 i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff; 5437 i2_p_q2_a0_d1 = (iq_res[2] & 0xfff); 5438 iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff; 5439 5440 if (i2_m_q2_a0_d1 > 0x800) { 5441 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1); 5442 } 5443 if (iq_corr_a0_d1 > 0x800) { 5444 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1); 5445 } 5446 5447 i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8); 5448 i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff; 5449 iq_corr_a1_d0 = iq_res[4] & 0xfff; 5450 5451 if (i2_m_q2_a1_d0 > 0x800) { 5452 i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1); 5453 } 5454 if (iq_corr_a1_d0 > 0x800) { 5455 iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1); 5456 } 5457 5458 i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff; 5459 i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8); 5460 iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff; 5461 5462 if (i2_m_q2_a1_d1 > 0x800) { 5463 i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1); 5464 } 5465 if (iq_corr_a1_d1 > 0x800) { 5466 iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1); 5467 } 5468 5469 if ((i2_p_q2_a0_d0 == 0) || 5470 (i2_p_q2_a0_d1 == 0) || 5471 (i2_p_q2_a1_d0 == 0) || 5472 (i2_p_q2_a1_d1 == 0)) { 5473 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5474 "%s: Divide by 0(%d):\na0_d0=%d\na0_d1=%d\na2_d0=%d\na1_d1=%d\n", 5475 __func__, __LINE__, 5476 i2_p_q2_a0_d0, i2_p_q2_a0_d1, i2_p_q2_a1_d0, i2_p_q2_a1_d1); 5477 return AH_FALSE; 5478 } 5479 5480 if ((i2_p_q2_a0_d0 <= 1024) || (i2_p_q2_a0_d0 > 2047) || 5481 (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) || 5482 (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) || 5483 (i2_p_q2_a0_d0 <= iq_corr_a0_d0) || 5484 (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) || 5485 (i2_p_q2_a0_d1 <= iq_corr_a0_d1) || 5486 (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) || 5487 (i2_p_q2_a1_d0 <= iq_corr_a1_d0) || 5488 (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) || 5489 (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) { 5490 return AH_FALSE; 5491 } 5492 5493 mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0; 5494 phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0; 5495 5496 mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1; 5497 phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1; 5498 5499 mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0; 5500 phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0; 5501 5502 mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1; 5503 phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1; 5504 5505 /* without analog phase shift */ 5506 sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT); 5507 /* without analog phase shift */ 5508 cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT); 5509 /* with analog phase shift */ 5510 sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT); 5511 /* with analog phase shift */ 5512 cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT); 5513 5514 /* force sin^2 + cos^2 = 1; */ 5515 /* find magnitude by approximation */ 5516 mag1 = ar9300_find_mag_approx(ah, cos_2phi_1, sin_2phi_1); 5517 mag2 = ar9300_find_mag_approx(ah, cos_2phi_2, sin_2phi_2); 5518 5519 if ((mag1 == 0) || (mag2 == 0)) { 5520 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5521 "%s: Divide by 0(%d): mag1=%d, mag2=%d\n", 5522 __func__, __LINE__, mag1, mag2); 5523 return AH_FALSE; 5524 } 5525 5526 /* normalization sin and cos by mag */ 5527 sin_2phi_1 = (sin_2phi_1 * res_scale / mag1); 5528 cos_2phi_1 = (cos_2phi_1 * res_scale / mag1); 5529 sin_2phi_2 = (sin_2phi_2 * res_scale / mag2); 5530 cos_2phi_2 = (cos_2phi_2 * res_scale / mag2); 5531 5532 /* calculate IQ mismatch */ 5533 if (AH_FALSE == ar9300_solve_iq_cal(ah, 5534 sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2, mag_a0_d0, 5535 phs_a0_d0, mag_a1_d0, phs_a1_d0, solved_eq)) 5536 { 5537 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5538 "%s: Call to ar9300_solve_iq_cal failed.\n", __func__); 5539 return AH_FALSE; 5540 } 5541 5542 mag_tx = solved_eq[0]; 5543 phs_tx = solved_eq[1]; 5544 mag_rx = solved_eq[2]; 5545 phs_rx = solved_eq[3]; 5546 5547 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5548 "%s: chain %d: mag mismatch=%d phase mismatch=%d\n", 5549 __func__, chain_idx, mag_tx / res_scale, phs_tx / res_scale); 5550 5551 if (res_scale == mag_tx) { 5552 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5553 "%s: Divide by 0(%d): mag_tx=%d, res_scale=%d\n", 5554 __func__, __LINE__, mag_tx, res_scale); 5555 return AH_FALSE; 5556 } 5557 5558 /* calculate and quantize Tx IQ correction factor */ 5559 mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx); 5560 phs_corr_tx = -phs_tx; 5561 5562 q_q_coff = (mag_corr_tx * 128 / res_scale); 5563 q_i_coff = (phs_corr_tx * 256 / res_scale); 5564 5565 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5566 "%s: tx chain %d: mag corr=%d phase corr=%d\n", 5567 __func__, chain_idx, q_q_coff, q_i_coff); 5568 5569 if (q_i_coff < -63) { 5570 q_i_coff = -63; 5571 } 5572 if (q_i_coff > 63) { 5573 q_i_coff = 63; 5574 } 5575 if (q_q_coff < -63) { 5576 q_q_coff = -63; 5577 } 5578 if (q_q_coff > 63) { 5579 q_q_coff = 63; 5580 } 5581 5582 iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff); 5583 5584 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: tx chain %d: iq corr coeff=%x\n", 5585 __func__, chain_idx, iqc_coeff[0]); 5586 5587 if (-mag_rx == res_scale) { 5588 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5589 "%s: Divide by 0(%d): mag_rx=%d, res_scale=%d\n", 5590 __func__, __LINE__, mag_rx, res_scale); 5591 return AH_FALSE; 5592 } 5593 5594 /* calculate and quantize Rx IQ correction factors */ 5595 mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx); 5596 phs_corr_rx = -phs_rx; 5597 5598 q_q_coff = (mag_corr_rx * 128 / res_scale); 5599 q_i_coff = (phs_corr_rx * 256 / res_scale); 5600 5601 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5602 "%s: rx chain %d: mag corr=%d phase corr=%d\n", 5603 __func__, chain_idx, q_q_coff, q_i_coff); 5604 5605 if (q_i_coff < -63) { 5606 q_i_coff = -63; 5607 } 5608 if (q_i_coff > 63) { 5609 q_i_coff = 63; 5610 } 5611 if (q_q_coff < -63) { 5612 q_q_coff = -63; 5613 } 5614 if (q_q_coff > 63) { 5615 q_q_coff = 63; 5616 } 5617 5618 iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff); 5619 5620 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: rx chain %d: iq corr coeff=%x\n", 5621 __func__, chain_idx, iqc_coeff[1]); 5622 5623 return AH_TRUE; 5624 } 5625 5626 #define MAX_MAG_DELTA 11 //maximum magnitude mismatch delta across gains 5627 #define MAX_PHS_DELTA 10 //maximum phase mismatch delta across gains 5628 #define ABS(x) ((x) >= 0 ? (x) : (-(x))) 5629 5630 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = { 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_01_B0, 5635 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, 5636 AR_PHY_TX_IQCAL_CORR_COEFF_01_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_23_B0, 5641 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1, 5642 AR_PHY_TX_IQCAL_CORR_COEFF_23_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_45_B0, 5647 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1, 5648 AR_PHY_TX_IQCAL_CORR_COEFF_45_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 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0, 5653 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1, 5654 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2}, 5655 }; 5656 5657 static void 5658 ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan, u_int32_t num_chains, 5659 struct coeff_t *coeff, HAL_BOOL is_cal_reusable) 5660 { 5661 int nmeasurement, ch_idx, im; 5662 int32_t magnitude, phase; 5663 int32_t magnitude_max, phase_max; 5664 int32_t magnitude_min, phase_min; 5665 5666 int32_t magnitude_max_idx, phase_max_idx; 5667 int32_t magnitude_min_idx, phase_min_idx; 5668 5669 int32_t magnitude_avg, phase_avg; 5670 int32_t outlier_mag_idx = 0; 5671 int32_t outlier_phs_idx = 0; 5672 5673 5674 if (AR_SREV_POSEIDON(ah)) { 5675 HALASSERT(num_chains == 0x1); 5676 5677 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON; 5678 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON; 5679 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON; 5680 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON; 5681 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON; 5682 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON; 5683 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON; 5684 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON; 5685 } 5686 5687 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) { 5688 nmeasurement = OS_REG_READ_FIELD(ah, 5689 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0); 5690 if (nmeasurement > MAX_MEASUREMENT) { 5691 nmeasurement = MAX_MEASUREMENT; 5692 } 5693 5694 if (!AR_SREV_SCORPION(ah)) { 5695 /* 5696 * reset max/min variable to min/max values so that 5697 * we always start with 1st calibrated gain value 5698 */ 5699 magnitude_max = -64; 5700 phase_max = -64; 5701 magnitude_min = 63; 5702 phase_min = 63; 5703 magnitude_avg = 0; 5704 phase_avg = 0; 5705 magnitude_max_idx = 0; 5706 magnitude_min_idx = 0; 5707 phase_max_idx = 0; 5708 phase_min_idx = 0; 5709 5710 /* detect outlier only if nmeasurement > 1 */ 5711 if (nmeasurement > 1) { 5712 /* printf("----------- start outlier detection -----------\n"); */ 5713 /* 5714 * find max/min and phase/mag mismatch across all calibrated gains 5715 */ 5716 for (im = 0; im < nmeasurement; im++) { 5717 magnitude = coeff->mag_coeff[ch_idx][im][0]; 5718 phase = coeff->phs_coeff[ch_idx][im][0]; 5719 5720 magnitude_avg = magnitude_avg + magnitude; 5721 phase_avg = phase_avg + phase; 5722 if (magnitude > magnitude_max) { 5723 magnitude_max = magnitude; 5724 magnitude_max_idx = im; 5725 } 5726 if (magnitude < magnitude_min) { 5727 magnitude_min = magnitude; 5728 magnitude_min_idx = im; 5729 } 5730 if (phase > phase_max) { 5731 phase_max = phase; 5732 phase_max_idx = im; 5733 } 5734 if (phase < phase_min) { 5735 phase_min = phase; 5736 phase_min_idx = im; 5737 } 5738 } 5739 /* find average (exclude max abs value) */ 5740 for (im = 0; im < nmeasurement; im++) { 5741 magnitude = coeff->mag_coeff[ch_idx][im][0]; 5742 phase = coeff->phs_coeff[ch_idx][im][0]; 5743 if ((ABS(magnitude) < ABS(magnitude_max)) || 5744 (ABS(magnitude) < ABS(magnitude_min))) 5745 { 5746 magnitude_avg = magnitude_avg + magnitude; 5747 } 5748 if ((ABS(phase) < ABS(phase_max)) || 5749 (ABS(phase) < ABS(phase_min))) 5750 { 5751 phase_avg = phase_avg + phase; 5752 } 5753 } 5754 magnitude_avg = magnitude_avg / (nmeasurement - 1); 5755 phase_avg = phase_avg / (nmeasurement - 1); 5756 5757 /* detect magnitude outlier */ 5758 if (ABS(magnitude_max - magnitude_min) > MAX_MAG_DELTA) { 5759 if (ABS(magnitude_max - magnitude_avg) > 5760 ABS(magnitude_min - magnitude_avg)) 5761 { 5762 /* max is outlier, force to avg */ 5763 outlier_mag_idx = magnitude_max_idx; 5764 } else { 5765 /* min is outlier, force to avg */ 5766 outlier_mag_idx = magnitude_min_idx; 5767 } 5768 coeff->mag_coeff[ch_idx][outlier_mag_idx][0] = magnitude_avg; 5769 coeff->phs_coeff[ch_idx][outlier_mag_idx][0] = phase_avg; 5770 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5771 "[ch%d][outlier mag gain%d]:: " 5772 "mag_avg = %d (/128), phase_avg = %d (/256)\n", 5773 ch_idx, outlier_mag_idx, magnitude_avg, phase_avg); 5774 } 5775 /* detect phase outlier */ 5776 if (ABS(phase_max - phase_min) > MAX_PHS_DELTA) { 5777 if (ABS(phase_max-phase_avg) > ABS(phase_min - phase_avg)) { 5778 /* max is outlier, force to avg */ 5779 outlier_phs_idx = phase_max_idx; 5780 } else{ 5781 /* min is outlier, force to avg */ 5782 outlier_phs_idx = phase_min_idx; 5783 } 5784 coeff->mag_coeff[ch_idx][outlier_phs_idx][0] = magnitude_avg; 5785 coeff->phs_coeff[ch_idx][outlier_phs_idx][0] = phase_avg; 5786 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5787 "[ch%d][outlier phs gain%d]:: " 5788 "mag_avg = %d (/128), phase_avg = %d (/256)\n", 5789 ch_idx, outlier_phs_idx, magnitude_avg, phase_avg); 5790 } 5791 } 5792 } 5793 5794 /*printf("------------ after outlier detection -------------\n");*/ 5795 for (im = 0; im < nmeasurement; im++) { 5796 magnitude = coeff->mag_coeff[ch_idx][im][0]; 5797 phase = coeff->phs_coeff[ch_idx][im][0]; 5798 5799 #if 0 5800 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n", 5801 ch_idx, im, magnitude, phase); 5802 #endif 5803 5804 coeff->iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7); 5805 5806 if ((im % 2) == 0) { 5807 OS_REG_RMW_FIELD(ah, 5808 tx_corr_coeff[im][ch_idx], 5809 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE, 5810 coeff->iqc_coeff[0]); 5811 } else { 5812 OS_REG_RMW_FIELD(ah, 5813 tx_corr_coeff[im][ch_idx], 5814 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, 5815 coeff->iqc_coeff[0]); 5816 } 5817 #if ATH_SUPPORT_CAL_REUSE 5818 ichan->tx_corr_coeff[im][ch_idx] = coeff->iqc_coeff[0]; 5819 #endif 5820 } 5821 #if ATH_SUPPORT_CAL_REUSE 5822 ichan->num_measures[ch_idx] = nmeasurement; 5823 #endif 5824 } 5825 5826 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, 5827 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); 5828 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, 5829 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); 5830 5831 #if ATH_SUPPORT_CAL_REUSE 5832 if (is_cal_reusable) { 5833 ichan->one_time_txiqcal_done = AH_TRUE; 5834 HALDEBUG(ah, HAL_DEBUG_FCS_RTT, 5835 "(FCS) TXIQCAL saved - %d\n", ichan->channel); 5836 } 5837 #endif 5838 } 5839 5840 #if ATH_SUPPORT_CAL_REUSE 5841 static void 5842 ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan) 5843 { 5844 struct ath_hal_9300 *ahp = AH9300(ah); 5845 int nmeasurement, ch_idx, im; 5846 5847 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = { 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_01_B0, 5852 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, 5853 AR_PHY_TX_IQCAL_CORR_COEFF_01_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_23_B0, 5858 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1, 5859 AR_PHY_TX_IQCAL_CORR_COEFF_23_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_45_B0, 5864 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1, 5865 AR_PHY_TX_IQCAL_CORR_COEFF_45_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 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0, 5870 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1, 5871 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2}, 5872 }; 5873 5874 if (AR_SREV_POSEIDON(ah)) { 5875 HALASSERT(ahp->ah_tx_cal_chainmask == 0x1); 5876 5877 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON; 5878 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON; 5879 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON; 5880 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON; 5881 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON; 5882 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON; 5883 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON; 5884 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON; 5885 } 5886 5887 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) { 5888 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) { 5889 continue; 5890 } 5891 nmeasurement = ichan->num_measures[ch_idx]; 5892 5893 for (im = 0; im < nmeasurement; im++) { 5894 if ((im % 2) == 0) { 5895 OS_REG_RMW_FIELD(ah, 5896 tx_corr_coeff[im][ch_idx], 5897 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE, 5898 ichan->tx_corr_coeff[im][ch_idx]); 5899 } else { 5900 OS_REG_RMW_FIELD(ah, 5901 tx_corr_coeff[im][ch_idx], 5902 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, 5903 ichan->tx_corr_coeff[im][ch_idx]); 5904 } 5905 } 5906 } 5907 5908 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, 5909 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); 5910 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, 5911 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); 5912 } 5913 #endif 5914 5915 /* 5916 * ar9300_tx_iq_cal_hw_run is only needed for osprey/wasp/hornet 5917 * It is not needed for jupiter/poseidon. 5918 */ 5919 HAL_BOOL 5920 ar9300_tx_iq_cal_hw_run(struct ath_hal *ah) 5921 { 5922 int is_tx_gain_forced; 5923 5924 is_tx_gain_forced = OS_REG_READ_FIELD(ah, 5925 AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE); 5926 if (is_tx_gain_forced) { 5927 /*printf("Tx gain can not be forced during tx I/Q cal!\n");*/ 5928 OS_REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE, 0); 5929 } 5930 5931 /* enable tx IQ cal */ 5932 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START(ah), 5933 AR_PHY_TX_IQCAL_START_DO_CAL, AR_PHY_TX_IQCAL_START_DO_CAL); 5934 5935 if (!ath_hal_wait(ah, 5936 AR_PHY_TX_IQCAL_START(ah), AR_PHY_TX_IQCAL_START_DO_CAL, 0)) 5937 { 5938 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5939 "%s: Tx IQ Cal is never completed.\n", __func__); 5940 return AH_FALSE; 5941 } 5942 return AH_TRUE; 5943 } 5944 5945 static void 5946 ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan, 5947 int iqcal_idx, int max_iqcal,HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr) 5948 { 5949 int nmeasurement=0, im, ix, iy, temp; 5950 struct ath_hal_9300 *ahp = AH9300(ah); 5951 u_int32_t txiqcal_status[AR9300_MAX_CHAINS] = { 5952 AR_PHY_TX_IQCAL_STATUS_B0(ah), 5953 AR_PHY_TX_IQCAL_STATUS_B1, 5954 AR_PHY_TX_IQCAL_STATUS_B2, 5955 }; 5956 const u_int32_t chan_info_tab[] = { 5957 AR_PHY_CHAN_INFO_TAB_0, 5958 AR_PHY_CHAN_INFO_TAB_1, 5959 AR_PHY_CHAN_INFO_TAB_2, 5960 }; 5961 int32_t iq_res[6]; 5962 int32_t ch_idx, j; 5963 u_int32_t num_chains = 0; 5964 static struct coeff_t coeff; 5965 txiqcal_status[0] = AR_PHY_TX_IQCAL_STATUS_B0(ah); 5966 5967 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) { 5968 if (ahp->ah_tx_chainmask & (1 << ch_idx)) { 5969 num_chains++; 5970 } 5971 } 5972 5973 if (apply_last_corr) { 5974 if (coeff.last_cal == AH_TRUE) { 5975 int32_t magnitude, phase; 5976 int ch_idx, im; 5977 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = { 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_01_B0, 5982 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, 5983 AR_PHY_TX_IQCAL_CORR_COEFF_01_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_23_B0, 5988 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1, 5989 AR_PHY_TX_IQCAL_CORR_COEFF_23_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_45_B0, 5994 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1, 5995 AR_PHY_TX_IQCAL_CORR_COEFF_45_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 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0, 6000 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1, 6001 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2}, 6002 }; 6003 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) { 6004 for (im = 0; im < coeff.last_nmeasurement; im++) { 6005 magnitude = coeff.mag_coeff[ch_idx][im][0]; 6006 phase = coeff.phs_coeff[ch_idx][im][0]; 6007 6008 #if 0 6009 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n", 6010 ch_idx, im, magnitude, phase); 6011 #endif 6012 6013 coeff.iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7); 6014 if ((im % 2) == 0) { 6015 OS_REG_RMW_FIELD(ah, 6016 tx_corr_coeff[im][ch_idx], 6017 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE, 6018 coeff.iqc_coeff[0]); 6019 } else { 6020 OS_REG_RMW_FIELD(ah, 6021 tx_corr_coeff[im][ch_idx], 6022 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, 6023 coeff.iqc_coeff[0]); 6024 } 6025 } 6026 } 6027 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, 6028 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); 6029 } 6030 return; 6031 } 6032 6033 6034 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) { 6035 nmeasurement = OS_REG_READ_FIELD(ah, 6036 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0); 6037 if (nmeasurement > MAX_MEASUREMENT) { 6038 nmeasurement = MAX_MEASUREMENT; 6039 } 6040 6041 for (im = 0; im < nmeasurement; im++) { 6042 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 6043 "%s: Doing Tx IQ Cal for chain %d.\n", __func__, ch_idx); 6044 if (OS_REG_READ(ah, txiqcal_status[ch_idx]) & 6045 AR_PHY_TX_IQCAL_STATUS_FAILED) 6046 { 6047 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 6048 "%s: Tx IQ Cal failed for chain %d.\n", __func__, ch_idx); 6049 goto TX_IQ_CAL_FAILED_; 6050 } 6051 6052 for (j = 0; j < 3; j++) { 6053 u_int32_t idx = 2 * j; 6054 /* 3 registers for each calibration result */ 6055 u_int32_t offset = 4 * (3 * im + j); 6056 6057 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, 6058 AR_PHY_CHAN_INFO_TAB_S2_READ, 0); 6059 /* 32 bits */ 6060 iq_res[idx] = OS_REG_READ(ah, chan_info_tab[ch_idx] + offset); 6061 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, 6062 AR_PHY_CHAN_INFO_TAB_S2_READ, 1); 6063 /* 16 bits */ 6064 iq_res[idx + 1] = 0xffff & 6065 OS_REG_READ(ah, chan_info_tab[ch_idx] + offset); 6066 6067 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 6068 "%s: IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n", 6069 __func__, idx, iq_res[idx], idx + 1, iq_res[idx + 1]); 6070 } 6071 6072 if (AH_FALSE == ar9300_calc_iq_corr( 6073 ah, ch_idx, iq_res, coeff.iqc_coeff)) 6074 { 6075 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 6076 "%s: Failed in calculation of IQ correction.\n", 6077 __func__); 6078 goto TX_IQ_CAL_FAILED_; 6079 } 6080 6081 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] = coeff.iqc_coeff[0] & 0x7f; 6082 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] = (coeff.iqc_coeff[0] >> 7) & 0x7f; 6083 if (coeff.mag_coeff[ch_idx][im][iqcal_idx-1] > 63) { 6084 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] -= 128; 6085 } 6086 if (coeff.phs_coeff[ch_idx][im][iqcal_idx-1] > 63) { 6087 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] -= 128; 6088 } 6089 #if 0 6090 ath_hal_printf(ah, "IQCAL::[ch%d][gain%d]:: mag = %d phase = %d \n", 6091 ch_idx, im, coeff.mag_coeff[ch_idx][im][iqcal_idx-1], 6092 coeff.phs_coeff[ch_idx][im][iqcal_idx-1]); 6093 #endif 6094 } 6095 } 6096 //last iteration; calculate mag and phs 6097 if (iqcal_idx == max_iqcal) { 6098 if (max_iqcal>1) { 6099 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) { 6100 for (im = 0; im < nmeasurement; im++) { 6101 //sort mag and phs 6102 for( ix=0;ix<max_iqcal-1;ix++){ 6103 for( iy=ix+1;iy<=max_iqcal-1;iy++){ 6104 if(coeff.mag_coeff[ch_idx][im][iy] < 6105 coeff.mag_coeff[ch_idx][im][ix]) { 6106 //swap 6107 temp=coeff.mag_coeff[ch_idx][im][ix]; 6108 coeff.mag_coeff[ch_idx][im][ix] = coeff.mag_coeff[ch_idx][im][iy]; 6109 coeff.mag_coeff[ch_idx][im][iy] = temp; 6110 } 6111 if(coeff.phs_coeff[ch_idx][im][iy] < 6112 coeff.phs_coeff[ch_idx][im][ix]){ 6113 //swap 6114 temp=coeff.phs_coeff[ch_idx][im][ix]; 6115 coeff.phs_coeff[ch_idx][im][ix]=coeff.phs_coeff[ch_idx][im][iy]; 6116 coeff.phs_coeff[ch_idx][im][iy]=temp; 6117 } 6118 } 6119 } 6120 //select median; 3rd entry in the sorted array 6121 coeff.mag_coeff[ch_idx][im][0] = 6122 coeff.mag_coeff[ch_idx][im][max_iqcal/2]; 6123 coeff.phs_coeff[ch_idx][im][0] = 6124 coeff.phs_coeff[ch_idx][im][max_iqcal/2]; 6125 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 6126 "IQCAL: Median [ch%d][gain%d]:: mag = %d phase = %d \n", 6127 ch_idx, im,coeff.mag_coeff[ch_idx][im][0], 6128 coeff.phs_coeff[ch_idx][im][0]); 6129 } 6130 } 6131 } 6132 ar9300_tx_iq_cal_outlier_detection(ah,ichan, num_chains, &coeff,is_cal_reusable); 6133 } 6134 6135 6136 coeff.last_nmeasurement = nmeasurement; 6137 coeff.last_cal = AH_TRUE; 6138 6139 return; 6140 6141 TX_IQ_CAL_FAILED_: 6142 /* no need to print this, it is AGC failure not chip stuck */ 6143 /*ath_hal_printf(ah, "Tx IQ Cal failed(%d)\n", line);*/ 6144 coeff.last_cal = AH_FALSE; 6145 return; 6146 } 6147 6148 6149 /* 6150 * ar9300_disable_phy_restart 6151 * 6152 * In some BBpanics, we can disable the phyrestart 6153 * disable_phy_restart 6154 * != 0, disable the phy restart in h/w 6155 * == 0, enable the phy restart in h/w 6156 */ 6157 void ar9300_disable_phy_restart(struct ath_hal *ah, int disable_phy_restart) 6158 { 6159 u_int32_t val; 6160 6161 val = OS_REG_READ(ah, AR_PHY_RESTART); 6162 if (disable_phy_restart) { 6163 val &= ~AR_PHY_RESTART_ENA; 6164 AH9300(ah)->ah_phyrestart_disabled = 1; 6165 } else { 6166 val |= AR_PHY_RESTART_ENA; 6167 AH9300(ah)->ah_phyrestart_disabled = 0; 6168 } 6169 OS_REG_WRITE(ah, AR_PHY_RESTART, val); 6170 6171 val = OS_REG_READ(ah, AR_PHY_RESTART); 6172 } 6173 6174 HAL_BOOL 6175 ar9300_interference_is_present(struct ath_hal *ah) 6176 { 6177 int i; 6178 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6179 const struct ieee80211_channel *chan = ahpriv->ah_curchan; 6180 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 6181 6182 if (ichan == NULL) { 6183 ath_hal_printf(ah, "%s: called with ichan=NULL\n", __func__); 6184 return AH_FALSE; 6185 } 6186 6187 /* This function is called after a stuck beacon, if EACS is enabled. 6188 * If CW interference is severe, then HW goes into a loop of continuous 6189 * stuck beacons and resets. On reset the NF cal history is cleared. 6190 * So the median value of the history cannot be used - 6191 * hence check if any value (Chain 0/Primary Channel) 6192 * is outside the bounds. 6193 */ 6194 HAL_NFCAL_HIST_FULL *h = AH_HOME_CHAN_NFCAL_HIST(ah, ichan); 6195 for (i = 0; i < HAL_NF_CAL_HIST_LEN_FULL; i++) { 6196 if (h->nf_cal_buffer[i][0] > 6197 AH9300(ah)->nfp->nominal + AH9300(ah)->nf_cw_int_delta) 6198 { 6199 return AH_TRUE; 6200 } 6201 6202 } 6203 return AH_FALSE; 6204 } 6205 6206 #if ATH_SUPPORT_CRDC 6207 void 6208 ar9300_crdc_rx_notify(struct ath_hal *ah, struct ath_rx_status *rxs) 6209 { 6210 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6211 int rssi_index; 6212 6213 if ((!AR_SREV_WASP(ah)) || 6214 (!ahpriv->ah_config.ath_hal_crdc_enable)) { 6215 return; 6216 } 6217 6218 if (rxs->rs_isaggr && rxs->rs_moreaggr) { 6219 return; 6220 } 6221 6222 if ((rxs->rs_rssi_ctl0 >= HAL_RSSI_BAD) || 6223 (rxs->rs_rssi_ctl1 >= HAL_RSSI_BAD)) { 6224 return; 6225 } 6226 6227 rssi_index = ah->ah_crdc_rssi_ptr % HAL_MAX_CRDC_RSSI_SAMPLE; 6228 6229 ah->ah_crdc_rssi_sample[0][rssi_index] = rxs->rs_rssi_ctl0; 6230 ah->ah_crdc_rssi_sample[1][rssi_index] = rxs->rs_rssi_ctl1; 6231 6232 ah->ah_crdc_rssi_ptr++; 6233 } 6234 6235 static int 6236 ar9300_crdc_avg_rssi(struct ath_hal *ah, int chain) 6237 { 6238 int crdc_rssi_sum = 0; 6239 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr, i; 6240 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6241 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window; 6242 6243 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) { 6244 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE; 6245 } 6246 6247 for (i = 1; i <= crdc_window; i++) { 6248 crdc_rssi_sum += 6249 ah->ah_crdc_rssi_sample[chain] 6250 [(crdc_rssi_ptr - i) % HAL_MAX_CRDC_RSSI_SAMPLE]; 6251 } 6252 6253 return crdc_rssi_sum / crdc_window; 6254 } 6255 6256 static void 6257 ar9300_crdc_activate(struct ath_hal *ah, int rssi_diff, int enable) 6258 { 6259 int val, orig_val; 6260 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6261 int crdc_numerator = ahpriv->ah_config.ath_hal_crdc_numerator; 6262 int crdc_denominator = ahpriv->ah_config.ath_hal_crdc_denominator; 6263 int c = (rssi_diff * crdc_numerator) / crdc_denominator; 6264 6265 val = orig_val = OS_REG_READ(ah, AR_PHY_MULTICHAIN_CTRL); 6266 val &= 0xffffff00; 6267 if (enable) { 6268 val |= 0x1; 6269 val |= ((c << 1) & 0xff); 6270 } 6271 OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_CTRL, val); 6272 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "diff: %02d comp: %02d reg: %08x %08x\n", 6273 rssi_diff, c, orig_val, val); 6274 } 6275 6276 6277 void ar9300_chain_rssi_diff_compensation(struct ath_hal *ah) 6278 { 6279 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6280 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window; 6281 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr; 6282 int crdc_rssi_thresh = ahpriv->ah_config.ath_hal_crdc_rssithresh; 6283 int crdc_diff_thresh = ahpriv->ah_config.ath_hal_crdc_diffthresh; 6284 int avg_rssi[2], avg_rssi_diff; 6285 6286 if ((!AR_SREV_WASP(ah)) || 6287 (!ahpriv->ah_config.ath_hal_crdc_enable)) { 6288 if (ah->ah_crdc_rssi_ptr) { 6289 ar9300_crdc_activate(ah, 0, 0); 6290 ah->ah_crdc_rssi_ptr = 0; 6291 } 6292 return; 6293 } 6294 6295 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) { 6296 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE; 6297 } 6298 6299 if (crdc_rssi_ptr < crdc_window) { 6300 return; 6301 } 6302 6303 avg_rssi[0] = ar9300_crdc_avg_rssi(ah, 0); 6304 avg_rssi[1] = ar9300_crdc_avg_rssi(ah, 1); 6305 avg_rssi_diff = avg_rssi[1] - avg_rssi[0]; 6306 6307 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "crdc: avg: %02d %02d ", 6308 avg_rssi[0], avg_rssi[1]); 6309 6310 if ((avg_rssi[0] < crdc_rssi_thresh) && 6311 (avg_rssi[1] < crdc_rssi_thresh)) { 6312 ar9300_crdc_activate(ah, 0, 0); 6313 } else { 6314 if (ABS(avg_rssi_diff) >= crdc_diff_thresh) { 6315 ar9300_crdc_activate(ah, avg_rssi_diff, 1); 6316 } else { 6317 ar9300_crdc_activate(ah, 0, 1); 6318 } 6319 } 6320 } 6321 #endif 6322 6323 #if ATH_ANT_DIV_COMB 6324 HAL_BOOL 6325 ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal *ah, HAL_BOOL enable, const struct ieee80211_channel *chan) 6326 { 6327 u_int32_t value; 6328 u_int32_t regval; 6329 struct ath_hal_9300 *ahp = AH9300(ah); 6330 HAL_CHANNEL_INTERNAL *ichan; 6331 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6332 HAL_CAPABILITIES *pcap = &ahpriv->ah_caps; 6333 6334 if (AR_SREV_POSEIDON(ah)) { 6335 // Make sure this scheme is only used for WB225(Astra) 6336 ahp->ah_lna_div_use_bt_ant_enable = enable; 6337 6338 ichan = ar9300_check_chan(ah, chan); 6339 if ( ichan == AH_NULL ) { 6340 HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel %u/0x%x; no mapping\n", 6341 __func__, chan->ic_freq, chan->ic_flags); 6342 return AH_FALSE; 6343 } 6344 6345 if ( enable == TRUE ) { 6346 pcap->halAntDivCombSupport = TRUE; 6347 } else { 6348 pcap->halAntDivCombSupport = pcap->halAntDivCombSupportOrg; 6349 } 6350 6351 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff) 6352 #define AR_SWITCH_TABLE_COM2_ALL_S (0) 6353 value = ar9300_ant_ctrl_common2_get(ah, IS_CHAN_2GHZ(ichan)); 6354 if ( enable == TRUE ) { 6355 value &= ~AR_SWITCH_TABLE_COM2_ALL; 6356 value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable; 6357 } 6358 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, value); 6359 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); 6360 6361 value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control); 6362 /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */ 6363 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 6364 regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */ 6365 regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S; 6366 /* enable_lnadiv */ 6367 regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK); 6368 regval |= ((value >> 6) & 0x1) << 6369 MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT; 6370 if ( enable == TRUE ) { 6371 regval |= ANT_DIV_ENABLE; 6372 } 6373 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 6374 6375 /* enable fast_div */ 6376 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT); 6377 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK); 6378 regval |= ((value >> 7) & 0x1) << 6379 BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT; 6380 if ( enable == TRUE ) { 6381 regval |= FAST_DIV_ENABLE; 6382 } 6383 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); 6384 6385 if ( AR_SREV_POSEIDON_11_OR_LATER(ah) ) { 6386 if (pcap->halAntDivCombSupport) { 6387 /* If support DivComb, set MAIN to LNA1 and ALT to LNA2 at the first beginning */ 6388 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 6389 /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */ 6390 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK | 6391 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK | 6392 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK | 6393 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK)); 6394 regval |= (HAL_ANT_DIV_COMB_LNA1 << 6395 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 6396 regval |= (HAL_ANT_DIV_COMB_LNA2 << 6397 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 6398 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 6399 } 6400 } 6401 6402 return AH_TRUE; 6403 } else { 6404 return AH_TRUE; 6405 } 6406 6407 /* XXX TODO: Add AR9565 support? */ 6408 } 6409 #endif /* ATH_ANT_DIV_COMB */ 6410