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  * $Id: ah_eeprom_v3.c,v 1.5 2021/04/13 03:27:13 mrg Exp $
18  */
19 #include "opt_ah.h"
20 
21 #include "ah.h"
22 #include "ah_internal.h"
23 #include "ah_eeprom_v3.h"
24 
25 static void
getPcdacInterceptsFromPcdacMinMax(HAL_EEPROM * ee,uint16_t pcdacMin,uint16_t pcdacMax,uint16_t * vp)26 getPcdacInterceptsFromPcdacMinMax(HAL_EEPROM *ee,
27           uint16_t pcdacMin, uint16_t pcdacMax, uint16_t *vp)
28 {
29           static const uint16_t intercepts3[] =
30                     { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
31           static const 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;
35           int i;
36 
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;
40 }
41 
42 /*
43  * Get channel value from binary representation held in eeprom
44  */
45 static uint16_t
fbin2freq(HAL_EEPROM * ee,uint16_t fbin)46 fbin2freq(HAL_EEPROM *ee, uint16_t fbin)
47 {
48           if (fbin == CHANNEL_UNUSED)   /* reserved value, don't convert */
49                     return fbin;
50           return ee->ee_version <= AR_EEPROM_VER3_2 ?
51                     (fbin > 62 ? 5100 + 10*62 + 5*(fbin-62) : 5100 + 10*fbin) :
52                     4800 + 5*fbin;
53 }
54 
55 static uint16_t
fbin2freq_2p4(HAL_EEPROM * ee,uint16_t fbin)56 fbin2freq_2p4(HAL_EEPROM *ee, uint16_t fbin)
57 {
58           if (fbin == CHANNEL_UNUSED)   /* reserved value, don't convert */
59                     return fbin;
60           return ee->ee_version <= AR_EEPROM_VER3_2 ?
61                     2400 + fbin :
62                     2300 + fbin;
63 }
64 
65 /*
66  * Now copy EEPROM frequency pier contents into the allocated space
67  */
68 static HAL_BOOL
readEepromFreqPierInfo(struct ath_hal * ah,HAL_EEPROM * ee)69 readEepromFreqPierInfo(struct ath_hal *ah, HAL_EEPROM *ee)
70 {
71 #define   EEREAD(_off) do {                                 \
72           if (!ath_hal_eepromRead(ah, _off, &eeval))        \
73                     return AH_FALSE;                        \
74 } while (0)
75           uint16_t eeval, off;
76           int i;
77 
78           if (ee->ee_version >= AR_EEPROM_VER4_0 &&
79               ee->ee_eepMap && !ee->ee_Amode) {
80                     /*
81                      * V4.0 EEPROMs with map type 1 have frequency pier
82                      * data only when 11a mode is supported.
83                      */
84                     return AH_TRUE;
85           }
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) {
89                               EEREAD(off++);
90                               ee->ee_channels11a[i]   = (eeval >> 8) & FREQ_MASK_3_3;
91                               ee->ee_channels11a[i+1] = eeval & FREQ_MASK_3_3;
92                     }
93           } else {
94                     off = GROUPS_OFFSET3_2 + GROUP1_OFFSET;
95 
96                     EEREAD(off++);
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;
100 
101                     EEREAD(off++);
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;
105 
106                     EEREAD(off++);
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;
110 
111                     EEREAD(off++);
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;
116 
117                     EEREAD(off++);
118                     ee->ee_channels11a[9] |= (eeval >> 10) & 0x3f;
119           }
120 
121           for (i = 0; i < ee->ee_numChannels11a; i++)
122                     ee->ee_channels11a[i] = fbin2freq(ee, ee->ee_channels11a[i]);
123 
124           return AH_TRUE;
125 #undef EEREAD
126 }
127 
128 /*
129  * Rev 4 Eeprom 5112 Power Extract Functions
130  */
131 
132 /*
133  * Allocate the power information based on the number of channels
134  * recorded by the calibration.  These values are then initialized.
135  */
136 static HAL_BOOL
eepromAllocExpnPower5112(struct ath_hal * ah,const EEPROM_POWER_5112 * pCalDataset,EEPROM_POWER_EXPN_5112 * pPowerExpn)137 eepromAllocExpnPower5112(struct ath_hal *ah,
138           const EEPROM_POWER_5112 *pCalDataset,
139           EEPROM_POWER_EXPN_5112 *pPowerExpn)
140 {
141           uint16_t numChannels = pCalDataset->numChannels;
142           const uint16_t *pChanList = pCalDataset->pChannels;
143           void *data;
144           int i, j;
145 
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__);
153                     return AH_FALSE;
154           }
155           pPowerExpn->pChannels = data;
156           pPowerExpn->pDataPerChannel = (void *)(((char *)data) +
157                     roundup(sizeof(uint16_t) * numChannels, sizeof(uint32_t)));
158 
159           pPowerExpn->numChannels = numChannels;
160           for (i = 0; i < numChannels; i++) {
161                     pPowerExpn->pChannels[i] =
162                               pPowerExpn->pDataPerChannel[i].channelValue =
163                                         pChanList[i];
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;
167                     }
168                     pPowerExpn->pDataPerChannel[i].pDataPerXPD[0].numPcdacs = 4;
169                     pPowerExpn->pDataPerChannel[i].pDataPerXPD[3].numPcdacs = 3;
170           }
171           return AH_TRUE;
172 }
173 
174 /*
175  * Expand the dataSet from the calibration information into the
176  * final power structure for 5112
177  */
178 static HAL_BOOL
eepromExpandPower5112(struct ath_hal * ah,const EEPROM_POWER_5112 * pCalDataset,EEPROM_POWER_EXPN_5112 * pPowerExpn)179 eepromExpandPower5112(struct ath_hal *ah,
180           const EEPROM_POWER_5112 *pCalDataset,
181           EEPROM_POWER_EXPN_5112 *pPowerExpn)
182 {
183           int ii, jj, kk;
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;
188 
189           pPowerExpn->xpdMask = pCalDataset->xpdMask;
190 
191           xgainList[0] = 0xDEAD;
192           xgainList[1] = 0xDEAD;
193 
194           kk = 0;
195           xpdMask = pPowerExpn->xpdMask;
196           for (jj = 0; jj < NUM_XPD_PER_CHANNEL; jj++) {
197                     if (((xpdMask >> jj) & 1) > 0) {
198                               if (kk > 1) {
199                                         HALDEBUG(ah, HAL_DEBUG_ANY,
200                                             "%s: too many xpdGains in dataset: %u\n",
201                                             __func__, kk);
202                                         return AH_FALSE;
203                               }
204                               xgainList[kk++] = jj;
205                     }
206           }
207 
208           pPowerExpn->numChannels = pCalDataset->numChannels;
209           if (pPowerExpn->numChannels == 0) {
210                     HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no channels\n", __func__);
211                     return AH_FALSE;
212           }
213 
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 =
219                               pCalCh->maxPower_t4;
220 
221                     for (jj = 0; jj < NUM_XPD_PER_CHANNEL; jj++)
222                               pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj].numPcdacs = 0;
223                     if (xgainList[1] == 0xDEAD) {
224                               jj = xgainList[0];
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);
234 
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;
239 
240                     } else {
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;
245 
246                               jj = xgainList[0];
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;
259 
260                               jj = xgainList[1];
261                               pExpnXPD = &pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj];
262                               pExpnXPD->numPcdacs = 3;
263 
264                               pExpnXPD->pwr_t4[0] = pCalCh->pwr1_xg3;
265                               pExpnXPD->pwr_t4[1] = pCalCh->pwr2_xg3;
266                               pExpnXPD->pwr_t4[2] = pCalCh->pwr3_xg3;
267                     }
268           }
269           return AH_TRUE;
270 }
271 
272 static HAL_BOOL
readEepromRawPowerCalInfo5112(struct ath_hal * ah,HAL_EEPROM * ee)273 readEepromRawPowerCalInfo5112(struct ath_hal *ah, HAL_EEPROM *ee)
274 {
275 #define   EEREAD(_off) do {                                 \
276           if (!ath_hal_eepromRead(ah, _off, &eeval))        \
277                     return AH_FALSE;                        \
278 } while (0)
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;
283 
284           int i, mode, numPiers;
285           uint32_t off;
286           uint16_t eeval;
287           uint16_t freq[NUM_11A_EEPROM_CHANNELS];
288         EEPROM_POWER_5112 eePower;
289 
290           HALASSERT(ee->ee_version >= AR_EEPROM_VER4_0);
291           off = GROUPS_OFFSET3_3;
292           for (mode = headerInfo11A; mode <= headerInfo11G; mode++) {
293                     numPiers = 0;
294                     switch (mode) {
295                     case headerInfo11A:
296                               if (!ee->ee_Amode)  /* no 11a calibration data */
297                                         continue;
298                               while (numPiers < NUM_11A_EEPROM_CHANNELS) {
299                                         EEREAD(off++);
300                                         if ((eeval & freqmask) == 0)
301                                                   break;
302                                         freq[numPiers++] = fbin2freq(ee,
303                                                   eeval & freqmask);
304 
305                                         if (((eeval >> 8) & freqmask) == 0)
306                                                   break;
307                                         freq[numPiers++] = fbin2freq(ee,
308                                                   (eeval>>8) & freqmask);
309                               }
310                               break;
311                     case headerInfo11B:
312                               if (!ee->ee_Bmode)  /* no 11b calibration data */
313                                         continue;
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];
317                               break;
318                     case headerInfo11G:
319                               if (!ee->ee_Gmode)  /* no 11g calibration data */
320                                         continue;
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];
324                               break;
325                     default:
326                               HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n",
327                                   __func__, mode);
328                               return AH_FALSE;
329                     }
330 
331                     OS_MEMZERO(&eePower, sizeof(eePower));
332                     eePower.numChannels = numPiers;
333 
334                     for (i = 0; i < numPiers; i++) {
335                               eePower.pChannels[i] = freq[i];
336                               eePower.pDataPerChannel[i].channelValue = freq[i];
337 
338                               EEREAD(off++);
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);
343 
344                               EEREAD(off++);
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);
349 
350                               EEREAD(off++);
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);
357 
358                               EEREAD(off++);
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);
363 
364                               EEREAD(off++);
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);
372                               } else {
373                                         eePower.pDataPerChannel[i].maxPower_t4 = (int16_t)
374                                                   (((eeval >> 8) & dbmmask) -
375                                                    ((eeval >> 15) & 0x1)*256);
376                                         eePower.pDataPerChannel[i].pcd1_xg0 = 1;
377                               }
378                     }
379                     eePower.xpdMask = ee->ee_xgain[mode];
380 
381                     if (!eepromAllocExpnPower5112(ah, &eePower, &ee->ee_modePowerArray5112[mode])) {
382                               HALDEBUG(ah, HAL_DEBUG_ANY,
383                                   "%s: did not allocate power struct\n", __func__);
384                               return AH_FALSE;
385                 }
386                 if (!eepromExpandPower5112(ah, &eePower, &ee->ee_modePowerArray5112[mode])) {
387                               HALDEBUG(ah, HAL_DEBUG_ANY,
388                                   "%s: did not expand power struct\n", __func__);
389                               return AH_FALSE;
390                     }
391           }
392           return AH_TRUE;
393 #undef EEREAD
394 }
395 
396 static void
freeEepromRawPowerCalInfo5112(struct ath_hal * ah,HAL_EEPROM * ee)397 freeEepromRawPowerCalInfo5112(struct ath_hal *ah, HAL_EEPROM *ee)
398 {
399           int mode;
400           void *data;
401 
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;
408                               ath_hal_free(data);
409                     }
410           }
411 }
412 
413 static void
ar2413SetupEEPROMDataset(EEPROM_DATA_STRUCT_2413 * pEEPROMDataset2413,uint16_t myNumRawChannels,uint16_t * pMyRawChanList)414 ar2413SetupEEPROMDataset(EEPROM_DATA_STRUCT_2413 *pEEPROMDataset2413,
415           uint16_t myNumRawChannels, uint16_t *pMyRawChanList)
416 {
417           uint16_t i, channelValue;
418           uint32_t xpd_mask;
419           uint16_t numPdGainsUsed;
420 
421           pEEPROMDataset2413->numChannels = myNumRawChannels;
422 
423           xpd_mask = pEEPROMDataset2413->xpd_mask;
424           numPdGainsUsed = 0;
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++;
429 
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;
435           }
436 }
437 
438 static HAL_BOOL
ar2413ReadCalDataset(struct ath_hal * ah,HAL_EEPROM * ee,EEPROM_DATA_STRUCT_2413 * pCalDataset,uint32_t start_offset,uint32_t maxPiers,uint8_t mode)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)
442 {
443 #define   EEREAD(_off) do {                                 \
444           if (!ath_hal_eepromRead(ah, _off, &eeval))        \
445                     return AH_FALSE;                        \
446 } while (0)
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;
452 
453           uint16_t ii, eeval;
454           uint16_t idx, numPiers;
455           uint16_t freq[NUM_11A_EEPROM_CHANNELS];
456 
457           idx = start_offset;
458     for (numPiers = 0; numPiers < maxPiers;) {
459         EEREAD(idx++);
460         if ((eeval & freqmask) == 0)
461             break;
462         if (mode == headerInfo11A)
463             freq[numPiers++] = fbin2freq(ee, (eeval & freqmask));
464         else
465             freq[numPiers++] = fbin2freq_2p4(ee, (eeval & freqmask));
466 
467         if (((eeval >> 8) & freqmask) == 0)
468             break;
469         if (mode == headerInfo11A)
470             freq[numPiers++] = fbin2freq(ee, (eeval >> 8) & freqmask);
471         else
472             freq[numPiers++] = fbin2freq_2p4(ee, (eeval >> 8) & freqmask);
473     }
474           ar2413SetupEEPROMDataset(pCalDataset, numPiers, &freq[0]);
475 
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]);
480 
481                     if (currCh->numPdGains > 0) {
482                               /*
483                                * Read the first NUM_POINTS_OTHER_PDGAINS pwr
484                                * and Vpd values for pdgain_0
485                                */
486                               EEREAD(idx++);
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;
491 
492                               EEREAD(idx++);
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;
498 
499                               EEREAD(idx++);
500                               currCh->pwr_delta_t2[2][0] = eeval & dbm_delta_mask;
501                               currCh->Vpd_delta[2][0] = (eeval >> 4) & Vpd_delta_mask;
502                     }
503 
504                     if (currCh->numPdGains > 1) {
505                               /*
506                                * Read the first NUM_POINTS_OTHER_PDGAINS pwr
507                                * and Vpd values for pdgain_1
508                                */
509                               currCh->pwr_I[1] = (eeval >> 10) & dbm_I_mask;
510                               currCh->Vpd_I[1] = (eeval >> 15) & 0x1;
511 
512                               EEREAD(idx++);
513                               /* upper 6 bits */
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;
519 
520                               EEREAD(idx++);
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;
526 
527                               EEREAD(idx++);
528                               /* upper 4 bits */
529                               currCh->Vpd_delta[2][1] |= (eeval & 0xF) << 2;
530                     } else if (currCh->numPdGains == 1) {
531                               /*
532                                * Read the last pwr and Vpd values for pdgain_0
533                                */
534                               currCh->pwr_delta_t2[3][0] =
535                                         (eeval >> 10) & dbm_delta_mask;
536                               currCh->Vpd_delta[3][0] = (eeval >> 14) & 0x3;
537 
538                               EEREAD(idx++);
539                               /* upper 4 bits */
540                               currCh->Vpd_delta[3][0] |= (eeval & 0xF) << 2;
541 
542                               /* 4 words if numPdGains == 1 */
543                     }
544 
545                     if (currCh->numPdGains > 2) {
546                               /*
547                                * Read the first NUM_POINTS_OTHER_PDGAINS pwr
548                                * and Vpd values for pdgain_2
549                                */
550                               currCh->pwr_I[2] = (eeval >> 4) & dbm_I_mask;
551                               currCh->Vpd_I[2] = (eeval >> 9) & Vpd_I_mask;
552 
553                               EEREAD(idx++);
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;
560 
561                               EEREAD(idx++);
562                               /* upper 4 bits */
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) {
568                               /*
569                                * Read the last pwr and Vpd values for pdgain_1
570                                */
571                               currCh->pwr_delta_t2[3][1] =
572                                         (eeval >> 4) & dbm_delta_mask;
573                               currCh->Vpd_delta[3][1] = (eeval >> 8) & Vpd_delta_mask;
574 
575                               /* 6 words if numPdGains == 2 */
576                     }
577 
578                     if (currCh->numPdGains > 3) {
579                               /*
580                                * Read the first NUM_POINTS_OTHER_PDGAINS pwr
581                                * and Vpd values for pdgain_3
582                                */
583                               currCh->pwr_I[3] = (eeval >> 14) & 0x3;
584 
585                               EEREAD(idx++);
586                               /* upper 3 bits */
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;
592 
593                               EEREAD(idx++);
594                               /* upper 4 bits */
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;
600 
601                               EEREAD(idx++);
602                               /* upper 2 bits */
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;
608 
609                               EEREAD(idx++);
610                               /* upper 2 bits */
611                               currCh->Vpd_delta[3][3] |= ((eeval >> 0) & 0x3) << 4;
612 
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;
617 
618                               EEREAD(idx++);
619                               /* upper 2 bits */
620                               currCh->pwr_delta_t2[3][2] |= ((eeval >> 0) & 0x3) << 2;
621                               currCh->Vpd_delta[3][2] = (eeval >> 2) & Vpd_delta_mask;
622 
623                               /* 9 words if numPdGains == 3 */
624                     }
625           }
626           return AH_TRUE;
627 #undef EEREAD
628 }
629 
630 static void
ar2413SetupRawDataset(RAW_DATA_STRUCT_2413 * pRaw,EEPROM_DATA_STRUCT_2413 * pCal)631 ar2413SetupRawDataset(RAW_DATA_STRUCT_2413 *pRaw, EEPROM_DATA_STRUCT_2413 *pCal)
632 {
633           uint16_t i, j, kk, channelValue;
634           uint16_t xpd_mask;
635           uint16_t numPdGainsUsed;
636 
637           pRaw->numChannels = pCal->numChannels;
638 
639           xpd_mask = pRaw->xpd_mask;
640           numPdGainsUsed = 0;
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++;
645 
646           for (i = 0; i < pCal->numChannels; i++) {
647                     channelValue = pCal->pChannels[i];
648 
649                     pRaw->pChannels[i] = channelValue;
650 
651                     pRaw->pDataPerChannel[i].channelValue = channelValue;
652                     pRaw->pDataPerChannel[i].numPdGains = numPdGainsUsed;
653 
654                     kk = 0;
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;
659                                         kk++;
660                                         if (kk == 1) {
661                                                   /*
662                                                    * lowest pd_gain corresponds
663                                                    *  to highest power and thus,
664                                                    *  has one more point
665                                                    */
666                                                   pRaw->pDataPerChannel[i].pDataPerPDGain[j].numVpd = NUM_POINTS_LAST_PDGAIN;
667                                         }
668                               } else {
669                                         pRaw->pDataPerChannel[i].pDataPerPDGain[j].numVpd = 0;
670                               }
671                     }
672           }
673 }
674 
675 static HAL_BOOL
ar2413EepromToRawDataset(struct ath_hal * ah,EEPROM_DATA_STRUCT_2413 * pCal,RAW_DATA_STRUCT_2413 * pRaw)676 ar2413EepromToRawDataset(struct ath_hal *ah,
677           EEPROM_DATA_STRUCT_2413 *pCal, RAW_DATA_STRUCT_2413 *pRaw)
678 {
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];
684           uint16_t xpd_mask;
685           uint32_t numPdGainsUsed;
686 
687           HALASSERT(pRaw->xpd_mask == pCal->xpd_mask);
688 
689           xgain_list[0] = 0xDEAD;
690           xgain_list[1] = 0xDEAD;
691           xgain_list[2] = 0xDEAD;
692           xgain_list[3] = 0xDEAD;
693 
694           numPdGainsUsed = 0;
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;
699           }
700 
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;
705 
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 */
709                               ss = xgain_list[jj];
710                               pRawXPD = &(pRaw->pDataPerChannel[ii].pDataPerPDGain[ss]);
711                               HALASSERT(pRawXPD->numVpd >= 1);
712 
713                               pRawXPD->pwr_t4[0] = (uint16_t)(4*pCalCh->pwr_I[jj]);
714                               pRawXPD->Vpd[0]    = pCalCh->Vpd_I[jj];
715 
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]);
719                               }
720                               /* loop over Vpds */
721                     }
722                     /* loop over pd_gains */
723           }
724           /* loop over channels */
725           return AH_TRUE;
726 }
727 
728 static HAL_BOOL
readEepromRawPowerCalInfo2413(struct ath_hal * ah,HAL_EEPROM * ee)729 readEepromRawPowerCalInfo2413(struct ath_hal *ah, HAL_EEPROM *ee)
730 {
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;
736           uint32_t off;
737           HAL_BOOL ret = AH_FALSE;
738 
739           HALASSERT(ee->ee_version >= AR_EEPROM_VER5_0);
740           HALASSERT(ee->ee_eepMap == 2);
741 
742           pCal = ath_hal_malloc(sizeof(EEPROM_DATA_STRUCT_2413));
743           if (pCal == AH_NULL)
744                     goto exit;
745 
746           off = ee->ee_eepMap2PowerCalStart;
747           if (ee->ee_Amode) {
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)) {
752                               goto exit;
753                     }
754                     pRaw = &ee->ee_rawDataset2413[headerInfo11A];
755                     pRaw->xpd_mask = ee->ee_xgain[headerInfo11A];
756                     ar2413SetupRawDataset(pRaw, pCal);
757                     if (!ar2413EepromToRawDataset(ah, pCal, pRaw)) {
758                               goto exit;
759                     }
760                     /* setup offsets for mode_11a next */
761                     numEEPROMWordsPerChannel = wordsForPdgains[
762                               pCal->pDataPerChannel[0].numPdGains - 1];
763                     off += pCal->numChannels * numEEPROMWordsPerChannel + 5;
764           }
765           if (ee->ee_Bmode) {
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)) {
770                               goto exit;
771                     }
772                     pRaw = &ee->ee_rawDataset2413[headerInfo11B];
773                     pRaw->xpd_mask = ee->ee_xgain[headerInfo11B];
774                     ar2413SetupRawDataset(pRaw, pCal);
775                     if (!ar2413EepromToRawDataset(ah, pCal, pRaw)) {
776                               goto exit;
777                     }
778                     /* setup offsets for mode_11g next */
779                     numEEPROMWordsPerChannel = wordsForPdgains[
780                               pCal->pDataPerChannel[0].numPdGains - 1];
781                     off += pCal->numChannels * numEEPROMWordsPerChannel + 2;
782           }
783           if (ee->ee_Gmode) {
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)) {
788                               goto exit;
789                     }
790                     pRaw = &ee->ee_rawDataset2413[headerInfo11G];
791                     pRaw->xpd_mask = ee->ee_xgain[headerInfo11G];
792                     ar2413SetupRawDataset(pRaw, pCal);
793                     if (!ar2413EepromToRawDataset(ah, pCal, pRaw)) {
794                               goto exit;
795                     }
796           }
797           ret = AH_TRUE;
798  exit:
799           if (pCal != AH_NULL)
800                     ath_hal_free(pCal);
801           return ret;
802 }
803 
804 /*
805  * Now copy EEPROM Raw Power Calibration per frequency contents
806  * into the allocated space
807  */
808 static HAL_BOOL
readEepromRawPowerCalInfo(struct ath_hal * ah,HAL_EEPROM * ee)809 readEepromRawPowerCalInfo(struct ath_hal *ah, HAL_EEPROM *ee)
810 {
811 #define   EEREAD(_off) do {                                 \
812           if (!ath_hal_eepromRead(ah, _off, &eeval))        \
813                     return AH_FALSE;                        \
814 } while (0)
815           uint16_t eeval, nchan;
816           uint32_t off;
817           int i, j, mode;
818 
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);
823 
824           /*
825            * Group 2:  read raw power data for all frequency piers
826            *
827            * NOTE: Group 2 contains the raw power calibration
828            *         information for each of the channels that
829            *         we recorded above.
830            */
831           for (mode = headerInfo11A; mode <= headerInfo11G; mode++) {
832                     uint16_t *pChannels = AH_NULL;
833                     DATA_PER_CHANNEL *pChannelData = AH_NULL;
834 
835                     off = ee->ee_version >= AR_EEPROM_VER3_3 ?
836                               GROUPS_OFFSET3_3 : GROUPS_OFFSET3_2;
837                     switch (mode) {
838                     case headerInfo11A:
839                               off       += GROUP2_OFFSET;
840                               nchan               = ee->ee_numChannels11a;
841                               pChannelData        = ee->ee_dataPerChannel11a;
842                               pChannels = ee->ee_channels11a;
843                               break;
844                     case headerInfo11B:
845                               if (!ee->ee_Bmode)
846                                         continue;
847                               off                 += GROUP3_OFFSET;
848                               nchan               = ee->ee_numChannels2_4;
849                               pChannelData        = ee->ee_dataPerChannel11b;
850                               pChannels = ee->ee_channels11b;
851                               break;
852                     case headerInfo11G:
853                               if (!ee->ee_Gmode)
854                                         continue;
855                               off                 += GROUP4_OFFSET;
856                               nchan               = ee->ee_numChannels2_4;
857                               pChannelData        = ee->ee_dataPerChannel11g;
858                               pChannels = ee->ee_channels11g;
859                               break;
860                     default:
861                               HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n",
862                                   __func__, mode);
863                               return AH_FALSE;
864                     }
865                     for (i = 0; i < nchan; i++) {
866                               pChannelData->channelValue = pChannels[i];
867 
868                               EEREAD(off++);
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);
872 
873                               EEREAD(off++);
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);
878 
879                               EEREAD(off++);
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);
883 
884                               EEREAD(off++);
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);
888 
889                               EEREAD(off++);
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);
893 
894                               getPcdacInterceptsFromPcdacMinMax(ee,
895                                         pChannelData->pcdacMin, pChannelData->pcdacMax,
896                                         pChannelData->PcdacValues) ;
897 
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. */
902                               }
903                               pChannelData++;
904                     }
905           }
906           return AH_TRUE;
907 #undef EEREAD
908 }
909 
910 /*
911  * Copy EEPROM Target Power Calbration per rate contents
912  * into the allocated space
913  */
914 static HAL_BOOL
readEepromTargetPowerCalInfo(struct ath_hal * ah,HAL_EEPROM * ee)915 readEepromTargetPowerCalInfo(struct ath_hal *ah, HAL_EEPROM *ee)
916 {
917 #define   EEREAD(_off) do {                                 \
918           if (!ath_hal_eepromRead(ah, _off, &eeval))        \
919                     return AH_FALSE;                        \
920 } while (0)
921           uint16_t eeval, enable24;
922           uint32_t off;
923           int i, mode, nchan;
924 
925           enable24 = ee->ee_Bmode || ee->ee_Gmode;
926           for (mode = headerInfo11A; mode <= headerInfo11G; mode++) {
927                     TRGT_POWER_INFO *pPowerInfo;
928                     uint16_t *pNumTrgtChannels;
929 
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;
934                     switch (mode) {
935                     case headerInfo11A:
936                               off += GROUP5_OFFSET;
937                               nchan = NUM_TEST_FREQUENCIES;
938                               pPowerInfo = ee->ee_trgtPwr_11a;
939                               pNumTrgtChannels = &ee->ee_numTargetPwr_11a;
940                               break;
941                     case headerInfo11B:
942                               if (!enable24)
943                                         continue;
944                               off += GROUP6_OFFSET;
945                               nchan = 2;
946                               pPowerInfo = ee->ee_trgtPwr_11b;
947                               pNumTrgtChannels = &ee->ee_numTargetPwr_11b;
948                               break;
949                     case headerInfo11G:
950                               if (!enable24)
951                                         continue;
952                               off += GROUP7_OFFSET;
953                               nchan = 3;
954                               pPowerInfo = ee->ee_trgtPwr_11g;
955                               pNumTrgtChannels = &ee->ee_numTargetPwr_11g;
956                               break;
957                     default:
958                               HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n",
959                                   __func__, mode);
960                               return AH_FALSE;
961                     }
962                     *pNumTrgtChannels = 0;
963                     for (i = 0; i < nchan; i++) {
964                               EEREAD(off++);
965                               if (ee->ee_version >= AR_EEPROM_VER3_3) {
966                                         pPowerInfo->testChannel = (eeval >> 8) & 0xff;
967                               } else {
968                                         pPowerInfo->testChannel = (eeval >> 9) & 0x7f;
969                               }
970 
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);
975                                         } else {
976                                                   pPowerInfo->testChannel = fbin2freq_2p4(ee, pPowerInfo->testChannel);
977                                         }
978 
979                                         if (ee->ee_version >= AR_EEPROM_VER3_3) {
980                                                   pPowerInfo->twicePwr6_24 = (eeval >> 2) & POWER_MASK;
981                                                   pPowerInfo->twicePwr36   = (eeval << 4) & POWER_MASK;
982                                         } else {
983                                                   pPowerInfo->twicePwr6_24 = (eeval >> 3) & POWER_MASK;
984                                                   pPowerInfo->twicePwr36   = (eeval << 3) & POWER_MASK;
985                                         }
986 
987                                         EEREAD(off++);
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;
992                                         } else {
993                                                   pPowerInfo->twicePwr36 |= (eeval >> 13) & 0x7;
994                                                   pPowerInfo->twicePwr48 = (eeval >> 7) & POWER_MASK;
995                                                   pPowerInfo->twicePwr54 = (eeval >> 1) & POWER_MASK;
996                                         }
997                                         (*pNumTrgtChannels)++;
998                               }
999                               pPowerInfo++;
1000                     }
1001           }
1002           return AH_TRUE;
1003 #undef EEREAD
1004 }
1005 
1006 /*
1007  * Now copy EEPROM Coformance Testing Limits contents
1008  * into the allocated space
1009  */
1010 static HAL_BOOL
readEepromCTLInfo(struct ath_hal * ah,HAL_EEPROM * ee)1011 readEepromCTLInfo(struct ath_hal *ah, HAL_EEPROM *ee)
1012 {
1013 #define   EEREAD(_off) do {                                 \
1014           if (!ath_hal_eepromRead(ah, _off, &eeval))        \
1015                     return AH_FALSE;                        \
1016 } while (0)
1017           RD_EDGES_POWER *rep;
1018           uint16_t eeval;
1019           uint32_t off;
1020           int i, j;
1021 
1022           rep = ee->ee_rdEdgesPower;
1023 
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);
1033                               rep += NUM_EDGES;
1034                               continue;
1035                     }
1036                     if (ee->ee_version >= AR_EEPROM_VER3_3) {
1037                               for (j = 0; j < NUM_EDGES; j += 2) {
1038                                         EEREAD(off++);
1039                                         rep[j].rdEdge = (eeval >> 8) & FREQ_MASK_3_3;
1040                                         rep[j+1].rdEdge = eeval & FREQ_MASK_3_3;
1041                               }
1042                               for (j = 0; j < NUM_EDGES; j += 2) {
1043                                         EEREAD(off++);
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;
1049                               }
1050                     } else {
1051                               EEREAD(off++);
1052                               rep[0].rdEdge = (eeval >> 9) & FREQ_MASK;
1053                               rep[1].rdEdge = (eeval >> 2) & FREQ_MASK;
1054                               rep[2].rdEdge = (eeval << 5) & FREQ_MASK;
1055 
1056                               EEREAD(off++);
1057                               rep[2].rdEdge |= (eeval >> 11) & 0x1f;
1058                               rep[3].rdEdge = (eeval >> 4) & FREQ_MASK;
1059                               rep[4].rdEdge = (eeval << 3) & FREQ_MASK;
1060 
1061                               EEREAD(off++);
1062                               rep[4].rdEdge |= (eeval >> 13) & 0x7;
1063                               rep[5].rdEdge = (eeval >> 6) & FREQ_MASK;
1064                               rep[6].rdEdge = (eeval << 1) & FREQ_MASK;
1065 
1066                               EEREAD(off++);
1067                               rep[6].rdEdge |= (eeval >> 15) & 0x1;
1068                               rep[7].rdEdge = (eeval >> 8) & FREQ_MASK;
1069 
1070                               rep[0].twice_rdEdgePower = (eeval >> 2) & POWER_MASK;
1071                               rep[1].twice_rdEdgePower = (eeval << 4) & POWER_MASK;
1072 
1073                               EEREAD(off++);
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;
1077 
1078                               EEREAD(off++);
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;
1082 
1083                               EEREAD(off++);
1084                               rep[6].twice_rdEdgePower |= (eeval >> 14) & 0x3;
1085                               rep[7].twice_rdEdgePower = (eeval >> 8) & POWER_MASK;
1086                     }
1087 
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);
1093                                         } else {
1094                                                   rep[j].rdEdge = fbin2freq_2p4(ee, rep[j].rdEdge);
1095                                         }
1096                               }
1097                     }
1098                     rep += NUM_EDGES;
1099           }
1100           return AH_TRUE;
1101 #undef EEREAD
1102 }
1103 
1104 /*
1105  * Read the individual header fields for a Rev 3 EEPROM
1106  */
1107 static HAL_BOOL
readHeaderInfo(struct ath_hal * ah,HAL_EEPROM * ee)1108 readHeaderInfo(struct ath_hal *ah, HAL_EEPROM *ee)
1109 {
1110 #define   EEREAD(_off) do {                                 \
1111           if (!ath_hal_eepromRead(ah, _off, &eeval))        \
1112                     return AH_FALSE;                        \
1113 } while (0)
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 */
1121           };
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 */
1129           };
1130 
1131           static const uint32_t regCapOffsetPre4_0 = 0x00CF;
1132           static const uint32_t regCapOffsetPost4_0 = 0x00CA;
1133 
1134           const uint32_t *header;
1135           uint32_t off;
1136           uint16_t eeval;
1137           int i;
1138 
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;
1142 
1143           if (ee->ee_version >= AR_EEPROM_VER3_3) {
1144                     header = headerOffset3_3;
1145                     ee->ee_numCtls = NUM_CTLS_3_3;
1146           } else {
1147                     header = headerOffset3_0;
1148                     ee->ee_numCtls = NUM_CTLS;
1149           }
1150           HALASSERT(ee->ee_numCtls <= NUM_CTLS_MAX);
1151 
1152           EEREAD(header[0]);
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;
1159           else
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);
1164 
1165           off = header[1];
1166           EEREAD(off++);
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) {
1170                     EEREAD(off++);
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;
1175 
1176                     EEREAD(off++);
1177                     ee->ee_targetPowersStart = eeval & 0xfff;
1178                     ee->ee_exist32kHzCrystal = (eeval>>14) & 0x1;
1179 
1180                     if (ee->ee_version >= AR_EEPROM_VER5_0) {
1181                               off += 2;
1182                               EEREAD(off);
1183                               ee->ee_eepMap2PowerCalStart = (eeval >> 4) & 0xfff;
1184                               /* Properly cal'ed 5.0 devices should be non-zero */
1185                     }
1186           }
1187 
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];
1192 
1193                     EEREAD(off++);
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;
1197 
1198                     EEREAD(off++);
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;
1202 
1203                     EEREAD(off++);
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;
1207 
1208                     EEREAD(off++);
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;
1213 
1214                     EEREAD(off++);
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;
1218 
1219                     EEREAD(off++);
1220                     ee->ee_adcDesiredSize[i] = (int8_t)((eeval >> 8)  & 0xff);
1221                     switch (i) {
1222                     case headerInfo11A:
1223                               ee->ee_ob4 = (eeval >> 5)  & 0x07;
1224                               ee->ee_db4 = (eeval >> 2)  & 0x07;
1225                               ee->ee_ob3 = (eeval << 1)  & 0x07;
1226                               break;
1227                     case headerInfo11B:
1228                               ee->ee_obFor24 = (eeval >> 4)  & 0x07;
1229                               ee->ee_dbFor24 = eeval & 0x07;
1230                               break;
1231                     case headerInfo11G:
1232                               ee->ee_obFor24g = (eeval >> 4)  & 0x07;
1233                               ee->ee_dbFor24g = eeval & 0x07;
1234                               break;
1235                     }
1236 
1237                     if (i == headerInfo11A) {
1238                               EEREAD(off++);
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;
1245                     }
1246 
1247                     EEREAD(off++);
1248                     ee->ee_txEndToXLNAOn[i] = (eeval >> 8)  & 0xff;
1249                     ee->ee_thresh62[i] = eeval & 0xff;
1250 
1251                     EEREAD(off++);
1252                     ee->ee_txEndToXPAOff[i] = (eeval >> 8)  & 0xff;
1253                     ee->ee_txFrameToXPAOn[i] = eeval  & 0xff;
1254 
1255                     EEREAD(off++);
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);
1261                     }
1262 
1263                     EEREAD(off++);
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) {
1268                               switch (i) {
1269                               case headerInfo11A:
1270                                         ee->ee_fixedBias5 = (eeval >> 13) & 0x1;
1271                                         break;
1272                               case headerInfo11G:
1273                                         ee->ee_fixedBias2 = (eeval >> 13) & 0x1;
1274                                         break;
1275                               }
1276                     }
1277 
1278                     if (ee->ee_version >= AR_EEPROM_VER3_3) {
1279                               EEREAD(off++);
1280                               ee->ee_falseDetectBackoff[i] = (eeval >> 6) & 0x7F;
1281                               switch (i) {
1282                               case headerInfo11B:
1283                                         ee->ee_ob2GHz[0] = eeval & 0x7;
1284                                         ee->ee_db2GHz[0] = (eeval >> 3) & 0x7;
1285                                         break;
1286                               case headerInfo11G:
1287                                         ee->ee_ob2GHz[1] = eeval & 0x7;
1288                                         ee->ee_db2GHz[1] = (eeval >> 3) & 0x7;
1289                                         break;
1290                               case headerInfo11A:
1291                                         ee->ee_xrTargetPower5 = eeval & 0x3f;
1292                                         break;
1293                               }
1294                     }
1295                     if (ee->ee_version >= AR_EEPROM_VER3_4) {
1296                               ee->ee_gainI[i] = (eeval >> 13) & 0x07;
1297 
1298                               EEREAD(off++);
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;
1305                               }
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;
1310                               }
1311                     } else {
1312                               ee->ee_gainI[i] = 10;
1313                               ee->ee_cckOfdmPwrDelta = TENX_OFDM_CCK_DELTA_INIT;
1314                     }
1315                     if (ee->ee_version >= AR_EEPROM_VER4_0) {
1316                               switch (i) {
1317                               case headerInfo11B:
1318                                         EEREAD(off++);
1319                                         ee->ee_calPier11b[0] =
1320                                                   fbin2freq_2p4(ee, eeval&0xff);
1321                                         ee->ee_calPier11b[1] =
1322                                                   fbin2freq_2p4(ee, (eeval >> 8)&0xff);
1323                                         EEREAD(off++);
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;
1329                                         break;
1330                               case headerInfo11G:
1331                                         EEREAD(off++);
1332                                         ee->ee_calPier11g[0] =
1333                                                   fbin2freq_2p4(ee, eeval & 0xff);
1334                                         ee->ee_calPier11g[1] =
1335                                                   fbin2freq_2p4(ee, (eeval >> 8) & 0xff);
1336 
1337                                         EEREAD(off++);
1338                                         ee->ee_turbo2WMaxPower2 = eeval & 0x7F;
1339                                         ee->ee_xrTargetPower2 = (eeval >> 7) & 0x3f;
1340 
1341                                         EEREAD(off++);
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;
1347 
1348                                         EEREAD(off++);
1349                                         ee->ee_iqCalI[1] = (eeval >> 5) & 0x3F;
1350                                         ee->ee_iqCalQ[1] = eeval & 0x1F;
1351 
1352                                         if (ee->ee_version >= AR_EEPROM_VER4_2) {
1353                                                   EEREAD(off++);
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;
1361                                                             EEREAD(off++);
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;
1368                                                             EEREAD(off++);
1369                                                             ee->ee_adcDesiredSizeTurbo[1] |=
1370                                                                       (eeval & 0x7) << 5;
1371                                                             ee->ee_pgaDesiredSizeTurbo[1] =
1372                                                                       (eeval >> 3) & 0xFF;
1373                                                   }
1374                                         }
1375                                         break;
1376                               case headerInfo11A:
1377                                         if (ee->ee_version >= AR_EEPROM_VER4_1) {
1378                                                   EEREAD(off++);
1379                                                   ee->ee_rxtxMargin[headerInfo11A] =
1380                                                             eeval & 0x3f;
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;
1386                                                             EEREAD(off++);
1387                                                             ee->ee_txrxAttenTurbo[0] |=
1388                                                                       (eeval & 0x7) << 3;
1389                                                             ee->ee_rxtxMarginTurbo[0] =
1390                                                                       (eeval >> 3) & 0x3F;
1391                                                             ee->ee_adcDesiredSizeTurbo[0] =
1392                                                                       (eeval >> 9) & 0x7F;
1393                                                             EEREAD(off++);
1394                                                             ee->ee_adcDesiredSizeTurbo[0] |=
1395                                                                       (eeval & 0x1) << 7;
1396                                                             ee->ee_pgaDesiredSizeTurbo[0] =
1397                                                                       (eeval >> 1) & 0xFF;
1398                                                   }
1399                                         }
1400                                         break;
1401                               }
1402                     }
1403           }
1404           if (ee->ee_version < AR_EEPROM_VER3_3) {
1405                     /* Version 3.1+ specific parameters */
1406                     EEREAD(0xec);
1407                     ee->ee_ob2GHz[0] = eeval & 0x7;
1408                     ee->ee_db2GHz[0] = (eeval >> 3) & 0x7;
1409 
1410                     EEREAD(0xed);
1411                     ee->ee_ob2GHz[1] = eeval & 0x7;
1412                     ee->ee_db2GHz[1] = (eeval >> 3) & 0x7;
1413           }
1414 
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;
1420 
1421           /*
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.
1425           */
1426           off = header[5];
1427           for (i = 0; i < ee->ee_numCtls; i += 2) {
1428                     EEREAD(off++);
1429                     ee->ee_ctl[i] = (eeval >> 8) & 0xff;
1430                     ee->ee_ctl[i+1] = eeval & 0xff;
1431           }
1432 
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;
1439           } else {
1440                     /* Read spur mitigation data */
1441                     for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
1442                               EEREAD(off);
1443                               ee->ee_spurChans[i][0] = eeval;
1444                               EEREAD(off+AR_EEPROM_MODAL_SPURS);
1445                               ee->ee_spurChans[i][1] = eeval;
1446                               off++;
1447                     }
1448           }
1449 
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;
1455           }
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 */
1461           }
1462 
1463           /* Check for regulatory capabilities */
1464           if (ee->ee_version >= AR_EEPROM_VER4_0) {
1465                     EEREAD(regCapOffsetPost4_0);
1466           } else {
1467                     EEREAD(regCapOffsetPre4_0);
1468           }
1469 
1470           ee->ee_regCap = eeval;
1471 
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;
1476                     } else {
1477                               ee->ee_Amode = (ee->ee_regCap & AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0)?1:0;
1478                     }
1479           }
1480 
1481           if (ee->ee_version >= AR_EEPROM_VER5_1)
1482                     EEREAD(AR_EEPROM_CAPABILITIES_OFFSET);
1483           else
1484                     eeval = 0;
1485           ee->ee_opCap = eeval;
1486 
1487           EEREAD(AR_EEPROM_REG_DOMAIN);
1488           ee->ee_regdomain = eeval;
1489 
1490           return AH_TRUE;
1491 #undef EEREAD
1492 }
1493 
1494 /*
1495  * Now verify and copy EEPROM contents into the allocated space
1496  */
1497 static HAL_BOOL
legacyEepromReadContents(struct ath_hal * ah,HAL_EEPROM * ee)1498 legacyEepromReadContents(struct ath_hal *ah, HAL_EEPROM *ee)
1499 {
1500           /* Read the header information here */
1501           if (!readHeaderInfo(ah, ee))
1502                     return AH_FALSE;
1503 #if 0
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__);
1509                     return AH_FALSE;
1510           }
1511 #endif
1512           /*
1513            * Group 1: frequency pier locations readback
1514            * check that the structure has been populated
1515            * with enough space to hold the channels
1516            *
1517            * NOTE: Group 1 contains the 5 GHz channel numbers
1518            *         that have dBm->pcdac calibrated information.
1519            */
1520           if (!readEepromFreqPierInfo(ah, ee))
1521                     return AH_FALSE;
1522 
1523           /*
1524            * Group 2:  readback data for all frequency piers
1525            *
1526            * NOTE: Group 2 contains the raw power calibration
1527            *         information for each of the channels that we
1528            *         recorded above.
1529            */
1530           if (!readEepromRawPowerCalInfo(ah, ee))
1531                     return AH_FALSE;
1532 
1533           /*
1534            * Group 5: target power values per rate
1535            *
1536            * NOTE: Group 5 contains the recorded maximum power
1537            *         in dB that can be attained for the given rate.
1538            */
1539           /* Read the power per rate info for test channels */
1540           if (!readEepromTargetPowerCalInfo(ah, ee))
1541                     return AH_FALSE;
1542 
1543           /*
1544            * Group 8: Conformance Test Limits information
1545            *
1546            * NOTE: Group 8 contains the values to limit the
1547            *         maximum transmit power value based on any
1548            *         band edge violations.
1549            */
1550           /* Read the RD edge power limits */
1551           return readEepromCTLInfo(ah, ee);
1552 }
1553 
1554 static HAL_STATUS
legacyEepromGet(struct ath_hal * ah,int param,void * val)1555 legacyEepromGet(struct ath_hal *ah, int param, void *val)
1556 {
1557           HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1558           uint8_t *macaddr;
1559           uint16_t eeval;
1560           uint32_t sum;
1561           int i;
1562 
1563           switch (param) {
1564           case AR_EEP_OPCAP:
1565                     *(uint16_t *) val = ee->ee_opCap;
1566                     return HAL_OK;
1567           case AR_EEP_REGDMN_0:
1568                     *(uint16_t *) val = ee->ee_regdomain;
1569                     return HAL_OK;
1570           case AR_EEP_RFSILENT:
1571                     if (!ath_hal_eepromRead(ah, AR_EEPROM_RFSILENT, &eeval))
1572                               return HAL_EEREAD;
1573                     *(uint16_t *) val = eeval;
1574                     return HAL_OK;
1575           case AR_EEP_MACADDR:
1576                     sum = 0;
1577                     macaddr = val;
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",
1582                                             __func__, i);
1583                                         return HAL_EEREAD;
1584                               }
1585                               sum += eeval;
1586                               macaddr[2*i] = eeval >> 8;
1587                               macaddr[2*i + 1] = eeval & 0xff;
1588                     }
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;
1594                     }
1595                     return HAL_OK;
1596           case AR_EEP_RFKILL:
1597                     HALASSERT(val == AH_NULL);
1598                     return ee->ee_rfKill ? HAL_OK : HAL_EIO;
1599           case AR_EEP_AMODE:
1600                     HALASSERT(val == AH_NULL);
1601                     return ee->ee_Amode ? HAL_OK : HAL_EIO;
1602           case AR_EEP_BMODE:
1603                     HALASSERT(val == AH_NULL);
1604                     return ee->ee_Bmode ? HAL_OK : HAL_EIO;
1605           case AR_EEP_GMODE:
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) ?
1618                               HAL_OK : HAL_EIO;
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 ?
1625                         HAL_OK : HAL_EIO;
1626           case AR_EEP_FASTFRAME:
1627                     HALASSERT(val == AH_NULL);
1628                     return (ee->ee_opCap & AR_EEPROM_EEPCAP_FASTFRAME_DIS) == 0 ?
1629                         HAL_OK : HAL_EIO;
1630           case AR_EEP_AES:
1631                     HALASSERT(val == AH_NULL);
1632                     return (ee->ee_opCap & AR_EEPROM_EEPCAP_AES_DIS) == 0 ?
1633                         HAL_OK : HAL_EIO;
1634           case AR_EEP_BURST:
1635                     HALASSERT(val == AH_NULL);
1636                     return (ee->ee_opCap & AR_EEPROM_EEPCAP_BURST_DIS) == 0 ?
1637                         HAL_OK : HAL_EIO;
1638           case AR_EEP_MAXQCU:
1639                     if (ee->ee_opCap & AR_EEPROM_EEPCAP_MAXQCU) {
1640                               *(uint16_t *) val =
1641                                   MS(ee->ee_opCap, AR_EEPROM_EEPCAP_MAXQCU);
1642                               return HAL_OK;
1643                     } else
1644                               return HAL_EIO;
1645           case AR_EEP_KCENTRIES:
1646                     if (ee->ee_opCap & AR_EEPROM_EEPCAP_KC_ENTRIES) {
1647                               *(uint16_t *) val =
1648                                   1 << MS(ee->ee_opCap, AR_EEPROM_EEPCAP_KC_ENTRIES);
1649                               return HAL_OK;
1650                     } else
1651                               return HAL_EIO;
1652           case AR_EEP_ANTGAINMAX_5:
1653                     *(int8_t *) val = ee->ee_antennaGainMax[0];
1654                     return HAL_OK;
1655           case AR_EEP_ANTGAINMAX_2:
1656                     *(int8_t *) val = ee->ee_antennaGainMax[1];
1657                     return HAL_OK;
1658           case AR_EEP_WRITEPROTECT:
1659                     HALASSERT(val == AH_NULL);
1660                     return (ee->ee_protect & AR_EEPROM_PROTECT_WP_128_191) ?
1661                         HAL_OK : HAL_EIO;
1662           }
1663           return HAL_EINVAL;
1664 }
1665 
1666 static HAL_BOOL
legacyEepromSet(struct ath_hal * ah,int param,int v)1667 legacyEepromSet(struct ath_hal *ah, int param, int v)
1668 {
1669           HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1670 
1671           switch (param) {
1672           case AR_EEP_AMODE:
1673                     ee->ee_Amode = v;
1674                     return AH_TRUE;
1675           case AR_EEP_BMODE:
1676                     ee->ee_Bmode = v;
1677                     return AH_TRUE;
1678           case AR_EEP_GMODE:
1679                     ee->ee_Gmode = v;
1680                     return AH_TRUE;
1681           case AR_EEP_TURBO5DISABLE:
1682                     ee->ee_turbo5Disable = v;
1683                     return AH_TRUE;
1684           case AR_EEP_TURBO2DISABLE:
1685                     ee->ee_turbo2Disable = v;
1686                     return AH_TRUE;
1687           case AR_EEP_COMPRESS:
1688                     if (v)
1689                               ee->ee_opCap &= ~AR_EEPROM_EEPCAP_COMPRESS_DIS;
1690                     else
1691                               ee->ee_opCap |= AR_EEPROM_EEPCAP_COMPRESS_DIS;
1692                     return AH_TRUE;
1693           case AR_EEP_FASTFRAME:
1694                     if (v)
1695                               ee->ee_opCap &= ~AR_EEPROM_EEPCAP_FASTFRAME_DIS;
1696                     else
1697                               ee->ee_opCap |= AR_EEPROM_EEPCAP_FASTFRAME_DIS;
1698                     return AH_TRUE;
1699           case AR_EEP_AES:
1700                     if (v)
1701                               ee->ee_opCap &= ~AR_EEPROM_EEPCAP_AES_DIS;
1702                     else
1703                               ee->ee_opCap |= AR_EEPROM_EEPCAP_AES_DIS;
1704                     return AH_TRUE;
1705           case AR_EEP_BURST:
1706                     if (v)
1707                               ee->ee_opCap &= ~AR_EEPROM_EEPCAP_BURST_DIS;
1708                     else
1709                               ee->ee_opCap |= AR_EEPROM_EEPCAP_BURST_DIS;
1710                     return AH_TRUE;
1711           }
1712           return AH_FALSE;
1713 }
1714 
1715 static HAL_BOOL
legacyEepromDiag(struct ath_hal * ah,int request,const void * args,uint32_t argsize,void ** result,uint32_t * resultsize)1716 legacyEepromDiag(struct ath_hal *ah, int request,
1717      const void *args, uint32_t argsize, void **result, uint32_t *resultsize)
1718 {
1719           HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1720           const EEPROM_POWER_EXPN_5112 *pe;
1721 
1722           switch (request) {
1723           case HAL_DIAG_EEPROM:
1724                     *result = ee;
1725                     *resultsize = sizeof(*ee);
1726                     return AH_TRUE;
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,
1735                                         sizeof(uint32_t)) +
1736                               sizeof(EXPN_DATA_PER_CHANNEL_5112) * pe->numChannels;
1737                     return AH_TRUE;
1738           }
1739           return AH_FALSE;
1740 }
1741 
1742 static uint16_t
legacyEepromGetSpurChan(struct ath_hal * ah,int ix,HAL_BOOL is2GHz)1743 legacyEepromGetSpurChan(struct ath_hal *ah, int ix, HAL_BOOL is2GHz)
1744 {
1745           HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1746 
1747           HALASSERT(0 <= ix && ix < AR_EEPROM_MODAL_SPURS);
1748           return ee->ee_spurChans[ix][is2GHz];
1749 }
1750 
1751 /*
1752  * Reclaim any EEPROM-related storage.
1753  */
1754 static void
legacyEepromDetach(struct ath_hal * ah)1755 legacyEepromDetach(struct ath_hal *ah)
1756 {
1757           HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1758 
1759         if (ee->ee_version >= AR_EEPROM_VER4_0 && ee->ee_eepMap == 1)
1760                     freeEepromRawPowerCalInfo5112(ah, ee);
1761           ath_hal_free(ee);
1762           AH_PRIVATE(ah)->ah_eeprom = AH_NULL;
1763 }
1764 
1765 /*
1766  * These are not valid 2.4 channels, either we change 'em
1767  * or we need to change the coding to accept them.
1768  */
1769 static const uint16_t channels11b[] = { 2412, 2447, 2484 };
1770 static const uint16_t channels11g[] = { 2312, 2412, 2484 };
1771 
1772 HAL_STATUS
ath_hal_legacyEepromAttach(struct ath_hal * ah)1773 ath_hal_legacyEepromAttach(struct ath_hal *ah)
1774 {
1775           HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1776           uint32_t sum, eepMax;
1777           uint16_t eeversion, eeprotect, eeval;
1778           u_int i;
1779 
1780           HALASSERT(ee == AH_NULL);
1781 
1782           if (!ath_hal_eepromRead(ah, AR_EEPROM_VERSION, &eeversion)) {
1783                     HALDEBUG(ah, HAL_DEBUG_ANY,
1784                         "%s: unable to read EEPROM version\n", __func__);
1785                     return HAL_EEREAD;
1786           }
1787           if (eeversion < AR_EEPROM_VER3) {
1788                     HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unsupported EEPROM version "
1789                         "%u (0x%x) found\n", __func__, eeversion, eeversion);
1790                     return HAL_EEVERSION;
1791           }
1792 
1793           if (!ath_hal_eepromRead(ah, AR_EEPROM_PROTECT, &eeprotect)) {
1794                     HALDEBUG(ah, HAL_DEBUG_ANY, "%s: cannot read EEPROM protection "
1795                         "bits; read locked?\n", __func__);
1796                     return HAL_EEREAD;
1797           }
1798           HALDEBUG(ah, HAL_DEBUG_ATTACH, "EEPROM protect 0x%x\n", eeprotect);
1799           /* XXX check proper access before continuing */
1800 
1801           /*
1802            * Read the Atheros EEPROM entries and calculate the checksum.
1803            */
1804           if (!ath_hal_eepromRead(ah, AR_EEPROM_SIZE_UPPER, &eeval)) {
1805                     HALDEBUG(ah, HAL_DEBUG_ANY,
1806                         "%s: cannot read EEPROM upper size\n" , __func__);
1807                     return HAL_EEREAD;
1808           }
1809           if (eeval != 0)     {
1810                     eepMax = (eeval & AR_EEPROM_SIZE_UPPER_MASK) <<
1811                               AR_EEPROM_SIZE_ENDLOC_SHIFT;
1812                     if (!ath_hal_eepromRead(ah, AR_EEPROM_SIZE_LOWER, &eeval)) {
1813                               HALDEBUG(ah, HAL_DEBUG_ANY,
1814                                   "%s: cannot read EEPROM lower size\n" , __func__);
1815                               return HAL_EEREAD;
1816                     }
1817                     eepMax = (eepMax | eeval) - AR_EEPROM_ATHEROS_BASE;
1818           } else
1819                     eepMax = AR_EEPROM_ATHEROS_MAX;
1820           sum = 0;
1821           for (i = 0; i < eepMax; i++) {
1822                     if (!ath_hal_eepromRead(ah, AR_EEPROM_ATHEROS(i), &eeval)) {
1823                               return HAL_EEREAD;
1824                     }
1825                     sum ^= eeval;
1826           }
1827           if (sum != 0xffff) {
1828                     HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad EEPROM checksum 0x%x\n",
1829                         __func__, sum);
1830                     return HAL_EEBADSUM;
1831           }
1832 
1833           ee = ath_hal_malloc(sizeof(HAL_EEPROM));
1834           if (ee == AH_NULL) {
1835                     /* XXX message */
1836                     return HAL_ENOMEM;
1837           }
1838 
1839           ee->ee_protect = eeprotect;
1840           ee->ee_version = eeversion;
1841 
1842           ee->ee_numChannels11a = NUM_11A_EEPROM_CHANNELS;
1843           ee->ee_numChannels2_4 = NUM_2_4_EEPROM_CHANNELS;
1844 
1845           for (i = 0; i < NUM_11A_EEPROM_CHANNELS; i ++)
1846                     ee->ee_dataPerChannel11a[i].numPcdacValues = NUM_PCDAC_VALUES;
1847 
1848           /* the channel list for 2.4 is fixed, fill this in here */
1849           for (i = 0; i < NUM_2_4_EEPROM_CHANNELS; i++) {
1850                     ee->ee_channels11b[i] = channels11b[i];
1851                     /* XXX 5211 requires a hack though we don't support 11g */
1852                     if (ah->ah_magic == 0x19570405)
1853                               ee->ee_channels11g[i] = channels11b[i];
1854                     else
1855                               ee->ee_channels11g[i] = channels11g[i];
1856                     ee->ee_dataPerChannel11b[i].numPcdacValues = NUM_PCDAC_VALUES;
1857                     ee->ee_dataPerChannel11g[i].numPcdacValues = NUM_PCDAC_VALUES;
1858           }
1859 
1860           if (!legacyEepromReadContents(ah, ee)) {
1861                     /* XXX message */
1862                     ath_hal_free(ee);
1863                     return HAL_EEREAD;  /* XXX */
1864           }
1865 
1866           AH_PRIVATE(ah)->ah_eeprom = ee;
1867           AH_PRIVATE(ah)->ah_eeversion = eeversion;
1868           AH_PRIVATE(ah)->ah_eepromDetach = legacyEepromDetach;
1869           AH_PRIVATE(ah)->ah_eepromGet = legacyEepromGet;
1870           AH_PRIVATE(ah)->ah_eepromSet = legacyEepromSet;
1871           AH_PRIVATE(ah)->ah_getSpurChan = legacyEepromGetSpurChan;
1872           AH_PRIVATE(ah)->ah_eepromDiag = legacyEepromDiag;
1873           return HAL_OK;
1874 }
1875