ar9003_eeprom.c 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838
  1. /*
  2. * Copyright (c) 2010 Atheros Communications Inc.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include "hw.h"
  17. #include "ar9003_phy.h"
  18. #include "ar9003_eeprom.h"
  19. #define COMP_HDR_LEN 4
  20. #define COMP_CKSUM_LEN 2
  21. #define AR_CH0_TOP (0x00016288)
  22. #define AR_CH0_TOP_XPABIASLVL (0x3)
  23. #define AR_CH0_TOP_XPABIASLVL_S (8)
  24. #define AR_CH0_THERM (0x00016290)
  25. #define AR_CH0_THERM_SPARE (0x3f)
  26. #define AR_CH0_THERM_SPARE_S (0)
  27. #define AR_SWITCH_TABLE_COM_ALL (0xffff)
  28. #define AR_SWITCH_TABLE_COM_ALL_S (0)
  29. #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
  30. #define AR_SWITCH_TABLE_COM2_ALL_S (0)
  31. #define AR_SWITCH_TABLE_ALL (0xfff)
  32. #define AR_SWITCH_TABLE_ALL_S (0)
  33. #define LE16(x) __constant_cpu_to_le16(x)
  34. #define LE32(x) __constant_cpu_to_le32(x)
  35. static const struct ar9300_eeprom ar9300_default = {
  36. .eepromVersion = 2,
  37. .templateVersion = 2,
  38. .macAddr = {1, 2, 3, 4, 5, 6},
  39. .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  40. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  41. .baseEepHeader = {
  42. .regDmn = { LE16(0), LE16(0x1f) },
  43. .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
  44. .opCapFlags = {
  45. .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
  46. .eepMisc = 0,
  47. },
  48. .rfSilent = 0,
  49. .blueToothOptions = 0,
  50. .deviceCap = 0,
  51. .deviceType = 5, /* takes lower byte in eeprom location */
  52. .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
  53. .params_for_tuning_caps = {0, 0},
  54. .featureEnable = 0x0c,
  55. /*
  56. * bit0 - enable tx temp comp - disabled
  57. * bit1 - enable tx volt comp - disabled
  58. * bit2 - enable fastClock - enabled
  59. * bit3 - enable doubling - enabled
  60. * bit4 - enable internal regulator - disabled
  61. */
  62. .miscConfiguration = 0, /* bit0 - turn down drivestrength */
  63. .eepromWriteEnableGpio = 3,
  64. .wlanDisableGpio = 0,
  65. .wlanLedGpio = 8,
  66. .rxBandSelectGpio = 0xff,
  67. .txrxgain = 0,
  68. .swreg = 0,
  69. },
  70. .modalHeader2G = {
  71. /* ar9300_modal_eep_header 2g */
  72. /* 4 idle,t1,t2,b(4 bits per setting) */
  73. .antCtrlCommon = LE32(0x110),
  74. /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
  75. .antCtrlCommon2 = LE32(0x22222),
  76. /*
  77. * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
  78. * rx1, rx12, b (2 bits each)
  79. */
  80. .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
  81. /*
  82. * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
  83. * for ar9280 (0xa20c/b20c 5:0)
  84. */
  85. .xatten1DB = {0, 0, 0},
  86. /*
  87. * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
  88. * for ar9280 (0xa20c/b20c 16:12
  89. */
  90. .xatten1Margin = {0, 0, 0},
  91. .tempSlope = 36,
  92. .voltSlope = 0,
  93. /*
  94. * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
  95. * channels in usual fbin coding format
  96. */
  97. .spurChans = {0, 0, 0, 0, 0},
  98. /*
  99. * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
  100. * if the register is per chain
  101. */
  102. .noiseFloorThreshCh = {-1, 0, 0},
  103. .ob = {1, 1, 1},/* 3 chain */
  104. .db_stage2 = {1, 1, 1}, /* 3 chain */
  105. .db_stage3 = {0, 0, 0},
  106. .db_stage4 = {0, 0, 0},
  107. .xpaBiasLvl = 0,
  108. .txFrameToDataStart = 0x0e,
  109. .txFrameToPaOn = 0x0e,
  110. .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
  111. .antennaGain = 0,
  112. .switchSettling = 0x2c,
  113. .adcDesiredSize = -30,
  114. .txEndToXpaOff = 0,
  115. .txEndToRxOn = 0x2,
  116. .txFrameToXpaOn = 0xe,
  117. .thresh62 = 28,
  118. .futureModal = { /* [32] */
  119. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  120. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  121. },
  122. },
  123. .calFreqPier2G = {
  124. FREQ2FBIN(2412, 1),
  125. FREQ2FBIN(2437, 1),
  126. FREQ2FBIN(2472, 1),
  127. },
  128. /* ar9300_cal_data_per_freq_op_loop 2g */
  129. .calPierData2G = {
  130. { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
  131. { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
  132. { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
  133. },
  134. .calTarget_freqbin_Cck = {
  135. FREQ2FBIN(2412, 1),
  136. FREQ2FBIN(2484, 1),
  137. },
  138. .calTarget_freqbin_2G = {
  139. FREQ2FBIN(2412, 1),
  140. FREQ2FBIN(2437, 1),
  141. FREQ2FBIN(2472, 1)
  142. },
  143. .calTarget_freqbin_2GHT20 = {
  144. FREQ2FBIN(2412, 1),
  145. FREQ2FBIN(2437, 1),
  146. FREQ2FBIN(2472, 1)
  147. },
  148. .calTarget_freqbin_2GHT40 = {
  149. FREQ2FBIN(2412, 1),
  150. FREQ2FBIN(2437, 1),
  151. FREQ2FBIN(2472, 1)
  152. },
  153. .calTargetPowerCck = {
  154. /* 1L-5L,5S,11L,11S */
  155. { {36, 36, 36, 36} },
  156. { {36, 36, 36, 36} },
  157. },
  158. .calTargetPower2G = {
  159. /* 6-24,36,48,54 */
  160. { {32, 32, 28, 24} },
  161. { {32, 32, 28, 24} },
  162. { {32, 32, 28, 24} },
  163. },
  164. .calTargetPower2GHT20 = {
  165. { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
  166. { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
  167. { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
  168. },
  169. .calTargetPower2GHT40 = {
  170. { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
  171. { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
  172. { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
  173. },
  174. .ctlIndex_2G = {
  175. 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
  176. 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
  177. },
  178. .ctl_freqbin_2G = {
  179. {
  180. FREQ2FBIN(2412, 1),
  181. FREQ2FBIN(2417, 1),
  182. FREQ2FBIN(2457, 1),
  183. FREQ2FBIN(2462, 1)
  184. },
  185. {
  186. FREQ2FBIN(2412, 1),
  187. FREQ2FBIN(2417, 1),
  188. FREQ2FBIN(2462, 1),
  189. 0xFF,
  190. },
  191. {
  192. FREQ2FBIN(2412, 1),
  193. FREQ2FBIN(2417, 1),
  194. FREQ2FBIN(2462, 1),
  195. 0xFF,
  196. },
  197. {
  198. FREQ2FBIN(2422, 1),
  199. FREQ2FBIN(2427, 1),
  200. FREQ2FBIN(2447, 1),
  201. FREQ2FBIN(2452, 1)
  202. },
  203. {
  204. /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
  205. /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
  206. /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
  207. /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
  208. },
  209. {
  210. /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
  211. /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
  212. /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
  213. 0,
  214. },
  215. {
  216. /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
  217. /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
  218. FREQ2FBIN(2472, 1),
  219. 0,
  220. },
  221. {
  222. /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
  223. /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
  224. /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
  225. /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
  226. },
  227. {
  228. /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
  229. /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
  230. /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
  231. },
  232. {
  233. /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
  234. /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
  235. /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
  236. 0
  237. },
  238. {
  239. /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
  240. /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
  241. /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
  242. 0
  243. },
  244. {
  245. /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
  246. /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
  247. /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
  248. /* Data[11].ctlEdges[3].bChannel */
  249. FREQ2FBIN(2462, 1),
  250. }
  251. },
  252. .ctlPowerData_2G = {
  253. { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
  254. { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
  255. { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } },
  256. { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } },
  257. { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
  258. { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
  259. { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } },
  260. { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
  261. { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
  262. { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
  263. { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } },
  264. },
  265. .modalHeader5G = {
  266. /* 4 idle,t1,t2,b (4 bits per setting) */
  267. .antCtrlCommon = LE32(0x110),
  268. /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
  269. .antCtrlCommon2 = LE32(0x22222),
  270. /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
  271. .antCtrlChain = {
  272. LE16(0x000), LE16(0x000), LE16(0x000),
  273. },
  274. /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
  275. .xatten1DB = {0, 0, 0},
  276. /*
  277. * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
  278. * for merlin (0xa20c/b20c 16:12
  279. */
  280. .xatten1Margin = {0, 0, 0},
  281. .tempSlope = 68,
  282. .voltSlope = 0,
  283. /* spurChans spur channels in usual fbin coding format */
  284. .spurChans = {0, 0, 0, 0, 0},
  285. /* noiseFloorThreshCh Check if the register is per chain */
  286. .noiseFloorThreshCh = {-1, 0, 0},
  287. .ob = {3, 3, 3}, /* 3 chain */
  288. .db_stage2 = {3, 3, 3}, /* 3 chain */
  289. .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
  290. .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
  291. .xpaBiasLvl = 0,
  292. .txFrameToDataStart = 0x0e,
  293. .txFrameToPaOn = 0x0e,
  294. .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
  295. .antennaGain = 0,
  296. .switchSettling = 0x2d,
  297. .adcDesiredSize = -30,
  298. .txEndToXpaOff = 0,
  299. .txEndToRxOn = 0x2,
  300. .txFrameToXpaOn = 0xe,
  301. .thresh62 = 28,
  302. .futureModal = {
  303. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  304. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  305. },
  306. },
  307. .calFreqPier5G = {
  308. FREQ2FBIN(5180, 0),
  309. FREQ2FBIN(5220, 0),
  310. FREQ2FBIN(5320, 0),
  311. FREQ2FBIN(5400, 0),
  312. FREQ2FBIN(5500, 0),
  313. FREQ2FBIN(5600, 0),
  314. FREQ2FBIN(5725, 0),
  315. FREQ2FBIN(5825, 0)
  316. },
  317. .calPierData5G = {
  318. {
  319. {0, 0, 0, 0, 0},
  320. {0, 0, 0, 0, 0},
  321. {0, 0, 0, 0, 0},
  322. {0, 0, 0, 0, 0},
  323. {0, 0, 0, 0, 0},
  324. {0, 0, 0, 0, 0},
  325. {0, 0, 0, 0, 0},
  326. {0, 0, 0, 0, 0},
  327. },
  328. {
  329. {0, 0, 0, 0, 0},
  330. {0, 0, 0, 0, 0},
  331. {0, 0, 0, 0, 0},
  332. {0, 0, 0, 0, 0},
  333. {0, 0, 0, 0, 0},
  334. {0, 0, 0, 0, 0},
  335. {0, 0, 0, 0, 0},
  336. {0, 0, 0, 0, 0},
  337. },
  338. {
  339. {0, 0, 0, 0, 0},
  340. {0, 0, 0, 0, 0},
  341. {0, 0, 0, 0, 0},
  342. {0, 0, 0, 0, 0},
  343. {0, 0, 0, 0, 0},
  344. {0, 0, 0, 0, 0},
  345. {0, 0, 0, 0, 0},
  346. {0, 0, 0, 0, 0},
  347. },
  348. },
  349. .calTarget_freqbin_5G = {
  350. FREQ2FBIN(5180, 0),
  351. FREQ2FBIN(5220, 0),
  352. FREQ2FBIN(5320, 0),
  353. FREQ2FBIN(5400, 0),
  354. FREQ2FBIN(5500, 0),
  355. FREQ2FBIN(5600, 0),
  356. FREQ2FBIN(5725, 0),
  357. FREQ2FBIN(5825, 0)
  358. },
  359. .calTarget_freqbin_5GHT20 = {
  360. FREQ2FBIN(5180, 0),
  361. FREQ2FBIN(5240, 0),
  362. FREQ2FBIN(5320, 0),
  363. FREQ2FBIN(5500, 0),
  364. FREQ2FBIN(5700, 0),
  365. FREQ2FBIN(5745, 0),
  366. FREQ2FBIN(5725, 0),
  367. FREQ2FBIN(5825, 0)
  368. },
  369. .calTarget_freqbin_5GHT40 = {
  370. FREQ2FBIN(5180, 0),
  371. FREQ2FBIN(5240, 0),
  372. FREQ2FBIN(5320, 0),
  373. FREQ2FBIN(5500, 0),
  374. FREQ2FBIN(5700, 0),
  375. FREQ2FBIN(5745, 0),
  376. FREQ2FBIN(5725, 0),
  377. FREQ2FBIN(5825, 0)
  378. },
  379. .calTargetPower5G = {
  380. /* 6-24,36,48,54 */
  381. { {20, 20, 20, 10} },
  382. { {20, 20, 20, 10} },
  383. { {20, 20, 20, 10} },
  384. { {20, 20, 20, 10} },
  385. { {20, 20, 20, 10} },
  386. { {20, 20, 20, 10} },
  387. { {20, 20, 20, 10} },
  388. { {20, 20, 20, 10} },
  389. },
  390. .calTargetPower5GHT20 = {
  391. /*
  392. * 0_8_16,1-3_9-11_17-19,
  393. * 4,5,6,7,12,13,14,15,20,21,22,23
  394. */
  395. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  396. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  397. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  398. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  399. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  400. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  401. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  402. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  403. },
  404. .calTargetPower5GHT40 = {
  405. /*
  406. * 0_8_16,1-3_9-11_17-19,
  407. * 4,5,6,7,12,13,14,15,20,21,22,23
  408. */
  409. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  410. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  411. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  412. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  413. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  414. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  415. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  416. { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
  417. },
  418. .ctlIndex_5G = {
  419. 0x10, 0x16, 0x18, 0x40, 0x46,
  420. 0x48, 0x30, 0x36, 0x38
  421. },
  422. .ctl_freqbin_5G = {
  423. {
  424. /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
  425. /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
  426. /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
  427. /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
  428. /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
  429. /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
  430. /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
  431. /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
  432. },
  433. {
  434. /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
  435. /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
  436. /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
  437. /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
  438. /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
  439. /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
  440. /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
  441. /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
  442. },
  443. {
  444. /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
  445. /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
  446. /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
  447. /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
  448. /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
  449. /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
  450. /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
  451. /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
  452. },
  453. {
  454. /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
  455. /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
  456. /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
  457. /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
  458. /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
  459. /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
  460. /* Data[3].ctlEdges[6].bChannel */ 0xFF,
  461. /* Data[3].ctlEdges[7].bChannel */ 0xFF,
  462. },
  463. {
  464. /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
  465. /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
  466. /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
  467. /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
  468. /* Data[4].ctlEdges[4].bChannel */ 0xFF,
  469. /* Data[4].ctlEdges[5].bChannel */ 0xFF,
  470. /* Data[4].ctlEdges[6].bChannel */ 0xFF,
  471. /* Data[4].ctlEdges[7].bChannel */ 0xFF,
  472. },
  473. {
  474. /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
  475. /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
  476. /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
  477. /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
  478. /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
  479. /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
  480. /* Data[5].ctlEdges[6].bChannel */ 0xFF,
  481. /* Data[5].ctlEdges[7].bChannel */ 0xFF
  482. },
  483. {
  484. /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
  485. /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
  486. /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
  487. /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
  488. /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
  489. /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
  490. /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
  491. /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
  492. },
  493. {
  494. /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
  495. /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
  496. /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
  497. /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
  498. /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
  499. /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
  500. /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
  501. /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
  502. },
  503. {
  504. /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
  505. /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
  506. /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
  507. /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
  508. /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
  509. /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
  510. /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
  511. /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
  512. }
  513. },
  514. .ctlPowerData_5G = {
  515. {
  516. {
  517. {60, 1}, {60, 1}, {60, 1}, {60, 1},
  518. {60, 1}, {60, 1}, {60, 1}, {60, 0},
  519. }
  520. },
  521. {
  522. {
  523. {60, 1}, {60, 1}, {60, 1}, {60, 1},
  524. {60, 1}, {60, 1}, {60, 1}, {60, 0},
  525. }
  526. },
  527. {
  528. {
  529. {60, 0}, {60, 1}, {60, 0}, {60, 1},
  530. {60, 1}, {60, 1}, {60, 1}, {60, 1},
  531. }
  532. },
  533. {
  534. {
  535. {60, 0}, {60, 1}, {60, 1}, {60, 0},
  536. {60, 1}, {60, 0}, {60, 0}, {60, 0},
  537. }
  538. },
  539. {
  540. {
  541. {60, 1}, {60, 1}, {60, 1}, {60, 0},
  542. {60, 0}, {60, 0}, {60, 0}, {60, 0},
  543. }
  544. },
  545. {
  546. {
  547. {60, 1}, {60, 1}, {60, 1}, {60, 1},
  548. {60, 1}, {60, 0}, {60, 0}, {60, 0},
  549. }
  550. },
  551. {
  552. {
  553. {60, 1}, {60, 1}, {60, 1}, {60, 1},
  554. {60, 1}, {60, 1}, {60, 1}, {60, 1},
  555. }
  556. },
  557. {
  558. {
  559. {60, 1}, {60, 1}, {60, 0}, {60, 1},
  560. {60, 1}, {60, 1}, {60, 1}, {60, 0},
  561. }
  562. },
  563. {
  564. {
  565. {60, 1}, {60, 0}, {60, 1}, {60, 1},
  566. {60, 1}, {60, 1}, {60, 0}, {60, 1},
  567. }
  568. },
  569. }
  570. };
  571. static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
  572. {
  573. return 0;
  574. }
  575. static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
  576. enum eeprom_param param)
  577. {
  578. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  579. struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
  580. switch (param) {
  581. case EEP_MAC_LSW:
  582. return eep->macAddr[0] << 8 | eep->macAddr[1];
  583. case EEP_MAC_MID:
  584. return eep->macAddr[2] << 8 | eep->macAddr[3];
  585. case EEP_MAC_MSW:
  586. return eep->macAddr[4] << 8 | eep->macAddr[5];
  587. case EEP_REG_0:
  588. return le16_to_cpu(pBase->regDmn[0]);
  589. case EEP_REG_1:
  590. return le16_to_cpu(pBase->regDmn[1]);
  591. case EEP_OP_CAP:
  592. return pBase->deviceCap;
  593. case EEP_OP_MODE:
  594. return pBase->opCapFlags.opFlags;
  595. case EEP_RF_SILENT:
  596. return pBase->rfSilent;
  597. case EEP_TX_MASK:
  598. return (pBase->txrxMask >> 4) & 0xf;
  599. case EEP_RX_MASK:
  600. return pBase->txrxMask & 0xf;
  601. case EEP_DRIVE_STRENGTH:
  602. #define AR9300_EEP_BASE_DRIV_STRENGTH 0x1
  603. return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
  604. case EEP_INTERNAL_REGULATOR:
  605. /* Bit 4 is internal regulator flag */
  606. return (pBase->featureEnable & 0x10) >> 4;
  607. case EEP_SWREG:
  608. return le32_to_cpu(pBase->swreg);
  609. default:
  610. return 0;
  611. }
  612. }
  613. static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
  614. u8 *buffer)
  615. {
  616. u16 val;
  617. if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
  618. return false;
  619. *buffer = (val >> (8 * (address % 2))) & 0xff;
  620. return true;
  621. }
  622. static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
  623. u8 *buffer)
  624. {
  625. u16 val;
  626. if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
  627. return false;
  628. buffer[0] = val >> 8;
  629. buffer[1] = val & 0xff;
  630. return true;
  631. }
  632. static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
  633. int count)
  634. {
  635. struct ath_common *common = ath9k_hw_common(ah);
  636. int i;
  637. if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
  638. ath_print(common, ATH_DBG_EEPROM,
  639. "eeprom address not in range\n");
  640. return false;
  641. }
  642. /*
  643. * Since we're reading the bytes in reverse order from a little-endian
  644. * word stream, an even address means we only use the lower half of
  645. * the 16-bit word at that address
  646. */
  647. if (address % 2 == 0) {
  648. if (!ar9300_eeprom_read_byte(common, address--, buffer++))
  649. goto error;
  650. count--;
  651. }
  652. for (i = 0; i < count / 2; i++) {
  653. if (!ar9300_eeprom_read_word(common, address, buffer))
  654. goto error;
  655. address -= 2;
  656. buffer += 2;
  657. }
  658. if (count % 2)
  659. if (!ar9300_eeprom_read_byte(common, address, buffer))
  660. goto error;
  661. return true;
  662. error:
  663. ath_print(common, ATH_DBG_EEPROM,
  664. "unable to read eeprom region at offset %d\n", address);
  665. return false;
  666. }
  667. static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
  668. int *length, int *major, int *minor)
  669. {
  670. unsigned long value[4];
  671. value[0] = best[0];
  672. value[1] = best[1];
  673. value[2] = best[2];
  674. value[3] = best[3];
  675. *code = ((value[0] >> 5) & 0x0007);
  676. *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
  677. *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
  678. *major = (value[2] & 0x000f);
  679. *minor = (value[3] & 0x00ff);
  680. }
  681. static u16 ar9300_comp_cksum(u8 *data, int dsize)
  682. {
  683. int it, checksum = 0;
  684. for (it = 0; it < dsize; it++) {
  685. checksum += data[it];
  686. checksum &= 0xffff;
  687. }
  688. return checksum;
  689. }
  690. static bool ar9300_uncompress_block(struct ath_hw *ah,
  691. u8 *mptr,
  692. int mdataSize,
  693. u8 *block,
  694. int size)
  695. {
  696. int it;
  697. int spot;
  698. int offset;
  699. int length;
  700. struct ath_common *common = ath9k_hw_common(ah);
  701. spot = 0;
  702. for (it = 0; it < size; it += (length+2)) {
  703. offset = block[it];
  704. offset &= 0xff;
  705. spot += offset;
  706. length = block[it+1];
  707. length &= 0xff;
  708. if (length > 0 && spot >= 0 && spot+length < mdataSize) {
  709. ath_print(common, ATH_DBG_EEPROM,
  710. "Restore at %d: spot=%d "
  711. "offset=%d length=%d\n",
  712. it, spot, offset, length);
  713. memcpy(&mptr[spot], &block[it+2], length);
  714. spot += length;
  715. } else if (length > 0) {
  716. ath_print(common, ATH_DBG_EEPROM,
  717. "Bad restore at %d: spot=%d "
  718. "offset=%d length=%d\n",
  719. it, spot, offset, length);
  720. return false;
  721. }
  722. }
  723. return true;
  724. }
  725. static int ar9300_compress_decision(struct ath_hw *ah,
  726. int it,
  727. int code,
  728. int reference,
  729. u8 *mptr,
  730. u8 *word, int length, int mdata_size)
  731. {
  732. struct ath_common *common = ath9k_hw_common(ah);
  733. u8 *dptr;
  734. switch (code) {
  735. case _CompressNone:
  736. if (length != mdata_size) {
  737. ath_print(common, ATH_DBG_EEPROM,
  738. "EEPROM structure size mismatch"
  739. "memory=%d eeprom=%d\n", mdata_size, length);
  740. return -1;
  741. }
  742. memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
  743. ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
  744. " uncompressed, length %d\n", it, length);
  745. break;
  746. case _CompressBlock:
  747. if (reference == 0) {
  748. dptr = mptr;
  749. } else {
  750. if (reference != 2) {
  751. ath_print(common, ATH_DBG_EEPROM,
  752. "cant find reference eeprom"
  753. "struct %d\n", reference);
  754. return -1;
  755. }
  756. memcpy(mptr, &ar9300_default, mdata_size);
  757. }
  758. ath_print(common, ATH_DBG_EEPROM,
  759. "restore eeprom %d: block, reference %d,"
  760. " length %d\n", it, reference, length);
  761. ar9300_uncompress_block(ah, mptr, mdata_size,
  762. (u8 *) (word + COMP_HDR_LEN), length);
  763. break;
  764. default:
  765. ath_print(common, ATH_DBG_EEPROM, "unknown compression"
  766. " code %d\n", code);
  767. return -1;
  768. }
  769. return 0;
  770. }
  771. /*
  772. * Read the configuration data from the eeprom.
  773. * The data can be put in any specified memory buffer.
  774. *
  775. * Returns -1 on error.
  776. * Returns address of next memory location on success.
  777. */
  778. static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
  779. u8 *mptr, int mdata_size)
  780. {
  781. #define MDEFAULT 15
  782. #define MSTATE 100
  783. int cptr;
  784. u8 *word;
  785. int code;
  786. int reference, length, major, minor;
  787. int osize;
  788. int it;
  789. u16 checksum, mchecksum;
  790. struct ath_common *common = ath9k_hw_common(ah);
  791. word = kzalloc(2048, GFP_KERNEL);
  792. if (!word)
  793. return -1;
  794. memcpy(mptr, &ar9300_default, mdata_size);
  795. cptr = AR9300_BASE_ADDR;
  796. for (it = 0; it < MSTATE; it++) {
  797. if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
  798. goto fail;
  799. if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
  800. word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
  801. && word[2] == 0xff && word[3] == 0xff))
  802. break;
  803. ar9300_comp_hdr_unpack(word, &code, &reference,
  804. &length, &major, &minor);
  805. ath_print(common, ATH_DBG_EEPROM,
  806. "Found block at %x: code=%d ref=%d"
  807. "length=%d major=%d minor=%d\n", cptr, code,
  808. reference, length, major, minor);
  809. if (length >= 1024) {
  810. ath_print(common, ATH_DBG_EEPROM,
  811. "Skipping bad header\n");
  812. cptr -= COMP_HDR_LEN;
  813. continue;
  814. }
  815. osize = length;
  816. ar9300_read_eeprom(ah, cptr, word,
  817. COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
  818. checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
  819. mchecksum = word[COMP_HDR_LEN + osize] |
  820. (word[COMP_HDR_LEN + osize + 1] << 8);
  821. ath_print(common, ATH_DBG_EEPROM,
  822. "checksum %x %x\n", checksum, mchecksum);
  823. if (checksum == mchecksum) {
  824. ar9300_compress_decision(ah, it, code, reference, mptr,
  825. word, length, mdata_size);
  826. } else {
  827. ath_print(common, ATH_DBG_EEPROM,
  828. "skipping block with bad checksum\n");
  829. }
  830. cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
  831. }
  832. kfree(word);
  833. return cptr;
  834. fail:
  835. kfree(word);
  836. return -1;
  837. }
  838. /*
  839. * Restore the configuration structure by reading the eeprom.
  840. * This function destroys any existing in-memory structure
  841. * content.
  842. */
  843. static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
  844. {
  845. u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
  846. if (ar9300_eeprom_restore_internal(ah, mptr,
  847. sizeof(struct ar9300_eeprom)) < 0)
  848. return false;
  849. return true;
  850. }
  851. /* XXX: review hardware docs */
  852. static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
  853. {
  854. return ah->eeprom.ar9300_eep.eepromVersion;
  855. }
  856. /* XXX: could be read from the eepromVersion, not sure yet */
  857. static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
  858. {
  859. return 0;
  860. }
  861. static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
  862. enum ieee80211_band freq_band)
  863. {
  864. return 1;
  865. }
  866. static u16 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
  867. struct ath9k_channel *chan)
  868. {
  869. return -EINVAL;
  870. }
  871. static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
  872. {
  873. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  874. if (is2ghz)
  875. return eep->modalHeader2G.xpaBiasLvl;
  876. else
  877. return eep->modalHeader5G.xpaBiasLvl;
  878. }
  879. static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
  880. {
  881. int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
  882. REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3));
  883. REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE,
  884. ((bias >> 2) & 0x3));
  885. }
  886. static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
  887. {
  888. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  889. __le32 val;
  890. if (is2ghz)
  891. val = eep->modalHeader2G.antCtrlCommon;
  892. else
  893. val = eep->modalHeader5G.antCtrlCommon;
  894. return le32_to_cpu(val);
  895. }
  896. static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
  897. {
  898. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  899. __le32 val;
  900. if (is2ghz)
  901. val = eep->modalHeader2G.antCtrlCommon2;
  902. else
  903. val = eep->modalHeader5G.antCtrlCommon2;
  904. return le32_to_cpu(val);
  905. }
  906. static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
  907. int chain,
  908. bool is2ghz)
  909. {
  910. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  911. __le16 val = 0;
  912. if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
  913. if (is2ghz)
  914. val = eep->modalHeader2G.antCtrlChain[chain];
  915. else
  916. val = eep->modalHeader5G.antCtrlChain[chain];
  917. }
  918. return le16_to_cpu(val);
  919. }
  920. static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
  921. {
  922. u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
  923. REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
  924. value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
  925. REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
  926. value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
  927. REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
  928. value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
  929. REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
  930. value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
  931. REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
  932. }
  933. static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
  934. {
  935. int drive_strength;
  936. unsigned long reg;
  937. drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
  938. if (!drive_strength)
  939. return;
  940. reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
  941. reg &= ~0x00ffffc0;
  942. reg |= 0x5 << 21;
  943. reg |= 0x5 << 18;
  944. reg |= 0x5 << 15;
  945. reg |= 0x5 << 12;
  946. reg |= 0x5 << 9;
  947. reg |= 0x5 << 6;
  948. REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
  949. reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
  950. reg &= ~0xffffffe0;
  951. reg |= 0x5 << 29;
  952. reg |= 0x5 << 26;
  953. reg |= 0x5 << 23;
  954. reg |= 0x5 << 20;
  955. reg |= 0x5 << 17;
  956. reg |= 0x5 << 14;
  957. reg |= 0x5 << 11;
  958. reg |= 0x5 << 8;
  959. reg |= 0x5 << 5;
  960. REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
  961. reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
  962. reg &= ~0xff800000;
  963. reg |= 0x5 << 29;
  964. reg |= 0x5 << 26;
  965. reg |= 0x5 << 23;
  966. REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
  967. }
  968. static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
  969. {
  970. int internal_regulator =
  971. ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
  972. if (internal_regulator) {
  973. /* Internal regulator is ON. Write swreg register. */
  974. int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
  975. REG_WRITE(ah, AR_RTC_REG_CONTROL1,
  976. REG_READ(ah, AR_RTC_REG_CONTROL1) &
  977. (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
  978. REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
  979. /* Set REG_CONTROL1.SWREG_PROGRAM */
  980. REG_WRITE(ah, AR_RTC_REG_CONTROL1,
  981. REG_READ(ah,
  982. AR_RTC_REG_CONTROL1) |
  983. AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
  984. } else {
  985. REG_WRITE(ah, AR_RTC_SLEEP_CLK,
  986. (REG_READ(ah,
  987. AR_RTC_SLEEP_CLK) |
  988. AR_RTC_FORCE_SWREG_PRD));
  989. }
  990. }
  991. static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
  992. struct ath9k_channel *chan)
  993. {
  994. ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
  995. ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
  996. ar9003_hw_drive_strength_apply(ah);
  997. ar9003_hw_internal_regulator_apply(ah);
  998. }
  999. static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
  1000. struct ath9k_channel *chan)
  1001. {
  1002. }
  1003. /*
  1004. * Returns the interpolated y value corresponding to the specified x value
  1005. * from the np ordered pairs of data (px,py).
  1006. * The pairs do not have to be in any order.
  1007. * If the specified x value is less than any of the px,
  1008. * the returned y value is equal to the py for the lowest px.
  1009. * If the specified x value is greater than any of the px,
  1010. * the returned y value is equal to the py for the highest px.
  1011. */
  1012. static int ar9003_hw_power_interpolate(int32_t x,
  1013. int32_t *px, int32_t *py, u_int16_t np)
  1014. {
  1015. int ip = 0;
  1016. int lx = 0, ly = 0, lhave = 0;
  1017. int hx = 0, hy = 0, hhave = 0;
  1018. int dx = 0;
  1019. int y = 0;
  1020. lhave = 0;
  1021. hhave = 0;
  1022. /* identify best lower and higher x calibration measurement */
  1023. for (ip = 0; ip < np; ip++) {
  1024. dx = x - px[ip];
  1025. /* this measurement is higher than our desired x */
  1026. if (dx <= 0) {
  1027. if (!hhave || dx > (x - hx)) {
  1028. /* new best higher x measurement */
  1029. hx = px[ip];
  1030. hy = py[ip];
  1031. hhave = 1;
  1032. }
  1033. }
  1034. /* this measurement is lower than our desired x */
  1035. if (dx >= 0) {
  1036. if (!lhave || dx < (x - lx)) {
  1037. /* new best lower x measurement */
  1038. lx = px[ip];
  1039. ly = py[ip];
  1040. lhave = 1;
  1041. }
  1042. }
  1043. }
  1044. /* the low x is good */
  1045. if (lhave) {
  1046. /* so is the high x */
  1047. if (hhave) {
  1048. /* they're the same, so just pick one */
  1049. if (hx == lx)
  1050. y = ly;
  1051. else /* interpolate */
  1052. y = ly + (((x - lx) * (hy - ly)) / (hx - lx));
  1053. } else /* only low is good, use it */
  1054. y = ly;
  1055. } else if (hhave) /* only high is good, use it */
  1056. y = hy;
  1057. else /* nothing is good,this should never happen unless np=0, ???? */
  1058. y = -(1 << 30);
  1059. return y;
  1060. }
  1061. static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
  1062. u16 rateIndex, u16 freq, bool is2GHz)
  1063. {
  1064. u16 numPiers, i;
  1065. s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
  1066. s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
  1067. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  1068. struct cal_tgt_pow_legacy *pEepromTargetPwr;
  1069. u8 *pFreqBin;
  1070. if (is2GHz) {
  1071. numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
  1072. pEepromTargetPwr = eep->calTargetPower2G;
  1073. pFreqBin = eep->calTarget_freqbin_2G;
  1074. } else {
  1075. numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
  1076. pEepromTargetPwr = eep->calTargetPower5G;
  1077. pFreqBin = eep->calTarget_freqbin_5G;
  1078. }
  1079. /*
  1080. * create array of channels and targetpower from
  1081. * targetpower piers stored on eeprom
  1082. */
  1083. for (i = 0; i < numPiers; i++) {
  1084. freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
  1085. targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
  1086. }
  1087. /* interpolate to get target power for given frequency */
  1088. return (u8) ar9003_hw_power_interpolate((s32) freq,
  1089. freqArray,
  1090. targetPowerArray, numPiers);
  1091. }
  1092. static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
  1093. u16 rateIndex,
  1094. u16 freq, bool is2GHz)
  1095. {
  1096. u16 numPiers, i;
  1097. s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
  1098. s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
  1099. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  1100. struct cal_tgt_pow_ht *pEepromTargetPwr;
  1101. u8 *pFreqBin;
  1102. if (is2GHz) {
  1103. numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
  1104. pEepromTargetPwr = eep->calTargetPower2GHT20;
  1105. pFreqBin = eep->calTarget_freqbin_2GHT20;
  1106. } else {
  1107. numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
  1108. pEepromTargetPwr = eep->calTargetPower5GHT20;
  1109. pFreqBin = eep->calTarget_freqbin_5GHT20;
  1110. }
  1111. /*
  1112. * create array of channels and targetpower
  1113. * from targetpower piers stored on eeprom
  1114. */
  1115. for (i = 0; i < numPiers; i++) {
  1116. freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
  1117. targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
  1118. }
  1119. /* interpolate to get target power for given frequency */
  1120. return (u8) ar9003_hw_power_interpolate((s32) freq,
  1121. freqArray,
  1122. targetPowerArray, numPiers);
  1123. }
  1124. static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
  1125. u16 rateIndex,
  1126. u16 freq, bool is2GHz)
  1127. {
  1128. u16 numPiers, i;
  1129. s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
  1130. s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
  1131. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  1132. struct cal_tgt_pow_ht *pEepromTargetPwr;
  1133. u8 *pFreqBin;
  1134. if (is2GHz) {
  1135. numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
  1136. pEepromTargetPwr = eep->calTargetPower2GHT40;
  1137. pFreqBin = eep->calTarget_freqbin_2GHT40;
  1138. } else {
  1139. numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
  1140. pEepromTargetPwr = eep->calTargetPower5GHT40;
  1141. pFreqBin = eep->calTarget_freqbin_5GHT40;
  1142. }
  1143. /*
  1144. * create array of channels and targetpower from
  1145. * targetpower piers stored on eeprom
  1146. */
  1147. for (i = 0; i < numPiers; i++) {
  1148. freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
  1149. targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
  1150. }
  1151. /* interpolate to get target power for given frequency */
  1152. return (u8) ar9003_hw_power_interpolate((s32) freq,
  1153. freqArray,
  1154. targetPowerArray, numPiers);
  1155. }
  1156. static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
  1157. u16 rateIndex, u16 freq)
  1158. {
  1159. u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
  1160. s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
  1161. s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
  1162. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  1163. struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
  1164. u8 *pFreqBin = eep->calTarget_freqbin_Cck;
  1165. /*
  1166. * create array of channels and targetpower from
  1167. * targetpower piers stored on eeprom
  1168. */
  1169. for (i = 0; i < numPiers; i++) {
  1170. freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
  1171. targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
  1172. }
  1173. /* interpolate to get target power for given frequency */
  1174. return (u8) ar9003_hw_power_interpolate((s32) freq,
  1175. freqArray,
  1176. targetPowerArray, numPiers);
  1177. }
  1178. /* Set tx power registers to array of values passed in */
  1179. static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
  1180. {
  1181. #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
  1182. /* make sure forced gain is not set */
  1183. REG_WRITE(ah, 0xa458, 0);
  1184. /* Write the OFDM power per rate set */
  1185. /* 6 (LSB), 9, 12, 18 (MSB) */
  1186. REG_WRITE(ah, 0xa3c0,
  1187. POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
  1188. POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
  1189. POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
  1190. POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
  1191. /* 24 (LSB), 36, 48, 54 (MSB) */
  1192. REG_WRITE(ah, 0xa3c4,
  1193. POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
  1194. POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
  1195. POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
  1196. POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
  1197. /* Write the CCK power per rate set */
  1198. /* 1L (LSB), reserved, 2L, 2S (MSB) */
  1199. REG_WRITE(ah, 0xa3c8,
  1200. POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
  1201. POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
  1202. /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
  1203. POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
  1204. /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
  1205. REG_WRITE(ah, 0xa3cc,
  1206. POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
  1207. POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
  1208. POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
  1209. POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
  1210. );
  1211. /* Write the HT20 power per rate set */
  1212. /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
  1213. REG_WRITE(ah, 0xa3d0,
  1214. POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
  1215. POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
  1216. POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
  1217. POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
  1218. );
  1219. /* 6 (LSB), 7, 12, 13 (MSB) */
  1220. REG_WRITE(ah, 0xa3d4,
  1221. POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
  1222. POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
  1223. POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
  1224. POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
  1225. );
  1226. /* 14 (LSB), 15, 20, 21 */
  1227. REG_WRITE(ah, 0xa3e4,
  1228. POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
  1229. POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
  1230. POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
  1231. POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
  1232. );
  1233. /* Mixed HT20 and HT40 rates */
  1234. /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
  1235. REG_WRITE(ah, 0xa3e8,
  1236. POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
  1237. POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
  1238. POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
  1239. POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
  1240. );
  1241. /*
  1242. * Write the HT40 power per rate set
  1243. * correct PAR difference between HT40 and HT20/LEGACY
  1244. * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
  1245. */
  1246. REG_WRITE(ah, 0xa3d8,
  1247. POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
  1248. POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
  1249. POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
  1250. POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
  1251. );
  1252. /* 6 (LSB), 7, 12, 13 (MSB) */
  1253. REG_WRITE(ah, 0xa3dc,
  1254. POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
  1255. POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
  1256. POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
  1257. POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
  1258. );
  1259. /* 14 (LSB), 15, 20, 21 */
  1260. REG_WRITE(ah, 0xa3ec,
  1261. POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
  1262. POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
  1263. POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
  1264. POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
  1265. );
  1266. return 0;
  1267. #undef POW_SM
  1268. }
  1269. static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq)
  1270. {
  1271. u8 targetPowerValT2[ar9300RateSize];
  1272. /* XXX: hard code for now, need to get from eeprom struct */
  1273. u8 ht40PowerIncForPdadc = 0;
  1274. bool is2GHz = false;
  1275. unsigned int i = 0;
  1276. struct ath_common *common = ath9k_hw_common(ah);
  1277. if (freq < 4000)
  1278. is2GHz = true;
  1279. targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
  1280. ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
  1281. is2GHz);
  1282. targetPowerValT2[ALL_TARGET_LEGACY_36] =
  1283. ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
  1284. is2GHz);
  1285. targetPowerValT2[ALL_TARGET_LEGACY_48] =
  1286. ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
  1287. is2GHz);
  1288. targetPowerValT2[ALL_TARGET_LEGACY_54] =
  1289. ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
  1290. is2GHz);
  1291. targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
  1292. ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
  1293. freq);
  1294. targetPowerValT2[ALL_TARGET_LEGACY_5S] =
  1295. ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
  1296. targetPowerValT2[ALL_TARGET_LEGACY_11L] =
  1297. ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
  1298. targetPowerValT2[ALL_TARGET_LEGACY_11S] =
  1299. ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
  1300. targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
  1301. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
  1302. is2GHz);
  1303. targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
  1304. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
  1305. freq, is2GHz);
  1306. targetPowerValT2[ALL_TARGET_HT20_4] =
  1307. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
  1308. is2GHz);
  1309. targetPowerValT2[ALL_TARGET_HT20_5] =
  1310. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
  1311. is2GHz);
  1312. targetPowerValT2[ALL_TARGET_HT20_6] =
  1313. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
  1314. is2GHz);
  1315. targetPowerValT2[ALL_TARGET_HT20_7] =
  1316. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
  1317. is2GHz);
  1318. targetPowerValT2[ALL_TARGET_HT20_12] =
  1319. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
  1320. is2GHz);
  1321. targetPowerValT2[ALL_TARGET_HT20_13] =
  1322. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
  1323. is2GHz);
  1324. targetPowerValT2[ALL_TARGET_HT20_14] =
  1325. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
  1326. is2GHz);
  1327. targetPowerValT2[ALL_TARGET_HT20_15] =
  1328. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
  1329. is2GHz);
  1330. targetPowerValT2[ALL_TARGET_HT20_20] =
  1331. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
  1332. is2GHz);
  1333. targetPowerValT2[ALL_TARGET_HT20_21] =
  1334. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
  1335. is2GHz);
  1336. targetPowerValT2[ALL_TARGET_HT20_22] =
  1337. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
  1338. is2GHz);
  1339. targetPowerValT2[ALL_TARGET_HT20_23] =
  1340. ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
  1341. is2GHz);
  1342. targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
  1343. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
  1344. is2GHz) + ht40PowerIncForPdadc;
  1345. targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
  1346. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
  1347. freq,
  1348. is2GHz) + ht40PowerIncForPdadc;
  1349. targetPowerValT2[ALL_TARGET_HT40_4] =
  1350. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
  1351. is2GHz) + ht40PowerIncForPdadc;
  1352. targetPowerValT2[ALL_TARGET_HT40_5] =
  1353. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
  1354. is2GHz) + ht40PowerIncForPdadc;
  1355. targetPowerValT2[ALL_TARGET_HT40_6] =
  1356. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
  1357. is2GHz) + ht40PowerIncForPdadc;
  1358. targetPowerValT2[ALL_TARGET_HT40_7] =
  1359. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
  1360. is2GHz) + ht40PowerIncForPdadc;
  1361. targetPowerValT2[ALL_TARGET_HT40_12] =
  1362. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
  1363. is2GHz) + ht40PowerIncForPdadc;
  1364. targetPowerValT2[ALL_TARGET_HT40_13] =
  1365. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
  1366. is2GHz) + ht40PowerIncForPdadc;
  1367. targetPowerValT2[ALL_TARGET_HT40_14] =
  1368. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
  1369. is2GHz) + ht40PowerIncForPdadc;
  1370. targetPowerValT2[ALL_TARGET_HT40_15] =
  1371. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
  1372. is2GHz) + ht40PowerIncForPdadc;
  1373. targetPowerValT2[ALL_TARGET_HT40_20] =
  1374. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
  1375. is2GHz) + ht40PowerIncForPdadc;
  1376. targetPowerValT2[ALL_TARGET_HT40_21] =
  1377. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
  1378. is2GHz) + ht40PowerIncForPdadc;
  1379. targetPowerValT2[ALL_TARGET_HT40_22] =
  1380. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
  1381. is2GHz) + ht40PowerIncForPdadc;
  1382. targetPowerValT2[ALL_TARGET_HT40_23] =
  1383. ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
  1384. is2GHz) + ht40PowerIncForPdadc;
  1385. while (i < ar9300RateSize) {
  1386. ath_print(common, ATH_DBG_EEPROM,
  1387. "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
  1388. i++;
  1389. ath_print(common, ATH_DBG_EEPROM,
  1390. "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
  1391. i++;
  1392. ath_print(common, ATH_DBG_EEPROM,
  1393. "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
  1394. i++;
  1395. ath_print(common, ATH_DBG_EEPROM,
  1396. "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
  1397. i++;
  1398. }
  1399. /* Write target power array to registers */
  1400. ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
  1401. }
  1402. static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
  1403. int mode,
  1404. int ipier,
  1405. int ichain,
  1406. int *pfrequency,
  1407. int *pcorrection,
  1408. int *ptemperature, int *pvoltage)
  1409. {
  1410. u8 *pCalPier;
  1411. struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
  1412. int is2GHz;
  1413. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  1414. struct ath_common *common = ath9k_hw_common(ah);
  1415. if (ichain >= AR9300_MAX_CHAINS) {
  1416. ath_print(common, ATH_DBG_EEPROM,
  1417. "Invalid chain index, must be less than %d\n",
  1418. AR9300_MAX_CHAINS);
  1419. return -1;
  1420. }
  1421. if (mode) { /* 5GHz */
  1422. if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
  1423. ath_print(common, ATH_DBG_EEPROM,
  1424. "Invalid 5GHz cal pier index, must "
  1425. "be less than %d\n",
  1426. AR9300_NUM_5G_CAL_PIERS);
  1427. return -1;
  1428. }
  1429. pCalPier = &(eep->calFreqPier5G[ipier]);
  1430. pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
  1431. is2GHz = 0;
  1432. } else {
  1433. if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
  1434. ath_print(common, ATH_DBG_EEPROM,
  1435. "Invalid 2GHz cal pier index, must "
  1436. "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
  1437. return -1;
  1438. }
  1439. pCalPier = &(eep->calFreqPier2G[ipier]);
  1440. pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
  1441. is2GHz = 1;
  1442. }
  1443. *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
  1444. *pcorrection = pCalPierStruct->refPower;
  1445. *ptemperature = pCalPierStruct->tempMeas;
  1446. *pvoltage = pCalPierStruct->voltMeas;
  1447. return 0;
  1448. }
  1449. static int ar9003_hw_power_control_override(struct ath_hw *ah,
  1450. int frequency,
  1451. int *correction,
  1452. int *voltage, int *temperature)
  1453. {
  1454. int tempSlope = 0;
  1455. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  1456. REG_RMW(ah, AR_PHY_TPC_11_B0,
  1457. (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
  1458. AR_PHY_TPC_OLPC_GAIN_DELTA);
  1459. REG_RMW(ah, AR_PHY_TPC_11_B1,
  1460. (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
  1461. AR_PHY_TPC_OLPC_GAIN_DELTA);
  1462. REG_RMW(ah, AR_PHY_TPC_11_B2,
  1463. (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
  1464. AR_PHY_TPC_OLPC_GAIN_DELTA);
  1465. /* enable open loop power control on chip */
  1466. REG_RMW(ah, AR_PHY_TPC_6_B0,
  1467. (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
  1468. AR_PHY_TPC_6_ERROR_EST_MODE);
  1469. REG_RMW(ah, AR_PHY_TPC_6_B1,
  1470. (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
  1471. AR_PHY_TPC_6_ERROR_EST_MODE);
  1472. REG_RMW(ah, AR_PHY_TPC_6_B2,
  1473. (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
  1474. AR_PHY_TPC_6_ERROR_EST_MODE);
  1475. /*
  1476. * enable temperature compensation
  1477. * Need to use register names
  1478. */
  1479. if (frequency < 4000)
  1480. tempSlope = eep->modalHeader2G.tempSlope;
  1481. else
  1482. tempSlope = eep->modalHeader5G.tempSlope;
  1483. REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
  1484. REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
  1485. temperature[0]);
  1486. return 0;
  1487. }
  1488. /* Apply the recorded correction values. */
  1489. static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
  1490. {
  1491. int ichain, ipier, npier;
  1492. int mode;
  1493. int lfrequency[AR9300_MAX_CHAINS],
  1494. lcorrection[AR9300_MAX_CHAINS],
  1495. ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
  1496. int hfrequency[AR9300_MAX_CHAINS],
  1497. hcorrection[AR9300_MAX_CHAINS],
  1498. htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
  1499. int fdiff;
  1500. int correction[AR9300_MAX_CHAINS],
  1501. voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
  1502. int pfrequency, pcorrection, ptemperature, pvoltage;
  1503. struct ath_common *common = ath9k_hw_common(ah);
  1504. mode = (frequency >= 4000);
  1505. if (mode)
  1506. npier = AR9300_NUM_5G_CAL_PIERS;
  1507. else
  1508. npier = AR9300_NUM_2G_CAL_PIERS;
  1509. for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
  1510. lfrequency[ichain] = 0;
  1511. hfrequency[ichain] = 100000;
  1512. }
  1513. /* identify best lower and higher frequency calibration measurement */
  1514. for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
  1515. for (ipier = 0; ipier < npier; ipier++) {
  1516. if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
  1517. &pfrequency, &pcorrection,
  1518. &ptemperature, &pvoltage)) {
  1519. fdiff = frequency - pfrequency;
  1520. /*
  1521. * this measurement is higher than
  1522. * our desired frequency
  1523. */
  1524. if (fdiff <= 0) {
  1525. if (hfrequency[ichain] <= 0 ||
  1526. hfrequency[ichain] >= 100000 ||
  1527. fdiff >
  1528. (frequency - hfrequency[ichain])) {
  1529. /*
  1530. * new best higher
  1531. * frequency measurement
  1532. */
  1533. hfrequency[ichain] = pfrequency;
  1534. hcorrection[ichain] =
  1535. pcorrection;
  1536. htemperature[ichain] =
  1537. ptemperature;
  1538. hvoltage[ichain] = pvoltage;
  1539. }
  1540. }
  1541. if (fdiff >= 0) {
  1542. if (lfrequency[ichain] <= 0
  1543. || fdiff <
  1544. (frequency - lfrequency[ichain])) {
  1545. /*
  1546. * new best lower
  1547. * frequency measurement
  1548. */
  1549. lfrequency[ichain] = pfrequency;
  1550. lcorrection[ichain] =
  1551. pcorrection;
  1552. ltemperature[ichain] =
  1553. ptemperature;
  1554. lvoltage[ichain] = pvoltage;
  1555. }
  1556. }
  1557. }
  1558. }
  1559. }
  1560. /* interpolate */
  1561. for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
  1562. ath_print(common, ATH_DBG_EEPROM,
  1563. "ch=%d f=%d low=%d %d h=%d %d\n",
  1564. ichain, frequency, lfrequency[ichain],
  1565. lcorrection[ichain], hfrequency[ichain],
  1566. hcorrection[ichain]);
  1567. /* they're the same, so just pick one */
  1568. if (hfrequency[ichain] == lfrequency[ichain]) {
  1569. correction[ichain] = lcorrection[ichain];
  1570. voltage[ichain] = lvoltage[ichain];
  1571. temperature[ichain] = ltemperature[ichain];
  1572. }
  1573. /* the low frequency is good */
  1574. else if (frequency - lfrequency[ichain] < 1000) {
  1575. /* so is the high frequency, interpolate */
  1576. if (hfrequency[ichain] - frequency < 1000) {
  1577. correction[ichain] = lcorrection[ichain] +
  1578. (((frequency - lfrequency[ichain]) *
  1579. (hcorrection[ichain] -
  1580. lcorrection[ichain])) /
  1581. (hfrequency[ichain] - lfrequency[ichain]));
  1582. temperature[ichain] = ltemperature[ichain] +
  1583. (((frequency - lfrequency[ichain]) *
  1584. (htemperature[ichain] -
  1585. ltemperature[ichain])) /
  1586. (hfrequency[ichain] - lfrequency[ichain]));
  1587. voltage[ichain] =
  1588. lvoltage[ichain] +
  1589. (((frequency -
  1590. lfrequency[ichain]) * (hvoltage[ichain] -
  1591. lvoltage[ichain]))
  1592. / (hfrequency[ichain] -
  1593. lfrequency[ichain]));
  1594. }
  1595. /* only low is good, use it */
  1596. else {
  1597. correction[ichain] = lcorrection[ichain];
  1598. temperature[ichain] = ltemperature[ichain];
  1599. voltage[ichain] = lvoltage[ichain];
  1600. }
  1601. }
  1602. /* only high is good, use it */
  1603. else if (hfrequency[ichain] - frequency < 1000) {
  1604. correction[ichain] = hcorrection[ichain];
  1605. temperature[ichain] = htemperature[ichain];
  1606. voltage[ichain] = hvoltage[ichain];
  1607. } else { /* nothing is good, presume 0???? */
  1608. correction[ichain] = 0;
  1609. temperature[ichain] = 0;
  1610. voltage[ichain] = 0;
  1611. }
  1612. }
  1613. ar9003_hw_power_control_override(ah, frequency, correction, voltage,
  1614. temperature);
  1615. ath_print(common, ATH_DBG_EEPROM,
  1616. "for frequency=%d, calibration correction = %d %d %d\n",
  1617. frequency, correction[0], correction[1], correction[2]);
  1618. return 0;
  1619. }
  1620. static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
  1621. struct ath9k_channel *chan, u16 cfgCtl,
  1622. u8 twiceAntennaReduction,
  1623. u8 twiceMaxRegulatoryPower,
  1624. u8 powerLimit)
  1625. {
  1626. ah->txpower_limit = powerLimit;
  1627. ar9003_hw_set_target_power_eeprom(ah, chan->channel);
  1628. ar9003_hw_calibration_apply(ah, chan->channel);
  1629. }
  1630. static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
  1631. u16 i, bool is2GHz)
  1632. {
  1633. return AR_NO_SPUR;
  1634. }
  1635. s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
  1636. {
  1637. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  1638. return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
  1639. }
  1640. s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
  1641. {
  1642. struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
  1643. return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
  1644. }
  1645. const struct eeprom_ops eep_ar9300_ops = {
  1646. .check_eeprom = ath9k_hw_ar9300_check_eeprom,
  1647. .get_eeprom = ath9k_hw_ar9300_get_eeprom,
  1648. .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
  1649. .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
  1650. .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
  1651. .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
  1652. .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
  1653. .set_board_values = ath9k_hw_ar9300_set_board_values,
  1654. .set_addac = ath9k_hw_ar9300_set_addac,
  1655. .set_txpower = ath9k_hw_ar9300_set_txpower,
  1656. .get_spur_channel = ath9k_hw_ar9300_get_spur_channel
  1657. };