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