xref: /titanic_41/usr/src/uts/common/io/arn/arn_calib.c (revision c0c934808d1b7d058148814255f32064a0e09555)
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
ath9k_hw_nf_in_range(struct ath_hal * ah,signed short nf)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
ath9k_hw_get_nf_hist_mid(int16_t * nfCalBuffer)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
ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist * h,int16_t * nfarray)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
ath9k_hw_do_getnf(struct ath_hal * ah,int16_t nfarray[NUM_NF_READINGS])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
getNoiseFloorThresh(struct ath_hal * ah,const struct ath9k_channel * chan,int16_t * nft)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
ath9k_hw_setup_calibration(struct ath_hal * ah,struct hal_cal_list * currCal)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
ath9k_hw_reset_calibration(struct ath_hal * ah,struct hal_cal_list * currCal)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
ath9k_hw_per_calibration(struct ath_hal * ah,struct ath9k_channel * ichan,uint8_t rxchainmask,struct hal_cal_list * currCal,boolean_t * isCalDone)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
ath9k_hw_iscal_supported(struct ath_hal * ah,struct ath9k_channel * chan,enum hal_cal_types calType)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
ath9k_hw_iqcal_collect(struct ath_hal * ah)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
ath9k_hw_adc_gaincal_collect(struct ath_hal * ah)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
ath9k_hw_adc_dccal_collect(struct ath_hal * ah)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
ath9k_hw_iqcalibrate(struct ath_hal * ah,uint8_t numChains)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
ath9k_hw_adc_gaincal_calibrate(struct ath_hal * ah,uint8_t numChains)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
ath9k_hw_adc_dccal_calibrate(struct ath_hal * ah,uint8_t numChains)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
ath9k_hw_reset_calvalid(struct ath_hal * ah,struct ath9k_channel * chan,boolean_t * isCalDone)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
ath9k_hw_start_nfcal(struct ath_hal * ah)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
ath9k_hw_loadnf(struct ath_hal * ah,struct ath9k_channel * chan)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
ath9k_hw_getnf(struct ath_hal * ah,struct ath9k_channel * chan)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
ath9k_init_nfcal_hist_buffer(struct ath_hal * ah)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
ath9k_hw_getchan_noise(struct ath_hal * ah,struct ath9k_channel * chan)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
ath9k_hw_calibrate(struct ath_hal * ah,struct ath9k_channel * chan,uint8_t rxchainmask,boolean_t longcal,boolean_t * isCalDone)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
ath9k_hw_9285_pa_cal(struct ath_hal * ah)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
ath9k_hw_init_cal(struct ath_hal * ah,struct ath9k_channel * chan)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