1dd1de374Slin wang - Sun Microsystems - Beijing China /* 2*c0c93480Slin wang - Sun Microsystems - Beijing China * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 3dd1de374Slin wang - Sun Microsystems - Beijing China * Use is subject to license terms. 4dd1de374Slin wang - Sun Microsystems - Beijing China */ 5dd1de374Slin wang - Sun Microsystems - Beijing China 6dd1de374Slin wang - Sun Microsystems - Beijing China /* 7dd1de374Slin wang - Sun Microsystems - Beijing China * Copyright (c) 2008 Atheros Communications Inc. 8dd1de374Slin wang - Sun Microsystems - Beijing China * 9dd1de374Slin wang - Sun Microsystems - Beijing China * Permission to use, copy, modify, and/or distribute this software for any 10dd1de374Slin wang - Sun Microsystems - Beijing China * purpose with or without fee is hereby granted, provided that the above 11dd1de374Slin wang - Sun Microsystems - Beijing China * copyright notice and this permission notice appear in all copies. 12dd1de374Slin wang - Sun Microsystems - Beijing China * 13dd1de374Slin wang - Sun Microsystems - Beijing China * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14dd1de374Slin wang - Sun Microsystems - Beijing China * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15dd1de374Slin wang - Sun Microsystems - Beijing China * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16dd1de374Slin wang - Sun Microsystems - Beijing China * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17dd1de374Slin wang - Sun Microsystems - Beijing China * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18dd1de374Slin wang - Sun Microsystems - Beijing China * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19dd1de374Slin wang - Sun Microsystems - Beijing China * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20dd1de374Slin wang - Sun Microsystems - Beijing China */ 21dd1de374Slin wang - Sun Microsystems - Beijing China 22dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_core.h" 23dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_hw.h" 24dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_reg.h" 25dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_phy.h" 26dd1de374Slin wang - Sun Microsystems - Beijing China 27dd1de374Slin wang - Sun Microsystems - Beijing China static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 }; 28dd1de374Slin wang - Sun Microsystems - Beijing China 29dd1de374Slin wang - Sun Microsystems - Beijing China /* We can tune this as we go by monitoring really low values */ 30dd1de374Slin wang - Sun Microsystems - Beijing China #define ATH9K_NF_TOO_LOW -60 31dd1de374Slin wang - Sun Microsystems - Beijing China 32dd1de374Slin wang - Sun Microsystems - Beijing China /* 33dd1de374Slin wang - Sun Microsystems - Beijing China * AR5416 may return very high value (like -31 dBm), in those cases the nf 34dd1de374Slin wang - Sun Microsystems - Beijing China * is incorrect and we should use the static NF value. Later we can try to 35dd1de374Slin wang - Sun Microsystems - Beijing China * find out why they are reporting these values 36dd1de374Slin wang - Sun Microsystems - Beijing China */ 37dd1de374Slin wang - Sun Microsystems - Beijing China 38dd1de374Slin wang - Sun Microsystems - Beijing China /* ARGSUSED */ 39dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 40dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_nf_in_range(struct ath_hal *ah, signed short nf) 41dd1de374Slin wang - Sun Microsystems - Beijing China { 42dd1de374Slin wang - Sun Microsystems - Beijing China if (nf > ATH9K_NF_TOO_LOW) { 43dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 44dd1de374Slin wang - Sun Microsystems - Beijing China "%s: noise floor value detected (%d) is " 45dd1de374Slin wang - Sun Microsystems - Beijing China "lower than what we think is a " 46dd1de374Slin wang - Sun Microsystems - Beijing China "reasonable value (%d)\n", 47dd1de374Slin wang - Sun Microsystems - Beijing China __func__, nf, ATH9K_NF_TOO_LOW)); 48dd1de374Slin wang - Sun Microsystems - Beijing China 49dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 50dd1de374Slin wang - Sun Microsystems - Beijing China } 51dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 52dd1de374Slin wang - Sun Microsystems - Beijing China } 53dd1de374Slin wang - Sun Microsystems - Beijing China 54dd1de374Slin wang - Sun Microsystems - Beijing China static int16_t 55dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) 56dd1de374Slin wang - Sun Microsystems - Beijing China { 57dd1de374Slin wang - Sun Microsystems - Beijing China int16_t nfval; 58dd1de374Slin wang - Sun Microsystems - Beijing China int16_t sort[ATH9K_NF_CAL_HIST_MAX]; 59dd1de374Slin wang - Sun Microsystems - Beijing China int i, j; 60dd1de374Slin wang - Sun Microsystems - Beijing China 61dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++) 62dd1de374Slin wang - Sun Microsystems - Beijing China sort[i] = nfCalBuffer[i]; 63dd1de374Slin wang - Sun Microsystems - Beijing China 64dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) { 65dd1de374Slin wang - Sun Microsystems - Beijing China for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) { 66dd1de374Slin wang - Sun Microsystems - Beijing China if (sort[j] > sort[j - 1]) { 67dd1de374Slin wang - Sun Microsystems - Beijing China nfval = sort[j]; 68dd1de374Slin wang - Sun Microsystems - Beijing China sort[j] = sort[j - 1]; 69dd1de374Slin wang - Sun Microsystems - Beijing China sort[j - 1] = nfval; 70dd1de374Slin wang - Sun Microsystems - Beijing China } 71dd1de374Slin wang - Sun Microsystems - Beijing China } 72dd1de374Slin wang - Sun Microsystems - Beijing China } 73dd1de374Slin wang - Sun Microsystems - Beijing China nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1]; 74dd1de374Slin wang - Sun Microsystems - Beijing China 75dd1de374Slin wang - Sun Microsystems - Beijing China return (nfval); 76dd1de374Slin wang - Sun Microsystems - Beijing China } 77dd1de374Slin wang - Sun Microsystems - Beijing China 78dd1de374Slin wang - Sun Microsystems - Beijing China static void 79dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h, 80dd1de374Slin wang - Sun Microsystems - Beijing China int16_t *nfarray) 81dd1de374Slin wang - Sun Microsystems - Beijing China { 82dd1de374Slin wang - Sun Microsystems - Beijing China int i; 83dd1de374Slin wang - Sun Microsystems - Beijing China 84dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < NUM_NF_READINGS; i++) { 85dd1de374Slin wang - Sun Microsystems - Beijing China h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; 86dd1de374Slin wang - Sun Microsystems - Beijing China 87dd1de374Slin wang - Sun Microsystems - Beijing China if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX) 88dd1de374Slin wang - Sun Microsystems - Beijing China h[i].currIndex = 0; 89dd1de374Slin wang - Sun Microsystems - Beijing China 90dd1de374Slin wang - Sun Microsystems - Beijing China if (h[i].invalidNFcount > 0) { 91dd1de374Slin wang - Sun Microsystems - Beijing China if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE || 92dd1de374Slin wang - Sun Microsystems - Beijing China nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) { 93dd1de374Slin wang - Sun Microsystems - Beijing China h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX; 94dd1de374Slin wang - Sun Microsystems - Beijing China } else { 95dd1de374Slin wang - Sun Microsystems - Beijing China h[i].invalidNFcount--; 96dd1de374Slin wang - Sun Microsystems - Beijing China h[i].privNF = nfarray[i]; 97dd1de374Slin wang - Sun Microsystems - Beijing China } 98dd1de374Slin wang - Sun Microsystems - Beijing China } else { 99dd1de374Slin wang - Sun Microsystems - Beijing China h[i].privNF = 100dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer); 101dd1de374Slin wang - Sun Microsystems - Beijing China } 102dd1de374Slin wang - Sun Microsystems - Beijing China } 103dd1de374Slin wang - Sun Microsystems - Beijing China } 104dd1de374Slin wang - Sun Microsystems - Beijing China 105dd1de374Slin wang - Sun Microsystems - Beijing China static void 106dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_do_getnf(struct ath_hal *ah, 107dd1de374Slin wang - Sun Microsystems - Beijing China int16_t nfarray[NUM_NF_READINGS]) 108dd1de374Slin wang - Sun Microsystems - Beijing China { 109dd1de374Slin wang - Sun Microsystems - Beijing China int16_t nf; 110dd1de374Slin wang - Sun Microsystems - Beijing China 111dd1de374Slin wang - Sun Microsystems - Beijing China if (AR_SREV_9280_10_OR_LATER(ah)) 112dd1de374Slin wang - Sun Microsystems - Beijing China nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); 113dd1de374Slin wang - Sun Microsystems - Beijing China else 114dd1de374Slin wang - Sun Microsystems - Beijing China nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); 115dd1de374Slin wang - Sun Microsystems - Beijing China 116dd1de374Slin wang - Sun Microsystems - Beijing China if (nf & 0x100) 117dd1de374Slin wang - Sun Microsystems - Beijing China nf = 0 - ((nf ^ 0x1ff) + 1); 118dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 119dd1de374Slin wang - Sun Microsystems - Beijing China "NF calibrated [ctl] [chain 0] is %d\n", nf)); 120dd1de374Slin wang - Sun Microsystems - Beijing China nfarray[0] = nf; 121dd1de374Slin wang - Sun Microsystems - Beijing China 122dd1de374Slin wang - Sun Microsystems - Beijing China if (AR_SREV_9280_10_OR_LATER(ah)) 123dd1de374Slin wang - Sun Microsystems - Beijing China nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), 124dd1de374Slin wang - Sun Microsystems - Beijing China AR9280_PHY_CH1_MINCCA_PWR); 125dd1de374Slin wang - Sun Microsystems - Beijing China else 126dd1de374Slin wang - Sun Microsystems - Beijing China nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), 127dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CH1_MINCCA_PWR); 128dd1de374Slin wang - Sun Microsystems - Beijing China 129dd1de374Slin wang - Sun Microsystems - Beijing China if (nf & 0x100) 130dd1de374Slin wang - Sun Microsystems - Beijing China nf = 0 - ((nf ^ 0x1ff) + 1); 131dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 132dd1de374Slin wang - Sun Microsystems - Beijing China "NF calibrated [ctl] [chain 1] is %d\n", nf)); 133dd1de374Slin wang - Sun Microsystems - Beijing China nfarray[1] = nf; 134dd1de374Slin wang - Sun Microsystems - Beijing China 135dd1de374Slin wang - Sun Microsystems - Beijing China if (!AR_SREV_9280(ah)) { 136dd1de374Slin wang - Sun Microsystems - Beijing China nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), 137dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CH2_MINCCA_PWR); 138dd1de374Slin wang - Sun Microsystems - Beijing China if (nf & 0x100) 139dd1de374Slin wang - Sun Microsystems - Beijing China nf = 0 - ((nf ^ 0x1ff) + 1); 140dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 141dd1de374Slin wang - Sun Microsystems - Beijing China "NF calibrated [ctl] [chain 2] is %d\n", nf)); 142dd1de374Slin wang - Sun Microsystems - Beijing China nfarray[2] = nf; 143dd1de374Slin wang - Sun Microsystems - Beijing China } 144dd1de374Slin wang - Sun Microsystems - Beijing China 145dd1de374Slin wang - Sun Microsystems - Beijing China if (AR_SREV_9280_10_OR_LATER(ah)) 146dd1de374Slin wang - Sun Microsystems - Beijing China nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), 147dd1de374Slin wang - Sun Microsystems - Beijing China AR9280_PHY_EXT_MINCCA_PWR); 148dd1de374Slin wang - Sun Microsystems - Beijing China else 149dd1de374Slin wang - Sun Microsystems - Beijing China nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), 150dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_EXT_MINCCA_PWR); 151dd1de374Slin wang - Sun Microsystems - Beijing China 152dd1de374Slin wang - Sun Microsystems - Beijing China if (nf & 0x100) 153dd1de374Slin wang - Sun Microsystems - Beijing China nf = 0 - ((nf ^ 0x1ff) + 1); 154dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 155dd1de374Slin wang - Sun Microsystems - Beijing China "NF calibrated [ext] [chain 0] is %d\n", nf)); 156dd1de374Slin wang - Sun Microsystems - Beijing China nfarray[3] = nf; 157dd1de374Slin wang - Sun Microsystems - Beijing China 158dd1de374Slin wang - Sun Microsystems - Beijing China if (AR_SREV_9280_10_OR_LATER(ah)) 159dd1de374Slin wang - Sun Microsystems - Beijing China nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), 160dd1de374Slin wang - Sun Microsystems - Beijing China AR9280_PHY_CH1_EXT_MINCCA_PWR); 161dd1de374Slin wang - Sun Microsystems - Beijing China else 162dd1de374Slin wang - Sun Microsystems - Beijing China nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), 163dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CH1_EXT_MINCCA_PWR); 164dd1de374Slin wang - Sun Microsystems - Beijing China 165dd1de374Slin wang - Sun Microsystems - Beijing China if (nf & 0x100) 166dd1de374Slin wang - Sun Microsystems - Beijing China nf = 0 - ((nf ^ 0x1ff) + 1); 167dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 168dd1de374Slin wang - Sun Microsystems - Beijing China "NF calibrated [ext] [chain 1] is %d\n", nf)); 169dd1de374Slin wang - Sun Microsystems - Beijing China nfarray[4] = nf; 170dd1de374Slin wang - Sun Microsystems - Beijing China 171dd1de374Slin wang - Sun Microsystems - Beijing China if (!AR_SREV_9280(ah)) { 172dd1de374Slin wang - Sun Microsystems - Beijing China nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), 173dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CH2_EXT_MINCCA_PWR); 174dd1de374Slin wang - Sun Microsystems - Beijing China if (nf & 0x100) 175dd1de374Slin wang - Sun Microsystems - Beijing China nf = 0 - ((nf ^ 0x1ff) + 1); 176dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 177dd1de374Slin wang - Sun Microsystems - Beijing China "NF calibrated [ext] [chain 2] is %d\n", nf)); 178dd1de374Slin wang - Sun Microsystems - Beijing China nfarray[5] = nf; 179dd1de374Slin wang - Sun Microsystems - Beijing China } 180dd1de374Slin wang - Sun Microsystems - Beijing China } 181dd1de374Slin wang - Sun Microsystems - Beijing China 182dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 183dd1de374Slin wang - Sun Microsystems - Beijing China getNoiseFloorThresh(struct ath_hal *ah, 184dd1de374Slin wang - Sun Microsystems - Beijing China const struct ath9k_channel *chan, 185dd1de374Slin wang - Sun Microsystems - Beijing China int16_t *nft) 186dd1de374Slin wang - Sun Microsystems - Beijing China { 187dd1de374Slin wang - Sun Microsystems - Beijing China switch (chan->chanmode) { 188dd1de374Slin wang - Sun Microsystems - Beijing China case CHANNEL_A: 189dd1de374Slin wang - Sun Microsystems - Beijing China case CHANNEL_A_HT20: 190dd1de374Slin wang - Sun Microsystems - Beijing China case CHANNEL_A_HT40PLUS: 191dd1de374Slin wang - Sun Microsystems - Beijing China case CHANNEL_A_HT40MINUS: 192dd1de374Slin wang - Sun Microsystems - Beijing China *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5); 193dd1de374Slin wang - Sun Microsystems - Beijing China break; 194dd1de374Slin wang - Sun Microsystems - Beijing China case CHANNEL_B: 195dd1de374Slin wang - Sun Microsystems - Beijing China case CHANNEL_G: 196dd1de374Slin wang - Sun Microsystems - Beijing China case CHANNEL_G_HT20: 197dd1de374Slin wang - Sun Microsystems - Beijing China case CHANNEL_G_HT40PLUS: 198dd1de374Slin wang - Sun Microsystems - Beijing China case CHANNEL_G_HT40MINUS: 199dd1de374Slin wang - Sun Microsystems - Beijing China *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2); 200dd1de374Slin wang - Sun Microsystems - Beijing China break; 201dd1de374Slin wang - Sun Microsystems - Beijing China default: 202dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CHANNEL, 203dd1de374Slin wang - Sun Microsystems - Beijing China "%s: invalid channel flags 0x%x\n", __func__, 204dd1de374Slin wang - Sun Microsystems - Beijing China chan->channelFlags)); 205dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 206dd1de374Slin wang - Sun Microsystems - Beijing China } 207dd1de374Slin wang - Sun Microsystems - Beijing China 208dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 209dd1de374Slin wang - Sun Microsystems - Beijing China } 210dd1de374Slin wang - Sun Microsystems - Beijing China 211dd1de374Slin wang - Sun Microsystems - Beijing China static void 212dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_setup_calibration(struct ath_hal *ah, 213dd1de374Slin wang - Sun Microsystems - Beijing China struct hal_cal_list *currCal) 214dd1de374Slin wang - Sun Microsystems - Beijing China { 215dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), 216dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, 217dd1de374Slin wang - Sun Microsystems - Beijing China currCal->calData->calCountMax); 218dd1de374Slin wang - Sun Microsystems - Beijing China 219dd1de374Slin wang - Sun Microsystems - Beijing China switch (currCal->calData->calType) { 220dd1de374Slin wang - Sun Microsystems - Beijing China case IQ_MISMATCH_CAL: 221dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); 222dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 223dd1de374Slin wang - Sun Microsystems - Beijing China "%s: starting IQ Mismatch Calibration\n", 224dd1de374Slin wang - Sun Microsystems - Beijing China __func__)); 225dd1de374Slin wang - Sun Microsystems - Beijing China break; 226dd1de374Slin wang - Sun Microsystems - Beijing China case ADC_GAIN_CAL: 227dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); 228dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 229dd1de374Slin wang - Sun Microsystems - Beijing China "%s: starting ADC Gain Calibration\n", __func__)); 230dd1de374Slin wang - Sun Microsystems - Beijing China break; 231dd1de374Slin wang - Sun Microsystems - Beijing China case ADC_DC_CAL: 232dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); 233dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 234dd1de374Slin wang - Sun Microsystems - Beijing China "%s: starting ADC DC Calibration\n", __func__)); 235dd1de374Slin wang - Sun Microsystems - Beijing China break; 236dd1de374Slin wang - Sun Microsystems - Beijing China case ADC_DC_INIT_CAL: 237dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); 238dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 239dd1de374Slin wang - Sun Microsystems - Beijing China "%s: starting Init ADC DC Calibration\n", 240dd1de374Slin wang - Sun Microsystems - Beijing China __func__)); 241dd1de374Slin wang - Sun Microsystems - Beijing China break; 242dd1de374Slin wang - Sun Microsystems - Beijing China } 243dd1de374Slin wang - Sun Microsystems - Beijing China 244dd1de374Slin wang - Sun Microsystems - Beijing China REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), 245dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_TIMING_CTRL4_DO_CAL); 246dd1de374Slin wang - Sun Microsystems - Beijing China } 247dd1de374Slin wang - Sun Microsystems - Beijing China 248dd1de374Slin wang - Sun Microsystems - Beijing China static void 249dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_reset_calibration(struct ath_hal *ah, 250dd1de374Slin wang - Sun Microsystems - Beijing China struct hal_cal_list *currCal) 251dd1de374Slin wang - Sun Microsystems - Beijing China { 252dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 253dd1de374Slin wang - Sun Microsystems - Beijing China int i; 254dd1de374Slin wang - Sun Microsystems - Beijing China 255dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_setup_calibration(ah, currCal); 256dd1de374Slin wang - Sun Microsystems - Beijing China 257dd1de374Slin wang - Sun Microsystems - Beijing China currCal->calState = CAL_RUNNING; 258dd1de374Slin wang - Sun Microsystems - Beijing China 259dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < AR5416_MAX_CHAINS; i++) { 260dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_Meas0.sign[i] = 0; 261dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_Meas1.sign[i] = 0; 262dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_Meas2.sign[i] = 0; 263dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_Meas3.sign[i] = 0; 264dd1de374Slin wang - Sun Microsystems - Beijing China } 265dd1de374Slin wang - Sun Microsystems - Beijing China 266dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_CalSamples = 0; 267dd1de374Slin wang - Sun Microsystems - Beijing China } 268dd1de374Slin wang - Sun Microsystems - Beijing China 269dd1de374Slin wang - Sun Microsystems - Beijing China static void 270dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_per_calibration(struct ath_hal *ah, 271dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *ichan, 272dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t rxchainmask, 273dd1de374Slin wang - Sun Microsystems - Beijing China struct hal_cal_list *currCal, 274dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t *isCalDone) 275dd1de374Slin wang - Sun Microsystems - Beijing China { 276dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 277dd1de374Slin wang - Sun Microsystems - Beijing China 278dd1de374Slin wang - Sun Microsystems - Beijing China *isCalDone = B_FALSE; 279dd1de374Slin wang - Sun Microsystems - Beijing China 280dd1de374Slin wang - Sun Microsystems - Beijing China if (currCal->calState == CAL_RUNNING) { 281dd1de374Slin wang - Sun Microsystems - Beijing China if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) & 282dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_TIMING_CTRL4_DO_CAL)) { 283dd1de374Slin wang - Sun Microsystems - Beijing China 284dd1de374Slin wang - Sun Microsystems - Beijing China currCal->calData->calCollect(ah); 285dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_CalSamples++; 286dd1de374Slin wang - Sun Microsystems - Beijing China 287dd1de374Slin wang - Sun Microsystems - Beijing China if (ahp->ah_CalSamples >= 288dd1de374Slin wang - Sun Microsystems - Beijing China currCal->calData->calNumSamples) { 289dd1de374Slin wang - Sun Microsystems - Beijing China int i, numChains = 0; 290dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < AR5416_MAX_CHAINS; i++) { 291dd1de374Slin wang - Sun Microsystems - Beijing China if (rxchainmask & (1 << i)) 292dd1de374Slin wang - Sun Microsystems - Beijing China numChains++; 293dd1de374Slin wang - Sun Microsystems - Beijing China } 294dd1de374Slin wang - Sun Microsystems - Beijing China 295dd1de374Slin wang - Sun Microsystems - Beijing China currCal->calData->calPostProc(ah, numChains); 296dd1de374Slin wang - Sun Microsystems - Beijing China ichan->CalValid |= currCal->calData->calType; 297dd1de374Slin wang - Sun Microsystems - Beijing China currCal->calState = CAL_DONE; 298dd1de374Slin wang - Sun Microsystems - Beijing China *isCalDone = B_TRUE; 299dd1de374Slin wang - Sun Microsystems - Beijing China } else { 300dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_setup_calibration(ah, currCal); 301dd1de374Slin wang - Sun Microsystems - Beijing China } 302dd1de374Slin wang - Sun Microsystems - Beijing China } 303dd1de374Slin wang - Sun Microsystems - Beijing China } else if (!(ichan->CalValid & currCal->calData->calType)) { 304dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_reset_calibration(ah, currCal); 305dd1de374Slin wang - Sun Microsystems - Beijing China } 306dd1de374Slin wang - Sun Microsystems - Beijing China } 307dd1de374Slin wang - Sun Microsystems - Beijing China 308dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 309dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_iscal_supported(struct ath_hal *ah, 310dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *chan, 311dd1de374Slin wang - Sun Microsystems - Beijing China enum hal_cal_types calType) 312dd1de374Slin wang - Sun Microsystems - Beijing China { 313dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 314dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t retval = B_FALSE; 315dd1de374Slin wang - Sun Microsystems - Beijing China 316dd1de374Slin wang - Sun Microsystems - Beijing China switch (calType & ahp->ah_suppCals) { 317dd1de374Slin wang - Sun Microsystems - Beijing China case IQ_MISMATCH_CAL: 318dd1de374Slin wang - Sun Microsystems - Beijing China if (!IS_CHAN_B(chan)) 319dd1de374Slin wang - Sun Microsystems - Beijing China retval = B_TRUE; 320dd1de374Slin wang - Sun Microsystems - Beijing China break; 321dd1de374Slin wang - Sun Microsystems - Beijing China case ADC_GAIN_CAL: 322dd1de374Slin wang - Sun Microsystems - Beijing China case ADC_DC_CAL: 323dd1de374Slin wang - Sun Microsystems - Beijing China if (!IS_CHAN_B(chan) && 324dd1de374Slin wang - Sun Microsystems - Beijing China !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) 325dd1de374Slin wang - Sun Microsystems - Beijing China retval = B_TRUE; 326dd1de374Slin wang - Sun Microsystems - Beijing China break; 327dd1de374Slin wang - Sun Microsystems - Beijing China } 328dd1de374Slin wang - Sun Microsystems - Beijing China 329dd1de374Slin wang - Sun Microsystems - Beijing China return (retval); 330dd1de374Slin wang - Sun Microsystems - Beijing China } 331dd1de374Slin wang - Sun Microsystems - Beijing China 332dd1de374Slin wang - Sun Microsystems - Beijing China static void 333dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_iqcal_collect(struct ath_hal *ah) 334dd1de374Slin wang - Sun Microsystems - Beijing China { 335dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 336dd1de374Slin wang - Sun Microsystems - Beijing China int i; 337dd1de374Slin wang - Sun Microsystems - Beijing China 338dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < AR5416_MAX_CHAINS; i++) { 339dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalPowerMeasI[i] += 340dd1de374Slin wang - Sun Microsystems - Beijing China REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); 341dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalPowerMeasQ[i] += 342dd1de374Slin wang - Sun Microsystems - Beijing China REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); 343dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalIqCorrMeas[i] += 344dd1de374Slin wang - Sun Microsystems - Beijing China (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); 345dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 346dd1de374Slin wang - Sun Microsystems - Beijing China "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", 347dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i], 348dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalPowerMeasQ[i], 349dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalIqCorrMeas[i])); 350dd1de374Slin wang - Sun Microsystems - Beijing China } 351dd1de374Slin wang - Sun Microsystems - Beijing China } 352dd1de374Slin wang - Sun Microsystems - Beijing China 353dd1de374Slin wang - Sun Microsystems - Beijing China static void 354dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_gaincal_collect(struct ath_hal *ah) 355dd1de374Slin wang - Sun Microsystems - Beijing China { 356dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 357dd1de374Slin wang - Sun Microsystems - Beijing China int i; 358dd1de374Slin wang - Sun Microsystems - Beijing China 359dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < AR5416_MAX_CHAINS; i++) { 360dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcIOddPhase[i] += 361dd1de374Slin wang - Sun Microsystems - Beijing China REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); 362dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcIEvenPhase[i] += 363dd1de374Slin wang - Sun Microsystems - Beijing China REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); 364dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcQOddPhase[i] += 365dd1de374Slin wang - Sun Microsystems - Beijing China REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); 366dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcQEvenPhase[i] += 367dd1de374Slin wang - Sun Microsystems - Beijing China REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); 368dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 369dd1de374Slin wang - Sun Microsystems - Beijing China "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " 370dd1de374Slin wang - Sun Microsystems - Beijing China "oddq=0x%08x; evenq=0x%08x;\n", 371dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_CalSamples, i, 372dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcIOddPhase[i], 373dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcIEvenPhase[i], 374dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcQOddPhase[i], 375dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcQEvenPhase[i])); 376dd1de374Slin wang - Sun Microsystems - Beijing China } 377dd1de374Slin wang - Sun Microsystems - Beijing China } 378dd1de374Slin wang - Sun Microsystems - Beijing China 379dd1de374Slin wang - Sun Microsystems - Beijing China static void 380dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_dccal_collect(struct ath_hal *ah) 381dd1de374Slin wang - Sun Microsystems - Beijing China { 382dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 383dd1de374Slin wang - Sun Microsystems - Beijing China int i; 384dd1de374Slin wang - Sun Microsystems - Beijing China 385dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < AR5416_MAX_CHAINS; i++) { 386dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcDcOffsetIOddPhase[i] += 387dd1de374Slin wang - Sun Microsystems - Beijing China (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); 388dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcDcOffsetIEvenPhase[i] += 389dd1de374Slin wang - Sun Microsystems - Beijing China (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); 390dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcDcOffsetQOddPhase[i] += 391dd1de374Slin wang - Sun Microsystems - Beijing China (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); 392dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcDcOffsetQEvenPhase[i] += 393dd1de374Slin wang - Sun Microsystems - Beijing China (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); 394dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 395dd1de374Slin wang - Sun Microsystems - Beijing China "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " 396dd1de374Slin wang - Sun Microsystems - Beijing China "oddq=0x%08x; evenq=0x%08x;\n", 397dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_CalSamples, i, 398dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcDcOffsetIOddPhase[i], 399dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcDcOffsetIEvenPhase[i], 400dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcDcOffsetQOddPhase[i], 401dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_totalAdcDcOffsetQEvenPhase[i])); 402dd1de374Slin wang - Sun Microsystems - Beijing China } 403dd1de374Slin wang - Sun Microsystems - Beijing China } 404dd1de374Slin wang - Sun Microsystems - Beijing China 405dd1de374Slin wang - Sun Microsystems - Beijing China static void 406dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_iqcalibrate(struct ath_hal *ah, uint8_t numChains) 407dd1de374Slin wang - Sun Microsystems - Beijing China { 408dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 409dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t powerMeasQ, powerMeasI, iqCorrMeas; 410dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t qCoffDenom, iCoffDenom; 411dd1de374Slin wang - Sun Microsystems - Beijing China int32_t qCoff, iCoff; 412dd1de374Slin wang - Sun Microsystems - Beijing China int iqCorrNeg, i; 413dd1de374Slin wang - Sun Microsystems - Beijing China 414dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < numChains; i++) { 415dd1de374Slin wang - Sun Microsystems - Beijing China powerMeasI = ahp->ah_totalPowerMeasI[i]; 416dd1de374Slin wang - Sun Microsystems - Beijing China powerMeasQ = ahp->ah_totalPowerMeasQ[i]; 417dd1de374Slin wang - Sun Microsystems - Beijing China iqCorrMeas = ahp->ah_totalIqCorrMeas[i]; 418dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 419dd1de374Slin wang - Sun Microsystems - Beijing China "Starting IQ Cal and Correction for Chain %d\n", 420dd1de374Slin wang - Sun Microsystems - Beijing China i)); 421dd1de374Slin wang - Sun Microsystems - Beijing China 422dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 423dd1de374Slin wang - Sun Microsystems - Beijing China "Orignal: Chn %diq_corr_meas = 0x%08x\n", 424dd1de374Slin wang - Sun Microsystems - Beijing China i, ahp->ah_totalIqCorrMeas[i])); 425dd1de374Slin wang - Sun Microsystems - Beijing China 426dd1de374Slin wang - Sun Microsystems - Beijing China iqCorrNeg = 0; 427dd1de374Slin wang - Sun Microsystems - Beijing China 428dd1de374Slin wang - Sun Microsystems - Beijing China if (iqCorrMeas > 0x80000000) { 429dd1de374Slin wang - Sun Microsystems - Beijing China iqCorrMeas = (0xffffffff - iqCorrMeas) + 1; 430dd1de374Slin wang - Sun Microsystems - Beijing China iqCorrNeg = 1; 431dd1de374Slin wang - Sun Microsystems - Beijing China } 432dd1de374Slin wang - Sun Microsystems - Beijing China 433dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 434dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI)); 435dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 436dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ)); 437dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", 438dd1de374Slin wang - Sun Microsystems - Beijing China iqCorrNeg)); 439dd1de374Slin wang - Sun Microsystems - Beijing China 440dd1de374Slin wang - Sun Microsystems - Beijing China iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; 441dd1de374Slin wang - Sun Microsystems - Beijing China qCoffDenom = powerMeasQ / 64; 442dd1de374Slin wang - Sun Microsystems - Beijing China 443dd1de374Slin wang - Sun Microsystems - Beijing China if (powerMeasQ != 0) { 444dd1de374Slin wang - Sun Microsystems - Beijing China iCoff = iqCorrMeas / iCoffDenom; 445dd1de374Slin wang - Sun Microsystems - Beijing China qCoff = powerMeasI / qCoffDenom - 64; 446dd1de374Slin wang - Sun Microsystems - Beijing China 447dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 448dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d iCoff = 0x%08x\n", i, iCoff)); 449dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 450dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d qCoff = 0x%08x\n", i, qCoff)); 451dd1de374Slin wang - Sun Microsystems - Beijing China 452dd1de374Slin wang - Sun Microsystems - Beijing China iCoff = iCoff & 0x3f; 453dd1de374Slin wang - Sun Microsystems - Beijing China 454dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 455dd1de374Slin wang - Sun Microsystems - Beijing China "New: Chn %d iCoff = 0x%08x\n", i, iCoff)); 456dd1de374Slin wang - Sun Microsystems - Beijing China 457dd1de374Slin wang - Sun Microsystems - Beijing China if (iqCorrNeg == 0x0) 458dd1de374Slin wang - Sun Microsystems - Beijing China iCoff = 0x40 - iCoff; 459dd1de374Slin wang - Sun Microsystems - Beijing China 460dd1de374Slin wang - Sun Microsystems - Beijing China if (qCoff > 15) 461dd1de374Slin wang - Sun Microsystems - Beijing China qCoff = 15; 462dd1de374Slin wang - Sun Microsystems - Beijing China else if (qCoff <= -16) 463dd1de374Slin wang - Sun Microsystems - Beijing China qCoff = 16; 464dd1de374Slin wang - Sun Microsystems - Beijing China 465dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 466dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", 467dd1de374Slin wang - Sun Microsystems - Beijing China i, iCoff, qCoff)); 468dd1de374Slin wang - Sun Microsystems - Beijing China 469dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), 470dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, 471dd1de374Slin wang - Sun Microsystems - Beijing China iCoff); 472dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), 473dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, 474dd1de374Slin wang - Sun Microsystems - Beijing China qCoff); 475dd1de374Slin wang - Sun Microsystems - Beijing China 476dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 477dd1de374Slin wang - Sun Microsystems - Beijing China "IQ Cal and Correction done for Chain %d\n", 478dd1de374Slin wang - Sun Microsystems - Beijing China i)); 479dd1de374Slin wang - Sun Microsystems - Beijing China } 480dd1de374Slin wang - Sun Microsystems - Beijing China } 481dd1de374Slin wang - Sun Microsystems - Beijing China 482dd1de374Slin wang - Sun Microsystems - Beijing China REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), 483dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_TIMING_CTRL4_IQCORR_ENABLE); 484dd1de374Slin wang - Sun Microsystems - Beijing China } 485dd1de374Slin wang - Sun Microsystems - Beijing China 486dd1de374Slin wang - Sun Microsystems - Beijing China static void 487dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, uint8_t numChains) 488dd1de374Slin wang - Sun Microsystems - Beijing China { 489dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 490dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, 491dd1de374Slin wang - Sun Microsystems - Beijing China qEvenMeasOffset; 492dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t qGainMismatch, iGainMismatch, val, i; 493dd1de374Slin wang - Sun Microsystems - Beijing China 494dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < numChains; i++) { 495dd1de374Slin wang - Sun Microsystems - Beijing China iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i]; 496dd1de374Slin wang - Sun Microsystems - Beijing China iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i]; 497dd1de374Slin wang - Sun Microsystems - Beijing China qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i]; 498dd1de374Slin wang - Sun Microsystems - Beijing China qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i]; 499dd1de374Slin wang - Sun Microsystems - Beijing China 500dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 501dd1de374Slin wang - Sun Microsystems - Beijing China "Starting ADC Gain Cal for Chain %d\n", i)); 502dd1de374Slin wang - Sun Microsystems - Beijing China 503dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 504dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d pwr_meas_odd_i = 0x%08x\n", i, 505dd1de374Slin wang - Sun Microsystems - Beijing China iOddMeasOffset)); 506dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 507dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d pwr_meas_even_i = 0x%08x\n", i, 508dd1de374Slin wang - Sun Microsystems - Beijing China iEvenMeasOffset)); 509dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 510dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d pwr_meas_odd_q = 0x%08x\n", i, 511dd1de374Slin wang - Sun Microsystems - Beijing China qOddMeasOffset)); 512dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 513dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d pwr_meas_even_q = 0x%08x\n", i, 514dd1de374Slin wang - Sun Microsystems - Beijing China qEvenMeasOffset)); 515dd1de374Slin wang - Sun Microsystems - Beijing China 516dd1de374Slin wang - Sun Microsystems - Beijing China if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { 517dd1de374Slin wang - Sun Microsystems - Beijing China iGainMismatch = 518dd1de374Slin wang - Sun Microsystems - Beijing China ((iEvenMeasOffset * 32) / 519dd1de374Slin wang - Sun Microsystems - Beijing China iOddMeasOffset) & 0x3f; 520dd1de374Slin wang - Sun Microsystems - Beijing China qGainMismatch = 521dd1de374Slin wang - Sun Microsystems - Beijing China ((qOddMeasOffset * 32) / 522dd1de374Slin wang - Sun Microsystems - Beijing China qEvenMeasOffset) & 0x3f; 523dd1de374Slin wang - Sun Microsystems - Beijing China 524dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 525dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d gain_mismatch_i = 0x%08x\n", i, 526dd1de374Slin wang - Sun Microsystems - Beijing China iGainMismatch)); 527dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 528dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d gain_mismatch_q = 0x%08x\n", i, 529dd1de374Slin wang - Sun Microsystems - Beijing China qGainMismatch)); 530dd1de374Slin wang - Sun Microsystems - Beijing China 531dd1de374Slin wang - Sun Microsystems - Beijing China val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); 532dd1de374Slin wang - Sun Microsystems - Beijing China val &= 0xfffff000; 533dd1de374Slin wang - Sun Microsystems - Beijing China val |= (qGainMismatch) | (iGainMismatch << 6); 534dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); 535dd1de374Slin wang - Sun Microsystems - Beijing China 536dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 537dd1de374Slin wang - Sun Microsystems - Beijing China "ADC Gain Cal done for Chain %d\n", i)); 538dd1de374Slin wang - Sun Microsystems - Beijing China } 539dd1de374Slin wang - Sun Microsystems - Beijing China } 540dd1de374Slin wang - Sun Microsystems - Beijing China 541dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), 542dd1de374Slin wang - Sun Microsystems - Beijing China REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | 543dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_NEW_ADC_GAIN_CORR_ENABLE); 544dd1de374Slin wang - Sun Microsystems - Beijing China } 545dd1de374Slin wang - Sun Microsystems - Beijing China 546dd1de374Slin wang - Sun Microsystems - Beijing China static void 547dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, uint8_t numChains) 548dd1de374Slin wang - Sun Microsystems - Beijing China { 549dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 550dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t iOddMeasOffset, iEvenMeasOffset, val, i; 551dd1de374Slin wang - Sun Microsystems - Beijing China int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch; 552dd1de374Slin wang - Sun Microsystems - Beijing China const struct hal_percal_data *calData = 553dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_cal_list_curr->calData; 554dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t numSamples = 555dd1de374Slin wang - Sun Microsystems - Beijing China (1 << (calData->calCountMax + 5)) * calData->calNumSamples; 556dd1de374Slin wang - Sun Microsystems - Beijing China 557dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < numChains; i++) { 558dd1de374Slin wang - Sun Microsystems - Beijing China iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i]; 559dd1de374Slin wang - Sun Microsystems - Beijing China iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i]; 560dd1de374Slin wang - Sun Microsystems - Beijing China qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i]; 561dd1de374Slin wang - Sun Microsystems - Beijing China qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i]; 562dd1de374Slin wang - Sun Microsystems - Beijing China 563dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 564dd1de374Slin wang - Sun Microsystems - Beijing China "Starting ADC DC Offset Cal for Chain %d\n", i)); 565dd1de374Slin wang - Sun Microsystems - Beijing China 566dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 567dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d pwr_meas_odd_i = %d\n", i, 568dd1de374Slin wang - Sun Microsystems - Beijing China iOddMeasOffset)); 569dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 570dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d pwr_meas_even_i = %d\n", i, 571dd1de374Slin wang - Sun Microsystems - Beijing China iEvenMeasOffset)); 572dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 573dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d pwr_meas_odd_q = %d\n", i, 574dd1de374Slin wang - Sun Microsystems - Beijing China qOddMeasOffset)); 575dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 576dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d pwr_meas_even_q = %d\n", i, 577dd1de374Slin wang - Sun Microsystems - Beijing China qEvenMeasOffset)); 578dd1de374Slin wang - Sun Microsystems - Beijing China 579dd1de374Slin wang - Sun Microsystems - Beijing China iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / 580dd1de374Slin wang - Sun Microsystems - Beijing China numSamples) & 0x1ff; 581dd1de374Slin wang - Sun Microsystems - Beijing China qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / 582dd1de374Slin wang - Sun Microsystems - Beijing China numSamples) & 0x1ff; 583dd1de374Slin wang - Sun Microsystems - Beijing China 584dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 585dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d dc_offset_mismatch_i = 0x%08x\n", i, 586dd1de374Slin wang - Sun Microsystems - Beijing China iDcMismatch)); 587dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 588dd1de374Slin wang - Sun Microsystems - Beijing China "Chn %d dc_offset_mismatch_q = 0x%08x\n", i, 589dd1de374Slin wang - Sun Microsystems - Beijing China qDcMismatch)); 590dd1de374Slin wang - Sun Microsystems - Beijing China 591dd1de374Slin wang - Sun Microsystems - Beijing China val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); 592dd1de374Slin wang - Sun Microsystems - Beijing China val &= 0xc0000fff; 593dd1de374Slin wang - Sun Microsystems - Beijing China val |= (qDcMismatch << 12) | (iDcMismatch << 21); 594dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); 595dd1de374Slin wang - Sun Microsystems - Beijing China 596dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 597dd1de374Slin wang - Sun Microsystems - Beijing China "ADC DC Offset Cal done for Chain %d\n", i)); 598dd1de374Slin wang - Sun Microsystems - Beijing China } 599dd1de374Slin wang - Sun Microsystems - Beijing China 600dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), 601dd1de374Slin wang - Sun Microsystems - Beijing China REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | 602dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE); 603dd1de374Slin wang - Sun Microsystems - Beijing China } 604dd1de374Slin wang - Sun Microsystems - Beijing China 605dd1de374Slin wang - Sun Microsystems - Beijing China void 606dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan, 607dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t *isCalDone) 608dd1de374Slin wang - Sun Microsystems - Beijing China { 609dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 610dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *ichan = 611dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_check_channel(ah, chan); 612dd1de374Slin wang - Sun Microsystems - Beijing China struct hal_cal_list *currCal = ahp->ah_cal_list_curr; 613dd1de374Slin wang - Sun Microsystems - Beijing China 614dd1de374Slin wang - Sun Microsystems - Beijing China *isCalDone = B_TRUE; 615dd1de374Slin wang - Sun Microsystems - Beijing China 616dd1de374Slin wang - Sun Microsystems - Beijing China if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah)) 617dd1de374Slin wang - Sun Microsystems - Beijing China return; 618dd1de374Slin wang - Sun Microsystems - Beijing China 619dd1de374Slin wang - Sun Microsystems - Beijing China if (currCal == NULL) 620dd1de374Slin wang - Sun Microsystems - Beijing China return; 621dd1de374Slin wang - Sun Microsystems - Beijing China 622dd1de374Slin wang - Sun Microsystems - Beijing China if (ichan == NULL) { 623dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 624dd1de374Slin wang - Sun Microsystems - Beijing China "%s: invalid channel %u/0x%x; no mapping\n", 625dd1de374Slin wang - Sun Microsystems - Beijing China __func__, chan->channel, chan->channelFlags)); 626dd1de374Slin wang - Sun Microsystems - Beijing China return; 627dd1de374Slin wang - Sun Microsystems - Beijing China } 628dd1de374Slin wang - Sun Microsystems - Beijing China 629dd1de374Slin wang - Sun Microsystems - Beijing China 630dd1de374Slin wang - Sun Microsystems - Beijing China if (currCal->calState != CAL_DONE) { 631dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 632dd1de374Slin wang - Sun Microsystems - Beijing China "%s: Calibration state incorrect, %d\n", 633dd1de374Slin wang - Sun Microsystems - Beijing China __func__, currCal->calState)); 634dd1de374Slin wang - Sun Microsystems - Beijing China return; 635dd1de374Slin wang - Sun Microsystems - Beijing China } 636dd1de374Slin wang - Sun Microsystems - Beijing China 637dd1de374Slin wang - Sun Microsystems - Beijing China 638dd1de374Slin wang - Sun Microsystems - Beijing China if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType)) 639dd1de374Slin wang - Sun Microsystems - Beijing China return; 640dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 641dd1de374Slin wang - Sun Microsystems - Beijing China "%s: Resetting Cal %d state for channel %u/0x%x\n", 642dd1de374Slin wang - Sun Microsystems - Beijing China __func__, currCal->calData->calType, chan->channel, 643dd1de374Slin wang - Sun Microsystems - Beijing China chan->channelFlags)); 644dd1de374Slin wang - Sun Microsystems - Beijing China 645dd1de374Slin wang - Sun Microsystems - Beijing China ichan->CalValid &= ~currCal->calData->calType; 646dd1de374Slin wang - Sun Microsystems - Beijing China currCal->calState = CAL_WAITING; 647dd1de374Slin wang - Sun Microsystems - Beijing China 648dd1de374Slin wang - Sun Microsystems - Beijing China *isCalDone = B_FALSE; 649dd1de374Slin wang - Sun Microsystems - Beijing China } 650dd1de374Slin wang - Sun Microsystems - Beijing China 651dd1de374Slin wang - Sun Microsystems - Beijing China void 652dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_start_nfcal(struct ath_hal *ah) 653dd1de374Slin wang - Sun Microsystems - Beijing China { 654dd1de374Slin wang - Sun Microsystems - Beijing China REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, 655dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_AGC_CONTROL_ENABLE_NF); 656dd1de374Slin wang - Sun Microsystems - Beijing China REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, 657dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_AGC_CONTROL_NO_UPDATE_NF); 658dd1de374Slin wang - Sun Microsystems - Beijing China REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); 659dd1de374Slin wang - Sun Microsystems - Beijing China } 660dd1de374Slin wang - Sun Microsystems - Beijing China 661dd1de374Slin wang - Sun Microsystems - Beijing China /* ARGSUSED */ 662dd1de374Slin wang - Sun Microsystems - Beijing China void 663dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan) 664dd1de374Slin wang - Sun Microsystems - Beijing China { 665dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_nfcal_hist *h; 666dd1de374Slin wang - Sun Microsystems - Beijing China int i, j; 667dd1de374Slin wang - Sun Microsystems - Beijing China int32_t val; 668dd1de374Slin wang - Sun Microsystems - Beijing China const uint32_t ar5416_cca_regs[6] = { 669dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CCA, 670dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CH1_CCA, 671dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CH2_CCA, 672dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_EXT_CCA, 673dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CH1_EXT_CCA, 674dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CH2_EXT_CCA 675dd1de374Slin wang - Sun Microsystems - Beijing China }; 676dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t chainmask; 677dd1de374Slin wang - Sun Microsystems - Beijing China 678dd1de374Slin wang - Sun Microsystems - Beijing China if (AR_SREV_9280(ah)) 679dd1de374Slin wang - Sun Microsystems - Beijing China chainmask = 0x1B; 680dd1de374Slin wang - Sun Microsystems - Beijing China else 681dd1de374Slin wang - Sun Microsystems - Beijing China chainmask = 0x3F; 682dd1de374Slin wang - Sun Microsystems - Beijing China 683dd1de374Slin wang - Sun Microsystems - Beijing China #ifdef ARN_NF_PER_CHAN 684dd1de374Slin wang - Sun Microsystems - Beijing China h = chan->nfCalHist; 685dd1de374Slin wang - Sun Microsystems - Beijing China #else 686dd1de374Slin wang - Sun Microsystems - Beijing China h = ah->nfCalHist; 687dd1de374Slin wang - Sun Microsystems - Beijing China #endif 688dd1de374Slin wang - Sun Microsystems - Beijing China 689dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < NUM_NF_READINGS; i++) { 690dd1de374Slin wang - Sun Microsystems - Beijing China if (chainmask & (1 << i)) { 691dd1de374Slin wang - Sun Microsystems - Beijing China val = REG_READ(ah, ar5416_cca_regs[i]); 692dd1de374Slin wang - Sun Microsystems - Beijing China val &= 0xFFFFFE00; 693dd1de374Slin wang - Sun Microsystems - Beijing China val |= (((uint32_t)(h[i].privNF) << 1) & 0x1ff); 694dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, ar5416_cca_regs[i], val); 695dd1de374Slin wang - Sun Microsystems - Beijing China } 696dd1de374Slin wang - Sun Microsystems - Beijing China } 697dd1de374Slin wang - Sun Microsystems - Beijing China 698dd1de374Slin wang - Sun Microsystems - Beijing China REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, 699dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_AGC_CONTROL_ENABLE_NF); 700dd1de374Slin wang - Sun Microsystems - Beijing China REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, 701dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_AGC_CONTROL_NO_UPDATE_NF); 702dd1de374Slin wang - Sun Microsystems - Beijing China REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); 703dd1de374Slin wang - Sun Microsystems - Beijing China 704dd1de374Slin wang - Sun Microsystems - Beijing China for (j = 0; j < 1000; j++) { 705dd1de374Slin wang - Sun Microsystems - Beijing China if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & 706dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_AGC_CONTROL_NF) == 0) 707dd1de374Slin wang - Sun Microsystems - Beijing China break; 708dd1de374Slin wang - Sun Microsystems - Beijing China drv_usecwait(10); 709dd1de374Slin wang - Sun Microsystems - Beijing China } 710dd1de374Slin wang - Sun Microsystems - Beijing China 711dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < NUM_NF_READINGS; i++) { 712dd1de374Slin wang - Sun Microsystems - Beijing China if (chainmask & (1 << i)) { 713dd1de374Slin wang - Sun Microsystems - Beijing China val = REG_READ(ah, ar5416_cca_regs[i]); 714dd1de374Slin wang - Sun Microsystems - Beijing China val &= 0xFFFFFE00; 715dd1de374Slin wang - Sun Microsystems - Beijing China val |= (((uint32_t)(-50) << 1) & 0x1ff); 716dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, ar5416_cca_regs[i], val); 717dd1de374Slin wang - Sun Microsystems - Beijing China } 718dd1de374Slin wang - Sun Microsystems - Beijing China } 719dd1de374Slin wang - Sun Microsystems - Beijing China } 720dd1de374Slin wang - Sun Microsystems - Beijing China 721dd1de374Slin wang - Sun Microsystems - Beijing China int16_t 722dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_getnf(struct ath_hal *ah, struct ath9k_channel *chan) 723dd1de374Slin wang - Sun Microsystems - Beijing China { 724dd1de374Slin wang - Sun Microsystems - Beijing China int16_t nf, nfThresh; 725dd1de374Slin wang - Sun Microsystems - Beijing China int16_t nfarray[NUM_NF_READINGS] = { 0 }; 726dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_nfcal_hist *h; 727dd1de374Slin wang - Sun Microsystems - Beijing China /* LINTED E_FUNC_SET_NOT_USED */ 728dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t chainmask; 729dd1de374Slin wang - Sun Microsystems - Beijing China 730dd1de374Slin wang - Sun Microsystems - Beijing China if (AR_SREV_9280(ah)) 731dd1de374Slin wang - Sun Microsystems - Beijing China chainmask = 0x1B; 732dd1de374Slin wang - Sun Microsystems - Beijing China else 733dd1de374Slin wang - Sun Microsystems - Beijing China chainmask = 0x3F; 734dd1de374Slin wang - Sun Microsystems - Beijing China 735dd1de374Slin wang - Sun Microsystems - Beijing China chan->channelFlags &= (~CHANNEL_CW_INT); 736dd1de374Slin wang - Sun Microsystems - Beijing China if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { 737dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, "arn: " 738dd1de374Slin wang - Sun Microsystems - Beijing China "%s: NF did not complete in calibration window\n", 739dd1de374Slin wang - Sun Microsystems - Beijing China __func__)); 740dd1de374Slin wang - Sun Microsystems - Beijing China nf = 0; 741dd1de374Slin wang - Sun Microsystems - Beijing China chan->rawNoiseFloor = nf; 742dd1de374Slin wang - Sun Microsystems - Beijing China return (chan->rawNoiseFloor); 743dd1de374Slin wang - Sun Microsystems - Beijing China } else { 744dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_do_getnf(ah, nfarray); 745dd1de374Slin wang - Sun Microsystems - Beijing China nf = nfarray[0]; 746dd1de374Slin wang - Sun Microsystems - Beijing China if (getNoiseFloorThresh(ah, chan, &nfThresh) && 747dd1de374Slin wang - Sun Microsystems - Beijing China nf > nfThresh) { 748dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, "arn: " 749dd1de374Slin wang - Sun Microsystems - Beijing China "%s: noise floor failed detected; " 750dd1de374Slin wang - Sun Microsystems - Beijing China "detected %d, threshold %d\n", __func__, 751dd1de374Slin wang - Sun Microsystems - Beijing China nf, nfThresh)); 752dd1de374Slin wang - Sun Microsystems - Beijing China chan->channelFlags |= CHANNEL_CW_INT; 753dd1de374Slin wang - Sun Microsystems - Beijing China } 754dd1de374Slin wang - Sun Microsystems - Beijing China } 755dd1de374Slin wang - Sun Microsystems - Beijing China 756dd1de374Slin wang - Sun Microsystems - Beijing China #ifdef ARN_NF_PER_CHAN 757dd1de374Slin wang - Sun Microsystems - Beijing China h = chan->nfCalHist; 758dd1de374Slin wang - Sun Microsystems - Beijing China #else 759dd1de374Slin wang - Sun Microsystems - Beijing China h = ah->nfCalHist; 760dd1de374Slin wang - Sun Microsystems - Beijing China #endif 761dd1de374Slin wang - Sun Microsystems - Beijing China 762dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_update_nfcal_hist_buffer(h, nfarray); 763dd1de374Slin wang - Sun Microsystems - Beijing China chan->rawNoiseFloor = h[0].privNF; 764dd1de374Slin wang - Sun Microsystems - Beijing China 765dd1de374Slin wang - Sun Microsystems - Beijing China return (chan->rawNoiseFloor); 766dd1de374Slin wang - Sun Microsystems - Beijing China } 767dd1de374Slin wang - Sun Microsystems - Beijing China 768dd1de374Slin wang - Sun Microsystems - Beijing China void 769dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_init_nfcal_hist_buffer(struct ath_hal *ah) 770dd1de374Slin wang - Sun Microsystems - Beijing China { 771dd1de374Slin wang - Sun Microsystems - Beijing China int i, j; 772*c0c93480Slin wang - Sun Microsystems - Beijing China int16_t noise_floor; 773*c0c93480Slin wang - Sun Microsystems - Beijing China 774*c0c93480Slin wang - Sun Microsystems - Beijing China if (AR_SREV_9280(ah)) 775*c0c93480Slin wang - Sun Microsystems - Beijing China noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE; 776*c0c93480Slin wang - Sun Microsystems - Beijing China else if (AR_SREV_9285(ah)) 777*c0c93480Slin wang - Sun Microsystems - Beijing China noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE; 778*c0c93480Slin wang - Sun Microsystems - Beijing China else 779*c0c93480Slin wang - Sun Microsystems - Beijing China noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE; 780dd1de374Slin wang - Sun Microsystems - Beijing China 781dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < NUM_NF_READINGS; i++) { 782dd1de374Slin wang - Sun Microsystems - Beijing China ah->nfCalHist[i].currIndex = 0; 783*c0c93480Slin wang - Sun Microsystems - Beijing China ah->nfCalHist[i].privNF = noise_floor; 784dd1de374Slin wang - Sun Microsystems - Beijing China ah->nfCalHist[i].invalidNFcount = 785dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CCA_FILTERWINDOW_LENGTH; 786dd1de374Slin wang - Sun Microsystems - Beijing China for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { 787*c0c93480Slin wang - Sun Microsystems - Beijing China ah->nfCalHist[i].nfCalBuffer[j] = noise_floor; 788dd1de374Slin wang - Sun Microsystems - Beijing China } 789dd1de374Slin wang - Sun Microsystems - Beijing China } 790dd1de374Slin wang - Sun Microsystems - Beijing China } 791dd1de374Slin wang - Sun Microsystems - Beijing China 792dd1de374Slin wang - Sun Microsystems - Beijing China signed short 793dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) 794dd1de374Slin wang - Sun Microsystems - Beijing China { 795dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *ichan; 796dd1de374Slin wang - Sun Microsystems - Beijing China signed short nf; 797dd1de374Slin wang - Sun Microsystems - Beijing China 798dd1de374Slin wang - Sun Microsystems - Beijing China ichan = ath9k_regd_check_channel(ah, chan); 799dd1de374Slin wang - Sun Microsystems - Beijing China if (ichan == NULL) { 800dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 801dd1de374Slin wang - Sun Microsystems - Beijing China "%s: invalid channel %u/0x%x; no mapping\n", 802dd1de374Slin wang - Sun Microsystems - Beijing China __func__, chan->channel, chan->channelFlags)); 803dd1de374Slin wang - Sun Microsystems - Beijing China return (ATH_DEFAULT_NOISE_FLOOR); 804dd1de374Slin wang - Sun Microsystems - Beijing China } 805dd1de374Slin wang - Sun Microsystems - Beijing China if (ichan->rawNoiseFloor == 0) { 806dd1de374Slin wang - Sun Microsystems - Beijing China enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan); 807dd1de374Slin wang - Sun Microsystems - Beijing China nf = NOISE_FLOOR[mode]; 808dd1de374Slin wang - Sun Microsystems - Beijing China } else 809dd1de374Slin wang - Sun Microsystems - Beijing China nf = ichan->rawNoiseFloor; 810dd1de374Slin wang - Sun Microsystems - Beijing China 811dd1de374Slin wang - Sun Microsystems - Beijing China if (!ath9k_hw_nf_in_range(ah, nf)) 812dd1de374Slin wang - Sun Microsystems - Beijing China nf = ATH_DEFAULT_NOISE_FLOOR; 813dd1de374Slin wang - Sun Microsystems - Beijing China 814dd1de374Slin wang - Sun Microsystems - Beijing China return (nf); 815dd1de374Slin wang - Sun Microsystems - Beijing China } 816dd1de374Slin wang - Sun Microsystems - Beijing China 817dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t 818dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, 819dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t rxchainmask, boolean_t longcal, 820dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t *isCalDone) 821dd1de374Slin wang - Sun Microsystems - Beijing China { 822dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 823dd1de374Slin wang - Sun Microsystems - Beijing China struct hal_cal_list *currCal = ahp->ah_cal_list_curr; 824dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan); 825dd1de374Slin wang - Sun Microsystems - Beijing China 826dd1de374Slin wang - Sun Microsystems - Beijing China *isCalDone = B_TRUE; 827dd1de374Slin wang - Sun Microsystems - Beijing China 828dd1de374Slin wang - Sun Microsystems - Beijing China if (ichan == NULL) { 829dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CHANNEL, 830dd1de374Slin wang - Sun Microsystems - Beijing China "%s: invalid channel %u/0x%x; no mapping\n", 831dd1de374Slin wang - Sun Microsystems - Beijing China __func__, chan->channel, chan->channelFlags)); 832dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 833dd1de374Slin wang - Sun Microsystems - Beijing China } 834dd1de374Slin wang - Sun Microsystems - Beijing China 835dd1de374Slin wang - Sun Microsystems - Beijing China if (currCal && 836dd1de374Slin wang - Sun Microsystems - Beijing China (currCal->calState == CAL_RUNNING || 837dd1de374Slin wang - Sun Microsystems - Beijing China currCal->calState == CAL_WAITING)) { 838dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal, 839dd1de374Slin wang - Sun Microsystems - Beijing China isCalDone); 840dd1de374Slin wang - Sun Microsystems - Beijing China if (*isCalDone) { 841dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_cal_list_curr = currCal = currCal->calNext; 842dd1de374Slin wang - Sun Microsystems - Beijing China 843dd1de374Slin wang - Sun Microsystems - Beijing China if (currCal->calState == CAL_WAITING) { 844dd1de374Slin wang - Sun Microsystems - Beijing China *isCalDone = B_FALSE; 845dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_reset_calibration(ah, currCal); 846dd1de374Slin wang - Sun Microsystems - Beijing China } 847dd1de374Slin wang - Sun Microsystems - Beijing China } 848dd1de374Slin wang - Sun Microsystems - Beijing China } 849dd1de374Slin wang - Sun Microsystems - Beijing China 850dd1de374Slin wang - Sun Microsystems - Beijing China if (longcal) { 851dd1de374Slin wang - Sun Microsystems - Beijing China (void) ath9k_hw_getnf(ah, ichan); 852dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_loadnf(ah, ah->ah_curchan); 853dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_start_nfcal(ah); 854dd1de374Slin wang - Sun Microsystems - Beijing China 855dd1de374Slin wang - Sun Microsystems - Beijing China if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) { 856dd1de374Slin wang - Sun Microsystems - Beijing China chan->channelFlags |= CHANNEL_CW_INT; 857dd1de374Slin wang - Sun Microsystems - Beijing China ichan->channelFlags &= ~CHANNEL_CW_INT; 858dd1de374Slin wang - Sun Microsystems - Beijing China } 859dd1de374Slin wang - Sun Microsystems - Beijing China } 860dd1de374Slin wang - Sun Microsystems - Beijing China 861dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 862dd1de374Slin wang - Sun Microsystems - Beijing China } 863dd1de374Slin wang - Sun Microsystems - Beijing China 864dd1de374Slin wang - Sun Microsystems - Beijing China /* AR9285 */ 865dd1de374Slin wang - Sun Microsystems - Beijing China static inline void 866dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_9285_pa_cal(struct ath_hal *ah) 867dd1de374Slin wang - Sun Microsystems - Beijing China { 868dd1de374Slin wang - Sun Microsystems - Beijing China 869dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t regVal; 870dd1de374Slin wang - Sun Microsystems - Beijing China int i, offset, offs_6_1, offs_0; 871dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t ccomp_org, reg_field; 872dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t regList[][2] = { 873dd1de374Slin wang - Sun Microsystems - Beijing China { 0x786c, 0 }, 874dd1de374Slin wang - Sun Microsystems - Beijing China { 0x7854, 0 }, 875dd1de374Slin wang - Sun Microsystems - Beijing China { 0x7820, 0 }, 876dd1de374Slin wang - Sun Microsystems - Beijing China { 0x7824, 0 }, 877dd1de374Slin wang - Sun Microsystems - Beijing China { 0x7868, 0 }, 878dd1de374Slin wang - Sun Microsystems - Beijing China { 0x783c, 0 }, 879dd1de374Slin wang - Sun Microsystems - Beijing China { 0x7838, 0 }, 880dd1de374Slin wang - Sun Microsystems - Beijing China }; 881dd1de374Slin wang - Sun Microsystems - Beijing China 882dd1de374Slin wang - Sun Microsystems - Beijing China if (AR_SREV_9285_11(ah)) { 883dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); 884dd1de374Slin wang - Sun Microsystems - Beijing China drv_usecwait(10); 885dd1de374Slin wang - Sun Microsystems - Beijing China } 886dd1de374Slin wang - Sun Microsystems - Beijing China 887dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(regList); i++) 888dd1de374Slin wang - Sun Microsystems - Beijing China regList[i][1] = REG_READ(ah, regList[i][0]); 889dd1de374Slin wang - Sun Microsystems - Beijing China 890dd1de374Slin wang - Sun Microsystems - Beijing China regVal = REG_READ(ah, 0x7834); 891dd1de374Slin wang - Sun Microsystems - Beijing China regVal &= (~(0x1)); 892dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, 0x7834, regVal); 893dd1de374Slin wang - Sun Microsystems - Beijing China regVal = REG_READ(ah, 0x9808); 894dd1de374Slin wang - Sun Microsystems - Beijing China regVal |= (0x1 << 27); 895dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, 0x9808, regVal); 896dd1de374Slin wang - Sun Microsystems - Beijing China 897dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1); 898dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1); 899dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1); 900dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1); 901dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0); 902dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0); 903dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0); 904dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 1); 905dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0); 906dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0); 907dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7); 908dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0); 909dd1de374Slin wang - Sun Microsystems - Beijing China ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP); 910dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 7); 911dd1de374Slin wang - Sun Microsystems - Beijing China 912dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0); 913dd1de374Slin wang - Sun Microsystems - Beijing China drv_usecwait(30); 914dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0); 915dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0); 916dd1de374Slin wang - Sun Microsystems - Beijing China 917dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 6; i > 0; i--) { 918dd1de374Slin wang - Sun Microsystems - Beijing China regVal = REG_READ(ah, 0x7834); 919dd1de374Slin wang - Sun Microsystems - Beijing China regVal |= (1 << (19 + i)); 920dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, 0x7834, regVal); 921dd1de374Slin wang - Sun Microsystems - Beijing China drv_usecwait(1); 922dd1de374Slin wang - Sun Microsystems - Beijing China regVal = REG_READ(ah, 0x7834); 923dd1de374Slin wang - Sun Microsystems - Beijing China regVal &= (~(0x1 << (19 + i))); 924dd1de374Slin wang - Sun Microsystems - Beijing China reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9); 925dd1de374Slin wang - Sun Microsystems - Beijing China regVal |= (reg_field << (19 + i)); 926dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, 0x7834, regVal); 927dd1de374Slin wang - Sun Microsystems - Beijing China } 928dd1de374Slin wang - Sun Microsystems - Beijing China 929dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1); 930dd1de374Slin wang - Sun Microsystems - Beijing China drv_usecwait(1); 931dd1de374Slin wang - Sun Microsystems - Beijing China reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9); 932dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field); 933dd1de374Slin wang - Sun Microsystems - Beijing China offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS); 934dd1de374Slin wang - Sun Microsystems - Beijing China offs_0 = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP); 935dd1de374Slin wang - Sun Microsystems - Beijing China 936dd1de374Slin wang - Sun Microsystems - Beijing China offset = (offs_6_1<<1) | offs_0; 937dd1de374Slin wang - Sun Microsystems - Beijing China offset = offset - 0; 938dd1de374Slin wang - Sun Microsystems - Beijing China offs_6_1 = offset>>1; 939dd1de374Slin wang - Sun Microsystems - Beijing China offs_0 = offset & 1; 940dd1de374Slin wang - Sun Microsystems - Beijing China 941dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1); 942dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0); 943dd1de374Slin wang - Sun Microsystems - Beijing China 944dd1de374Slin wang - Sun Microsystems - Beijing China regVal = REG_READ(ah, 0x7834); 945dd1de374Slin wang - Sun Microsystems - Beijing China regVal |= 0x1; 946dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, 0x7834, regVal); 947dd1de374Slin wang - Sun Microsystems - Beijing China regVal = REG_READ(ah, 0x9808); 948dd1de374Slin wang - Sun Microsystems - Beijing China regVal &= (~(0x1 << 27)); 949dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, 0x9808, regVal); 950dd1de374Slin wang - Sun Microsystems - Beijing China 951dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(regList); i++) 952dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, regList[i][0], regList[i][1]); 953dd1de374Slin wang - Sun Microsystems - Beijing China 954dd1de374Slin wang - Sun Microsystems - Beijing China REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org); 955dd1de374Slin wang - Sun Microsystems - Beijing China 956dd1de374Slin wang - Sun Microsystems - Beijing China if (AR_SREV_9285_11(ah)) 957dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); 958dd1de374Slin wang - Sun Microsystems - Beijing China 959dd1de374Slin wang - Sun Microsystems - Beijing China } 960dd1de374Slin wang - Sun Microsystems - Beijing China 961dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t 962dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_init_cal(struct ath_hal *ah, 963dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *chan) 964dd1de374Slin wang - Sun Microsystems - Beijing China { 965dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal_5416 *ahp = AH5416(ah); 966dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan); 967dd1de374Slin wang - Sun Microsystems - Beijing China 968dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_AGC_CONTROL, 969dd1de374Slin wang - Sun Microsystems - Beijing China REG_READ(ah, AR_PHY_AGC_CONTROL) | 970dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_AGC_CONTROL_CAL); 971dd1de374Slin wang - Sun Microsystems - Beijing China 972dd1de374Slin wang - Sun Microsystems - Beijing China if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) { 973dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 974dd1de374Slin wang - Sun Microsystems - Beijing China "%s: offset calibration failed to complete in 1ms; " 975dd1de374Slin wang - Sun Microsystems - Beijing China "noisy environment?\n", __func__)); 976dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 977dd1de374Slin wang - Sun Microsystems - Beijing China } 978dd1de374Slin wang - Sun Microsystems - Beijing China 979dd1de374Slin wang - Sun Microsystems - Beijing China if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah)) 980dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_9285_pa_cal(ah); 981dd1de374Slin wang - Sun Microsystems - Beijing China 982dd1de374Slin wang - Sun Microsystems - Beijing China REG_WRITE(ah, AR_PHY_AGC_CONTROL, 983dd1de374Slin wang - Sun Microsystems - Beijing China REG_READ(ah, AR_PHY_AGC_CONTROL) | 984dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_AGC_CONTROL_NF); 985dd1de374Slin wang - Sun Microsystems - Beijing China 986dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL; 987dd1de374Slin wang - Sun Microsystems - Beijing China 988dd1de374Slin wang - Sun Microsystems - Beijing China if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { 989dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) { 990dd1de374Slin wang - Sun Microsystems - Beijing China /* LINTED: E_CONSTANT_CONDITION */ 991dd1de374Slin wang - Sun Microsystems - Beijing China INIT_CAL(&ahp->ah_adcGainCalData); 992dd1de374Slin wang - Sun Microsystems - Beijing China /* LINTED: E_CONSTANT_CONDITION */ 993dd1de374Slin wang - Sun Microsystems - Beijing China INSERT_CAL(ahp, &ahp->ah_adcGainCalData); 994dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 995dd1de374Slin wang - Sun Microsystems - Beijing China "%s: enabling ADC Gain Calibration.\n", 996dd1de374Slin wang - Sun Microsystems - Beijing China __func__)); 997dd1de374Slin wang - Sun Microsystems - Beijing China } 998dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) { 999dd1de374Slin wang - Sun Microsystems - Beijing China /* LINTED: E_CONSTANT_CONDITION */ 1000dd1de374Slin wang - Sun Microsystems - Beijing China INIT_CAL(&ahp->ah_adcDcCalData); 1001dd1de374Slin wang - Sun Microsystems - Beijing China /* LINTED: E_CONSTANT_CONDITION */ 1002dd1de374Slin wang - Sun Microsystems - Beijing China INSERT_CAL(ahp, &ahp->ah_adcDcCalData); 1003dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 1004dd1de374Slin wang - Sun Microsystems - Beijing China "%s: enabling ADC DC Calibration.\n", 1005dd1de374Slin wang - Sun Microsystems - Beijing China __func__)); 1006dd1de374Slin wang - Sun Microsystems - Beijing China } 1007dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) { 1008dd1de374Slin wang - Sun Microsystems - Beijing China /* LINTED: E_CONSTANT_CONDITION */ 1009dd1de374Slin wang - Sun Microsystems - Beijing China INIT_CAL(&ahp->ah_iqCalData); 1010dd1de374Slin wang - Sun Microsystems - Beijing China /* LINTED: E_CONSTANT_CONDITION */ 1011dd1de374Slin wang - Sun Microsystems - Beijing China INSERT_CAL(ahp, &ahp->ah_iqCalData); 1012dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_CALIBRATE, 1013dd1de374Slin wang - Sun Microsystems - Beijing China "%s: enabling IQ Calibration.\n", 1014dd1de374Slin wang - Sun Microsystems - Beijing China __func__)); 1015dd1de374Slin wang - Sun Microsystems - Beijing China } 1016dd1de374Slin wang - Sun Microsystems - Beijing China 1017dd1de374Slin wang - Sun Microsystems - Beijing China ahp->ah_cal_list_curr = ahp->ah_cal_list; 1018dd1de374Slin wang - Sun Microsystems - Beijing China 1019dd1de374Slin wang - Sun Microsystems - Beijing China if (ahp->ah_cal_list_curr) 1020dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr); 1021dd1de374Slin wang - Sun Microsystems - Beijing China } 1022dd1de374Slin wang - Sun Microsystems - Beijing China 1023dd1de374Slin wang - Sun Microsystems - Beijing China ichan->CalValid = 0; 1024dd1de374Slin wang - Sun Microsystems - Beijing China 1025dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 1026dd1de374Slin wang - Sun Microsystems - Beijing China } 1027dd1de374Slin wang - Sun Microsystems - Beijing China 1028dd1de374Slin wang - Sun Microsystems - Beijing China const struct hal_percal_data iq_cal_multi_sample = { 1029dd1de374Slin wang - Sun Microsystems - Beijing China IQ_MISMATCH_CAL, 1030dd1de374Slin wang - Sun Microsystems - Beijing China MAX_CAL_SAMPLES, 1031dd1de374Slin wang - Sun Microsystems - Beijing China PER_MIN_LOG_COUNT, 1032dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_iqcal_collect, 1033dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_iqcalibrate 1034dd1de374Slin wang - Sun Microsystems - Beijing China }; 1035dd1de374Slin wang - Sun Microsystems - Beijing China const struct hal_percal_data iq_cal_single_sample = { 1036dd1de374Slin wang - Sun Microsystems - Beijing China IQ_MISMATCH_CAL, 1037dd1de374Slin wang - Sun Microsystems - Beijing China MIN_CAL_SAMPLES, 1038dd1de374Slin wang - Sun Microsystems - Beijing China PER_MAX_LOG_COUNT, 1039dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_iqcal_collect, 1040dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_iqcalibrate 1041dd1de374Slin wang - Sun Microsystems - Beijing China }; 1042dd1de374Slin wang - Sun Microsystems - Beijing China const struct hal_percal_data adc_gain_cal_multi_sample = { 1043dd1de374Slin wang - Sun Microsystems - Beijing China ADC_GAIN_CAL, 1044dd1de374Slin wang - Sun Microsystems - Beijing China MAX_CAL_SAMPLES, 1045dd1de374Slin wang - Sun Microsystems - Beijing China PER_MIN_LOG_COUNT, 1046dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_gaincal_collect, 1047dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_gaincal_calibrate 1048dd1de374Slin wang - Sun Microsystems - Beijing China }; 1049dd1de374Slin wang - Sun Microsystems - Beijing China const struct hal_percal_data adc_gain_cal_single_sample = { 1050dd1de374Slin wang - Sun Microsystems - Beijing China ADC_GAIN_CAL, 1051dd1de374Slin wang - Sun Microsystems - Beijing China MIN_CAL_SAMPLES, 1052dd1de374Slin wang - Sun Microsystems - Beijing China PER_MAX_LOG_COUNT, 1053dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_gaincal_collect, 1054dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_gaincal_calibrate 1055dd1de374Slin wang - Sun Microsystems - Beijing China }; 1056dd1de374Slin wang - Sun Microsystems - Beijing China const struct hal_percal_data adc_dc_cal_multi_sample = { 1057dd1de374Slin wang - Sun Microsystems - Beijing China ADC_DC_CAL, 1058dd1de374Slin wang - Sun Microsystems - Beijing China MAX_CAL_SAMPLES, 1059dd1de374Slin wang - Sun Microsystems - Beijing China PER_MIN_LOG_COUNT, 1060dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_dccal_collect, 1061dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_dccal_calibrate 1062dd1de374Slin wang - Sun Microsystems - Beijing China }; 1063dd1de374Slin wang - Sun Microsystems - Beijing China const struct hal_percal_data adc_dc_cal_single_sample = { 1064dd1de374Slin wang - Sun Microsystems - Beijing China ADC_DC_CAL, 1065dd1de374Slin wang - Sun Microsystems - Beijing China MIN_CAL_SAMPLES, 1066dd1de374Slin wang - Sun Microsystems - Beijing China PER_MAX_LOG_COUNT, 1067dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_dccal_collect, 1068dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_dccal_calibrate 1069dd1de374Slin wang - Sun Microsystems - Beijing China }; 1070dd1de374Slin wang - Sun Microsystems - Beijing China const struct hal_percal_data adc_init_dc_cal = { 1071dd1de374Slin wang - Sun Microsystems - Beijing China ADC_DC_INIT_CAL, 1072dd1de374Slin wang - Sun Microsystems - Beijing China MIN_CAL_SAMPLES, 1073dd1de374Slin wang - Sun Microsystems - Beijing China INIT_LOG_COUNT, 1074dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_dccal_collect, 1075dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_hw_adc_dccal_calibrate 1076dd1de374Slin wang - Sun Microsystems - Beijing China }; 1077