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