The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ath/ath_hal/ah_eeprom_v3.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 7194573bbce618a242cfd43d52067ea8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.