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