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) || AR_SREV_HONEYBEE(ah)) { 292 chainmask = 0x03; 293 } else { 294 chainmask = 0x07; 295 } 296 297 for (chan = 0; chan < 2 /*ctl,ext*/; chan++) { 298 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { 299 int i; 300 301 if (!((chainmask >> chain) & 0x1)) { 302 continue; 303 } 304 i = chan * AR9300_MAX_CHAINS + chain; 305 nf = (OS_REG_READ(ah, regs[i]) & masks[chan]) >> shifts[chan]; 306 nfarray[i] = AH_NF_SIGN_EXTEND(nf); 307 } 308 } 309 } 310 311 /* ar9300_get_min_cca_pwr - 312 * Used by the scan function for a quick read of the noise floor. 313 * This is used to detect presence of CW interference such as video bridge. 314 * The noise floor is assumed to have been already started during reset 315 * called during channel change. The function checks if the noise floor 316 * reading is done. In case it has been done, it reads the noise floor value. 317 * If the noise floor calibration has not been finished, it assumes this is 318 * due to presence of CW interference an returns a high value for noise floor, 319 * derived from the CW interference threshold + margin fudge factor. 320 */ 321 #define BAD_SCAN_NF_MARGIN (30) 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) || AR_SREV_HONEYBEE(ah)) { 1480 #define SRIF_PLL 1 1481 u_int32_t regdata, pll2_divint, pll2_divfrac; 1482 1483 #ifndef SRIF_PLL 1484 u_int32_t pll2_clkmode; 1485 #endif 1486 1487 #ifdef SRIF_PLL 1488 u_int32_t refdiv; 1489 #endif 1490 if (clk_25mhz) { 1491 #ifndef SRIF_PLL 1492 pll2_divint = 0x1c; 1493 pll2_divfrac = 0xa3d7; 1494 #else 1495 if (AR_SREV_HONEYBEE(ah)) { 1496 pll2_divint = 0x1c; 1497 pll2_divfrac = 0xa3d2; 1498 refdiv = 1; 1499 } else { 1500 pll2_divint = 0x54; 1501 pll2_divfrac = 0x1eb85; 1502 refdiv = 3; 1503 } 1504 #endif 1505 } else { 1506 #ifndef SRIF_PLL 1507 pll2_divint = 0x11; 1508 pll2_divfrac = 0x26666; 1509 #else 1510 if (AR_SREV_WASP(ah)) { 1511 pll2_divint = 88; 1512 pll2_divfrac = 0; 1513 refdiv = 5; 1514 } else { 1515 pll2_divint = 0x11; 1516 pll2_divfrac = 0x26666; 1517 refdiv = 1; 1518 } 1519 #endif 1520 } 1521 #ifndef SRIF_PLL 1522 pll2_clkmode = 0x3d; 1523 #endif 1524 /* PLL programming through SRIF Local Mode */ 1525 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); /* Bypass mode */ 1526 OS_DELAY(1000); 1527 do { 1528 regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE); 1529 if (AR_SREV_HONEYBEE(ah)) { 1530 regdata = regdata | (0x1 << 22); 1531 } else { 1532 regdata = regdata | (0x1 << 16); 1533 } 1534 OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata); /* PWD_PLL set to 1 */ 1535 OS_DELAY(100); 1536 /* override int, frac, refdiv */ 1537 #ifndef SRIF_PLL 1538 OS_REG_WRITE(ah, AR_PHY_PLL_CONTROL, 1539 ((1 << 27) | (pll2_divint << 18) | pll2_divfrac)); 1540 #else 1541 OS_REG_WRITE(ah, AR_PHY_PLL_CONTROL, 1542 ((refdiv << 27) | (pll2_divint << 18) | pll2_divfrac)); 1543 #endif 1544 OS_DELAY(100); 1545 regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE); 1546 #ifndef SRIF_PLL 1547 regdata = (regdata & 0x80071fff) | 1548 (0x1 << 30) | (0x1 << 13) | (0x6 << 26) | (pll2_clkmode << 19); 1549 #else 1550 if (AR_SREV_WASP(ah)) { 1551 regdata = (regdata & 0x80071fff) | 1552 (0x1 << 30) | (0x1 << 13) | (0x4 << 26) | (0x18 << 19); 1553 } else if (AR_SREV_HONEYBEE(ah)) { 1554 /* 1555 * Kd=10, Ki=2, Outdiv=1, Local PLL=0, Phase Shift=4 1556 */ 1557 regdata = (regdata & 0x01c00fff) | 1558 (0x1 << 31) | (0x2 << 29) | (0xa << 25) | (0x1 << 19) | (0x6 << 12); 1559 } else { 1560 regdata = (regdata & 0x80071fff) | 1561 (0x3 << 30) | (0x1 << 13) | (0x4 << 26) | (0x60 << 19); 1562 } 1563 #endif 1564 /* Ki, Kd, Local PLL, Outdiv */ 1565 OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata); 1566 regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE); 1567 if (AR_SREV_HONEYBEE(ah)) { 1568 regdata = (regdata & 0xffbfffff); 1569 } else { 1570 regdata = (regdata & 0xfffeffff); 1571 } 1572 OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata); /* PWD_PLL set to 0 */ 1573 OS_DELAY(1000); 1574 if (AR_SREV_WASP(ah)) { 1575 /* clear do measure */ 1576 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3); 1577 regdata &= ~(1 << 30); 1578 OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata); 1579 OS_DELAY(100); 1580 1581 /* set do measure */ 1582 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3); 1583 regdata |= (1 << 30); 1584 OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata); 1585 1586 /* wait for measure done */ 1587 do { 1588 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL4); 1589 } while ((regdata & (1 << 3)) == 0); 1590 1591 /* clear do measure */ 1592 regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3); 1593 regdata &= ~(1 << 30); 1594 OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata); 1595 1596 /* get measure sqsum dvc */ 1597 regdata = (OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3) & 0x007FFFF8) >> 3; 1598 } else { 1599 break; 1600 } 1601 } while (regdata >= 0x40000); 1602 1603 /* Remove from Bypass mode */ 1604 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c); 1605 OS_DELAY(1000); 1606 } else { 1607 pll = SM(0x5, AR_RTC_PLL_REFDIV); 1608 1609 /* Supposedly not needed on Osprey */ 1610 #if 0 1611 if (chan && IS_CHAN_HALF_RATE(chan)) { 1612 pll |= SM(0x1, AR_RTC_PLL_CLKSEL); 1613 } else if (chan && IS_CHAN_QUARTER_RATE(chan)) { 1614 pll |= SM(0x2, AR_RTC_PLL_CLKSEL); 1615 } 1616 #endif 1617 if (ichan && IS_CHAN_5GHZ(ichan)) { 1618 pll |= SM(0x28, AR_RTC_PLL_DIV); 1619 /* 1620 * When doing fast clock, set PLL to 0x142c 1621 */ 1622 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 1623 pll = 0x142c; 1624 } 1625 } else { 1626 pll |= SM(0x2c, AR_RTC_PLL_DIV); 1627 } 1628 1629 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); 1630 } 1631 1632 /* TODO: 1633 * For multi-band owl, switch between bands by reiniting the PLL. 1634 */ 1635 OS_DELAY(RTC_PLL_SETTLE_DELAY); 1636 1637 OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, 1638 AR_RTC_FORCE_DERIVED_CLK | AR_RTC_PCIE_RST_PWDN_EN); 1639 1640 /* XXX TODO: honeybee? */ 1641 if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) { 1642 if (clk_25mhz) { 1643 OS_REG_WRITE(ah, 1644 AR_RTC_DERIVED_RTC_CLK, (0x17c << 1)); /* 32KHz sleep clk */ 1645 OS_REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7); 1646 OS_REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae); 1647 } else { 1648 OS_REG_WRITE(ah, 1649 AR_RTC_DERIVED_RTC_CLK, (0x261 << 1)); /* 32KHz sleep clk */ 1650 OS_REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400); 1651 OS_REG_WRITE(ah, AR_SLP32_INC, 0x0001e800); 1652 } 1653 OS_DELAY(100); 1654 } 1655 } 1656 1657 static inline HAL_BOOL 1658 ar9300_set_reset(struct ath_hal *ah, int type) 1659 { 1660 u_int32_t rst_flags; 1661 u_int32_t tmp_reg; 1662 struct ath_hal_9300 *ahp = AH9300(ah); 1663 1664 HALASSERT(type == HAL_RESET_WARM || type == HAL_RESET_COLD); 1665 1666 /* 1667 * RTC Force wake should be done before resetting the MAC. 1668 * MDK/ART does it that way. 1669 */ 1670 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val); 1671 OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */ 1672 OS_REG_WRITE(ah, 1673 AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1674 1675 /* Reset AHB */ 1676 /* Bug26871 */ 1677 tmp_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)); 1678 if (AR_SREV_WASP(ah)) { 1679 if (tmp_reg & (AR9340_INTR_SYNC_LOCAL_TIMEOUT)) { 1680 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0); 1681 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF); 1682 } 1683 } else { 1684 if (tmp_reg & (AR9300_INTR_SYNC_LOCAL_TIMEOUT | AR9300_INTR_SYNC_RADM_CPL_TIMEOUT)) { 1685 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0); 1686 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF); 1687 } 1688 else { 1689 /* NO AR_RC_AHB in Osprey */ 1690 /*OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_AHB);*/ 1691 } 1692 } 1693 1694 rst_flags = AR_RTC_RC_MAC_WARM; 1695 if (type == HAL_RESET_COLD) { 1696 rst_flags |= AR_RTC_RC_MAC_COLD; 1697 } 1698 1699 #ifdef AH_SUPPORT_HORNET 1700 /* Hornet WAR: trigger SoC to reset WMAC if ... 1701 * (1) doing cold reset. Ref: EV 69254 1702 * (2) beacon pending. Ref: EV 70983 1703 */ 1704 if (AR_SREV_HORNET(ah) && 1705 (ar9300_num_tx_pending( 1706 ah, AH_PRIVATE(ah)->ah_caps.halTotalQueues - 1) != 0 || 1707 type == HAL_RESET_COLD)) 1708 { 1709 u_int32_t time_out; 1710 #define AR_SOC_RST_RESET 0xB806001C 1711 #define AR_SOC_BOOT_STRAP 0xB80600AC 1712 #define AR_SOC_WLAN_RST 0x00000800 /* WLAN reset */ 1713 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val); 1714 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg)) 1715 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Hornet SoC reset WMAC.\n", __func__); 1716 1717 REG_WRITE(AR_SOC_RST_RESET, 1718 REG_READ(AR_SOC_RST_RESET) | AR_SOC_WLAN_RST); 1719 REG_WRITE(AR_SOC_RST_RESET, 1720 REG_READ(AR_SOC_RST_RESET) & (~AR_SOC_WLAN_RST)); 1721 1722 time_out = 0; 1723 1724 while (1) { 1725 tmp_reg = REG_READ(AR_SOC_BOOT_STRAP); 1726 if ((tmp_reg & 0x10) == 0) { 1727 break; 1728 } 1729 if (time_out > 20) { 1730 break; 1731 } 1732 OS_DELAY(10000); 1733 time_out++; 1734 } 1735 1736 OS_REG_WRITE(ah, AR_RTC_RESET, 1); 1737 #undef REG_READ 1738 #undef REG_WRITE 1739 #undef AR_SOC_WLAN_RST 1740 #undef AR_SOC_RST_RESET 1741 #undef AR_SOC_BOOT_STRAP 1742 } 1743 #endif /* AH_SUPPORT_HORNET */ 1744 1745 #ifdef AH_SUPPORT_SCORPION 1746 if (AR_SREV_SCORPION(ah)) { 1747 #define DDR_CTL_CONFIG_ADDRESS 0xb8000000 1748 #define DDR_CTL_CONFIG_OFFSET 0x0108 1749 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_MSB 29 1750 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB 21 1751 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK 0x3fe00000 1752 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_GET(x) (((x) & DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK) >> DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB) 1753 #define DDR_CTL_CONFIG_CLIENT_ACTIVITY_SET(x) (((x) << DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB) & DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK) 1754 #define MAC_DMA_CFG_ADDRESS 0xb8100000 1755 #define MAC_DMA_CFG_OFFSET 0x0014 1756 1757 #define MAC_DMA_CFG_HALT_REQ_MSB 11 1758 #define MAC_DMA_CFG_HALT_REQ_LSB 11 1759 #define MAC_DMA_CFG_HALT_REQ_MASK 0x00000800 1760 #define MAC_DMA_CFG_HALT_REQ_GET(x) (((x) & MAC_DMA_CFG_HALT_REQ_MASK) >> MAC_DMA_CFG_HALT_REQ_LSB) 1761 #define MAC_DMA_CFG_HALT_REQ_SET(x) (((x) << MAC_DMA_CFG_HALT_REQ_LSB) & MAC_DMA_CFG_HALT_REQ_MASK) 1762 #define MAC_DMA_CFG_HALT_ACK_MSB 12 1763 #define MAC_DMA_CFG_HALT_ACK_LSB 12 1764 #define MAC_DMA_CFG_HALT_ACK_MASK 0x00001000 1765 #define MAC_DMA_CFG_HALT_ACK_GET(x) (((x) & MAC_DMA_CFG_HALT_ACK_MASK) >> MAC_DMA_CFG_HALT_ACK_LSB) 1766 #define MAC_DMA_CFG_HALT_ACK_SET(x) (((x) << MAC_DMA_CFG_HALT_ACK_LSB) & MAC_DMA_CFG_HALT_ACK_MASK) 1767 1768 #define RST_RESET 0xB806001c 1769 #define RTC_RESET (1<<27) 1770 1771 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg)) 1772 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val); 1773 1774 #define DDR_REG_READ(_ah, _reg) \ 1775 *((volatile u_int32_t *)( DDR_CTL_CONFIG_ADDRESS + (_reg))) 1776 #define DDR_REG_WRITE(_ah, _reg, _val) \ 1777 *((volatile u_int32_t *)(DDR_CTL_CONFIG_ADDRESS + (_reg))) = (_val) 1778 1779 OS_REG_WRITE(ah,MAC_DMA_CFG_OFFSET, (OS_REG_READ(ah,MAC_DMA_CFG_OFFSET) & ~MAC_DMA_CFG_HALT_REQ_MASK) | 1780 MAC_DMA_CFG_HALT_REQ_SET(1)); 1781 1782 { 1783 int count; 1784 u_int32_t data; 1785 1786 count = 0; 1787 while (!MAC_DMA_CFG_HALT_ACK_GET(OS_REG_READ(ah, MAC_DMA_CFG_OFFSET) )) 1788 { 1789 count++; 1790 if (count > 10) { 1791 ath_hal_printf(ah, "Halt ACK timeout\n"); 1792 break; 1793 } 1794 OS_DELAY(10); 1795 } 1796 1797 data = DDR_REG_READ(ah,DDR_CTL_CONFIG_OFFSET); 1798 HALDEBUG(ah, HAL_DEBUG_RESET, "check DDR Activity - HIGH\n"); 1799 1800 count = 0; 1801 while (DDR_CTL_CONFIG_CLIENT_ACTIVITY_GET(data)) { 1802 // AVE_DEBUG(0,"DDR Activity - HIGH\n"); 1803 HALDEBUG(ah, HAL_DEBUG_RESET, "DDR Activity - HIGH\n"); 1804 count++; 1805 OS_DELAY(10); 1806 data = DDR_REG_READ(ah,DDR_CTL_CONFIG_OFFSET); 1807 if (count > 10) { 1808 ath_hal_printf(ah, "DDR Activity timeout\n"); 1809 break; 1810 } 1811 } 1812 } 1813 1814 1815 { 1816 //Force RTC reset 1817 REG_WRITE(RST_RESET, (REG_READ(RST_RESET) | RTC_RESET)); 1818 OS_DELAY(10); 1819 REG_WRITE(RST_RESET, (REG_READ(RST_RESET) & ~RTC_RESET)); 1820 OS_DELAY(10); 1821 OS_REG_WRITE(ah, AR_RTC_RESET, 0); 1822 OS_DELAY(10); 1823 OS_REG_WRITE(ah, AR_RTC_RESET, 1); 1824 OS_DELAY(10); 1825 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Scorpion SoC RTC reset done.\n", __func__); 1826 } 1827 #undef REG_READ 1828 #undef REG_WRITE 1829 } 1830 #endif /* AH_SUPPORT_SCORPION */ 1831 1832 /* 1833 * Set Mac(BB,Phy) Warm Reset 1834 */ 1835 OS_REG_WRITE(ah, AR_RTC_RC, rst_flags); 1836 1837 OS_DELAY(50); /* XXX 50 usec */ 1838 1839 /* 1840 * Clear resets and force wakeup 1841 */ 1842 OS_REG_WRITE(ah, AR_RTC_RC, 0); 1843 if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) { 1844 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 1845 "%s: RTC stuck in MAC reset\n", __FUNCTION__); 1846 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 1847 "%s: AR_RTC_RC = 0x%x\n", __func__, OS_REG_READ(ah, AR_RTC_RC)); 1848 return AH_FALSE; 1849 } 1850 1851 /* Clear AHB reset */ 1852 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), 0); 1853 1854 ar9300_attach_hw_platform(ah); 1855 1856 ahp->ah_chip_reset_done = 1; 1857 return AH_TRUE; 1858 } 1859 1860 static inline HAL_BOOL 1861 ar9300_set_reset_power_on(struct ath_hal *ah) 1862 { 1863 /* Force wake */ 1864 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val); 1865 OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */ 1866 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1867 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1868 /* 1869 * RTC reset and clear. Some delay in between is needed 1870 * to give the chip time to settle. 1871 */ 1872 OS_REG_WRITE(ah, AR_RTC_RESET, 0); 1873 OS_DELAY(2); 1874 OS_REG_WRITE(ah, AR_RTC_RESET, 1); 1875 1876 /* 1877 * Poll till RTC is ON 1878 */ 1879 if (!ath_hal_wait(ah, 1880 AR_RTC_STATUS, AR_RTC_STATUS_M, 1881 AR_RTC_STATUS_ON)) 1882 { 1883 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 1884 "%s: RTC not waking up for %d\n", __FUNCTION__, 1000); 1885 return AH_FALSE; 1886 } 1887 1888 /* 1889 * Read Revisions from Chip right after RTC is on for the first time. 1890 * This helps us detect the chip type early and initialize it accordingly. 1891 */ 1892 ar9300_read_revisions(ah); 1893 1894 /* 1895 * Warm reset if we aren't really powering on, 1896 * just restarting the driver. 1897 */ 1898 return ar9300_set_reset(ah, HAL_RESET_WARM); 1899 } 1900 1901 /* 1902 * Write the given reset bit mask into the reset register 1903 */ 1904 HAL_BOOL 1905 ar9300_set_reset_reg(struct ath_hal *ah, u_int32_t type) 1906 { 1907 HAL_BOOL ret = AH_FALSE; 1908 1909 /* 1910 * Set force wake 1911 */ 1912 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val); 1913 OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */ 1914 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1915 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1916 1917 switch (type) { 1918 case HAL_RESET_POWER_ON: 1919 ret = ar9300_set_reset_power_on(ah); 1920 break; 1921 case HAL_RESET_WARM: 1922 case HAL_RESET_COLD: 1923 ret = ar9300_set_reset(ah, type); 1924 break; 1925 default: 1926 break; 1927 } 1928 1929 #if ATH_SUPPORT_MCI 1930 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) { 1931 OS_REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); 1932 } 1933 #endif 1934 1935 return ret; 1936 } 1937 1938 /* 1939 * Places the PHY and Radio chips into reset. A full reset 1940 * must be called to leave this state. The PCI/MAC/PCU are 1941 * not placed into reset as we must receive interrupt to 1942 * re-enable the hardware. 1943 */ 1944 HAL_BOOL 1945 ar9300_phy_disable(struct ath_hal *ah) 1946 { 1947 if (!ar9300_set_reset_reg(ah, HAL_RESET_WARM)) { 1948 return AH_FALSE; 1949 } 1950 1951 #ifdef ATH_SUPPORT_LED 1952 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg)) 1953 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val); 1954 #define ATH_GPIO_OE 0xB8040000 1955 #define ATH_GPIO_OUT 0xB8040008 /* GPIO Ouput Value reg.*/ 1956 if (AR_SREV_WASP(ah)) { 1957 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) { 1958 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 13))); 1959 } 1960 else { 1961 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12))); 1962 } 1963 } 1964 else if (AR_SREV_SCORPION(ah)) { 1965 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) { 1966 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 13))); 1967 } 1968 else { 1969 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12))); 1970 } 1971 /* Turn off JMPST led */ 1972 REG_WRITE(ATH_GPIO_OUT, (REG_READ(ATH_GPIO_OUT) | (0x1 << 15))); 1973 } 1974 else if (AR_SREV_HONEYBEE(ah)) { 1975 REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12))); 1976 } 1977 #undef REG_READ 1978 #undef REG_WRITE 1979 #endif 1980 1981 if ( AR_SREV_OSPREY(ah) ) { 1982 OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1), 0x0, 0x1f); 1983 } 1984 1985 1986 ar9300_init_pll(ah, AH_NULL); 1987 1988 return AH_TRUE; 1989 } 1990 1991 /* 1992 * Places all of hardware into reset 1993 */ 1994 HAL_BOOL 1995 ar9300_disable(struct ath_hal *ah) 1996 { 1997 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) { 1998 return AH_FALSE; 1999 } 2000 if (!ar9300_set_reset_reg(ah, HAL_RESET_COLD)) { 2001 return AH_FALSE; 2002 } 2003 2004 ar9300_init_pll(ah, AH_NULL); 2005 2006 return AH_TRUE; 2007 } 2008 2009 /* 2010 * TODO: Only write the PLL if we're changing to or from CCK mode 2011 * 2012 * WARNING: The order of the PLL and mode registers must be correct. 2013 */ 2014 static inline void 2015 ar9300_set_rf_mode(struct ath_hal *ah, struct ieee80211_channel *chan) 2016 { 2017 u_int32_t rf_mode = 0; 2018 2019 if (chan == AH_NULL) { 2020 return; 2021 } 2022 switch (AH9300(ah)->ah_hwp) { 2023 case HAL_TRUE_CHIP: 2024 rf_mode |= (IEEE80211_IS_CHAN_B(chan) || IEEE80211_IS_CHAN_G(chan)) ? 2025 AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; 2026 break; 2027 default: 2028 HALASSERT(0); 2029 break; 2030 } 2031 /* Phy mode bits for 5GHz channels requiring Fast Clock */ 2032 if ( IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 2033 rf_mode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); 2034 } 2035 OS_REG_WRITE(ah, AR_PHY_MODE, rf_mode); 2036 } 2037 2038 /* 2039 * Places the hardware into reset and then pulls it out of reset 2040 */ 2041 HAL_BOOL 2042 ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *chan) 2043 { 2044 struct ath_hal_9300 *ahp = AH9300(ah); 2045 int type = HAL_RESET_WARM; 2046 2047 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0); 2048 2049 /* 2050 * Warm reset is optimistic. 2051 * 2052 * If the TX/RX DMA engines aren't shut down (eg, they're 2053 * wedged) then we're better off doing a full cold reset 2054 * to try and shake that condition. 2055 */ 2056 if (ahp->ah_chip_full_sleep || 2057 (ah->ah_config.ah_force_full_reset == 1) || 2058 OS_REG_READ(ah, AR_Q_TXE) || 2059 (OS_REG_READ(ah, AR_CR) & AR_CR_RXE)) { 2060 type = HAL_RESET_COLD; 2061 } 2062 2063 if (!ar9300_set_reset_reg(ah, type)) { 2064 return AH_FALSE; 2065 } 2066 2067 /* Bring out of sleep mode (AGAIN) */ 2068 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) { 2069 return AH_FALSE; 2070 } 2071 2072 ahp->ah_chip_full_sleep = AH_FALSE; 2073 2074 if (AR_SREV_HORNET(ah)) { 2075 ar9300_internal_regulator_apply(ah); 2076 } 2077 2078 ar9300_init_pll(ah, chan); 2079 2080 /* 2081 * Perform warm reset before the mode/PLL/turbo registers 2082 * are changed in order to deactivate the radio. Mode changes 2083 * with an active radio can result in corrupted shifts to the 2084 * radio device. 2085 */ 2086 ar9300_set_rf_mode(ah, chan); 2087 2088 return AH_TRUE; 2089 } 2090 2091 /* ar9300_setup_calibration 2092 * Setup HW to collect samples used for current cal 2093 */ 2094 inline static void 2095 ar9300_setup_calibration(struct ath_hal *ah, HAL_CAL_LIST *curr_cal) 2096 { 2097 /* Select calibration to run */ 2098 switch (curr_cal->cal_data->cal_type) { 2099 case IQ_MISMATCH_CAL: 2100 /* Start calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */ 2101 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, 2102 AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX, 2103 curr_cal->cal_data->cal_count_max); 2104 OS_REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); 2105 2106 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2107 "%s: starting IQ Mismatch Calibration\n", __func__); 2108 2109 /* Kick-off cal */ 2110 OS_REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL); 2111 2112 break; 2113 case TEMP_COMP_CAL: 2114 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || 2115 AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) { 2116 OS_REG_RMW_FIELD(ah, 2117 AR_HORNET_CH0_THERM, AR_PHY_65NM_CH0_THERM_LOCAL, 1); 2118 OS_REG_RMW_FIELD(ah, 2119 AR_HORNET_CH0_THERM, AR_PHY_65NM_CH0_THERM_START, 1); 2120 } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 2121 OS_REG_RMW_FIELD(ah, 2122 AR_PHY_65NM_CH0_THERM_JUPITER, AR_PHY_65NM_CH0_THERM_LOCAL, 1); 2123 OS_REG_RMW_FIELD(ah, 2124 AR_PHY_65NM_CH0_THERM_JUPITER, AR_PHY_65NM_CH0_THERM_START, 1); 2125 } else { 2126 OS_REG_RMW_FIELD(ah, 2127 AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_LOCAL, 1); 2128 OS_REG_RMW_FIELD(ah, 2129 AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_START, 1); 2130 } 2131 2132 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2133 "%s: starting Temperature Compensation Calibration\n", __func__); 2134 break; 2135 default: 2136 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 2137 "%s called with incorrect calibration type.\n", __func__); 2138 } 2139 } 2140 2141 /* ar9300_reset_calibration 2142 * Initialize shared data structures and prepare a cal to be run. 2143 */ 2144 inline static void 2145 ar9300_reset_calibration(struct ath_hal *ah, HAL_CAL_LIST *curr_cal) 2146 { 2147 struct ath_hal_9300 *ahp = AH9300(ah); 2148 int i; 2149 2150 /* Setup HW for new calibration */ 2151 ar9300_setup_calibration(ah, curr_cal); 2152 2153 /* Change SW state to RUNNING for this calibration */ 2154 curr_cal->cal_state = CAL_RUNNING; 2155 2156 /* Reset data structures shared between different calibrations */ 2157 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 2158 ahp->ah_meas0.sign[i] = 0; 2159 ahp->ah_meas1.sign[i] = 0; 2160 ahp->ah_meas2.sign[i] = 0; 2161 ahp->ah_meas3.sign[i] = 0; 2162 } 2163 2164 ahp->ah_cal_samples = 0; 2165 } 2166 2167 #ifdef XXX_UNUSED_FUNCTION 2168 /* 2169 * Find out which of the RX chains are enabled 2170 */ 2171 static u_int32_t 2172 ar9300_get_rx_chain_mask(struct ath_hal *ah) 2173 { 2174 u_int32_t ret_val = OS_REG_READ(ah, AR_PHY_RX_CHAINMASK); 2175 /* The bits [2:0] indicate the rx chain mask and are to be 2176 * interpreted as follows: 2177 * 00x => Only chain 0 is enabled 2178 * 01x => Chain 1 and 0 enabled 2179 * 1xx => Chain 2,1 and 0 enabled 2180 */ 2181 return (ret_val & 0x7); 2182 } 2183 #endif 2184 2185 static void 2186 ar9300_get_nf_hist_base(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, 2187 int is_scan, int16_t nf[]) 2188 { 2189 HAL_NFCAL_BASE *h_base; 2190 2191 #ifdef ATH_NF_PER_CHAN 2192 h_base = &chan->nf_cal_hist.base; 2193 #else 2194 if (is_scan) { 2195 /* 2196 * The channel we are currently on is not the home channel, 2197 * so we shouldn't use the home channel NF buffer's values on 2198 * this channel. Instead, use the NF single value already 2199 * read for this channel. (Or, if we haven't read the NF for 2200 * this channel yet, the SW default for this chip/band will 2201 * be used.) 2202 */ 2203 h_base = &chan->nf_cal_hist.base; 2204 } else { 2205 /* use the home channel NF info */ 2206 h_base = &AH_PRIVATE(ah)->nf_cal_hist.base; 2207 } 2208 #endif 2209 OS_MEMCPY(nf, h_base->priv_nf, sizeof(h_base->priv_nf)); 2210 } 2211 2212 HAL_BOOL 2213 ar9300_load_nf(struct ath_hal *ah, int16_t nf[]) 2214 { 2215 int i, j; 2216 int32_t val; 2217 /* XXX where are EXT regs defined */ 2218 const u_int32_t ar9300_cca_regs[] = { 2219 AR_PHY_CCA_0, 2220 AR_PHY_CCA_1, 2221 AR_PHY_CCA_2, 2222 AR_PHY_EXT_CCA, 2223 AR_PHY_EXT_CCA_1, 2224 AR_PHY_EXT_CCA_2, 2225 }; 2226 u_int8_t chainmask; 2227 2228 /* 2229 * Force NF calibration for all chains, otherwise Vista station 2230 * would conduct a bad performance 2231 */ 2232 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) { 2233 chainmask = 0x9; 2234 } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_HONEYBEE(ah)) { 2235 chainmask = 0x1b; 2236 } else { 2237 chainmask = 0x3F; 2238 } 2239 2240 /* 2241 * Write filtered NF values into max_cca_pwr register parameter 2242 * so we can load below. 2243 */ 2244 for (i = 0; i < HAL_NUM_NF_READINGS; i++) { 2245 if (chainmask & (1 << i)) { 2246 val = OS_REG_READ(ah, ar9300_cca_regs[i]); 2247 val &= 0xFFFFFE00; 2248 val |= (((u_int32_t)(nf[i]) << 1) & 0x1ff); 2249 OS_REG_WRITE(ah, ar9300_cca_regs[i], val); 2250 } 2251 } 2252 2253 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%s: load %d %d %d %d %d %d\n", 2254 __func__, 2255 nf[0], nf[1], nf[2], 2256 nf[3], nf[4], nf[5]); 2257 2258 /* 2259 * Load software filtered NF value into baseband internal min_cca_pwr 2260 * variable. 2261 */ 2262 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF); 2263 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF); 2264 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); 2265 2266 /* Wait for load to complete, should be fast, a few 10s of us. */ 2267 /* Changed the max delay 250us back to 10000us, since 250us often 2268 * results in NF load timeout and causes deaf condition 2269 * during stress testing 12/12/2009 2270 */ 2271 for (j = 0; j < 10000; j++) { 2272 if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){ 2273 break; 2274 } 2275 OS_DELAY(10); 2276 } 2277 if (j == 10000) { 2278 /* 2279 * We timed out waiting for the noisefloor to load, probably 2280 * due to an in-progress rx. Simply return here and allow 2281 * the load plenty of time to complete before the next 2282 * calibration interval. We need to avoid trying to load -50 2283 * (which happens below) while the previous load is still in 2284 * progress as this can cause rx deafness (see EV 66368,62830). 2285 * Instead by returning here, the baseband nf cal will 2286 * just be capped by our present noisefloor until the next 2287 * calibration timer. 2288 */ 2289 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, 2290 "%s: *** TIMEOUT while waiting for nf to load: " 2291 "AR_PHY_AGC_CONTROL=0x%x ***\n", 2292 __func__, OS_REG_READ(ah, AR_PHY_AGC_CONTROL)); 2293 return AH_FALSE; 2294 } 2295 2296 /* 2297 * Restore max_cca_power register parameter again so that we're not capped 2298 * by the median we just loaded. This will be initial (and max) value 2299 * of next noise floor calibration the baseband does. 2300 */ 2301 for (i = 0; i < HAL_NUM_NF_READINGS; i++) { 2302 if (chainmask & (1 << i)) { 2303 val = OS_REG_READ(ah, ar9300_cca_regs[i]); 2304 val &= 0xFFFFFE00; 2305 val |= (((u_int32_t)(-50) << 1) & 0x1ff); 2306 OS_REG_WRITE(ah, ar9300_cca_regs[i], val); 2307 } 2308 } 2309 return AH_TRUE; 2310 } 2311 2312 /* ar9300_per_calibration 2313 * Generic calibration routine. 2314 * Recalibrate the lower PHY chips to account for temperature/environment 2315 * changes. 2316 */ 2317 inline static void 2318 ar9300_per_calibration(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan, 2319 u_int8_t rxchainmask, HAL_CAL_LIST *curr_cal, HAL_BOOL *is_cal_done) 2320 { 2321 struct ath_hal_9300 *ahp = AH9300(ah); 2322 2323 /* Cal is assumed not done until explicitly set below */ 2324 *is_cal_done = AH_FALSE; 2325 2326 /* Calibration in progress. */ 2327 if (curr_cal->cal_state == CAL_RUNNING) { 2328 /* Check to see if it has finished. */ 2329 if (!(OS_REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) { 2330 int i, num_chains = 0; 2331 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 2332 if (rxchainmask & (1 << i)) { 2333 num_chains++; 2334 } 2335 } 2336 2337 /* 2338 * Accumulate cal measures for active chains 2339 */ 2340 curr_cal->cal_data->cal_collect(ah, num_chains); 2341 2342 ahp->ah_cal_samples++; 2343 2344 if (ahp->ah_cal_samples >= curr_cal->cal_data->cal_num_samples) { 2345 /* 2346 * Process accumulated data 2347 */ 2348 curr_cal->cal_data->cal_post_proc(ah, num_chains); 2349 2350 /* Calibration has finished. */ 2351 ichan->calValid |= curr_cal->cal_data->cal_type; 2352 curr_cal->cal_state = CAL_DONE; 2353 *is_cal_done = AH_TRUE; 2354 } else { 2355 /* Set-up collection of another sub-sample until we 2356 * get desired number 2357 */ 2358 ar9300_setup_calibration(ah, curr_cal); 2359 } 2360 } 2361 } else if (!(ichan->calValid & curr_cal->cal_data->cal_type)) { 2362 /* If current cal is marked invalid in channel, kick it off */ 2363 ar9300_reset_calibration(ah, curr_cal); 2364 } 2365 } 2366 2367 static void 2368 ar9300_start_nf_cal(struct ath_hal *ah) 2369 { 2370 struct ath_hal_9300 *ahp = AH9300(ah); 2371 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF); 2372 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF); 2373 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); 2374 AH9300(ah)->nf_tsf32 = ar9300_get_tsf32(ah); 2375 2376 /* 2377 * We are reading the NF values before we start the NF operation, because 2378 * of that we are getting very high values like -45. 2379 * This triggers the CW_INT detected and EACS module triggers the channel change 2380 * chip_reset_done value is used to fix this issue. 2381 * chip_reset_flag is set during the RTC reset. 2382 * chip_reset_flag is cleared during the starting NF operation. 2383 * if flag is set we will clear the flag and will not read the NF values. 2384 */ 2385 ahp->ah_chip_reset_done = 0; 2386 } 2387 2388 /* ar9300_calibration 2389 * Wrapper for a more generic Calibration routine. Primarily to abstract to 2390 * upper layers whether there is 1 or more calibrations to be run. 2391 */ 2392 HAL_BOOL 2393 ar9300_calibration(struct ath_hal *ah, struct ieee80211_channel *chan, u_int8_t rxchainmask, 2394 HAL_BOOL do_nf_cal, HAL_BOOL *is_cal_done, int is_scan, 2395 u_int32_t *sched_cals) 2396 { 2397 struct ath_hal_9300 *ahp = AH9300(ah); 2398 HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr; 2399 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 2400 int16_t nf_buf[HAL_NUM_NF_READINGS]; 2401 2402 *is_cal_done = AH_TRUE; 2403 2404 2405 /* XXX: For initial wasp bringup - disable periodic calibration */ 2406 /* Invalid channel check */ 2407 if (ichan == AH_NULL) { 2408 HALDEBUG(ah, HAL_DEBUG_CHANNEL, 2409 "%s: invalid channel %u/0x%x; no mapping\n", 2410 __func__, chan->ic_freq, chan->ic_flags); 2411 return AH_FALSE; 2412 } 2413 2414 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2415 "%s: Entering, Doing NF Cal = %d\n", __func__, do_nf_cal); 2416 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Chain 0 Rx IQ Cal Correction 0x%08x\n", 2417 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0)); 2418 if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah) && !AR_SREV_APHRODITE(ah)) { 2419 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2420 "%s: Chain 1 Rx IQ Cal Correction 0x%08x\n", 2421 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B1)); 2422 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah) && !AR_SREV_HONEYBEE(ah)) { 2423 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2424 "%s: Chain 2 Rx IQ Cal Correction 0x%08x\n", 2425 __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B2)); 2426 } 2427 } 2428 2429 OS_MARK(ah, AH_MARK_PERCAL, chan->ic_freq); 2430 2431 /* For given calibration: 2432 * 1. Call generic cal routine 2433 * 2. When this cal is done (is_cal_done) if we have more cals waiting 2434 * (eg after reset), mask this to upper layers by not propagating 2435 * is_cal_done if it is set to TRUE. 2436 * Instead, change is_cal_done to FALSE and setup the waiting cal(s) 2437 * to be run. 2438 */ 2439 if (curr_cal && (curr_cal->cal_data->cal_type & *sched_cals) && 2440 (curr_cal->cal_state == CAL_RUNNING || 2441 curr_cal->cal_state == CAL_WAITING)) 2442 { 2443 ar9300_per_calibration(ah, ichan, rxchainmask, curr_cal, is_cal_done); 2444 2445 if (*is_cal_done == AH_TRUE) { 2446 ahp->ah_cal_list_curr = curr_cal = curr_cal->cal_next; 2447 2448 if (curr_cal && curr_cal->cal_state == CAL_WAITING) { 2449 *is_cal_done = AH_FALSE; 2450 ar9300_reset_calibration(ah, curr_cal); 2451 } else { 2452 *sched_cals &= ~IQ_MISMATCH_CAL; 2453 } 2454 } 2455 } 2456 2457 /* Do NF cal only at longer intervals */ 2458 if (do_nf_cal) { 2459 int nf_done; 2460 2461 /* Get the value from the previous NF cal and update history buffer */ 2462 nf_done = ar9300_store_new_nf(ah, chan, is_scan); 2463 #if 0 2464 if (ichan->channel_flags & CHANNEL_CW_INT) { 2465 chan->channel_flags |= CHANNEL_CW_INT; 2466 } 2467 #endif 2468 chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT; 2469 2470 if (nf_done) { 2471 /* 2472 * Load the NF from history buffer of the current channel. 2473 * NF is slow time-variant, so it is OK to use a historical value. 2474 */ 2475 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf); 2476 ar9300_load_nf(ah, nf_buf); 2477 2478 /* start NF calibration, without updating BB NF register*/ 2479 ar9300_start_nf_cal(ah); 2480 } 2481 } 2482 return AH_TRUE; 2483 } 2484 2485 /* ar9300_iq_cal_collect 2486 * Collect data from HW to later perform IQ Mismatch Calibration 2487 */ 2488 void 2489 ar9300_iq_cal_collect(struct ath_hal *ah, u_int8_t num_chains) 2490 { 2491 struct ath_hal_9300 *ahp = AH9300(ah); 2492 int i; 2493 2494 /* 2495 * Accumulate IQ cal measures for active chains 2496 */ 2497 for (i = 0; i < num_chains; i++) { 2498 ahp->ah_total_power_meas_i[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); 2499 ahp->ah_total_power_meas_q[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); 2500 ahp->ah_total_iq_corr_meas[i] = 2501 (int32_t) OS_REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); 2502 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2503 "%d: Chn %d " 2504 "Reg Offset(0x%04x)pmi=0x%08x; " 2505 "Reg Offset(0x%04x)pmq=0x%08x; " 2506 "Reg Offset (0x%04x)iqcm=0x%08x;\n", 2507 ahp->ah_cal_samples, 2508 i, 2509 (unsigned) AR_PHY_CAL_MEAS_0(i), 2510 ahp->ah_total_power_meas_i[i], 2511 (unsigned) AR_PHY_CAL_MEAS_1(i), 2512 ahp->ah_total_power_meas_q[i], 2513 (unsigned) AR_PHY_CAL_MEAS_2(i), 2514 ahp->ah_total_iq_corr_meas[i]); 2515 } 2516 } 2517 2518 /* ar9300_iq_calibration 2519 * Use HW data to perform IQ Mismatch Calibration 2520 */ 2521 void 2522 ar9300_iq_calibration(struct ath_hal *ah, u_int8_t num_chains) 2523 { 2524 struct ath_hal_9300 *ahp = AH9300(ah); 2525 u_int32_t power_meas_q, power_meas_i, iq_corr_meas; 2526 u_int32_t q_coff_denom, i_coff_denom; 2527 int32_t q_coff, i_coff; 2528 int iq_corr_neg, i; 2529 HAL_CHANNEL_INTERNAL *ichan; 2530 static const u_int32_t offset_array[3] = { 2531 AR_PHY_RX_IQCAL_CORR_B0, 2532 AR_PHY_RX_IQCAL_CORR_B1, 2533 AR_PHY_RX_IQCAL_CORR_B2, 2534 }; 2535 2536 ichan = ath_hal_checkchannel(ah, AH_PRIVATE(ah)->ah_curchan); 2537 2538 for (i = 0; i < num_chains; i++) { 2539 power_meas_i = ahp->ah_total_power_meas_i[i]; 2540 power_meas_q = ahp->ah_total_power_meas_q[i]; 2541 iq_corr_meas = ahp->ah_total_iq_corr_meas[i]; 2542 2543 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2544 "Starting IQ Cal and Correction for Chain %d\n", i); 2545 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2546 "Orignal: Chn %diq_corr_meas = 0x%08x\n", 2547 i, ahp->ah_total_iq_corr_meas[i]); 2548 2549 iq_corr_neg = 0; 2550 2551 /* iq_corr_meas is always negative. */ 2552 if (iq_corr_meas > 0x80000000) { 2553 iq_corr_meas = (0xffffffff - iq_corr_meas) + 1; 2554 iq_corr_neg = 1; 2555 } 2556 2557 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2558 "Chn %d pwr_meas_i = 0x%08x\n", i, power_meas_i); 2559 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2560 "Chn %d pwr_meas_q = 0x%08x\n", i, power_meas_q); 2561 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2562 "iq_corr_neg is 0x%08x\n", iq_corr_neg); 2563 2564 i_coff_denom = (power_meas_i / 2 + power_meas_q / 2) / 256; 2565 q_coff_denom = power_meas_q / 64; 2566 2567 /* Protect against divide-by-0 */ 2568 if ((i_coff_denom != 0) && (q_coff_denom != 0)) { 2569 /* IQ corr_meas is already negated if iqcorr_neg == 1 */ 2570 i_coff = iq_corr_meas / i_coff_denom; 2571 q_coff = power_meas_i / q_coff_denom - 64; 2572 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2573 "Chn %d i_coff = 0x%08x\n", i, i_coff); 2574 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2575 "Chn %d q_coff = 0x%08x\n", i, q_coff); 2576 2577 /* Force bounds on i_coff */ 2578 if (i_coff >= 63) { 2579 i_coff = 63; 2580 } else if (i_coff <= -63) { 2581 i_coff = -63; 2582 } 2583 2584 /* Negate i_coff if iq_corr_neg == 0 */ 2585 if (iq_corr_neg == 0x0) { 2586 i_coff = -i_coff; 2587 } 2588 2589 /* Force bounds on q_coff */ 2590 if (q_coff >= 63) { 2591 q_coff = 63; 2592 } else if (q_coff <= -63) { 2593 q_coff = -63; 2594 } 2595 2596 i_coff = i_coff & 0x7f; 2597 q_coff = q_coff & 0x7f; 2598 2599 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2600 "Chn %d : i_coff = 0x%x q_coff = 0x%x\n", i, i_coff, q_coff); 2601 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2602 "Register offset (0x%04x) before update = 0x%x\n", 2603 offset_array[i], OS_REG_READ(ah, offset_array[i])); 2604 2605 OS_REG_RMW_FIELD(ah, offset_array[i], 2606 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, i_coff); 2607 OS_REG_RMW_FIELD(ah, offset_array[i], 2608 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, q_coff); 2609 2610 /* store the RX cal results */ 2611 if (ichan != NULL) { 2612 ahp->ah_rx_cal_corr[i] = OS_REG_READ(ah, offset_array[i]) & 0x7fff; 2613 ahp->ah_rx_cal_complete = AH_TRUE; 2614 ahp->ah_rx_cal_chan = ichan->channel; 2615 // ahp->ah_rx_cal_chan_flag = ichan->channel_flags &~ CHANNEL_PASSIVE; 2616 ahp->ah_rx_cal_chan_flag = 0; /* XXX */ 2617 } else { 2618 /* XXX? Is this what I should do? */ 2619 ahp->ah_rx_cal_complete = AH_FALSE; 2620 2621 } 2622 2623 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2624 "Register offset (0x%04x) QI COFF (bitfields 0x%08x) " 2625 "after update = 0x%x\n", 2626 offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, 2627 OS_REG_READ(ah, offset_array[i])); 2628 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2629 "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) " 2630 "after update = 0x%x\n", 2631 offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, 2632 OS_REG_READ(ah, offset_array[i])); 2633 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2634 "IQ Cal and Correction done for Chain %d\n", i); 2635 } 2636 } 2637 2638 OS_REG_SET_BIT(ah, 2639 AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE); 2640 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2641 "IQ Cal and Correction (offset 0x%04x) enabled " 2642 "(bit position 0x%08x). New Value 0x%08x\n", 2643 (unsigned) (AR_PHY_RX_IQCAL_CORR_B0), 2644 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE, 2645 OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0)); 2646 } 2647 2648 /* 2649 * When coming back from offchan, we do not perform RX IQ Cal. 2650 * But the chip reset will clear all previous results 2651 * We store the previous results and restore here. 2652 */ 2653 static void 2654 ar9300_rx_iq_cal_restore(struct ath_hal *ah) 2655 { 2656 struct ath_hal_9300 *ahp = AH9300(ah); 2657 u_int32_t i_coff, q_coff; 2658 HAL_BOOL is_restore = AH_FALSE; 2659 int i; 2660 static const u_int32_t offset_array[3] = { 2661 AR_PHY_RX_IQCAL_CORR_B0, 2662 AR_PHY_RX_IQCAL_CORR_B1, 2663 AR_PHY_RX_IQCAL_CORR_B2, 2664 }; 2665 2666 for (i=0; i<AR9300_MAX_CHAINS; i++) { 2667 if (ahp->ah_rx_cal_corr[i]) { 2668 i_coff = (ahp->ah_rx_cal_corr[i] & 2669 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF) >> 2670 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF_S; 2671 q_coff = (ahp->ah_rx_cal_corr[i] & 2672 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF) >> 2673 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF_S; 2674 2675 OS_REG_RMW_FIELD(ah, offset_array[i], 2676 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, i_coff); 2677 OS_REG_RMW_FIELD(ah, offset_array[i], 2678 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, q_coff); 2679 2680 is_restore = AH_TRUE; 2681 } 2682 } 2683 2684 if (is_restore) 2685 OS_REG_SET_BIT(ah, 2686 AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE); 2687 2688 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 2689 "%s: IQ Cal and Correction (offset 0x%04x) enabled " 2690 "(bit position 0x%08x). New Value 0x%08x\n", 2691 __func__, 2692 (unsigned) (AR_PHY_RX_IQCAL_CORR_B0), 2693 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE, 2694 OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0)); 2695 } 2696 2697 /* 2698 * Set a limit on the overall output power. Used for dynamic 2699 * transmit power control and the like. 2700 * 2701 * NB: limit is in units of 0.5 dbM. 2702 */ 2703 HAL_BOOL 2704 ar9300_set_tx_power_limit(struct ath_hal *ah, u_int32_t limit, 2705 u_int16_t extra_txpow, u_int16_t tpc_in_db) 2706 { 2707 struct ath_hal_9300 *ahp = AH9300(ah); 2708 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 2709 const struct ieee80211_channel *chan = ahpriv->ah_curchan; 2710 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 2711 2712 if (NULL == chan) { 2713 return AH_FALSE; 2714 } 2715 2716 ahpriv->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER); 2717 ahpriv->ah_extraTxPow = extra_txpow; 2718 2719 if(chan == NULL) { 2720 return AH_FALSE; 2721 } 2722 if (ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan, 2723 ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan), 2724 ath_hal_get_twice_max_regpower(ahpriv, ichan, chan), 2725 AH_MIN(MAX_RATE_POWER, ahpriv->ah_powerLimit)) != HAL_OK) 2726 { 2727 return AH_FALSE; 2728 } 2729 return AH_TRUE; 2730 } 2731 2732 /* 2733 * Exported call to check for a recent gain reading and return 2734 * the current state of the thermal calibration gain engine. 2735 */ 2736 HAL_RFGAIN 2737 ar9300_get_rfgain(struct ath_hal *ah) 2738 { 2739 return HAL_RFGAIN_INACTIVE; 2740 } 2741 2742 #define HAL_GREEN_AP_RX_MASK 0x1 2743 2744 static inline void 2745 ar9300_init_chain_masks(struct ath_hal *ah, int rx_chainmask, int tx_chainmask) 2746 { 2747 if (AH9300(ah)->green_ap_ps_on) { 2748 rx_chainmask = HAL_GREEN_AP_RX_MASK; 2749 } 2750 if (rx_chainmask == 0x5) { 2751 OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN); 2752 } 2753 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 2754 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 2755 2756 /* 2757 * Adaptive Power Management: 2758 * Some 3 stream chips exceed the PCIe power requirements. 2759 * This workaround will reduce power consumption by using 2 tx chains 2760 * for 1 and 2 stream rates (5 GHz only). 2761 * 2762 * Set the self gen mask to 2 tx chains when APM is enabled. 2763 * 2764 */ 2765 if (AH_PRIVATE(ah)->ah_caps.halApmEnable && (tx_chainmask == 0x7)) { 2766 OS_REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); 2767 } 2768 else { 2769 OS_REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask); 2770 } 2771 2772 if (tx_chainmask == 0x5) { 2773 OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN); 2774 } 2775 } 2776 2777 /* 2778 * Override INI values with chip specific configuration. 2779 */ 2780 static inline void 2781 ar9300_override_ini(struct ath_hal *ah, struct ieee80211_channel *chan) 2782 { 2783 u_int32_t val; 2784 HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps; 2785 2786 /* 2787 * Set the RX_ABORT and RX_DIS and clear it only after 2788 * RXE is set for MAC. This prevents frames with 2789 * corrupted descriptor status. 2790 */ 2791 OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 2792 /* 2793 * For Merlin and above, there is a new feature that allows Multicast 2794 * search based on both MAC Address and Key ID. 2795 * By default, this feature is enabled. 2796 * But since the driver is not using this feature, we switch it off; 2797 * otherwise multicast search based on MAC addr only will fail. 2798 */ 2799 val = OS_REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE); 2800 OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, 2801 val | AR_BUG_58603_FIX_ENABLE | AR_AGG_WEP_ENABLE); 2802 2803 2804 /* Osprey revision specific configuration */ 2805 2806 /* Osprey 2.0+ - if SW RAC support is disabled, must also disable 2807 * the Osprey 2.0 hardware RAC fix. 2808 */ 2809 if (p_cap->halIsrRacSupport == AH_FALSE) { 2810 OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_MISSING_TX_INTR_FIX_ENABLE); 2811 } 2812 2813 /* try to enable old pal if it is needed for h/w green tx */ 2814 ar9300_hwgreentx_set_pal_spare(ah, 1); 2815 } 2816 2817 static inline void 2818 ar9300_prog_ini(struct ath_hal *ah, struct ar9300_ini_array *ini_arr, 2819 int column) 2820 { 2821 int i, reg_writes = 0; 2822 2823 /* New INI format: Array may be undefined (pre, core, post arrays) */ 2824 if (ini_arr->ia_array == NULL) { 2825 return; 2826 } 2827 2828 /* 2829 * New INI format: Pre, core, and post arrays for a given subsystem may be 2830 * modal (> 2 columns) or non-modal (2 columns). 2831 * Determine if the array is non-modal and force the column to 1. 2832 */ 2833 if (column >= ini_arr->ia_columns) { 2834 column = 1; 2835 } 2836 2837 for (i = 0; i < ini_arr->ia_rows; i++) { 2838 u_int32_t reg = INI_RA(ini_arr, i, 0); 2839 u_int32_t val = INI_RA(ini_arr, i, column); 2840 2841 /* 2842 ** Determine if this is a shift register value 2843 ** (reg >= 0x16000 && reg < 0x17000 for Osprey) , 2844 ** and insert the configured delay if so. 2845 ** -this delay is not required for Osprey (EV#71410) 2846 */ 2847 OS_REG_WRITE(ah, reg, val); 2848 WAR_6773(reg_writes); 2849 2850 } 2851 } 2852 2853 static inline HAL_STATUS 2854 ar9300_process_ini(struct ath_hal *ah, struct ieee80211_channel *chan, 2855 HAL_CHANNEL_INTERNAL *ichan, HAL_HT_MACMODE macmode) 2856 { 2857 int reg_writes = 0; 2858 struct ath_hal_9300 *ahp = AH9300(ah); 2859 u_int modes_index, modes_txgaintable_index = 0; 2860 int i; 2861 HAL_STATUS status; 2862 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 2863 /* Setup the indices for the next set of register array writes */ 2864 /* TODO: 2865 * If the channel marker is indicative of the current mode rather 2866 * than capability, we do not need to check the phy mode below. 2867 */ 2868 #if 0 2869 switch (chan->channel_flags & CHANNEL_ALL) { 2870 case CHANNEL_A: 2871 case CHANNEL_A_HT20: 2872 if (AR_SREV_SCORPION(ah)){ 2873 if (chan->channel <= 5350){ 2874 modes_txgaintable_index = 1; 2875 }else if ((chan->channel > 5350) && (chan->channel <= 5600)){ 2876 modes_txgaintable_index = 3; 2877 }else if (chan->channel > 5600){ 2878 modes_txgaintable_index = 5; 2879 } 2880 } 2881 modes_index = 1; 2882 freq_index = 1; 2883 break; 2884 2885 case CHANNEL_A_HT40PLUS: 2886 case CHANNEL_A_HT40MINUS: 2887 if (AR_SREV_SCORPION(ah)){ 2888 if (chan->channel <= 5350){ 2889 modes_txgaintable_index = 2; 2890 }else if ((chan->channel > 5350) && (chan->channel <= 5600)){ 2891 modes_txgaintable_index = 4; 2892 }else if (chan->channel > 5600){ 2893 modes_txgaintable_index = 6; 2894 } 2895 } 2896 modes_index = 2; 2897 freq_index = 1; 2898 break; 2899 2900 case CHANNEL_PUREG: 2901 case CHANNEL_G_HT20: 2902 case CHANNEL_B: 2903 if (AR_SREV_SCORPION(ah)){ 2904 modes_txgaintable_index = 8; 2905 }else if (AR_SREV_HONEYBEE(ah)){ 2906 modes_txgaintable_index = 1; 2907 } 2908 modes_index = 4; 2909 freq_index = 2; 2910 break; 2911 2912 case CHANNEL_G_HT40PLUS: 2913 case CHANNEL_G_HT40MINUS: 2914 if (AR_SREV_SCORPION(ah)){ 2915 modes_txgaintable_index = 7; 2916 }else if (AR_SREV_HONEYBEE(ah)){ 2917 modes_txgaintable_index = 1; 2918 } 2919 modes_index = 3; 2920 freq_index = 2; 2921 break; 2922 2923 case CHANNEL_108G: 2924 modes_index = 5; 2925 freq_index = 2; 2926 break; 2927 2928 default: 2929 HALASSERT(0); 2930 return HAL_EINVAL; 2931 } 2932 #endif 2933 2934 /* FreeBSD */ 2935 if (IS_CHAN_5GHZ(ichan)) { 2936 if (IEEE80211_IS_CHAN_HT40U(chan) || IEEE80211_IS_CHAN_HT40D(chan)) { 2937 if (AR_SREV_SCORPION(ah)){ 2938 if (ichan->channel <= 5350){ 2939 modes_txgaintable_index = 2; 2940 }else if ((ichan->channel > 5350) && (ichan->channel <= 5600)){ 2941 modes_txgaintable_index = 4; 2942 }else if (ichan->channel > 5600){ 2943 modes_txgaintable_index = 6; 2944 } 2945 } 2946 modes_index = 2; 2947 } else if (IEEE80211_IS_CHAN_A(chan) || IEEE80211_IS_CHAN_HT20(chan)) { 2948 if (AR_SREV_SCORPION(ah)){ 2949 if (ichan->channel <= 5350){ 2950 modes_txgaintable_index = 1; 2951 }else if ((ichan->channel > 5350) && (ichan->channel <= 5600)){ 2952 modes_txgaintable_index = 3; 2953 }else if (ichan->channel > 5600){ 2954 modes_txgaintable_index = 5; 2955 } 2956 } 2957 modes_index = 1; 2958 } else 2959 return HAL_EINVAL; 2960 } else if (IS_CHAN_2GHZ(ichan)) { 2961 if (IEEE80211_IS_CHAN_108G(chan)) { 2962 modes_index = 5; 2963 } else if (IEEE80211_IS_CHAN_HT40U(chan) || IEEE80211_IS_CHAN_HT40D(chan)) { 2964 if (AR_SREV_SCORPION(ah)){ 2965 modes_txgaintable_index = 7; 2966 } else if (AR_SREV_HONEYBEE(ah)){ 2967 modes_txgaintable_index = 1; 2968 } 2969 modes_index = 3; 2970 } else if (IEEE80211_IS_CHAN_HT20(chan) || IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_B(chan) || IEEE80211_IS_CHAN_PUREG(chan)) { 2971 if (AR_SREV_SCORPION(ah)){ 2972 modes_txgaintable_index = 8; 2973 } else if (AR_SREV_HONEYBEE(ah)){ 2974 modes_txgaintable_index = 1; 2975 } 2976 modes_index = 4; 2977 } else 2978 return HAL_EINVAL; 2979 } else 2980 return HAL_EINVAL; 2981 2982 #if 0 2983 /* Set correct Baseband to analog shift setting to access analog chips. */ 2984 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 2985 #endif 2986 2987 HALDEBUG(ah, HAL_DEBUG_RESET, 2988 "ar9300_process_ini: " 2989 "Skipping OS-REG-WRITE(ah, AR-PHY(0), 0x00000007)\n"); 2990 HALDEBUG(ah, HAL_DEBUG_RESET, 2991 "ar9300_process_ini: no ADDac programming\n"); 2992 2993 2994 /* 2995 * Osprey 2.0+ - new INI format. 2996 * Each subsystem has a pre, core, and post array. 2997 */ 2998 for (i = 0; i < ATH_INI_NUM_SPLIT; i++) { 2999 ar9300_prog_ini(ah, &ahp->ah_ini_soc[i], modes_index); 3000 ar9300_prog_ini(ah, &ahp->ah_ini_mac[i], modes_index); 3001 ar9300_prog_ini(ah, &ahp->ah_ini_bb[i], modes_index); 3002 ar9300_prog_ini(ah, &ahp->ah_ini_radio[i], modes_index); 3003 if ((i == ATH_INI_POST) && (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah))) { 3004 ar9300_prog_ini(ah, &ahp->ah_ini_radio_post_sys2ant, modes_index); 3005 } 3006 3007 } 3008 3009 if (!(AR_SREV_SOC(ah))) { 3010 /* Doubler issue : Some board doesn't work well with MCS15. Turn off doubler after freq locking is complete*/ 3011 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)); 3012 OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | 3013 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */ 3014 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)); 3015 3016 OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | 3017 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */ 3018 OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | 3019 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */ 3020 OS_DELAY(200); 3021 3022 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)); 3023 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */ 3024 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */ 3025 OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */ 3026 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)); 3027 3028 OS_DELAY(1); 3029 3030 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)); 3031 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */ 3032 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */ 3033 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */ 3034 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)); 3035 3036 OS_DELAY(200); 3037 3038 //ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_SYNTH12, OS_REG_READ(ah, AR_PHY_65NM_CH0_SYNTH12)); 3039 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH12, AR_PHY_65NM_CH0_SYNTH12_VREFMUL3, 0xf); 3040 //OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_SYNTH12, 1<< 16); /* clr charge pump */ 3041 //ath_hal_printf(ah, "%s[%d] ==== After reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_SYNTH12, OS_REG_READ(ah, AR_PHY_65NM_CH0_SYNTH12)); 3042 3043 OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | 3044 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */ 3045 OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | 3046 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */ 3047 OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | 3048 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */ 3049 //ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)); 3050 } 3051 3052 /* Write rxgain Array Parameters */ 3053 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain, 1, reg_writes); 3054 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain programming\n"); 3055 3056 if (AR_SREV_SCORPION(ah)) { 3057 /* Write rxgain bounds Array */ 3058 REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bounds, modes_index, reg_writes); 3059 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain table bounds programming\n"); 3060 } 3061 /* UB124 xLNA settings */ 3062 if (AR_SREV_WASP(ah) && ar9300_rx_gain_index_get(ah) == 2) { 3063 #define REG_WRITE(_reg,_val) *((volatile u_int32_t *)(_reg)) = (_val); 3064 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg)) 3065 u_int32_t val; 3066 /* B8040000: bit[0]=0, bit[3]=0; */ 3067 val = REG_READ(0xB8040000); 3068 val &= 0xfffffff6; 3069 REG_WRITE(0xB8040000, val); 3070 /* B804002c: bit[31:24]=0x2e; bit[7:0]=0x2f; */ 3071 val = REG_READ(0xB804002c); 3072 val &= 0x00ffff00; 3073 val |= 0x2e00002f; 3074 REG_WRITE(0xB804002c, val); 3075 /* B804006c: bit[1]=1; */ 3076 val = REG_READ(0xB804006c); 3077 val |= 0x2; 3078 REG_WRITE(0xB804006c, val); 3079 #undef REG_READ 3080 #undef REG_WRITE 3081 } 3082 3083 3084 /* Write txgain Array Parameters */ 3085 if (AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) { 3086 REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_txgaintable_index, 3087 reg_writes); 3088 }else{ 3089 REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_index, reg_writes); 3090 } 3091 HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Tx Gain programming\n"); 3092 3093 3094 /* For 5GHz channels requiring Fast Clock, apply different modal values */ 3095 if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 3096 HALDEBUG(ah, HAL_DEBUG_RESET, 3097 "%s: Fast clock enabled, use special ini values\n", __func__); 3098 REG_WRITE_ARRAY(&ahp->ah_ini_modes_additional, modes_index, reg_writes); 3099 } 3100 3101 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) { 3102 HALDEBUG(ah, HAL_DEBUG_RESET, 3103 "%s: use xtal ini for AH9300(ah)->clk_25mhz: %d\n", 3104 __func__, AH9300(ah)->clk_25mhz); 3105 REG_WRITE_ARRAY( 3106 &ahp->ah_ini_modes_additional, 1/*modes_index*/, reg_writes); 3107 } 3108 3109 if (AR_SREV_WASP(ah) && (AH9300(ah)->clk_25mhz == 0)) { 3110 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Apply 40MHz ini settings\n", __func__); 3111 REG_WRITE_ARRAY( 3112 &ahp->ah_ini_modes_additional_40mhz, 1/*modesIndex*/, reg_writes); 3113 } 3114 3115 /* Handle Japan Channel 14 channel spreading */ 3116 if (2484 == ichan->channel) { 3117 ar9300_prog_ini(ah, &ahp->ah_ini_japan2484, 1); 3118 } 3119 3120 #if 0 3121 if (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)) { 3122 ar9300_prog_ini(ah, &ahp->ah_ini_BTCOEX_MAX_TXPWR, 1); 3123 } 3124 #endif 3125 3126 /* Override INI with chip specific configuration */ 3127 ar9300_override_ini(ah, chan); 3128 3129 /* Setup 11n MAC/Phy mode registers */ 3130 ar9300_set_11n_regs(ah, chan, macmode); 3131 3132 /* 3133 * Moved ar9300_init_chain_masks() here to ensure the swap bit is set before 3134 * the pdadc table is written. Swap must occur before any radio dependent 3135 * replicated register access. The pdadc curve addressing in particular 3136 * depends on the consistent setting of the swap bit. 3137 */ 3138 ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask); 3139 3140 /* 3141 * Setup the transmit power values. 3142 * 3143 * After the public to private hal channel mapping, ichan contains the 3144 * valid regulatory power value. 3145 * ath_hal_getctl and ath_hal_getantennaallowed look up ichan from chan. 3146 */ 3147 status = ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan, 3148 ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan), 3149 ath_hal_get_twice_max_regpower(ahpriv, ichan, chan), 3150 AH_MIN(MAX_RATE_POWER, ahpriv->ah_powerLimit)); 3151 if (status != HAL_OK) { 3152 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 3153 "%s: error init'ing transmit power\n", __func__); 3154 return HAL_EIO; 3155 } 3156 3157 3158 return HAL_OK; 3159 #undef N 3160 } 3161 3162 /* ar9300_is_cal_supp 3163 * Determine if calibration is supported by device and channel flags 3164 */ 3165 inline static HAL_BOOL 3166 ar9300_is_cal_supp(struct ath_hal *ah, const struct ieee80211_channel *chan, 3167 HAL_CAL_TYPES cal_type) 3168 { 3169 struct ath_hal_9300 *ahp = AH9300(ah); 3170 HAL_BOOL retval = AH_FALSE; 3171 3172 switch (cal_type & ahp->ah_supp_cals) { 3173 case IQ_MISMATCH_CAL: 3174 /* Run IQ Mismatch for non-CCK only */ 3175 if (!IEEE80211_IS_CHAN_B(chan)) { 3176 retval = AH_TRUE; 3177 } 3178 break; 3179 case TEMP_COMP_CAL: 3180 retval = AH_TRUE; 3181 break; 3182 } 3183 3184 return retval; 3185 } 3186 3187 3188 #if 0 3189 /* ar9285_pa_cal 3190 * PA Calibration for Kite 1.1 and later versions of Kite. 3191 * - from system's team. 3192 */ 3193 static inline void 3194 ar9285_pa_cal(struct ath_hal *ah) 3195 { 3196 u_int32_t reg_val; 3197 int i, lo_gn, offs_6_1, offs_0; 3198 u_int8_t reflo; 3199 u_int32_t phy_test2_reg_val, phy_adc_ctl_reg_val; 3200 u_int32_t an_top2_reg_val, phy_tst_dac_reg_val; 3201 3202 3203 /* Kite 1.1 WAR for Bug 35666 3204 * Increase the LDO value to 1.28V before accessing analog Reg */ 3205 if (AR_SREV_KITE_11(ah)) { 3206 OS_REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14) ); 3207 } 3208 an_top2_reg_val = OS_REG_READ(ah, AR9285_AN_TOP2); 3209 3210 /* set pdv2i pdrxtxbb */ 3211 reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1); 3212 reg_val |= ((0x1 << 5) | (0x1 << 7)); 3213 OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val); 3214 3215 /* clear pwddb */ 3216 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G7); 3217 reg_val &= 0xfffffffd; 3218 OS_REG_WRITE(ah, AR9285_AN_RF2G7, reg_val); 3219 3220 /* clear enpacal */ 3221 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1); 3222 reg_val &= 0xfffff7ff; 3223 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val); 3224 3225 /* set offcal */ 3226 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2); 3227 reg_val |= (0x1 << 12); 3228 OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val); 3229 3230 /* set pdpadrv1=pdpadrv2=pdpaout=1 */ 3231 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1); 3232 reg_val |= (0x7 << 23); 3233 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val); 3234 3235 /* Read back reflo, increase it by 1 and write it. */ 3236 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3); 3237 reflo = ((reg_val >> 26) & 0x7); 3238 3239 if (reflo < 0x7) { 3240 reflo++; 3241 } 3242 reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26)); 3243 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val); 3244 3245 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3); 3246 reflo = ((reg_val >> 26) & 0x7); 3247 3248 /* use TX single carrier to transmit 3249 * dac const 3250 * reg. 15 3251 */ 3252 phy_tst_dac_reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST); 3253 OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, ((0x7ff << 11) | 0x7ff)); 3254 reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST); 3255 3256 /* source is dac const 3257 * reg. 2 3258 */ 3259 phy_test2_reg_val = OS_REG_READ(ah, AR_PHY_TEST2); 3260 OS_REG_WRITE(ah, AR_PHY_TEST2, ((0x1 << 7) | (0x1 << 1))); 3261 reg_val = OS_REG_READ(ah, AR_PHY_TEST2); 3262 3263 /* set dac on 3264 * reg. 11 3265 */ 3266 phy_adc_ctl_reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL); 3267 OS_REG_WRITE(ah, AR_PHY_ADC_CTL, 0x80008000); 3268 reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL); 3269 3270 OS_REG_WRITE(ah, AR9285_AN_TOP2, (0x1 << 27) | (0x1 << 17) | (0x1 << 16) | 3271 (0x1 << 14) | (0x1 << 12) | (0x1 << 11) | 3272 (0x1 << 7) | (0x1 << 5)); 3273 3274 OS_DELAY(10); /* 10 usec */ 3275 3276 /* clear off[6:0] */ 3277 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6); 3278 reg_val &= 0xfc0fffff; 3279 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val); 3280 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3); 3281 reg_val &= 0xfdffffff; 3282 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val); 3283 3284 offs_6_1 = 0; 3285 for (i = 6; i > 0; i--) { 3286 /* sef off[$k]==1 */ 3287 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6); 3288 reg_val &= 0xfc0fffff; 3289 reg_val = reg_val | (0x1 << (19 + i)) | ((offs_6_1) << 20); 3290 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val); 3291 lo_gn = (OS_REG_READ(ah, AR9285_AN_RF2G9)) & 0x1; 3292 offs_6_1 = offs_6_1 | (lo_gn << (i - 1)); 3293 } 3294 3295 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6); 3296 reg_val &= 0xfc0fffff; 3297 reg_val = reg_val | ((offs_6_1 - 1) << 20); 3298 OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val); 3299 3300 /* set off_0=1; */ 3301 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3); 3302 reg_val &= 0xfdffffff; 3303 reg_val = reg_val | (0x1 << 25); 3304 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val); 3305 3306 lo_gn = OS_REG_READ(ah, AR9285_AN_RF2G9) & 0x1; 3307 offs_0 = lo_gn; 3308 3309 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3); 3310 reg_val &= 0xfdffffff; 3311 reg_val = reg_val | (offs_0 << 25); 3312 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val); 3313 3314 /* clear pdv2i */ 3315 reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1); 3316 reg_val &= 0xffffff5f; 3317 OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val); 3318 3319 /* set enpacal */ 3320 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1); 3321 reg_val |= (0x1 << 11); 3322 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val); 3323 3324 /* clear offcal */ 3325 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2); 3326 reg_val &= 0xffffefff; 3327 OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val); 3328 3329 /* set pdpadrv1=pdpadrv2=pdpaout=0 */ 3330 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1); 3331 reg_val &= 0xfc7fffff; 3332 OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val); 3333 3334 /* Read back reflo, decrease it by 1 and write it. */ 3335 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3); 3336 reflo = (reg_val >> 26) & 0x7; 3337 if (reflo) { 3338 reflo--; 3339 } 3340 reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26)); 3341 OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val); 3342 reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3); 3343 reflo = (reg_val >> 26) & 0x7; 3344 3345 /* write back registers */ 3346 OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, phy_tst_dac_reg_val); 3347 OS_REG_WRITE(ah, AR_PHY_TEST2, phy_test2_reg_val); 3348 OS_REG_WRITE(ah, AR_PHY_ADC_CTL, phy_adc_ctl_reg_val); 3349 OS_REG_WRITE(ah, AR9285_AN_TOP2, an_top2_reg_val); 3350 3351 /* Kite 1.1 WAR for Bug 35666 3352 * Decrease the LDO value back to 1.20V */ 3353 if (AR_SREV_KITE_11(ah)) { 3354 OS_REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); 3355 } 3356 } 3357 #endif 3358 3359 /* ar9300_run_init_cals 3360 * Runs non-periodic calibrations 3361 */ 3362 inline static HAL_BOOL 3363 ar9300_run_init_cals(struct ath_hal *ah, int init_cal_count) 3364 { 3365 struct ath_hal_9300 *ahp = AH9300(ah); 3366 HAL_CHANNEL_INTERNAL ichan; /* bogus */ 3367 HAL_BOOL is_cal_done; 3368 HAL_CAL_LIST *curr_cal; 3369 const HAL_PERCAL_DATA *cal_data; 3370 int i; 3371 3372 curr_cal = ahp->ah_cal_list_curr; 3373 if (curr_cal == AH_NULL) { 3374 return AH_FALSE; 3375 } 3376 cal_data = curr_cal->cal_data; 3377 ichan.calValid = 0; 3378 3379 for (i = 0; i < init_cal_count; i++) { 3380 /* Reset this Cal */ 3381 ar9300_reset_calibration(ah, curr_cal); 3382 /* Poll for offset calibration complete */ 3383 if (!ath_hal_wait( 3384 ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL, 0)) 3385 { 3386 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3387 "%s: Cal %d failed to complete in 100ms.\n", 3388 __func__, curr_cal->cal_data->cal_type); 3389 /* Re-initialize list pointers for periodic cals */ 3390 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr 3391 = AH_NULL; 3392 return AH_FALSE; 3393 } 3394 /* Run this cal */ 3395 ar9300_per_calibration( 3396 ah, &ichan, ahp->ah_rx_chainmask, curr_cal, &is_cal_done); 3397 if (is_cal_done == AH_FALSE) { 3398 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3399 "%s: Not able to run Init Cal %d.\n", __func__, 3400 curr_cal->cal_data->cal_type); 3401 } 3402 if (curr_cal->cal_next) { 3403 curr_cal = curr_cal->cal_next; 3404 } 3405 } 3406 3407 /* Re-initialize list pointers for periodic cals */ 3408 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL; 3409 return AH_TRUE; 3410 } 3411 3412 #if 0 3413 static void 3414 ar9300_tx_carrier_leak_war(struct ath_hal *ah) 3415 { 3416 unsigned long tx_gain_table_max; 3417 unsigned long reg_bb_cl_map_0_b0 = 0xffffffff; 3418 unsigned long reg_bb_cl_map_1_b0 = 0xffffffff; 3419 unsigned long reg_bb_cl_map_2_b0 = 0xffffffff; 3420 unsigned long reg_bb_cl_map_3_b0 = 0xffffffff; 3421 unsigned long tx_gain, cal_run = 0; 3422 unsigned long cal_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1]; 3423 unsigned long cal_gain_index[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1]; 3424 unsigned long new_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1]; 3425 int i, j; 3426 3427 OS_MEMSET(new_gain, 0, sizeof(new_gain)); 3428 /*printf(" Running TxCarrierLeakWAR\n");*/ 3429 3430 /* process tx gain table, we use cl_map_hw_gen=0. */ 3431 OS_REG_RMW_FIELD(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_MAP_HW_GEN, 0); 3432 3433 //the table we used is txbb_gc[2:0], 1dB[2:1]. 3434 tx_gain_table_max = OS_REG_READ_FIELD(ah, 3435 AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX); 3436 3437 for (i = 0; i <= tx_gain_table_max; i++) { 3438 tx_gain = OS_REG_READ(ah, AR_PHY_TXGAIN_TAB(1) + i * 4); 3439 cal_gain[i] = (((tx_gain >> 5)& 0x7) << 2) | 3440 (((tx_gain >> 1) & 0x3) << 0); 3441 if (i == 0) { 3442 cal_gain_index[i] = cal_run; 3443 new_gain[i] = 1; 3444 cal_run++; 3445 } else { 3446 new_gain[i] = 1; 3447 for (j = 0; j < i; j++) { 3448 /* 3449 printf("i=%d, j=%d cal_gain[$i]=0x%04x\n", i, j, cal_gain[i]); 3450 */ 3451 if (new_gain[i]) { 3452 if ((cal_gain[i] != cal_gain[j])) { 3453 new_gain[i] = 1; 3454 } else { 3455 /* if old gain found, use old cal_run value. */ 3456 new_gain[i] = 0; 3457 cal_gain_index[i] = cal_gain_index[j]; 3458 } 3459 } 3460 } 3461 /* if new gain found, increase cal_run */ 3462 if (new_gain[i] == 1) { 3463 cal_gain_index[i] = cal_run; 3464 cal_run++; 3465 } 3466 } 3467 3468 reg_bb_cl_map_0_b0 = (reg_bb_cl_map_0_b0 & ~(0x1 << i)) | 3469 ((cal_gain_index[i] >> 0 & 0x1) << i); 3470 reg_bb_cl_map_1_b0 = (reg_bb_cl_map_1_b0 & ~(0x1 << i)) | 3471 ((cal_gain_index[i] >> 1 & 0x1) << i); 3472 reg_bb_cl_map_2_b0 = (reg_bb_cl_map_2_b0 & ~(0x1 << i)) | 3473 ((cal_gain_index[i] >> 2 & 0x1) << i); 3474 reg_bb_cl_map_3_b0 = (reg_bb_cl_map_3_b0 & ~(0x1 << i)) | 3475 ((cal_gain_index[i] >> 3 & 0x1) << i); 3476 3477 /* 3478 printf("i=%2d, cal_gain[$i]= 0x%04x, cal_run= %d, " 3479 "cal_gain_index[i]=%d, new_gain[i] = %d\n", 3480 i, cal_gain[i], cal_run, cal_gain_index[i], new_gain[i]); 3481 */ 3482 } 3483 OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B0, reg_bb_cl_map_0_b0); 3484 OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B0, reg_bb_cl_map_1_b0); 3485 OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B0, reg_bb_cl_map_2_b0); 3486 OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B0, reg_bb_cl_map_3_b0); 3487 if (AR_SREV_WASP(ah)) { 3488 OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B1, reg_bb_cl_map_0_b0); 3489 OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B1, reg_bb_cl_map_1_b0); 3490 OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B1, reg_bb_cl_map_2_b0); 3491 OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B1, reg_bb_cl_map_3_b0); 3492 } 3493 } 3494 #endif 3495 3496 3497 static inline void 3498 ar9300_invalidate_saved_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan) 3499 { 3500 #if ATH_SUPPORT_CAL_REUSE 3501 if (AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse & 3502 ATH_CAL_REUSE_REDO_IN_FULL_RESET) 3503 { 3504 ichan->one_time_txiqcal_done = AH_FALSE; 3505 ichan->one_time_txclcal_done = AH_FALSE; 3506 } 3507 #endif 3508 } 3509 3510 static inline HAL_BOOL 3511 ar9300_restore_rtt_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan) 3512 { 3513 HAL_BOOL restore_status = AH_FALSE; 3514 3515 return restore_status; 3516 } 3517 3518 /* ar9300_init_cal 3519 * Initialize Calibration infrastructure 3520 */ 3521 static inline HAL_BOOL 3522 ar9300_init_cal_internal(struct ath_hal *ah, struct ieee80211_channel *chan, 3523 HAL_CHANNEL_INTERNAL *ichan, 3524 HAL_BOOL enable_rtt, HAL_BOOL do_rtt_cal, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr) 3525 { 3526 struct ath_hal_9300 *ahp = AH9300(ah); 3527 HAL_BOOL txiqcal_success_flag = AH_FALSE; 3528 HAL_BOOL cal_done = AH_FALSE; 3529 int iqcal_idx = 0; 3530 HAL_BOOL do_sep_iq_cal = AH_FALSE; 3531 HAL_BOOL do_agc_cal = do_rtt_cal; 3532 HAL_BOOL is_cal_reusable = AH_TRUE; 3533 #if ATH_SUPPORT_CAL_REUSE 3534 HAL_BOOL cal_reuse_enable = AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse & 3535 ATH_CAL_REUSE_ENABLE; 3536 HAL_BOOL clc_success = AH_FALSE; 3537 int32_t ch_idx, j, cl_tab_reg; 3538 u_int32_t BB_cl_tab_entry = MAX_BB_CL_TABLE_ENTRY; 3539 u_int32_t BB_cl_tab_b[AR9300_MAX_CHAINS] = { 3540 AR_PHY_CL_TAB_0, 3541 AR_PHY_CL_TAB_1, 3542 AR_PHY_CL_TAB_2 3543 }; 3544 #endif 3545 3546 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) { 3547 /* Hornet: 1 x 1 */ 3548 ahp->ah_rx_cal_chainmask = 0x1; 3549 ahp->ah_tx_cal_chainmask = 0x1; 3550 } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_HONEYBEE(ah)) { 3551 /* Wasp/Jupiter: 2 x 2 */ 3552 ahp->ah_rx_cal_chainmask = 0x3; 3553 ahp->ah_tx_cal_chainmask = 0x3; 3554 } else { 3555 /* 3556 * Osprey needs to be configured for the correct chain mode 3557 * before running AGC/TxIQ cals. 3558 */ 3559 if (ahp->ah_enterprise_mode & AR_ENT_OTP_CHAIN2_DISABLE) { 3560 /* chain 2 disabled - 2 chain mode */ 3561 ahp->ah_rx_cal_chainmask = 0x3; 3562 ahp->ah_tx_cal_chainmask = 0x3; 3563 } else { 3564 ahp->ah_rx_cal_chainmask = 0x7; 3565 ahp->ah_tx_cal_chainmask = 0x7; 3566 } 3567 } 3568 ar9300_init_chain_masks(ah, ahp->ah_rx_cal_chainmask, ahp->ah_tx_cal_chainmask); 3569 3570 3571 if (ahp->tx_cl_cal_enable) { 3572 #if ATH_SUPPORT_CAL_REUSE 3573 /* disable Carrie Leak or set do_agc_cal accordingly */ 3574 if (cal_reuse_enable && ichan->one_time_txclcal_done) 3575 { 3576 OS_REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); 3577 } else 3578 #endif /* ATH_SUPPORT_CAL_REUSE */ 3579 { 3580 OS_REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); 3581 do_agc_cal = AH_TRUE; 3582 } 3583 } 3584 3585 /* Do Tx IQ Calibration here for osprey hornet and wasp */ 3586 /* XXX: For initial wasp bringup - check and enable this */ 3587 /* EV 74233: Tx IQ fails to complete for half/quarter rates */ 3588 if (!(IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) { 3589 if (ahp->tx_iq_cal_enable) { 3590 /* this should be eventually moved to INI file */ 3591 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1(ah), 3592 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT); 3593 3594 /* 3595 * For poseidon and later chips, 3596 * Tx IQ cal HW run will be a part of AGC calibration 3597 */ 3598 if (ahp->tx_iq_cal_during_agc_cal) { 3599 /* 3600 * txiqcal_success_flag always set to 1 to run 3601 * ar9300_tx_iq_cal_post_proc 3602 * if following AGC cal passes 3603 */ 3604 #if ATH_SUPPORT_CAL_REUSE 3605 if (!cal_reuse_enable || !ichan->one_time_txiqcal_done) 3606 { 3607 txiqcal_success_flag = AH_TRUE; 3608 OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah), 3609 OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) | 3610 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); 3611 } else { 3612 OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah), 3613 OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) & 3614 (~AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)); 3615 } 3616 #else 3617 if (OS_REG_READ_FIELD(ah, 3618 AR_PHY_TX_IQCAL_CONTROL_0(ah), 3619 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)){ 3620 if (apply_last_iqcorr == AH_TRUE) { 3621 OS_REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah), 3622 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); 3623 txiqcal_success_flag = AH_FALSE; 3624 } else { 3625 txiqcal_success_flag = AH_TRUE; 3626 } 3627 }else{ 3628 txiqcal_success_flag = AH_FALSE; 3629 } 3630 #endif 3631 if (txiqcal_success_flag) { 3632 do_agc_cal = AH_TRUE; 3633 } 3634 } else 3635 #if ATH_SUPPORT_CAL_REUSE 3636 if (!cal_reuse_enable || !ichan->one_time_txiqcal_done) 3637 #endif 3638 { 3639 do_sep_iq_cal = AH_TRUE; 3640 do_agc_cal = AH_TRUE; 3641 } 3642 } 3643 } 3644 3645 #if ATH_SUPPORT_MCI 3646 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && 3647 IS_CHAN_2GHZ(ichan) && 3648 (ahp->ah_mci_bt_state == MCI_BT_AWAKE) && 3649 do_agc_cal && 3650 !(ah->ah_config.ath_hal_mci_config & 3651 ATH_MCI_CONFIG_DISABLE_MCI_CAL)) 3652 { 3653 u_int32_t payload[4] = {0, 0, 0, 0}; 3654 3655 /* Send CAL_REQ only when BT is AWAKE. */ 3656 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_REQ 0x%X\n", 3657 __func__, ahp->ah_mci_wlan_cal_seq); 3658 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_REQ); 3659 payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_seq++; 3660 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE); 3661 3662 /* Wait BT_CAL_GRANT for 50ms */ 3663 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 3664 "(MCI) %s: Wait for BT_CAL_GRANT\n", __func__); 3665 if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) 3666 { 3667 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 3668 "(MCI) %s: Got BT_CAL_GRANT.\n", __func__); 3669 } 3670 else { 3671 is_cal_reusable = AH_FALSE; 3672 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 3673 "(MCI) %s: BT is not responding.\n", __func__); 3674 } 3675 } 3676 #endif /* ATH_SUPPORT_MCI */ 3677 3678 if (do_sep_iq_cal) 3679 { 3680 /* enable Tx IQ Calibration HW for osprey/hornet/wasp */ 3681 txiqcal_success_flag = ar9300_tx_iq_cal_hw_run(ah); 3682 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); 3683 OS_DELAY(5); 3684 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 3685 } 3686 #if 0 3687 if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) { 3688 ar9300_tx_carrier_leak_war(ah); 3689 } 3690 #endif 3691 /* 3692 * Calibrate the AGC 3693 * 3694 * Tx IQ cal is a part of AGC cal for Jupiter/Poseidon, etc. 3695 * please enable the bit of txiqcal_control_0[31] in INI file 3696 * for Jupiter/Poseidon/etc. 3697 */ 3698 if(!AR_SREV_SCORPION(ah)) { 3699 if (do_agc_cal || !skip_if_none) { 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 cal_done = ath_hal_wait(ah, 3705 AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0); 3706 if (!cal_done) { 3707 HALDEBUG(ah, HAL_DEBUG_FCS_RTT, 3708 "(FCS) CAL NOT DONE!!! - %d\n", ichan->channel); 3709 } 3710 } else { 3711 cal_done = AH_TRUE; 3712 } 3713 /* 3714 * Tx IQ cal post-processing in SW 3715 * This part of code should be common to all chips, 3716 * no chip specific code for Jupiter/Posdeion except for register names. 3717 */ 3718 if (txiqcal_success_flag) { 3719 ar9300_tx_iq_cal_post_proc(ah,ichan, 1, 1,is_cal_reusable, AH_FALSE); 3720 } 3721 } else { 3722 if (!txiqcal_success_flag) { 3723 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL, 3724 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL); 3725 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 3726 0)) { 3727 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3728 "%s: offset calibration failed to complete in 1ms; " 3729 "noisy environment?\n", __func__); 3730 return AH_FALSE; 3731 } 3732 if (apply_last_iqcorr == AH_TRUE) { 3733 ar9300_tx_iq_cal_post_proc(ah, ichan, 0, 0, is_cal_reusable, AH_TRUE); 3734 } 3735 } else { 3736 for (iqcal_idx=0;iqcal_idx<MAXIQCAL;iqcal_idx++) { 3737 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL, 3738 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL); 3739 3740 /* Poll for offset calibration complete */ 3741 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, 3742 AR_PHY_AGC_CONTROL_CAL, 0)) { 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 * Tx IQ cal post-processing in SW 3750 * This part of code should be common to all chips, 3751 * no chip specific code for Jupiter/Posdeion except for register names. 3752 */ 3753 ar9300_tx_iq_cal_post_proc(ah, ichan, iqcal_idx+1, MAXIQCAL, is_cal_reusable, AH_FALSE); 3754 } 3755 } 3756 } 3757 3758 3759 #if ATH_SUPPORT_MCI 3760 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && 3761 IS_CHAN_2GHZ(ichan) && 3762 (ahp->ah_mci_bt_state == MCI_BT_AWAKE) && 3763 do_agc_cal && 3764 !(ah->ah_config.ath_hal_mci_config & 3765 ATH_MCI_CONFIG_DISABLE_MCI_CAL)) 3766 { 3767 u_int32_t payload[4] = {0, 0, 0, 0}; 3768 3769 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_DONE 0x%X\n", 3770 __func__, ahp->ah_mci_wlan_cal_done); 3771 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE); 3772 payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_done++; 3773 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE); 3774 } 3775 #endif /* ATH_SUPPORT_MCI */ 3776 3777 3778 if (!cal_done && !AR_SREV_SCORPION(ah) ) 3779 { 3780 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3781 "%s: offset calibration failed to complete in 1ms; " 3782 "noisy environment?\n", __func__); 3783 return AH_FALSE; 3784 } 3785 3786 #if 0 3787 /* Beacon stuck fix, refer to EV 120056 */ 3788 if(IS_CHAN_2GHZ(chan) && AR_SREV_SCORPION(ah)) 3789 OS_REG_WRITE(ah, AR_PHY_TIMING5, OS_REG_READ(ah,AR_PHY_TIMING5) & ~AR_PHY_TIMING5_CYCPWR_THR1_ENABLE); 3790 #endif 3791 3792 #if 0 3793 /* Do PA Calibration */ 3794 if (AR_SREV_KITE(ah) && AR_SREV_KITE_11_OR_LATER(ah)) { 3795 ar9285_pa_cal(ah); 3796 } 3797 #endif 3798 3799 #if ATH_SUPPORT_CAL_REUSE 3800 if (ichan->one_time_txiqcal_done) { 3801 ar9300_tx_iq_cal_apply(ah, ichan); 3802 HALDEBUG(ah, HAL_DEBUG_FCS_RTT, 3803 "(FCS) TXIQCAL applied - %d\n", ichan->channel); 3804 } 3805 #endif /* ATH_SUPPORT_CAL_REUSE */ 3806 3807 #if ATH_SUPPORT_CAL_REUSE 3808 if (cal_reuse_enable && ahp->tx_cl_cal_enable) 3809 { 3810 clc_success = (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & 3811 AR_PHY_AGC_CONTROL_CLC_SUCCESS) ? 1 : 0; 3812 3813 if (ichan->one_time_txclcal_done) 3814 { 3815 /* reapply CL cal results */ 3816 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) { 3817 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) { 3818 continue; 3819 } 3820 cl_tab_reg = BB_cl_tab_b[ch_idx]; 3821 for (j = 0; j < BB_cl_tab_entry; j++) { 3822 OS_REG_WRITE(ah, cl_tab_reg, ichan->tx_clcal[ch_idx][j]); 3823 cl_tab_reg += 4;; 3824 } 3825 } 3826 HALDEBUG(ah, HAL_DEBUG_FCS_RTT, 3827 "(FCS) TX CL CAL applied - %d\n", ichan->channel); 3828 } 3829 else if (is_cal_reusable && clc_success) { 3830 /* save CL cal results */ 3831 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) { 3832 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) { 3833 continue; 3834 } 3835 cl_tab_reg = BB_cl_tab_b[ch_idx]; 3836 for (j = 0; j < BB_cl_tab_entry; j++) { 3837 ichan->tx_clcal[ch_idx][j] = OS_REG_READ(ah, cl_tab_reg); 3838 cl_tab_reg += 4; 3839 } 3840 } 3841 ichan->one_time_txclcal_done = AH_TRUE; 3842 HALDEBUG(ah, HAL_DEBUG_FCS_RTT, 3843 "(FCS) TX CL CAL saved - %d\n", ichan->channel); 3844 } 3845 } 3846 #endif /* ATH_SUPPORT_CAL_REUSE */ 3847 3848 /* Revert chainmasks to their original values before NF cal */ 3849 ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask); 3850 3851 #if !FIX_NOISE_FLOOR 3852 /* 3853 * Do NF calibration after DC offset and other CALs. 3854 * Per system engineers, noise floor value can sometimes be 20 dB 3855 * higher than normal value if DC offset and noise floor cal are 3856 * triggered at the same time. 3857 */ 3858 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL, 3859 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF); 3860 #endif 3861 3862 /* Initialize list pointers */ 3863 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL; 3864 3865 /* 3866 * Enable IQ, ADC Gain, ADC DC Offset Cals 3867 */ 3868 /* Setup all non-periodic, init time only calibrations */ 3869 /* XXX: Init DC Offset not working yet */ 3870 #ifdef not_yet 3871 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, ADC_DC_INIT_CAL)) { 3872 INIT_CAL(&ahp->ah_adc_dc_cal_init_data); 3873 INSERT_CAL(ahp, &ahp->ah_adc_dc_cal_init_data); 3874 } 3875 3876 /* Initialize current pointer to first element in list */ 3877 ahp->ah_cal_list_curr = ahp->ah_cal_list; 3878 3879 if (ahp->ah_cal_list_curr) { 3880 if (ar9300_run_init_cals(ah, 0) == AH_FALSE) { 3881 return AH_FALSE; 3882 } 3883 } 3884 #endif 3885 /* end - Init time calibrations */ 3886 3887 /* Do not do RX cal in case of offchan, or cal data already exists on same channel*/ 3888 if (ahp->ah_skip_rx_iq_cal) { 3889 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3890 "Skip RX IQ Cal\n"); 3891 return AH_TRUE; 3892 } 3893 3894 /* If Cals are supported, add them to list via INIT/INSERT_CAL */ 3895 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, IQ_MISMATCH_CAL)) { 3896 INIT_CAL(&ahp->ah_iq_cal_data); 3897 INSERT_CAL(ahp, &ahp->ah_iq_cal_data); 3898 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3899 "%s: enabling IQ Calibration.\n", __func__); 3900 } 3901 if (AH_TRUE == ar9300_is_cal_supp(ah, chan, TEMP_COMP_CAL)) { 3902 INIT_CAL(&ahp->ah_temp_comp_cal_data); 3903 INSERT_CAL(ahp, &ahp->ah_temp_comp_cal_data); 3904 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3905 "%s: enabling Temperature Compensation Calibration.\n", __func__); 3906 } 3907 3908 /* Initialize current pointer to first element in list */ 3909 ahp->ah_cal_list_curr = ahp->ah_cal_list; 3910 3911 /* Reset state within current cal */ 3912 if (ahp->ah_cal_list_curr) { 3913 ar9300_reset_calibration(ah, ahp->ah_cal_list_curr); 3914 } 3915 3916 /* Mark all calibrations on this channel as being invalid */ 3917 ichan->calValid = 0; 3918 3919 return AH_TRUE; 3920 } 3921 3922 static inline HAL_BOOL 3923 ar9300_init_cal(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr) 3924 { 3925 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 3926 HAL_BOOL do_rtt_cal = AH_TRUE; 3927 HAL_BOOL enable_rtt = AH_FALSE; 3928 3929 HALASSERT(ichan); 3930 3931 return ar9300_init_cal_internal(ah, chan, ichan, enable_rtt, do_rtt_cal, skip_if_none, apply_last_iqcorr); 3932 } 3933 3934 /* ar9300_reset_cal_valid 3935 * Entry point for upper layers to restart current cal. 3936 * Reset the calibration valid bit in channel. 3937 */ 3938 void 3939 ar9300_reset_cal_valid(struct ath_hal *ah, const struct ieee80211_channel *chan, 3940 HAL_BOOL *is_cal_done, u_int32_t cal_type) 3941 { 3942 struct ath_hal_9300 *ahp = AH9300(ah); 3943 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 3944 HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr; 3945 3946 *is_cal_done = AH_TRUE; 3947 3948 if (curr_cal == AH_NULL) { 3949 return; 3950 } 3951 if (ichan == AH_NULL) { 3952 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3953 "%s: invalid channel %u/0x%x; no mapping\n", 3954 __func__, chan->ic_freq, chan->ic_flags); 3955 return; 3956 } 3957 3958 if (!(cal_type & IQ_MISMATCH_CAL)) { 3959 *is_cal_done = AH_FALSE; 3960 return; 3961 } 3962 3963 /* Expected that this calibration has run before, post-reset. 3964 * Current state should be done 3965 */ 3966 if (curr_cal->cal_state != CAL_DONE) { 3967 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3968 "%s: Calibration state incorrect, %d\n", 3969 __func__, curr_cal->cal_state); 3970 return; 3971 } 3972 3973 /* Verify Cal is supported on this channel */ 3974 if (ar9300_is_cal_supp(ah, chan, curr_cal->cal_data->cal_type) == AH_FALSE) { 3975 return; 3976 } 3977 3978 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 3979 "%s: Resetting Cal %d state for channel %u/0x%x\n", __func__, 3980 curr_cal->cal_data->cal_type, chan->ic_freq, chan->ic_flags); 3981 3982 /* Disable cal validity in channel */ 3983 ichan->calValid &= ~curr_cal->cal_data->cal_type; 3984 curr_cal->cal_state = CAL_WAITING; 3985 /* Indicate to upper layers that we need polling */ 3986 *is_cal_done = AH_FALSE; 3987 } 3988 3989 static inline void 3990 ar9300_set_dma(struct ath_hal *ah) 3991 { 3992 u_int32_t regval; 3993 struct ath_hal_9300 *ahp = AH9300(ah); 3994 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 3995 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps; 3996 3997 #if 0 3998 /* 3999 * set AHB_MODE not to do cacheline prefetches 4000 */ 4001 regval = OS_REG_READ(ah, AR_AHB_MODE); 4002 OS_REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN); 4003 #endif 4004 4005 /* 4006 * let mac dma reads be in 128 byte chunks 4007 */ 4008 regval = OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; 4009 OS_REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); 4010 4011 /* 4012 * Restore TX Trigger Level to its pre-reset value. 4013 * The initial value depends on whether aggregation is enabled, and is 4014 * adjusted whenever underruns are detected. 4015 */ 4016 /* 4017 OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, AH_PRIVATE(ah)->ah_tx_trig_level); 4018 */ 4019 /* 4020 * Osprey 1.0 bug (EV 61936). Don't change trigger level from .ini default. 4021 * Osprey 2.0 - hardware recommends using the default INI settings. 4022 */ 4023 #if 0 4024 OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, 0x3f); 4025 #endif 4026 /* 4027 * let mac dma writes be in 128 byte chunks 4028 */ 4029 regval = OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK; 4030 OS_REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B); 4031 4032 /* 4033 * Setup receive FIFO threshold to hold off TX activities 4034 */ 4035 OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); 4036 4037 /* 4038 * reduce the number of usable entries in PCU TXBUF to avoid 4039 * wrap around bugs. (bug 20428) 4040 */ 4041 4042 if (AR_SREV_WASP(ah) && 4043 (AH_PRIVATE((ah))->ah_macRev > AR_SREV_REVISION_WASP_12)) { 4044 /* Wasp 1.3 fix for EV#85395 requires usable entries 4045 * to be set to 0x500 4046 */ 4047 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 0x500); 4048 } else { 4049 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE); 4050 } 4051 4052 /* 4053 * Enable HPQ for UAPSD 4054 */ 4055 if (pCap->halHwUapsdTrig == AH_TRUE) { 4056 /* Only enable this if HAL capabilities says it is OK */ 4057 if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) { 4058 OS_REG_WRITE(ah, AR_HP_Q_CONTROL, 4059 AR_HPQ_ENABLE | AR_HPQ_UAPSD | AR_HPQ_UAPSD_TRIGGER_EN); 4060 } 4061 } else { 4062 /* use default value from ini file - which disable HPQ queue usage */ 4063 } 4064 4065 /* 4066 * set the transmit status ring 4067 */ 4068 ar9300_reset_tx_status_ring(ah); 4069 4070 /* 4071 * set rxbp threshold. Must be non-zero for RX_EOL to occur. 4072 * For Osprey 2.0+, keep the original thresholds 4073 * otherwise performance is lost due to excessive RX EOL interrupts. 4074 */ 4075 OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1); 4076 OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1); 4077 4078 /* 4079 * set receive buffer size. 4080 */ 4081 if (ahp->rx_buf_size) { 4082 OS_REG_WRITE(ah, AR_DATABUF, ahp->rx_buf_size); 4083 } 4084 } 4085 4086 static inline void 4087 ar9300_init_bb(struct ath_hal *ah, struct ieee80211_channel *chan) 4088 { 4089 u_int32_t synth_delay; 4090 4091 /* 4092 * Wait for the frequency synth to settle (synth goes on 4093 * via AR_PHY_ACTIVE_EN). Read the phy active delay register. 4094 * Value is in 100ns increments. 4095 */ 4096 synth_delay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 4097 if (IEEE80211_IS_CHAN_CCK(chan)) { 4098 synth_delay = (4 * synth_delay) / 22; 4099 } else { 4100 synth_delay /= 10; 4101 } 4102 4103 /* Activate the PHY (includes baseband activate + synthesizer on) */ 4104 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 4105 4106 /* 4107 * There is an issue if the AP starts the calibration before 4108 * the base band timeout completes. This could result in the 4109 * rx_clear false triggering. As a workaround we add delay an 4110 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition 4111 * does not happen. 4112 */ 4113 OS_DELAY(synth_delay + BASE_ACTIVATE_DELAY); 4114 } 4115 4116 static inline void 4117 ar9300_init_interrupt_masks(struct ath_hal *ah, HAL_OPMODE opmode) 4118 { 4119 struct ath_hal_9300 *ahp = AH9300(ah); 4120 u_int32_t msi_cfg = 0; 4121 u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT; 4122 4123 /* 4124 * Setup interrupt handling. Note that ar9300_reset_tx_queue 4125 * manipulates the secondary IMR's as queues are enabled 4126 * and disabled. This is done with RMW ops to insure the 4127 * settings we make here are preserved. 4128 */ 4129 ahp->ah_mask_reg = 4130 AR_IMR_TXERR | AR_IMR_TXURN | 4131 AR_IMR_RXERR | AR_IMR_RXORN | 4132 AR_IMR_BCNMISC; 4133 4134 if (ahp->ah_intr_mitigation_rx) { 4135 /* enable interrupt mitigation for rx */ 4136 ahp->ah_mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR | AR_IMR_RXOK_HP; 4137 msi_cfg |= AR_INTCFG_MSI_RXINTM | AR_INTCFG_MSI_RXMINTR; 4138 } else { 4139 ahp->ah_mask_reg |= AR_IMR_RXOK_LP | AR_IMR_RXOK_HP; 4140 msi_cfg |= AR_INTCFG_MSI_RXOK; 4141 } 4142 if (ahp->ah_intr_mitigation_tx) { 4143 /* enable interrupt mitigation for tx */ 4144 ahp->ah_mask_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR; 4145 msi_cfg |= AR_INTCFG_MSI_TXINTM | AR_INTCFG_MSI_TXMINTR; 4146 } else { 4147 ahp->ah_mask_reg |= AR_IMR_TXOK; 4148 msi_cfg |= AR_INTCFG_MSI_TXOK; 4149 } 4150 if (opmode == HAL_M_HOSTAP) { 4151 ahp->ah_mask_reg |= AR_IMR_MIB; 4152 } 4153 4154 OS_REG_WRITE(ah, AR_IMR, ahp->ah_mask_reg); 4155 OS_REG_WRITE(ah, AR_IMR_S2, OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT); 4156 ahp->ah_mask2Reg = OS_REG_READ(ah, AR_IMR_S2); 4157 4158 if (ah->ah_config.ath_hal_enable_msi) { 4159 /* Cache MSI register value */ 4160 ahp->ah_msi_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI)); 4161 ahp->ah_msi_reg |= AR_PCIE_MSI_HW_DBI_WR_EN; 4162 if (AR_SREV_POSEIDON(ah)) { 4163 ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64; 4164 } else { 4165 ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR; 4166 } 4167 /* Program MSI configuration */ 4168 OS_REG_WRITE(ah, AR_INTCFG, msi_cfg); 4169 } 4170 4171 /* 4172 * debug - enable to see all synchronous interrupts status 4173 */ 4174 /* Clear any pending sync cause interrupts */ 4175 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE), 0xFFFFFFFF); 4176 4177 /* Allow host interface sync interrupt sources to set cause bit */ 4178 if (AR_SREV_POSEIDON(ah)) { 4179 sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR; 4180 } 4181 else if (AR_SREV_WASP(ah)) { 4182 sync_en_def = AR9340_INTR_SYNC_DEFAULT; 4183 } 4184 OS_REG_WRITE(ah, 4185 AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), sync_en_def); 4186 4187 /* _Disable_ host interface sync interrupt when cause bits set */ 4188 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK), 0); 4189 4190 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE), 0); 4191 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_MASK), 0); 4192 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_ENABLE), 0); 4193 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_MASK), 0); 4194 } 4195 4196 static inline void 4197 ar9300_init_qos(struct ath_hal *ah) 4198 { 4199 OS_REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); /* XXX magic */ 4200 OS_REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); /* XXX magic */ 4201 4202 /* Turn on NOACK Support for QoS packets */ 4203 OS_REG_WRITE(ah, AR_QOS_NO_ACK, 4204 SM(2, AR_QOS_NO_ACK_TWO_BIT) | 4205 SM(5, AR_QOS_NO_ACK_BIT_OFF) | 4206 SM(0, AR_QOS_NO_ACK_BYTE_OFF)); 4207 4208 /* 4209 * initialize TXOP for all TIDs 4210 */ 4211 OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL); 4212 OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF); 4213 OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); 4214 OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); 4215 OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 4216 } 4217 4218 static inline void 4219 ar9300_init_user_settings(struct ath_hal *ah) 4220 { 4221 struct ath_hal_9300 *ahp = AH9300(ah); 4222 4223 /* Restore user-specified settings */ 4224 HALDEBUG(ah, HAL_DEBUG_RESET, 4225 "--AP %s ahp->ah_misc_mode 0x%x\n", __func__, ahp->ah_misc_mode); 4226 if (ahp->ah_misc_mode != 0) { 4227 OS_REG_WRITE(ah, 4228 AR_PCU_MISC, OS_REG_READ(ah, AR_PCU_MISC) | ahp->ah_misc_mode); 4229 } 4230 if (ahp->ah_get_plcp_hdr) { 4231 OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM); 4232 } 4233 if (ahp->ah_slot_time != (u_int) -1) { 4234 ar9300_set_slot_time(ah, ahp->ah_slot_time); 4235 } 4236 if (ahp->ah_ack_timeout != (u_int) -1) { 4237 ar9300_set_ack_timeout(ah, ahp->ah_ack_timeout); 4238 } 4239 if (AH_PRIVATE(ah)->ah_diagreg != 0) { 4240 OS_REG_SET_BIT(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); 4241 } 4242 if (ahp->ah_beacon_rssi_threshold != 0) { 4243 ar9300_set_hw_beacon_rssi_threshold(ah, ahp->ah_beacon_rssi_threshold); 4244 } 4245 #ifdef ATH_SUPPORT_DFS 4246 if (ahp->ah_cac_quiet_enabled) { 4247 ar9300_cac_tx_quiet(ah, 1); 4248 } 4249 #endif /* ATH_SUPPORT_DFS */ 4250 } 4251 4252 int 4253 ar9300_get_spur_info(struct ath_hal * ah, int *enable, int len, u_int16_t *freq) 4254 { 4255 // struct ath_hal_private *ap = AH_PRIVATE(ah); 4256 int i, j; 4257 4258 for (i = 0; i < len; i++) { 4259 freq[i] = 0; 4260 } 4261 4262 *enable = ah->ah_config.ath_hal_spur_mode; 4263 for (i = 0, j = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 4264 if (AH9300(ah)->ath_hal_spur_chans[i][0] != AR_NO_SPUR) { 4265 freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][0]; 4266 HALDEBUG(ah, HAL_DEBUG_ANI, 4267 "1. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][0]); 4268 } 4269 if (AH9300(ah)->ath_hal_spur_chans[i][1] != AR_NO_SPUR) { 4270 freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][1]; 4271 HALDEBUG(ah, HAL_DEBUG_ANI, 4272 "2. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][1]); 4273 } 4274 } 4275 4276 return 0; 4277 } 4278 4279 #define ATH_HAL_2GHZ_FREQ_MIN 20000 4280 #define ATH_HAL_2GHZ_FREQ_MAX 29999 4281 #define ATH_HAL_5GHZ_FREQ_MIN 50000 4282 #define ATH_HAL_5GHZ_FREQ_MAX 59999 4283 4284 #if 0 4285 int 4286 ar9300_set_spur_info(struct ath_hal * ah, int enable, int len, u_int16_t *freq) 4287 { 4288 struct ath_hal_private *ap = AH_PRIVATE(ah); 4289 int i, j, k; 4290 4291 ap->ah_config.ath_hal_spur_mode = enable; 4292 4293 if (ap->ah_config.ath_hal_spur_mode == SPUR_ENABLE_IOCTL) { 4294 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 4295 AH9300(ah)->ath_hal_spur_chans[i][0] = AR_NO_SPUR; 4296 AH9300(ah)->ath_hal_spur_chans[i][1] = AR_NO_SPUR; 4297 } 4298 for (i = 0, j = 0, k = 0; i < len; i++) { 4299 if (freq[i] > ATH_HAL_2GHZ_FREQ_MIN && 4300 freq[i] < ATH_HAL_2GHZ_FREQ_MAX) 4301 { 4302 /* 2GHz Spur */ 4303 if (j < AR_EEPROM_MODAL_SPURS) { 4304 AH9300(ah)->ath_hal_spur_chans[j++][1] = freq[i]; 4305 HALDEBUG(ah, HAL_DEBUG_ANI, "1 set spur %d\n", freq[i]); 4306 } 4307 } else if (freq[i] > ATH_HAL_5GHZ_FREQ_MIN && 4308 freq[i] < ATH_HAL_5GHZ_FREQ_MAX) 4309 { 4310 /* 5Ghz Spur */ 4311 if (k < AR_EEPROM_MODAL_SPURS) { 4312 AH9300(ah)->ath_hal_spur_chans[k++][0] = freq[i]; 4313 HALDEBUG(ah, HAL_DEBUG_ANI, "2 set spur %d\n", freq[i]); 4314 } 4315 } 4316 } 4317 } 4318 4319 return 0; 4320 } 4321 #endif 4322 4323 #define ar9300_check_op_mode(_opmode) \ 4324 ((_opmode == HAL_M_STA) || (_opmode == HAL_M_IBSS) ||\ 4325 (_opmode == HAL_M_HOSTAP) || (_opmode == HAL_M_MONITOR)) 4326 4327 4328 4329 4330 #ifndef ATH_NF_PER_CHAN 4331 /* 4332 * To fixed first reset noise floor value not correct issue 4333 * For ART need it to fixed low rate sens too low issue 4334 */ 4335 static int 4336 First_NFCal(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan, 4337 int is_scan, struct ieee80211_channel *chan) 4338 { 4339 HAL_NFCAL_HIST_FULL *nfh; 4340 int i, j, k; 4341 int16_t nfarray[HAL_NUM_NF_READINGS] = {0}; 4342 int is_2g = 0; 4343 int nf_hist_len; 4344 int stats = 0; 4345 4346 int16_t nf_buf[HAL_NUM_NF_READINGS]; 4347 #define IS(_c, _f) (((_c)->channel_flags & _f) || 0) 4348 4349 4350 if ((!is_scan) && 4351 chan->ic_freq == AH_PRIVATE(ah)->ah_curchan->ic_freq) 4352 { 4353 nfh = &AH_PRIVATE(ah)->nf_cal_hist; 4354 } else { 4355 nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist; 4356 } 4357 4358 ar9300_start_nf_cal(ah); 4359 for (j = 0; j < 10000; j++) { 4360 if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){ 4361 break; 4362 } 4363 OS_DELAY(10); 4364 } 4365 if (j < 10000) { 4366 is_2g = IEEE80211_IS_CHAN_2GHZ(chan); 4367 ar9300_upload_noise_floor(ah, is_2g, nfarray); 4368 4369 if (is_scan) { 4370 /* 4371 * This channel's NF cal info is just a HAL_NFCAL_HIST_SMALL struct 4372 * rather than a HAL_NFCAL_HIST_FULL struct. 4373 * As long as we only use the first history element of nf_cal_buffer 4374 * (nf_cal_buffer[0][0:HAL_NUM_NF_READINGS-1]), we can use 4375 * HAL_NFCAL_HIST_SMALL and HAL_NFCAL_HIST_FULL interchangeably. 4376 */ 4377 nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist; 4378 nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL; 4379 } else { 4380 nfh = &AH_PRIVATE(ah)->nf_cal_hist; 4381 nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL; 4382 } 4383 4384 for (i = 0; i < HAL_NUM_NF_READINGS; i ++) { 4385 for (k = 0; k < HAL_NF_CAL_HIST_LEN_FULL; k++) { 4386 nfh->nf_cal_buffer[k][i] = nfarray[i]; 4387 } 4388 nfh->base.priv_nf[i] = ar9300_limit_nf_range(ah, 4389 ar9300_get_nf_hist_mid(ah, nfh, i, nf_hist_len)); 4390 } 4391 4392 4393 //ar9300StoreNewNf(ah, ichan, is_scan); 4394 4395 /* 4396 * See if the NF value from the old channel should be 4397 * retained when switching to a new channel. 4398 * TBD: this may need to be changed, as it wipes out the 4399 * purpose of saving NF values for each channel. 4400 */ 4401 for (i = 0; i < HAL_NUM_NF_READINGS; i++) 4402 { 4403 if (IEEE80211_IS_CHAN_2GHZ(chan)) 4404 { 4405 if (nfh->nf_cal_buffer[0][i] < 4406 AR_PHY_CCA_MAX_GOOD_VAL_OSPREY_2GHZ) 4407 { 4408 ichan->nf_cal_hist.nf_cal_buffer[0][i] = 4409 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i]; 4410 } 4411 } else { 4412 if (AR_SREV_AR9580(ah)) { 4413 if (nfh->nf_cal_buffer[0][i] < 4414 AR_PHY_CCA_NOM_VAL_PEACOCK_5GHZ) 4415 { 4416 ichan->nf_cal_hist.nf_cal_buffer[0][i] = 4417 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i]; 4418 } 4419 } else { 4420 if (nfh->nf_cal_buffer[0][i] < 4421 AR_PHY_CCA_NOM_VAL_OSPREY_5GHZ) 4422 { 4423 ichan->nf_cal_hist.nf_cal_buffer[0][i] = 4424 AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i]; 4425 } 4426 } 4427 } 4428 } 4429 /* 4430 * Copy the channel's NF buffer, which may have been modified 4431 * just above here, to the full NF history buffer. 4432 */ 4433 ar9300_reset_nf_hist_buff(ah, ichan); 4434 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf); 4435 ar9300_load_nf(ah, nf_buf); 4436 stats = 0; 4437 } else { 4438 stats = 1; 4439 } 4440 #undef IS 4441 return stats; 4442 } 4443 #endif 4444 4445 4446 /* 4447 * Places the device in and out of reset and then places sane 4448 * values in the registers based on EEPROM config, initialization 4449 * vectors (as determined by the mode), and station configuration 4450 * 4451 * b_channel_change is used to preserve DMA/PCU registers across 4452 * a HW Reset during channel change. 4453 */ 4454 HAL_BOOL 4455 ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan, 4456 HAL_HT_MACMODE macmode, u_int8_t txchainmask, u_int8_t rxchainmask, 4457 HAL_HT_EXTPROTSPACING extprotspacing, HAL_BOOL b_channel_change, 4458 HAL_STATUS *status, int is_scan) 4459 { 4460 #define FAIL(_code) do { ecode = _code; goto bad; } while (0) 4461 u_int32_t save_led_state; 4462 struct ath_hal_9300 *ahp = AH9300(ah); 4463 struct ath_hal_private *ap = AH_PRIVATE(ah); 4464 HAL_CHANNEL_INTERNAL *ichan; 4465 //const struct ieee80211_channel *curchan = ap->ah_curchan; 4466 #if ATH_SUPPORT_MCI 4467 HAL_BOOL save_full_sleep = ahp->ah_chip_full_sleep; 4468 #endif 4469 u_int32_t save_def_antenna; 4470 u_int32_t mac_sta_id1; 4471 HAL_STATUS ecode; 4472 int i, rx_chainmask; 4473 int nf_hist_buff_reset = 0; 4474 int16_t nf_buf[HAL_NUM_NF_READINGS]; 4475 #ifdef ATH_FORCE_PPM 4476 u_int32_t save_force_val, tmp_reg; 4477 #endif 4478 u_int8_t clk_25mhz = AH9300(ah)->clk_25mhz; 4479 HAL_BOOL stopped, cal_ret; 4480 HAL_BOOL apply_last_iqcorr = AH_FALSE; 4481 4482 4483 if (OS_REG_READ(ah, AR_IER) == AR_IER_ENABLE) { 4484 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "** Reset called with WLAN " 4485 "interrupt enabled %08x **\n", ar9300_get_interrupts(ah)); 4486 } 4487 4488 /* 4489 * Set the status to "ok" by default to cover the cases 4490 * where we return false without going to "bad" 4491 */ 4492 HALASSERT(status); 4493 *status = HAL_OK; 4494 if ((ah->ah_config.ath_hal_sta_update_tx_pwr_enable)) { 4495 AH9300(ah)->green_tx_status = HAL_RSSI_TX_POWER_NONE; 4496 } 4497 4498 #if ATH_SUPPORT_MCI 4499 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && 4500 (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah))) 4501 { 4502 ar9300_mci_2g5g_changed(ah, IEEE80211_IS_CHAN_2GHZ(chan)); 4503 } 4504 #endif 4505 4506 ahp->ah_ext_prot_spacing = extprotspacing; 4507 ahp->ah_tx_chainmask = txchainmask & ap->ah_caps.halTxChainMask; 4508 ahp->ah_rx_chainmask = rxchainmask & ap->ah_caps.halRxChainMask; 4509 ahp->ah_tx_cal_chainmask = ap->ah_caps.halTxChainMask; 4510 ahp->ah_rx_cal_chainmask = ap->ah_caps.halRxChainMask; 4511 4512 /* 4513 * Keep the previous optinal txchainmask value 4514 */ 4515 4516 HALASSERT(ar9300_check_op_mode(opmode)); 4517 4518 OS_MARK(ah, AH_MARK_RESET, b_channel_change); 4519 4520 /* 4521 * Map public channel to private. 4522 */ 4523 ichan = ar9300_check_chan(ah, chan); 4524 if (ichan == AH_NULL) { 4525 HALDEBUG(ah, HAL_DEBUG_CHANNEL, 4526 "%s: invalid channel %u/0x%x; no mapping\n", 4527 __func__, chan->ic_freq, chan->ic_flags); 4528 FAIL(HAL_EINVAL); 4529 } 4530 4531 ichan->paprd_table_write_done = 0; /* Clear PAPRD table write flag */ 4532 #if 0 4533 chan->paprd_table_write_done = 0; /* Clear PAPRD table write flag */ 4534 #endif 4535 4536 if (ar9300_get_power_mode(ah) != HAL_PM_FULL_SLEEP) { 4537 /* Need to stop RX DMA before reset otherwise chip might hang */ 4538 stopped = ar9300_set_rx_abort(ah, AH_TRUE); /* abort and disable PCU */ 4539 ar9300_set_rx_filter(ah, 0); 4540 stopped &= ar9300_stop_dma_receive(ah, 0); /* stop and disable RX DMA */ 4541 if (!stopped) { 4542 /* 4543 * During the transition from full sleep to reset, 4544 * recv DMA regs are not available to be read 4545 */ 4546 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 4547 "%s[%d]: ar9300_stop_dma_receive failed\n", __func__, __LINE__); 4548 b_channel_change = AH_FALSE; 4549 } 4550 } else { 4551 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 4552 "%s[%d]: Chip is already in full sleep\n", __func__, __LINE__); 4553 } 4554 4555 #if ATH_SUPPORT_MCI 4556 if ((AH_PRIVATE(ah)->ah_caps.halMciSupport) && 4557 (ahp->ah_mci_bt_state == MCI_BT_CAL_START)) 4558 { 4559 u_int32_t payload[4] = {0, 0, 0, 0}; 4560 4561 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 4562 "(MCI) %s: Stop rx for BT cal.\n", __func__); 4563 ahp->ah_mci_bt_state = MCI_BT_CAL; 4564 4565 /* 4566 * MCIFIX: disable mci interrupt here. This is to avoid SW_MSG_DONE or 4567 * RX_MSG bits to trigger MCI_INT and lead to mci_intr reentry. 4568 */ 4569 ar9300_mci_disable_interrupt(ah); 4570 4571 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 4572 "(MCI) %s: Send WLAN_CAL_GRANT\n", __func__); 4573 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT); 4574 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE); 4575 4576 /* Wait BT calibration to be completed for 25ms */ 4577 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 4578 "(MCI) %s: BT is calibrating.\n", __func__); 4579 if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE, 0, 25000)) { 4580 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 4581 "(MCI) %s: Got BT_CAL_DONE.\n", __func__); 4582 } 4583 else { 4584 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 4585 "(MCI) %s: ### BT cal takes too long. Force bt_state to be bt_awake.\n", 4586 __func__); 4587 } 4588 ahp->ah_mci_bt_state = MCI_BT_AWAKE; 4589 /* MCIFIX: enable mci interrupt here */ 4590 ar9300_mci_enable_interrupt(ah); 4591 4592 return AH_TRUE; 4593 } 4594 #endif 4595 4596 /* Bring out of sleep mode */ 4597 if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) { 4598 *status = HAL_INV_PMODE; 4599 return AH_FALSE; 4600 } 4601 4602 /* Check the Rx mitigation config again, it might have changed 4603 * during attach in ath_vap_attach. 4604 */ 4605 if (ah->ah_config.ath_hal_intr_mitigation_rx != 0) { 4606 ahp->ah_intr_mitigation_rx = AH_TRUE; 4607 } else { 4608 ahp->ah_intr_mitigation_rx = AH_FALSE; 4609 } 4610 4611 /* 4612 * XXX TODO FreeBSD: 4613 * 4614 * This is painful because we don't have a non-const channel pointer 4615 * at this stage. 4616 * 4617 * Make sure this gets fixed! 4618 */ 4619 #if 0 4620 /* Get the value from the previous NF cal and update history buffer */ 4621 if (curchan && (ahp->ah_chip_full_sleep != AH_TRUE)) { 4622 4623 if(ahp->ah_chip_reset_done){ 4624 ahp->ah_chip_reset_done = 0; 4625 } else { 4626 /* 4627 * is_scan controls updating NF for home channel or off channel. 4628 * Home -> Off, update home channel 4629 * Off -> Home, update off channel 4630 * Home -> Home, uppdate home channel 4631 */ 4632 if (ap->ah_curchan->channel != chan->channel) 4633 ar9300_store_new_nf(ah, curchan, !is_scan); 4634 else 4635 ar9300_store_new_nf(ah, curchan, is_scan); 4636 } 4637 } 4638 #endif 4639 4640 /* 4641 * Account for the effect of being in either the 2 GHz or 5 GHz band 4642 * on the nominal, max allowable, and min allowable noise floor values. 4643 */ 4644 AH9300(ah)->nfp = IS_CHAN_2GHZ(ichan) ? &ahp->nf_2GHz : &ahp->nf_5GHz; 4645 4646 /* 4647 * XXX FreeBSD For now, don't apply the last IQ correction. 4648 * 4649 * This should be done when scorpion is enabled on FreeBSD; just be 4650 * sure to fix this channel match code so it uses net80211 flags 4651 * instead. 4652 */ 4653 #if 0 4654 if (AR_SREV_SCORPION(ah) && curchan && (chan->channel == curchan->channel) && 4655 ((chan->channel_flags & (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)) == 4656 (curchan->channel_flags & 4657 (CHANNEL_ALL | CHANNEL_HALF | CHANNEL_QUARTER)))) { 4658 apply_last_iqcorr = AH_TRUE; 4659 } 4660 #endif 4661 apply_last_iqcorr = AH_FALSE; 4662 4663 4664 #ifndef ATH_NF_PER_CHAN 4665 /* 4666 * If there's only one full-size home-channel NF history buffer 4667 * rather than a full-size NF history buffer per channel, decide 4668 * whether to (re)initialize the home-channel NF buffer. 4669 * If this is just a channel change for a scan, or if the channel 4670 * is not being changed, don't mess up the home channel NF history 4671 * buffer with NF values from this scanned channel. If we're 4672 * changing the home channel to a new channel, reset the home-channel 4673 * NF history buffer with the most accurate NF known for the new channel. 4674 */ 4675 if (!is_scan && (!ap->ah_curchan || 4676 ap->ah_curchan->ic_freq != chan->ic_freq)) // || 4677 // ap->ah_curchan->channel_flags != chan->channel_flags)) 4678 { 4679 nf_hist_buff_reset = 1; 4680 ar9300_reset_nf_hist_buff(ah, ichan); 4681 } 4682 #endif 4683 /* 4684 * In case of 4685 * - offchan scan, or 4686 * - same channel and RX IQ Cal already available 4687 * disable RX IQ Cal. 4688 */ 4689 if (is_scan) { 4690 ahp->ah_skip_rx_iq_cal = AH_TRUE; 4691 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 4692 "Skip RX IQ Cal due to scanning\n"); 4693 } else { 4694 #if 0 4695 /* XXX FreeBSD: always just do the RX IQ cal */ 4696 /* XXX I think it's just going to speed things up; I don't think it's to avoid chan bugs */ 4697 if (ahp->ah_rx_cal_complete && 4698 ahp->ah_rx_cal_chan == ichan->channel && 4699 ahp->ah_rx_cal_chan_flag == chan->channel_flags) { 4700 ahp->ah_skip_rx_iq_cal = AH_TRUE; 4701 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 4702 "Skip RX IQ Cal due to same channel with completed RX IQ Cal\n"); 4703 } else 4704 #endif 4705 ahp->ah_skip_rx_iq_cal = AH_FALSE; 4706 } 4707 4708 /* FreeBSD: clear the channel survey data */ 4709 ath_hal_survey_clear(ah); 4710 4711 /* 4712 * Fast channel change (Change synthesizer based on channel freq 4713 * without resetting chip) 4714 * Don't do it when 4715 * - Flag is not set 4716 * - Chip is just coming out of full sleep 4717 * - Channel to be set is same as current channel 4718 * - Channel flags are different, like when moving from 2GHz to 5GHz 4719 * channels 4720 * - Merlin: Switching in/out of fast clock enabled channels 4721 * (not currently coded, since fast clock is enabled 4722 * across the 5GHz band 4723 * and we already do a full reset when switching in/out 4724 * of 5GHz channels) 4725 */ 4726 #if 0 4727 if (b_channel_change && 4728 (ahp->ah_chip_full_sleep != AH_TRUE) && 4729 (AH_PRIVATE(ah)->ah_curchan != AH_NULL) && 4730 ((chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) && 4731 (((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & chan->channel_flags) == 4732 ((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & AH_PRIVATE(ah)->ah_curchan->channel_flags)))) 4733 { 4734 if (ar9300_channel_change(ah, chan, ichan, macmode)) { 4735 chan->channel_flags = ichan->channel_flags; 4736 chan->priv_flags = ichan->priv_flags; 4737 AH_PRIVATE(ah)->ah_curchan->ah_channel_time = 0; 4738 AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar9300_get_tsf64(ah); 4739 4740 /* 4741 * Load the NF from history buffer of the current channel. 4742 * NF is slow time-variant, so it is OK to use a historical value. 4743 */ 4744 ar9300_get_nf_hist_base(ah, 4745 AH_PRIVATE(ah)->ah_curchan, is_scan, nf_buf); 4746 ar9300_load_nf(ah, nf_buf); 4747 4748 /* start NF calibration, without updating BB NF register*/ 4749 ar9300_start_nf_cal(ah); 4750 4751 /* 4752 * If channel_change completed and DMA was stopped 4753 * successfully - skip the rest of reset 4754 */ 4755 if (AH9300(ah)->ah_dma_stuck != AH_TRUE) { 4756 WAR_USB_DISABLE_PLL_LOCK_DETECT(ah); 4757 #if ATH_SUPPORT_MCI 4758 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) 4759 { 4760 ar9300_mci_2g5g_switch(ah, AH_TRUE); 4761 } 4762 #endif 4763 return HAL_OK; 4764 } 4765 } 4766 } 4767 #endif /* #if 0 */ 4768 4769 #if ATH_SUPPORT_MCI 4770 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) { 4771 ar9300_mci_disable_interrupt(ah); 4772 if (ahp->ah_mci_ready && !save_full_sleep) { 4773 ar9300_mci_mute_bt(ah); 4774 OS_DELAY(20); 4775 OS_REG_WRITE(ah, AR_BTCOEX_CTRL, 0); 4776 } 4777 4778 ahp->ah_mci_bt_state = MCI_BT_SLEEP; 4779 ahp->ah_mci_ready = AH_FALSE; 4780 } 4781 #endif 4782 4783 AH9300(ah)->ah_dma_stuck = AH_FALSE; 4784 #ifdef ATH_FORCE_PPM 4785 /* Preserve force ppm state */ 4786 save_force_val = 4787 OS_REG_READ(ah, AR_PHY_TIMING2) & 4788 (AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL); 4789 #endif 4790 /* 4791 * Preserve the antenna on a channel change 4792 */ 4793 save_def_antenna = OS_REG_READ(ah, AR_DEF_ANTENNA); 4794 if (0 == ahp->ah_smartantenna_enable ) 4795 { 4796 if (save_def_antenna == 0) { 4797 save_def_antenna = 1; 4798 } 4799 } 4800 4801 /* Save hardware flag before chip reset clears the register */ 4802 mac_sta_id1 = OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; 4803 4804 /* Save led state from pci config register */ 4805 save_led_state = OS_REG_READ(ah, AR_CFG_LED) & 4806 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | 4807 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW); 4808 4809 /* Mark PHY inactive prior to reset, to be undone in ar9300_init_bb () */ 4810 ar9300_mark_phy_inactive(ah); 4811 4812 if (!ar9300_chip_reset(ah, chan)) { 4813 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: chip reset failed\n", __func__); 4814 FAIL(HAL_EIO); 4815 } 4816 4817 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 4818 4819 4820 /* Disable JTAG */ 4821 OS_REG_SET_BIT(ah, 4822 AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE); 4823 4824 /* 4825 * Note that ar9300_init_chain_masks() is called from within 4826 * ar9300_process_ini() to ensure the swap bit is set before 4827 * the pdadc table is written. 4828 */ 4829 ecode = ar9300_process_ini(ah, chan, ichan, macmode); 4830 if (ecode != HAL_OK) { 4831 goto bad; 4832 } 4833 4834 /* 4835 * Configuring WMAC PLL values for 25/40 MHz 4836 */ 4837 if(AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah) || AR_SREV_SCORPION(ah) ) { 4838 if(clk_25mhz) { 4839 OS_REG_WRITE(ah, AR_RTC_DERIVED_RTC_CLK, (0x17c << 1)); // 32KHz sleep clk 4840 } else { 4841 OS_REG_WRITE(ah, AR_RTC_DERIVED_RTC_CLK, (0x261 << 1)); // 32KHz sleep clk 4842 } 4843 OS_DELAY(100); 4844 } 4845 4846 ahp->ah_immunity_on = AH_FALSE; 4847 4848 if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) { 4849 ahp->tx_iq_cal_enable = OS_REG_READ_FIELD(ah, 4850 AR_PHY_TX_IQCAL_CONTROL_0(ah), 4851 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL) ? 4852 1 : 0; 4853 } 4854 ahp->tx_cl_cal_enable = (OS_REG_READ(ah, AR_PHY_CL_CAL_CTL) & 4855 AR_PHY_CL_CAL_ENABLE) ? 1 : 0; 4856 4857 /* For devices with full HW RIFS Rx support (Sowl/Howl/Merlin, etc), 4858 * restore register settings from prior to reset. 4859 */ 4860 if ((AH_PRIVATE(ah)->ah_curchan != AH_NULL) && 4861 (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK)) 4862 { 4863 /* Re-program RIFS Rx policy after reset */ 4864 ar9300_set_rifs_delay(ah, ahp->ah_rifs_enabled); 4865 } 4866 4867 #if ATH_SUPPORT_MCI 4868 if (AH_PRIVATE(ah)->ah_caps.halMciSupport) { 4869 ar9300_mci_reset(ah, AH_FALSE, IS_CHAN_2GHZ(ichan), save_full_sleep); 4870 } 4871 #endif 4872 4873 /* Initialize Management Frame Protection */ 4874 ar9300_init_mfp(ah); 4875 4876 ahp->ah_immunity_vals[0] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW, 4877 AR_PHY_SFCORR_LOW_M1_THRESH_LOW); 4878 ahp->ah_immunity_vals[1] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW, 4879 AR_PHY_SFCORR_LOW_M2_THRESH_LOW); 4880 ahp->ah_immunity_vals[2] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR, 4881 AR_PHY_SFCORR_M1_THRESH); 4882 ahp->ah_immunity_vals[3] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR, 4883 AR_PHY_SFCORR_M2_THRESH); 4884 ahp->ah_immunity_vals[4] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR, 4885 AR_PHY_SFCORR_M2COUNT_THR); 4886 ahp->ah_immunity_vals[5] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW, 4887 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW); 4888 4889 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 4890 if (IEEE80211_IS_CHAN_OFDM(chan) || IEEE80211_IS_CHAN_HT(chan)) { 4891 ar9300_set_delta_slope(ah, chan); 4892 } 4893 4894 ar9300_spur_mitigate(ah, chan); 4895 if (!ar9300_eeprom_set_board_values(ah, chan)) { 4896 HALDEBUG(ah, HAL_DEBUG_EEPROM, 4897 "%s: error setting board options\n", __func__); 4898 FAIL(HAL_EIO); 4899 } 4900 4901 #ifdef ATH_HAL_WAR_REG16284_APH128 4902 /* temp work around, will be removed. */ 4903 if (AR_SREV_WASP(ah)) { 4904 OS_REG_WRITE(ah, 0x16284, 0x1553e000); 4905 } 4906 #endif 4907 4908 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 4909 4910 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr)); 4911 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4) 4912 | mac_sta_id1 4913 | AR_STA_ID1_RTS_USE_DEF 4914 | (ah->ah_config.ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0) 4915 | ahp->ah_sta_id1_defaults 4916 ); 4917 ar9300_set_operating_mode(ah, opmode); 4918 4919 /* Set Venice BSSID mask according to current state */ 4920 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssid_mask)); 4921 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssid_mask + 4)); 4922 4923 /* Restore previous antenna */ 4924 OS_REG_WRITE(ah, AR_DEF_ANTENNA, save_def_antenna); 4925 #ifdef ATH_FORCE_PPM 4926 /* Restore force ppm state */ 4927 tmp_reg = OS_REG_READ(ah, AR_PHY_TIMING2) & 4928 ~(AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL); 4929 OS_REG_WRITE(ah, AR_PHY_TIMING2, tmp_reg | save_force_val); 4930 #endif 4931 4932 /* then our BSSID and assocID */ 4933 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 4934 OS_REG_WRITE(ah, AR_BSS_ID1, 4935 LE_READ_2(ahp->ah_bssid + 4) | 4936 ((ahp->ah_assoc_id & 0x3fff) << AR_BSS_ID1_AID_S)); 4937 4938 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */ 4939 4940 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, INIT_RSSI_THR); 4941 4942 /* HW beacon processing */ 4943 /* 4944 * XXX what happens if I just leave filter_interval=0? 4945 * it stays disabled? 4946 */ 4947 OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_BCN_WEIGHT, 4948 INIT_RSSI_BEACON_WEIGHT); 4949 OS_REG_SET_BIT(ah, AR_HWBCNPROC1, AR_HWBCNPROC1_CRC_ENABLE | 4950 AR_HWBCNPROC1_EXCLUDE_TIM_ELM); 4951 if (ah->ah_config.ath_hal_beacon_filter_interval) { 4952 OS_REG_RMW_FIELD(ah, AR_HWBCNPROC2, AR_HWBCNPROC2_FILTER_INTERVAL, 4953 ah->ah_config.ath_hal_beacon_filter_interval); 4954 OS_REG_SET_BIT(ah, AR_HWBCNPROC2, 4955 AR_HWBCNPROC2_FILTER_INTERVAL_ENABLE); 4956 } 4957 4958 4959 /* 4960 * Set Channel now modifies bank 6 parameters for FOWL workaround 4961 * to force rf_pwd_icsyndiv bias current as function of synth 4962 * frequency.Thus must be called after ar9300_process_ini() to ensure 4963 * analog register cache is valid. 4964 */ 4965 if (!ahp->ah_rf_hal.set_channel(ah, chan)) { 4966 FAIL(HAL_EIO); 4967 } 4968 4969 4970 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 4971 4972 /* Set 1:1 QCU to DCU mapping for all queues */ 4973 for (i = 0; i < AR_NUM_DCU; i++) { 4974 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 4975 } 4976 4977 ahp->ah_intr_txqs = 0; 4978 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) { 4979 ar9300_reset_tx_queue(ah, i); 4980 } 4981 4982 ar9300_init_interrupt_masks(ah, opmode); 4983 4984 /* Reset ier reference count to disabled */ 4985 // OS_ATOMIC_SET(&ahp->ah_ier_ref_count, 1); 4986 if (ath_hal_isrfkillenabled(ah)) { 4987 ar9300_enable_rf_kill(ah); 4988 } 4989 4990 /* must be called AFTER ini is processed */ 4991 ar9300_ani_init_defaults(ah, macmode); 4992 4993 ar9300_init_qos(ah); 4994 4995 ar9300_init_user_settings(ah); 4996 4997 4998 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */ 4999 5000 OS_MARK(ah, AH_MARK_RESET_DONE, 0); 5001 5002 /* 5003 * disable seq number generation in hw 5004 */ 5005 OS_REG_WRITE(ah, AR_STA_ID1, 5006 OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); 5007 5008 ar9300_set_dma(ah); 5009 5010 /* 5011 * program OBS bus to see MAC interrupts 5012 */ 5013 #if ATH_SUPPORT_MCI 5014 if (!AH_PRIVATE(ah)->ah_caps.halMciSupport) { 5015 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8); 5016 } 5017 #else 5018 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8); 5019 #endif 5020 5021 5022 /* enabling AR_GTTM_IGNORE_IDLE in GTTM register so that 5023 GTT timer will not increment if the channel idle indicates 5024 the air is busy or NAV is still counting down */ 5025 OS_REG_WRITE(ah, AR_GTTM, AR_GTTM_IGNORE_IDLE); 5026 5027 /* 5028 * GTT debug mode setting 5029 */ 5030 /* 5031 OS_REG_WRITE(ah, 0x64, 0x00320000); 5032 OS_REG_WRITE(ah, 0x68, 7); 5033 OS_REG_WRITE(ah, 0x4080, 0xC); 5034 */ 5035 /* 5036 * Disable general interrupt mitigation by setting MIRT = 0x0 5037 * Rx and tx interrupt mitigation are conditionally enabled below. 5038 */ 5039 OS_REG_WRITE(ah, AR_MIRT, 0); 5040 if (ahp->ah_intr_mitigation_rx) { 5041 /* 5042 * Enable Interrupt Mitigation for Rx. 5043 * If no build-specific limits for the rx interrupt mitigation 5044 * timer have been specified, use conservative defaults. 5045 */ 5046 #ifndef AH_RIMT_VAL_LAST 5047 #define AH_RIMT_LAST_MICROSEC 500 5048 #endif 5049 #ifndef AH_RIMT_VAL_FIRST 5050 #define AH_RIMT_FIRST_MICROSEC 2000 5051 #endif 5052 #ifndef HOST_OFFLOAD 5053 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, AH_RIMT_LAST_MICROSEC); 5054 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, AH_RIMT_FIRST_MICROSEC); 5055 #else 5056 /* lower mitigation level to reduce latency for offload arch. */ 5057 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 5058 (AH_RIMT_LAST_MICROSEC >> 2)); 5059 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 5060 (AH_RIMT_FIRST_MICROSEC >> 2)); 5061 #endif 5062 } 5063 5064 if (ahp->ah_intr_mitigation_tx) { 5065 /* 5066 * Enable Interrupt Mitigation for Tx. 5067 * If no build-specific limits for the tx interrupt mitigation 5068 * timer have been specified, use the values preferred for 5069 * the carrier group's products. 5070 */ 5071 #ifndef AH_TIMT_LAST 5072 #define AH_TIMT_LAST_MICROSEC 300 5073 #endif 5074 #ifndef AH_TIMT_FIRST 5075 #define AH_TIMT_FIRST_MICROSEC 750 5076 #endif 5077 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, AH_TIMT_LAST_MICROSEC); 5078 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, AH_TIMT_FIRST_MICROSEC); 5079 } 5080 5081 rx_chainmask = ahp->ah_rx_chainmask; 5082 5083 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 5084 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 5085 5086 ar9300_init_bb(ah, chan); 5087 5088 /* BB Step 7: Calibration */ 5089 /* 5090 * Only kick off calibration not on offchan. 5091 * If coming back from offchan, restore prevous Cal results 5092 * since chip reset will clear existings. 5093 */ 5094 if (!ahp->ah_skip_rx_iq_cal) { 5095 int i; 5096 /* clear existing RX cal data */ 5097 for (i=0; i<AR9300_MAX_CHAINS; i++) 5098 ahp->ah_rx_cal_corr[i] = 0; 5099 5100 ahp->ah_rx_cal_complete = AH_FALSE; 5101 // ahp->ah_rx_cal_chan = chan->channel; 5102 // ahp->ah_rx_cal_chan_flag = ichan->channel_flags; 5103 ahp->ah_rx_cal_chan = 0; 5104 ahp->ah_rx_cal_chan_flag = 0; /* XXX FreeBSD */ 5105 } 5106 ar9300_invalidate_saved_cals(ah, ichan); 5107 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr); 5108 5109 #if ATH_SUPPORT_MCI 5110 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) { 5111 if (IS_CHAN_2GHZ(ichan) && 5112 (ahp->ah_mci_bt_state == MCI_BT_SLEEP)) 5113 { 5114 if (ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) || 5115 ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) 5116 { 5117 /* 5118 * BT is sleeping. Check if BT wakes up duing WLAN 5119 * calibration. If BT wakes up during WLAN calibration, need 5120 * to go through all message exchanges again and recal. 5121 */ 5122 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 5123 "(MCI) ### %s: BT wakes up during WLAN calibration.\n", 5124 __func__); 5125 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, 5126 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | 5127 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE); 5128 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) send REMOTE_RESET\n"); 5129 ar9300_mci_remote_reset(ah, AH_TRUE); 5130 ar9300_mci_send_sys_waking(ah, AH_TRUE); 5131 OS_DELAY(1); 5132 if (IS_CHAN_2GHZ(ichan)) { 5133 ar9300_mci_send_lna_transfer(ah, AH_TRUE); 5134 } 5135 ahp->ah_mci_bt_state = MCI_BT_AWAKE; 5136 5137 /* Redo calibration */ 5138 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Re-calibrate.\n", 5139 __func__); 5140 ar9300_invalidate_saved_cals(ah, ichan); 5141 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr); 5142 } 5143 } 5144 ar9300_mci_enable_interrupt(ah); 5145 } 5146 #endif 5147 5148 if (!cal_ret) { 5149 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Init Cal Failed\n", __func__); 5150 FAIL(HAL_ESELFTEST); 5151 } 5152 5153 ar9300_init_txbf(ah); 5154 #if 0 5155 /* 5156 * WAR for owl 1.0 - restore chain mask for 2-chain cfgs after cal 5157 */ 5158 rx_chainmask = ahp->ah_rx_chainmask; 5159 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { 5160 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 5161 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 5162 } 5163 #endif 5164 5165 /* Restore previous led state */ 5166 OS_REG_WRITE(ah, AR_CFG_LED, save_led_state | AR_CFG_SCLK_32KHZ); 5167 5168 #if ATH_BT_COEX 5169 if (ahp->ah_bt_coex_config_type != HAL_BT_COEX_CFG_NONE) { 5170 ar9300_init_bt_coex(ah); 5171 5172 #if ATH_SUPPORT_MCI 5173 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) { 5174 /* Check BT state again to make sure it's not changed. */ 5175 ar9300_mci_sync_bt_state(ah); 5176 ar9300_mci_2g5g_switch(ah, AH_TRUE); 5177 5178 if ((ahp->ah_mci_bt_state == MCI_BT_AWAKE) && 5179 (ahp->ah_mci_query_bt == AH_TRUE)) 5180 { 5181 ahp->ah_mci_need_flush_btinfo = AH_TRUE; 5182 } 5183 } 5184 #endif 5185 } 5186 #endif 5187 5188 /* Start TSF2 for generic timer 8-15. */ 5189 ar9300_start_tsf2(ah); 5190 5191 /* MIMO Power save setting */ 5192 if (ar9300_get_capability(ah, HAL_CAP_DYNAMIC_SMPS, 0, AH_NULL) == HAL_OK) { 5193 ar9300_set_sm_power_mode(ah, ahp->ah_sm_power_mode); 5194 } 5195 5196 /* 5197 * For big endian systems turn on swapping for descriptors 5198 */ 5199 #if AH_BYTE_ORDER == AH_BIG_ENDIAN 5200 if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) { 5201 OS_REG_RMW(ah, AR_CFG, AR_CFG_SWTB | AR_CFG_SWRB, 0); 5202 } else { 5203 ar9300_init_cfg_reg(ah); 5204 } 5205 #endif 5206 5207 if ( AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah) ) { 5208 OS_REG_RMW(ah, AR_CFG_LED, AR_CFG_LED_ASSOC_CTL, AR_CFG_LED_ASSOC_CTL); 5209 } 5210 5211 #if !(defined(ART_BUILD)) && defined(ATH_SUPPORT_LED) 5212 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val); 5213 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg)) 5214 #define ATH_GPIO_OUT_FUNCTION3 0xB8040038 5215 #define ATH_GPIO_OE 0xB8040000 5216 if ( AR_SREV_WASP(ah)) { 5217 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) { 5218 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x33 << 8) ); 5219 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) ))); 5220 } 5221 else { 5222 5223 /* Disable 2G WLAN LED. During ath_open, reset function is called even before channel is set. 5224 So 2GHz is taken as default and it also blinks. Hence 5225 to avoid both from blinking, disable 2G led while in 5G mode */ 5226 5227 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) | (1 << 13) )); 5228 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x33) ); 5229 REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) ))); 5230 } 5231 5232 } 5233 else if (AR_SREV_SCORPION(ah)) { 5234 if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) { 5235 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x2F << 8) ); 5236 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )) | (0x1 << 12))); 5237 } else if (IS_CHAN_5GHZ((AH_PRIVATE(ah)->ah_curchan))) { 5238 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x2F) ); 5239 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )) | (0x1 << 13))); 5240 } 5241 } 5242 else if (AR_SREV_HONEYBEE(ah)) { 5243 REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x32) ); 5244 REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )))); 5245 } 5246 #undef REG_READ 5247 #undef REG_WRITE 5248 #endif 5249 5250 /* XXX FreeBSD What's this? -adrian */ 5251 #if 0 5252 chan->channel_flags = ichan->channel_flags; 5253 chan->priv_flags = ichan->priv_flags; 5254 #endif 5255 5256 #if FIX_NOISE_FLOOR 5257 /* XXX FreeBSD is ichan appropariate? It was curchan.. */ 5258 ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf); 5259 ar9300_load_nf(ah, nf_buf); 5260 if (nf_hist_buff_reset == 1) 5261 { 5262 nf_hist_buff_reset = 0; 5263 #ifndef ATH_NF_PER_CHAN 5264 if (First_NFCal(ah, ichan, is_scan, chan)){ 5265 if (ahp->ah_skip_rx_iq_cal && !is_scan) { 5266 /* restore RX Cal result if existing */ 5267 ar9300_rx_iq_cal_restore(ah); 5268 ahp->ah_skip_rx_iq_cal = AH_FALSE; 5269 } 5270 } 5271 #endif /* ATH_NF_PER_CHAN */ 5272 } 5273 else{ 5274 ar9300_start_nf_cal(ah); 5275 } 5276 #endif 5277 5278 #ifdef AH_SUPPORT_AR9300 5279 /* BB Panic Watchdog */ 5280 if (ar9300_get_capability(ah, HAL_CAP_BB_PANIC_WATCHDOG, 0, AH_NULL) == 5281 HAL_OK) 5282 { 5283 ar9300_config_bb_panic_watchdog(ah); 5284 } 5285 #endif 5286 5287 /* While receiving unsupported rate frame receive state machine 5288 * gets into a state 0xb and if phy_restart happens when rx 5289 * state machine is in 0xb state, BB would go hang, if we 5290 * see 0xb state after first bb panic, make sure that we 5291 * disable the phy_restart. 5292 * 5293 * There may be multiple panics, make sure that we always do 5294 * this if we see this panic at least once. This is required 5295 * because reset seems to be writing from INI file. 5296 */ 5297 if ((ar9300_get_capability(ah, HAL_CAP_PHYRESTART_CLR_WAR, 0, AH_NULL) 5298 == HAL_OK) && (((MS((AH9300(ah)->ah_bb_panic_last_status), 5299 AR_PHY_BB_WD_RX_OFDM_SM)) == 0xb) || 5300 AH9300(ah)->ah_phyrestart_disabled) ) 5301 { 5302 ar9300_disable_phy_restart(ah, 1); 5303 } 5304 5305 5306 5307 ahp->ah_radar1 = MS(OS_REG_READ(ah, AR_PHY_RADAR_1), 5308 AR_PHY_RADAR_1_CF_BIN_THRESH); 5309 ahp->ah_dc_offset = MS(OS_REG_READ(ah, AR_PHY_TIMING2), 5310 AR_PHY_TIMING2_DC_OFFSET); 5311 ahp->ah_disable_cck = MS(OS_REG_READ(ah, AR_PHY_MODE), 5312 AR_PHY_MODE_DISABLE_CCK); 5313 5314 if (AH9300(ah)->ah_enable_keysearch_always) { 5315 ar9300_enable_keysearch_always(ah, 1); 5316 } 5317 5318 #if ATH_LOW_POWER_ENABLE 5319 #define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val) 5320 #define REG_READ(_reg) *((volatile u_int32_t *)(_reg)) 5321 if (AR_SREV_OSPREY(ah)) { 5322 REG_WRITE(0xb4000080, REG_READ(0xb4000080) | 3); 5323 OS_REG_WRITE(ah, AR_RTC_RESET, 1); 5324 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL), 5325 AR_PCIE_PM_CTRL_ENA); 5326 OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_SPARE), 0xffffffff); 5327 } 5328 #undef REG_READ 5329 #undef REG_WRITE 5330 #endif /* ATH_LOW_POWER_ENABLE */ 5331 5332 WAR_USB_DISABLE_PLL_LOCK_DETECT(ah); 5333 5334 /* H/W Green TX */ 5335 ar9300_control_signals_for_green_tx_mode(ah); 5336 /* Smart Antenna, only for 5GHz on Scropion */ 5337 if (IEEE80211_IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan)) && AR_SREV_SCORPION(ah)) { 5338 ahp->ah_smartantenna_enable = 0; 5339 } 5340 5341 ar9300_set_smart_antenna(ah, ahp->ah_smartantenna_enable); 5342 5343 if (ahp->ah_skip_rx_iq_cal && !is_scan) { 5344 /* restore RX Cal result if existing */ 5345 ar9300_rx_iq_cal_restore(ah); 5346 ahp->ah_skip_rx_iq_cal = AH_FALSE; 5347 } 5348 5349 5350 return AH_TRUE; 5351 bad: 5352 OS_MARK(ah, AH_MARK_RESET_DONE, ecode); 5353 *status = ecode; 5354 5355 if (ahp->ah_skip_rx_iq_cal && !is_scan) { 5356 /* restore RX Cal result if existing */ 5357 ar9300_rx_iq_cal_restore(ah); 5358 ahp->ah_skip_rx_iq_cal = AH_FALSE; 5359 } 5360 5361 return AH_FALSE; 5362 #undef FAIL 5363 } 5364 5365 void 5366 ar9300_green_ap_ps_on_off( struct ath_hal *ah, u_int16_t on_off) 5367 { 5368 /* Set/reset the ps flag */ 5369 AH9300(ah)->green_ap_ps_on = !!on_off; 5370 } 5371 5372 /* 5373 * This function returns 1, where it is possible to do 5374 * single-chain power save. 5375 */ 5376 u_int16_t 5377 ar9300_is_single_ant_power_save_possible(struct ath_hal *ah) 5378 { 5379 return AH_TRUE; 5380 } 5381 5382 /* To avoid compilation warnings. Functions not used when EMULATION. */ 5383 /* 5384 * ar9300_find_mag_approx() 5385 */ 5386 static int32_t 5387 ar9300_find_mag_approx(struct ath_hal *ah, int32_t in_re, int32_t in_im) 5388 { 5389 int32_t abs_i = abs(in_re); 5390 int32_t abs_q = abs(in_im); 5391 int32_t max_abs, min_abs; 5392 5393 if (abs_i > abs_q) { 5394 max_abs = abs_i; 5395 min_abs = abs_q; 5396 } else { 5397 max_abs = abs_q; 5398 min_abs = abs_i; 5399 } 5400 5401 return (max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4)); 5402 } 5403 5404 /* 5405 * ar9300_solve_iq_cal() 5406 * solve 4x4 linear equation used in loopback iq cal. 5407 */ 5408 static HAL_BOOL 5409 ar9300_solve_iq_cal( 5410 struct ath_hal *ah, 5411 int32_t sin_2phi_1, 5412 int32_t cos_2phi_1, 5413 int32_t sin_2phi_2, 5414 int32_t cos_2phi_2, 5415 int32_t mag_a0_d0, 5416 int32_t phs_a0_d0, 5417 int32_t mag_a1_d0, 5418 int32_t phs_a1_d0, 5419 int32_t solved_eq[]) 5420 { 5421 int32_t f1 = cos_2phi_1 - cos_2phi_2; 5422 int32_t f3 = sin_2phi_1 - sin_2phi_2; 5423 int32_t f2; 5424 int32_t mag_tx, phs_tx, mag_rx, phs_rx; 5425 const int32_t result_shift = 1 << 15; 5426 5427 f2 = (((int64_t)f1 * (int64_t)f1) / result_shift) + (((int64_t)f3 * (int64_t)f3) / result_shift); 5428 5429 if (0 == f2) { 5430 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Divide by 0(%d).\n", 5431 __func__, __LINE__); 5432 return AH_FALSE; 5433 } 5434 5435 /* magnitude mismatch, tx */ 5436 mag_tx = f1 * (mag_a0_d0 - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0); 5437 /* phase mismatch, tx */ 5438 phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0); 5439 5440 mag_tx = (mag_tx / f2); 5441 phs_tx = (phs_tx / f2); 5442 5443 /* magnitude mismatch, rx */ 5444 mag_rx = 5445 mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) / result_shift; 5446 /* phase mismatch, rx */ 5447 phs_rx = 5448 phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) / result_shift; 5449 5450 solved_eq[0] = mag_tx; 5451 solved_eq[1] = phs_tx; 5452 solved_eq[2] = mag_rx; 5453 solved_eq[3] = phs_rx; 5454 5455 return AH_TRUE; 5456 } 5457 5458 /* 5459 * ar9300_calc_iq_corr() 5460 */ 5461 static HAL_BOOL 5462 ar9300_calc_iq_corr(struct ath_hal *ah, int32_t chain_idx, 5463 const int32_t iq_res[], int32_t iqc_coeff[]) 5464 { 5465 int32_t i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0; 5466 int32_t i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1; 5467 int32_t i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0; 5468 int32_t i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1; 5469 int32_t mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1; 5470 int32_t phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1; 5471 int32_t sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2; 5472 int32_t mag_tx, phs_tx, mag_rx, phs_rx; 5473 int32_t solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx; 5474 int32_t q_q_coff, q_i_coff; 5475 const int32_t res_scale = 1 << 15; 5476 const int32_t delpt_shift = 1 << 8; 5477 int32_t mag1, mag2; 5478 5479 i2_m_q2_a0_d0 = iq_res[0] & 0xfff; 5480 i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff; 5481 iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8); 5482 5483 if (i2_m_q2_a0_d0 > 0x800) { 5484 i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1); 5485 } 5486 if (iq_corr_a0_d0 > 0x800) { 5487 iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1); 5488 } 5489 5490 i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff; 5491 i2_p_q2_a0_d1 = (iq_res[2] & 0xfff); 5492 iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff; 5493 5494 if (i2_m_q2_a0_d1 > 0x800) { 5495 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1); 5496 } 5497 if (iq_corr_a0_d1 > 0x800) { 5498 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1); 5499 } 5500 5501 i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8); 5502 i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff; 5503 iq_corr_a1_d0 = iq_res[4] & 0xfff; 5504 5505 if (i2_m_q2_a1_d0 > 0x800) { 5506 i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1); 5507 } 5508 if (iq_corr_a1_d0 > 0x800) { 5509 iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1); 5510 } 5511 5512 i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff; 5513 i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8); 5514 iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff; 5515 5516 if (i2_m_q2_a1_d1 > 0x800) { 5517 i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1); 5518 } 5519 if (iq_corr_a1_d1 > 0x800) { 5520 iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1); 5521 } 5522 5523 if ((i2_p_q2_a0_d0 == 0) || 5524 (i2_p_q2_a0_d1 == 0) || 5525 (i2_p_q2_a1_d0 == 0) || 5526 (i2_p_q2_a1_d1 == 0)) { 5527 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5528 "%s: Divide by 0(%d):\na0_d0=%d\na0_d1=%d\na2_d0=%d\na1_d1=%d\n", 5529 __func__, __LINE__, 5530 i2_p_q2_a0_d0, i2_p_q2_a0_d1, i2_p_q2_a1_d0, i2_p_q2_a1_d1); 5531 return AH_FALSE; 5532 } 5533 5534 if ((i2_p_q2_a0_d0 <= 1024) || (i2_p_q2_a0_d0 > 2047) || 5535 (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) || 5536 (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) || 5537 (i2_p_q2_a0_d0 <= iq_corr_a0_d0) || 5538 (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) || 5539 (i2_p_q2_a0_d1 <= iq_corr_a0_d1) || 5540 (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) || 5541 (i2_p_q2_a1_d0 <= iq_corr_a1_d0) || 5542 (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) || 5543 (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) { 5544 return AH_FALSE; 5545 } 5546 5547 mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0; 5548 phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0; 5549 5550 mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1; 5551 phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1; 5552 5553 mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0; 5554 phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0; 5555 5556 mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1; 5557 phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1; 5558 5559 /* without analog phase shift */ 5560 sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT); 5561 /* without analog phase shift */ 5562 cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT); 5563 /* with analog phase shift */ 5564 sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT); 5565 /* with analog phase shift */ 5566 cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT); 5567 5568 /* force sin^2 + cos^2 = 1; */ 5569 /* find magnitude by approximation */ 5570 mag1 = ar9300_find_mag_approx(ah, cos_2phi_1, sin_2phi_1); 5571 mag2 = ar9300_find_mag_approx(ah, cos_2phi_2, sin_2phi_2); 5572 5573 if ((mag1 == 0) || (mag2 == 0)) { 5574 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5575 "%s: Divide by 0(%d): mag1=%d, mag2=%d\n", 5576 __func__, __LINE__, mag1, mag2); 5577 return AH_FALSE; 5578 } 5579 5580 /* normalization sin and cos by mag */ 5581 sin_2phi_1 = (sin_2phi_1 * res_scale / mag1); 5582 cos_2phi_1 = (cos_2phi_1 * res_scale / mag1); 5583 sin_2phi_2 = (sin_2phi_2 * res_scale / mag2); 5584 cos_2phi_2 = (cos_2phi_2 * res_scale / mag2); 5585 5586 /* calculate IQ mismatch */ 5587 if (AH_FALSE == ar9300_solve_iq_cal(ah, 5588 sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2, mag_a0_d0, 5589 phs_a0_d0, mag_a1_d0, phs_a1_d0, solved_eq)) 5590 { 5591 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5592 "%s: Call to ar9300_solve_iq_cal failed.\n", __func__); 5593 return AH_FALSE; 5594 } 5595 5596 mag_tx = solved_eq[0]; 5597 phs_tx = solved_eq[1]; 5598 mag_rx = solved_eq[2]; 5599 phs_rx = solved_eq[3]; 5600 5601 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5602 "%s: chain %d: mag mismatch=%d phase mismatch=%d\n", 5603 __func__, chain_idx, mag_tx / res_scale, phs_tx / res_scale); 5604 5605 if (res_scale == mag_tx) { 5606 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5607 "%s: Divide by 0(%d): mag_tx=%d, res_scale=%d\n", 5608 __func__, __LINE__, mag_tx, res_scale); 5609 return AH_FALSE; 5610 } 5611 5612 /* calculate and quantize Tx IQ correction factor */ 5613 mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx); 5614 phs_corr_tx = -phs_tx; 5615 5616 q_q_coff = (mag_corr_tx * 128 / res_scale); 5617 q_i_coff = (phs_corr_tx * 256 / res_scale); 5618 5619 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5620 "%s: tx chain %d: mag corr=%d phase corr=%d\n", 5621 __func__, chain_idx, q_q_coff, q_i_coff); 5622 5623 if (q_i_coff < -63) { 5624 q_i_coff = -63; 5625 } 5626 if (q_i_coff > 63) { 5627 q_i_coff = 63; 5628 } 5629 if (q_q_coff < -63) { 5630 q_q_coff = -63; 5631 } 5632 if (q_q_coff > 63) { 5633 q_q_coff = 63; 5634 } 5635 5636 iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff); 5637 5638 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: tx chain %d: iq corr coeff=%x\n", 5639 __func__, chain_idx, iqc_coeff[0]); 5640 5641 if (-mag_rx == res_scale) { 5642 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5643 "%s: Divide by 0(%d): mag_rx=%d, res_scale=%d\n", 5644 __func__, __LINE__, mag_rx, res_scale); 5645 return AH_FALSE; 5646 } 5647 5648 /* calculate and quantize Rx IQ correction factors */ 5649 mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx); 5650 phs_corr_rx = -phs_rx; 5651 5652 q_q_coff = (mag_corr_rx * 128 / res_scale); 5653 q_i_coff = (phs_corr_rx * 256 / res_scale); 5654 5655 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5656 "%s: rx chain %d: mag corr=%d phase corr=%d\n", 5657 __func__, chain_idx, q_q_coff, q_i_coff); 5658 5659 if (q_i_coff < -63) { 5660 q_i_coff = -63; 5661 } 5662 if (q_i_coff > 63) { 5663 q_i_coff = 63; 5664 } 5665 if (q_q_coff < -63) { 5666 q_q_coff = -63; 5667 } 5668 if (q_q_coff > 63) { 5669 q_q_coff = 63; 5670 } 5671 5672 iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff); 5673 5674 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: rx chain %d: iq corr coeff=%x\n", 5675 __func__, chain_idx, iqc_coeff[1]); 5676 5677 return AH_TRUE; 5678 } 5679 5680 #define MAX_MAG_DELTA 11 //maximum magnitude mismatch delta across gains 5681 #define MAX_PHS_DELTA 10 //maximum phase mismatch delta across gains 5682 #define ABS(x) ((x) >= 0 ? (x) : (-(x))) 5683 5684 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = { 5685 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0, 5686 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, 5687 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2}, 5688 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0, 5689 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, 5690 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2}, 5691 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0, 5692 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1, 5693 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2}, 5694 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0, 5695 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1, 5696 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2}, 5697 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0, 5698 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1, 5699 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2}, 5700 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0, 5701 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1, 5702 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2}, 5703 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0, 5704 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1, 5705 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2}, 5706 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0, 5707 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1, 5708 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2}, 5709 }; 5710 5711 static void 5712 ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan, u_int32_t num_chains, 5713 struct coeff_t *coeff, HAL_BOOL is_cal_reusable) 5714 { 5715 int nmeasurement, ch_idx, im; 5716 int32_t magnitude, phase; 5717 int32_t magnitude_max, phase_max; 5718 int32_t magnitude_min, phase_min; 5719 5720 int32_t magnitude_max_idx, phase_max_idx; 5721 int32_t magnitude_min_idx, phase_min_idx; 5722 5723 int32_t magnitude_avg, phase_avg; 5724 int32_t outlier_mag_idx = 0; 5725 int32_t outlier_phs_idx = 0; 5726 5727 5728 if (AR_SREV_POSEIDON(ah)) { 5729 HALASSERT(num_chains == 0x1); 5730 5731 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON; 5732 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON; 5733 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON; 5734 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON; 5735 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON; 5736 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON; 5737 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON; 5738 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON; 5739 } 5740 5741 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) { 5742 nmeasurement = OS_REG_READ_FIELD(ah, 5743 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0); 5744 if (nmeasurement > MAX_MEASUREMENT) { 5745 nmeasurement = MAX_MEASUREMENT; 5746 } 5747 5748 if (!AR_SREV_SCORPION(ah)) { 5749 /* 5750 * reset max/min variable to min/max values so that 5751 * we always start with 1st calibrated gain value 5752 */ 5753 magnitude_max = -64; 5754 phase_max = -64; 5755 magnitude_min = 63; 5756 phase_min = 63; 5757 magnitude_avg = 0; 5758 phase_avg = 0; 5759 magnitude_max_idx = 0; 5760 magnitude_min_idx = 0; 5761 phase_max_idx = 0; 5762 phase_min_idx = 0; 5763 5764 /* detect outlier only if nmeasurement > 1 */ 5765 if (nmeasurement > 1) { 5766 /* printf("----------- start outlier detection -----------\n"); */ 5767 /* 5768 * find max/min and phase/mag mismatch across all calibrated gains 5769 */ 5770 for (im = 0; im < nmeasurement; im++) { 5771 magnitude = coeff->mag_coeff[ch_idx][im][0]; 5772 phase = coeff->phs_coeff[ch_idx][im][0]; 5773 5774 magnitude_avg = magnitude_avg + magnitude; 5775 phase_avg = phase_avg + phase; 5776 if (magnitude > magnitude_max) { 5777 magnitude_max = magnitude; 5778 magnitude_max_idx = im; 5779 } 5780 if (magnitude < magnitude_min) { 5781 magnitude_min = magnitude; 5782 magnitude_min_idx = im; 5783 } 5784 if (phase > phase_max) { 5785 phase_max = phase; 5786 phase_max_idx = im; 5787 } 5788 if (phase < phase_min) { 5789 phase_min = phase; 5790 phase_min_idx = im; 5791 } 5792 } 5793 /* find average (exclude max abs value) */ 5794 for (im = 0; im < nmeasurement; im++) { 5795 magnitude = coeff->mag_coeff[ch_idx][im][0]; 5796 phase = coeff->phs_coeff[ch_idx][im][0]; 5797 if ((ABS(magnitude) < ABS(magnitude_max)) || 5798 (ABS(magnitude) < ABS(magnitude_min))) 5799 { 5800 magnitude_avg = magnitude_avg + magnitude; 5801 } 5802 if ((ABS(phase) < ABS(phase_max)) || 5803 (ABS(phase) < ABS(phase_min))) 5804 { 5805 phase_avg = phase_avg + phase; 5806 } 5807 } 5808 magnitude_avg = magnitude_avg / (nmeasurement - 1); 5809 phase_avg = phase_avg / (nmeasurement - 1); 5810 5811 /* detect magnitude outlier */ 5812 if (ABS(magnitude_max - magnitude_min) > MAX_MAG_DELTA) { 5813 if (ABS(magnitude_max - magnitude_avg) > 5814 ABS(magnitude_min - magnitude_avg)) 5815 { 5816 /* max is outlier, force to avg */ 5817 outlier_mag_idx = magnitude_max_idx; 5818 } else { 5819 /* min is outlier, force to avg */ 5820 outlier_mag_idx = magnitude_min_idx; 5821 } 5822 coeff->mag_coeff[ch_idx][outlier_mag_idx][0] = magnitude_avg; 5823 coeff->phs_coeff[ch_idx][outlier_mag_idx][0] = phase_avg; 5824 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5825 "[ch%d][outlier mag gain%d]:: " 5826 "mag_avg = %d (/128), phase_avg = %d (/256)\n", 5827 ch_idx, outlier_mag_idx, magnitude_avg, phase_avg); 5828 } 5829 /* detect phase outlier */ 5830 if (ABS(phase_max - phase_min) > MAX_PHS_DELTA) { 5831 if (ABS(phase_max-phase_avg) > ABS(phase_min - phase_avg)) { 5832 /* max is outlier, force to avg */ 5833 outlier_phs_idx = phase_max_idx; 5834 } else{ 5835 /* min is outlier, force to avg */ 5836 outlier_phs_idx = phase_min_idx; 5837 } 5838 coeff->mag_coeff[ch_idx][outlier_phs_idx][0] = magnitude_avg; 5839 coeff->phs_coeff[ch_idx][outlier_phs_idx][0] = phase_avg; 5840 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5841 "[ch%d][outlier phs gain%d]:: " 5842 "mag_avg = %d (/128), phase_avg = %d (/256)\n", 5843 ch_idx, outlier_phs_idx, magnitude_avg, phase_avg); 5844 } 5845 } 5846 } 5847 5848 /*printf("------------ after outlier detection -------------\n");*/ 5849 for (im = 0; im < nmeasurement; im++) { 5850 magnitude = coeff->mag_coeff[ch_idx][im][0]; 5851 phase = coeff->phs_coeff[ch_idx][im][0]; 5852 5853 #if 0 5854 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n", 5855 ch_idx, im, magnitude, phase); 5856 #endif 5857 5858 coeff->iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7); 5859 5860 if ((im % 2) == 0) { 5861 OS_REG_RMW_FIELD(ah, 5862 tx_corr_coeff[im][ch_idx], 5863 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE, 5864 coeff->iqc_coeff[0]); 5865 } else { 5866 OS_REG_RMW_FIELD(ah, 5867 tx_corr_coeff[im][ch_idx], 5868 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, 5869 coeff->iqc_coeff[0]); 5870 } 5871 #if ATH_SUPPORT_CAL_REUSE 5872 ichan->tx_corr_coeff[im][ch_idx] = coeff->iqc_coeff[0]; 5873 #endif 5874 } 5875 #if ATH_SUPPORT_CAL_REUSE 5876 ichan->num_measures[ch_idx] = nmeasurement; 5877 #endif 5878 } 5879 5880 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, 5881 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); 5882 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, 5883 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); 5884 5885 #if ATH_SUPPORT_CAL_REUSE 5886 if (is_cal_reusable) { 5887 ichan->one_time_txiqcal_done = AH_TRUE; 5888 HALDEBUG(ah, HAL_DEBUG_FCS_RTT, 5889 "(FCS) TXIQCAL saved - %d\n", ichan->channel); 5890 } 5891 #endif 5892 } 5893 5894 #if ATH_SUPPORT_CAL_REUSE 5895 static void 5896 ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan) 5897 { 5898 struct ath_hal_9300 *ahp = AH9300(ah); 5899 int nmeasurement, ch_idx, im; 5900 5901 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = { 5902 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0, 5903 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, 5904 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2}, 5905 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0, 5906 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, 5907 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2}, 5908 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0, 5909 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1, 5910 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2}, 5911 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0, 5912 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1, 5913 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2}, 5914 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0, 5915 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1, 5916 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2}, 5917 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0, 5918 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1, 5919 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2}, 5920 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0, 5921 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1, 5922 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2}, 5923 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0, 5924 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1, 5925 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2}, 5926 }; 5927 5928 if (AR_SREV_POSEIDON(ah)) { 5929 HALASSERT(ahp->ah_tx_cal_chainmask == 0x1); 5930 5931 tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON; 5932 tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON; 5933 tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON; 5934 tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON; 5935 tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON; 5936 tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON; 5937 tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON; 5938 tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON; 5939 } 5940 5941 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) { 5942 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) { 5943 continue; 5944 } 5945 nmeasurement = ichan->num_measures[ch_idx]; 5946 5947 for (im = 0; im < nmeasurement; im++) { 5948 if ((im % 2) == 0) { 5949 OS_REG_RMW_FIELD(ah, 5950 tx_corr_coeff[im][ch_idx], 5951 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE, 5952 ichan->tx_corr_coeff[im][ch_idx]); 5953 } else { 5954 OS_REG_RMW_FIELD(ah, 5955 tx_corr_coeff[im][ch_idx], 5956 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, 5957 ichan->tx_corr_coeff[im][ch_idx]); 5958 } 5959 } 5960 } 5961 5962 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, 5963 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); 5964 OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, 5965 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); 5966 } 5967 #endif 5968 5969 /* 5970 * ar9300_tx_iq_cal_hw_run is only needed for osprey/wasp/hornet 5971 * It is not needed for jupiter/poseidon. 5972 */ 5973 HAL_BOOL 5974 ar9300_tx_iq_cal_hw_run(struct ath_hal *ah) 5975 { 5976 int is_tx_gain_forced; 5977 5978 is_tx_gain_forced = OS_REG_READ_FIELD(ah, 5979 AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE); 5980 if (is_tx_gain_forced) { 5981 /*printf("Tx gain can not be forced during tx I/Q cal!\n");*/ 5982 OS_REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE, 0); 5983 } 5984 5985 /* enable tx IQ cal */ 5986 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START(ah), 5987 AR_PHY_TX_IQCAL_START_DO_CAL, AR_PHY_TX_IQCAL_START_DO_CAL); 5988 5989 if (!ath_hal_wait(ah, 5990 AR_PHY_TX_IQCAL_START(ah), AR_PHY_TX_IQCAL_START_DO_CAL, 0)) 5991 { 5992 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 5993 "%s: Tx IQ Cal is never completed.\n", __func__); 5994 return AH_FALSE; 5995 } 5996 return AH_TRUE; 5997 } 5998 5999 static void 6000 ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan, 6001 int iqcal_idx, int max_iqcal,HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr) 6002 { 6003 int nmeasurement=0, im, ix, iy, temp; 6004 struct ath_hal_9300 *ahp = AH9300(ah); 6005 u_int32_t txiqcal_status[AR9300_MAX_CHAINS] = { 6006 AR_PHY_TX_IQCAL_STATUS_B0(ah), 6007 AR_PHY_TX_IQCAL_STATUS_B1, 6008 AR_PHY_TX_IQCAL_STATUS_B2, 6009 }; 6010 const u_int32_t chan_info_tab[] = { 6011 AR_PHY_CHAN_INFO_TAB_0, 6012 AR_PHY_CHAN_INFO_TAB_1, 6013 AR_PHY_CHAN_INFO_TAB_2, 6014 }; 6015 int32_t iq_res[6]; 6016 int32_t ch_idx, j; 6017 u_int32_t num_chains = 0; 6018 static struct coeff_t coeff; 6019 txiqcal_status[0] = AR_PHY_TX_IQCAL_STATUS_B0(ah); 6020 6021 for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) { 6022 if (ahp->ah_tx_chainmask & (1 << ch_idx)) { 6023 num_chains++; 6024 } 6025 } 6026 6027 if (apply_last_corr) { 6028 if (coeff.last_cal == AH_TRUE) { 6029 int32_t magnitude, phase; 6030 int ch_idx, im; 6031 u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = { 6032 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0, 6033 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, 6034 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2}, 6035 { AR_PHY_TX_IQCAL_CORR_COEFF_01_B0, 6036 AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, 6037 AR_PHY_TX_IQCAL_CORR_COEFF_01_B2}, 6038 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0, 6039 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1, 6040 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2}, 6041 { AR_PHY_TX_IQCAL_CORR_COEFF_23_B0, 6042 AR_PHY_TX_IQCAL_CORR_COEFF_23_B1, 6043 AR_PHY_TX_IQCAL_CORR_COEFF_23_B2}, 6044 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0, 6045 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1, 6046 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2}, 6047 { AR_PHY_TX_IQCAL_CORR_COEFF_45_B0, 6048 AR_PHY_TX_IQCAL_CORR_COEFF_45_B1, 6049 AR_PHY_TX_IQCAL_CORR_COEFF_45_B2}, 6050 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0, 6051 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1, 6052 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2}, 6053 { AR_PHY_TX_IQCAL_CORR_COEFF_67_B0, 6054 AR_PHY_TX_IQCAL_CORR_COEFF_67_B1, 6055 AR_PHY_TX_IQCAL_CORR_COEFF_67_B2}, 6056 }; 6057 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) { 6058 for (im = 0; im < coeff.last_nmeasurement; im++) { 6059 magnitude = coeff.mag_coeff[ch_idx][im][0]; 6060 phase = coeff.phs_coeff[ch_idx][im][0]; 6061 6062 #if 0 6063 printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n", 6064 ch_idx, im, magnitude, phase); 6065 #endif 6066 6067 coeff.iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7); 6068 if ((im % 2) == 0) { 6069 OS_REG_RMW_FIELD(ah, 6070 tx_corr_coeff[im][ch_idx], 6071 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE, 6072 coeff.iqc_coeff[0]); 6073 } else { 6074 OS_REG_RMW_FIELD(ah, 6075 tx_corr_coeff[im][ch_idx], 6076 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, 6077 coeff.iqc_coeff[0]); 6078 } 6079 } 6080 } 6081 OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, 6082 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); 6083 } 6084 return; 6085 } 6086 6087 6088 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) { 6089 nmeasurement = OS_REG_READ_FIELD(ah, 6090 AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0); 6091 if (nmeasurement > MAX_MEASUREMENT) { 6092 nmeasurement = MAX_MEASUREMENT; 6093 } 6094 6095 for (im = 0; im < nmeasurement; im++) { 6096 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 6097 "%s: Doing Tx IQ Cal for chain %d.\n", __func__, ch_idx); 6098 if (OS_REG_READ(ah, txiqcal_status[ch_idx]) & 6099 AR_PHY_TX_IQCAL_STATUS_FAILED) 6100 { 6101 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 6102 "%s: Tx IQ Cal failed for chain %d.\n", __func__, ch_idx); 6103 goto TX_IQ_CAL_FAILED_; 6104 } 6105 6106 for (j = 0; j < 3; j++) { 6107 u_int32_t idx = 2 * j; 6108 /* 3 registers for each calibration result */ 6109 u_int32_t offset = 4 * (3 * im + j); 6110 6111 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, 6112 AR_PHY_CHAN_INFO_TAB_S2_READ, 0); 6113 /* 32 bits */ 6114 iq_res[idx] = OS_REG_READ(ah, chan_info_tab[ch_idx] + offset); 6115 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, 6116 AR_PHY_CHAN_INFO_TAB_S2_READ, 1); 6117 /* 16 bits */ 6118 iq_res[idx + 1] = 0xffff & 6119 OS_REG_READ(ah, chan_info_tab[ch_idx] + offset); 6120 6121 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 6122 "%s: IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n", 6123 __func__, idx, iq_res[idx], idx + 1, iq_res[idx + 1]); 6124 } 6125 6126 if (AH_FALSE == ar9300_calc_iq_corr( 6127 ah, ch_idx, iq_res, coeff.iqc_coeff)) 6128 { 6129 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 6130 "%s: Failed in calculation of IQ correction.\n", 6131 __func__); 6132 goto TX_IQ_CAL_FAILED_; 6133 } 6134 6135 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] = coeff.iqc_coeff[0] & 0x7f; 6136 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] = (coeff.iqc_coeff[0] >> 7) & 0x7f; 6137 if (coeff.mag_coeff[ch_idx][im][iqcal_idx-1] > 63) { 6138 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] -= 128; 6139 } 6140 if (coeff.phs_coeff[ch_idx][im][iqcal_idx-1] > 63) { 6141 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] -= 128; 6142 } 6143 #if 0 6144 ath_hal_printf(ah, "IQCAL::[ch%d][gain%d]:: mag = %d phase = %d \n", 6145 ch_idx, im, coeff.mag_coeff[ch_idx][im][iqcal_idx-1], 6146 coeff.phs_coeff[ch_idx][im][iqcal_idx-1]); 6147 #endif 6148 } 6149 } 6150 //last iteration; calculate mag and phs 6151 if (iqcal_idx == max_iqcal) { 6152 if (max_iqcal>1) { 6153 for (ch_idx = 0; ch_idx < num_chains; ch_idx++) { 6154 for (im = 0; im < nmeasurement; im++) { 6155 //sort mag and phs 6156 for( ix=0;ix<max_iqcal-1;ix++){ 6157 for( iy=ix+1;iy<=max_iqcal-1;iy++){ 6158 if(coeff.mag_coeff[ch_idx][im][iy] < 6159 coeff.mag_coeff[ch_idx][im][ix]) { 6160 //swap 6161 temp=coeff.mag_coeff[ch_idx][im][ix]; 6162 coeff.mag_coeff[ch_idx][im][ix] = coeff.mag_coeff[ch_idx][im][iy]; 6163 coeff.mag_coeff[ch_idx][im][iy] = temp; 6164 } 6165 if(coeff.phs_coeff[ch_idx][im][iy] < 6166 coeff.phs_coeff[ch_idx][im][ix]){ 6167 //swap 6168 temp=coeff.phs_coeff[ch_idx][im][ix]; 6169 coeff.phs_coeff[ch_idx][im][ix]=coeff.phs_coeff[ch_idx][im][iy]; 6170 coeff.phs_coeff[ch_idx][im][iy]=temp; 6171 } 6172 } 6173 } 6174 //select median; 3rd entry in the sorted array 6175 coeff.mag_coeff[ch_idx][im][0] = 6176 coeff.mag_coeff[ch_idx][im][max_iqcal/2]; 6177 coeff.phs_coeff[ch_idx][im][0] = 6178 coeff.phs_coeff[ch_idx][im][max_iqcal/2]; 6179 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, 6180 "IQCAL: Median [ch%d][gain%d]:: mag = %d phase = %d \n", 6181 ch_idx, im,coeff.mag_coeff[ch_idx][im][0], 6182 coeff.phs_coeff[ch_idx][im][0]); 6183 } 6184 } 6185 } 6186 ar9300_tx_iq_cal_outlier_detection(ah,ichan, num_chains, &coeff,is_cal_reusable); 6187 } 6188 6189 6190 coeff.last_nmeasurement = nmeasurement; 6191 coeff.last_cal = AH_TRUE; 6192 6193 return; 6194 6195 TX_IQ_CAL_FAILED_: 6196 /* no need to print this, it is AGC failure not chip stuck */ 6197 /*ath_hal_printf(ah, "Tx IQ Cal failed(%d)\n", line);*/ 6198 coeff.last_cal = AH_FALSE; 6199 return; 6200 } 6201 6202 6203 /* 6204 * ar9300_disable_phy_restart 6205 * 6206 * In some BBpanics, we can disable the phyrestart 6207 * disable_phy_restart 6208 * != 0, disable the phy restart in h/w 6209 * == 0, enable the phy restart in h/w 6210 */ 6211 void ar9300_disable_phy_restart(struct ath_hal *ah, int disable_phy_restart) 6212 { 6213 u_int32_t val; 6214 6215 val = OS_REG_READ(ah, AR_PHY_RESTART); 6216 if (disable_phy_restart) { 6217 val &= ~AR_PHY_RESTART_ENA; 6218 AH9300(ah)->ah_phyrestart_disabled = 1; 6219 } else { 6220 val |= AR_PHY_RESTART_ENA; 6221 AH9300(ah)->ah_phyrestart_disabled = 0; 6222 } 6223 OS_REG_WRITE(ah, AR_PHY_RESTART, val); 6224 6225 val = OS_REG_READ(ah, AR_PHY_RESTART); 6226 } 6227 6228 HAL_BOOL 6229 ar9300_interference_is_present(struct ath_hal *ah) 6230 { 6231 int i; 6232 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6233 const struct ieee80211_channel *chan = ahpriv->ah_curchan; 6234 HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); 6235 6236 if (ichan == NULL) { 6237 ath_hal_printf(ah, "%s: called with ichan=NULL\n", __func__); 6238 return AH_FALSE; 6239 } 6240 6241 /* This function is called after a stuck beacon, if EACS is enabled. 6242 * If CW interference is severe, then HW goes into a loop of continuous 6243 * stuck beacons and resets. On reset the NF cal history is cleared. 6244 * So the median value of the history cannot be used - 6245 * hence check if any value (Chain 0/Primary Channel) 6246 * is outside the bounds. 6247 */ 6248 HAL_NFCAL_HIST_FULL *h = AH_HOME_CHAN_NFCAL_HIST(ah, ichan); 6249 for (i = 0; i < HAL_NF_CAL_HIST_LEN_FULL; i++) { 6250 if (h->nf_cal_buffer[i][0] > 6251 AH9300(ah)->nfp->nominal + AH9300(ah)->nf_cw_int_delta) 6252 { 6253 return AH_TRUE; 6254 } 6255 6256 } 6257 return AH_FALSE; 6258 } 6259 6260 #if ATH_SUPPORT_CRDC 6261 void 6262 ar9300_crdc_rx_notify(struct ath_hal *ah, struct ath_rx_status *rxs) 6263 { 6264 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6265 int rssi_index; 6266 6267 if ((!AR_SREV_WASP(ah)) || 6268 (!ahpriv->ah_config.ath_hal_crdc_enable)) { 6269 return; 6270 } 6271 6272 if (rxs->rs_isaggr && rxs->rs_moreaggr) { 6273 return; 6274 } 6275 6276 if ((rxs->rs_rssi_ctl0 >= HAL_RSSI_BAD) || 6277 (rxs->rs_rssi_ctl1 >= HAL_RSSI_BAD)) { 6278 return; 6279 } 6280 6281 rssi_index = ah->ah_crdc_rssi_ptr % HAL_MAX_CRDC_RSSI_SAMPLE; 6282 6283 ah->ah_crdc_rssi_sample[0][rssi_index] = rxs->rs_rssi_ctl0; 6284 ah->ah_crdc_rssi_sample[1][rssi_index] = rxs->rs_rssi_ctl1; 6285 6286 ah->ah_crdc_rssi_ptr++; 6287 } 6288 6289 static int 6290 ar9300_crdc_avg_rssi(struct ath_hal *ah, int chain) 6291 { 6292 int crdc_rssi_sum = 0; 6293 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr, i; 6294 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6295 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window; 6296 6297 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) { 6298 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE; 6299 } 6300 6301 for (i = 1; i <= crdc_window; i++) { 6302 crdc_rssi_sum += 6303 ah->ah_crdc_rssi_sample[chain] 6304 [(crdc_rssi_ptr - i) % HAL_MAX_CRDC_RSSI_SAMPLE]; 6305 } 6306 6307 return crdc_rssi_sum / crdc_window; 6308 } 6309 6310 static void 6311 ar9300_crdc_activate(struct ath_hal *ah, int rssi_diff, int enable) 6312 { 6313 int val, orig_val; 6314 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6315 int crdc_numerator = ahpriv->ah_config.ath_hal_crdc_numerator; 6316 int crdc_denominator = ahpriv->ah_config.ath_hal_crdc_denominator; 6317 int c = (rssi_diff * crdc_numerator) / crdc_denominator; 6318 6319 val = orig_val = OS_REG_READ(ah, AR_PHY_MULTICHAIN_CTRL); 6320 val &= 0xffffff00; 6321 if (enable) { 6322 val |= 0x1; 6323 val |= ((c << 1) & 0xff); 6324 } 6325 OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_CTRL, val); 6326 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "diff: %02d comp: %02d reg: %08x %08x\n", 6327 rssi_diff, c, orig_val, val); 6328 } 6329 6330 6331 void ar9300_chain_rssi_diff_compensation(struct ath_hal *ah) 6332 { 6333 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6334 int crdc_window = ahpriv->ah_config.ath_hal_crdc_window; 6335 int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr; 6336 int crdc_rssi_thresh = ahpriv->ah_config.ath_hal_crdc_rssithresh; 6337 int crdc_diff_thresh = ahpriv->ah_config.ath_hal_crdc_diffthresh; 6338 int avg_rssi[2], avg_rssi_diff; 6339 6340 if ((!AR_SREV_WASP(ah)) || 6341 (!ahpriv->ah_config.ath_hal_crdc_enable)) { 6342 if (ah->ah_crdc_rssi_ptr) { 6343 ar9300_crdc_activate(ah, 0, 0); 6344 ah->ah_crdc_rssi_ptr = 0; 6345 } 6346 return; 6347 } 6348 6349 if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) { 6350 crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE; 6351 } 6352 6353 if (crdc_rssi_ptr < crdc_window) { 6354 return; 6355 } 6356 6357 avg_rssi[0] = ar9300_crdc_avg_rssi(ah, 0); 6358 avg_rssi[1] = ar9300_crdc_avg_rssi(ah, 1); 6359 avg_rssi_diff = avg_rssi[1] - avg_rssi[0]; 6360 6361 HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "crdc: avg: %02d %02d ", 6362 avg_rssi[0], avg_rssi[1]); 6363 6364 if ((avg_rssi[0] < crdc_rssi_thresh) && 6365 (avg_rssi[1] < crdc_rssi_thresh)) { 6366 ar9300_crdc_activate(ah, 0, 0); 6367 } else { 6368 if (ABS(avg_rssi_diff) >= crdc_diff_thresh) { 6369 ar9300_crdc_activate(ah, avg_rssi_diff, 1); 6370 } else { 6371 ar9300_crdc_activate(ah, 0, 1); 6372 } 6373 } 6374 } 6375 #endif 6376 6377 #if ATH_ANT_DIV_COMB 6378 HAL_BOOL 6379 ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal *ah, HAL_BOOL enable, const struct ieee80211_channel *chan) 6380 { 6381 u_int32_t value; 6382 u_int32_t regval; 6383 struct ath_hal_9300 *ahp = AH9300(ah); 6384 HAL_CHANNEL_INTERNAL *ichan; 6385 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 6386 HAL_CAPABILITIES *pcap = &ahpriv->ah_caps; 6387 6388 if (AR_SREV_POSEIDON(ah)) { 6389 // Make sure this scheme is only used for WB225(Astra) 6390 ahp->ah_lna_div_use_bt_ant_enable = enable; 6391 6392 ichan = ar9300_check_chan(ah, chan); 6393 if ( ichan == AH_NULL ) { 6394 HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel %u/0x%x; no mapping\n", 6395 __func__, chan->ic_freq, chan->ic_flags); 6396 return AH_FALSE; 6397 } 6398 6399 if ( enable == TRUE ) { 6400 pcap->halAntDivCombSupport = TRUE; 6401 } else { 6402 pcap->halAntDivCombSupport = pcap->halAntDivCombSupportOrg; 6403 } 6404 6405 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff) 6406 #define AR_SWITCH_TABLE_COM2_ALL_S (0) 6407 value = ar9300_ant_ctrl_common2_get(ah, IS_CHAN_2GHZ(ichan)); 6408 if ( enable == TRUE ) { 6409 value &= ~AR_SWITCH_TABLE_COM2_ALL; 6410 value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable; 6411 } 6412 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, value); 6413 OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); 6414 6415 value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control); 6416 /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */ 6417 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 6418 regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */ 6419 regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S; 6420 /* enable_lnadiv */ 6421 regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK); 6422 regval |= ((value >> 6) & 0x1) << 6423 MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT; 6424 if ( enable == TRUE ) { 6425 regval |= ANT_DIV_ENABLE; 6426 } 6427 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 6428 6429 /* enable fast_div */ 6430 regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT); 6431 regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK); 6432 regval |= ((value >> 7) & 0x1) << 6433 BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT; 6434 if ( enable == TRUE ) { 6435 regval |= FAST_DIV_ENABLE; 6436 } 6437 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); 6438 6439 if ( AR_SREV_POSEIDON_11_OR_LATER(ah) ) { 6440 if (pcap->halAntDivCombSupport) { 6441 /* If support DivComb, set MAIN to LNA1 and ALT to LNA2 at the first beginning */ 6442 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL); 6443 /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */ 6444 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK | 6445 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK | 6446 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK | 6447 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK)); 6448 regval |= (HAL_ANT_DIV_COMB_LNA1 << 6449 MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 6450 regval |= (HAL_ANT_DIV_COMB_LNA2 << 6451 MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 6452 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); 6453 } 6454 } 6455 6456 return AH_TRUE; 6457 } else { 6458 return AH_TRUE; 6459 } 6460 6461 /* XXX TODO: Add AR9565 support? */ 6462 } 6463 #endif /* ATH_ANT_DIV_COMB */ 6464