srom.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298
  1. /*
  2. * Copyright (c) 2010 Broadcom Corporation
  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 ANY
  11. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  13. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/string.h>
  18. #include <linux/io.h>
  19. #include <linux/etherdevice.h>
  20. #include <linux/crc8.h>
  21. #include <stdarg.h>
  22. #include <chipcommon.h>
  23. #include <brcmu_utils.h>
  24. #include "pub.h"
  25. #include "nicpci.h"
  26. #include "aiutils.h"
  27. #include "otp.h"
  28. #include "srom.h"
  29. /*
  30. * SROM CRC8 polynomial value:
  31. *
  32. * x^8 + x^7 +x^6 + x^4 + x^2 + 1
  33. */
  34. #define SROM_CRC8_POLY 0xAB
  35. /* Maximum srom: 6 Kilobits == 768 bytes */
  36. #define SROM_MAX 768
  37. /* PCI fields */
  38. #define PCI_F0DEVID 48
  39. #define SROM_WORDS 64
  40. #define SROM_SSID 2
  41. #define SROM_WL1LHMAXP 29
  42. #define SROM_WL1LPAB0 30
  43. #define SROM_WL1LPAB1 31
  44. #define SROM_WL1LPAB2 32
  45. #define SROM_WL1HPAB0 33
  46. #define SROM_WL1HPAB1 34
  47. #define SROM_WL1HPAB2 35
  48. #define SROM_MACHI_IL0 36
  49. #define SROM_MACMID_IL0 37
  50. #define SROM_MACLO_IL0 38
  51. #define SROM_MACHI_ET1 42
  52. #define SROM_MACMID_ET1 43
  53. #define SROM_MACLO_ET1 44
  54. #define SROM3_MACHI 37
  55. #define SROM3_MACMID 38
  56. #define SROM3_MACLO 39
  57. #define SROM_BXARSSI2G 40
  58. #define SROM_BXARSSI5G 41
  59. #define SROM_TRI52G 42
  60. #define SROM_TRI5GHL 43
  61. #define SROM_RXPO52G 45
  62. #define SROM_AABREV 46
  63. /* Fields in AABREV */
  64. #define SROM_BR_MASK 0x00ff
  65. #define SROM_CC_MASK 0x0f00
  66. #define SROM_CC_SHIFT 8
  67. #define SROM_AA0_MASK 0x3000
  68. #define SROM_AA0_SHIFT 12
  69. #define SROM_AA1_MASK 0xc000
  70. #define SROM_AA1_SHIFT 14
  71. #define SROM_WL0PAB0 47
  72. #define SROM_WL0PAB1 48
  73. #define SROM_WL0PAB2 49
  74. #define SROM_LEDBH10 50
  75. #define SROM_LEDBH32 51
  76. #define SROM_WL10MAXP 52
  77. #define SROM_WL1PAB0 53
  78. #define SROM_WL1PAB1 54
  79. #define SROM_WL1PAB2 55
  80. #define SROM_ITT 56
  81. #define SROM_BFL 57
  82. #define SROM_BFL2 28
  83. #define SROM3_BFL2 61
  84. #define SROM_AG10 58
  85. #define SROM_CCODE 59
  86. #define SROM_OPO 60
  87. #define SROM3_LEDDC 62
  88. #define SROM_CRCREV 63
  89. /* SROM Rev 4: Reallocate the software part of the srom to accommodate
  90. * MIMO features. It assumes up to two PCIE functions and 440 bytes
  91. * of usable srom i.e. the usable storage in chips with OTP that
  92. * implements hardware redundancy.
  93. */
  94. #define SROM4_WORDS 220
  95. #define SROM4_SIGN 32
  96. #define SROM4_SIGNATURE 0x5372
  97. #define SROM4_BREV 33
  98. #define SROM4_BFL0 34
  99. #define SROM4_BFL1 35
  100. #define SROM4_BFL2 36
  101. #define SROM4_BFL3 37
  102. #define SROM5_BFL0 37
  103. #define SROM5_BFL1 38
  104. #define SROM5_BFL2 39
  105. #define SROM5_BFL3 40
  106. #define SROM4_MACHI 38
  107. #define SROM4_MACMID 39
  108. #define SROM4_MACLO 40
  109. #define SROM5_MACHI 41
  110. #define SROM5_MACMID 42
  111. #define SROM5_MACLO 43
  112. #define SROM4_CCODE 41
  113. #define SROM4_REGREV 42
  114. #define SROM5_CCODE 34
  115. #define SROM5_REGREV 35
  116. #define SROM4_LEDBH10 43
  117. #define SROM4_LEDBH32 44
  118. #define SROM5_LEDBH10 59
  119. #define SROM5_LEDBH32 60
  120. #define SROM4_LEDDC 45
  121. #define SROM5_LEDDC 45
  122. #define SROM4_AA 46
  123. #define SROM4_AG10 47
  124. #define SROM4_AG32 48
  125. #define SROM4_TXPID2G 49
  126. #define SROM4_TXPID5G 51
  127. #define SROM4_TXPID5GL 53
  128. #define SROM4_TXPID5GH 55
  129. #define SROM4_TXRXC 61
  130. #define SROM4_TXCHAIN_MASK 0x000f
  131. #define SROM4_TXCHAIN_SHIFT 0
  132. #define SROM4_RXCHAIN_MASK 0x00f0
  133. #define SROM4_RXCHAIN_SHIFT 4
  134. #define SROM4_SWITCH_MASK 0xff00
  135. #define SROM4_SWITCH_SHIFT 8
  136. /* Per-path fields */
  137. #define MAX_PATH_SROM 4
  138. #define SROM4_PATH0 64
  139. #define SROM4_PATH1 87
  140. #define SROM4_PATH2 110
  141. #define SROM4_PATH3 133
  142. #define SROM4_2G_ITT_MAXP 0
  143. #define SROM4_2G_PA 1
  144. #define SROM4_5G_ITT_MAXP 5
  145. #define SROM4_5GLH_MAXP 6
  146. #define SROM4_5G_PA 7
  147. #define SROM4_5GL_PA 11
  148. #define SROM4_5GH_PA 15
  149. /* All the miriad power offsets */
  150. #define SROM4_2G_CCKPO 156
  151. #define SROM4_2G_OFDMPO 157
  152. #define SROM4_5G_OFDMPO 159
  153. #define SROM4_5GL_OFDMPO 161
  154. #define SROM4_5GH_OFDMPO 163
  155. #define SROM4_2G_MCSPO 165
  156. #define SROM4_5G_MCSPO 173
  157. #define SROM4_5GL_MCSPO 181
  158. #define SROM4_5GH_MCSPO 189
  159. #define SROM4_CDDPO 197
  160. #define SROM4_STBCPO 198
  161. #define SROM4_BW40PO 199
  162. #define SROM4_BWDUPPO 200
  163. #define SROM4_CRCREV 219
  164. /* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6.
  165. * This is acombined srom for both MIMO and SISO boards, usable in
  166. * the .130 4Kilobit OTP with hardware redundancy.
  167. */
  168. #define SROM8_BREV 65
  169. #define SROM8_BFL0 66
  170. #define SROM8_BFL1 67
  171. #define SROM8_BFL2 68
  172. #define SROM8_BFL3 69
  173. #define SROM8_MACHI 70
  174. #define SROM8_MACMID 71
  175. #define SROM8_MACLO 72
  176. #define SROM8_CCODE 73
  177. #define SROM8_REGREV 74
  178. #define SROM8_LEDBH10 75
  179. #define SROM8_LEDBH32 76
  180. #define SROM8_LEDDC 77
  181. #define SROM8_AA 78
  182. #define SROM8_AG10 79
  183. #define SROM8_AG32 80
  184. #define SROM8_TXRXC 81
  185. #define SROM8_BXARSSI2G 82
  186. #define SROM8_BXARSSI5G 83
  187. #define SROM8_TRI52G 84
  188. #define SROM8_TRI5GHL 85
  189. #define SROM8_RXPO52G 86
  190. #define SROM8_FEM2G 87
  191. #define SROM8_FEM5G 88
  192. #define SROM8_FEM_ANTSWLUT_MASK 0xf800
  193. #define SROM8_FEM_ANTSWLUT_SHIFT 11
  194. #define SROM8_FEM_TR_ISO_MASK 0x0700
  195. #define SROM8_FEM_TR_ISO_SHIFT 8
  196. #define SROM8_FEM_PDET_RANGE_MASK 0x00f8
  197. #define SROM8_FEM_PDET_RANGE_SHIFT 3
  198. #define SROM8_FEM_EXTPA_GAIN_MASK 0x0006
  199. #define SROM8_FEM_EXTPA_GAIN_SHIFT 1
  200. #define SROM8_FEM_TSSIPOS_MASK 0x0001
  201. #define SROM8_FEM_TSSIPOS_SHIFT 0
  202. #define SROM8_THERMAL 89
  203. /* Temp sense related entries */
  204. #define SROM8_MPWR_RAWTS 90
  205. #define SROM8_TS_SLP_OPT_CORRX 91
  206. /* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable,
  207. * IQSWP: IQ CAL swap disable */
  208. #define SROM8_FOC_HWIQ_IQSWP 92
  209. /* Temperature delta for PHY calibration */
  210. #define SROM8_PHYCAL_TEMPDELTA 93
  211. /* Per-path offsets & fields */
  212. #define SROM8_PATH0 96
  213. #define SROM8_PATH1 112
  214. #define SROM8_PATH2 128
  215. #define SROM8_PATH3 144
  216. #define SROM8_2G_ITT_MAXP 0
  217. #define SROM8_2G_PA 1
  218. #define SROM8_5G_ITT_MAXP 4
  219. #define SROM8_5GLH_MAXP 5
  220. #define SROM8_5G_PA 6
  221. #define SROM8_5GL_PA 9
  222. #define SROM8_5GH_PA 12
  223. /* All the miriad power offsets */
  224. #define SROM8_2G_CCKPO 160
  225. #define SROM8_2G_OFDMPO 161
  226. #define SROM8_5G_OFDMPO 163
  227. #define SROM8_5GL_OFDMPO 165
  228. #define SROM8_5GH_OFDMPO 167
  229. #define SROM8_2G_MCSPO 169
  230. #define SROM8_5G_MCSPO 177
  231. #define SROM8_5GL_MCSPO 185
  232. #define SROM8_5GH_MCSPO 193
  233. #define SROM8_CDDPO 201
  234. #define SROM8_STBCPO 202
  235. #define SROM8_BW40PO 203
  236. #define SROM8_BWDUPPO 204
  237. /* SISO PA parameters are in the path0 spaces */
  238. #define SROM8_SISO 96
  239. /* Legacy names for SISO PA paramters */
  240. #define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP)
  241. #define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA)
  242. #define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1)
  243. #define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2)
  244. #define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP)
  245. #define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP)
  246. #define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA)
  247. #define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1)
  248. #define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2)
  249. #define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA)
  250. #define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1)
  251. #define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2)
  252. #define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA)
  253. #define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1)
  254. #define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2)
  255. /* SROM REV 9 */
  256. #define SROM9_2GPO_CCKBW20 160
  257. #define SROM9_2GPO_CCKBW20UL 161
  258. #define SROM9_2GPO_LOFDMBW20 162
  259. #define SROM9_2GPO_LOFDMBW20UL 164
  260. #define SROM9_5GLPO_LOFDMBW20 166
  261. #define SROM9_5GLPO_LOFDMBW20UL 168
  262. #define SROM9_5GMPO_LOFDMBW20 170
  263. #define SROM9_5GMPO_LOFDMBW20UL 172
  264. #define SROM9_5GHPO_LOFDMBW20 174
  265. #define SROM9_5GHPO_LOFDMBW20UL 176
  266. #define SROM9_2GPO_MCSBW20 178
  267. #define SROM9_2GPO_MCSBW20UL 180
  268. #define SROM9_2GPO_MCSBW40 182
  269. #define SROM9_5GLPO_MCSBW20 184
  270. #define SROM9_5GLPO_MCSBW20UL 186
  271. #define SROM9_5GLPO_MCSBW40 188
  272. #define SROM9_5GMPO_MCSBW20 190
  273. #define SROM9_5GMPO_MCSBW20UL 192
  274. #define SROM9_5GMPO_MCSBW40 194
  275. #define SROM9_5GHPO_MCSBW20 196
  276. #define SROM9_5GHPO_MCSBW20UL 198
  277. #define SROM9_5GHPO_MCSBW40 200
  278. #define SROM9_PO_MCS32 202
  279. #define SROM9_PO_LOFDM40DUP 203
  280. /* SROM flags (see sromvar_t) */
  281. /* value continues as described by the next entry */
  282. #define SRFL_MORE 1
  283. #define SRFL_NOFFS 2 /* value bits can't be all one's */
  284. #define SRFL_PRHEX 4 /* value is in hexdecimal format */
  285. #define SRFL_PRSIGN 8 /* value is in signed decimal format */
  286. #define SRFL_CCODE 0x10 /* value is in country code format */
  287. #define SRFL_ETHADDR 0x20 /* value is an Ethernet address */
  288. #define SRFL_LEDDC 0x40 /* value is an LED duty cycle */
  289. /* do not generate a nvram param, entry is for mfgc */
  290. #define SRFL_NOVAR 0x80
  291. /* Max. nvram variable table size */
  292. #define MAXSZ_NVRAM_VARS 4096
  293. /*
  294. * indicates type of value.
  295. */
  296. enum brcms_srom_var_type {
  297. BRCMS_SROM_STRING,
  298. BRCMS_SROM_SNUMBER,
  299. BRCMS_SROM_UNUMBER
  300. };
  301. /*
  302. * storage type for srom variable.
  303. *
  304. * var_list: for linked list operations.
  305. * varid: identifier of the variable.
  306. * var_type: type of variable.
  307. * buf: variable value when var_type == BRCMS_SROM_STRING.
  308. * uval: unsigned variable value when var_type == BRCMS_SROM_UNUMBER.
  309. * sval: signed variable value when var_type == BRCMS_SROM_SNUMBER.
  310. */
  311. struct brcms_srom_list_head {
  312. struct list_head var_list;
  313. enum brcms_srom_id varid;
  314. enum brcms_srom_var_type var_type;
  315. union {
  316. char buf[0];
  317. u32 uval;
  318. s32 sval;
  319. };
  320. };
  321. struct brcms_sromvar {
  322. enum brcms_srom_id varid;
  323. u32 revmask;
  324. u32 flags;
  325. u16 off;
  326. u16 mask;
  327. };
  328. struct brcms_varbuf {
  329. char *base; /* pointer to buffer base */
  330. char *buf; /* pointer to current position */
  331. unsigned int size; /* current (residual) size in bytes */
  332. };
  333. /*
  334. * Assumptions:
  335. * - Ethernet address spans across 3 consecutive words
  336. *
  337. * Table rules:
  338. * - Add multiple entries next to each other if a value spans across multiple
  339. * words (even multiple fields in the same word) with each entry except the
  340. * last having it's SRFL_MORE bit set.
  341. * - Ethernet address entry does not follow above rule and must not have
  342. * SRFL_MORE bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
  343. * - The last entry's name field must be NULL to indicate the end of the table.
  344. * Other entries must have non-NULL name.
  345. */
  346. static const struct brcms_sromvar pci_sromvars[] = {
  347. {BRCMS_SROM_DEVID, 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID,
  348. 0xffff},
  349. {BRCMS_SROM_BOARDREV, 0x0000000e, SRFL_PRHEX, SROM_AABREV,
  350. SROM_BR_MASK},
  351. {BRCMS_SROM_BOARDREV, 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff},
  352. {BRCMS_SROM_BOARDREV, 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
  353. {BRCMS_SROM_BOARDFLAGS, 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff},
  354. {BRCMS_SROM_BOARDFLAGS, 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL,
  355. 0xffff},
  356. {BRCMS_SROM_CONT, 0, 0, SROM_BFL2, 0xffff},
  357. {BRCMS_SROM_BOARDFLAGS, 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL,
  358. 0xffff},
  359. {BRCMS_SROM_CONT, 0, 0, SROM3_BFL2, 0xffff},
  360. {BRCMS_SROM_BOARDFLAGS, 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0,
  361. 0xffff},
  362. {BRCMS_SROM_CONT, 0, 0, SROM4_BFL1, 0xffff},
  363. {BRCMS_SROM_BOARDFLAGS, 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0,
  364. 0xffff},
  365. {BRCMS_SROM_CONT, 0, 0, SROM5_BFL1, 0xffff},
  366. {BRCMS_SROM_BOARDFLAGS, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0,
  367. 0xffff},
  368. {BRCMS_SROM_CONT, 0, 0, SROM8_BFL1, 0xffff},
  369. {BRCMS_SROM_BOARDFLAGS2, 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2,
  370. 0xffff},
  371. {BRCMS_SROM_CONT, 0, 0, SROM4_BFL3, 0xffff},
  372. {BRCMS_SROM_BOARDFLAGS2, 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2,
  373. 0xffff},
  374. {BRCMS_SROM_CONT, 0, 0, SROM5_BFL3, 0xffff},
  375. {BRCMS_SROM_BOARDFLAGS2, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2,
  376. 0xffff},
  377. {BRCMS_SROM_CONT, 0, 0, SROM8_BFL3, 0xffff},
  378. {BRCMS_SROM_BOARDTYPE, 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
  379. {BRCMS_SROM_BOARDNUM, 0x00000006, 0, SROM_MACLO_IL0, 0xffff},
  380. {BRCMS_SROM_BOARDNUM, 0x00000008, 0, SROM3_MACLO, 0xffff},
  381. {BRCMS_SROM_BOARDNUM, 0x00000010, 0, SROM4_MACLO, 0xffff},
  382. {BRCMS_SROM_BOARDNUM, 0x000000e0, 0, SROM5_MACLO, 0xffff},
  383. {BRCMS_SROM_BOARDNUM, 0xffffff00, 0, SROM8_MACLO, 0xffff},
  384. {BRCMS_SROM_CC, 0x00000002, 0, SROM_AABREV, SROM_CC_MASK},
  385. {BRCMS_SROM_REGREV, 0x00000008, 0, SROM_OPO, 0xff00},
  386. {BRCMS_SROM_REGREV, 0x00000010, 0, SROM4_REGREV, 0x00ff},
  387. {BRCMS_SROM_REGREV, 0x000000e0, 0, SROM5_REGREV, 0x00ff},
  388. {BRCMS_SROM_REGREV, 0xffffff00, 0, SROM8_REGREV, 0x00ff},
  389. {BRCMS_SROM_LEDBH0, 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff},
  390. {BRCMS_SROM_LEDBH1, 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00},
  391. {BRCMS_SROM_LEDBH2, 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff},
  392. {BRCMS_SROM_LEDBH3, 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00},
  393. {BRCMS_SROM_LEDBH0, 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff},
  394. {BRCMS_SROM_LEDBH1, 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00},
  395. {BRCMS_SROM_LEDBH2, 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff},
  396. {BRCMS_SROM_LEDBH3, 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00},
  397. {BRCMS_SROM_LEDBH0, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff},
  398. {BRCMS_SROM_LEDBH1, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00},
  399. {BRCMS_SROM_LEDBH2, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff},
  400. {BRCMS_SROM_LEDBH3, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00},
  401. {BRCMS_SROM_LEDBH0, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
  402. {BRCMS_SROM_LEDBH1, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
  403. {BRCMS_SROM_LEDBH2, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
  404. {BRCMS_SROM_LEDBH3, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
  405. {BRCMS_SROM_PA0B0, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff},
  406. {BRCMS_SROM_PA0B1, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff},
  407. {BRCMS_SROM_PA0B2, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff},
  408. {BRCMS_SROM_PA0ITSSIT, 0x0000000e, 0, SROM_ITT, 0x00ff},
  409. {BRCMS_SROM_PA0MAXPWR, 0x0000000e, 0, SROM_WL10MAXP, 0x00ff},
  410. {BRCMS_SROM_PA0B0, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
  411. {BRCMS_SROM_PA0B1, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
  412. {BRCMS_SROM_PA0B2, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
  413. {BRCMS_SROM_PA0ITSSIT, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
  414. {BRCMS_SROM_PA0MAXPWR, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
  415. {BRCMS_SROM_OPO, 0x0000000c, 0, SROM_OPO, 0x00ff},
  416. {BRCMS_SROM_OPO, 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
  417. {BRCMS_SROM_AA2G, 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK},
  418. {BRCMS_SROM_AA2G, 0x000000f0, 0, SROM4_AA, 0x00ff},
  419. {BRCMS_SROM_AA2G, 0xffffff00, 0, SROM8_AA, 0x00ff},
  420. {BRCMS_SROM_AA5G, 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK},
  421. {BRCMS_SROM_AA5G, 0x000000f0, 0, SROM4_AA, 0xff00},
  422. {BRCMS_SROM_AA5G, 0xffffff00, 0, SROM8_AA, 0xff00},
  423. {BRCMS_SROM_AG0, 0x0000000e, 0, SROM_AG10, 0x00ff},
  424. {BRCMS_SROM_AG1, 0x0000000e, 0, SROM_AG10, 0xff00},
  425. {BRCMS_SROM_AG0, 0x000000f0, 0, SROM4_AG10, 0x00ff},
  426. {BRCMS_SROM_AG1, 0x000000f0, 0, SROM4_AG10, 0xff00},
  427. {BRCMS_SROM_AG2, 0x000000f0, 0, SROM4_AG32, 0x00ff},
  428. {BRCMS_SROM_AG3, 0x000000f0, 0, SROM4_AG32, 0xff00},
  429. {BRCMS_SROM_AG0, 0xffffff00, 0, SROM8_AG10, 0x00ff},
  430. {BRCMS_SROM_AG1, 0xffffff00, 0, SROM8_AG10, 0xff00},
  431. {BRCMS_SROM_AG2, 0xffffff00, 0, SROM8_AG32, 0x00ff},
  432. {BRCMS_SROM_AG3, 0xffffff00, 0, SROM8_AG32, 0xff00},
  433. {BRCMS_SROM_PA1B0, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff},
  434. {BRCMS_SROM_PA1B1, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff},
  435. {BRCMS_SROM_PA1B2, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff},
  436. {BRCMS_SROM_PA1LOB0, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff},
  437. {BRCMS_SROM_PA1LOB1, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff},
  438. {BRCMS_SROM_PA1LOB2, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff},
  439. {BRCMS_SROM_PA1HIB0, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff},
  440. {BRCMS_SROM_PA1HIB1, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff},
  441. {BRCMS_SROM_PA1HIB2, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff},
  442. {BRCMS_SROM_PA1ITSSIT, 0x0000000e, 0, SROM_ITT, 0xff00},
  443. {BRCMS_SROM_PA1MAXPWR, 0x0000000e, 0, SROM_WL10MAXP, 0xff00},
  444. {BRCMS_SROM_PA1LOMAXPWR, 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00},
  445. {BRCMS_SROM_PA1HIMAXPWR, 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff},
  446. {BRCMS_SROM_PA1B0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
  447. {BRCMS_SROM_PA1B1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
  448. {BRCMS_SROM_PA1B2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
  449. {BRCMS_SROM_PA1LOB0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
  450. {BRCMS_SROM_PA1LOB1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
  451. {BRCMS_SROM_PA1LOB2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
  452. {BRCMS_SROM_PA1HIB0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
  453. {BRCMS_SROM_PA1HIB1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
  454. {BRCMS_SROM_PA1HIB2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
  455. {BRCMS_SROM_PA1ITSSIT, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
  456. {BRCMS_SROM_PA1MAXPWR, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
  457. {BRCMS_SROM_PA1LOMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
  458. {BRCMS_SROM_PA1HIMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
  459. {BRCMS_SROM_BXA2G, 0x00000008, 0, SROM_BXARSSI2G, 0x1800},
  460. {BRCMS_SROM_RSSISAV2G, 0x00000008, 0, SROM_BXARSSI2G, 0x0700},
  461. {BRCMS_SROM_RSSISMC2G, 0x00000008, 0, SROM_BXARSSI2G, 0x00f0},
  462. {BRCMS_SROM_RSSISMF2G, 0x00000008, 0, SROM_BXARSSI2G, 0x000f},
  463. {BRCMS_SROM_BXA2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
  464. {BRCMS_SROM_RSSISAV2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
  465. {BRCMS_SROM_RSSISMC2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
  466. {BRCMS_SROM_RSSISMF2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
  467. {BRCMS_SROM_BXA5G, 0x00000008, 0, SROM_BXARSSI5G, 0x1800},
  468. {BRCMS_SROM_RSSISAV5G, 0x00000008, 0, SROM_BXARSSI5G, 0x0700},
  469. {BRCMS_SROM_RSSISMC5G, 0x00000008, 0, SROM_BXARSSI5G, 0x00f0},
  470. {BRCMS_SROM_RSSISMF5G, 0x00000008, 0, SROM_BXARSSI5G, 0x000f},
  471. {BRCMS_SROM_BXA5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
  472. {BRCMS_SROM_RSSISAV5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
  473. {BRCMS_SROM_RSSISMC5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
  474. {BRCMS_SROM_RSSISMF5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
  475. {BRCMS_SROM_TRI2G, 0x00000008, 0, SROM_TRI52G, 0x00ff},
  476. {BRCMS_SROM_TRI5G, 0x00000008, 0, SROM_TRI52G, 0xff00},
  477. {BRCMS_SROM_TRI5GL, 0x00000008, 0, SROM_TRI5GHL, 0x00ff},
  478. {BRCMS_SROM_TRI5GH, 0x00000008, 0, SROM_TRI5GHL, 0xff00},
  479. {BRCMS_SROM_TRI2G, 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
  480. {BRCMS_SROM_TRI5G, 0xffffff00, 0, SROM8_TRI52G, 0xff00},
  481. {BRCMS_SROM_TRI5GL, 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
  482. {BRCMS_SROM_TRI5GH, 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
  483. {BRCMS_SROM_RXPO2G, 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff},
  484. {BRCMS_SROM_RXPO5G, 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00},
  485. {BRCMS_SROM_RXPO2G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
  486. {BRCMS_SROM_RXPO5G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
  487. {BRCMS_SROM_TXCHAIN, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC,
  488. SROM4_TXCHAIN_MASK},
  489. {BRCMS_SROM_RXCHAIN, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC,
  490. SROM4_RXCHAIN_MASK},
  491. {BRCMS_SROM_ANTSWITCH, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC,
  492. SROM4_SWITCH_MASK},
  493. {BRCMS_SROM_TXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
  494. SROM4_TXCHAIN_MASK},
  495. {BRCMS_SROM_RXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
  496. SROM4_RXCHAIN_MASK},
  497. {BRCMS_SROM_ANTSWITCH, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC,
  498. SROM4_SWITCH_MASK},
  499. {BRCMS_SROM_TSSIPOS2G, 0xffffff00, 0, SROM8_FEM2G,
  500. SROM8_FEM_TSSIPOS_MASK},
  501. {BRCMS_SROM_EXTPAGAIN2G, 0xffffff00, 0, SROM8_FEM2G,
  502. SROM8_FEM_EXTPA_GAIN_MASK},
  503. {BRCMS_SROM_PDETRANGE2G, 0xffffff00, 0, SROM8_FEM2G,
  504. SROM8_FEM_PDET_RANGE_MASK},
  505. {BRCMS_SROM_TRISO2G, 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
  506. {BRCMS_SROM_ANTSWCTL2G, 0xffffff00, 0, SROM8_FEM2G,
  507. SROM8_FEM_ANTSWLUT_MASK},
  508. {BRCMS_SROM_TSSIPOS5G, 0xffffff00, 0, SROM8_FEM5G,
  509. SROM8_FEM_TSSIPOS_MASK},
  510. {BRCMS_SROM_EXTPAGAIN5G, 0xffffff00, 0, SROM8_FEM5G,
  511. SROM8_FEM_EXTPA_GAIN_MASK},
  512. {BRCMS_SROM_PDETRANGE5G, 0xffffff00, 0, SROM8_FEM5G,
  513. SROM8_FEM_PDET_RANGE_MASK},
  514. {BRCMS_SROM_TRISO5G, 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
  515. {BRCMS_SROM_ANTSWCTL5G, 0xffffff00, 0, SROM8_FEM5G,
  516. SROM8_FEM_ANTSWLUT_MASK},
  517. {BRCMS_SROM_TEMPTHRESH, 0xffffff00, 0, SROM8_THERMAL, 0xff00},
  518. {BRCMS_SROM_TEMPOFFSET, 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
  519. {BRCMS_SROM_TXPID2GA0, 0x000000f0, 0, SROM4_TXPID2G, 0x00ff},
  520. {BRCMS_SROM_TXPID2GA1, 0x000000f0, 0, SROM4_TXPID2G, 0xff00},
  521. {BRCMS_SROM_TXPID2GA2, 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff},
  522. {BRCMS_SROM_TXPID2GA3, 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00},
  523. {BRCMS_SROM_TXPID5GA0, 0x000000f0, 0, SROM4_TXPID5G, 0x00ff},
  524. {BRCMS_SROM_TXPID5GA1, 0x000000f0, 0, SROM4_TXPID5G, 0xff00},
  525. {BRCMS_SROM_TXPID5GA2, 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff},
  526. {BRCMS_SROM_TXPID5GA3, 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00},
  527. {BRCMS_SROM_TXPID5GLA0, 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff},
  528. {BRCMS_SROM_TXPID5GLA1, 0x000000f0, 0, SROM4_TXPID5GL, 0xff00},
  529. {BRCMS_SROM_TXPID5GLA2, 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff},
  530. {BRCMS_SROM_TXPID5GLA3, 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00},
  531. {BRCMS_SROM_TXPID5GHA0, 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff},
  532. {BRCMS_SROM_TXPID5GHA1, 0x000000f0, 0, SROM4_TXPID5GH, 0xff00},
  533. {BRCMS_SROM_TXPID5GHA2, 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff},
  534. {BRCMS_SROM_TXPID5GHA3, 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00},
  535. {BRCMS_SROM_CCODE, 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff},
  536. {BRCMS_SROM_CCODE, 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff},
  537. {BRCMS_SROM_CCODE, 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff},
  538. {BRCMS_SROM_CCODE, 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
  539. {BRCMS_SROM_MACADDR, 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
  540. {BRCMS_SROM_MACADDR, 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff},
  541. {BRCMS_SROM_MACADDR, 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff},
  542. {BRCMS_SROM_MACADDR, 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff},
  543. {BRCMS_SROM_IL0MACADDR, 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0,
  544. 0xffff},
  545. {BRCMS_SROM_ET1MACADDR, 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1,
  546. 0xffff},
  547. {BRCMS_SROM_LEDDC, 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC,
  548. 0xffff},
  549. {BRCMS_SROM_LEDDC, 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC,
  550. 0xffff},
  551. {BRCMS_SROM_LEDDC, 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC,
  552. 0xffff},
  553. {BRCMS_SROM_LEDDC, 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC,
  554. 0xffff},
  555. {BRCMS_SROM_RAWTEMPSENSE, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS,
  556. 0x01ff},
  557. {BRCMS_SROM_MEASPOWER, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS,
  558. 0xfe00},
  559. {BRCMS_SROM_TEMPSENSE_SLOPE, 0xffffff00, SRFL_PRHEX,
  560. SROM8_TS_SLP_OPT_CORRX, 0x00ff},
  561. {BRCMS_SROM_TEMPCORRX, 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
  562. 0xfc00},
  563. {BRCMS_SROM_TEMPSENSE_OPTION, 0xffffff00, SRFL_PRHEX,
  564. SROM8_TS_SLP_OPT_CORRX, 0x0300},
  565. {BRCMS_SROM_FREQOFFSET_CORR, 0xffffff00, SRFL_PRHEX,
  566. SROM8_FOC_HWIQ_IQSWP, 0x000f},
  567. {BRCMS_SROM_IQCAL_SWP_DIS, 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
  568. 0x0010},
  569. {BRCMS_SROM_HW_IQCAL_EN, 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
  570. 0x0020},
  571. {BRCMS_SROM_PHYCAL_TEMPDELTA, 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA,
  572. 0x00ff},
  573. {BRCMS_SROM_CCK2GPO, 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff},
  574. {BRCMS_SROM_CCK2GPO, 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
  575. {BRCMS_SROM_OFDM2GPO, 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff},
  576. {BRCMS_SROM_CONT, 0, 0, SROM4_2G_OFDMPO + 1, 0xffff},
  577. {BRCMS_SROM_OFDM5GPO, 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff},
  578. {BRCMS_SROM_CONT, 0, 0, SROM4_5G_OFDMPO + 1, 0xffff},
  579. {BRCMS_SROM_OFDM5GLPO, 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff},
  580. {BRCMS_SROM_CONT, 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff},
  581. {BRCMS_SROM_OFDM5GHPO, 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff},
  582. {BRCMS_SROM_CONT, 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff},
  583. {BRCMS_SROM_OFDM2GPO, 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
  584. {BRCMS_SROM_CONT, 0, 0, SROM8_2G_OFDMPO + 1, 0xffff},
  585. {BRCMS_SROM_OFDM5GPO, 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
  586. {BRCMS_SROM_CONT, 0, 0, SROM8_5G_OFDMPO + 1, 0xffff},
  587. {BRCMS_SROM_OFDM5GLPO, 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
  588. {BRCMS_SROM_CONT, 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff},
  589. {BRCMS_SROM_OFDM5GHPO, 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
  590. {BRCMS_SROM_CONT, 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff},
  591. {BRCMS_SROM_MCS2GPO0, 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff},
  592. {BRCMS_SROM_MCS2GPO1, 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff},
  593. {BRCMS_SROM_MCS2GPO2, 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff},
  594. {BRCMS_SROM_MCS2GPO3, 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff},
  595. {BRCMS_SROM_MCS2GPO4, 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff},
  596. {BRCMS_SROM_MCS2GPO5, 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff},
  597. {BRCMS_SROM_MCS2GPO6, 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff},
  598. {BRCMS_SROM_MCS2GPO7, 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff},
  599. {BRCMS_SROM_MCS5GPO0, 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff},
  600. {BRCMS_SROM_MCS5GPO1, 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff},
  601. {BRCMS_SROM_MCS5GPO2, 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff},
  602. {BRCMS_SROM_MCS5GPO3, 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff},
  603. {BRCMS_SROM_MCS5GPO4, 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff},
  604. {BRCMS_SROM_MCS5GPO5, 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff},
  605. {BRCMS_SROM_MCS5GPO6, 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff},
  606. {BRCMS_SROM_MCS5GPO7, 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff},
  607. {BRCMS_SROM_MCS5GLPO0, 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff},
  608. {BRCMS_SROM_MCS5GLPO1, 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff},
  609. {BRCMS_SROM_MCS5GLPO2, 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff},
  610. {BRCMS_SROM_MCS5GLPO3, 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff},
  611. {BRCMS_SROM_MCS5GLPO4, 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff},
  612. {BRCMS_SROM_MCS5GLPO5, 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff},
  613. {BRCMS_SROM_MCS5GLPO6, 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff},
  614. {BRCMS_SROM_MCS5GLPO7, 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff},
  615. {BRCMS_SROM_MCS5GHPO0, 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff},
  616. {BRCMS_SROM_MCS5GHPO1, 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff},
  617. {BRCMS_SROM_MCS5GHPO2, 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff},
  618. {BRCMS_SROM_MCS5GHPO3, 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff},
  619. {BRCMS_SROM_MCS5GHPO4, 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff},
  620. {BRCMS_SROM_MCS5GHPO5, 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff},
  621. {BRCMS_SROM_MCS5GHPO6, 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff},
  622. {BRCMS_SROM_MCS5GHPO7, 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff},
  623. {BRCMS_SROM_MCS2GPO0, 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
  624. {BRCMS_SROM_MCS2GPO1, 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff},
  625. {BRCMS_SROM_MCS2GPO2, 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff},
  626. {BRCMS_SROM_MCS2GPO3, 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff},
  627. {BRCMS_SROM_MCS2GPO4, 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff},
  628. {BRCMS_SROM_MCS2GPO5, 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff},
  629. {BRCMS_SROM_MCS2GPO6, 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff},
  630. {BRCMS_SROM_MCS2GPO7, 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff},
  631. {BRCMS_SROM_MCS5GPO0, 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
  632. {BRCMS_SROM_MCS5GPO1, 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff},
  633. {BRCMS_SROM_MCS5GPO2, 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff},
  634. {BRCMS_SROM_MCS5GPO3, 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff},
  635. {BRCMS_SROM_MCS5GPO4, 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff},
  636. {BRCMS_SROM_MCS5GPO5, 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff},
  637. {BRCMS_SROM_MCS5GPO6, 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff},
  638. {BRCMS_SROM_MCS5GPO7, 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff},
  639. {BRCMS_SROM_MCS5GLPO0, 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
  640. {BRCMS_SROM_MCS5GLPO1, 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff},
  641. {BRCMS_SROM_MCS5GLPO2, 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff},
  642. {BRCMS_SROM_MCS5GLPO3, 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff},
  643. {BRCMS_SROM_MCS5GLPO4, 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff},
  644. {BRCMS_SROM_MCS5GLPO5, 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff},
  645. {BRCMS_SROM_MCS5GLPO6, 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff},
  646. {BRCMS_SROM_MCS5GLPO7, 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff},
  647. {BRCMS_SROM_MCS5GHPO0, 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
  648. {BRCMS_SROM_MCS5GHPO1, 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff},
  649. {BRCMS_SROM_MCS5GHPO2, 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff},
  650. {BRCMS_SROM_MCS5GHPO3, 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff},
  651. {BRCMS_SROM_MCS5GHPO4, 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff},
  652. {BRCMS_SROM_MCS5GHPO5, 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff},
  653. {BRCMS_SROM_MCS5GHPO6, 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff},
  654. {BRCMS_SROM_MCS5GHPO7, 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff},
  655. {BRCMS_SROM_CDDPO, 0x000000f0, 0, SROM4_CDDPO, 0xffff},
  656. {BRCMS_SROM_STBCPO, 0x000000f0, 0, SROM4_STBCPO, 0xffff},
  657. {BRCMS_SROM_BW40PO, 0x000000f0, 0, SROM4_BW40PO, 0xffff},
  658. {BRCMS_SROM_BWDUPPO, 0x000000f0, 0, SROM4_BWDUPPO, 0xffff},
  659. {BRCMS_SROM_CDDPO, 0x00000100, 0, SROM8_CDDPO, 0xffff},
  660. {BRCMS_SROM_STBCPO, 0x00000100, 0, SROM8_STBCPO, 0xffff},
  661. {BRCMS_SROM_BW40PO, 0x00000100, 0, SROM8_BW40PO, 0xffff},
  662. {BRCMS_SROM_BWDUPPO, 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
  663. /* power per rate from sromrev 9 */
  664. {BRCMS_SROM_CCKBW202GPO, 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
  665. {BRCMS_SROM_CCKBW20UL2GPO, 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
  666. {BRCMS_SROM_LEGOFDMBW202GPO, 0xfffffe00, SRFL_MORE,
  667. SROM9_2GPO_LOFDMBW20, 0xffff},
  668. {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff},
  669. {BRCMS_SROM_LEGOFDMBW20UL2GPO, 0xfffffe00, SRFL_MORE,
  670. SROM9_2GPO_LOFDMBW20UL, 0xffff},
  671. {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff},
  672. {BRCMS_SROM_LEGOFDMBW205GLPO, 0xfffffe00, SRFL_MORE,
  673. SROM9_5GLPO_LOFDMBW20, 0xffff},
  674. {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff},
  675. {BRCMS_SROM_LEGOFDMBW20UL5GLPO, 0xfffffe00, SRFL_MORE,
  676. SROM9_5GLPO_LOFDMBW20UL, 0xffff},
  677. {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff},
  678. {BRCMS_SROM_LEGOFDMBW205GMPO, 0xfffffe00, SRFL_MORE,
  679. SROM9_5GMPO_LOFDMBW20, 0xffff},
  680. {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff},
  681. {BRCMS_SROM_LEGOFDMBW20UL5GMPO, 0xfffffe00, SRFL_MORE,
  682. SROM9_5GMPO_LOFDMBW20UL, 0xffff},
  683. {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff},
  684. {BRCMS_SROM_LEGOFDMBW205GHPO, 0xfffffe00, SRFL_MORE,
  685. SROM9_5GHPO_LOFDMBW20, 0xffff},
  686. {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff},
  687. {BRCMS_SROM_LEGOFDMBW20UL5GHPO, 0xfffffe00, SRFL_MORE,
  688. SROM9_5GHPO_LOFDMBW20UL, 0xffff},
  689. {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff},
  690. {BRCMS_SROM_MCSBW202GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20,
  691. 0xffff},
  692. {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff},
  693. {BRCMS_SROM_MCSBW20UL2GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL,
  694. 0xffff},
  695. {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff},
  696. {BRCMS_SROM_MCSBW402GPO, 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40,
  697. 0xffff},
  698. {BRCMS_SROM_CONT, 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff},
  699. {BRCMS_SROM_MCSBW205GLPO, 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20,
  700. 0xffff},
  701. {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff},
  702. {BRCMS_SROM_MCSBW20UL5GLPO, 0xfffffe00, SRFL_MORE,
  703. SROM9_5GLPO_MCSBW20UL, 0xffff},
  704. {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff},
  705. {BRCMS_SROM_MCSBW405GLPO, 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40,
  706. 0xffff},
  707. {BRCMS_SROM_CONT, 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff},
  708. {BRCMS_SROM_MCSBW205GMPO, 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20,
  709. 0xffff},
  710. {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff},
  711. {BRCMS_SROM_MCSBW20UL5GMPO, 0xfffffe00, SRFL_MORE,
  712. SROM9_5GMPO_MCSBW20UL, 0xffff},
  713. {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff},
  714. {BRCMS_SROM_MCSBW405GMPO, 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40,
  715. 0xffff},
  716. {BRCMS_SROM_CONT, 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff},
  717. {BRCMS_SROM_MCSBW205GHPO, 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20,
  718. 0xffff},
  719. {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff},
  720. {BRCMS_SROM_MCSBW20UL5GHPO, 0xfffffe00, SRFL_MORE,
  721. SROM9_5GHPO_MCSBW20UL, 0xffff},
  722. {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff},
  723. {BRCMS_SROM_MCSBW405GHPO, 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40,
  724. 0xffff},
  725. {BRCMS_SROM_CONT, 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff},
  726. {BRCMS_SROM_MCS32PO, 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
  727. {BRCMS_SROM_LEGOFDM40DUPPO, 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
  728. {BRCMS_SROM_NULL, 0, 0, 0, 0}
  729. };
  730. static const struct brcms_sromvar perpath_pci_sromvars[] = {
  731. {BRCMS_SROM_MAXP2GA0, 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff},
  732. {BRCMS_SROM_ITT2GA0, 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00},
  733. {BRCMS_SROM_ITT5GA0, 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00},
  734. {BRCMS_SROM_PA2GW0A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff},
  735. {BRCMS_SROM_PA2GW1A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff},
  736. {BRCMS_SROM_PA2GW2A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff},
  737. {BRCMS_SROM_PA2GW3A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff},
  738. {BRCMS_SROM_MAXP5GA0, 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff},
  739. {BRCMS_SROM_MAXP5GHA0, 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff},
  740. {BRCMS_SROM_MAXP5GLA0, 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00},
  741. {BRCMS_SROM_PA5GW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff},
  742. {BRCMS_SROM_PA5GW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff},
  743. {BRCMS_SROM_PA5GW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff},
  744. {BRCMS_SROM_PA5GW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff},
  745. {BRCMS_SROM_PA5GLW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff},
  746. {BRCMS_SROM_PA5GLW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1,
  747. 0xffff},
  748. {BRCMS_SROM_PA5GLW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2,
  749. 0xffff},
  750. {BRCMS_SROM_PA5GLW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3,
  751. 0xffff},
  752. {BRCMS_SROM_PA5GHW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff},
  753. {BRCMS_SROM_PA5GHW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1,
  754. 0xffff},
  755. {BRCMS_SROM_PA5GHW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2,
  756. 0xffff},
  757. {BRCMS_SROM_PA5GHW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3,
  758. 0xffff},
  759. {BRCMS_SROM_MAXP2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
  760. {BRCMS_SROM_ITT2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
  761. {BRCMS_SROM_ITT5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
  762. {BRCMS_SROM_PA2GW0A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
  763. {BRCMS_SROM_PA2GW1A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff},
  764. {BRCMS_SROM_PA2GW2A0, 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff},
  765. {BRCMS_SROM_MAXP5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
  766. {BRCMS_SROM_MAXP5GHA0, 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
  767. {BRCMS_SROM_MAXP5GLA0, 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
  768. {BRCMS_SROM_PA5GW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
  769. {BRCMS_SROM_PA5GW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff},
  770. {BRCMS_SROM_PA5GW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff},
  771. {BRCMS_SROM_PA5GLW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
  772. {BRCMS_SROM_PA5GLW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1,
  773. 0xffff},
  774. {BRCMS_SROM_PA5GLW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2,
  775. 0xffff},
  776. {BRCMS_SROM_PA5GHW0A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
  777. {BRCMS_SROM_PA5GHW1A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1,
  778. 0xffff},
  779. {BRCMS_SROM_PA5GHW2A0, 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2,
  780. 0xffff},
  781. {BRCMS_SROM_NULL, 0, 0, 0, 0}
  782. };
  783. /* crc table has the same contents for every device instance, so it can be
  784. * shared between devices. */
  785. static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE];
  786. static u16 __iomem *
  787. srom_window_address(struct si_pub *sih, u8 __iomem *curmap)
  788. {
  789. if (sih->ccrev < 32)
  790. return (u16 __iomem *)(curmap + PCI_BAR0_SPROM_OFFSET);
  791. if (sih->cccaps & CC_CAP_SROM)
  792. return (u16 __iomem *)
  793. (curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP);
  794. return NULL;
  795. }
  796. /* Parse SROM and create name=value pairs. 'srom' points to
  797. * the SROM word array. 'off' specifies the offset of the
  798. * first word 'srom' points to, which should be either 0 or
  799. * SROM3_SWRG_OFF (full SROM or software region).
  800. */
  801. static uint mask_shift(u16 mask)
  802. {
  803. uint i;
  804. for (i = 0; i < (sizeof(mask) << 3); i++) {
  805. if (mask & (1 << i))
  806. return i;
  807. }
  808. return 0;
  809. }
  810. static uint mask_width(u16 mask)
  811. {
  812. int i;
  813. for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) {
  814. if (mask & (1 << i))
  815. return (uint) (i - mask_shift(mask) + 1);
  816. }
  817. return 0;
  818. }
  819. static inline void ltoh16_buf(u16 *buf, unsigned int size)
  820. {
  821. size /= 2;
  822. while (size--)
  823. *(buf + size) = le16_to_cpu(*(__le16 *)(buf + size));
  824. }
  825. static inline void htol16_buf(u16 *buf, unsigned int size)
  826. {
  827. size /= 2;
  828. while (size--)
  829. *(__le16 *)(buf + size) = cpu_to_le16(*(buf + size));
  830. }
  831. /*
  832. * convert binary srom data into linked list of srom variable items.
  833. */
  834. static void
  835. _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
  836. {
  837. struct brcms_srom_list_head *entry;
  838. enum brcms_srom_id id;
  839. u16 w;
  840. u32 val;
  841. const struct brcms_sromvar *srv;
  842. uint width;
  843. uint flags;
  844. u32 sr = (1 << sromrev);
  845. /* first store the srom revision */
  846. entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL);
  847. entry->varid = BRCMS_SROM_REV;
  848. entry->var_type = BRCMS_SROM_UNUMBER;
  849. entry->uval = sromrev;
  850. list_add(&entry->var_list, var_list);
  851. for (srv = pci_sromvars; srv->varid != BRCMS_SROM_NULL; srv++) {
  852. enum brcms_srom_var_type type;
  853. u8 ea[ETH_ALEN];
  854. u8 extra_space = 0;
  855. if ((srv->revmask & sr) == 0)
  856. continue;
  857. flags = srv->flags;
  858. id = srv->varid;
  859. /* This entry is for mfgc only. Don't generate param for it, */
  860. if (flags & SRFL_NOVAR)
  861. continue;
  862. if (flags & SRFL_ETHADDR) {
  863. /*
  864. * stored in string format XX:XX:XX:XX:XX:XX (17 chars)
  865. */
  866. ea[0] = (srom[srv->off] >> 8) & 0xff;
  867. ea[1] = srom[srv->off] & 0xff;
  868. ea[2] = (srom[srv->off + 1] >> 8) & 0xff;
  869. ea[3] = srom[srv->off + 1] & 0xff;
  870. ea[4] = (srom[srv->off + 2] >> 8) & 0xff;
  871. ea[5] = srom[srv->off + 2] & 0xff;
  872. /* 17 characters + string terminator - union size */
  873. extra_space = 18 - sizeof(s32);
  874. type = BRCMS_SROM_STRING;
  875. } else {
  876. w = srom[srv->off];
  877. val = (w & srv->mask) >> mask_shift(srv->mask);
  878. width = mask_width(srv->mask);
  879. while (srv->flags & SRFL_MORE) {
  880. srv++;
  881. if (srv->off == 0)
  882. continue;
  883. w = srom[srv->off];
  884. val +=
  885. ((w & srv->mask) >> mask_shift(srv->
  886. mask)) <<
  887. width;
  888. width += mask_width(srv->mask);
  889. }
  890. if ((flags & SRFL_NOFFS)
  891. && ((int)val == (1 << width) - 1))
  892. continue;
  893. if (flags & SRFL_CCODE) {
  894. type = BRCMS_SROM_STRING;
  895. } else if (flags & SRFL_LEDDC) {
  896. /* LED Powersave duty cycle has to be scaled:
  897. *(oncount >> 24) (offcount >> 8)
  898. */
  899. u32 w32 = /* oncount */
  900. (((val >> 8) & 0xff) << 24) |
  901. /* offcount */
  902. (((val & 0xff)) << 8);
  903. type = BRCMS_SROM_UNUMBER;
  904. val = w32;
  905. } else if ((flags & SRFL_PRSIGN)
  906. && (val & (1 << (width - 1)))) {
  907. type = BRCMS_SROM_SNUMBER;
  908. val |= ~0 << width;
  909. } else
  910. type = BRCMS_SROM_UNUMBER;
  911. }
  912. entry = kzalloc(sizeof(struct brcms_srom_list_head) +
  913. extra_space, GFP_KERNEL);
  914. entry->varid = id;
  915. entry->var_type = type;
  916. if (flags & SRFL_ETHADDR) {
  917. snprintf(entry->buf, 18, "%pM", ea);
  918. } else if (flags & SRFL_CCODE) {
  919. if (val == 0)
  920. entry->buf[0] = '\0';
  921. else
  922. snprintf(entry->buf, 3, "%c%c",
  923. (val >> 8), (val & 0xff));
  924. } else {
  925. entry->uval = val;
  926. }
  927. list_add(&entry->var_list, var_list);
  928. }
  929. if (sromrev >= 4) {
  930. /* Do per-path variables */
  931. uint p, pb, psz;
  932. if (sromrev >= 8) {
  933. pb = SROM8_PATH0;
  934. psz = SROM8_PATH1 - SROM8_PATH0;
  935. } else {
  936. pb = SROM4_PATH0;
  937. psz = SROM4_PATH1 - SROM4_PATH0;
  938. }
  939. for (p = 0; p < MAX_PATH_SROM; p++) {
  940. for (srv = perpath_pci_sromvars;
  941. srv->varid != BRCMS_SROM_NULL; srv++) {
  942. if ((srv->revmask & sr) == 0)
  943. continue;
  944. if (srv->flags & SRFL_NOVAR)
  945. continue;
  946. w = srom[pb + srv->off];
  947. val = (w & srv->mask) >> mask_shift(srv->mask);
  948. width = mask_width(srv->mask);
  949. /* Cheating: no per-path var is more than
  950. * 1 word */
  951. if ((srv->flags & SRFL_NOFFS)
  952. && ((int)val == (1 << width) - 1))
  953. continue;
  954. entry =
  955. kzalloc(sizeof(struct brcms_srom_list_head),
  956. GFP_KERNEL);
  957. entry->varid = srv->varid+p;
  958. entry->var_type = BRCMS_SROM_UNUMBER;
  959. entry->uval = val;
  960. list_add(&entry->var_list, var_list);
  961. }
  962. pb += psz;
  963. }
  964. }
  965. }
  966. /*
  967. * Read in and validate sprom.
  968. * Return 0 on success, nonzero on error.
  969. */
  970. static int
  971. sprom_read_pci(struct si_pub *sih, u16 __iomem *sprom, uint wordoff,
  972. u16 *buf, uint nwords, bool check_crc)
  973. {
  974. int err = 0;
  975. uint i;
  976. /* read the sprom */
  977. for (i = 0; i < nwords; i++)
  978. buf[i] = R_REG(&sprom[wordoff + i]);
  979. if (check_crc) {
  980. if (buf[0] == 0xffff)
  981. /*
  982. * The hardware thinks that an srom that starts with
  983. * 0xffff is blank, regardless of the rest of the
  984. * content, so declare it bad.
  985. */
  986. return -ENODATA;
  987. /* fixup the endianness so crc8 will pass */
  988. htol16_buf(buf, nwords * 2);
  989. if (crc8(brcms_srom_crc8_table, (u8 *) buf, nwords * 2,
  990. CRC8_INIT_VALUE) !=
  991. CRC8_GOOD_VALUE(brcms_srom_crc8_table))
  992. /* DBG only pci always read srom4 first, then srom8/9 */
  993. err = -EIO;
  994. /* now correct the endianness of the byte array */
  995. ltoh16_buf(buf, nwords * 2);
  996. }
  997. return err;
  998. }
  999. static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz)
  1000. {
  1001. u8 *otp;
  1002. uint sz = OTP_SZ_MAX / 2; /* size in words */
  1003. int err = 0;
  1004. otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC);
  1005. if (otp == NULL)
  1006. return -ENOMEM;
  1007. err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz);
  1008. memcpy(buf, otp, bufsz);
  1009. kfree(otp);
  1010. /* Check CRC */
  1011. if (buf[0] == 0xffff)
  1012. /* The hardware thinks that an srom that starts with 0xffff
  1013. * is blank, regardless of the rest of the content, so declare
  1014. * it bad.
  1015. */
  1016. return -ENODATA;
  1017. /* fixup the endianness so crc8 will pass */
  1018. htol16_buf(buf, bufsz);
  1019. if (crc8(brcms_srom_crc8_table, (u8 *) buf, SROM4_WORDS * 2,
  1020. CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(brcms_srom_crc8_table))
  1021. err = -EIO;
  1022. /* now correct the endianness of the byte array */
  1023. ltoh16_buf(buf, bufsz);
  1024. return err;
  1025. }
  1026. /*
  1027. * Initialize nonvolatile variable table from sprom.
  1028. * Return 0 on success, nonzero on error.
  1029. */
  1030. static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap)
  1031. {
  1032. u16 *srom;
  1033. u16 __iomem *sromwindow;
  1034. u8 sromrev = 0;
  1035. u32 sr;
  1036. int err = 0;
  1037. /*
  1038. * Apply CRC over SROM content regardless SROM is present or not.
  1039. */
  1040. srom = kmalloc(SROM_MAX, GFP_ATOMIC);
  1041. if (!srom)
  1042. return -ENOMEM;
  1043. sromwindow = srom_window_address(sih, curmap);
  1044. crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY);
  1045. if (ai_is_sprom_available(sih)) {
  1046. err = sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS,
  1047. true);
  1048. if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) ||
  1049. (((sih->buscoretype == PCIE_CORE_ID)
  1050. && (sih->buscorerev >= 6))
  1051. || ((sih->buscoretype == PCI_CORE_ID)
  1052. && (sih->buscorerev >= 0xe)))) {
  1053. /* sromrev >= 4, read more */
  1054. err = sprom_read_pci(sih, sromwindow, 0, srom,
  1055. SROM4_WORDS, true);
  1056. sromrev = srom[SROM4_CRCREV] & 0xff;
  1057. } else if (err == 0) {
  1058. /* srom is good and is rev < 4 */
  1059. /* top word of sprom contains version and crc8 */
  1060. sromrev = srom[SROM_CRCREV] & 0xff;
  1061. /* bcm4401 sroms misprogrammed */
  1062. if (sromrev == 0x10)
  1063. sromrev = 1;
  1064. }
  1065. } else {
  1066. /* Use OTP if SPROM not available */
  1067. err = otp_read_pci(sih, srom, SROM_MAX);
  1068. if (err == 0)
  1069. /* OTP only contain SROM rev8/rev9 for now */
  1070. sromrev = srom[SROM4_CRCREV] & 0xff;
  1071. }
  1072. if (!err) {
  1073. struct si_info *sii = (struct si_info *)sih;
  1074. /* Bitmask for the sromrev */
  1075. sr = 1 << sromrev;
  1076. /*
  1077. * srom version check: Current valid versions: 1, 2, 3, 4, 5, 8,
  1078. * 9
  1079. */
  1080. if ((sr & 0x33e) == 0) {
  1081. err = -EINVAL;
  1082. goto errout;
  1083. }
  1084. INIT_LIST_HEAD(&sii->var_list);
  1085. /* parse SROM into name=value pairs. */
  1086. _initvars_srom_pci(sromrev, srom, &sii->var_list);
  1087. }
  1088. errout:
  1089. kfree(srom);
  1090. return err;
  1091. }
  1092. void srom_free_vars(struct si_pub *sih)
  1093. {
  1094. struct si_info *sii;
  1095. struct brcms_srom_list_head *entry, *next;
  1096. sii = (struct si_info *)sih;
  1097. list_for_each_entry_safe(entry, next, &sii->var_list, var_list) {
  1098. list_del(&entry->var_list);
  1099. kfree(entry);
  1100. }
  1101. }
  1102. /*
  1103. * Initialize local vars from the right source for this platform.
  1104. * Return 0 on success, nonzero on error.
  1105. */
  1106. int srom_var_init(struct si_pub *sih, void __iomem *curmap)
  1107. {
  1108. uint len;
  1109. len = 0;
  1110. if (curmap != NULL)
  1111. return initvars_srom_pci(sih, curmap);
  1112. return -EINVAL;
  1113. }
  1114. /*
  1115. * Search the name=value vars for a specific one and return its value.
  1116. * Returns NULL if not found.
  1117. */
  1118. char *getvar(struct si_pub *sih, enum brcms_srom_id id)
  1119. {
  1120. struct si_info *sii;
  1121. struct brcms_srom_list_head *entry;
  1122. sii = (struct si_info *)sih;
  1123. list_for_each_entry(entry, &sii->var_list, var_list)
  1124. if (entry->varid == id)
  1125. return &entry->buf[0];
  1126. /* nothing found */
  1127. return NULL;
  1128. }
  1129. /*
  1130. * Search the vars for a specific one and return its value as
  1131. * an integer. Returns 0 if not found.-
  1132. */
  1133. int getintvar(struct si_pub *sih, enum brcms_srom_id id)
  1134. {
  1135. struct si_info *sii;
  1136. struct brcms_srom_list_head *entry;
  1137. unsigned long res;
  1138. sii = (struct si_info *)sih;
  1139. list_for_each_entry(entry, &sii->var_list, var_list)
  1140. if (entry->varid == id) {
  1141. if (entry->var_type == BRCMS_SROM_SNUMBER ||
  1142. entry->var_type == BRCMS_SROM_UNUMBER)
  1143. return (int)entry->sval;
  1144. else if (!kstrtoul(&entry->buf[0], 0, &res))
  1145. return (int)res;
  1146. }
  1147. return 0;
  1148. }