PageRenderTime 88ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/sys/dev/ath/ath_hal/ah_eeprom_v3.c

https://bitbucket.org/freebsd/freebsd-head/
C | 1876 lines | 1506 code | 186 blank | 184 comment | 274 complexity | 064be410771816777a66f21aec7813c3 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

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

Large files files are truncated, but you can click here to view the full file