2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2008 Atheros Communications, Inc.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include "ah_internal.h"
23 #include "ah_eeprom_v3.h"
26 getPcdacInterceptsFromPcdacMinMax(HAL_EEPROM
*ee
,
27 uint16_t pcdacMin
, uint16_t pcdacMax
, uint16_t *vp
)
29 const static uint16_t intercepts3
[] =
30 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
31 const static uint16_t intercepts3_2
[] =
32 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
33 const uint16_t *ip
= ee
->ee_version
< AR_EEPROM_VER3_2
?
34 intercepts3
: intercepts3_2
;
37 /* loop for the percentages in steps or 5 */
38 for (i
= 0; i
< NUM_INTERCEPTS
; i
++ )
39 *vp
++ = (ip
[i
] * pcdacMax
+ (100 - ip
[i
]) * pcdacMin
) / 100;
43 * Get channel value from binary representation held in eeprom
46 fbin2freq(HAL_EEPROM
*ee
, uint16_t fbin
)
48 if (fbin
== CHANNEL_UNUSED
) /* reserved value, don't convert */
50 return ee
->ee_version
<= AR_EEPROM_VER3_2
?
51 (fbin
> 62 ? 5100 + 10*62 + 5*(fbin
-62) : 5100 + 10*fbin
) :
56 fbin2freq_2p4(HAL_EEPROM
*ee
, uint16_t fbin
)
58 if (fbin
== CHANNEL_UNUSED
) /* reserved value, don't convert */
60 return ee
->ee_version
<= AR_EEPROM_VER3_2
?
66 * Now copy EEPROM frequency pier contents into the allocated space
69 readEepromFreqPierInfo(struct ath_hal
*ah
, HAL_EEPROM
*ee
)
71 #define EEREAD(_off) do { \
72 if (!ath_hal_eepromRead(ah, _off, &eeval)) \
78 if (ee
->ee_version
>= AR_EEPROM_VER4_0
&&
79 ee
->ee_eepMap
&& !ee
->ee_Amode
) {
81 * V4.0 EEPROMs with map type 1 have frequency pier
82 * data only when 11a mode is supported.
86 if (ee
->ee_version
>= AR_EEPROM_VER3_3
) {
87 off
= GROUPS_OFFSET3_3
+ GROUP1_OFFSET
;
88 for (i
= 0; i
< ee
->ee_numChannels11a
; i
+= 2) {
90 ee
->ee_channels11a
[i
] = (eeval
>> 8) & FREQ_MASK_3_3
;
91 ee
->ee_channels11a
[i
+1] = eeval
& FREQ_MASK_3_3
;
94 off
= GROUPS_OFFSET3_2
+ GROUP1_OFFSET
;
97 ee
->ee_channels11a
[0] = (eeval
>> 9) & FREQ_MASK
;
98 ee
->ee_channels11a
[1] = (eeval
>> 2) & FREQ_MASK
;
99 ee
->ee_channels11a
[2] = (eeval
<< 5) & FREQ_MASK
;
102 ee
->ee_channels11a
[2] |= (eeval
>> 11) & 0x1f;
103 ee
->ee_channels11a
[3] = (eeval
>> 4) & FREQ_MASK
;
104 ee
->ee_channels11a
[4] = (eeval
<< 3) & FREQ_MASK
;
107 ee
->ee_channels11a
[4] |= (eeval
>> 13) & 0x7;
108 ee
->ee_channels11a
[5] = (eeval
>> 6) & FREQ_MASK
;
109 ee
->ee_channels11a
[6] = (eeval
<< 1) & FREQ_MASK
;
112 ee
->ee_channels11a
[6] |= (eeval
>> 15) & 0x1;
113 ee
->ee_channels11a
[7] = (eeval
>> 8) & FREQ_MASK
;
114 ee
->ee_channels11a
[8] = (eeval
>> 1) & FREQ_MASK
;
115 ee
->ee_channels11a
[9] = (eeval
<< 6) & FREQ_MASK
;
118 ee
->ee_channels11a
[9] |= (eeval
>> 10) & 0x3f;
121 for (i
= 0; i
< ee
->ee_numChannels11a
; i
++)
122 ee
->ee_channels11a
[i
] = fbin2freq(ee
, ee
->ee_channels11a
[i
]);
129 * Rev 4 Eeprom 5112 Power Extract Functions
133 * Allocate the power information based on the number of channels
134 * recorded by the calibration. These values are then initialized.
137 eepromAllocExpnPower5112(struct ath_hal
*ah
,
138 const EEPROM_POWER_5112
*pCalDataset
,
139 EEPROM_POWER_EXPN_5112
*pPowerExpn
)
141 uint16_t numChannels
= pCalDataset
->numChannels
;
142 const uint16_t *pChanList
= pCalDataset
->pChannels
;
146 /* Allocate the channel and Power Data arrays together */
147 data
= ath_hal_malloc(
148 roundup(sizeof(uint16_t) * numChannels
, sizeof(uint32_t)) +
149 sizeof(EXPN_DATA_PER_CHANNEL_5112
) * numChannels
);
150 if (data
== AH_NULL
) {
151 HALDEBUG(ah
, HAL_DEBUG_ANY
,
152 "%s unable to allocate raw data struct (gen3)\n", __func__
);
155 pPowerExpn
->pChannels
= data
;
156 pPowerExpn
->pDataPerChannel
= (void *)(((char *)data
) +
157 roundup(sizeof(uint16_t) * numChannels
, sizeof(uint32_t)));
159 pPowerExpn
->numChannels
= numChannels
;
160 for (i
= 0; i
< numChannels
; i
++) {
161 pPowerExpn
->pChannels
[i
] =
162 pPowerExpn
->pDataPerChannel
[i
].channelValue
=
164 for (j
= 0; j
< NUM_XPD_PER_CHANNEL
; j
++) {
165 pPowerExpn
->pDataPerChannel
[i
].pDataPerXPD
[j
].xpd_gain
= j
;
166 pPowerExpn
->pDataPerChannel
[i
].pDataPerXPD
[j
].numPcdacs
= 0;
168 pPowerExpn
->pDataPerChannel
[i
].pDataPerXPD
[0].numPcdacs
= 4;
169 pPowerExpn
->pDataPerChannel
[i
].pDataPerXPD
[3].numPcdacs
= 3;
175 * Expand the dataSet from the calibration information into the
176 * final power structure for 5112
179 eepromExpandPower5112(struct ath_hal
*ah
,
180 const EEPROM_POWER_5112
*pCalDataset
,
181 EEPROM_POWER_EXPN_5112
*pPowerExpn
)
184 EXPN_DATA_PER_XPD_5112
*pExpnXPD
;
185 /* ptr to array of info held per channel */
186 const EEPROM_DATA_PER_CHANNEL_5112
*pCalCh
;
187 uint16_t xgainList
[2], xpdMask
;
189 pPowerExpn
->xpdMask
= pCalDataset
->xpdMask
;
191 xgainList
[0] = 0xDEAD;
192 xgainList
[1] = 0xDEAD;
195 xpdMask
= pPowerExpn
->xpdMask
;
196 for (jj
= 0; jj
< NUM_XPD_PER_CHANNEL
; jj
++) {
197 if (((xpdMask
>> jj
) & 1) > 0) {
199 HALDEBUG(ah
, HAL_DEBUG_ANY
,
200 "%s: too many xpdGains in dataset: %u\n",
204 xgainList
[kk
++] = jj
;
208 pPowerExpn
->numChannels
= pCalDataset
->numChannels
;
209 if (pPowerExpn
->numChannels
== 0) {
210 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: no channels\n", __func__
);
214 for (ii
= 0; ii
< pPowerExpn
->numChannels
; ii
++) {
215 pCalCh
= &pCalDataset
->pDataPerChannel
[ii
];
216 pPowerExpn
->pDataPerChannel
[ii
].channelValue
=
217 pCalCh
->channelValue
;
218 pPowerExpn
->pDataPerChannel
[ii
].maxPower_t4
=
221 for (jj
= 0; jj
< NUM_XPD_PER_CHANNEL
; jj
++)
222 pPowerExpn
->pDataPerChannel
[ii
].pDataPerXPD
[jj
].numPcdacs
= 0;
223 if (xgainList
[1] == 0xDEAD) {
225 pExpnXPD
= &pPowerExpn
->pDataPerChannel
[ii
].pDataPerXPD
[jj
];
226 pExpnXPD
->numPcdacs
= 4;
227 pExpnXPD
->pcdac
[0] = pCalCh
->pcd1_xg0
;
228 pExpnXPD
->pcdac
[1] = (uint16_t)
229 (pExpnXPD
->pcdac
[0] + pCalCh
->pcd2_delta_xg0
);
230 pExpnXPD
->pcdac
[2] = (uint16_t)
231 (pExpnXPD
->pcdac
[1] + pCalCh
->pcd3_delta_xg0
);
232 pExpnXPD
->pcdac
[3] = (uint16_t)
233 (pExpnXPD
->pcdac
[2] + pCalCh
->pcd4_delta_xg0
);
235 pExpnXPD
->pwr_t4
[0] = pCalCh
->pwr1_xg0
;
236 pExpnXPD
->pwr_t4
[1] = pCalCh
->pwr2_xg0
;
237 pExpnXPD
->pwr_t4
[2] = pCalCh
->pwr3_xg0
;
238 pExpnXPD
->pwr_t4
[3] = pCalCh
->pwr4_xg0
;
241 pPowerExpn
->pDataPerChannel
[ii
].pDataPerXPD
[xgainList
[0]].pcdac
[0] = pCalCh
->pcd1_xg0
;
242 pPowerExpn
->pDataPerChannel
[ii
].pDataPerXPD
[xgainList
[1]].pcdac
[0] = 20;
243 pPowerExpn
->pDataPerChannel
[ii
].pDataPerXPD
[xgainList
[1]].pcdac
[1] = 35;
244 pPowerExpn
->pDataPerChannel
[ii
].pDataPerXPD
[xgainList
[1]].pcdac
[2] = 63;
247 pExpnXPD
= &pPowerExpn
->pDataPerChannel
[ii
].pDataPerXPD
[jj
];
248 pExpnXPD
->numPcdacs
= 4;
249 pExpnXPD
->pcdac
[1] = (uint16_t)
250 (pExpnXPD
->pcdac
[0] + pCalCh
->pcd2_delta_xg0
);
251 pExpnXPD
->pcdac
[2] = (uint16_t)
252 (pExpnXPD
->pcdac
[1] + pCalCh
->pcd3_delta_xg0
);
253 pExpnXPD
->pcdac
[3] = (uint16_t)
254 (pExpnXPD
->pcdac
[2] + pCalCh
->pcd4_delta_xg0
);
255 pExpnXPD
->pwr_t4
[0] = pCalCh
->pwr1_xg0
;
256 pExpnXPD
->pwr_t4
[1] = pCalCh
->pwr2_xg0
;
257 pExpnXPD
->pwr_t4
[2] = pCalCh
->pwr3_xg0
;
258 pExpnXPD
->pwr_t4
[3] = pCalCh
->pwr4_xg0
;
261 pExpnXPD
= &pPowerExpn
->pDataPerChannel
[ii
].pDataPerXPD
[jj
];
262 pExpnXPD
->numPcdacs
= 3;
264 pExpnXPD
->pwr_t4
[0] = pCalCh
->pwr1_xg3
;
265 pExpnXPD
->pwr_t4
[1] = pCalCh
->pwr2_xg3
;
266 pExpnXPD
->pwr_t4
[2] = pCalCh
->pwr3_xg3
;
273 readEepromRawPowerCalInfo5112(struct ath_hal
*ah
, HAL_EEPROM
*ee
)
275 #define EEREAD(_off) do { \
276 if (!ath_hal_eepromRead(ah, _off, &eeval)) \
279 const uint16_t dbmmask
= 0xff;
280 const uint16_t pcdac_delta_mask
= 0x1f;
281 const uint16_t pcdac_mask
= 0x3f;
282 const uint16_t freqmask
= 0xff;
284 int i
, mode
, numPiers
;
287 uint16_t freq
[NUM_11A_EEPROM_CHANNELS
];
288 EEPROM_POWER_5112 eePower
;
290 HALASSERT(ee
->ee_version
>= AR_EEPROM_VER4_0
);
291 off
= GROUPS_OFFSET3_3
;
292 for (mode
= headerInfo11A
; mode
<= headerInfo11G
; mode
++) {
296 if (!ee
->ee_Amode
) /* no 11a calibration data */
298 while (numPiers
< NUM_11A_EEPROM_CHANNELS
) {
300 if ((eeval
& freqmask
) == 0)
302 freq
[numPiers
++] = fbin2freq(ee
,
305 if (((eeval
>> 8) & freqmask
) == 0)
307 freq
[numPiers
++] = fbin2freq(ee
,
308 (eeval
>>8) & freqmask
);
312 if (!ee
->ee_Bmode
) /* no 11b calibration data */
314 for (i
= 0; i
< NUM_2_4_EEPROM_CHANNELS
; i
++)
315 if (ee
->ee_calPier11b
[i
] != CHANNEL_UNUSED
)
316 freq
[numPiers
++] = ee
->ee_calPier11b
[i
];
319 if (!ee
->ee_Gmode
) /* no 11g calibration data */
321 for (i
= 0; i
< NUM_2_4_EEPROM_CHANNELS
; i
++)
322 if (ee
->ee_calPier11g
[i
] != CHANNEL_UNUSED
)
323 freq
[numPiers
++] = ee
->ee_calPier11g
[i
];
326 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: invalid mode 0x%x\n",
331 OS_MEMZERO(&eePower
, sizeof(eePower
));
332 eePower
.numChannels
= numPiers
;
334 for (i
= 0; i
< numPiers
; i
++) {
335 eePower
.pChannels
[i
] = freq
[i
];
336 eePower
.pDataPerChannel
[i
].channelValue
= freq
[i
];
339 eePower
.pDataPerChannel
[i
].pwr1_xg0
= (int16_t)
340 ((eeval
& dbmmask
) - ((eeval
>> 7) & 0x1)*256);
341 eePower
.pDataPerChannel
[i
].pwr2_xg0
= (int16_t)
342 (((eeval
>> 8) & dbmmask
) - ((eeval
>> 15) & 0x1)*256);
345 eePower
.pDataPerChannel
[i
].pwr3_xg0
= (int16_t)
346 ((eeval
& dbmmask
) - ((eeval
>> 7) & 0x1)*256);
347 eePower
.pDataPerChannel
[i
].pwr4_xg0
= (int16_t)
348 (((eeval
>> 8) & dbmmask
) - ((eeval
>> 15) & 0x1)*256);
351 eePower
.pDataPerChannel
[i
].pcd2_delta_xg0
= (uint16_t)
352 (eeval
& pcdac_delta_mask
);
353 eePower
.pDataPerChannel
[i
].pcd3_delta_xg0
= (uint16_t)
354 ((eeval
>> 5) & pcdac_delta_mask
);
355 eePower
.pDataPerChannel
[i
].pcd4_delta_xg0
= (uint16_t)
356 ((eeval
>> 10) & pcdac_delta_mask
);
359 eePower
.pDataPerChannel
[i
].pwr1_xg3
= (int16_t)
360 ((eeval
& dbmmask
) - ((eeval
>> 7) & 0x1)*256);
361 eePower
.pDataPerChannel
[i
].pwr2_xg3
= (int16_t)
362 (((eeval
>> 8) & dbmmask
) - ((eeval
>> 15) & 0x1)*256);
365 eePower
.pDataPerChannel
[i
].pwr3_xg3
= (int16_t)
366 ((eeval
& dbmmask
) - ((eeval
>> 7) & 0x1)*256);
367 if (ee
->ee_version
>= AR_EEPROM_VER4_3
) {
368 eePower
.pDataPerChannel
[i
].maxPower_t4
=
369 eePower
.pDataPerChannel
[i
].pwr4_xg0
;
370 eePower
.pDataPerChannel
[i
].pcd1_xg0
= (uint16_t)
371 ((eeval
>> 8) & pcdac_mask
);
373 eePower
.pDataPerChannel
[i
].maxPower_t4
= (int16_t)
374 (((eeval
>> 8) & dbmmask
) -
375 ((eeval
>> 15) & 0x1)*256);
376 eePower
.pDataPerChannel
[i
].pcd1_xg0
= 1;
379 eePower
.xpdMask
= ee
->ee_xgain
[mode
];
381 if (!eepromAllocExpnPower5112(ah
, &eePower
, &ee
->ee_modePowerArray5112
[mode
])) {
382 HALDEBUG(ah
, HAL_DEBUG_ANY
,
383 "%s: did not allocate power struct\n", __func__
);
386 if (!eepromExpandPower5112(ah
, &eePower
, &ee
->ee_modePowerArray5112
[mode
])) {
387 HALDEBUG(ah
, HAL_DEBUG_ANY
,
388 "%s: did not expand power struct\n", __func__
);
397 freeEepromRawPowerCalInfo5112(struct ath_hal
*ah
, HAL_EEPROM
*ee
)
402 for (mode
= headerInfo11A
; mode
<= headerInfo11G
; mode
++) {
403 EEPROM_POWER_EXPN_5112
*pPowerExpn
=
404 &ee
->ee_modePowerArray5112
[mode
];
405 data
= pPowerExpn
->pChannels
;
406 if (data
!= AH_NULL
) {
407 pPowerExpn
->pChannels
= AH_NULL
;
414 ar2413SetupEEPROMDataset(EEPROM_DATA_STRUCT_2413
*pEEPROMDataset2413
,
415 uint16_t myNumRawChannels
, uint16_t *pMyRawChanList
)
417 uint16_t i
, channelValue
;
419 uint16_t numPdGainsUsed
;
421 pEEPROMDataset2413
->numChannels
= myNumRawChannels
;
423 xpd_mask
= pEEPROMDataset2413
->xpd_mask
;
425 if ((xpd_mask
>> 0) & 0x1) numPdGainsUsed
++;
426 if ((xpd_mask
>> 1) & 0x1) numPdGainsUsed
++;
427 if ((xpd_mask
>> 2) & 0x1) numPdGainsUsed
++;
428 if ((xpd_mask
>> 3) & 0x1) numPdGainsUsed
++;
430 for (i
= 0; i
< myNumRawChannels
; i
++) {
431 channelValue
= pMyRawChanList
[i
];
432 pEEPROMDataset2413
->pChannels
[i
] = channelValue
;
433 pEEPROMDataset2413
->pDataPerChannel
[i
].channelValue
= channelValue
;
434 pEEPROMDataset2413
->pDataPerChannel
[i
].numPdGains
= numPdGainsUsed
;
439 ar2413ReadCalDataset(struct ath_hal
*ah
, HAL_EEPROM
*ee
,
440 EEPROM_DATA_STRUCT_2413
*pCalDataset
,
441 uint32_t start_offset
, uint32_t maxPiers
, uint8_t mode
)
443 #define EEREAD(_off) do { \
444 if (!ath_hal_eepromRead(ah, _off, &eeval)) \
447 const uint16_t dbm_I_mask
= 0x1F; /* 5-bits. 1dB step. */
448 const uint16_t dbm_delta_mask
= 0xF; /* 4-bits. 0.5dB step. */
449 const uint16_t Vpd_I_mask
= 0x7F; /* 7-bits. 0-128 */
450 const uint16_t Vpd_delta_mask
= 0x3F; /* 6-bits. 0-63 */
451 const uint16_t freqmask
= 0xff;
454 uint16_t idx
, numPiers
;
455 uint16_t freq
[NUM_11A_EEPROM_CHANNELS
];
458 for (numPiers
= 0; numPiers
< maxPiers
;) {
460 if ((eeval
& freqmask
) == 0)
462 if (mode
== headerInfo11A
)
463 freq
[numPiers
++] = fbin2freq(ee
, (eeval
& freqmask
));
465 freq
[numPiers
++] = fbin2freq_2p4(ee
, (eeval
& freqmask
));
467 if (((eeval
>> 8) & freqmask
) == 0)
469 if (mode
== headerInfo11A
)
470 freq
[numPiers
++] = fbin2freq(ee
, (eeval
>> 8) & freqmask
);
472 freq
[numPiers
++] = fbin2freq_2p4(ee
, (eeval
>> 8) & freqmask
);
474 ar2413SetupEEPROMDataset(pCalDataset
, numPiers
, &freq
[0]);
476 idx
= start_offset
+ (maxPiers
/ 2);
477 for (ii
= 0; ii
< pCalDataset
->numChannels
; ii
++) {
478 EEPROM_DATA_PER_CHANNEL_2413
*currCh
=
479 &(pCalDataset
->pDataPerChannel
[ii
]);
481 if (currCh
->numPdGains
> 0) {
483 * Read the first NUM_POINTS_OTHER_PDGAINS pwr
484 * and Vpd values for pdgain_0
487 currCh
->pwr_I
[0] = eeval
& dbm_I_mask
;
488 currCh
->Vpd_I
[0] = (eeval
>> 5) & Vpd_I_mask
;
489 currCh
->pwr_delta_t2
[0][0] =
490 (eeval
>> 12) & dbm_delta_mask
;
493 currCh
->Vpd_delta
[0][0] = eeval
& Vpd_delta_mask
;
494 currCh
->pwr_delta_t2
[1][0] =
495 (eeval
>> 6) & dbm_delta_mask
;
496 currCh
->Vpd_delta
[1][0] =
497 (eeval
>> 10) & Vpd_delta_mask
;
500 currCh
->pwr_delta_t2
[2][0] = eeval
& dbm_delta_mask
;
501 currCh
->Vpd_delta
[2][0] = (eeval
>> 4) & Vpd_delta_mask
;
504 if (currCh
->numPdGains
> 1) {
506 * Read the first NUM_POINTS_OTHER_PDGAINS pwr
507 * and Vpd values for pdgain_1
509 currCh
->pwr_I
[1] = (eeval
>> 10) & dbm_I_mask
;
510 currCh
->Vpd_I
[1] = (eeval
>> 15) & 0x1;
514 currCh
->Vpd_I
[1] |= (eeval
& 0x3F) << 1;
515 currCh
->pwr_delta_t2
[0][1] =
516 (eeval
>> 6) & dbm_delta_mask
;
517 currCh
->Vpd_delta
[0][1] =
518 (eeval
>> 10) & Vpd_delta_mask
;
521 currCh
->pwr_delta_t2
[1][1] = eeval
& dbm_delta_mask
;
522 currCh
->Vpd_delta
[1][1] = (eeval
>> 4) & Vpd_delta_mask
;
523 currCh
->pwr_delta_t2
[2][1] =
524 (eeval
>> 10) & dbm_delta_mask
;
525 currCh
->Vpd_delta
[2][1] = (eeval
>> 14) & 0x3;
529 currCh
->Vpd_delta
[2][1] |= (eeval
& 0xF) << 2;
530 } else if (currCh
->numPdGains
== 1) {
532 * Read the last pwr and Vpd values for pdgain_0
534 currCh
->pwr_delta_t2
[3][0] =
535 (eeval
>> 10) & dbm_delta_mask
;
536 currCh
->Vpd_delta
[3][0] = (eeval
>> 14) & 0x3;
540 currCh
->Vpd_delta
[3][0] |= (eeval
& 0xF) << 2;
542 /* 4 words if numPdGains == 1 */
545 if (currCh
->numPdGains
> 2) {
547 * Read the first NUM_POINTS_OTHER_PDGAINS pwr
548 * and Vpd values for pdgain_2
550 currCh
->pwr_I
[2] = (eeval
>> 4) & dbm_I_mask
;
551 currCh
->Vpd_I
[2] = (eeval
>> 9) & Vpd_I_mask
;
554 currCh
->pwr_delta_t2
[0][2] =
555 (eeval
>> 0) & dbm_delta_mask
;
556 currCh
->Vpd_delta
[0][2] = (eeval
>> 4) & Vpd_delta_mask
;
557 currCh
->pwr_delta_t2
[1][2] =
558 (eeval
>> 10) & dbm_delta_mask
;
559 currCh
->Vpd_delta
[1][2] = (eeval
>> 14) & 0x3;
563 currCh
->Vpd_delta
[1][2] |= (eeval
& 0xF) << 2;
564 currCh
->pwr_delta_t2
[2][2] =
565 (eeval
>> 4) & dbm_delta_mask
;
566 currCh
->Vpd_delta
[2][2] = (eeval
>> 8) & Vpd_delta_mask
;
567 } else if (currCh
->numPdGains
== 2) {
569 * Read the last pwr and Vpd values for pdgain_1
571 currCh
->pwr_delta_t2
[3][1] =
572 (eeval
>> 4) & dbm_delta_mask
;
573 currCh
->Vpd_delta
[3][1] = (eeval
>> 8) & Vpd_delta_mask
;
575 /* 6 words if numPdGains == 2 */
578 if (currCh
->numPdGains
> 3) {
580 * Read the first NUM_POINTS_OTHER_PDGAINS pwr
581 * and Vpd values for pdgain_3
583 currCh
->pwr_I
[3] = (eeval
>> 14) & 0x3;
587 currCh
->pwr_I
[3] |= ((eeval
>> 0) & 0x7) << 2;
588 currCh
->Vpd_I
[3] = (eeval
>> 3) & Vpd_I_mask
;
589 currCh
->pwr_delta_t2
[0][3] =
590 (eeval
>> 10) & dbm_delta_mask
;
591 currCh
->Vpd_delta
[0][3] = (eeval
>> 14) & 0x3;
595 currCh
->Vpd_delta
[0][3] |= (eeval
& 0xF) << 2;
596 currCh
->pwr_delta_t2
[1][3] =
597 (eeval
>> 4) & dbm_delta_mask
;
598 currCh
->Vpd_delta
[1][3] = (eeval
>> 8) & Vpd_delta_mask
;
599 currCh
->pwr_delta_t2
[2][3] = (eeval
>> 14) & 0x3;
603 currCh
->pwr_delta_t2
[2][3] |= ((eeval
>> 0) & 0x3) << 2;
604 currCh
->Vpd_delta
[2][3] = (eeval
>> 2) & Vpd_delta_mask
;
605 currCh
->pwr_delta_t2
[3][3] =
606 (eeval
>> 8) & dbm_delta_mask
;
607 currCh
->Vpd_delta
[3][3] = (eeval
>> 12) & 0xF;
611 currCh
->Vpd_delta
[3][3] |= ((eeval
>> 0) & 0x3) << 4;
613 /* 12 words if numPdGains == 4 */
614 } else if (currCh
->numPdGains
== 3) {
615 /* read the last pwr and Vpd values for pdgain_2 */
616 currCh
->pwr_delta_t2
[3][2] = (eeval
>> 14) & 0x3;
620 currCh
->pwr_delta_t2
[3][2] |= ((eeval
>> 0) & 0x3) << 2;
621 currCh
->Vpd_delta
[3][2] = (eeval
>> 2) & Vpd_delta_mask
;
623 /* 9 words if numPdGains == 3 */
631 ar2413SetupRawDataset(RAW_DATA_STRUCT_2413
*pRaw
, EEPROM_DATA_STRUCT_2413
*pCal
)
633 uint16_t i
, j
, kk
, channelValue
;
635 uint16_t numPdGainsUsed
;
637 pRaw
->numChannels
= pCal
->numChannels
;
639 xpd_mask
= pRaw
->xpd_mask
;
641 if ((xpd_mask
>> 0) & 0x1) numPdGainsUsed
++;
642 if ((xpd_mask
>> 1) & 0x1) numPdGainsUsed
++;
643 if ((xpd_mask
>> 2) & 0x1) numPdGainsUsed
++;
644 if ((xpd_mask
>> 3) & 0x1) numPdGainsUsed
++;
646 for (i
= 0; i
< pCal
->numChannels
; i
++) {
647 channelValue
= pCal
->pChannels
[i
];
649 pRaw
->pChannels
[i
] = channelValue
;
651 pRaw
->pDataPerChannel
[i
].channelValue
= channelValue
;
652 pRaw
->pDataPerChannel
[i
].numPdGains
= numPdGainsUsed
;
655 for (j
= 0; j
< MAX_NUM_PDGAINS_PER_CHANNEL
; j
++) {
656 pRaw
->pDataPerChannel
[i
].pDataPerPDGain
[j
].pd_gain
= j
;
657 if ((xpd_mask
>> j
) & 0x1) {
658 pRaw
->pDataPerChannel
[i
].pDataPerPDGain
[j
].numVpd
= NUM_POINTS_OTHER_PDGAINS
;
662 * lowest pd_gain corresponds
663 * to highest power and thus,
666 pRaw
->pDataPerChannel
[i
].pDataPerPDGain
[j
].numVpd
= NUM_POINTS_LAST_PDGAIN
;
669 pRaw
->pDataPerChannel
[i
].pDataPerPDGain
[j
].numVpd
= 0;
676 ar2413EepromToRawDataset(struct ath_hal
*ah
,
677 EEPROM_DATA_STRUCT_2413
*pCal
, RAW_DATA_STRUCT_2413
*pRaw
)
679 uint16_t ii
, jj
, kk
, ss
;
680 RAW_DATA_PER_PDGAIN_2413
*pRawXPD
;
681 /* ptr to array of info held per channel */
682 EEPROM_DATA_PER_CHANNEL_2413
*pCalCh
;
683 uint16_t xgain_list
[MAX_NUM_PDGAINS_PER_CHANNEL
];
685 uint32_t numPdGainsUsed
;
687 HALASSERT(pRaw
->xpd_mask
== pCal
->xpd_mask
);
689 xgain_list
[0] = 0xDEAD;
690 xgain_list
[1] = 0xDEAD;
691 xgain_list
[2] = 0xDEAD;
692 xgain_list
[3] = 0xDEAD;
695 xpd_mask
= pRaw
->xpd_mask
;
696 for (jj
= 0; jj
< MAX_NUM_PDGAINS_PER_CHANNEL
; jj
++) {
697 if ((xpd_mask
>> (MAX_NUM_PDGAINS_PER_CHANNEL
-jj
-1)) & 1)
698 xgain_list
[numPdGainsUsed
++] = MAX_NUM_PDGAINS_PER_CHANNEL
-jj
-1;
701 pRaw
->numChannels
= pCal
->numChannels
;
702 for (ii
= 0; ii
< pRaw
->numChannels
; ii
++) {
703 pCalCh
= &(pCal
->pDataPerChannel
[ii
]);
704 pRaw
->pDataPerChannel
[ii
].channelValue
= pCalCh
->channelValue
;
706 /* numVpd has already been setup appropriately for the relevant pdGains */
707 for (jj
= 0; jj
< numPdGainsUsed
; jj
++) {
708 /* use jj for calDataset and ss for rawDataset */
710 pRawXPD
= &(pRaw
->pDataPerChannel
[ii
].pDataPerPDGain
[ss
]);
711 HALASSERT(pRawXPD
->numVpd
>= 1);
713 pRawXPD
->pwr_t4
[0] = (uint16_t)(4*pCalCh
->pwr_I
[jj
]);
714 pRawXPD
->Vpd
[0] = pCalCh
->Vpd_I
[jj
];
716 for (kk
= 1; kk
< pRawXPD
->numVpd
; kk
++) {
717 pRawXPD
->pwr_t4
[kk
] = (int16_t)(pRawXPD
->pwr_t4
[kk
-1] + 2*pCalCh
->pwr_delta_t2
[kk
-1][jj
]);
718 pRawXPD
->Vpd
[kk
] = (uint16_t)(pRawXPD
->Vpd
[kk
-1] + pCalCh
->Vpd_delta
[kk
-1][jj
]);
722 /* loop over pd_gains */
724 /* loop over channels */
729 readEepromRawPowerCalInfo2413(struct ath_hal
*ah
, HAL_EEPROM
*ee
)
731 /* NB: index is 1 less than numPdgains */
732 static const uint16_t wordsForPdgains
[] = { 4, 6, 9, 12 };
733 EEPROM_DATA_STRUCT_2413
*pCal
= AH_NULL
;
734 RAW_DATA_STRUCT_2413
*pRaw
;
735 int numEEPROMWordsPerChannel
;
737 HAL_BOOL ret
= AH_FALSE
;
739 HALASSERT(ee
->ee_version
>= AR_EEPROM_VER5_0
);
740 HALASSERT(ee
->ee_eepMap
== 2);
742 pCal
= ath_hal_malloc(sizeof(EEPROM_DATA_STRUCT_2413
));
746 off
= ee
->ee_eepMap2PowerCalStart
;
748 OS_MEMZERO(pCal
, sizeof(EEPROM_DATA_STRUCT_2413
));
749 pCal
->xpd_mask
= ee
->ee_xgain
[headerInfo11A
];
750 if (!ar2413ReadCalDataset(ah
, ee
, pCal
, off
,
751 NUM_11A_EEPROM_CHANNELS_2413
, headerInfo11A
)) {
754 pRaw
= &ee
->ee_rawDataset2413
[headerInfo11A
];
755 pRaw
->xpd_mask
= ee
->ee_xgain
[headerInfo11A
];
756 ar2413SetupRawDataset(pRaw
, pCal
);
757 if (!ar2413EepromToRawDataset(ah
, pCal
, pRaw
)) {
760 /* setup offsets for mode_11a next */
761 numEEPROMWordsPerChannel
= wordsForPdgains
[
762 pCal
->pDataPerChannel
[0].numPdGains
- 1];
763 off
+= pCal
->numChannels
* numEEPROMWordsPerChannel
+ 5;
766 OS_MEMZERO(pCal
, sizeof(EEPROM_DATA_STRUCT_2413
));
767 pCal
->xpd_mask
= ee
->ee_xgain
[headerInfo11B
];
768 if (!ar2413ReadCalDataset(ah
, ee
, pCal
, off
,
769 NUM_2_4_EEPROM_CHANNELS_2413
, headerInfo11B
)) {
772 pRaw
= &ee
->ee_rawDataset2413
[headerInfo11B
];
773 pRaw
->xpd_mask
= ee
->ee_xgain
[headerInfo11B
];
774 ar2413SetupRawDataset(pRaw
, pCal
);
775 if (!ar2413EepromToRawDataset(ah
, pCal
, pRaw
)) {
778 /* setup offsets for mode_11g next */
779 numEEPROMWordsPerChannel
= wordsForPdgains
[
780 pCal
->pDataPerChannel
[0].numPdGains
- 1];
781 off
+= pCal
->numChannels
* numEEPROMWordsPerChannel
+ 2;
784 OS_MEMZERO(pCal
, sizeof(EEPROM_DATA_STRUCT_2413
));
785 pCal
->xpd_mask
= ee
->ee_xgain
[headerInfo11G
];
786 if (!ar2413ReadCalDataset(ah
, ee
, pCal
, off
,
787 NUM_2_4_EEPROM_CHANNELS_2413
, headerInfo11G
)) {
790 pRaw
= &ee
->ee_rawDataset2413
[headerInfo11G
];
791 pRaw
->xpd_mask
= ee
->ee_xgain
[headerInfo11G
];
792 ar2413SetupRawDataset(pRaw
, pCal
);
793 if (!ar2413EepromToRawDataset(ah
, pCal
, pRaw
)) {
805 * Now copy EEPROM Raw Power Calibration per frequency contents
806 * into the allocated space
809 readEepromRawPowerCalInfo(struct ath_hal
*ah
, HAL_EEPROM
*ee
)
811 #define EEREAD(_off) do { \
812 if (!ath_hal_eepromRead(ah, _off, &eeval)) \
815 uint16_t eeval
, nchan
;
819 if (ee
->ee_version
>= AR_EEPROM_VER4_0
&& ee
->ee_eepMap
== 1)
820 return readEepromRawPowerCalInfo5112(ah
, ee
);
821 if (ee
->ee_version
>= AR_EEPROM_VER5_0
&& ee
->ee_eepMap
== 2)
822 return readEepromRawPowerCalInfo2413(ah
, ee
);
825 * Group 2: read raw power data for all frequency piers
827 * NOTE: Group 2 contains the raw power calibration
828 * information for each of the channels that
831 for (mode
= headerInfo11A
; mode
<= headerInfo11G
; mode
++) {
832 uint16_t *pChannels
= AH_NULL
;
833 DATA_PER_CHANNEL
*pChannelData
= AH_NULL
;
835 off
= ee
->ee_version
>= AR_EEPROM_VER3_3
?
836 GROUPS_OFFSET3_3
: GROUPS_OFFSET3_2
;
839 off
+= GROUP2_OFFSET
;
840 nchan
= ee
->ee_numChannels11a
;
841 pChannelData
= ee
->ee_dataPerChannel11a
;
842 pChannels
= ee
->ee_channels11a
;
847 off
+= GROUP3_OFFSET
;
848 nchan
= ee
->ee_numChannels2_4
;
849 pChannelData
= ee
->ee_dataPerChannel11b
;
850 pChannels
= ee
->ee_channels11b
;
855 off
+= GROUP4_OFFSET
;
856 nchan
= ee
->ee_numChannels2_4
;
857 pChannelData
= ee
->ee_dataPerChannel11g
;
858 pChannels
= ee
->ee_channels11g
;
861 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: invalid mode 0x%x\n",
865 for (i
= 0; i
< nchan
; i
++) {
866 pChannelData
->channelValue
= pChannels
[i
];
869 pChannelData
->pcdacMax
= (uint16_t)((eeval
>> 10) & PCDAC_MASK
);
870 pChannelData
->pcdacMin
= (uint16_t)((eeval
>> 4) & PCDAC_MASK
);
871 pChannelData
->PwrValues
[0] = (uint16_t)((eeval
<< 2) & POWER_MASK
);
874 pChannelData
->PwrValues
[0] |= (uint16_t)((eeval
>> 14) & 0x3);
875 pChannelData
->PwrValues
[1] = (uint16_t)((eeval
>> 8) & POWER_MASK
);
876 pChannelData
->PwrValues
[2] = (uint16_t)((eeval
>> 2) & POWER_MASK
);
877 pChannelData
->PwrValues
[3] = (uint16_t)((eeval
<< 4) & POWER_MASK
);
880 pChannelData
->PwrValues
[3] |= (uint16_t)((eeval
>> 12) & 0xf);
881 pChannelData
->PwrValues
[4] = (uint16_t)((eeval
>> 6) & POWER_MASK
);
882 pChannelData
->PwrValues
[5] = (uint16_t)(eeval
& POWER_MASK
);
885 pChannelData
->PwrValues
[6] = (uint16_t)((eeval
>> 10) & POWER_MASK
);
886 pChannelData
->PwrValues
[7] = (uint16_t)((eeval
>> 4) & POWER_MASK
);
887 pChannelData
->PwrValues
[8] = (uint16_t)((eeval
<< 2) & POWER_MASK
);
890 pChannelData
->PwrValues
[8] |= (uint16_t)((eeval
>> 14) & 0x3);
891 pChannelData
->PwrValues
[9] = (uint16_t)((eeval
>> 8) & POWER_MASK
);
892 pChannelData
->PwrValues
[10] = (uint16_t)((eeval
>> 2) & POWER_MASK
);
894 getPcdacInterceptsFromPcdacMinMax(ee
,
895 pChannelData
->pcdacMin
, pChannelData
->pcdacMax
,
896 pChannelData
->PcdacValues
) ;
898 for (j
= 0; j
< pChannelData
->numPcdacValues
; j
++) {
899 pChannelData
->PwrValues
[j
] = (uint16_t)(
900 PWR_STEP
* pChannelData
->PwrValues
[j
]);
901 /* Note these values are scaled up. */
911 * Copy EEPROM Target Power Calbration per rate contents
912 * into the allocated space
915 readEepromTargetPowerCalInfo(struct ath_hal
*ah
, HAL_EEPROM
*ee
)
917 #define EEREAD(_off) do { \
918 if (!ath_hal_eepromRead(ah, _off, &eeval)) \
921 uint16_t eeval
, enable24
;
925 enable24
= ee
->ee_Bmode
|| ee
->ee_Gmode
;
926 for (mode
= headerInfo11A
; mode
<= headerInfo11G
; mode
++) {
927 TRGT_POWER_INFO
*pPowerInfo
;
928 uint16_t *pNumTrgtChannels
;
930 off
= ee
->ee_version
>= AR_EEPROM_VER4_0
?
931 ee
->ee_targetPowersStart
- GROUP5_OFFSET
:
932 ee
->ee_version
>= AR_EEPROM_VER3_3
?
933 GROUPS_OFFSET3_3
: GROUPS_OFFSET3_2
;
936 off
+= GROUP5_OFFSET
;
937 nchan
= NUM_TEST_FREQUENCIES
;
938 pPowerInfo
= ee
->ee_trgtPwr_11a
;
939 pNumTrgtChannels
= &ee
->ee_numTargetPwr_11a
;
944 off
+= GROUP6_OFFSET
;
946 pPowerInfo
= ee
->ee_trgtPwr_11b
;
947 pNumTrgtChannels
= &ee
->ee_numTargetPwr_11b
;
952 off
+= GROUP7_OFFSET
;
954 pPowerInfo
= ee
->ee_trgtPwr_11g
;
955 pNumTrgtChannels
= &ee
->ee_numTargetPwr_11g
;
958 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: invalid mode 0x%x\n",
962 *pNumTrgtChannels
= 0;
963 for (i
= 0; i
< nchan
; i
++) {
965 if (ee
->ee_version
>= AR_EEPROM_VER3_3
) {
966 pPowerInfo
->testChannel
= (eeval
>> 8) & 0xff;
968 pPowerInfo
->testChannel
= (eeval
>> 9) & 0x7f;
971 if (pPowerInfo
->testChannel
!= 0) {
972 /* get the channel value and read rest of info */
973 if (mode
== headerInfo11A
) {
974 pPowerInfo
->testChannel
= fbin2freq(ee
, pPowerInfo
->testChannel
);
976 pPowerInfo
->testChannel
= fbin2freq_2p4(ee
, pPowerInfo
->testChannel
);
979 if (ee
->ee_version
>= AR_EEPROM_VER3_3
) {
980 pPowerInfo
->twicePwr6_24
= (eeval
>> 2) & POWER_MASK
;
981 pPowerInfo
->twicePwr36
= (eeval
<< 4) & POWER_MASK
;
983 pPowerInfo
->twicePwr6_24
= (eeval
>> 3) & POWER_MASK
;
984 pPowerInfo
->twicePwr36
= (eeval
<< 3) & POWER_MASK
;
988 if (ee
->ee_version
>= AR_EEPROM_VER3_3
) {
989 pPowerInfo
->twicePwr36
|= (eeval
>> 12) & 0xf;
990 pPowerInfo
->twicePwr48
= (eeval
>> 6) & POWER_MASK
;
991 pPowerInfo
->twicePwr54
= eeval
& POWER_MASK
;
993 pPowerInfo
->twicePwr36
|= (eeval
>> 13) & 0x7;
994 pPowerInfo
->twicePwr48
= (eeval
>> 7) & POWER_MASK
;
995 pPowerInfo
->twicePwr54
= (eeval
>> 1) & POWER_MASK
;
997 (*pNumTrgtChannels
)++;
1007 * Now copy EEPROM Coformance Testing Limits contents
1008 * into the allocated space
1011 readEepromCTLInfo(struct ath_hal
*ah
, HAL_EEPROM
*ee
)
1013 #define EEREAD(_off) do { \
1014 if (!ath_hal_eepromRead(ah, _off, &eeval)) \
1017 RD_EDGES_POWER
*rep
;
1022 rep
= ee
->ee_rdEdgesPower
;
1024 off
= GROUP8_OFFSET
+
1025 (ee
->ee_version
>= AR_EEPROM_VER4_0
?
1026 ee
->ee_targetPowersStart
- GROUP5_OFFSET
:
1027 ee
->ee_version
>= AR_EEPROM_VER3_3
?
1028 GROUPS_OFFSET3_3
: GROUPS_OFFSET3_2
);
1029 for (i
= 0; i
< ee
->ee_numCtls
; i
++) {
1030 if (ee
->ee_ctl
[i
] == 0) {
1031 /* Move offset and edges */
1032 off
+= (ee
->ee_version
>= AR_EEPROM_VER3_3
? 8 : 7);
1036 if (ee
->ee_version
>= AR_EEPROM_VER3_3
) {
1037 for (j
= 0; j
< NUM_EDGES
; j
+= 2) {
1039 rep
[j
].rdEdge
= (eeval
>> 8) & FREQ_MASK_3_3
;
1040 rep
[j
+1].rdEdge
= eeval
& FREQ_MASK_3_3
;
1042 for (j
= 0; j
< NUM_EDGES
; j
+= 2) {
1044 rep
[j
].twice_rdEdgePower
=
1045 (eeval
>> 8) & POWER_MASK
;
1046 rep
[j
].flag
= (eeval
>> 14) & 1;
1047 rep
[j
+1].twice_rdEdgePower
= eeval
& POWER_MASK
;
1048 rep
[j
+1].flag
= (eeval
>> 6) & 1;
1052 rep
[0].rdEdge
= (eeval
>> 9) & FREQ_MASK
;
1053 rep
[1].rdEdge
= (eeval
>> 2) & FREQ_MASK
;
1054 rep
[2].rdEdge
= (eeval
<< 5) & FREQ_MASK
;
1057 rep
[2].rdEdge
|= (eeval
>> 11) & 0x1f;
1058 rep
[3].rdEdge
= (eeval
>> 4) & FREQ_MASK
;
1059 rep
[4].rdEdge
= (eeval
<< 3) & FREQ_MASK
;
1062 rep
[4].rdEdge
|= (eeval
>> 13) & 0x7;
1063 rep
[5].rdEdge
= (eeval
>> 6) & FREQ_MASK
;
1064 rep
[6].rdEdge
= (eeval
<< 1) & FREQ_MASK
;
1067 rep
[6].rdEdge
|= (eeval
>> 15) & 0x1;
1068 rep
[7].rdEdge
= (eeval
>> 8) & FREQ_MASK
;
1070 rep
[0].twice_rdEdgePower
= (eeval
>> 2) & POWER_MASK
;
1071 rep
[1].twice_rdEdgePower
= (eeval
<< 4) & POWER_MASK
;
1074 rep
[1].twice_rdEdgePower
|= (eeval
>> 12) & 0xf;
1075 rep
[2].twice_rdEdgePower
= (eeval
>> 6) & POWER_MASK
;
1076 rep
[3].twice_rdEdgePower
= eeval
& POWER_MASK
;
1079 rep
[4].twice_rdEdgePower
= (eeval
>> 10) & POWER_MASK
;
1080 rep
[5].twice_rdEdgePower
= (eeval
>> 4) & POWER_MASK
;
1081 rep
[6].twice_rdEdgePower
= (eeval
<< 2) & POWER_MASK
;
1084 rep
[6].twice_rdEdgePower
|= (eeval
>> 14) & 0x3;
1085 rep
[7].twice_rdEdgePower
= (eeval
>> 8) & POWER_MASK
;
1088 for (j
= 0; j
< NUM_EDGES
; j
++ ) {
1089 if (rep
[j
].rdEdge
!= 0 || rep
[j
].twice_rdEdgePower
!= 0) {
1090 if ((ee
->ee_ctl
[i
] & CTL_MODE_M
) == CTL_11A
||
1091 (ee
->ee_ctl
[i
] & CTL_MODE_M
) == CTL_TURBO
) {
1092 rep
[j
].rdEdge
= fbin2freq(ee
, rep
[j
].rdEdge
);
1094 rep
[j
].rdEdge
= fbin2freq_2p4(ee
, rep
[j
].rdEdge
);
1105 * Read the individual header fields for a Rev 3 EEPROM
1108 readHeaderInfo(struct ath_hal
*ah
, HAL_EEPROM
*ee
)
1110 #define EEREAD(_off) do { \
1111 if (!ath_hal_eepromRead(ah, _off, &eeval)) \
1114 static const uint32_t headerOffset3_0
[] = {
1115 0x00C2, /* 0 - Mode bits, device type, max turbo power */
1116 0x00C4, /* 1 - 2.4 and 5 antenna gain */
1117 0x00C5, /* 2 - Begin 11A modal section */
1118 0x00D0, /* 3 - Begin 11B modal section */
1119 0x00DA, /* 4 - Begin 11G modal section */
1120 0x00E4 /* 5 - Begin CTL section */
1122 static const uint32_t headerOffset3_3
[] = {
1123 0x00C2, /* 0 - Mode bits, device type, max turbo power */
1124 0x00C3, /* 1 - 2.4 and 5 antenna gain */
1125 0x00D4, /* 2 - Begin 11A modal section */
1126 0x00F2, /* 3 - Begin 11B modal section */
1127 0x010D, /* 4 - Begin 11G modal section */
1128 0x0128 /* 5 - Begin CTL section */
1131 static const uint32_t regCapOffsetPre4_0
= 0x00CF;
1132 static const uint32_t regCapOffsetPost4_0
= 0x00CA;
1134 const uint32_t *header
;
1139 /* initialize cckOfdmGainDelta for < 4.2 eeprom */
1140 ee
->ee_cckOfdmGainDelta
= CCK_OFDM_GAIN_DELTA
;
1141 ee
->ee_scaledCh14FilterCckDelta
= TENX_CH14_FILTER_CCK_DELTA_INIT
;
1143 if (ee
->ee_version
>= AR_EEPROM_VER3_3
) {
1144 header
= headerOffset3_3
;
1145 ee
->ee_numCtls
= NUM_CTLS_3_3
;
1147 header
= headerOffset3_0
;
1148 ee
->ee_numCtls
= NUM_CTLS
;
1150 HALASSERT(ee
->ee_numCtls
<= NUM_CTLS_MAX
);
1153 ee
->ee_turbo5Disable
= (eeval
>> 15) & 0x01;
1154 ee
->ee_rfKill
= (eeval
>> 14) & 0x01;
1155 ee
->ee_deviceType
= (eeval
>> 11) & 0x07;
1156 ee
->ee_turbo2WMaxPower5
= (eeval
>> 4) & 0x7F;
1157 if (ee
->ee_version
>= AR_EEPROM_VER4_0
)
1158 ee
->ee_turbo2Disable
= (eeval
>> 3) & 0x01;
1160 ee
->ee_turbo2Disable
= 1;
1161 ee
->ee_Gmode
= (eeval
>> 2) & 0x01;
1162 ee
->ee_Bmode
= (eeval
>> 1) & 0x01;
1163 ee
->ee_Amode
= (eeval
& 0x01);
1167 ee
->ee_antennaGainMax
[0] = (int8_t)((eeval
>> 8) & 0xFF);
1168 ee
->ee_antennaGainMax
[1] = (int8_t)(eeval
& 0xFF);
1169 if (ee
->ee_version
>= AR_EEPROM_VER4_0
) {
1171 ee
->ee_eepMap
= (eeval
>>14) & 0x3;
1172 ee
->ee_disableXr5
= (eeval
>>13) & 0x1;
1173 ee
->ee_disableXr2
= (eeval
>>12) & 0x1;
1174 ee
->ee_earStart
= eeval
& 0xfff;
1177 ee
->ee_targetPowersStart
= eeval
& 0xfff;
1178 ee
->ee_exist32kHzCrystal
= (eeval
>>14) & 0x1;
1180 if (ee
->ee_version
>= AR_EEPROM_VER5_0
) {
1183 ee
->ee_eepMap2PowerCalStart
= (eeval
>> 4) & 0xfff;
1184 /* Properly cal'ed 5.0 devices should be non-zero */
1188 /* Read the moded sections of the EEPROM header in the order A, B, G */
1189 for (i
= headerInfo11A
; i
<= headerInfo11G
; i
++) {
1190 /* Set the offset via the index */
1191 off
= header
[2 + i
];
1194 ee
->ee_switchSettling
[i
] = (eeval
>> 8) & 0x7f;
1195 ee
->ee_txrxAtten
[i
] = (eeval
>> 2) & 0x3f;
1196 ee
->ee_antennaControl
[0][i
] = (eeval
<< 4) & 0x3f;
1199 ee
->ee_antennaControl
[0][i
] |= (eeval
>> 12) & 0x0f;
1200 ee
->ee_antennaControl
[1][i
] = (eeval
>> 6) & 0x3f;
1201 ee
->ee_antennaControl
[2][i
] = eeval
& 0x3f;
1204 ee
->ee_antennaControl
[3][i
] = (eeval
>> 10) & 0x3f;
1205 ee
->ee_antennaControl
[4][i
] = (eeval
>> 4) & 0x3f;
1206 ee
->ee_antennaControl
[5][i
] = (eeval
<< 2) & 0x3f;
1209 ee
->ee_antennaControl
[5][i
] |= (eeval
>> 14) & 0x03;
1210 ee
->ee_antennaControl
[6][i
] = (eeval
>> 8) & 0x3f;
1211 ee
->ee_antennaControl
[7][i
] = (eeval
>> 2) & 0x3f;
1212 ee
->ee_antennaControl
[8][i
] = (eeval
<< 4) & 0x3f;
1215 ee
->ee_antennaControl
[8][i
] |= (eeval
>> 12) & 0x0f;
1216 ee
->ee_antennaControl
[9][i
] = (eeval
>> 6) & 0x3f;
1217 ee
->ee_antennaControl
[10][i
] = eeval
& 0x3f;
1220 ee
->ee_adcDesiredSize
[i
] = (int8_t)((eeval
>> 8) & 0xff);
1223 ee
->ee_ob4
= (eeval
>> 5) & 0x07;
1224 ee
->ee_db4
= (eeval
>> 2) & 0x07;
1225 ee
->ee_ob3
= (eeval
<< 1) & 0x07;
1228 ee
->ee_obFor24
= (eeval
>> 4) & 0x07;
1229 ee
->ee_dbFor24
= eeval
& 0x07;
1232 ee
->ee_obFor24g
= (eeval
>> 4) & 0x07;
1233 ee
->ee_dbFor24g
= eeval
& 0x07;
1237 if (i
== headerInfo11A
) {
1239 ee
->ee_ob3
|= (eeval
>> 15) & 0x01;
1240 ee
->ee_db3
= (eeval
>> 12) & 0x07;
1241 ee
->ee_ob2
= (eeval
>> 9) & 0x07;
1242 ee
->ee_db2
= (eeval
>> 6) & 0x07;
1243 ee
->ee_ob1
= (eeval
>> 3) & 0x07;
1244 ee
->ee_db1
= eeval
& 0x07;
1248 ee
->ee_txEndToXLNAOn
[i
] = (eeval
>> 8) & 0xff;
1249 ee
->ee_thresh62
[i
] = eeval
& 0xff;
1252 ee
->ee_txEndToXPAOff
[i
] = (eeval
>> 8) & 0xff;
1253 ee
->ee_txFrameToXPAOn
[i
] = eeval
& 0xff;
1256 ee
->ee_pgaDesiredSize
[i
] = (int8_t)((eeval
>> 8) & 0xff);
1257 ee
->ee_noiseFloorThresh
[i
] = eeval
& 0xff;
1258 if (ee
->ee_noiseFloorThresh
[i
] & 0x80) {
1259 ee
->ee_noiseFloorThresh
[i
] = 0 -
1260 ((ee
->ee_noiseFloorThresh
[i
] ^ 0xff) + 1);
1264 ee
->ee_xlnaGain
[i
] = (eeval
>> 5) & 0xff;
1265 ee
->ee_xgain
[i
] = (eeval
>> 1) & 0x0f;
1266 ee
->ee_xpd
[i
] = eeval
& 0x01;
1267 if (ee
->ee_version
>= AR_EEPROM_VER4_0
) {
1270 ee
->ee_fixedBias5
= (eeval
>> 13) & 0x1;
1273 ee
->ee_fixedBias2
= (eeval
>> 13) & 0x1;
1278 if (ee
->ee_version
>= AR_EEPROM_VER3_3
) {
1280 ee
->ee_falseDetectBackoff
[i
] = (eeval
>> 6) & 0x7F;
1283 ee
->ee_ob2GHz
[0] = eeval
& 0x7;
1284 ee
->ee_db2GHz
[0] = (eeval
>> 3) & 0x7;
1287 ee
->ee_ob2GHz
[1] = eeval
& 0x7;
1288 ee
->ee_db2GHz
[1] = (eeval
>> 3) & 0x7;
1291 ee
->ee_xrTargetPower5
= eeval
& 0x3f;
1295 if (ee
->ee_version
>= AR_EEPROM_VER3_4
) {
1296 ee
->ee_gainI
[i
] = (eeval
>> 13) & 0x07;
1299 ee
->ee_gainI
[i
] |= (eeval
<< 3) & 0x38;
1300 if (i
== headerInfo11G
) {
1301 ee
->ee_cckOfdmPwrDelta
= (eeval
>> 3) & 0xFF;
1302 if (ee
->ee_version
>= AR_EEPROM_VER4_6
)
1303 ee
->ee_scaledCh14FilterCckDelta
=
1304 (eeval
>> 11) & 0x1f;
1306 if (i
== headerInfo11A
&&
1307 ee
->ee_version
>= AR_EEPROM_VER4_0
) {
1308 ee
->ee_iqCalI
[0] = (eeval
>> 8 ) & 0x3f;
1309 ee
->ee_iqCalQ
[0] = (eeval
>> 3 ) & 0x1f;
1312 ee
->ee_gainI
[i
] = 10;
1313 ee
->ee_cckOfdmPwrDelta
= TENX_OFDM_CCK_DELTA_INIT
;
1315 if (ee
->ee_version
>= AR_EEPROM_VER4_0
) {
1319 ee
->ee_calPier11b
[0] =
1320 fbin2freq_2p4(ee
, eeval
&0xff);
1321 ee
->ee_calPier11b
[1] =
1322 fbin2freq_2p4(ee
, (eeval
>> 8)&0xff);
1324 ee
->ee_calPier11b
[2] =
1325 fbin2freq_2p4(ee
, eeval
&0xff);
1326 if (ee
->ee_version
>= AR_EEPROM_VER4_1
)
1327 ee
->ee_rxtxMargin
[headerInfo11B
] =
1328 (eeval
>> 8) & 0x3f;
1332 ee
->ee_calPier11g
[0] =
1333 fbin2freq_2p4(ee
, eeval
& 0xff);
1334 ee
->ee_calPier11g
[1] =
1335 fbin2freq_2p4(ee
, (eeval
>> 8) & 0xff);
1338 ee
->ee_turbo2WMaxPower2
= eeval
& 0x7F;
1339 ee
->ee_xrTargetPower2
= (eeval
>> 7) & 0x3f;
1342 ee
->ee_calPier11g
[2] =
1343 fbin2freq_2p4(ee
, eeval
& 0xff);
1344 if (ee
->ee_version
>= AR_EEPROM_VER4_1
)
1345 ee
->ee_rxtxMargin
[headerInfo11G
] =
1346 (eeval
>> 8) & 0x3f;
1349 ee
->ee_iqCalI
[1] = (eeval
>> 5) & 0x3F;
1350 ee
->ee_iqCalQ
[1] = eeval
& 0x1F;
1352 if (ee
->ee_version
>= AR_EEPROM_VER4_2
) {
1354 ee
->ee_cckOfdmGainDelta
=
1355 (uint8_t)(eeval
& 0xFF);
1356 if (ee
->ee_version
>= AR_EEPROM_VER5_0
) {
1357 ee
->ee_switchSettlingTurbo
[1] =
1358 (eeval
>> 8) & 0x7f;
1359 ee
->ee_txrxAttenTurbo
[1] =
1360 (eeval
>> 15) & 0x1;
1362 ee
->ee_txrxAttenTurbo
[1] |=
1363 (eeval
& 0x1F) << 1;
1364 ee
->ee_rxtxMarginTurbo
[1] =
1365 (eeval
>> 5) & 0x3F;
1366 ee
->ee_adcDesiredSizeTurbo
[1] =
1367 (eeval
>> 11) & 0x1F;
1369 ee
->ee_adcDesiredSizeTurbo
[1] |=
1371 ee
->ee_pgaDesiredSizeTurbo
[1] =
1372 (eeval
>> 3) & 0xFF;
1377 if (ee
->ee_version
>= AR_EEPROM_VER4_1
) {
1379 ee
->ee_rxtxMargin
[headerInfo11A
] =
1381 if (ee
->ee_version
>= AR_EEPROM_VER5_0
) {
1382 ee
->ee_switchSettlingTurbo
[0] =
1383 (eeval
>> 6) & 0x7f;
1384 ee
->ee_txrxAttenTurbo
[0] =
1385 (eeval
>> 13) & 0x7;
1387 ee
->ee_txrxAttenTurbo
[0] |=
1389 ee
->ee_rxtxMarginTurbo
[0] =
1390 (eeval
>> 3) & 0x3F;
1391 ee
->ee_adcDesiredSizeTurbo
[0] =
1392 (eeval
>> 9) & 0x7F;
1394 ee
->ee_adcDesiredSizeTurbo
[0] |=
1396 ee
->ee_pgaDesiredSizeTurbo
[0] =
1397 (eeval
>> 1) & 0xFF;
1404 if (ee
->ee_version
< AR_EEPROM_VER3_3
) {
1405 /* Version 3.1+ specific parameters */
1407 ee
->ee_ob2GHz
[0] = eeval
& 0x7;
1408 ee
->ee_db2GHz
[0] = (eeval
>> 3) & 0x7;
1411 ee
->ee_ob2GHz
[1] = eeval
& 0x7;
1412 ee
->ee_db2GHz
[1] = (eeval
>> 3) & 0x7;
1415 /* Initialize corner cal (thermal tx gain adjust parameters) */
1416 ee
->ee_cornerCal
.clip
= 4;
1417 ee
->ee_cornerCal
.pd90
= 1;
1418 ee
->ee_cornerCal
.pd84
= 1;
1419 ee
->ee_cornerCal
.gSel
= 0;
1422 * Read the conformance test limit identifiers
1423 * These are used to match regulatory domain testing needs with
1424 * the RD-specific tests that have been calibrated in the EEPROM.
1427 for (i
= 0; i
< ee
->ee_numCtls
; i
+= 2) {
1429 ee
->ee_ctl
[i
] = (eeval
>> 8) & 0xff;
1430 ee
->ee_ctl
[i
+1] = eeval
& 0xff;
1433 if (ee
->ee_version
< AR_EEPROM_VER5_3
) {
1434 /* XXX only for 5413? */
1435 ee
->ee_spurChans
[0][1] = AR_SPUR_5413_1
;
1436 ee
->ee_spurChans
[1][1] = AR_SPUR_5413_2
;
1437 ee
->ee_spurChans
[2][1] = AR_NO_SPUR
;
1438 ee
->ee_spurChans
[0][0] = AR_NO_SPUR
;
1440 /* Read spur mitigation data */
1441 for (i
= 0; i
< AR_EEPROM_MODAL_SPURS
; i
++) {
1443 ee
->ee_spurChans
[i
][0] = eeval
;
1444 EEREAD(off
+AR_EEPROM_MODAL_SPURS
);
1445 ee
->ee_spurChans
[i
][1] = eeval
;
1450 /* for recent changes to NF scale */
1451 if (ee
->ee_version
<= AR_EEPROM_VER3_2
) {
1452 ee
->ee_noiseFloorThresh
[headerInfo11A
] = -54;
1453 ee
->ee_noiseFloorThresh
[headerInfo11B
] = -1;
1454 ee
->ee_noiseFloorThresh
[headerInfo11G
] = -1;
1456 /* to override thresh62 for better 2.4 and 5 operation */
1457 if (ee
->ee_version
<= AR_EEPROM_VER3_2
) {
1458 ee
->ee_thresh62
[headerInfo11A
] = 15; /* 11A */
1459 ee
->ee_thresh62
[headerInfo11B
] = 28; /* 11B */
1460 ee
->ee_thresh62
[headerInfo11G
] = 28; /* 11G */
1463 /* Check for regulatory capabilities */
1464 if (ee
->ee_version
>= AR_EEPROM_VER4_0
) {
1465 EEREAD(regCapOffsetPost4_0
);
1467 EEREAD(regCapOffsetPre4_0
);
1470 ee
->ee_regCap
= eeval
;
1472 if (ee
->ee_Amode
== 0) {
1473 /* Check for valid Amode in upgraded h/w */
1474 if (ee
->ee_version
>= AR_EEPROM_VER4_0
) {
1475 ee
->ee_Amode
= (ee
->ee_regCap
& AR_EEPROM_EEREGCAP_EN_KK_NEW_11A
)?1:0;
1477 ee
->ee_Amode
= (ee
->ee_regCap
& AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0
)?1:0;
1481 if (ee
->ee_version
>= AR_EEPROM_VER5_1
)
1482 EEREAD(AR_EEPROM_CAPABILITIES_OFFSET
);
1485 ee
->ee_opCap
= eeval
;
1487 EEREAD(AR_EEPROM_REG_DOMAIN
);
1488 ee
->ee_regdomain
= eeval
;
1495 * Now verify and copy EEPROM contents into the allocated space
1498 legacyEepromReadContents(struct ath_hal
*ah
, HAL_EEPROM
*ee
)
1500 /* Read the header information here */
1501 if (!readHeaderInfo(ah
, ee
))
1504 /* Require 5112 devices to have EEPROM 4.0 EEP_MAP set */
1505 if (IS_5112(ah
) && !ee
->ee_eepMap
) {
1506 HALDEBUG(ah
, HAL_DEBUG_ANY
,
1507 "%s: 5112 devices must have EEPROM 4.0 with the "
1508 "EEP_MAP set\n", __func__
);
1513 * Group 1: frequency pier locations readback
1514 * check that the structure has been populated
1515 * with enough space to hold the channels
1517 * NOTE: Group 1 contains the 5 GHz channel numbers
1518 * that have dBm->pcdac calibrated information.
1520 if (!readEepromFreqPierInfo(ah
, ee
))
1524 * Group 2: readback data for all frequency piers
1526 * NOTE: Group 2 contains the raw power calibration
1527 * information for each of the channels that we
1530 if (!readEepromRawPowerCalInfo(ah
, ee
))
1534 * Group 5: target power values per rate
1536 * NOTE: Group 5 contains the recorded maximum power
1537 * in dB that can be attained for the given rate.
1539 /* Read the power per rate info for test channels */
1540 if (!readEepromTargetPowerCalInfo(ah
, ee
))
1544 * Group 8: Conformance Test Limits information
1546 * NOTE: Group 8 contains the values to limit the
1547 * maximum transmit power value based on any
1548 * band edge violations.
1550 /* Read the RD edge power limits */
1551 return readEepromCTLInfo(ah
, ee
);
1555 legacyEepromGet(struct ath_hal
*ah
, int param
, void *val
)
1557 HAL_EEPROM
*ee
= AH_PRIVATE(ah
)->ah_eeprom
;
1565 *(uint16_t *) val
= ee
->ee_opCap
;
1567 case AR_EEP_REGDMN_0
:
1568 *(uint16_t *) val
= ee
->ee_regdomain
;
1570 case AR_EEP_RFSILENT
:
1571 if (!ath_hal_eepromRead(ah
, AR_EEPROM_RFSILENT
, &eeval
))
1573 *(uint16_t *) val
= eeval
;
1575 case AR_EEP_MACADDR
:
1578 for (i
= 0; i
< 3; i
++) {
1579 if (!ath_hal_eepromRead(ah
, AR_EEPROM_MAC(2-i
), &eeval
)) {
1580 HALDEBUG(ah
, HAL_DEBUG_ANY
,
1581 "%s: cannot read EEPROM location %u\n",
1586 macaddr
[2*i
] = eeval
>> 8;
1587 macaddr
[2*i
+ 1] = eeval
& 0xff;
1589 if (sum
== 0 || sum
== 0xffff*3) {
1590 HALDEBUG(ah
, HAL_DEBUG_ANY
,
1591 "%s: mac address read failed: %s\n", __func__
,
1592 ath_hal_ether_sprintf(macaddr
));
1593 return HAL_EEBADMAC
;
1597 HALASSERT(val
== AH_NULL
);
1598 return ee
->ee_rfKill
? HAL_OK
: HAL_EIO
;
1600 HALASSERT(val
== AH_NULL
);
1601 return ee
->ee_Amode
? HAL_OK
: HAL_EIO
;
1603 HALASSERT(val
== AH_NULL
);
1604 return ee
->ee_Bmode
? HAL_OK
: HAL_EIO
;
1606 HALASSERT(val
== AH_NULL
);
1607 return ee
->ee_Gmode
? HAL_OK
: HAL_EIO
;
1608 case AR_EEP_TURBO5DISABLE
:
1609 HALASSERT(val
== AH_NULL
);
1610 return ee
->ee_turbo5Disable
? HAL_OK
: HAL_EIO
;
1611 case AR_EEP_TURBO2DISABLE
:
1612 HALASSERT(val
== AH_NULL
);
1613 return ee
->ee_turbo2Disable
? HAL_OK
: HAL_EIO
;
1614 case AR_EEP_ISTALON
: /* Talon detect */
1615 HALASSERT(val
== AH_NULL
);
1616 return (ee
->ee_version
>= AR_EEPROM_VER5_4
&&
1617 ath_hal_eepromRead(ah
, 0x0b, &eeval
) && eeval
== 1) ?
1619 case AR_EEP_32KHZCRYSTAL
:
1620 HALASSERT(val
== AH_NULL
);
1621 return ee
->ee_exist32kHzCrystal
? HAL_OK
: HAL_EIO
;
1622 case AR_EEP_COMPRESS
:
1623 HALASSERT(val
== AH_NULL
);
1624 return (ee
->ee_opCap
& AR_EEPROM_EEPCAP_COMPRESS_DIS
) == 0 ?
1626 case AR_EEP_FASTFRAME
:
1627 HALASSERT(val
== AH_NULL
);
1628 return (ee
->ee_opCap
& AR_EEPROM_EEPCAP_FASTFRAME_DIS
) == 0 ?
1631 HALASSERT(val
== AH_NULL
);
1632 return (ee
->ee_opCap
& AR_EEPROM_EEPCAP_AES_DIS
) == 0 ?
1635 HALASSERT(val
== AH_NULL
);
1636 return (ee
->ee_opCap
& AR_EEPROM_EEPCAP_BURST_DIS
) == 0 ?
1639 if (ee
->ee_opCap
& AR_EEPROM_EEPCAP_MAXQCU
) {
1641 MS(ee
->ee_opCap
, AR_EEPROM_EEPCAP_MAXQCU
);
1645 case AR_EEP_KCENTRIES
:
1646 if (ee
->ee_opCap
& AR_EEPROM_EEPCAP_KC_ENTRIES
) {
1648 1 << MS(ee
->ee_opCap
, AR_EEPROM_EEPCAP_KC_ENTRIES
);
1652 case AR_EEP_ANTGAINMAX_5
:
1653 *(int8_t *) val
= ee
->ee_antennaGainMax
[0];
1655 case AR_EEP_ANTGAINMAX_2
:
1656 *(int8_t *) val
= ee
->ee_antennaGainMax
[1];
1658 case AR_EEP_WRITEPROTECT
:
1659 HALASSERT(val
== AH_NULL
);
1660 return (ee
->ee_protect
& AR_EEPROM_PROTECT_WP_128_191
) ?
1667 legacyEepromSet(struct ath_hal
*ah
, int param
, int v
)
1669 HAL_EEPROM
*ee
= AH_PRIVATE(ah
)->ah_eeprom
;
1681 case AR_EEP_TURBO5DISABLE
:
1682 ee
->ee_turbo5Disable
= v
;
1684 case AR_EEP_TURBO2DISABLE
:
1685 ee
->ee_turbo2Disable
= v
;
1687 case AR_EEP_COMPRESS
:
1689 ee
->ee_opCap
&= ~AR_EEPROM_EEPCAP_COMPRESS_DIS
;
1691 ee
->ee_opCap
|= AR_EEPROM_EEPCAP_COMPRESS_DIS
;
1693 case AR_EEP_FASTFRAME
:
1695 ee
->ee_opCap
&= ~AR_EEPROM_EEPCAP_FASTFRAME_DIS
;
1697 ee
->ee_opCap
|= AR_EEPROM_EEPCAP_FASTFRAME_DIS
;
1701 ee
->ee_opCap
&= ~AR_EEPROM_EEPCAP_AES_DIS
;
1703 ee
->ee_opCap
|= AR_EEPROM_EEPCAP_AES_DIS
;
1707 ee
->ee_opCap
&= ~AR_EEPROM_EEPCAP_BURST_DIS
;
1709 ee
->ee_opCap
|= AR_EEPROM_EEPCAP_BURST_DIS
;
1716 legacyEepromDiag(struct ath_hal
*ah
, int request
,
1717 const void *args
, uint32_t argsize
, void **result
, uint32_t *resultsize
)
1719 HAL_EEPROM
*ee
= AH_PRIVATE(ah
)->ah_eeprom
;
1720 const EEPROM_POWER_EXPN_5112
*pe
;
1723 case HAL_DIAG_EEPROM
:
1725 *resultsize
= sizeof(*ee
);
1727 case HAL_DIAG_EEPROM_EXP_11A
:
1728 case HAL_DIAG_EEPROM_EXP_11B
:
1729 case HAL_DIAG_EEPROM_EXP_11G
:
1730 pe
= &ee
->ee_modePowerArray5112
[
1731 request
- HAL_DIAG_EEPROM_EXP_11A
];
1732 *result
= pe
->pChannels
;
1733 *resultsize
= (*result
== AH_NULL
) ? 0 :
1734 roundup(sizeof(uint16_t) * pe
->numChannels
,
1736 sizeof(EXPN_DATA_PER_CHANNEL_5112
) * pe
->numChannels
;
1743 legacyEepromGetSpurChan(struct ath_hal
*ah
, int ix
, HAL_BOOL is2GHz
)
1745 HAL_EEPROM
*ee
= AH_PRIVATE(ah
)->ah_eeprom
;
1747 HALASSERT(0 <= ix
&& ix
< AR_EEPROM_MODAL_SPURS
);
1748 return ee
->ee_spurChans
[ix
][is2GHz
];
1752 * Reclaim any EEPROM-related storage.
1755 legacyEepromDetach(struct ath_hal
*ah
)
1757 HAL_EEPROM
*ee
= AH_PRIVATE(ah
)->ah_eeprom
;
1759 if (ee
->ee_version
>= AR_EEPROM_VER4_0
&& ee
->ee_eepMap
== 1)
1760 return freeEepromRawPowerCalInfo5112(ah
, ee
);
1762 AH_PRIVATE(ah
)->ah_eeprom
= AH_NULL
;
1766 * TODO: Need to talk to Praveen about this, these are
1767 * not valid 2.4 channels, either we change these
1768 * or I need to change the beanie coding to accept these
1770 static const uint16_t channels11b
[] = { 2412, 2447, 2484 };
1771 static const uint16_t channels11g
[] = { 2312, 2412, 2484 };
1774 ath_hal_legacyEepromAttach(struct ath_hal
*ah
)
1776 HAL_EEPROM
*ee
= AH_PRIVATE(ah
)->ah_eeprom
;
1777 uint32_t sum
, eepMax
;
1778 uint16_t eeversion
, eeprotect
, eeval
;
1781 HALASSERT(ee
== AH_NULL
);
1783 if (!ath_hal_eepromRead(ah
, AR_EEPROM_VERSION
, &eeversion
)) {
1784 HALDEBUG(ah
, HAL_DEBUG_ANY
,
1785 "%s: unable to read EEPROM version\n", __func__
);
1788 if (eeversion
< AR_EEPROM_VER3
) {
1789 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: unsupported EEPROM version "
1790 "%u (0x%x) found\n", __func__
, eeversion
, eeversion
);
1791 return HAL_EEVERSION
;
1794 if (!ath_hal_eepromRead(ah
, AR_EEPROM_PROTECT
, &eeprotect
)) {
1795 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: cannot read EEPROM protection "
1796 "bits; read locked?\n", __func__
);
1799 HALDEBUG(ah
, HAL_DEBUG_ATTACH
, "EEPROM protect 0x%x\n", eeprotect
);
1800 /* XXX check proper access before continuing */
1803 * Read the Atheros EEPROM entries and calculate the checksum.
1805 if (!ath_hal_eepromRead(ah
, AR_EEPROM_SIZE_UPPER
, &eeval
)) {
1806 HALDEBUG(ah
, HAL_DEBUG_ANY
,
1807 "%s: cannot read EEPROM upper size\n" , __func__
);
1811 eepMax
= (eeval
& AR_EEPROM_SIZE_UPPER_MASK
) <<
1812 AR_EEPROM_SIZE_ENDLOC_SHIFT
;
1813 if (!ath_hal_eepromRead(ah
, AR_EEPROM_SIZE_LOWER
, &eeval
)) {
1814 HALDEBUG(ah
, HAL_DEBUG_ANY
,
1815 "%s: cannot read EEPROM lower size\n" , __func__
);
1818 eepMax
= (eepMax
| eeval
) - AR_EEPROM_ATHEROS_BASE
;
1820 eepMax
= AR_EEPROM_ATHEROS_MAX
;
1822 for (i
= 0; i
< eepMax
; i
++) {
1823 if (!ath_hal_eepromRead(ah
, AR_EEPROM_ATHEROS(i
), &eeval
)) {
1828 if (sum
!= 0xffff) {
1829 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: bad EEPROM checksum 0x%x\n",
1831 return HAL_EEBADSUM
;
1834 ee
= ath_hal_malloc(sizeof(HAL_EEPROM
));
1835 if (ee
== AH_NULL
) {
1840 ee
->ee_protect
= eeprotect
;
1841 ee
->ee_version
= eeversion
;
1843 ee
->ee_numChannels11a
= NUM_11A_EEPROM_CHANNELS
;
1844 ee
->ee_numChannels2_4
= NUM_2_4_EEPROM_CHANNELS
;
1846 for (i
= 0; i
< NUM_11A_EEPROM_CHANNELS
; i
++)
1847 ee
->ee_dataPerChannel11a
[i
].numPcdacValues
= NUM_PCDAC_VALUES
;
1849 /* the channel list for 2.4 is fixed, fill this in here */
1850 for (i
= 0; i
< NUM_2_4_EEPROM_CHANNELS
; i
++) {
1851 ee
->ee_channels11b
[i
] = channels11b
[i
];
1852 /* XXX 5211 requires a hack though we don't support 11g */
1853 if (ah
->ah_magic
== 0x19570405)
1854 ee
->ee_channels11g
[i
] = channels11b
[i
];
1856 ee
->ee_channels11g
[i
] = channels11g
[i
];
1857 ee
->ee_dataPerChannel11b
[i
].numPcdacValues
= NUM_PCDAC_VALUES
;
1858 ee
->ee_dataPerChannel11g
[i
].numPcdacValues
= NUM_PCDAC_VALUES
;
1861 if (!legacyEepromReadContents(ah
, ee
)) {
1864 return HAL_EEREAD
; /* XXX */
1867 AH_PRIVATE(ah
)->ah_eeprom
= ee
;
1868 AH_PRIVATE(ah
)->ah_eeversion
= eeversion
;
1869 AH_PRIVATE(ah
)->ah_eepromDetach
= legacyEepromDetach
;
1870 AH_PRIVATE(ah
)->ah_eepromGet
= legacyEepromGet
;
1871 AH_PRIVATE(ah
)->ah_eepromSet
= legacyEepromSet
;
1872 AH_PRIVATE(ah
)->ah_getSpurChan
= legacyEepromGetSpurChan
;
1873 AH_PRIVATE(ah
)->ah_eepromDiag
= legacyEepromDiag
;