eeprom.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366
  1. /*
  2. * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
  3. * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
  4. * Copyright (c) 2008 Felix Fietkau <nbd@openwrt.org>
  5. *
  6. * Permission to use, copy, modify, and distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. *
  18. */
  19. /*************************************\
  20. * EEPROM access functions and helpers *
  21. \*************************************/
  22. #include "ath5k.h"
  23. #include "reg.h"
  24. #include "debug.h"
  25. #include "base.h"
  26. /*
  27. * Read from eeprom
  28. */
  29. static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
  30. {
  31. u32 status, timeout;
  32. ATH5K_TRACE(ah->ah_sc);
  33. /*
  34. * Initialize EEPROM access
  35. */
  36. if (ah->ah_version == AR5K_AR5210) {
  37. AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
  38. (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
  39. } else {
  40. ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
  41. AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
  42. AR5K_EEPROM_CMD_READ);
  43. }
  44. for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
  45. status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
  46. if (status & AR5K_EEPROM_STAT_RDDONE) {
  47. if (status & AR5K_EEPROM_STAT_RDERR)
  48. return -EIO;
  49. *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
  50. 0xffff);
  51. return 0;
  52. }
  53. udelay(15);
  54. }
  55. return -ETIMEDOUT;
  56. }
  57. /*
  58. * Translate binary channel representation in EEPROM to frequency
  59. */
  60. static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
  61. unsigned int mode)
  62. {
  63. u16 val;
  64. if (bin == AR5K_EEPROM_CHANNEL_DIS)
  65. return bin;
  66. if (mode == AR5K_EEPROM_MODE_11A) {
  67. if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
  68. val = (5 * bin) + 4800;
  69. else
  70. val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
  71. (bin * 10) + 5100;
  72. } else {
  73. if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
  74. val = bin + 2300;
  75. else
  76. val = bin + 2400;
  77. }
  78. return val;
  79. }
  80. /*
  81. * Initialize eeprom & capabilities structs
  82. */
  83. static int
  84. ath5k_eeprom_init_header(struct ath5k_hw *ah)
  85. {
  86. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  87. int ret;
  88. u16 val;
  89. /* Initial TX thermal adjustment values */
  90. ee->ee_tx_clip = 4;
  91. ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
  92. ee->ee_gain_select = 1;
  93. /*
  94. * Read values from EEPROM and store them in the capability structure
  95. */
  96. AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
  97. AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
  98. AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
  99. AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
  100. AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
  101. /* Return if we have an old EEPROM */
  102. if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
  103. return 0;
  104. #ifdef notyet
  105. /*
  106. * Validate the checksum of the EEPROM date. There are some
  107. * devices with invalid EEPROMs.
  108. */
  109. for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
  110. AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
  111. cksum ^= val;
  112. }
  113. if (cksum != AR5K_EEPROM_INFO_CKSUM) {
  114. ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
  115. return -EIO;
  116. }
  117. #endif
  118. AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
  119. ee_ant_gain);
  120. if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
  121. AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
  122. AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
  123. }
  124. if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
  125. AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
  126. ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
  127. ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
  128. AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
  129. ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
  130. ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
  131. }
  132. return 0;
  133. }
  134. /*
  135. * Read antenna infos from eeprom
  136. */
  137. static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
  138. unsigned int mode)
  139. {
  140. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  141. u32 o = *offset;
  142. u16 val;
  143. int ret, i = 0;
  144. AR5K_EEPROM_READ(o++, val);
  145. ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
  146. ee->ee_atn_tx_rx[mode] = (val >> 2) & 0x3f;
  147. ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
  148. AR5K_EEPROM_READ(o++, val);
  149. ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
  150. ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
  151. ee->ee_ant_control[mode][i++] = val & 0x3f;
  152. AR5K_EEPROM_READ(o++, val);
  153. ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
  154. ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
  155. ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
  156. AR5K_EEPROM_READ(o++, val);
  157. ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
  158. ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
  159. ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
  160. ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
  161. AR5K_EEPROM_READ(o++, val);
  162. ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
  163. ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
  164. ee->ee_ant_control[mode][i++] = val & 0x3f;
  165. /* Get antenna modes */
  166. ah->ah_antenna[mode][0] =
  167. (ee->ee_ant_control[mode][0] << 4) | 0x1;
  168. ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
  169. ee->ee_ant_control[mode][1] |
  170. (ee->ee_ant_control[mode][2] << 6) |
  171. (ee->ee_ant_control[mode][3] << 12) |
  172. (ee->ee_ant_control[mode][4] << 18) |
  173. (ee->ee_ant_control[mode][5] << 24);
  174. ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
  175. ee->ee_ant_control[mode][6] |
  176. (ee->ee_ant_control[mode][7] << 6) |
  177. (ee->ee_ant_control[mode][8] << 12) |
  178. (ee->ee_ant_control[mode][9] << 18) |
  179. (ee->ee_ant_control[mode][10] << 24);
  180. /* return new offset */
  181. *offset = o;
  182. return 0;
  183. }
  184. /*
  185. * Read supported modes from eeprom
  186. */
  187. static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
  188. unsigned int mode)
  189. {
  190. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  191. u32 o = *offset;
  192. u16 val;
  193. int ret;
  194. ee->ee_n_piers[mode] = 0;
  195. AR5K_EEPROM_READ(o++, val);
  196. ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
  197. switch(mode) {
  198. case AR5K_EEPROM_MODE_11A:
  199. ee->ee_ob[mode][3] = (val >> 5) & 0x7;
  200. ee->ee_db[mode][3] = (val >> 2) & 0x7;
  201. ee->ee_ob[mode][2] = (val << 1) & 0x7;
  202. AR5K_EEPROM_READ(o++, val);
  203. ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
  204. ee->ee_db[mode][2] = (val >> 12) & 0x7;
  205. ee->ee_ob[mode][1] = (val >> 9) & 0x7;
  206. ee->ee_db[mode][1] = (val >> 6) & 0x7;
  207. ee->ee_ob[mode][0] = (val >> 3) & 0x7;
  208. ee->ee_db[mode][0] = val & 0x7;
  209. break;
  210. case AR5K_EEPROM_MODE_11G:
  211. case AR5K_EEPROM_MODE_11B:
  212. ee->ee_ob[mode][1] = (val >> 4) & 0x7;
  213. ee->ee_db[mode][1] = val & 0x7;
  214. break;
  215. }
  216. AR5K_EEPROM_READ(o++, val);
  217. ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
  218. ee->ee_thr_62[mode] = val & 0xff;
  219. if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
  220. ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
  221. AR5K_EEPROM_READ(o++, val);
  222. ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
  223. ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
  224. AR5K_EEPROM_READ(o++, val);
  225. ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
  226. if ((val & 0xff) & 0x80)
  227. ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
  228. else
  229. ee->ee_noise_floor_thr[mode] = val & 0xff;
  230. if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
  231. ee->ee_noise_floor_thr[mode] =
  232. mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
  233. AR5K_EEPROM_READ(o++, val);
  234. ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
  235. ee->ee_x_gain[mode] = (val >> 1) & 0xf;
  236. ee->ee_xpd[mode] = val & 0x1;
  237. if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
  238. ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
  239. if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
  240. AR5K_EEPROM_READ(o++, val);
  241. ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
  242. if (mode == AR5K_EEPROM_MODE_11A)
  243. ee->ee_xr_power[mode] = val & 0x3f;
  244. else {
  245. ee->ee_ob[mode][0] = val & 0x7;
  246. ee->ee_db[mode][0] = (val >> 3) & 0x7;
  247. }
  248. }
  249. if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
  250. ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
  251. ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
  252. } else {
  253. ee->ee_i_gain[mode] = (val >> 13) & 0x7;
  254. AR5K_EEPROM_READ(o++, val);
  255. ee->ee_i_gain[mode] |= (val << 3) & 0x38;
  256. if (mode == AR5K_EEPROM_MODE_11G) {
  257. ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
  258. if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6)
  259. ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
  260. }
  261. }
  262. if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
  263. mode == AR5K_EEPROM_MODE_11A) {
  264. ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
  265. ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
  266. }
  267. if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
  268. goto done;
  269. switch(mode) {
  270. case AR5K_EEPROM_MODE_11A:
  271. if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
  272. break;
  273. AR5K_EEPROM_READ(o++, val);
  274. ee->ee_margin_tx_rx[mode] = val & 0x3f;
  275. break;
  276. case AR5K_EEPROM_MODE_11B:
  277. AR5K_EEPROM_READ(o++, val);
  278. ee->ee_pwr_cal_b[0].freq =
  279. ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
  280. if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS)
  281. ee->ee_n_piers[mode]++;
  282. ee->ee_pwr_cal_b[1].freq =
  283. ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
  284. if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS)
  285. ee->ee_n_piers[mode]++;
  286. AR5K_EEPROM_READ(o++, val);
  287. ee->ee_pwr_cal_b[2].freq =
  288. ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
  289. if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS)
  290. ee->ee_n_piers[mode]++;
  291. if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
  292. ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
  293. break;
  294. case AR5K_EEPROM_MODE_11G:
  295. AR5K_EEPROM_READ(o++, val);
  296. ee->ee_pwr_cal_g[0].freq =
  297. ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
  298. if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS)
  299. ee->ee_n_piers[mode]++;
  300. ee->ee_pwr_cal_g[1].freq =
  301. ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
  302. if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS)
  303. ee->ee_n_piers[mode]++;
  304. AR5K_EEPROM_READ(o++, val);
  305. ee->ee_turbo_max_power[mode] = val & 0x7f;
  306. ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
  307. AR5K_EEPROM_READ(o++, val);
  308. ee->ee_pwr_cal_g[2].freq =
  309. ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
  310. if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS)
  311. ee->ee_n_piers[mode]++;
  312. if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
  313. ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
  314. AR5K_EEPROM_READ(o++, val);
  315. ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
  316. ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
  317. if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
  318. AR5K_EEPROM_READ(o++, val);
  319. ee->ee_cck_ofdm_gain_delta = val & 0xff;
  320. }
  321. break;
  322. }
  323. done:
  324. /* return new offset */
  325. *offset = o;
  326. return 0;
  327. }
  328. /*
  329. * Read turbo mode information on newer EEPROM versions
  330. */
  331. static int
  332. ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah,
  333. u32 *offset, unsigned int mode)
  334. {
  335. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  336. u32 o = *offset;
  337. u16 val;
  338. int ret;
  339. if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
  340. return 0;
  341. switch (mode){
  342. case AR5K_EEPROM_MODE_11A:
  343. ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
  344. ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7;
  345. AR5K_EEPROM_READ(o++, val);
  346. ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3;
  347. ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f;
  348. ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f;
  349. AR5K_EEPROM_READ(o++, val);
  350. ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;
  351. ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff;
  352. if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2)
  353. ee->ee_pd_gain_overlap = (val >> 9) & 0xf;
  354. break;
  355. case AR5K_EEPROM_MODE_11G:
  356. ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f;
  357. ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7;
  358. AR5K_EEPROM_READ(o++, val);
  359. ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1;
  360. ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f;
  361. ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f;
  362. AR5K_EEPROM_READ(o++, val);
  363. ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5;
  364. ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff;
  365. break;
  366. }
  367. /* return new offset */
  368. *offset = o;
  369. return 0;
  370. }
  371. static int
  372. ath5k_eeprom_init_modes(struct ath5k_hw *ah)
  373. {
  374. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  375. u32 mode_offset[3];
  376. unsigned int mode;
  377. u32 offset;
  378. int ret;
  379. /*
  380. * Get values for all modes
  381. */
  382. mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
  383. mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
  384. mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
  385. ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] =
  386. AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
  387. for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
  388. offset = mode_offset[mode];
  389. ret = ath5k_eeprom_read_ants(ah, &offset, mode);
  390. if (ret)
  391. return ret;
  392. ret = ath5k_eeprom_read_modes(ah, &offset, mode);
  393. if (ret)
  394. return ret;
  395. ret = ath5k_eeprom_read_turbo_modes(ah, &offset, mode);
  396. if (ret)
  397. return ret;
  398. }
  399. /* override for older eeprom versions for better performance */
  400. if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) {
  401. ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15;
  402. ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28;
  403. ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28;
  404. }
  405. return 0;
  406. }
  407. static inline void
  408. ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
  409. {
  410. const static u16 intercepts3[] =
  411. { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
  412. const static u16 intercepts3_2[] =
  413. { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
  414. const u16 *ip;
  415. int i;
  416. if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
  417. ip = intercepts3_2;
  418. else
  419. ip = intercepts3;
  420. for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
  421. *vp++ = (ip[i] * max + (100 - ip[i]) * min) / 100;
  422. }
  423. static inline int
  424. ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
  425. struct ath5k_chan_pcal_info *pc, u8 *count)
  426. {
  427. int o = *offset;
  428. int i = 0;
  429. u8 f1, f2;
  430. int ret;
  431. u16 val;
  432. while(i < max) {
  433. AR5K_EEPROM_READ(o++, val);
  434. f1 = (val >> 8) & 0xff;
  435. f2 = val & 0xff;
  436. if (f1)
  437. pc[i++].freq = f1;
  438. if (f2)
  439. pc[i++].freq = f2;
  440. if (!f1 || !f2)
  441. break;
  442. }
  443. *offset = o;
  444. *count = i;
  445. return 0;
  446. }
  447. static int
  448. ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
  449. {
  450. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  451. struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a;
  452. int i, ret;
  453. u16 val;
  454. u8 mask;
  455. if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
  456. ath5k_eeprom_read_freq_list(ah, &offset,
  457. AR5K_EEPROM_N_5GHZ_CHAN, pcal,
  458. &ee->ee_n_piers[AR5K_EEPROM_MODE_11A]);
  459. } else {
  460. mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
  461. AR5K_EEPROM_READ(offset++, val);
  462. pcal[0].freq = (val >> 9) & mask;
  463. pcal[1].freq = (val >> 2) & mask;
  464. pcal[2].freq = (val << 5) & mask;
  465. AR5K_EEPROM_READ(offset++, val);
  466. pcal[2].freq |= (val >> 11) & 0x1f;
  467. pcal[3].freq = (val >> 4) & mask;
  468. pcal[4].freq = (val << 3) & mask;
  469. AR5K_EEPROM_READ(offset++, val);
  470. pcal[4].freq |= (val >> 13) & 0x7;
  471. pcal[5].freq = (val >> 6) & mask;
  472. pcal[6].freq = (val << 1) & mask;
  473. AR5K_EEPROM_READ(offset++, val);
  474. pcal[6].freq |= (val >> 15) & 0x1;
  475. pcal[7].freq = (val >> 8) & mask;
  476. pcal[8].freq = (val >> 1) & mask;
  477. pcal[9].freq = (val << 6) & mask;
  478. AR5K_EEPROM_READ(offset++, val);
  479. pcal[9].freq |= (val >> 10) & 0x3f;
  480. ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
  481. }
  482. for(i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i += 1) {
  483. pcal[i].freq = ath5k_eeprom_bin2freq(ee,
  484. pcal[i].freq, AR5K_EEPROM_MODE_11A);
  485. }
  486. return 0;
  487. }
  488. static inline int
  489. ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
  490. {
  491. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  492. struct ath5k_chan_pcal_info *pcal;
  493. int i;
  494. switch(mode) {
  495. case AR5K_EEPROM_MODE_11B:
  496. pcal = ee->ee_pwr_cal_b;
  497. break;
  498. case AR5K_EEPROM_MODE_11G:
  499. pcal = ee->ee_pwr_cal_g;
  500. break;
  501. default:
  502. return -EINVAL;
  503. }
  504. ath5k_eeprom_read_freq_list(ah, &offset,
  505. AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
  506. &ee->ee_n_piers[mode]);
  507. for(i = 0; i < AR5K_EEPROM_N_2GHZ_CHAN_2413; i += 1) {
  508. pcal[i].freq = ath5k_eeprom_bin2freq(ee,
  509. pcal[i].freq, mode);
  510. }
  511. return 0;
  512. }
  513. static int
  514. ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
  515. {
  516. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  517. struct ath5k_chan_pcal_info *pcal;
  518. int offset, ret;
  519. int i, j;
  520. u16 val;
  521. offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
  522. switch(mode) {
  523. case AR5K_EEPROM_MODE_11A:
  524. if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
  525. return 0;
  526. ret = ath5k_eeprom_init_11a_pcal_freq(ah,
  527. offset + AR5K_EEPROM_GROUP1_OFFSET);
  528. if (ret < 0)
  529. return ret;
  530. offset += AR5K_EEPROM_GROUP2_OFFSET;
  531. pcal = ee->ee_pwr_cal_a;
  532. break;
  533. case AR5K_EEPROM_MODE_11B:
  534. if (!AR5K_EEPROM_HDR_11B(ee->ee_header) &&
  535. !AR5K_EEPROM_HDR_11G(ee->ee_header))
  536. return 0;
  537. pcal = ee->ee_pwr_cal_b;
  538. offset += AR5K_EEPROM_GROUP3_OFFSET;
  539. /* fixed piers */
  540. pcal[0].freq = 2412;
  541. pcal[1].freq = 2447;
  542. pcal[2].freq = 2484;
  543. ee->ee_n_piers[mode] = 3;
  544. break;
  545. case AR5K_EEPROM_MODE_11G:
  546. if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
  547. return 0;
  548. pcal = ee->ee_pwr_cal_g;
  549. offset += AR5K_EEPROM_GROUP4_OFFSET;
  550. /* fixed piers */
  551. pcal[0].freq = 2312;
  552. pcal[1].freq = 2412;
  553. pcal[2].freq = 2484;
  554. ee->ee_n_piers[mode] = 3;
  555. break;
  556. default:
  557. return -EINVAL;
  558. }
  559. for (i = 0; i < ee->ee_n_piers[mode]; i++) {
  560. struct ath5k_chan_pcal_info_rf5111 *cdata =
  561. &pcal[i].rf5111_info;
  562. AR5K_EEPROM_READ(offset++, val);
  563. cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M);
  564. cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M);
  565. cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M);
  566. AR5K_EEPROM_READ(offset++, val);
  567. cdata->pwr[0] |= ((val >> 14) & 0x3);
  568. cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M);
  569. cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M);
  570. cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M);
  571. AR5K_EEPROM_READ(offset++, val);
  572. cdata->pwr[3] |= ((val >> 12) & 0xf);
  573. cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M);
  574. cdata->pwr[5] = (val & AR5K_EEPROM_POWER_M);
  575. AR5K_EEPROM_READ(offset++, val);
  576. cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M);
  577. cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M);
  578. cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M);
  579. AR5K_EEPROM_READ(offset++, val);
  580. cdata->pwr[8] |= ((val >> 14) & 0x3);
  581. cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M);
  582. cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M);
  583. ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
  584. cdata->pcdac_max, cdata->pcdac);
  585. for (j = 0; j < AR5K_EEPROM_N_PCDAC; j++) {
  586. cdata->pwr[j] = (u16)
  587. (AR5K_EEPROM_POWER_STEP * cdata->pwr[j]);
  588. }
  589. }
  590. return 0;
  591. }
  592. static int
  593. ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
  594. {
  595. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  596. struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
  597. struct ath5k_chan_pcal_info *gen_chan_info;
  598. u32 offset;
  599. unsigned int i, c;
  600. u16 val;
  601. int ret;
  602. switch (mode) {
  603. case AR5K_EEPROM_MODE_11A:
  604. /*
  605. * Read 5GHz EEPROM channels
  606. */
  607. offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
  608. ath5k_eeprom_init_11a_pcal_freq(ah, offset);
  609. offset += AR5K_EEPROM_GROUP2_OFFSET;
  610. gen_chan_info = ee->ee_pwr_cal_a;
  611. break;
  612. case AR5K_EEPROM_MODE_11B:
  613. offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
  614. if (AR5K_EEPROM_HDR_11A(ee->ee_header))
  615. offset += AR5K_EEPROM_GROUP3_OFFSET;
  616. /* NB: frequency piers parsed during mode init */
  617. gen_chan_info = ee->ee_pwr_cal_b;
  618. break;
  619. case AR5K_EEPROM_MODE_11G:
  620. offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
  621. if (AR5K_EEPROM_HDR_11A(ee->ee_header))
  622. offset += AR5K_EEPROM_GROUP4_OFFSET;
  623. else if (AR5K_EEPROM_HDR_11B(ee->ee_header))
  624. offset += AR5K_EEPROM_GROUP2_OFFSET;
  625. /* NB: frequency piers parsed during mode init */
  626. gen_chan_info = ee->ee_pwr_cal_g;
  627. break;
  628. default:
  629. return -EINVAL;
  630. }
  631. for (i = 0; i < ee->ee_n_piers[mode]; i++) {
  632. chan_pcal_info = &gen_chan_info[i].rf5112_info;
  633. /* Power values in dBm * 4
  634. * for the lower xpd gain curve
  635. * (0 dBm -> higher output power) */
  636. for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
  637. AR5K_EEPROM_READ(offset++, val);
  638. chan_pcal_info->pwr_x0[c] = (val & 0xff);
  639. chan_pcal_info->pwr_x0[++c] = ((val >> 8) & 0xff);
  640. }
  641. /* PCDAC steps
  642. * corresponding to the above power
  643. * measurements */
  644. AR5K_EEPROM_READ(offset++, val);
  645. chan_pcal_info->pcdac_x0[1] = (val & 0x1f);
  646. chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
  647. chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
  648. /* Power values in dBm * 4
  649. * for the higher xpd gain curve
  650. * (18 dBm -> lower output power) */
  651. AR5K_EEPROM_READ(offset++, val);
  652. chan_pcal_info->pwr_x3[0] = (val & 0xff);
  653. chan_pcal_info->pwr_x3[1] = ((val >> 8) & 0xff);
  654. AR5K_EEPROM_READ(offset++, val);
  655. chan_pcal_info->pwr_x3[2] = (val & 0xff);
  656. /* PCDAC steps
  657. * corresponding to the above power
  658. * measurements (static) */
  659. chan_pcal_info->pcdac_x3[0] = 20;
  660. chan_pcal_info->pcdac_x3[1] = 35;
  661. chan_pcal_info->pcdac_x3[2] = 63;
  662. if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
  663. chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0xff);
  664. /* Last xpd0 power level is also channel maximum */
  665. gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
  666. } else {
  667. chan_pcal_info->pcdac_x0[0] = 1;
  668. gen_chan_info[i].max_pwr = ((val >> 8) & 0xff);
  669. }
  670. /* Recreate pcdac_x0 table for this channel using pcdac steps */
  671. chan_pcal_info->pcdac_x0[1] += chan_pcal_info->pcdac_x0[0];
  672. chan_pcal_info->pcdac_x0[2] += chan_pcal_info->pcdac_x0[1];
  673. chan_pcal_info->pcdac_x0[3] += chan_pcal_info->pcdac_x0[2];
  674. }
  675. return 0;
  676. }
  677. static inline unsigned int
  678. ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
  679. {
  680. static const unsigned int pdgains_size[] = { 4, 6, 9, 12 };
  681. unsigned int sz;
  682. sz = pdgains_size[ee->ee_pd_gains[mode] - 1];
  683. sz *= ee->ee_n_piers[mode];
  684. return sz;
  685. }
  686. static unsigned int
  687. ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
  688. {
  689. u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4);
  690. switch(mode) {
  691. case AR5K_EEPROM_MODE_11G:
  692. if (AR5K_EEPROM_HDR_11B(ee->ee_header))
  693. offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11B) + 2;
  694. /* fall through */
  695. case AR5K_EEPROM_MODE_11B:
  696. if (AR5K_EEPROM_HDR_11A(ee->ee_header))
  697. offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11A) + 5;
  698. /* fall through */
  699. case AR5K_EEPROM_MODE_11A:
  700. break;
  701. default:
  702. break;
  703. }
  704. return offset;
  705. }
  706. static int
  707. ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
  708. {
  709. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  710. struct ath5k_chan_pcal_info_rf2413 *chan_pcal_info;
  711. struct ath5k_chan_pcal_info *gen_chan_info;
  712. unsigned int i, c;
  713. u32 offset;
  714. int ret;
  715. u16 val;
  716. u8 pd_gains = 0;
  717. if (ee->ee_x_gain[mode] & 0x1) pd_gains++;
  718. if ((ee->ee_x_gain[mode] >> 1) & 0x1) pd_gains++;
  719. if ((ee->ee_x_gain[mode] >> 2) & 0x1) pd_gains++;
  720. if ((ee->ee_x_gain[mode] >> 3) & 0x1) pd_gains++;
  721. ee->ee_pd_gains[mode] = pd_gains;
  722. offset = ath5k_cal_data_offset_2413(ee, mode);
  723. switch (mode) {
  724. case AR5K_EEPROM_MODE_11A:
  725. if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
  726. return 0;
  727. ath5k_eeprom_init_11a_pcal_freq(ah, offset);
  728. offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
  729. gen_chan_info = ee->ee_pwr_cal_a;
  730. break;
  731. case AR5K_EEPROM_MODE_11B:
  732. if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
  733. return 0;
  734. ath5k_eeprom_init_11bg_2413(ah, mode, offset);
  735. offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
  736. gen_chan_info = ee->ee_pwr_cal_b;
  737. break;
  738. case AR5K_EEPROM_MODE_11G:
  739. if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
  740. return 0;
  741. ath5k_eeprom_init_11bg_2413(ah, mode, offset);
  742. offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
  743. gen_chan_info = ee->ee_pwr_cal_g;
  744. break;
  745. default:
  746. return -EINVAL;
  747. }
  748. if (pd_gains == 0)
  749. return 0;
  750. for (i = 0; i < ee->ee_n_piers[mode]; i++) {
  751. chan_pcal_info = &gen_chan_info[i].rf2413_info;
  752. /*
  753. * Read pwr_i, pddac_i and the first
  754. * 2 pd points (pwr, pddac)
  755. */
  756. AR5K_EEPROM_READ(offset++, val);
  757. chan_pcal_info->pwr_i[0] = val & 0x1f;
  758. chan_pcal_info->pddac_i[0] = (val >> 5) & 0x7f;
  759. chan_pcal_info->pwr[0][0] =
  760. (val >> 12) & 0xf;
  761. AR5K_EEPROM_READ(offset++, val);
  762. chan_pcal_info->pddac[0][0] = val & 0x3f;
  763. chan_pcal_info->pwr[0][1] = (val >> 6) & 0xf;
  764. chan_pcal_info->pddac[0][1] =
  765. (val >> 10) & 0x3f;
  766. AR5K_EEPROM_READ(offset++, val);
  767. chan_pcal_info->pwr[0][2] = val & 0xf;
  768. chan_pcal_info->pddac[0][2] =
  769. (val >> 4) & 0x3f;
  770. chan_pcal_info->pwr[0][3] = 0;
  771. chan_pcal_info->pddac[0][3] = 0;
  772. if (pd_gains > 1) {
  773. /*
  774. * Pd gain 0 is not the last pd gain
  775. * so it only has 2 pd points.
  776. * Continue wih pd gain 1.
  777. */
  778. chan_pcal_info->pwr_i[1] = (val >> 10) & 0x1f;
  779. chan_pcal_info->pddac_i[1] = (val >> 15) & 0x1;
  780. AR5K_EEPROM_READ(offset++, val);
  781. chan_pcal_info->pddac_i[1] |= (val & 0x3F) << 1;
  782. chan_pcal_info->pwr[1][0] = (val >> 6) & 0xf;
  783. chan_pcal_info->pddac[1][0] =
  784. (val >> 10) & 0x3f;
  785. AR5K_EEPROM_READ(offset++, val);
  786. chan_pcal_info->pwr[1][1] = val & 0xf;
  787. chan_pcal_info->pddac[1][1] =
  788. (val >> 4) & 0x3f;
  789. chan_pcal_info->pwr[1][2] =
  790. (val >> 10) & 0xf;
  791. chan_pcal_info->pddac[1][2] =
  792. (val >> 14) & 0x3;
  793. AR5K_EEPROM_READ(offset++, val);
  794. chan_pcal_info->pddac[1][2] |=
  795. (val & 0xF) << 2;
  796. chan_pcal_info->pwr[1][3] = 0;
  797. chan_pcal_info->pddac[1][3] = 0;
  798. } else if (pd_gains == 1) {
  799. /*
  800. * Pd gain 0 is the last one so
  801. * read the extra point.
  802. */
  803. chan_pcal_info->pwr[0][3] =
  804. (val >> 10) & 0xf;
  805. chan_pcal_info->pddac[0][3] =
  806. (val >> 14) & 0x3;
  807. AR5K_EEPROM_READ(offset++, val);
  808. chan_pcal_info->pddac[0][3] |=
  809. (val & 0xF) << 2;
  810. }
  811. /*
  812. * Proceed with the other pd_gains
  813. * as above.
  814. */
  815. if (pd_gains > 2) {
  816. chan_pcal_info->pwr_i[2] = (val >> 4) & 0x1f;
  817. chan_pcal_info->pddac_i[2] = (val >> 9) & 0x7f;
  818. AR5K_EEPROM_READ(offset++, val);
  819. chan_pcal_info->pwr[2][0] =
  820. (val >> 0) & 0xf;
  821. chan_pcal_info->pddac[2][0] =
  822. (val >> 4) & 0x3f;
  823. chan_pcal_info->pwr[2][1] =
  824. (val >> 10) & 0xf;
  825. chan_pcal_info->pddac[2][1] =
  826. (val >> 14) & 0x3;
  827. AR5K_EEPROM_READ(offset++, val);
  828. chan_pcal_info->pddac[2][1] |=
  829. (val & 0xF) << 2;
  830. chan_pcal_info->pwr[2][2] =
  831. (val >> 4) & 0xf;
  832. chan_pcal_info->pddac[2][2] =
  833. (val >> 8) & 0x3f;
  834. chan_pcal_info->pwr[2][3] = 0;
  835. chan_pcal_info->pddac[2][3] = 0;
  836. } else if (pd_gains == 2) {
  837. chan_pcal_info->pwr[1][3] =
  838. (val >> 4) & 0xf;
  839. chan_pcal_info->pddac[1][3] =
  840. (val >> 8) & 0x3f;
  841. }
  842. if (pd_gains > 3) {
  843. chan_pcal_info->pwr_i[3] = (val >> 14) & 0x3;
  844. AR5K_EEPROM_READ(offset++, val);
  845. chan_pcal_info->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
  846. chan_pcal_info->pddac_i[3] = (val >> 3) & 0x7f;
  847. chan_pcal_info->pwr[3][0] =
  848. (val >> 10) & 0xf;
  849. chan_pcal_info->pddac[3][0] =
  850. (val >> 14) & 0x3;
  851. AR5K_EEPROM_READ(offset++, val);
  852. chan_pcal_info->pddac[3][0] |=
  853. (val & 0xF) << 2;
  854. chan_pcal_info->pwr[3][1] =
  855. (val >> 4) & 0xf;
  856. chan_pcal_info->pddac[3][1] =
  857. (val >> 8) & 0x3f;
  858. chan_pcal_info->pwr[3][2] =
  859. (val >> 14) & 0x3;
  860. AR5K_EEPROM_READ(offset++, val);
  861. chan_pcal_info->pwr[3][2] |=
  862. ((val >> 0) & 0x3) << 2;
  863. chan_pcal_info->pddac[3][2] =
  864. (val >> 2) & 0x3f;
  865. chan_pcal_info->pwr[3][3] =
  866. (val >> 8) & 0xf;
  867. chan_pcal_info->pddac[3][3] =
  868. (val >> 12) & 0xF;
  869. AR5K_EEPROM_READ(offset++, val);
  870. chan_pcal_info->pddac[3][3] |=
  871. ((val >> 0) & 0x3) << 4;
  872. } else if (pd_gains == 3) {
  873. chan_pcal_info->pwr[2][3] =
  874. (val >> 14) & 0x3;
  875. AR5K_EEPROM_READ(offset++, val);
  876. chan_pcal_info->pwr[2][3] |=
  877. ((val >> 0) & 0x3) << 2;
  878. chan_pcal_info->pddac[2][3] =
  879. (val >> 2) & 0x3f;
  880. }
  881. for (c = 0; c < pd_gains; c++) {
  882. /* Recreate pwr table for this channel using pwr steps */
  883. chan_pcal_info->pwr[c][0] += chan_pcal_info->pwr_i[c] * 2;
  884. chan_pcal_info->pwr[c][1] += chan_pcal_info->pwr[c][0];
  885. chan_pcal_info->pwr[c][2] += chan_pcal_info->pwr[c][1];
  886. chan_pcal_info->pwr[c][3] += chan_pcal_info->pwr[c][2];
  887. if (chan_pcal_info->pwr[c][3] == chan_pcal_info->pwr[c][2])
  888. chan_pcal_info->pwr[c][3] = 0;
  889. /* Recreate pddac table for this channel using pddac steps */
  890. chan_pcal_info->pddac[c][0] += chan_pcal_info->pddac_i[c];
  891. chan_pcal_info->pddac[c][1] += chan_pcal_info->pddac[c][0];
  892. chan_pcal_info->pddac[c][2] += chan_pcal_info->pddac[c][1];
  893. chan_pcal_info->pddac[c][3] += chan_pcal_info->pddac[c][2];
  894. if (chan_pcal_info->pddac[c][3] == chan_pcal_info->pddac[c][2])
  895. chan_pcal_info->pddac[c][3] = 0;
  896. }
  897. }
  898. return 0;
  899. }
  900. /*
  901. * Read per rate target power (this is the maximum tx power
  902. * supported by the card). This info is used when setting
  903. * tx power, no matter the channel.
  904. *
  905. * This also works for v5 EEPROMs.
  906. */
  907. static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
  908. {
  909. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  910. struct ath5k_rate_pcal_info *rate_pcal_info;
  911. u16 *rate_target_pwr_num;
  912. u32 offset;
  913. u16 val;
  914. int ret, i;
  915. offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1);
  916. rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode];
  917. switch (mode) {
  918. case AR5K_EEPROM_MODE_11A:
  919. offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
  920. rate_pcal_info = ee->ee_rate_tpwr_a;
  921. ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN;
  922. break;
  923. case AR5K_EEPROM_MODE_11B:
  924. offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
  925. rate_pcal_info = ee->ee_rate_tpwr_b;
  926. ee->ee_rate_target_pwr_num[mode] = 2; /* 3rd is g mode's 1st */
  927. break;
  928. case AR5K_EEPROM_MODE_11G:
  929. offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
  930. rate_pcal_info = ee->ee_rate_tpwr_g;
  931. ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN;
  932. break;
  933. default:
  934. return -EINVAL;
  935. }
  936. /* Different freq mask for older eeproms (<= v3.2) */
  937. if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) {
  938. for (i = 0; i < (*rate_target_pwr_num); i++) {
  939. AR5K_EEPROM_READ(offset++, val);
  940. rate_pcal_info[i].freq =
  941. ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
  942. rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
  943. rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
  944. AR5K_EEPROM_READ(offset++, val);
  945. if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
  946. val == 0) {
  947. (*rate_target_pwr_num) = i;
  948. break;
  949. }
  950. rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
  951. rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
  952. rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
  953. }
  954. } else {
  955. for (i = 0; i < (*rate_target_pwr_num); i++) {
  956. AR5K_EEPROM_READ(offset++, val);
  957. rate_pcal_info[i].freq =
  958. ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
  959. rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
  960. rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
  961. AR5K_EEPROM_READ(offset++, val);
  962. if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
  963. val == 0) {
  964. (*rate_target_pwr_num) = i;
  965. break;
  966. }
  967. rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
  968. rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
  969. rate_pcal_info[i].target_power_54 = (val & 0x3f);
  970. }
  971. }
  972. return 0;
  973. }
  974. static int
  975. ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
  976. {
  977. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  978. int (*read_pcal)(struct ath5k_hw *hw, int mode);
  979. int mode;
  980. int err;
  981. if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) &&
  982. (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1))
  983. read_pcal = ath5k_eeprom_read_pcal_info_5112;
  984. else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) &&
  985. (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2))
  986. read_pcal = ath5k_eeprom_read_pcal_info_2413;
  987. else
  988. read_pcal = ath5k_eeprom_read_pcal_info_5111;
  989. for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
  990. err = read_pcal(ah, mode);
  991. if (err)
  992. return err;
  993. err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode);
  994. if (err < 0)
  995. return err;
  996. }
  997. return 0;
  998. }
  999. /* Read conformance test limits */
  1000. static int
  1001. ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
  1002. {
  1003. struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
  1004. struct ath5k_edge_power *rep;
  1005. unsigned int fmask, pmask;
  1006. unsigned int ctl_mode;
  1007. int ret, i, j;
  1008. u32 offset;
  1009. u16 val;
  1010. pmask = AR5K_EEPROM_POWER_M;
  1011. fmask = AR5K_EEPROM_FREQ_M(ee->ee_version);
  1012. offset = AR5K_EEPROM_CTL(ee->ee_version);
  1013. ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version);
  1014. for (i = 0; i < ee->ee_ctls; i += 2) {
  1015. AR5K_EEPROM_READ(offset++, val);
  1016. ee->ee_ctl[i] = (val >> 8) & 0xff;
  1017. ee->ee_ctl[i + 1] = val & 0xff;
  1018. }
  1019. offset = AR5K_EEPROM_GROUP8_OFFSET;
  1020. if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
  1021. offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) -
  1022. AR5K_EEPROM_GROUP5_OFFSET;
  1023. else
  1024. offset += AR5K_EEPROM_GROUPS_START(ee->ee_version);
  1025. rep = ee->ee_ctl_pwr;
  1026. for(i = 0; i < ee->ee_ctls; i++) {
  1027. switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
  1028. case AR5K_CTL_11A:
  1029. case AR5K_CTL_TURBO:
  1030. ctl_mode = AR5K_EEPROM_MODE_11A;
  1031. break;
  1032. default:
  1033. ctl_mode = AR5K_EEPROM_MODE_11G;
  1034. break;
  1035. }
  1036. if (ee->ee_ctl[i] == 0) {
  1037. if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3)
  1038. offset += 8;
  1039. else
  1040. offset += 7;
  1041. rep += AR5K_EEPROM_N_EDGES;
  1042. continue;
  1043. }
  1044. if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
  1045. for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
  1046. AR5K_EEPROM_READ(offset++, val);
  1047. rep[j].freq = (val >> 8) & fmask;
  1048. rep[j + 1].freq = val & fmask;
  1049. }
  1050. for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
  1051. AR5K_EEPROM_READ(offset++, val);
  1052. rep[j].edge = (val >> 8) & pmask;
  1053. rep[j].flag = (val >> 14) & 1;
  1054. rep[j + 1].edge = val & pmask;
  1055. rep[j + 1].flag = (val >> 6) & 1;
  1056. }
  1057. } else {
  1058. AR5K_EEPROM_READ(offset++, val);
  1059. rep[0].freq = (val >> 9) & fmask;
  1060. rep[1].freq = (val >> 2) & fmask;
  1061. rep[2].freq = (val << 5) & fmask;
  1062. AR5K_EEPROM_READ(offset++, val);
  1063. rep[2].freq |= (val >> 11) & 0x1f;
  1064. rep[3].freq = (val >> 4) & fmask;
  1065. rep[4].freq = (val << 3) & fmask;
  1066. AR5K_EEPROM_READ(offset++, val);
  1067. rep[4].freq |= (val >> 13) & 0x7;
  1068. rep[5].freq = (val >> 6) & fmask;
  1069. rep[6].freq = (val << 1) & fmask;
  1070. AR5K_EEPROM_READ(offset++, val);
  1071. rep[6].freq |= (val >> 15) & 0x1;
  1072. rep[7].freq = (val >> 8) & fmask;
  1073. rep[0].edge = (val >> 2) & pmask;
  1074. rep[1].edge = (val << 4) & pmask;
  1075. AR5K_EEPROM_READ(offset++, val);
  1076. rep[1].edge |= (val >> 12) & 0xf;
  1077. rep[2].edge = (val >> 6) & pmask;
  1078. rep[3].edge = val & pmask;
  1079. AR5K_EEPROM_READ(offset++, val);
  1080. rep[4].edge = (val >> 10) & pmask;
  1081. rep[5].edge = (val >> 4) & pmask;
  1082. rep[6].edge = (val << 2) & pmask;
  1083. AR5K_EEPROM_READ(offset++, val);
  1084. rep[6].edge |= (val >> 14) & 0x3;
  1085. rep[7].edge = (val >> 8) & pmask;
  1086. }
  1087. for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) {
  1088. rep[j].freq = ath5k_eeprom_bin2freq(ee,
  1089. rep[j].freq, ctl_mode);
  1090. }
  1091. rep += AR5K_EEPROM_N_EDGES;
  1092. }
  1093. return 0;
  1094. }
  1095. /*
  1096. * Initialize eeprom power tables
  1097. */
  1098. int
  1099. ath5k_eeprom_init(struct ath5k_hw *ah)
  1100. {
  1101. int err;
  1102. err = ath5k_eeprom_init_header(ah);
  1103. if (err < 0)
  1104. return err;
  1105. err = ath5k_eeprom_init_modes(ah);
  1106. if (err < 0)
  1107. return err;
  1108. err = ath5k_eeprom_read_pcal_info(ah);
  1109. if (err < 0)
  1110. return err;
  1111. err = ath5k_eeprom_read_ctl_info(ah);
  1112. if (err < 0)
  1113. return err;
  1114. return 0;
  1115. }
  1116. /*
  1117. * Read the MAC address from eeprom
  1118. */
  1119. int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
  1120. {
  1121. u8 mac_d[ETH_ALEN];
  1122. u32 total, offset;
  1123. u16 data;
  1124. int octet, ret;
  1125. memset(mac, 0, ETH_ALEN);
  1126. memset(mac_d, 0, ETH_ALEN);
  1127. ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
  1128. if (ret)
  1129. return ret;
  1130. for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
  1131. ret = ath5k_hw_eeprom_read(ah, offset, &data);
  1132. if (ret)
  1133. return ret;
  1134. total += data;
  1135. mac_d[octet + 1] = data & 0xff;
  1136. mac_d[octet] = data >> 8;
  1137. octet += 2;
  1138. }
  1139. memcpy(mac, mac_d, ETH_ALEN);
  1140. if (!total || total == 3 * 0xffff)
  1141. return -EINVAL;
  1142. return 0;
  1143. }