Update ath_hal from FreeBSD.
[dragonfly.git] / sys / dev / netif / ath / hal / ath_hal / ah_eeprom_v3.c
1 /*
2  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3  * Copyright (c) 2002-2008 Atheros Communications, Inc.
4  *
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.
8  *
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.
16  *
17  * $FreeBSD: head/sys/dev/ath/ath_hal/ah_eeprom_v3.c 196970 2009-09-08 13:19:05Z phk $
18  * $DragonFly$
19  */
20 #include "opt_ah.h"
21
22 #include "ah.h"
23 #include "ah_internal.h"
24 #include "ah_eeprom_v3.h"
25
26 static void
27 getPcdacInterceptsFromPcdacMinMax(HAL_EEPROM *ee,
28         uint16_t pcdacMin, uint16_t pcdacMax, uint16_t *vp)
29 {
30         static const uint16_t intercepts3[] =
31                 { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
32         static const uint16_t intercepts3_2[] =
33                 { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
34         const uint16_t *ip = ee->ee_version < AR_EEPROM_VER3_2 ?
35                 intercepts3 : intercepts3_2;
36         int i;
37
38         /* loop for the percentages in steps or 5 */
39         for (i = 0; i < NUM_INTERCEPTS; i++ )
40                 *vp++ = (ip[i] * pcdacMax + (100 - ip[i]) * pcdacMin) / 100;
41 }
42
43 /*
44  * Get channel value from binary representation held in eeprom
45  */
46 static uint16_t
47 fbin2freq(HAL_EEPROM *ee, uint16_t fbin)
48 {
49         if (fbin == CHANNEL_UNUSED)     /* reserved value, don't convert */
50                 return fbin;
51         return ee->ee_version <= AR_EEPROM_VER3_2 ?
52                 (fbin > 62 ? 5100 + 10*62 + 5*(fbin-62) : 5100 + 10*fbin) :
53                 4800 + 5*fbin;
54 }
55
56 static uint16_t
57 fbin2freq_2p4(HAL_EEPROM *ee, uint16_t fbin)
58 {
59         if (fbin == CHANNEL_UNUSED)     /* reserved value, don't convert */
60                 return fbin;
61         return ee->ee_version <= AR_EEPROM_VER3_2 ?
62                 2400 + fbin :
63                 2300 + fbin;
64 }
65
66 /*
67  * Now copy EEPROM frequency pier contents into the allocated space
68  */
69 static HAL_BOOL
70 readEepromFreqPierInfo(struct ath_hal *ah, HAL_EEPROM *ee)
71 {
72 #define EEREAD(_off) do {                               \
73         if (!ath_hal_eepromRead(ah, _off, &eeval))      \
74                 return AH_FALSE;                        \
75 } while (0)
76         uint16_t eeval, off;
77         int i;
78
79         if (ee->ee_version >= AR_EEPROM_VER4_0 &&
80             ee->ee_eepMap && !ee->ee_Amode) {
81                 /*
82                  * V4.0 EEPROMs with map type 1 have frequency pier
83                  * data only when 11a mode is supported.
84                  */
85                 return AH_TRUE;
86         }
87         if (ee->ee_version >= AR_EEPROM_VER3_3) {
88                 off = GROUPS_OFFSET3_3 + GROUP1_OFFSET;
89                 for (i = 0; i < ee->ee_numChannels11a; i += 2) {
90                         EEREAD(off++);
91                         ee->ee_channels11a[i]   = (eeval >> 8) & FREQ_MASK_3_3;
92                         ee->ee_channels11a[i+1] = eeval & FREQ_MASK_3_3;
93                 } 
94         } else {
95                 off = GROUPS_OFFSET3_2 + GROUP1_OFFSET;
96
97                 EEREAD(off++);
98                 ee->ee_channels11a[0] = (eeval >> 9) & FREQ_MASK;
99                 ee->ee_channels11a[1] = (eeval >> 2) & FREQ_MASK;
100                 ee->ee_channels11a[2] = (eeval << 5) & FREQ_MASK;
101
102                 EEREAD(off++);
103                 ee->ee_channels11a[2] |= (eeval >> 11) & 0x1f;
104                 ee->ee_channels11a[3]  = (eeval >>  4) & FREQ_MASK;
105                 ee->ee_channels11a[4]  = (eeval <<  3) & FREQ_MASK;
106
107                 EEREAD(off++);
108                 ee->ee_channels11a[4] |= (eeval >> 13) & 0x7;
109                 ee->ee_channels11a[5]  = (eeval >>  6) & FREQ_MASK;
110                 ee->ee_channels11a[6]  = (eeval <<  1) & FREQ_MASK;
111
112                 EEREAD(off++);
113                 ee->ee_channels11a[6] |= (eeval >> 15) & 0x1;
114                 ee->ee_channels11a[7]  = (eeval >>  8) & FREQ_MASK;
115                 ee->ee_channels11a[8]  = (eeval >>  1) & FREQ_MASK;
116                 ee->ee_channels11a[9]  = (eeval <<  6) & FREQ_MASK;
117
118                 EEREAD(off++);
119                 ee->ee_channels11a[9] |= (eeval >> 10) & 0x3f;
120         }
121
122         for (i = 0; i < ee->ee_numChannels11a; i++)
123                 ee->ee_channels11a[i] = fbin2freq(ee, ee->ee_channels11a[i]);
124
125         return AH_TRUE;
126 #undef EEREAD
127 }
128
129 /*
130  * Rev 4 Eeprom 5112 Power Extract Functions
131  */
132
133 /*
134  * Allocate the power information based on the number of channels
135  * recorded by the calibration.  These values are then initialized.
136  */
137 static HAL_BOOL
138 eepromAllocExpnPower5112(struct ath_hal *ah,
139         const EEPROM_POWER_5112 *pCalDataset,
140         EEPROM_POWER_EXPN_5112 *pPowerExpn)
141 {
142         uint16_t numChannels = pCalDataset->numChannels;
143         const uint16_t *pChanList = pCalDataset->pChannels;
144         void *data;
145         int i, j;
146
147         /* Allocate the channel and Power Data arrays together */
148         data = ath_hal_malloc(
149                 roundup(sizeof(uint16_t) * numChannels, sizeof(uint32_t)) +
150                 sizeof(EXPN_DATA_PER_CHANNEL_5112) * numChannels);
151         if (data == AH_NULL) {
152                 HALDEBUG(ah, HAL_DEBUG_ANY,
153                     "%s unable to allocate raw data struct (gen3)\n", __func__);
154                 return AH_FALSE;
155         }
156         pPowerExpn->pChannels = data;
157         pPowerExpn->pDataPerChannel = (void *)(((char *)data) +
158                 roundup(sizeof(uint16_t) * numChannels, sizeof(uint32_t)));
159
160         pPowerExpn->numChannels = numChannels;
161         for (i = 0; i < numChannels; i++) {
162                 pPowerExpn->pChannels[i] =
163                         pPowerExpn->pDataPerChannel[i].channelValue =
164                                 pChanList[i];
165                 for (j = 0; j < NUM_XPD_PER_CHANNEL; j++) {
166                         pPowerExpn->pDataPerChannel[i].pDataPerXPD[j].xpd_gain = j;
167                         pPowerExpn->pDataPerChannel[i].pDataPerXPD[j].numPcdacs = 0;
168                 }
169                 pPowerExpn->pDataPerChannel[i].pDataPerXPD[0].numPcdacs = 4;
170                 pPowerExpn->pDataPerChannel[i].pDataPerXPD[3].numPcdacs = 3;
171         }
172         return AH_TRUE;
173 }
174
175 /*
176  * Expand the dataSet from the calibration information into the
177  * final power structure for 5112
178  */
179 static HAL_BOOL
180 eepromExpandPower5112(struct ath_hal *ah,
181         const EEPROM_POWER_5112 *pCalDataset,
182         EEPROM_POWER_EXPN_5112 *pPowerExpn)
183 {
184         int ii, jj, kk;
185         int16_t maxPower_t4;
186         EXPN_DATA_PER_XPD_5112 *pExpnXPD;
187         /* ptr to array of info held per channel */
188         const EEPROM_DATA_PER_CHANNEL_5112 *pCalCh;
189         uint16_t xgainList[2], xpdMask;
190
191         pPowerExpn->xpdMask = pCalDataset->xpdMask;
192
193         xgainList[0] = 0xDEAD;
194         xgainList[1] = 0xDEAD;
195
196         kk = 0;
197         xpdMask = pPowerExpn->xpdMask;
198         for (jj = 0; jj < NUM_XPD_PER_CHANNEL; jj++) {
199                 if (((xpdMask >> jj) & 1) > 0) {
200                         if (kk > 1) {
201                                 HALDEBUG(ah, HAL_DEBUG_ANY,
202                                     "%s: too many xpdGains in dataset: %u\n",
203                                     __func__, kk);
204                                 return AH_FALSE;
205                         }
206                         xgainList[kk++] = jj;
207                 }
208         }
209
210         pPowerExpn->numChannels = pCalDataset->numChannels;
211         if (pPowerExpn->numChannels == 0) {
212                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no channels\n", __func__);
213                 return AH_FALSE;
214         }
215
216         for (ii = 0; ii < pPowerExpn->numChannels; ii++) {
217                 pCalCh = &pCalDataset->pDataPerChannel[ii];
218                 pPowerExpn->pDataPerChannel[ii].channelValue =
219                         pCalCh->channelValue;
220                 pPowerExpn->pDataPerChannel[ii].maxPower_t4 =
221                         pCalCh->maxPower_t4;
222                 maxPower_t4 = pPowerExpn->pDataPerChannel[ii].maxPower_t4;
223
224                 for (jj = 0; jj < NUM_XPD_PER_CHANNEL; jj++)
225                         pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj].numPcdacs = 0;
226                 if (xgainList[1] == 0xDEAD) {
227                         jj = xgainList[0];
228                         pExpnXPD = &pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj];
229                         pExpnXPD->numPcdacs = 4;
230                         pExpnXPD->pcdac[0] = pCalCh->pcd1_xg0;
231                         pExpnXPD->pcdac[1] = (uint16_t)
232                                 (pExpnXPD->pcdac[0] + pCalCh->pcd2_delta_xg0);
233                         pExpnXPD->pcdac[2] = (uint16_t)
234                                 (pExpnXPD->pcdac[1] + pCalCh->pcd3_delta_xg0);
235                         pExpnXPD->pcdac[3] = (uint16_t)
236                                 (pExpnXPD->pcdac[2] + pCalCh->pcd4_delta_xg0);
237
238                         pExpnXPD->pwr_t4[0] = pCalCh->pwr1_xg0;
239                         pExpnXPD->pwr_t4[1] = pCalCh->pwr2_xg0;
240                         pExpnXPD->pwr_t4[2] = pCalCh->pwr3_xg0;
241                         pExpnXPD->pwr_t4[3] = pCalCh->pwr4_xg0;
242
243                 } else {
244                         pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[0]].pcdac[0] = pCalCh->pcd1_xg0;
245                         pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[1]].pcdac[0] = 20;
246                         pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[1]].pcdac[1] = 35;
247                         pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[1]].pcdac[2] = 63;
248
249                         jj = xgainList[0];
250                         pExpnXPD = &pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj];
251                         pExpnXPD->numPcdacs = 4;
252                         pExpnXPD->pcdac[1] = (uint16_t)
253                                 (pExpnXPD->pcdac[0] + pCalCh->pcd2_delta_xg0);
254                         pExpnXPD->pcdac[2] = (uint16_t)
255                                 (pExpnXPD->pcdac[1] + pCalCh->pcd3_delta_xg0);
256                         pExpnXPD->pcdac[3] = (uint16_t)
257                                 (pExpnXPD->pcdac[2] + pCalCh->pcd4_delta_xg0);
258                         pExpnXPD->pwr_t4[0] = pCalCh->pwr1_xg0;
259                         pExpnXPD->pwr_t4[1] = pCalCh->pwr2_xg0;
260                         pExpnXPD->pwr_t4[2] = pCalCh->pwr3_xg0;
261                         pExpnXPD->pwr_t4[3] = pCalCh->pwr4_xg0;
262
263                         jj = xgainList[1];
264                         pExpnXPD = &pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj];
265                         pExpnXPD->numPcdacs = 3;
266
267                         pExpnXPD->pwr_t4[0] = pCalCh->pwr1_xg3;
268                         pExpnXPD->pwr_t4[1] = pCalCh->pwr2_xg3;
269                         pExpnXPD->pwr_t4[2] = pCalCh->pwr3_xg3;
270                 }
271         }
272         return AH_TRUE;
273 }
274
275 static HAL_BOOL
276 readEepromRawPowerCalInfo5112(struct ath_hal *ah, HAL_EEPROM *ee)
277 {
278 #define EEREAD(_off) do {                               \
279         if (!ath_hal_eepromRead(ah, _off, &eeval))      \
280                 return AH_FALSE;                        \
281 } while (0)
282         const uint16_t dbmmask           = 0xff;
283         const uint16_t pcdac_delta_mask = 0x1f;
284         const uint16_t pcdac_mask        = 0x3f;
285         const uint16_t freqmask  = 0xff;
286
287         int i, mode, numPiers;
288         uint32_t off;
289         uint16_t eeval;
290         uint16_t freq[NUM_11A_EEPROM_CHANNELS];
291         EEPROM_POWER_5112 eePower;
292
293         HALASSERT(ee->ee_version >= AR_EEPROM_VER4_0);
294         off = GROUPS_OFFSET3_3;
295         for (mode = headerInfo11A; mode <= headerInfo11G; mode++) {
296                 numPiers = 0;
297                 switch (mode) {
298                 case headerInfo11A:
299                         if (!ee->ee_Amode)      /* no 11a calibration data */
300                                 continue;
301                         while (numPiers < NUM_11A_EEPROM_CHANNELS) {
302                                 EEREAD(off++);
303                                 if ((eeval & freqmask) == 0)
304                                         break;
305                                 freq[numPiers++] = fbin2freq(ee,
306                                         eeval & freqmask);
307
308                                 if (((eeval >> 8) & freqmask) == 0)
309                                         break;
310                                 freq[numPiers++] = fbin2freq(ee,
311                                         (eeval>>8) & freqmask);
312                         }
313                         break;
314                 case headerInfo11B:
315                         if (!ee->ee_Bmode)      /* no 11b calibration data */
316                                 continue;
317                         for (i = 0; i < NUM_2_4_EEPROM_CHANNELS; i++)
318                                 if (ee->ee_calPier11b[i] != CHANNEL_UNUSED)
319                                         freq[numPiers++] = ee->ee_calPier11b[i];
320                         break;
321                 case headerInfo11G:
322                         if (!ee->ee_Gmode)      /* no 11g calibration data */
323                                 continue;
324                         for (i = 0; i < NUM_2_4_EEPROM_CHANNELS; i++)
325                                 if (ee->ee_calPier11g[i] != CHANNEL_UNUSED)
326                                         freq[numPiers++] = ee->ee_calPier11g[i];
327                         break;
328                 default:
329                         HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n",
330                             __func__, mode);
331                         return AH_FALSE;
332                 }
333
334                 OS_MEMZERO(&eePower, sizeof(eePower));
335                 eePower.numChannels = numPiers;
336
337                 for (i = 0; i < numPiers; i++) {
338                         eePower.pChannels[i] = freq[i];
339                         eePower.pDataPerChannel[i].channelValue = freq[i];
340
341                         EEREAD(off++);
342                         eePower.pDataPerChannel[i].pwr1_xg0 = (int16_t)
343                                 ((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256);
344                         eePower.pDataPerChannel[i].pwr2_xg0 = (int16_t)
345                                 (((eeval >> 8) & dbmmask) - ((eeval >> 15) & 0x1)*256);
346
347                         EEREAD(off++);
348                         eePower.pDataPerChannel[i].pwr3_xg0 = (int16_t)
349                                 ((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256);
350                         eePower.pDataPerChannel[i].pwr4_xg0 = (int16_t)
351                                 (((eeval >> 8) & dbmmask) - ((eeval >> 15) & 0x1)*256);
352
353                         EEREAD(off++);
354                         eePower.pDataPerChannel[i].pcd2_delta_xg0 = (uint16_t)
355                                 (eeval & pcdac_delta_mask);
356                         eePower.pDataPerChannel[i].pcd3_delta_xg0 = (uint16_t)
357                                 ((eeval >> 5) & pcdac_delta_mask);
358                         eePower.pDataPerChannel[i].pcd4_delta_xg0 = (uint16_t)
359                                 ((eeval >> 10) & pcdac_delta_mask);
360
361                         EEREAD(off++);
362                         eePower.pDataPerChannel[i].pwr1_xg3 = (int16_t)
363                                 ((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256);
364                         eePower.pDataPerChannel[i].pwr2_xg3 = (int16_t)
365                                 (((eeval >> 8) & dbmmask) - ((eeval >> 15) & 0x1)*256);
366
367                         EEREAD(off++);
368                         eePower.pDataPerChannel[i].pwr3_xg3 = (int16_t)
369                                 ((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256);
370                         if (ee->ee_version >= AR_EEPROM_VER4_3) {
371                                 eePower.pDataPerChannel[i].maxPower_t4 =
372                                         eePower.pDataPerChannel[i].pwr4_xg0;     
373                                 eePower.pDataPerChannel[i].pcd1_xg0 = (uint16_t)
374                                         ((eeval >> 8) & pcdac_mask);
375                         } else {
376                                 eePower.pDataPerChannel[i].maxPower_t4 = (int16_t)
377                                         (((eeval >> 8) & dbmmask) -
378                                          ((eeval >> 15) & 0x1)*256);
379                                 eePower.pDataPerChannel[i].pcd1_xg0 = 1;
380                         }
381                 }
382                 eePower.xpdMask = ee->ee_xgain[mode];
383
384                 if (!eepromAllocExpnPower5112(ah, &eePower, &ee->ee_modePowerArray5112[mode])) {
385                         HALDEBUG(ah, HAL_DEBUG_ANY,
386                             "%s: did not allocate power struct\n", __func__);
387                         return AH_FALSE;
388                 }
389                 if (!eepromExpandPower5112(ah, &eePower, &ee->ee_modePowerArray5112[mode])) {
390                         HALDEBUG(ah, HAL_DEBUG_ANY,
391                             "%s: did not expand power struct\n", __func__);
392                         return AH_FALSE;
393                 }
394         }
395         return AH_TRUE;
396 #undef EEREAD
397 }
398
399 static void
400 freeEepromRawPowerCalInfo5112(struct ath_hal *ah, HAL_EEPROM *ee)
401 {
402         int mode;
403         void *data;
404
405         for (mode = headerInfo11A; mode <= headerInfo11G; mode++) {
406                 EEPROM_POWER_EXPN_5112 *pPowerExpn =
407                         &ee->ee_modePowerArray5112[mode];
408                 data = pPowerExpn->pChannels;
409                 if (data != AH_NULL) {
410                         pPowerExpn->pChannels = AH_NULL;
411                         ath_hal_free(data);
412                 }
413         }
414 }
415
416 static void
417 ar2413SetupEEPROMDataset(EEPROM_DATA_STRUCT_2413 *pEEPROMDataset2413,
418         uint16_t myNumRawChannels, uint16_t *pMyRawChanList)
419 {
420         uint16_t i, channelValue;
421         uint32_t xpd_mask;
422         uint16_t numPdGainsUsed;
423
424         pEEPROMDataset2413->numChannels = myNumRawChannels;
425
426         xpd_mask = pEEPROMDataset2413->xpd_mask;
427         numPdGainsUsed = 0;
428         if ((xpd_mask >> 0) & 0x1) numPdGainsUsed++;
429         if ((xpd_mask >> 1) & 0x1) numPdGainsUsed++;
430         if ((xpd_mask >> 2) & 0x1) numPdGainsUsed++;
431         if ((xpd_mask >> 3) & 0x1) numPdGainsUsed++;
432
433         for (i = 0; i < myNumRawChannels; i++) {
434                 channelValue = pMyRawChanList[i];
435                 pEEPROMDataset2413->pChannels[i] = channelValue;
436                 pEEPROMDataset2413->pDataPerChannel[i].channelValue = channelValue;
437                 pEEPROMDataset2413->pDataPerChannel[i].numPdGains = numPdGainsUsed;
438         }
439 }
440
441 static HAL_BOOL
442 ar2413ReadCalDataset(struct ath_hal *ah, HAL_EEPROM *ee,
443         EEPROM_DATA_STRUCT_2413 *pCalDataset,
444         uint32_t start_offset, uint32_t maxPiers, uint8_t mode)
445 {
446 #define EEREAD(_off) do {                               \
447         if (!ath_hal_eepromRead(ah, _off, &eeval))      \
448                 return AH_FALSE;                        \
449 } while (0)
450         const uint16_t dbm_I_mask = 0x1F;       /* 5-bits. 1dB step. */
451         const uint16_t dbm_delta_mask = 0xF;    /* 4-bits. 0.5dB step. */
452         const uint16_t Vpd_I_mask = 0x7F;       /* 7-bits. 0-128 */
453         const uint16_t Vpd_delta_mask = 0x3F;   /* 6-bits. 0-63 */
454         const uint16_t freqmask = 0xff;
455
456         uint16_t ii, eeval;
457         uint16_t idx, numPiers;
458         uint16_t freq[NUM_11A_EEPROM_CHANNELS];
459
460         idx = start_offset;
461     for (numPiers = 0; numPiers < maxPiers;) {
462         EEREAD(idx++);
463         if ((eeval & freqmask) == 0)
464             break;
465         if (mode == headerInfo11A)
466             freq[numPiers++] = fbin2freq(ee, (eeval & freqmask));
467         else
468             freq[numPiers++] = fbin2freq_2p4(ee, (eeval & freqmask));
469                                                                                           
470         if (((eeval >> 8) & freqmask) == 0)
471             break;
472         if (mode == headerInfo11A)
473             freq[numPiers++] = fbin2freq(ee, (eeval >> 8) & freqmask);
474         else
475             freq[numPiers++] = fbin2freq_2p4(ee, (eeval >> 8) & freqmask);
476     }
477         ar2413SetupEEPROMDataset(pCalDataset, numPiers, &freq[0]);
478
479         idx = start_offset + (maxPiers / 2);
480         for (ii = 0; ii < pCalDataset->numChannels; ii++) {
481                 EEPROM_DATA_PER_CHANNEL_2413 *currCh =
482                         &(pCalDataset->pDataPerChannel[ii]);
483
484                 if (currCh->numPdGains > 0) {
485                         /*
486                          * Read the first NUM_POINTS_OTHER_PDGAINS pwr
487                          * and Vpd values for pdgain_0
488                          */
489                         EEREAD(idx++);
490                         currCh->pwr_I[0] = eeval & dbm_I_mask;
491                         currCh->Vpd_I[0] = (eeval >> 5) & Vpd_I_mask;
492                         currCh->pwr_delta_t2[0][0] =
493                                 (eeval >> 12) & dbm_delta_mask;
494                         
495                         EEREAD(idx++);
496                         currCh->Vpd_delta[0][0] = eeval & Vpd_delta_mask;
497                         currCh->pwr_delta_t2[1][0] =
498                                 (eeval >> 6) & dbm_delta_mask;
499                         currCh->Vpd_delta[1][0] =
500                                 (eeval >> 10) & Vpd_delta_mask;
501                         
502                         EEREAD(idx++);
503                         currCh->pwr_delta_t2[2][0] = eeval & dbm_delta_mask;
504                         currCh->Vpd_delta[2][0] = (eeval >> 4) & Vpd_delta_mask;
505                 }
506                 
507                 if (currCh->numPdGains > 1) {
508                         /*
509                          * Read the first NUM_POINTS_OTHER_PDGAINS pwr
510                          * and Vpd values for pdgain_1
511                          */
512                         currCh->pwr_I[1] = (eeval >> 10) & dbm_I_mask;
513                         currCh->Vpd_I[1] = (eeval >> 15) & 0x1;
514                         
515                         EEREAD(idx++);
516                         /* upper 6 bits */
517                         currCh->Vpd_I[1] |= (eeval & 0x3F) << 1;
518                         currCh->pwr_delta_t2[0][1] =
519                                 (eeval >> 6) & dbm_delta_mask;
520                         currCh->Vpd_delta[0][1] =
521                                 (eeval >> 10) & Vpd_delta_mask;
522                         
523                         EEREAD(idx++);
524                         currCh->pwr_delta_t2[1][1] = eeval & dbm_delta_mask;
525                         currCh->Vpd_delta[1][1] = (eeval >> 4) & Vpd_delta_mask;
526                         currCh->pwr_delta_t2[2][1] =
527                                 (eeval >> 10) & dbm_delta_mask;
528                         currCh->Vpd_delta[2][1] = (eeval >> 14) & 0x3;
529                         
530                         EEREAD(idx++);
531                         /* upper 4 bits */
532                         currCh->Vpd_delta[2][1] |= (eeval & 0xF) << 2;
533                 } else if (currCh->numPdGains == 1) {
534                         /*
535                          * Read the last pwr and Vpd values for pdgain_0
536                          */
537                         currCh->pwr_delta_t2[3][0] =
538                                 (eeval >> 10) & dbm_delta_mask;
539                         currCh->Vpd_delta[3][0] = (eeval >> 14) & 0x3;
540
541                         EEREAD(idx++);
542                         /* upper 4 bits */
543                         currCh->Vpd_delta[3][0] |= (eeval & 0xF) << 2;
544
545                         /* 4 words if numPdGains == 1 */
546                 }
547
548                 if (currCh->numPdGains > 2) {
549                         /*
550                          * Read the first NUM_POINTS_OTHER_PDGAINS pwr
551                          * and Vpd values for pdgain_2
552                          */
553                         currCh->pwr_I[2] = (eeval >> 4) & dbm_I_mask;
554                         currCh->Vpd_I[2] = (eeval >> 9) & Vpd_I_mask;
555                         
556                         EEREAD(idx++);
557                         currCh->pwr_delta_t2[0][2] =
558                                 (eeval >> 0) & dbm_delta_mask;
559                         currCh->Vpd_delta[0][2] = (eeval >> 4) & Vpd_delta_mask;
560                         currCh->pwr_delta_t2[1][2] =
561                                 (eeval >> 10) & dbm_delta_mask;
562                         currCh->Vpd_delta[1][2] = (eeval >> 14) & 0x3;
563                         
564                         EEREAD(idx++);
565                         /* upper 4 bits */
566                         currCh->Vpd_delta[1][2] |= (eeval & 0xF) << 2;
567                         currCh->pwr_delta_t2[2][2] =
568                                 (eeval >> 4) & dbm_delta_mask;
569                         currCh->Vpd_delta[2][2] = (eeval >> 8) & Vpd_delta_mask;
570                 } else if (currCh->numPdGains == 2) {
571                         /*
572                          * Read the last pwr and Vpd values for pdgain_1
573                          */
574                         currCh->pwr_delta_t2[3][1] =
575                                 (eeval >> 4) & dbm_delta_mask;
576                         currCh->Vpd_delta[3][1] = (eeval >> 8) & Vpd_delta_mask;
577
578                         /* 6 words if numPdGains == 2 */
579                 }
580
581                 if (currCh->numPdGains > 3) {
582                         /*
583                          * Read the first NUM_POINTS_OTHER_PDGAINS pwr
584                          * and Vpd values for pdgain_3
585                          */
586                         currCh->pwr_I[3] = (eeval >> 14) & 0x3;
587                         
588                         EEREAD(idx++);
589                         /* upper 3 bits */
590                         currCh->pwr_I[3] |= ((eeval >> 0) & 0x7) << 2;
591                         currCh->Vpd_I[3] = (eeval >> 3) & Vpd_I_mask;
592                         currCh->pwr_delta_t2[0][3] =
593                                 (eeval >> 10) & dbm_delta_mask;
594                         currCh->Vpd_delta[0][3] = (eeval >> 14) & 0x3;
595                         
596                         EEREAD(idx++);
597                         /* upper 4 bits */
598                         currCh->Vpd_delta[0][3] |= (eeval & 0xF) << 2;
599                         currCh->pwr_delta_t2[1][3] =
600                                 (eeval >> 4) & dbm_delta_mask;
601                         currCh->Vpd_delta[1][3] = (eeval >> 8) & Vpd_delta_mask;
602                         currCh->pwr_delta_t2[2][3] = (eeval >> 14) & 0x3;
603                         
604                         EEREAD(idx++);
605                         /* upper 2 bits */
606                         currCh->pwr_delta_t2[2][3] |= ((eeval >> 0) & 0x3) << 2;
607                         currCh->Vpd_delta[2][3] = (eeval >> 2) & Vpd_delta_mask;
608                         currCh->pwr_delta_t2[3][3] =
609                                 (eeval >> 8) & dbm_delta_mask;
610                         currCh->Vpd_delta[3][3] = (eeval >> 12) & 0xF;
611                         
612                         EEREAD(idx++);
613                         /* upper 2 bits */
614                         currCh->Vpd_delta[3][3] |= ((eeval >> 0) & 0x3) << 4;
615
616                         /* 12 words if numPdGains == 4 */
617                 } else if (currCh->numPdGains == 3) {
618                         /* read the last pwr and Vpd values for pdgain_2 */
619                         currCh->pwr_delta_t2[3][2] = (eeval >> 14) & 0x3;
620                         
621                         EEREAD(idx++);
622                         /* upper 2 bits */
623                         currCh->pwr_delta_t2[3][2] |= ((eeval >> 0) & 0x3) << 2;
624                         currCh->Vpd_delta[3][2] = (eeval >> 2) & Vpd_delta_mask;
625
626                         /* 9 words if numPdGains == 3 */
627                 }
628         }
629         return AH_TRUE;
630 #undef EEREAD
631 }
632
633 static void
634 ar2413SetupRawDataset(RAW_DATA_STRUCT_2413 *pRaw, EEPROM_DATA_STRUCT_2413 *pCal)
635 {
636         uint16_t i, j, kk, channelValue;
637         uint16_t xpd_mask;
638         uint16_t numPdGainsUsed;
639
640         pRaw->numChannels = pCal->numChannels;
641
642         xpd_mask = pRaw->xpd_mask;
643         numPdGainsUsed = 0;
644         if ((xpd_mask >> 0) & 0x1) numPdGainsUsed++;
645         if ((xpd_mask >> 1) & 0x1) numPdGainsUsed++;
646         if ((xpd_mask >> 2) & 0x1) numPdGainsUsed++;
647         if ((xpd_mask >> 3) & 0x1) numPdGainsUsed++;
648
649         for (i = 0; i < pCal->numChannels; i++) {
650                 channelValue = pCal->pChannels[i];
651
652                 pRaw->pChannels[i] = channelValue;
653
654                 pRaw->pDataPerChannel[i].channelValue = channelValue;
655                 pRaw->pDataPerChannel[i].numPdGains = numPdGainsUsed;
656
657                 kk = 0;
658                 for (j = 0; j < MAX_NUM_PDGAINS_PER_CHANNEL; j++) {
659                         pRaw->pDataPerChannel[i].pDataPerPDGain[j].pd_gain = j;
660                         if ((xpd_mask >> j) & 0x1) {
661                                 pRaw->pDataPerChannel[i].pDataPerPDGain[j].numVpd = NUM_POINTS_OTHER_PDGAINS;
662                                 kk++;
663                                 if (kk == 1) {
664                                         /* 
665                                          * lowest pd_gain corresponds
666                                          *  to highest power and thus,
667                                          *  has one more point
668                                          */
669                                         pRaw->pDataPerChannel[i].pDataPerPDGain[j].numVpd = NUM_POINTS_LAST_PDGAIN;
670                                 }
671                         } else {
672                                 pRaw->pDataPerChannel[i].pDataPerPDGain[j].numVpd = 0;
673                         }
674                 }
675         }
676 }
677
678 static HAL_BOOL
679 ar2413EepromToRawDataset(struct ath_hal *ah,
680         EEPROM_DATA_STRUCT_2413 *pCal, RAW_DATA_STRUCT_2413 *pRaw)
681 {
682         uint16_t ii, jj, kk, ss;
683         RAW_DATA_PER_PDGAIN_2413 *pRawXPD;
684         /* ptr to array of info held per channel */
685         EEPROM_DATA_PER_CHANNEL_2413 *pCalCh;
686         uint16_t xgain_list[MAX_NUM_PDGAINS_PER_CHANNEL];
687         uint16_t xpd_mask;
688         uint32_t numPdGainsUsed;
689
690         HALASSERT(pRaw->xpd_mask == pCal->xpd_mask);
691
692         xgain_list[0] = 0xDEAD;
693         xgain_list[1] = 0xDEAD;
694         xgain_list[2] = 0xDEAD;
695         xgain_list[3] = 0xDEAD;
696
697         numPdGainsUsed = 0;
698         xpd_mask = pRaw->xpd_mask;
699         for (jj = 0; jj < MAX_NUM_PDGAINS_PER_CHANNEL; jj++) {
700                 if ((xpd_mask >> (MAX_NUM_PDGAINS_PER_CHANNEL-jj-1)) & 1)
701                         xgain_list[numPdGainsUsed++] = MAX_NUM_PDGAINS_PER_CHANNEL-jj-1;
702         }
703
704         pRaw->numChannels = pCal->numChannels;
705         for (ii = 0; ii < pRaw->numChannels; ii++) {
706                 pCalCh = &(pCal->pDataPerChannel[ii]);
707                 pRaw->pDataPerChannel[ii].channelValue = pCalCh->channelValue;
708
709                 /* numVpd has already been setup appropriately for the relevant pdGains */
710                 for (jj = 0; jj < numPdGainsUsed; jj++) {
711                         /* use jj for calDataset and ss for rawDataset */
712                         ss = xgain_list[jj];
713                         pRawXPD = &(pRaw->pDataPerChannel[ii].pDataPerPDGain[ss]);
714                         HALASSERT(pRawXPD->numVpd >= 1);
715
716                         pRawXPD->pwr_t4[0] = (uint16_t)(4*pCalCh->pwr_I[jj]);
717                         pRawXPD->Vpd[0]    = pCalCh->Vpd_I[jj];
718
719                         for (kk = 1; kk < pRawXPD->numVpd; kk++) {
720                                 pRawXPD->pwr_t4[kk] = (int16_t)(pRawXPD->pwr_t4[kk-1] + 2*pCalCh->pwr_delta_t2[kk-1][jj]);
721                                 pRawXPD->Vpd[kk] = (uint16_t)(pRawXPD->Vpd[kk-1] + pCalCh->Vpd_delta[kk-1][jj]);
722                         }
723                         /* loop over Vpds */
724                 }
725                 /* loop over pd_gains */
726         }
727         /* loop over channels */
728         return AH_TRUE;
729 }
730
731 static HAL_BOOL
732 readEepromRawPowerCalInfo2413(struct ath_hal *ah, HAL_EEPROM *ee)
733 {
734         /* NB: index is 1 less than numPdgains */
735         static const uint16_t wordsForPdgains[] = { 4, 6, 9, 12 };
736         EEPROM_DATA_STRUCT_2413 *pCal = AH_NULL;
737         RAW_DATA_STRUCT_2413 *pRaw;
738         int numEEPROMWordsPerChannel;
739         uint32_t off;
740         HAL_BOOL ret = AH_FALSE;
741         
742         HALASSERT(ee->ee_version >= AR_EEPROM_VER5_0);
743         HALASSERT(ee->ee_eepMap == 2);
744         
745         pCal = ath_hal_malloc(sizeof(EEPROM_DATA_STRUCT_2413));
746         if (pCal == AH_NULL)
747                 goto exit;
748         
749         off = ee->ee_eepMap2PowerCalStart;
750         if (ee->ee_Amode) {
751                 OS_MEMZERO(pCal, sizeof(EEPROM_DATA_STRUCT_2413));
752                 pCal->xpd_mask = ee->ee_xgain[headerInfo11A];
753                 if (!ar2413ReadCalDataset(ah, ee, pCal, off,
754                         NUM_11A_EEPROM_CHANNELS_2413, headerInfo11A)) {
755                         goto exit;
756                 }
757                 pRaw = &ee->ee_rawDataset2413[headerInfo11A];
758                 pRaw->xpd_mask = ee->ee_xgain[headerInfo11A];
759                 ar2413SetupRawDataset(pRaw, pCal);
760                 if (!ar2413EepromToRawDataset(ah, pCal, pRaw)) {
761                         goto exit;
762                 }
763                 /* setup offsets for mode_11a next */
764                 numEEPROMWordsPerChannel = wordsForPdgains[
765                         pCal->pDataPerChannel[0].numPdGains - 1];
766                 off += pCal->numChannels * numEEPROMWordsPerChannel + 5;
767         }
768         if (ee->ee_Bmode) {
769                 OS_MEMZERO(pCal, sizeof(EEPROM_DATA_STRUCT_2413));
770                 pCal->xpd_mask = ee->ee_xgain[headerInfo11B];
771                 if (!ar2413ReadCalDataset(ah, ee, pCal, off,
772                         NUM_2_4_EEPROM_CHANNELS_2413 , headerInfo11B)) {
773                         goto exit;
774                 }
775                 pRaw = &ee->ee_rawDataset2413[headerInfo11B];
776                 pRaw->xpd_mask = ee->ee_xgain[headerInfo11B];
777                 ar2413SetupRawDataset(pRaw, pCal);
778                 if (!ar2413EepromToRawDataset(ah, pCal, pRaw)) {
779                         goto exit;
780                 }
781                 /* setup offsets for mode_11g next */
782                 numEEPROMWordsPerChannel = wordsForPdgains[
783                         pCal->pDataPerChannel[0].numPdGains - 1];
784                 off += pCal->numChannels * numEEPROMWordsPerChannel + 2;
785         }
786         if (ee->ee_Gmode) {
787                 OS_MEMZERO(pCal, sizeof(EEPROM_DATA_STRUCT_2413));
788                 pCal->xpd_mask = ee->ee_xgain[headerInfo11G];
789                 if (!ar2413ReadCalDataset(ah, ee, pCal, off,
790                         NUM_2_4_EEPROM_CHANNELS_2413, headerInfo11G)) {
791                         goto exit;
792                 }
793                 pRaw = &ee->ee_rawDataset2413[headerInfo11G];
794                 pRaw->xpd_mask = ee->ee_xgain[headerInfo11G];
795                 ar2413SetupRawDataset(pRaw, pCal);
796                 if (!ar2413EepromToRawDataset(ah, pCal, pRaw)) {
797                         goto exit;
798                 }
799         }
800         ret = AH_TRUE;
801  exit:
802         if (pCal != AH_NULL)
803                 ath_hal_free(pCal);
804         return ret;
805 }
806
807 /*
808  * Now copy EEPROM Raw Power Calibration per frequency contents 
809  * into the allocated space
810  */
811 static HAL_BOOL
812 readEepromRawPowerCalInfo(struct ath_hal *ah, HAL_EEPROM *ee)
813 {
814 #define EEREAD(_off) do {                               \
815         if (!ath_hal_eepromRead(ah, _off, &eeval))      \
816                 return AH_FALSE;                        \
817 } while (0)
818         uint16_t eeval, nchan;
819         uint32_t off;
820         int i, j, mode;
821
822         if (ee->ee_version >= AR_EEPROM_VER4_0 && ee->ee_eepMap == 1)
823                 return readEepromRawPowerCalInfo5112(ah, ee);
824         if (ee->ee_version >= AR_EEPROM_VER5_0 && ee->ee_eepMap == 2)
825                 return readEepromRawPowerCalInfo2413(ah, ee);
826
827         /*
828          * Group 2:  read raw power data for all frequency piers
829          *
830          * NOTE: Group 2 contains the raw power calibration
831          *       information for each of the channels that
832          *       we recorded above.
833          */
834         for (mode = headerInfo11A; mode <= headerInfo11G; mode++) {
835                 uint16_t *pChannels = AH_NULL;
836                 DATA_PER_CHANNEL *pChannelData = AH_NULL;
837
838                 off = ee->ee_version >= AR_EEPROM_VER3_3 ? 
839                         GROUPS_OFFSET3_3 : GROUPS_OFFSET3_2;
840                 switch (mode) {
841                 case headerInfo11A:
842                         off             += GROUP2_OFFSET;
843                         nchan           = ee->ee_numChannels11a;
844                         pChannelData    = ee->ee_dataPerChannel11a;
845                         pChannels       = ee->ee_channels11a;
846                         break;
847                 case headerInfo11B:
848                         if (!ee->ee_Bmode)
849                                 continue;
850                         off             += GROUP3_OFFSET;
851                         nchan           = ee->ee_numChannels2_4;
852                         pChannelData    = ee->ee_dataPerChannel11b;
853                         pChannels       = ee->ee_channels11b;
854                         break;
855                 case headerInfo11G:
856                         if (!ee->ee_Gmode)
857                                 continue;
858                         off             += GROUP4_OFFSET;
859                         nchan           = ee->ee_numChannels2_4;
860                         pChannelData    = ee->ee_dataPerChannel11g;
861                         pChannels       = ee->ee_channels11g;
862                         break;
863                 default:
864                         HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n",
865                             __func__, mode);
866                         return AH_FALSE;
867                 }
868                 for (i = 0; i < nchan; i++) {
869                         pChannelData->channelValue = pChannels[i];
870
871                         EEREAD(off++);
872                         pChannelData->pcdacMax     = (uint16_t)((eeval >> 10) & PCDAC_MASK);
873                         pChannelData->pcdacMin     = (uint16_t)((eeval >> 4) & PCDAC_MASK);
874                         pChannelData->PwrValues[0] = (uint16_t)((eeval << 2) & POWER_MASK);
875
876                         EEREAD(off++);
877                         pChannelData->PwrValues[0] |= (uint16_t)((eeval >> 14) & 0x3);
878                         pChannelData->PwrValues[1] = (uint16_t)((eeval >> 8) & POWER_MASK);
879                         pChannelData->PwrValues[2] = (uint16_t)((eeval >> 2) & POWER_MASK);
880                         pChannelData->PwrValues[3] = (uint16_t)((eeval << 4) & POWER_MASK);
881
882                         EEREAD(off++);
883                         pChannelData->PwrValues[3] |= (uint16_t)((eeval >> 12) & 0xf);
884                         pChannelData->PwrValues[4] = (uint16_t)((eeval >> 6) & POWER_MASK);
885                         pChannelData->PwrValues[5] = (uint16_t)(eeval  & POWER_MASK);
886
887                         EEREAD(off++);
888                         pChannelData->PwrValues[6] = (uint16_t)((eeval >> 10) & POWER_MASK);
889                         pChannelData->PwrValues[7] = (uint16_t)((eeval >> 4) & POWER_MASK);
890                         pChannelData->PwrValues[8] = (uint16_t)((eeval << 2) & POWER_MASK);
891
892                         EEREAD(off++);
893                         pChannelData->PwrValues[8] |= (uint16_t)((eeval >> 14) & 0x3);
894                         pChannelData->PwrValues[9] = (uint16_t)((eeval >> 8) & POWER_MASK);
895                         pChannelData->PwrValues[10] = (uint16_t)((eeval >> 2) & POWER_MASK);
896
897                         getPcdacInterceptsFromPcdacMinMax(ee,
898                                 pChannelData->pcdacMin, pChannelData->pcdacMax,
899                                 pChannelData->PcdacValues) ;
900
901                         for (j = 0; j < pChannelData->numPcdacValues; j++) {
902                                 pChannelData->PwrValues[j] = (uint16_t)(
903                                         PWR_STEP * pChannelData->PwrValues[j]);
904                                 /* Note these values are scaled up. */
905                         }
906                         pChannelData++;
907                 }
908         }
909         return AH_TRUE;
910 #undef EEREAD
911 }
912
913 /*
914  * Copy EEPROM Target Power Calbration per rate contents 
915  * into the allocated space
916  */
917 static HAL_BOOL
918 readEepromTargetPowerCalInfo(struct ath_hal *ah, HAL_EEPROM *ee)
919 {
920 #define EEREAD(_off) do {                               \
921         if (!ath_hal_eepromRead(ah, _off, &eeval))      \
922                 return AH_FALSE;                        \
923 } while (0)
924         uint16_t eeval, enable24;
925         uint32_t off;
926         int i, mode, nchan;
927
928         enable24 = ee->ee_Bmode || ee->ee_Gmode;
929         for (mode = headerInfo11A; mode <= headerInfo11G; mode++) {
930                 TRGT_POWER_INFO *pPowerInfo;
931                 uint16_t *pNumTrgtChannels;
932
933                 off = ee->ee_version >= AR_EEPROM_VER4_0 ?
934                                 ee->ee_targetPowersStart - GROUP5_OFFSET :
935                       ee->ee_version >= AR_EEPROM_VER3_3 ?
936                                 GROUPS_OFFSET3_3 : GROUPS_OFFSET3_2;
937                 switch (mode) {
938                 case headerInfo11A:
939                         off += GROUP5_OFFSET;
940                         nchan = NUM_TEST_FREQUENCIES;
941                         pPowerInfo = ee->ee_trgtPwr_11a;
942                         pNumTrgtChannels = &ee->ee_numTargetPwr_11a;
943                         break;
944                 case headerInfo11B:
945                         if (!enable24)
946                                 continue;
947                         off += GROUP6_OFFSET;
948                         nchan = 2;
949                         pPowerInfo = ee->ee_trgtPwr_11b;
950                         pNumTrgtChannels = &ee->ee_numTargetPwr_11b;
951                         break;
952                 case headerInfo11G:
953                         if (!enable24)
954                                 continue;
955                         off += GROUP7_OFFSET;
956                         nchan = 3;
957                         pPowerInfo = ee->ee_trgtPwr_11g;
958                         pNumTrgtChannels = &ee->ee_numTargetPwr_11g;
959                         break;
960                 default:
961                         HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n",
962                             __func__, mode);
963                         return AH_FALSE;
964                 }
965                 *pNumTrgtChannels = 0;
966                 for (i = 0; i < nchan; i++) {
967                         EEREAD(off++);
968                         if (ee->ee_version >= AR_EEPROM_VER3_3) {
969                                 pPowerInfo->testChannel = (eeval >> 8) & 0xff;
970                         } else {
971                                 pPowerInfo->testChannel = (eeval >> 9) & 0x7f;
972                         }
973
974                         if (pPowerInfo->testChannel != 0) {
975                                 /* get the channel value and read rest of info */
976                                 if (mode == headerInfo11A) {
977                                         pPowerInfo->testChannel = fbin2freq(ee, pPowerInfo->testChannel);
978                                 } else {
979                                         pPowerInfo->testChannel = fbin2freq_2p4(ee, pPowerInfo->testChannel);
980                                 }
981
982                                 if (ee->ee_version >= AR_EEPROM_VER3_3) {
983                                         pPowerInfo->twicePwr6_24 = (eeval >> 2) & POWER_MASK;
984                                         pPowerInfo->twicePwr36   = (eeval << 4) & POWER_MASK;
985                                 } else {
986                                         pPowerInfo->twicePwr6_24 = (eeval >> 3) & POWER_MASK;
987                                         pPowerInfo->twicePwr36   = (eeval << 3) & POWER_MASK;
988                                 }
989
990                                 EEREAD(off++);
991                                 if (ee->ee_version >= AR_EEPROM_VER3_3) {
992                                         pPowerInfo->twicePwr36 |= (eeval >> 12) & 0xf;
993                                         pPowerInfo->twicePwr48 = (eeval >> 6) & POWER_MASK;
994                                         pPowerInfo->twicePwr54 =  eeval & POWER_MASK;
995                                 } else {
996                                         pPowerInfo->twicePwr36 |= (eeval >> 13) & 0x7;
997                                         pPowerInfo->twicePwr48 = (eeval >> 7) & POWER_MASK;
998                                         pPowerInfo->twicePwr54 = (eeval >> 1) & POWER_MASK;
999                                 }
1000                                 (*pNumTrgtChannels)++;
1001                         }
1002                         pPowerInfo++;
1003                 }
1004         }
1005         return AH_TRUE;
1006 #undef EEREAD
1007 }
1008
1009 /*
1010  * Now copy EEPROM Coformance Testing Limits contents 
1011  * into the allocated space
1012  */
1013 static HAL_BOOL
1014 readEepromCTLInfo(struct ath_hal *ah, HAL_EEPROM *ee)
1015 {
1016 #define EEREAD(_off) do {                               \
1017         if (!ath_hal_eepromRead(ah, _off, &eeval))      \
1018                 return AH_FALSE;                        \
1019 } while (0)
1020         RD_EDGES_POWER *rep;
1021         uint16_t eeval;
1022         uint32_t off;
1023         int i, j;
1024
1025         rep = ee->ee_rdEdgesPower;
1026
1027         off = GROUP8_OFFSET +
1028                 (ee->ee_version >= AR_EEPROM_VER4_0 ?
1029                         ee->ee_targetPowersStart - GROUP5_OFFSET :
1030                  ee->ee_version >= AR_EEPROM_VER3_3 ?
1031                         GROUPS_OFFSET3_3 : GROUPS_OFFSET3_2);
1032         for (i = 0; i < ee->ee_numCtls; i++) {
1033                 if (ee->ee_ctl[i] == 0) {
1034                         /* Move offset and edges */
1035                         off += (ee->ee_version >= AR_EEPROM_VER3_3 ? 8 : 7);
1036                         rep += NUM_EDGES;
1037                         continue;
1038                 }
1039                 if (ee->ee_version >= AR_EEPROM_VER3_3) {
1040                         for (j = 0; j < NUM_EDGES; j += 2) {
1041                                 EEREAD(off++);
1042                                 rep[j].rdEdge = (eeval >> 8) & FREQ_MASK_3_3;
1043                                 rep[j+1].rdEdge = eeval & FREQ_MASK_3_3;
1044                         }
1045                         for (j = 0; j < NUM_EDGES; j += 2) {
1046                                 EEREAD(off++);
1047                                 rep[j].twice_rdEdgePower = 
1048                                         (eeval >> 8) & POWER_MASK;
1049                                 rep[j].flag = (eeval >> 14) & 1;
1050                                 rep[j+1].twice_rdEdgePower = eeval & POWER_MASK;
1051                                 rep[j+1].flag = (eeval >> 6) & 1;
1052                         }
1053                 } else { 
1054                         EEREAD(off++);
1055                         rep[0].rdEdge = (eeval >> 9) & FREQ_MASK;
1056                         rep[1].rdEdge = (eeval >> 2) & FREQ_MASK;
1057                         rep[2].rdEdge = (eeval << 5) & FREQ_MASK;
1058
1059                         EEREAD(off++);
1060                         rep[2].rdEdge |= (eeval >> 11) & 0x1f;
1061                         rep[3].rdEdge = (eeval >> 4) & FREQ_MASK;
1062                         rep[4].rdEdge = (eeval << 3) & FREQ_MASK;
1063
1064                         EEREAD(off++);
1065                         rep[4].rdEdge |= (eeval >> 13) & 0x7;
1066                         rep[5].rdEdge = (eeval >> 6) & FREQ_MASK;
1067                         rep[6].rdEdge = (eeval << 1) & FREQ_MASK;
1068
1069                         EEREAD(off++);
1070                         rep[6].rdEdge |= (eeval >> 15) & 0x1;
1071                         rep[7].rdEdge = (eeval >> 8) & FREQ_MASK;
1072
1073                         rep[0].twice_rdEdgePower = (eeval >> 2) & POWER_MASK;
1074                         rep[1].twice_rdEdgePower = (eeval << 4) & POWER_MASK;
1075
1076                         EEREAD(off++);
1077                         rep[1].twice_rdEdgePower |= (eeval >> 12) & 0xf;
1078                         rep[2].twice_rdEdgePower = (eeval >> 6) & POWER_MASK;
1079                         rep[3].twice_rdEdgePower = eeval & POWER_MASK;
1080
1081                         EEREAD(off++);
1082                         rep[4].twice_rdEdgePower = (eeval >> 10) & POWER_MASK;
1083                         rep[5].twice_rdEdgePower = (eeval >> 4) & POWER_MASK;
1084                         rep[6].twice_rdEdgePower = (eeval << 2) & POWER_MASK;
1085
1086                         EEREAD(off++);
1087                         rep[6].twice_rdEdgePower |= (eeval >> 14) & 0x3;
1088                         rep[7].twice_rdEdgePower = (eeval >> 8) & POWER_MASK;
1089                 }
1090
1091                 for (j = 0; j < NUM_EDGES; j++ ) {
1092                         if (rep[j].rdEdge != 0 || rep[j].twice_rdEdgePower != 0) {
1093                                 if ((ee->ee_ctl[i] & CTL_MODE_M) == CTL_11A ||
1094                                     (ee->ee_ctl[i] & CTL_MODE_M) == CTL_TURBO) {
1095                                         rep[j].rdEdge = fbin2freq(ee, rep[j].rdEdge);
1096                                 } else {
1097                                         rep[j].rdEdge = fbin2freq_2p4(ee, rep[j].rdEdge);
1098                                 }
1099                         }
1100                 }
1101                 rep += NUM_EDGES;
1102         }
1103         return AH_TRUE;
1104 #undef EEREAD
1105 }
1106
1107 /*
1108  * Read the individual header fields for a Rev 3 EEPROM
1109  */
1110 static HAL_BOOL
1111 readHeaderInfo(struct ath_hal *ah, HAL_EEPROM *ee)
1112 {
1113 #define EEREAD(_off) do {                               \
1114         if (!ath_hal_eepromRead(ah, _off, &eeval))      \
1115                 return AH_FALSE;                        \
1116 } while (0)
1117         static const uint32_t headerOffset3_0[] = {
1118                 0x00C2, /* 0 - Mode bits, device type, max turbo power */
1119                 0x00C4, /* 1 - 2.4 and 5 antenna gain */
1120                 0x00C5, /* 2 - Begin 11A modal section */
1121                 0x00D0, /* 3 - Begin 11B modal section */
1122                 0x00DA, /* 4 - Begin 11G modal section */
1123                 0x00E4  /* 5 - Begin CTL section */
1124         };
1125         static const uint32_t headerOffset3_3[] = {
1126                 0x00C2, /* 0 - Mode bits, device type, max turbo power */
1127                 0x00C3, /* 1 - 2.4 and 5 antenna gain */
1128                 0x00D4, /* 2 - Begin 11A modal section */
1129                 0x00F2, /* 3 - Begin 11B modal section */
1130                 0x010D, /* 4 - Begin 11G modal section */
1131                 0x0128  /* 5 - Begin CTL section */
1132         };
1133
1134         static const uint32_t regCapOffsetPre4_0 = 0x00CF;
1135         static const uint32_t regCapOffsetPost4_0 = 0x00CA; 
1136
1137         const uint32_t *header;
1138         uint32_t off;
1139         uint16_t eeval;
1140         int i;
1141
1142         /* initialize cckOfdmGainDelta for < 4.2 eeprom */
1143         ee->ee_cckOfdmGainDelta = CCK_OFDM_GAIN_DELTA;
1144         ee->ee_scaledCh14FilterCckDelta = TENX_CH14_FILTER_CCK_DELTA_INIT;
1145
1146         if (ee->ee_version >= AR_EEPROM_VER3_3) {
1147                 header = headerOffset3_3;
1148                 ee->ee_numCtls = NUM_CTLS_3_3;
1149         } else {
1150                 header = headerOffset3_0;
1151                 ee->ee_numCtls = NUM_CTLS;
1152         }
1153         HALASSERT(ee->ee_numCtls <= NUM_CTLS_MAX);
1154
1155         EEREAD(header[0]);
1156         ee->ee_turbo5Disable    = (eeval >> 15) & 0x01;
1157         ee->ee_rfKill           = (eeval >> 14) & 0x01;
1158         ee->ee_deviceType       = (eeval >> 11) & 0x07;
1159         ee->ee_turbo2WMaxPower5 = (eeval >> 4) & 0x7F;
1160         if (ee->ee_version >= AR_EEPROM_VER4_0)
1161                 ee->ee_turbo2Disable    = (eeval >> 3) & 0x01;
1162         else
1163                 ee->ee_turbo2Disable    = 1;
1164         ee->ee_Gmode            = (eeval >> 2) & 0x01;
1165         ee->ee_Bmode            = (eeval >> 1) & 0x01;
1166         ee->ee_Amode            = (eeval & 0x01);
1167
1168         off = header[1];
1169         EEREAD(off++);
1170         ee->ee_antennaGainMax[0] = (int8_t)((eeval >> 8) & 0xFF);
1171         ee->ee_antennaGainMax[1] = (int8_t)(eeval & 0xFF);
1172         if (ee->ee_version >= AR_EEPROM_VER4_0) {
1173                 EEREAD(off++);
1174                 ee->ee_eepMap            = (eeval>>14) & 0x3;
1175                 ee->ee_disableXr5        = (eeval>>13) & 0x1;
1176                 ee->ee_disableXr2        = (eeval>>12) & 0x1;
1177                 ee->ee_earStart          = eeval & 0xfff;
1178
1179                 EEREAD(off++);
1180                 ee->ee_targetPowersStart = eeval & 0xfff;
1181                 ee->ee_exist32kHzCrystal = (eeval>>14) & 0x1;
1182
1183                 if (ee->ee_version >= AR_EEPROM_VER5_0) {
1184                         off += 2;
1185                         EEREAD(off);
1186                         ee->ee_eepMap2PowerCalStart = (eeval >> 4) & 0xfff;
1187                         /* Properly cal'ed 5.0 devices should be non-zero */
1188                 }
1189         }
1190
1191         /* Read the moded sections of the EEPROM header in the order A, B, G */
1192         for (i = headerInfo11A; i <= headerInfo11G; i++) {
1193                 /* Set the offset via the index */
1194                 off = header[2 + i];
1195
1196                 EEREAD(off++);
1197                 ee->ee_switchSettling[i] = (eeval >> 8) & 0x7f;
1198                 ee->ee_txrxAtten[i] = (eeval >> 2) & 0x3f;
1199                 ee->ee_antennaControl[0][i] = (eeval << 4) & 0x3f;
1200
1201                 EEREAD(off++);
1202                 ee->ee_antennaControl[0][i] |= (eeval >> 12) & 0x0f;
1203                 ee->ee_antennaControl[1][i] = (eeval >> 6) & 0x3f;
1204                 ee->ee_antennaControl[2][i] = eeval & 0x3f;
1205
1206                 EEREAD(off++);
1207                 ee->ee_antennaControl[3][i] = (eeval >> 10)  & 0x3f;
1208                 ee->ee_antennaControl[4][i] = (eeval >> 4)  & 0x3f;
1209                 ee->ee_antennaControl[5][i] = (eeval << 2)  & 0x3f;
1210
1211                 EEREAD(off++);
1212                 ee->ee_antennaControl[5][i] |= (eeval >> 14)  & 0x03;
1213                 ee->ee_antennaControl[6][i] = (eeval >> 8)  & 0x3f;
1214                 ee->ee_antennaControl[7][i] = (eeval >> 2)  & 0x3f;
1215                 ee->ee_antennaControl[8][i] = (eeval << 4)  & 0x3f;
1216
1217                 EEREAD(off++);
1218                 ee->ee_antennaControl[8][i] |= (eeval >> 12)  & 0x0f;
1219                 ee->ee_antennaControl[9][i] = (eeval >> 6)  & 0x3f;
1220                 ee->ee_antennaControl[10][i] = eeval & 0x3f;
1221
1222                 EEREAD(off++);
1223                 ee->ee_adcDesiredSize[i] = (int8_t)((eeval >> 8)  & 0xff);
1224                 switch (i) {
1225                 case headerInfo11A:
1226                         ee->ee_ob4 = (eeval >> 5)  & 0x07;
1227                         ee->ee_db4 = (eeval >> 2)  & 0x07;
1228                         ee->ee_ob3 = (eeval << 1)  & 0x07;
1229                         break;
1230                 case headerInfo11B:
1231                         ee->ee_obFor24 = (eeval >> 4)  & 0x07;
1232                         ee->ee_dbFor24 = eeval & 0x07;
1233                         break;
1234                 case headerInfo11G:
1235                         ee->ee_obFor24g = (eeval >> 4)  & 0x07;
1236                         ee->ee_dbFor24g = eeval & 0x07;
1237                         break;
1238                 }
1239
1240                 if (i == headerInfo11A) {
1241                         EEREAD(off++);
1242                         ee->ee_ob3 |= (eeval >> 15)  & 0x01;
1243                         ee->ee_db3 = (eeval >> 12)  & 0x07;
1244                         ee->ee_ob2 = (eeval >> 9)  & 0x07;
1245                         ee->ee_db2 = (eeval >> 6)  & 0x07;
1246                         ee->ee_ob1 = (eeval >> 3)  & 0x07;
1247                         ee->ee_db1 = eeval & 0x07;
1248                 }
1249
1250                 EEREAD(off++);
1251                 ee->ee_txEndToXLNAOn[i] = (eeval >> 8)  & 0xff;
1252                 ee->ee_thresh62[i] = eeval & 0xff;
1253
1254                 EEREAD(off++);
1255                 ee->ee_txEndToXPAOff[i] = (eeval >> 8)  & 0xff;
1256                 ee->ee_txFrameToXPAOn[i] = eeval  & 0xff;
1257
1258                 EEREAD(off++);
1259                 ee->ee_pgaDesiredSize[i] = (int8_t)((eeval >> 8)  & 0xff);
1260                 ee->ee_noiseFloorThresh[i] = eeval  & 0xff;
1261                 if (ee->ee_noiseFloorThresh[i] & 0x80) {
1262                         ee->ee_noiseFloorThresh[i] = 0 -
1263                                 ((ee->ee_noiseFloorThresh[i] ^ 0xff) + 1);
1264                 }
1265
1266                 EEREAD(off++);
1267                 ee->ee_xlnaGain[i] = (eeval >> 5)  & 0xff;
1268                 ee->ee_xgain[i] = (eeval >> 1)  & 0x0f;
1269                 ee->ee_xpd[i] = eeval  & 0x01;
1270                 if (ee->ee_version >= AR_EEPROM_VER4_0) {
1271                         switch (i) {
1272                         case headerInfo11A:
1273                                 ee->ee_fixedBias5 = (eeval >> 13) & 0x1;
1274                                 break;
1275                         case headerInfo11G:
1276                                 ee->ee_fixedBias2 = (eeval >> 13) & 0x1;
1277                                 break;
1278                         }
1279                 }
1280
1281                 if (ee->ee_version >= AR_EEPROM_VER3_3) {
1282                         EEREAD(off++);
1283                         ee->ee_falseDetectBackoff[i] = (eeval >> 6) & 0x7F;
1284                         switch (i) {
1285                         case headerInfo11B:
1286                                 ee->ee_ob2GHz[0] = eeval & 0x7;
1287                                 ee->ee_db2GHz[0] = (eeval >> 3) & 0x7;
1288                                 break;
1289                         case headerInfo11G:
1290                                 ee->ee_ob2GHz[1] = eeval & 0x7;
1291                                 ee->ee_db2GHz[1] = (eeval >> 3) & 0x7;
1292                                 break;
1293                         case headerInfo11A:
1294                                 ee->ee_xrTargetPower5 = eeval & 0x3f;
1295                                 break;
1296                         }
1297                 }
1298                 if (ee->ee_version >= AR_EEPROM_VER3_4) {
1299                         ee->ee_gainI[i] = (eeval >> 13) & 0x07;
1300
1301                         EEREAD(off++);
1302                         ee->ee_gainI[i] |= (eeval << 3) & 0x38;
1303                         if (i == headerInfo11G) {
1304                                 ee->ee_cckOfdmPwrDelta = (eeval >> 3) & 0xFF;
1305                                 if (ee->ee_version >= AR_EEPROM_VER4_6)
1306                                         ee->ee_scaledCh14FilterCckDelta =
1307                                                 (eeval >> 11) & 0x1f;
1308                         }
1309                         if (i == headerInfo11A &&
1310                             ee->ee_version >= AR_EEPROM_VER4_0) {
1311                                 ee->ee_iqCalI[0] = (eeval >> 8 ) & 0x3f;
1312                                 ee->ee_iqCalQ[0] = (eeval >> 3 ) & 0x1f;
1313                         }
1314                 } else {
1315                         ee->ee_gainI[i] = 10;
1316                         ee->ee_cckOfdmPwrDelta = TENX_OFDM_CCK_DELTA_INIT;
1317                 }
1318                 if (ee->ee_version >= AR_EEPROM_VER4_0) {
1319                         switch (i) {
1320                         case headerInfo11B:
1321                                 EEREAD(off++);
1322                                 ee->ee_calPier11b[0] =
1323                                         fbin2freq_2p4(ee, eeval&0xff);
1324                                 ee->ee_calPier11b[1] =
1325                                         fbin2freq_2p4(ee, (eeval >> 8)&0xff);
1326                                 EEREAD(off++);
1327                                 ee->ee_calPier11b[2] =
1328                                         fbin2freq_2p4(ee, eeval&0xff);
1329                                 if (ee->ee_version >= AR_EEPROM_VER4_1)
1330                                         ee->ee_rxtxMargin[headerInfo11B] =
1331                                                 (eeval >> 8) & 0x3f;
1332                                 break;
1333                         case headerInfo11G:
1334                                 EEREAD(off++);
1335                                 ee->ee_calPier11g[0] =
1336                                         fbin2freq_2p4(ee, eeval & 0xff);
1337                                 ee->ee_calPier11g[1] =
1338                                         fbin2freq_2p4(ee, (eeval >> 8) & 0xff);
1339
1340                                 EEREAD(off++);
1341                                 ee->ee_turbo2WMaxPower2 = eeval & 0x7F;
1342                                 ee->ee_xrTargetPower2 = (eeval >> 7) & 0x3f;
1343
1344                                 EEREAD(off++);
1345                                 ee->ee_calPier11g[2] =
1346                                         fbin2freq_2p4(ee, eeval & 0xff);
1347                                 if (ee->ee_version >= AR_EEPROM_VER4_1)
1348                                          ee->ee_rxtxMargin[headerInfo11G] =
1349                                                 (eeval >> 8) & 0x3f;
1350
1351                                 EEREAD(off++);
1352                                 ee->ee_iqCalI[1] = (eeval >> 5) & 0x3F;
1353                                 ee->ee_iqCalQ[1] = eeval & 0x1F;
1354
1355                                 if (ee->ee_version >= AR_EEPROM_VER4_2) {
1356                                         EEREAD(off++);
1357                                         ee->ee_cckOfdmGainDelta =
1358                                                 (uint8_t)(eeval & 0xFF);
1359                                         if (ee->ee_version >= AR_EEPROM_VER5_0) {
1360                                                 ee->ee_switchSettlingTurbo[1] =
1361                                                         (eeval >> 8) & 0x7f;
1362                                                 ee->ee_txrxAttenTurbo[1] =
1363                                                         (eeval >> 15) & 0x1;
1364                                                 EEREAD(off++);
1365                                                 ee->ee_txrxAttenTurbo[1] |=
1366                                                         (eeval & 0x1F) << 1;
1367                                                 ee->ee_rxtxMarginTurbo[1] =
1368                                                         (eeval >> 5) & 0x3F;
1369                                                 ee->ee_adcDesiredSizeTurbo[1] =
1370                                                         (eeval >> 11) & 0x1F;
1371                                                 EEREAD(off++);
1372                                                 ee->ee_adcDesiredSizeTurbo[1] |=
1373                                                         (eeval & 0x7) << 5;
1374                                                 ee->ee_pgaDesiredSizeTurbo[1] =
1375                                                         (eeval >> 3) & 0xFF;
1376                                         }
1377                                 }
1378                                 break;
1379                         case headerInfo11A:
1380                                 if (ee->ee_version >= AR_EEPROM_VER4_1) {
1381                                         EEREAD(off++);
1382                                         ee->ee_rxtxMargin[headerInfo11A] =
1383                                                 eeval & 0x3f;
1384                                         if (ee->ee_version >= AR_EEPROM_VER5_0) {
1385                                                 ee->ee_switchSettlingTurbo[0] =
1386                                                         (eeval >> 6) & 0x7f;
1387                                                 ee->ee_txrxAttenTurbo[0] =
1388                                                         (eeval >> 13) & 0x7;
1389                                                 EEREAD(off++);
1390                                                 ee->ee_txrxAttenTurbo[0] |=
1391                                                         (eeval & 0x7) << 3;
1392                                                 ee->ee_rxtxMarginTurbo[0] =
1393                                                         (eeval >> 3) & 0x3F;
1394                                                 ee->ee_adcDesiredSizeTurbo[0] =
1395                                                         (eeval >> 9) & 0x7F;
1396                                                 EEREAD(off++);
1397                                                 ee->ee_adcDesiredSizeTurbo[0] |=
1398                                                         (eeval & 0x1) << 7;
1399                                                 ee->ee_pgaDesiredSizeTurbo[0] =
1400                                                         (eeval >> 1) & 0xFF;
1401                                         }
1402                                 }
1403                                 break;
1404                         }
1405                 }
1406         }
1407         if (ee->ee_version < AR_EEPROM_VER3_3) {
1408                 /* Version 3.1+ specific parameters */
1409                 EEREAD(0xec);
1410                 ee->ee_ob2GHz[0] = eeval & 0x7;
1411                 ee->ee_db2GHz[0] = (eeval >> 3) & 0x7;
1412
1413                 EEREAD(0xed);
1414                 ee->ee_ob2GHz[1] = eeval & 0x7;
1415                 ee->ee_db2GHz[1] = (eeval >> 3) & 0x7;
1416         }
1417
1418         /* Initialize corner cal (thermal tx gain adjust parameters) */
1419         ee->ee_cornerCal.clip = 4;
1420         ee->ee_cornerCal.pd90 = 1;
1421         ee->ee_cornerCal.pd84 = 1;
1422         ee->ee_cornerCal.gSel = 0;
1423
1424         /*
1425         * Read the conformance test limit identifiers
1426         * These are used to match regulatory domain testing needs with
1427         * the RD-specific tests that have been calibrated in the EEPROM.
1428         */
1429         off = header[5];
1430         for (i = 0; i < ee->ee_numCtls; i += 2) {
1431                 EEREAD(off++);
1432                 ee->ee_ctl[i] = (eeval >> 8) & 0xff;
1433                 ee->ee_ctl[i+1] = eeval & 0xff;
1434         }
1435
1436         if (ee->ee_version < AR_EEPROM_VER5_3) {
1437                 /* XXX only for 5413? */
1438                 ee->ee_spurChans[0][1] = AR_SPUR_5413_1;
1439                 ee->ee_spurChans[1][1] = AR_SPUR_5413_2;
1440                 ee->ee_spurChans[2][1] = AR_NO_SPUR;
1441                 ee->ee_spurChans[0][0] = AR_NO_SPUR;
1442         } else {
1443                 /* Read spur mitigation data */
1444                 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
1445                         EEREAD(off);
1446                         ee->ee_spurChans[i][0] = eeval;
1447                         EEREAD(off+AR_EEPROM_MODAL_SPURS);
1448                         ee->ee_spurChans[i][1] = eeval;
1449                         off++;
1450                 }
1451         }
1452
1453         /* for recent changes to NF scale */
1454         if (ee->ee_version <= AR_EEPROM_VER3_2) {
1455                 ee->ee_noiseFloorThresh[headerInfo11A] = -54;
1456                 ee->ee_noiseFloorThresh[headerInfo11B] = -1;
1457                 ee->ee_noiseFloorThresh[headerInfo11G] = -1;
1458         }
1459         /* to override thresh62 for better 2.4 and 5 operation */
1460         if (ee->ee_version <= AR_EEPROM_VER3_2) {
1461                 ee->ee_thresh62[headerInfo11A] = 15;    /* 11A */
1462                 ee->ee_thresh62[headerInfo11B] = 28;    /* 11B */
1463                 ee->ee_thresh62[headerInfo11G] = 28;    /* 11G */
1464         }
1465
1466         /* Check for regulatory capabilities */
1467         if (ee->ee_version >= AR_EEPROM_VER4_0) {
1468                 EEREAD(regCapOffsetPost4_0);
1469         } else {
1470                 EEREAD(regCapOffsetPre4_0);
1471         }
1472
1473         ee->ee_regCap = eeval;
1474
1475         if (ee->ee_Amode == 0) {
1476                 /* Check for valid Amode in upgraded h/w */
1477                 if (ee->ee_version >= AR_EEPROM_VER4_0) {
1478                         ee->ee_Amode = (ee->ee_regCap & AR_EEPROM_EEREGCAP_EN_KK_NEW_11A)?1:0;
1479                 } else {
1480                         ee->ee_Amode = (ee->ee_regCap & AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0)?1:0;
1481                 }
1482         }
1483
1484         if (ee->ee_version >= AR_EEPROM_VER5_1)
1485                 EEREAD(AR_EEPROM_CAPABILITIES_OFFSET);
1486         else
1487                 eeval = 0;
1488         ee->ee_opCap = eeval;
1489
1490         EEREAD(AR_EEPROM_REG_DOMAIN);
1491         ee->ee_regdomain = eeval;
1492
1493         return AH_TRUE;
1494 #undef EEREAD
1495 }
1496
1497 /*
1498  * Now verify and copy EEPROM contents into the allocated space
1499  */
1500 static HAL_BOOL
1501 legacyEepromReadContents(struct ath_hal *ah, HAL_EEPROM *ee)
1502 {
1503         /* Read the header information here */
1504         if (!readHeaderInfo(ah, ee))
1505                 return AH_FALSE;
1506 #if 0
1507         /* Require 5112 devices to have EEPROM 4.0 EEP_MAP set */
1508         if (IS_5112(ah) && !ee->ee_eepMap) {
1509                 HALDEBUG(ah, HAL_DEBUG_ANY,
1510                     "%s: 5112 devices must have EEPROM 4.0 with the "
1511                     "EEP_MAP set\n", __func__);
1512                 return AH_FALSE;
1513         }
1514 #endif
1515         /*
1516          * Group 1: frequency pier locations readback
1517          * check that the structure has been populated
1518          * with enough space to hold the channels
1519          *
1520          * NOTE: Group 1 contains the 5 GHz channel numbers
1521          *       that have dBm->pcdac calibrated information.
1522          */
1523         if (!readEepromFreqPierInfo(ah, ee))
1524                 return AH_FALSE;
1525
1526         /*
1527          * Group 2:  readback data for all frequency piers
1528          *
1529          * NOTE: Group 2 contains the raw power calibration
1530          *       information for each of the channels that we
1531          *       recorded above.
1532          */
1533         if (!readEepromRawPowerCalInfo(ah, ee))
1534                 return AH_FALSE;
1535
1536         /*
1537          * Group 5: target power values per rate
1538          *
1539          * NOTE: Group 5 contains the recorded maximum power
1540          *       in dB that can be attained for the given rate.
1541          */
1542         /* Read the power per rate info for test channels */
1543         if (!readEepromTargetPowerCalInfo(ah, ee))
1544                 return AH_FALSE;
1545
1546         /*
1547          * Group 8: Conformance Test Limits information
1548          *
1549          * NOTE: Group 8 contains the values to limit the
1550          *       maximum transmit power value based on any
1551          *       band edge violations.
1552          */
1553         /* Read the RD edge power limits */
1554         return readEepromCTLInfo(ah, ee);
1555 }
1556
1557 static HAL_STATUS
1558 legacyEepromGet(struct ath_hal *ah, int param, void *val)
1559 {
1560         HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1561         uint8_t *macaddr;
1562         uint16_t eeval;
1563         uint32_t sum;
1564         int i;
1565
1566         switch (param) {
1567         case AR_EEP_OPCAP:
1568                 *(uint16_t *) val = ee->ee_opCap;
1569                 return HAL_OK;
1570         case AR_EEP_REGDMN_0:
1571                 *(uint16_t *) val = ee->ee_regdomain;
1572                 return HAL_OK;
1573         case AR_EEP_RFSILENT:
1574                 if (!ath_hal_eepromRead(ah, AR_EEPROM_RFSILENT, &eeval))
1575                         return HAL_EEREAD;
1576                 *(uint16_t *) val = eeval;
1577                 return HAL_OK;
1578         case AR_EEP_MACADDR:
1579                 sum = 0;
1580                 macaddr = val;
1581                 for (i = 0; i < 3; i++) {
1582                         if (!ath_hal_eepromRead(ah, AR_EEPROM_MAC(2-i), &eeval)) {
1583                                 HALDEBUG(ah, HAL_DEBUG_ANY,
1584                                     "%s: cannot read EEPROM location %u\n",
1585                                     __func__, i);
1586                                 return HAL_EEREAD;
1587                         }
1588                         sum += eeval;
1589                         macaddr[2*i] = eeval >> 8;
1590                         macaddr[2*i + 1] = eeval & 0xff;
1591                 }
1592                 if (sum == 0 || sum == 0xffff*3) {
1593                         HALDEBUG(ah, HAL_DEBUG_ANY,
1594                             "%s: mac address read failed: %s\n", __func__,
1595                             ath_hal_ether_sprintf(macaddr));
1596                         return HAL_EEBADMAC;
1597                 }
1598                 return HAL_OK;
1599         case AR_EEP_RFKILL:
1600                 HALASSERT(val == AH_NULL);
1601                 return ee->ee_rfKill ? HAL_OK : HAL_EIO;
1602         case AR_EEP_AMODE:
1603                 HALASSERT(val == AH_NULL);
1604                 return ee->ee_Amode ? HAL_OK : HAL_EIO;
1605         case AR_EEP_BMODE:
1606                 HALASSERT(val == AH_NULL);
1607                 return ee->ee_Bmode ? HAL_OK : HAL_EIO;
1608         case AR_EEP_GMODE:
1609                 HALASSERT(val == AH_NULL);
1610                 return ee->ee_Gmode ? HAL_OK : HAL_EIO;
1611         case AR_EEP_TURBO5DISABLE:
1612                 HALASSERT(val == AH_NULL);
1613                 return ee->ee_turbo5Disable ? HAL_OK : HAL_EIO;
1614         case AR_EEP_TURBO2DISABLE:
1615                 HALASSERT(val == AH_NULL);
1616                 return ee->ee_turbo2Disable ? HAL_OK : HAL_EIO;
1617         case AR_EEP_ISTALON:            /* Talon detect */
1618                 HALASSERT(val == AH_NULL);
1619                 return (ee->ee_version >= AR_EEPROM_VER5_4 &&
1620                     ath_hal_eepromRead(ah, 0x0b, &eeval) && eeval == 1) ?
1621                         HAL_OK : HAL_EIO;
1622         case AR_EEP_32KHZCRYSTAL:
1623                 HALASSERT(val == AH_NULL);
1624                 return ee->ee_exist32kHzCrystal ? HAL_OK : HAL_EIO;
1625         case AR_EEP_COMPRESS:
1626                 HALASSERT(val == AH_NULL);
1627                 return (ee->ee_opCap & AR_EEPROM_EEPCAP_COMPRESS_DIS) == 0 ?
1628                     HAL_OK : HAL_EIO;
1629         case AR_EEP_FASTFRAME:
1630                 HALASSERT(val == AH_NULL);
1631                 return (ee->ee_opCap & AR_EEPROM_EEPCAP_FASTFRAME_DIS) == 0 ?
1632                     HAL_OK : HAL_EIO;
1633         case AR_EEP_AES:
1634                 HALASSERT(val == AH_NULL);
1635                 return (ee->ee_opCap & AR_EEPROM_EEPCAP_AES_DIS) == 0 ?
1636                     HAL_OK : HAL_EIO;
1637         case AR_EEP_BURST:
1638                 HALASSERT(val == AH_NULL);
1639                 return (ee->ee_opCap & AR_EEPROM_EEPCAP_BURST_DIS) == 0 ?
1640                     HAL_OK : HAL_EIO;
1641         case AR_EEP_MAXQCU:
1642                 if (ee->ee_opCap & AR_EEPROM_EEPCAP_MAXQCU) {
1643                         *(uint16_t *) val =
1644                             MS(ee->ee_opCap, AR_EEPROM_EEPCAP_MAXQCU);
1645                         return HAL_OK;
1646                 } else
1647                         return HAL_EIO;
1648         case AR_EEP_KCENTRIES:
1649                 if (ee->ee_opCap & AR_EEPROM_EEPCAP_KC_ENTRIES) {
1650                         *(uint16_t *) val =
1651                             1 << MS(ee->ee_opCap, AR_EEPROM_EEPCAP_KC_ENTRIES);
1652                         return HAL_OK;
1653                 } else
1654                         return HAL_EIO;
1655         case AR_EEP_ANTGAINMAX_5:
1656                 *(int8_t *) val = ee->ee_antennaGainMax[0];
1657                 return HAL_OK;
1658         case AR_EEP_ANTGAINMAX_2:
1659                 *(int8_t *) val = ee->ee_antennaGainMax[1];
1660                 return HAL_OK;
1661         case AR_EEP_WRITEPROTECT:
1662                 HALASSERT(val == AH_NULL);
1663                 return (ee->ee_protect & AR_EEPROM_PROTECT_WP_128_191) ?
1664                     HAL_OK : HAL_EIO;
1665         }
1666         return HAL_EINVAL;
1667 }
1668
1669 static HAL_BOOL
1670 legacyEepromSet(struct ath_hal *ah, int param, int v)
1671 {
1672         HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1673
1674         switch (param) {
1675         case AR_EEP_AMODE:
1676                 ee->ee_Amode = v;
1677                 return HAL_OK;
1678         case AR_EEP_BMODE:
1679                 ee->ee_Bmode = v;
1680                 return HAL_OK;
1681         case AR_EEP_GMODE:
1682                 ee->ee_Gmode = v;
1683                 return HAL_OK;
1684         case AR_EEP_TURBO5DISABLE:
1685                 ee->ee_turbo5Disable = v;
1686                 return HAL_OK;
1687         case AR_EEP_TURBO2DISABLE:
1688                 ee->ee_turbo2Disable = v;
1689                 return HAL_OK;
1690         case AR_EEP_COMPRESS:
1691                 if (v)
1692                         ee->ee_opCap &= ~AR_EEPROM_EEPCAP_COMPRESS_DIS;
1693                 else
1694                         ee->ee_opCap |= AR_EEPROM_EEPCAP_COMPRESS_DIS;
1695                 return HAL_OK;
1696         case AR_EEP_FASTFRAME:
1697                 if (v)
1698                         ee->ee_opCap &= ~AR_EEPROM_EEPCAP_FASTFRAME_DIS;
1699                 else
1700                         ee->ee_opCap |= AR_EEPROM_EEPCAP_FASTFRAME_DIS;
1701                 return HAL_OK;
1702         case AR_EEP_AES:
1703                 if (v)
1704                         ee->ee_opCap &= ~AR_EEPROM_EEPCAP_AES_DIS;
1705                 else
1706                         ee->ee_opCap |= AR_EEPROM_EEPCAP_AES_DIS;
1707                 return HAL_OK;
1708         case AR_EEP_BURST:
1709                 if (v)
1710                         ee->ee_opCap &= ~AR_EEPROM_EEPCAP_BURST_DIS;
1711                 else
1712                         ee->ee_opCap |= AR_EEPROM_EEPCAP_BURST_DIS;
1713                 return HAL_OK;
1714         }
1715         return HAL_EINVAL;
1716 }
1717
1718 static HAL_BOOL
1719 legacyEepromDiag(struct ath_hal *ah, int request,
1720      const void *args, uint32_t argsize, void **result, uint32_t *resultsize)
1721 {
1722         HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1723         const EEPROM_POWER_EXPN_5112 *pe;
1724
1725         switch (request) {
1726         case HAL_DIAG_EEPROM:
1727                 *result = ee;
1728                 *resultsize = sizeof(*ee);
1729                 return AH_TRUE;
1730         case HAL_DIAG_EEPROM_EXP_11A:
1731         case HAL_DIAG_EEPROM_EXP_11B:
1732         case HAL_DIAG_EEPROM_EXP_11G:
1733                 pe = &ee->ee_modePowerArray5112[
1734                     request - HAL_DIAG_EEPROM_EXP_11A];
1735                 *result = pe->pChannels;
1736                 *resultsize = (*result == AH_NULL) ? 0 :
1737                         roundup(sizeof(uint16_t) * pe->numChannels,
1738                                 sizeof(uint32_t)) +
1739                         sizeof(EXPN_DATA_PER_CHANNEL_5112) * pe->numChannels;
1740                 return AH_TRUE;
1741         }
1742         return AH_FALSE;
1743 }
1744
1745 static uint16_t
1746 legacyEepromGetSpurChan(struct ath_hal *ah, int ix, HAL_BOOL is2GHz)
1747 {
1748         HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1749
1750         HALASSERT(0 <= ix && ix < AR_EEPROM_MODAL_SPURS);
1751         return ee->ee_spurChans[ix][is2GHz];
1752 }
1753
1754 /*
1755  * Reclaim any EEPROM-related storage.
1756  */
1757 static void
1758 legacyEepromDetach(struct ath_hal *ah)
1759 {
1760         HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1761
1762         if (ee->ee_version >= AR_EEPROM_VER4_0 && ee->ee_eepMap == 1)
1763                 freeEepromRawPowerCalInfo5112(ah, ee);
1764         ath_hal_free(ee);
1765         AH_PRIVATE(ah)->ah_eeprom = AH_NULL;
1766 }
1767
1768 /*
1769  * These are not valid 2.4 channels, either we change 'em
1770  * or we need to change the coding to accept them.
1771  */
1772 static const uint16_t channels11b[] = { 2412, 2447, 2484 };
1773 static const uint16_t channels11g[] = { 2312, 2412, 2484 };
1774
1775 HAL_STATUS
1776 ath_hal_legacyEepromAttach(struct ath_hal *ah)
1777 {
1778         HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1779         uint32_t sum, eepMax;
1780         uint16_t eeversion, eeprotect, eeval;
1781         u_int i;
1782
1783         HALASSERT(ee == AH_NULL);
1784
1785         if (!ath_hal_eepromRead(ah, AR_EEPROM_VERSION, &eeversion)) {
1786                 HALDEBUG(ah, HAL_DEBUG_ANY,
1787                     "%s: unable to read EEPROM version\n", __func__);
1788                 return HAL_EEREAD;
1789         }
1790         if (eeversion < AR_EEPROM_VER3) {
1791                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unsupported EEPROM version "
1792                     "%u (0x%x) found\n", __func__, eeversion, eeversion);
1793                 return HAL_EEVERSION;
1794         }
1795
1796         if (!ath_hal_eepromRead(ah, AR_EEPROM_PROTECT, &eeprotect)) {
1797                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: cannot read EEPROM protection "
1798                     "bits; read locked?\n", __func__);
1799                 return HAL_EEREAD;
1800         }
1801         HALDEBUG(ah, HAL_DEBUG_ATTACH, "EEPROM protect 0x%x\n", eeprotect);
1802         /* XXX check proper access before continuing */
1803
1804         /*
1805          * Read the Atheros EEPROM entries and calculate the checksum.
1806          */
1807         if (!ath_hal_eepromRead(ah, AR_EEPROM_SIZE_UPPER, &eeval)) {
1808                 HALDEBUG(ah, HAL_DEBUG_ANY,
1809                     "%s: cannot read EEPROM upper size\n" , __func__);
1810                 return HAL_EEREAD;
1811         }
1812         if (eeval != 0) {
1813                 eepMax = (eeval & AR_EEPROM_SIZE_UPPER_MASK) <<
1814                         AR_EEPROM_SIZE_ENDLOC_SHIFT;
1815                 if (!ath_hal_eepromRead(ah, AR_EEPROM_SIZE_LOWER, &eeval)) {
1816                         HALDEBUG(ah, HAL_DEBUG_ANY,
1817                             "%s: cannot read EEPROM lower size\n" , __func__);
1818                         return HAL_EEREAD;
1819                 }
1820                 eepMax = (eepMax | eeval) - AR_EEPROM_ATHEROS_BASE;
1821         } else
1822                 eepMax = AR_EEPROM_ATHEROS_MAX;
1823         sum = 0;
1824         for (i = 0; i < eepMax; i++) {
1825                 if (!ath_hal_eepromRead(ah, AR_EEPROM_ATHEROS(i), &eeval)) {
1826                         return HAL_EEREAD;
1827                 }
1828                 sum ^= eeval;
1829         }
1830         if (sum != 0xffff) {
1831                 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad EEPROM checksum 0x%x\n",
1832                     __func__, sum);
1833                 return HAL_EEBADSUM;
1834         }
1835
1836         ee = ath_hal_malloc(sizeof(HAL_EEPROM));
1837         if (ee == AH_NULL) {
1838                 /* XXX message */
1839                 return HAL_ENOMEM;
1840         }
1841
1842         ee->ee_protect = eeprotect;
1843         ee->ee_version = eeversion;
1844
1845         ee->ee_numChannels11a = NUM_11A_EEPROM_CHANNELS;
1846         ee->ee_numChannels2_4 = NUM_2_4_EEPROM_CHANNELS;
1847
1848         for (i = 0; i < NUM_11A_EEPROM_CHANNELS; i ++)
1849                 ee->ee_dataPerChannel11a[i].numPcdacValues = NUM_PCDAC_VALUES;
1850
1851         /* the channel list for 2.4 is fixed, fill this in here */
1852         for (i = 0; i < NUM_2_4_EEPROM_CHANNELS; i++) {
1853                 ee->ee_channels11b[i] = channels11b[i];
1854                 /* XXX 5211 requires a hack though we don't support 11g */
1855                 if (ah->ah_magic == 0x19570405)
1856                         ee->ee_channels11g[i] = channels11b[i];
1857                 else
1858                         ee->ee_channels11g[i] = channels11g[i];
1859                 ee->ee_dataPerChannel11b[i].numPcdacValues = NUM_PCDAC_VALUES;
1860                 ee->ee_dataPerChannel11g[i].numPcdacValues = NUM_PCDAC_VALUES;
1861         }
1862
1863         if (!legacyEepromReadContents(ah, ee)) {
1864                 /* XXX message */
1865                 ath_hal_free(ee);
1866                 return HAL_EEREAD;      /* XXX */
1867         }
1868
1869         AH_PRIVATE(ah)->ah_eeprom = ee;
1870         AH_PRIVATE(ah)->ah_eeversion = eeversion;
1871         AH_PRIVATE(ah)->ah_eepromDetach = legacyEepromDetach;
1872         AH_PRIVATE(ah)->ah_eepromGet = legacyEepromGet;
1873         AH_PRIVATE(ah)->ah_eepromSet = legacyEepromSet;
1874         AH_PRIVATE(ah)->ah_getSpurChan = legacyEepromGetSpurChan;
1875         AH_PRIVATE(ah)->ah_eepromDiag = legacyEepromDiag;
1876         return HAL_OK;
1877 }