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