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