GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / shared / bcmsrom.c
blob952931b0c08917aea329312bfa18a10bb93f7584
1 /*
2 * Routines to access SPROM and to parse SROM/CIS variables.
4 * Copyright (C) 2012, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id: bcmsrom.c 364585 2012-10-24 18:17:16Z $
21 #include <bcm_cfg.h>
22 #include <typedefs.h>
23 #include <bcmdefs.h>
24 #include <osl.h>
25 #if defined(__FreeBSD__) || defined(__NetBSD__)
26 #if __NetBSD_Version__ >= 500000003
27 #include <sys/stdarg.h>
28 #else
29 #include <machine/stdarg.h>
30 #endif
31 #else
32 #include <stdarg.h>
33 #endif /* NetBSD */
34 #include <bcmutils.h>
35 #include <hndsoc.h>
36 #include <sbchipc.h>
37 #include <bcmdevs.h>
38 #include <bcmendian.h>
39 #include <sbpcmcia.h>
40 #include <pcicfg.h>
41 #include <siutils.h>
42 #include <bcmsrom.h>
43 #include <bcmsrom_tbl.h>
44 #ifdef BCMSPI
45 #include <spid.h>
46 #endif
48 #include <bcmnvram.h>
49 #include <bcmotp.h>
51 #if defined(BCMUSBDEV)
52 #include <sbsdio.h>
53 #include <sbhnddma.h>
54 #include <sbsdpcmdev.h>
55 #endif
57 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
58 #include <sbsprom.h>
59 #endif
60 #include <proto/ethernet.h> /* for sprom content groking */
63 #if defined(BCMDBG_ERR) || defined(WLTEST)
64 #define BS_ERROR(args) printf args
65 #else
66 #define BS_ERROR(args)
67 #endif
69 #define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \
70 (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \
71 ((uint8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \
72 ((uint8 *)curmap + PCI_BAR0_SPROM_OFFSET))
74 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
75 #define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */
76 #define WRITE_WORD_DELAY 20 /* 20 ms between each word write */
77 #endif
79 typedef struct varbuf {
80 char *base; /* pointer to buffer base */
81 char *buf; /* pointer to current position */
82 unsigned int size; /* current (residual) size in bytes */
83 } varbuf_t;
84 extern char *_vars;
85 extern uint _varsz;
87 #define SROM_CIS_SINGLE 1
90 static int initvars_srom_si(si_t *sih, osl_t *osh, void *curmap, char **vars, uint *count);
91 static void _initvars_srom_pci(uint8 sromrev, uint16 *srom, uint off, varbuf_t *b);
92 static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count);
93 static int initvars_cis_pcmcia(si_t *sih, osl_t *osh, char **vars, uint *count);
94 #if !defined(BCMUSBDEV_ENABLED) && !defined(BCMSDIODEV_ENABLED)
95 static int initvars_flash_si(si_t *sih, char **vars, uint *count);
96 #endif
97 #ifdef BCMSPI
98 static int initvars_cis_spi(osl_t *osh, char **vars, uint *count);
99 #endif /* BCMSPI */
100 static int sprom_cmd_pcmcia(osl_t *osh, uint8 cmd);
101 static int sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data);
102 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
103 static int sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data);
104 #endif
105 static int sprom_read_pci(osl_t *osh, si_t *sih, uint16 *sprom, uint wordoff, uint16 *buf,
106 uint nwords, bool check_crc);
107 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
108 static int otp_read_pci(osl_t *osh, si_t *sih, uint16 *buf, uint bufsz);
109 #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
110 static uint16 srom_cc_cmd(si_t *sih, osl_t *osh, void *ccregs, uint32 cmd, uint wordoff,
111 uint16 data);
113 static int initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count);
114 static int initvars_flash(si_t *sih, osl_t *osh, char **vp, uint len);
116 #if defined(BCMUSBDEV)
117 static int get_si_pcmcia_srom(si_t *sih, osl_t *osh, uint8 *pcmregs,
118 uint boff, uint16 *srom, uint bsz, bool check_crc);
119 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
120 static int set_si_pcmcia_srom(si_t *sih, osl_t *osh, uint8 *pcmregs,
121 uint boff, uint16 *srom, uint bsz);
122 #endif
123 #endif
125 #if defined(BCMUSBDEV)
126 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
127 /* default to bcm94323 P200, other boards should have OTP programmed */
128 static char BCMATTACHDATA(defaultsromvars_4322usb)[] =
129 "vendid=0x14e4\0"
130 "subvendid=0x0a5c\0"
131 "subdevid=0xbdc\0"
132 "macaddr=00:90:4c:d3:04:73\0"
133 "sromrev=8\0"
134 "devid=0x432b\0"
135 "boardrev=0x1200\0"
136 "boardflags=0xa00\0"
137 "boardflags2=0x602\0"
138 "boardtype=0x04a8\0"
139 "tssipos2g=0x1\0"
140 "extpagain2g=0x0\0"
141 "pdetrange2g=0x0\0"
142 "triso2g=0x3\0"
143 "antswctl2g=0x2\0"
144 "tssipos5g=0x1\0"
145 "extpagain5g=0x0\0"
146 "pdetrange5g=0x0\0"
147 "triso5g=0x3\0"
148 "antswctl5g=0x2\0"
149 "maxp2ga0=0x48\0"
150 "itt2ga0=0x20\0"
151 "pa2gw0a0=0xFEA8\0"
152 "pa2gw1a0=0x16CD\0"
153 "pa2gw2a0=0xFAA5\0"
154 "maxp5ga0=0x40\0"
155 "itt5ga0=0x3e\0"
156 "maxp5gha0=0x3c\0"
157 "maxp5gla0=0x40\0"
158 "pa5gw0a0=0xFEB2\0"
159 "pa5gw1a0=0x1471\0"
160 "pa5gw2a0=0xFB1F\0"
161 "pa5glw0a0=0xFEA2\0"
162 "pa5glw1a0=0x149A\0"
163 "pa5glw2a0=0xFAFC\0"
164 "pa5ghw0a0=0xFEC6\0"
165 "pa5ghw1a0=0x13DD\0"
166 "pa5ghw2a0=0xFB48\0"
167 "maxp2ga1=0x48\0"
168 "itt2ga1=0x20\0"
169 "pa2gw0a1=0xFEA3\0"
170 "pa2gw1a1=0x1687\0"
171 "pa2gw2a1=0xFAAA\0"
172 "maxp5ga1=0x40\0"
173 "itt5ga1=0x3e\0"
174 "maxp5gha1=0x3c\0"
175 "maxp5gla1=0x40\0"
176 "pa5gw0a1=0xFEBC\0"
177 "pa5gw1a1=0x14F9\0"
178 "pa5gw2a1=0xFB05\0"
179 "pa5glw0a1=0xFEBE\0"
180 "pa5glw1a1=0x1478\0"
181 "pa5glw2a1=0xFB1A\0"
182 "pa5ghw0a1=0xFEE1\0"
183 "pa5ghw1a1=0x14FD\0"
184 "pa5ghw2a1=0xFB38\0"
185 "cctl=0\0"
186 "ccode=US\0"
187 "regrev=0x0\0"
188 "ledbh0=0xff\0"
189 "ledbh1=0x2\0"
190 "ledbh2=0x3\0"
191 "ledbh3=0xff\0"
192 "leddc=0xa0a0\0"
193 "aa2g=0x3\0"
194 "aa5g=0x3\0"
195 "ag0=0x2\0"
196 "ag1=0x2\0"
197 "ag2=0xff\0"
198 "ag3=0xff\0"
199 "txchain=0x3\0"
200 "rxchain=0x3\0"
201 "antswitch=0\0"
202 "END\0";
204 static char BCMATTACHDATA(defaultsromvars_43234usb)[] =
205 "vendid=0x14e4\0"
206 "subvendid=0x0a5c\0"
207 "subdevid=0xbdc\0"
208 "macaddr=00:90:4c:03:21:23\0"
209 "cctl=0\0"
210 "ccode=US\0"
211 "regrev=0x0\0"
212 "ledbh0=0x82\0"
213 "ledbh1=0xff\0"
214 "ledbh2=0xff\0"
215 "ledbh3=0xff\0"
216 "leddc=0x0\0"
217 "aa2g=0x2\0"
218 "aa5g=0x2\0"
219 "ag0=0x2\0"
220 "ag1=0x2\0"
221 "ag2=0x2\0"
222 "ag3=0xff\0"
223 "txchain=0x2\0"
224 "rxchain=0x2\0"
225 "antswitch=0\0"
226 "sromrev=8\0"
227 "devid=0x4346\0"
228 "boardrev=0x1403\0"
229 "boardflags=0x200\0"
230 "boardflags2=0x2000\0"
231 "boardtype=0x0521\0"
232 "tssipos2g=0x1\0"
233 "extpagain2g=0x2\0"
234 "pdetrange2g=0x2\0"
235 "triso2g=0x3\0"
236 "antswctl2g=0x0\0"
237 "tssipos5g=0x1\0"
238 "extpagain5g=0x2\0"
239 "pdetrange5g=0x2\0"
240 "triso5g=0x3\0"
241 "antswctl5g=0x0\0"
242 "ofdm2gpo=0x0\0"
243 "ofdm5gpo=0x0\0"
244 "ofdm5glpo=0x0\0"
245 "ofdm5ghpo=0x0\0"
246 "mcs2gpo0=0x0\0"
247 "mcs2gpo1=0x0\0"
248 "mcs2gpo2=0x0\0"
249 "mcs2gpo3=0x0\0"
250 "mcs2gpo4=0x4444\0"
251 "mcs2gpo5=0x4444\0"
252 "mcs2gpo6=0x4444\0"
253 "mcs2gpo7=0x4444\0"
254 "mcs5gpo4=0x2222\0"
255 "mcs5gpo5=0x2222\0"
256 "mcs5gpo6=0x2222\0"
257 "mcs5gpo7=0x2222\0"
258 "mcs5glpo4=0x2222\0"
259 "mcs5glpo5=0x2222\0"
260 "mcs5glpo6=0x2222\0"
261 "mcs5glpo7=0x2222\0"
262 "mcs5ghpo4=0x2222\0"
263 "mcs5ghpo5=0x2222\0"
264 "mcs5ghpo6=0x2222\0"
265 "mcs5ghpo7=0x2222\0"
266 "maxp2ga0=0x42\0"
267 "itt2ga0=0x20\0"
268 "itt5ga0=0x3e\0"
269 "pa2gw0a0=0xFF21\0"
270 "pa2gw1a0=0x13B7\0"
271 "pa2gw2a0=0xFB44\0"
272 "maxp5ga0=0x3E\0"
273 "maxp5gha0=0x3a\0"
274 "maxp5gla0=0x3c\0"
275 "pa5gw0a0=0xFEB2\0"
276 "pa5gw1a0=0x1570\0"
277 "pa5gw2a0=0xFAD6\0"
278 "pa5glw0a0=0xFE64\0"
279 "pa5glw1a0=0x13F7\0"
280 "pa5glw2a0=0xFAF6\0"
281 "pa5ghw0a0=0xFEAB\0"
282 "pa5ghw1a0=0x15BB\0"
283 "pa5ghw2a0=0xFAC6\0"
284 "maxp2ga1=0x42\0"
285 "itt2ga1=0x20\0"
286 "itt5ga1=0x3e\0"
287 "pa2gw0a1=0xFF17\0"
288 "pa2gw1a1=0x13C4\0"
289 "pa2gw2a1=0xFB3C\0"
290 "maxp5ga1=0x3E\0"
291 "maxp5gha1=0x3a\0"
292 "maxp5gla1=0x3c\0"
293 "pa5gw0a1=0xFE6F\0"
294 "pa5gw1a1=0x13CC\0"
295 "pa5gw2a1=0xFAF8\0"
296 "pa5glw0a1=0xFE87\0"
297 "pa5glw1a1=0x14BE\0"
298 "pa5glw2a1=0xFAD6\0"
299 "pa5ghw0a1=0xFE68\0"
300 "pa5ghw1a1=0x13E9\0"
301 "pa5ghw2a1=0xFAF6\0"
302 "END\0";
304 static char BCMATTACHDATA(defaultsromvars_43235usb)[] =
305 "vendid=0x14e4\0"
306 "subvendid=0x0a5c\0"
307 "subdevid=0xbdc\0"
308 "macaddr=00:90:4c:05:30:01\0"
309 "ccode=US\0"
310 "regrev=0x0\0"
311 "ledbh0=0x82\0"
312 "ledbh1=0xff\0"
313 "ledbh2=0xff\0"
314 "ledbh3=0xff\0"
315 "leddc=0x0\0"
316 "aa2g=0x3\0"
317 "ag0=0x2\0"
318 "ag1=0x2\0"
319 "ag2=0xff\0"
320 "ag3=0xff\0"
321 "txchain=0x3\0"
322 "rxchain=0x3\0"
323 "antswitch=0\0"
324 "sromrev=8\0"
325 "devid=0x4347\0"
326 "boardrev=0x1113\0"
327 "boardflags=0x200\0"
328 "boardflags2=0x0\0"
329 "boardtype=0x0571\0"
330 "tssipos2g=0x1\0"
331 "extpagain2g=0x2\0"
332 "pdetrange2g=0x2\0"
333 "triso2g=0x3\0"
334 "antswctl2g=0x0\0"
335 "antswctl5g=0x0\0"
336 "ofdm2gpo=0x0\0"
337 "mcs2gpo0=0x0\0"
338 "mcs2gpo1=0x0\0"
339 "mcs2gpo2=0x0\0"
340 "mcs2gpo3=0x0\0"
341 "mcs2gpo4=0x2222\0"
342 "mcs2gpo5=0x2222\0"
343 "mcs2gpo6=0x2222\0"
344 "mcs2gpo7=0x4444\0"
345 "maxp2ga0=0x42\0"
346 "itt2ga0=0x20\0"
347 "pa2gw0a0=0xFF00\0"
348 "pa2gw1a0=0x143C\0"
349 "pa2gw2a0=0xFB27\0"
350 "maxp2ga1=0x42\0"
351 "itt2ga1=0x20\0"
352 "pa2gw0a1=0xFF22\0"
353 "pa2gw1a1=0x142E\0"
354 "pa2gw2a1=0xFB45\0"
355 "tempthresh=120\0"
356 "temps_period=5\0"
357 "temp_hysteresis=5\0"
358 "END\0";
360 static char BCMATTACHDATA(defaultsromvars_4350usb)[] =
361 "vendid=0x14e4\0"
362 "subvendid=0x0a5c\0"
363 "subdevid=0xbdc\0"
364 "sromrev=11\0"
365 "boardrev=0x1140\0"
366 "boardflags=0x0\0"
367 "boardflags2=0x0\0"
368 "boardtype=0x604\0"
369 "boardflags3=0x0\0"
370 "boardnum=57410\0"
371 "macaddr=00:90:4c:0c:e0:42\0"
372 "xtalfreq=37400\0"
373 "rxchain=3\0"
374 "txchain=3\0"
375 "ccode=0\0"
376 "regrev=0\0"
377 "aa2g=7\0"
378 "aa5g=7\0"
379 "agbg0=71\0"
380 "agbg1=71\0"
381 "agbg2=133\0"
382 "aga0=71\0"
383 "aga1=133\0"
384 "aga2=133\0"
385 "antswitch=0\0"
386 "tssiposslope2g=1\0"
387 "epagain2g=0\0"
388 "pdgain2g=0\0"
389 "tworangetssi2g=0\0"
390 "papdcap2g=0\0"
391 "femctrl=1\0"
392 "tssiposslope5g=1\0"
393 "epagain5g=0\0"
394 "pdgain5g=0\0"
395 "tworangetssi5g=0\0"
396 "papdcap5g=0\0"
397 "gainctrlsph=0\0"
398 "tempthresh=255\0"
399 "tempoffset=255\0"
400 "rawtempsense=0x1ff\0"
401 "measpower=0x7f\0"
402 "tempsense_slope=0xff\0"
403 "tempcorrx=0x3f\0"
404 "tempsense_option=0x3\0"
405 "phycal_tempdelta=255\0"
406 "temps_period=15\0"
407 "temps_hysteresis=15\0"
408 "measpower1=0x7f\0"
409 "measpower2=0x7f\0"
410 "subband5gver=0x4\0"
411 "sar2g=18\0"
412 "sar5g=15\0"
413 "noiselvl2ga0=31\0"
414 "noiselvl2ga1=31\0"
415 "noiselvl2ga2=31\0"
416 "noiselvl5gla0=31\0"
417 "noiselvl5gla1=31\0"
418 "noiselvl5gla2=31\0"
419 "noiselvl5gma0=31\0"
420 "noiselvl5gma1=31\0"
421 "noiselvl5gma2=31\0"
422 "noiselvl5gha0=31\0"
423 "noiselvl5gha1=31\0"
424 "noiselvl5gha2=31\0"
425 "noiselvl5gua0=31\0"
426 "noiselvl5gua1=31\0"
427 "noiselvl5gua2=31\0"
428 "rxgainerr2g=0xffff\0"
429 "rxgainerr5g=0xffff,0xffff,0xffff,0xffff\0"
430 "maxp2ga0=76\0"
431 "pa2ga0=0xfe72,0x14c0,0xfac7\0"
432 "rxgains2gelnagaina0=4\0"
433 "rxgains2gtrisoa0=10\0"
434 "rxgains2gtrelnabypa0=1\0"
435 "rxgains5gelnagaina0=3\0"
436 "rxgains5gtrisoa0=10\0"
437 "rxgains5gtrelnabypa0=1\0"
438 "maxp5ga0=17,34,51,68\0"
439 "pa5ga0=0xfe75,0x14b5,0xfad4,0xfe97,0x121a,0xfb6e,0xfe7f,0x149d,0xfad0,0xfe7c,0x1431,0xfae6\0"
440 "maxp2ga1=76\0"
441 "pa2ga1=0xfe80,0x1472,0xfabc\0"
442 "rxgains2gelnagaina1=4\0"
443 "rxgains2gtrisoa1=10\0"
444 "rxgains2gtrelnabypa1=1\0"
445 "rxgains5gelnagaina1=3\0"
446 "rxgains5gtrisoa1=10\0"
447 "rxgains5gtrelnabypa1=1\0"
448 "maxp5ga1=72,72,76,76\0"
449 "pa5ga1=0xfe72,0x155e,0xfa96,0xfea1,0x125d,0xfb55,0xfe77,0x1596,0xfa8e,0xfe78,0x15e1,0xfa7a\0"
450 "maxp2ga2=76\0"
451 "pa2ga2=0xfe82,0x14bf,0xfad9\0"
452 "rxgains2gelnagaina2=4\0"
453 "rxgains2gtrisoa2=10\0"
454 "rxgains2gtrelnabypa2=1\0"
455 "rxgains5gelnagaina2=3\0"
456 "rxgains5gtrisoa2=10\0"
457 "rxgains5gtrelnabypa2=1\0"
458 "maxp5ga2=72,72,76,76\0"
459 "pa5ga2=0xfe7d,0x14d8,0xfacd,0xfea6,0x1218,0xfb79,0xfe7c,0x1452,0xfade,0xfe82,0x1406,0xfaf6\0"
460 "END\0";
462 static char BCMATTACHDATA(defaultsromvars_43242usb)[] =
463 "devid=0x4374\0"
464 "boardtype=0x063A\0"
465 "boardrev=0x1100\0"
466 "boardflags=0x200\0"
467 "boardflags2=0\0"
468 "macaddr=00:90:4c:c5:12:38\0"
469 "sromrev=9\0"
470 "xtalfreq=37400\0"
471 "nocrc=1\0"
472 "ag0=0x2\0"
473 "ag1=0x2\0"
474 "ag2=0xff\0"
475 "ag3=0xff\0"
476 "txchain=0x3\0"
477 "rxchain=0x3\0"
478 "aa2g=3\0"
479 "aa5g=3\0"
480 "ccode=ALL\0"
481 "regrev=0\0"
482 "ledbh0=0xff\0"
483 "ledbh1=0xff\0"
484 "ledbh2=0xff\0"
485 "ledbh3=0xff\0"
486 "leddc=0xffff\0"
487 "pa2gw0a0=0xFFC3\0"
488 "pa2gw1a0=0x143F\0"
489 "pa2gw2a0=0xFEE1\0"
490 "pa2gw0a1=0xFFBA\0"
491 "pa2gw1a1=0x141E\0"
492 "pa2gw2a1=0xFEDB\0"
493 "maxp2ga0=70\0"
494 "maxp2ga1=70\0"
495 "maxp5ga0=70\0"
496 "maxp5ga1=70\0"
497 "maxp5gha0=70\0"
498 "maxp5gha1=70\0"
499 "maxp5gla0=70\0"
500 "maxp5gla1=70\0"
501 "pa0itssit=62\0"
502 "pa1itssit=62\0"
503 "antswctl2g=0x15\0"
504 "antswctl5g=0x16\0"
505 "antswitch=0x0\0"
506 "pa5gw0a0=0xFFC5\0"
507 "pa5gw1a0=0x1321\0"
508 "pa5gw2a0=0xFEF2\0"
509 "pa5gw0a1=0xFFBC\0"
510 "pa5gw1a1=0x1386\0"
511 "pa5gw2a1=0xFEE3\0"
512 "pa5glw0a0=0xFFC4\0"
513 "pa5glw1a0=0x12CF\0"
514 "pa5glw2a0=0xFEF4\0"
515 "pa5glw0a1=0xFFC5\0"
516 "pa5glw1a1=0x1391\0"
517 "pa5glw2a1=0xFEED\0"
518 "pa5ghw0a0=0xFFC4\0"
519 "pa5ghw1a0=0x12CF\0"
520 "pa5ghw2a0=0xFEF4\0"
521 "pa5ghw0a1=0xFFC5\0"
522 "pa5ghw1a1=0x1391\0"
523 "pa5ghw2a1=0xFEED\0"
524 "extpagain2g=2\0"
525 "extpagain5g=2\0"
526 "pdetrange2g=2\0"
527 "pdetrange5g=2\0"
528 "triso2g=2\0"
529 "triso5g=4\0"
530 "tssipos2g=1\0"
531 "tssipos5g=1\0"
532 "cckbw202gpo=0x0\0"
533 "cckbw20ul2gpo=0x0\0"
534 "legofdmbw202gpo=0x88888888\0"
535 "legofdmbw20ul2gpo=0x88888888\0"
536 "mcsbw202gpo=0x88888888\0"
537 "mcsbw20ul2gpo=0x88888888\0"
538 "mcsbw402gpo=0x88888888\0"
539 "mcs32po=0x5555\0"
540 "leg40dup2gpo=0x2\0"
541 "legofdmbw205glpo=0x22220000\0"
542 "legofdmbw20ul5glpo=0x44442222\0"
543 "legofdmbw205gmpo=0x22220000\0"
544 "legofdmbw20ul5gmpo=0x44442222\0"
545 "legofdmbw205ghpo=0x22220000\0"
546 "legofdmbw20ul5ghpo=0x44442222\0"
547 "mcsbw205glpo=0x44422222\0"
548 "mcsbw20ul5glpo=0x66644444\0"
549 "mcsbw405glpo=0x66644444\0"
550 "mcsbw205gmpo=0x44422222\0"
551 "mcsbw20ul5gmpo=0x66644444\0"
552 "mcsbw405gmpo=0x66644444\0"
553 "mcsbw205ghpo=0x44422222\0"
554 "mcsbw20ul5ghpo=0x66644444\0"
555 "mcsbw405ghpo=0x66644444\0"
556 "itt2ga0=0x20\0"
557 "itt5ga0=0x3e\0"
558 "itt2ga1=0x20\0"
559 "itt5ga1=0x3e\0"
560 "tempthresh=120\0"
561 "noisecaloffset=10\0"
562 "noisecaloffset5g=12\0"
563 "END\0";
565 static char BCMATTACHDATA(defaultsromvars_43143usb)[] =
566 "vendid=0x14e4\0"
567 "devid=0x4366\0"
568 "subvendid=0xa5c\0"
569 "subdevid=0xbdc\0"
570 "sromrev=10\0"
571 "boardnum=0x1100\0"
572 "boardtype=0x0629\0"
573 "boardrev=0x1403\0"
574 "boardflags=0x000\0"
575 "boardflags2=0x000\0"
576 "macaddr=00:90:4c:0e:81:23\0"
577 "ccode=ALL\0"
578 "cctl=0\0"
579 "regrev=0\0"
580 "ledbh0=0xff\0"
581 "ledbh1=0xff\0"
582 "ledbh2=0xff\0"
583 "ledbh3=0xff\0"
584 "leddc=0xffff\0"
585 "aa2g=1\0"
586 "ag0=2\0"
587 "ag1=2\0"
588 "txchain=1\0"
589 "rxchain=1\0"
590 "antswitch=0\0"
591 "maxp2ga0=68\0"
592 "pa0itssit=0x20\0"
593 "pa0b0=6022\0"
594 "pa0b1=-709\0"
595 "pa0b2=-147\0"
596 "cckPwrOffset=3\0"
597 "tssipos2g=0\0"
598 "extpagain2g=0\0"
599 "pdetrange2g=0\0"
600 "triso2g=3\0"
601 "antswctl2g=0\0"
602 "cckbw202gpo=0x0000\0"
603 "legofdmbw202gpo=0x43333333\0"
604 "mcsbw202gpo=0x63333333\0"
605 "mcsbw402gpo=0x66666666\0"
606 "swctrlmap_2g=0x00000000,0x00000000,0x00000000,0x00000000,0x000\0"
607 "xtalfreq=20000\0"
608 "otpimagesize=154\0"
609 "tempthresh=120\0"
610 "temps_period=5\0"
611 "temp_hysteresis=5\0"
612 "rssismf2g=0x8\0"
613 "rssismc2g=0x8\0"
614 "rssisav2g=0x2\0"
615 "END\0";
617 static char BCMATTACHDATA(defaultsromvars_43236usb)[] =
618 "vendid=0x14e4\0"
619 "subvendid=0x0a5c\0"
620 "subdevid=0xbdc\0"
621 "macaddr=00:90:4c:03:21:23\0"
622 "cctl=0\0"
623 "ccode=US\0"
624 "regrev=0x0\0"
625 "ledbh0=0x82\0"
626 "ledbh1=0xff\0"
627 "ledbh2=0xff\0"
628 "ledbh3=0xff\0"
629 "leddc=0x0\0"
630 "aa2g=0x3\0"
631 "aa5g=0x3\0"
632 "ag0=0x2\0"
633 "ag1=0x2\0"
634 "ag2=0x2\0"
635 "ag3=0xff\0"
636 "txchain=0x3\0"
637 "rxchain=0x3\0"
638 "antswitch=0\0"
639 "sromrev=8\0"
640 "devid=0x4346\0"
641 "boardrev=0x1532\0"
642 "boardflags=0x200\0"
643 "boardflags2=0x2000\0"
644 "boardtype=0x0521\0"
645 "tssipos2g=0x1\0"
646 "extpagain2g=0x2\0"
647 "pdetrange2g=0x2\0"
648 "triso2g=0x3\0"
649 "antswctl2g=0x0\0"
650 "tssipos5g=0x1\0"
651 "extpagain5g=0x2\0"
652 "pdetrange5g=0x2\0"
653 "triso5g=0x3\0"
654 "antswctl5g=0x0\0"
655 "ofdm2gpo=0x33333333\0"
656 "ofdm5gpo=0x0\0"
657 "ofdm5glpo=0x0\0"
658 "ofdm5ghpo=0x0\0"
659 "mcs2gpo0=0x3333\0"
660 "mcs2gpo1=0x3333\0"
661 "mcs2gpo2=0x3333\0"
662 "mcs2gpo3=0x3333\0"
663 "mcs2gpo4=0x5555\0"
664 "mcs2gpo5=0x5555\0"
665 "mcs2gpo6=0x5555\0"
666 "mcs2gpo7=0x5555\0"
667 "mcs5gpo4=0x2222\0"
668 "mcs5gpo5=0x2222\0"
669 "mcs5gpo6=0x2222\0"
670 "mcs5gpo7=0x2222\0"
671 "mcs5glpo4=0x2222\0"
672 "mcs5glpo5=0x2222\0"
673 "mcs5glpo6=0x2222\0"
674 "mcs5glpo7=0x2222\0"
675 "mcs5ghpo4=0x2222\0"
676 "mcs5ghpo5=0x2222\0"
677 "mcs5ghpo6=0x2222\0"
678 "mcs5ghpo7=0x2222\0"
679 "maxp2ga0=0x48\0"
680 "itt2ga0=0x20\0"
681 "itt5ga0=0x3e\0"
682 "pa2gw0a0=0xFFD8\0"
683 "pa2gw1a0=0x171C\0"
684 "pa2gw2a0=0xFB14\0"
685 "maxp5ga0=0x3e\0"
686 "maxp5gha0=0x3a\0"
687 "maxp5gla0=0x3c\0"
688 "pa5gw0a0=0xFE88\0"
689 "pa5gw1a0=0x141C\0"
690 "pa5gw2a0=0xFB17\0"
691 "pa5glw0a0=0xFE8C\0"
692 "pa5glw1a0=0x1493\0"
693 "pa5glw2a0=0xFAFC\0"
694 "pa5ghw0a0=0xFE86\0"
695 "pa5ghw1a0=0x13CC\0"
696 "pa5ghw2a0=0xFB20\0"
697 "maxp2ga1=0x48\0"
698 "itt2ga1=0x20\0"
699 "itt5ga1=0x3e\0"
700 "pa2gw0a1=0x0020\0"
701 "pa2gw1a1=0x1791\0"
702 "pa2gw2a1=0xFB5F\0"
703 "maxp5ga1=0x3e\0"
704 "maxp5gha1=0x3a\0"
705 "maxp5gla1=0x3c\0"
706 "pa5gw0a1=0xFE7E\0"
707 "pa5gw1a1=0x1399\0"
708 "pa5gw2a1=0xFB27\0"
709 "pa5glw0a1=0xFE82\0"
710 "pa5glw1a1=0x13F3\0"
711 "pa5glw2a1=0xFB14\0"
712 "pa5ghw0a1=0xFE96\0"
713 "pa5ghw1a1=0x13BF\0"
714 "pa5ghw2a1=0xFB30\0"
715 "tempthresh=120\0"
716 "temps_period=5\0"
717 "temp_hysteresis=5\0"
718 "END\0";
720 static char BCMATTACHDATA(defaultsromvars_4319usb)[] =
721 "sromrev=3\0"
722 "vendid=0x14e4\0"
723 "devid=0x4338\0"
724 "boardtype=0x4e7\0"
725 "boardrev=0x1508\0"
726 "boardflags=0x200\0"
727 "xtalfreq=30000\0"
728 "aa2g=3\0"
729 "aa5g=0\0"
730 "ag0=255\0"
731 "opo=0\0"
732 "pa0b0=5756\0"
733 "pa0b1=64121\0"
734 "pa0b2=65153\0"
735 "pa0itssit=62\0"
736 "pa0maxpwr=76\0"
737 "rssismf2g=0xa\0"
738 "rssismc2g=0xb\0"
739 "rssisav2g=0x3\0"
740 "bxa2g=0\0"
741 "tri2g=78\0"
742 "cckdigfilttype=6\0"
743 "rxpo2g=2\0"
744 "cckpo=0\0"
745 "ofdmpo=0x44441111\0"
746 "mcs2gpo0=0xaaaa\0"
747 "mcs2gpo1=0xaaaa\0"
748 "boardnum=1\0"
749 "macaddr=00:90:4c:16:${maclo}\0"
750 "otpimagesize=182\0"
751 "END\0";
753 static char BCMATTACHDATA(defaultsromvars_4360usb)[] =
754 "sromrev=11\0"
755 "boardtype=0x623\0"
756 "venid=0x14e4\0"
757 "boardvendor=0x14e4\0"
758 "devid=0x43a0\0"
759 "boardrev=0x1200\0"
760 "boardflags=0x10001000\0"
761 "boardflags2=0x0\0"
762 "boardflags3=0x0\0"
763 "macaddr=00:90:4c:0e:60:11\0"
764 "ccode=0\0"
765 "regrev=0\0"
766 "ledbh0=0xff\0"
767 "ledbh1=0xff\0"
768 "ledbh2=0xff\0"
769 "ledbh3=0xff\0"
770 "leddc=0xffff\0"
771 "aa2g=0x3\0"
772 "aa5g=0x3\0"
773 "agbg0=0x2\0"
774 "agbg1=0x2\0"
775 "agbg2=0xff\0"
776 "aga0=0x2\0"
777 "aga1=0x2\0"
778 "aga2=0xff\0"
779 "txchain=0x3\0"
780 "rxchain=0x3\0"
781 "antswitch=0\0"
782 "tssiposslope2g=1\0"
783 "epagain2g=0\0"
784 "pdgain2g=7\0"
785 "tworangetssi2g=0\0"
786 "papdcap2g=0\0"
787 "femctrl=1\0"
788 "tssiposslope5g=1\0"
789 "epagain5g=0\0"
790 "pdgain5g=7\0"
791 "tworangetssi5g=0\0"
792 "papdcap5g=0\0"
793 "gainctrlsph=0\0"
794 "tempthresh=0xff\0"
795 "tempoffset=0xff\0"
796 "rawtempsense=0x1ff\0"
797 "measpower=0x7f\0"
798 "tempsense_slope=0xff\0"
799 "tempcorrx=0x3f\0"
800 "tempsense_option=0x3\0"
801 "phycal_tempdelta=255\0"
802 "temps_period=15\0"
803 "temps_hysteresis=15\0"
804 "measpower1=0x7f\0"
805 "measpower2=0x7f\0"
806 "subband5gver=0x4\0"
807 "muxenab=0x01\0"
808 "pcieingress_war=15\0"
809 "sar2g=18\0"
810 "sar5g=15\0"
811 "noiselvl2ga0=31\0"
812 "noiselvl2ga1=31\0"
813 "noiselvl5ga0=31,31,31,31\0"
814 "noiselvl5ga1=31,31,31,31\0"
815 "rxgainerr2ga0=31\0"
816 "rxgainerr2ga1=31\0"
817 "rxgainerr5ga0=31,31,31,31\0"
818 "rxgainerr5ga1=31,31,31,31\0"
819 "maxp2ga0=76\0"
820 "pa2ga0=0xff34,0x19d6,0xfccf\0"
821 "rxgains2gelnagaina0=4\0"
822 "rxgains2gtrisoa0=9\0"
823 "rxgains2gtrelnabypa0=1\0"
824 "rxgains5gelnagaina0=3\0"
825 "rxgains5gtrisoa0=9\0"
826 "rxgains5gtrelnabypa0=1\0"
827 "maxp5ga0=72,72,76,76\0"
828 "pa5ga0=0xff2b,0x1652,0xfd2b,0xff2f,0x167a,0xfd29,0xff29,0x1615,0xfd2e,0xff2b,0x15c9,0xfd3a\0"
829 "maxp2ga1=76\0"
830 "pa2ga1=0xff27,0x1895,0xfced\0"
831 "rxgains2gelnagaina1=4\0"
832 "rxgains2gtrisoa1=9\0"
833 "rxgains2gtrelnabypa1=1\0"
834 "rxgains5gelnagaina1=3\0"
835 "rxgains5gtrisoa1=9\0"
836 "rxgains5gtrelnabypa1=1\0"
837 "maxp5ga1=72,72,72,72\0"
838 "pa5ga1=0xff27,0x171b,0xfd14,0xff2d,0x1741,0xfd0f,0xff33,0x1705,0xfd1a,0xff32,0x1666,0xfd2c\0"
839 "END\0";
841 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
842 #endif /* BCMUSBDEV */
845 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
846 #if defined(BCMHOSTVARS)
847 /* Also used by wl_readconfigdata for vars download */
848 char BCMATTACHDATA(mfgsromvars)[VARS_MAX];
849 int BCMATTACHDATA(defvarslen) = 0;
850 #endif
852 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
853 #if defined(BCMHOSTVARS)
854 static char BCMATTACHDATA(defaultsromvars_4331)[] =
855 "sromrev=9\0"
856 "boardrev=0x1104\0"
857 "boardflags=0x200\0"
858 "boardflags2=0x0\0"
859 "boardtype=0x524\0"
860 "boardvendor=0x14e4\0"
861 "boardnum=0x2064\0"
862 "macaddr=00:90:4c:1a:20:64\0"
863 "ccode=0x0\0"
864 "regrev=0x0\0"
865 "ledbh0=0xff\0"
866 "ledbh1=0xff\0"
867 "ledbh2=0xff\0"
868 "ledbh3=0xff\0"
869 "leddc=0xffff\0"
870 "opo=0x0\0"
871 "aa2g=0x7\0"
872 "aa5g=0x7\0"
873 "ag0=0x2\0"
874 "ag1=0x2\0"
875 "ag2=0x2\0"
876 "ag3=0xff\0"
877 "pa0b0=0xfe7f\0"
878 "pa0b1=0x15d9\0"
879 "pa0b2=0xfac6\0"
880 "pa0itssit=0x20\0"
881 "pa0maxpwr=0x48\0"
882 "pa1b0=0xfe89\0"
883 "pa1b1=0x14b1\0"
884 "pa1b2=0xfada\0"
885 "pa1lob0=0xffff\0"
886 "pa1lob1=0xffff\0"
887 "pa1lob2=0xffff\0"
888 "pa1hib0=0xfe8f\0"
889 "pa1hib1=0x13df\0"
890 "pa1hib2=0xfafa\0"
891 "pa1itssit=0x3e\0"
892 "pa1maxpwr=0x3c\0"
893 "pa1lomaxpwr=0x3c\0"
894 "pa1himaxpwr=0x3c\0"
895 "bxa2g=0x3\0"
896 "rssisav2g=0x7\0"
897 "rssismc2g=0xf\0"
898 "rssismf2g=0xf\0"
899 "bxa5g=0x3\0"
900 "rssisav5g=0x7\0"
901 "rssismc5g=0xf\0"
902 "rssismf5g=0xf\0"
903 "tri2g=0xff\0"
904 "tri5g=0xff\0"
905 "tri5gl=0xff\0"
906 "tri5gh=0xff\0"
907 "rxpo2g=0xff\0"
908 "rxpo5g=0xff\0"
909 "txchain=0x7\0"
910 "rxchain=0x7\0"
911 "antswitch=0x0\0"
912 "tssipos2g=0x1\0"
913 "extpagain2g=0x2\0"
914 "pdetrange2g=0x4\0"
915 "triso2g=0x3\0"
916 "antswctl2g=0x0\0"
917 "tssipos5g=0x1\0"
918 "elna2g=0xff\0"
919 "extpagain5g=0x2\0"
920 "pdetrange5g=0x4\0"
921 "triso5g=0x3\0"
922 "antswctl5g=0x0\0"
923 "elna5g=0xff\0"
924 "cckbw202gpo=0x0\0"
925 "cckbw20ul2gpo=0x0\0"
926 "legofdmbw202gpo=0x0\0"
927 "legofdmbw20ul2gpo=0x0\0"
928 "legofdmbw205glpo=0x0\0"
929 "legofdmbw20ul5glpo=0x0\0"
930 "legofdmbw205gmpo=0x0\0"
931 "legofdmbw20ul5gmpo=0x0\0"
932 "legofdmbw205ghpo=0x0\0"
933 "legofdmbw20ul5ghpo=0x0\0"
934 "mcsbw202gpo=0x0\0"
935 "mcsbw20ul2gpo=0x0\0"
936 "mcsbw402gpo=0x0\0"
937 "mcsbw205glpo=0x0\0"
938 "mcsbw20ul5glpo=0x0\0"
939 "mcsbw405glpo=0x0\0"
940 "mcsbw205gmpo=0x0\0"
941 "mcsbw20ul5gmpo=0x0\0"
942 "mcsbw405gmpo=0x0\0"
943 "mcsbw205ghpo=0x0\0"
944 "mcsbw20ul5ghpo=0x0\0"
945 "mcsbw405ghpo=0x0\0"
946 "mcs32po=0x0\0"
947 "legofdm40duppo=0x0\0"
948 "maxp2ga0=0x48\0"
949 "itt2ga0=0x20\0"
950 "itt5ga0=0x3e\0"
951 "pa2gw0a0=0xfe7f\0"
952 "pa2gw1a0=0x15d9\0"
953 "pa2gw2a0=0xfac6\0"
954 "maxp5ga0=0x3c\0"
955 "maxp5gha0=0x3c\0"
956 "maxp5gla0=0x3c\0"
957 "pa5gw0a0=0xfe89\0"
958 "pa5gw1a0=0x14b1\0"
959 "pa5gw2a0=0xfada\0"
960 "pa5glw0a0=0xffff\0"
961 "pa5glw1a0=0xffff\0"
962 "pa5glw2a0=0xffff\0"
963 "pa5ghw0a0=0xfe8f\0"
964 "pa5ghw1a0=0x13df\0"
965 "pa5ghw2a0=0xfafa\0"
966 "maxp2ga1=0x48\0"
967 "itt2ga1=0x20\0"
968 "itt5ga1=0x3e\0"
969 "pa2gw0a1=0xfe54\0"
970 "pa2gw1a1=0x1563\0"
971 "pa2gw2a1=0xfa7f\0"
972 "maxp5ga1=0x3c\0"
973 "maxp5gha1=0x3c\0"
974 "maxp5gla1=0x3c\0"
975 "pa5gw0a1=0xfe53\0"
976 "pa5gw1a1=0x14fe\0"
977 "pa5gw2a1=0xfa94\0"
978 "pa5glw0a1=0xffff\0"
979 "pa5glw1a1=0xffff\0"
980 "pa5glw2a1=0xffff\0"
981 "pa5ghw0a1=0xfe6e\0"
982 "pa5ghw1a1=0x1457\0"
983 "pa5ghw2a1=0xfab9\0"
984 "END\0";
986 static char BCMATTACHDATA(defaultsromvars_4360)[] =
987 "sromrev=11\0"
988 "boardrev=0x1421\0"
989 "boardflags=0x10401001\0"
990 "boardflags2=0x0\0"
991 "boardtype=0x61b\0"
992 "subvid=0x14e4\0"
993 "boardflags3=0x1\0"
994 "boardnum=62526\0"
995 "macaddr=00:90:4c:0d:f4:3e\0"
996 "ccode=X0\0"
997 "regrev=15\0"
998 "aa2g=7\0"
999 "aa5g=7\0"
1000 "agbg0=71\0"
1001 "agbg1=71\0"
1002 "agbg2=133\0"
1003 "aga0=71\0"
1004 "aga1=133\0"
1005 "aga2=133\0"
1006 "antswitch=0\0"
1007 "tssiposslope2g=1\0"
1008 "epagain2g=0\0"
1009 "pdgain2g=9\0"
1010 "tworangetssi2g=0\0"
1011 "papdcap2g=0\0"
1012 "femctrl=2\0"
1013 "tssiposslope5g=1\0"
1014 "epagain5g=0\0"
1015 "pdgain5g=9\0"
1016 "tworangetssi5g=0\0"
1017 "papdcap5g=0\0"
1018 "gainctrlsph=0\0"
1019 "tempthresh=255\0"
1020 "tempoffset=255\0"
1021 "rawtempsense=0x1ff\0"
1022 "measpower=0x7f\0"
1023 "tempsense_slope=0xff\0"
1024 "tempcorrx=0x3f\0"
1025 "tempsense_option=0x3\0"
1026 "xtalfreq=65535\0"
1027 "phycal_tempdelta=255\0"
1028 "temps_period=15\0"
1029 "temps_hysteresis=15\0"
1030 "measpower1=0x7f\0"
1031 "measpower2=0x7f\0"
1032 "pdoffset2g40ma0=15\0"
1033 "pdoffset2g40ma1=15\0"
1034 "pdoffset2g40ma2=15\0"
1035 "pdoffset2g40mvalid=1\0"
1036 "pdoffset40ma0=9010\0"
1037 "pdoffset40ma1=12834\0"
1038 "pdoffset40ma2=8994\0"
1039 "pdoffset80ma0=16\0"
1040 "pdoffset80ma1=4096\0"
1041 "pdoffset80ma2=0\0"
1042 "subband5gver=0x4\0"
1043 "cckbw202gpo=0\0"
1044 "cckbw20ul2gpo=0\0"
1045 "mcsbw202gpo=2571386880\0"
1046 "mcsbw402gpo=2571386880\0"
1047 "dot11agofdmhrbw202gpo=17408\0"
1048 "ofdmlrbw202gpo=0\0"
1049 "mcsbw205glpo=4001923072\0"
1050 "mcsbw405glpo=4001923072\0"
1051 "mcsbw805glpo=4001923072\0"
1052 "mcsbw1605glpo=0\0"
1053 "mcsbw205gmpo=3431497728\0"
1054 "mcsbw405gmpo=3431497728\0"
1055 "mcsbw805gmpo=3431497728\0"
1056 "mcsbw1605gmpo=0\0"
1057 "mcsbw205ghpo=3431497728\0"
1058 "mcsbw405ghpo=3431497728\0"
1059 "mcsbw805ghpo=3431497728\0"
1060 "mcsbw1605ghpo=0\0"
1061 "mcslr5glpo=0\0"
1062 "mcslr5gmpo=0\0"
1063 "mcslr5ghpo=0\0"
1064 "sb20in40hrpo=0\0"
1065 "sb20in80and160hr5glpo=0\0"
1066 "sb40and80hr5glpo=0\0"
1067 "sb20in80and160hr5gmpo=0\0"
1068 "sb40and80hr5gmpo=0\0"
1069 "sb20in80and160hr5ghpo=0\0"
1070 "sb40and80hr5ghpo=0\0"
1071 "sb20in40lrpo=0\0"
1072 "sb20in80and160lr5glpo=0\0"
1073 "sb40and80lr5glpo=0\0"
1074 "sb20in80and160lr5gmpo=0\0"
1075 "sb40and80lr5gmpo=0\0"
1076 "sb20in80and160lr5ghpo=0\0"
1077 "sb40and80lr5ghpo=0\0"
1078 "dot11agduphrpo=0\0"
1079 "dot11agduplrpo=0\0"
1080 "pcieingress_war=15\0"
1081 "sar2g=18\0"
1082 "sar5g=15\0"
1083 "noiselvl2ga0=31\0"
1084 "noiselvl2ga1=31\0"
1085 "noiselvl2ga2=31\0"
1086 "noiselvl5ga0=31,31,31,31\0"
1087 "noiselvl5ga1=31,31,31,31\0"
1088 "noiselvl5ga2=31,31,31,31\0"
1089 "rxgainerr2ga0=63\0"
1090 "rxgainerr2ga1=31\0"
1091 "rxgainerr2ga2=31\0"
1092 "rxgainerr5ga0=63,63,63,63\0"
1093 "rxgainerr5ga1=31,31,31,31\0"
1094 "rxgainerr5ga2=31,31,31,31\0"
1095 "maxp2ga0=76\0"
1096 "pa2ga0=0xff3c,0x172c,0xfd20\0"
1097 "rxgains5gmelnagaina0=7\0"
1098 "rxgains5gmtrisoa0=15\0"
1099 "rxgains5gmtrelnabypa0=1\0"
1100 "rxgains5ghelnagaina0=7\0"
1101 "rxgains5ghtrisoa0=15\0"
1102 "rxgains5ghtrelnabypa0=1\0"
1103 "rxgains2gelnagaina0=4\0"
1104 "rxgains2gtrisoa0=7\0"
1105 "rxgains2gtrelnabypa0=1\0"
1106 "rxgains5gelnagaina0=3\0"
1107 "rxgains5gtrisoa0=7\0"
1108 "rxgains5gtrelnabypa0=1\0"
1109 "maxp5ga0=76,76,76,76\0"
1110 "pa5ga0=0xff3a,0x14d4,0xfd5f,0xff36,0x1626,0xfd2e,0xff42,0x15bd,0xfd47,0xff39,0x15a3,0xfd3d\0"
1111 "maxp2ga1=76\0"
1112 "pa2ga1=0xff2a,0x16b2,0xfd28\0"
1113 "rxgains5gmelnagaina1=7\0"
1114 "rxgains5gmtrisoa1=15\0"
1115 "rxgains5gmtrelnabypa1=1\0"
1116 "rxgains5ghelnagaina1=7\0"
1117 "rxgains5ghtrisoa1=15\0"
1118 "rxgains5ghtrelnabypa1=1\0"
1119 "rxgains2gelnagaina1=3\0"
1120 "rxgains2gtrisoa1=6\0"
1121 "rxgains2gtrelnabypa1=1\0"
1122 "rxgains5gelnagaina1=3\0"
1123 "rxgains5gtrisoa1=6\0"
1124 "rxgains5gtrelnabypa1=1\0"
1125 "maxp5ga1=76,76,76,76\0"
1126 "pa5ga1=0xff4e,0x1530,0xfd53,0xff58,0x15b4,0xfd4d,0xff58,0x1671,0xfd2f,0xff55,0x15e2,0xfd46\0"
1127 "maxp2ga2=76\0"
1128 "pa2ga2=0xff3c,0x1736,0xfd1f\0"
1129 "rxgains5gmelnagaina2=7\0"
1130 "rxgains5gmtrisoa2=15\0"
1131 "rxgains5gmtrelnabypa2=1\0"
1132 "rxgains5ghelnagaina2=7\0"
1133 "rxgains5ghtrisoa2=15\0"
1134 "rxgains5ghtrelnabypa2=1\0"
1135 "rxgains2gelnagaina2=4\0"
1136 "rxgains2gtrisoa2=7\0"
1137 "rxgains2gtrelnabypa2=1\0"
1138 "rxgains5gelnagaina2=3\0"
1139 "rxgains5gtrisoa2=7\0"
1140 "rxgains5gtrelnabypa2=1\0"
1141 "maxp5ga2=76,76,76,76\0"
1142 "pa5ga2=0xff2d,0x144a,0xfd63,0xff35,0x15d7,0xfd3b,0xff35,0x1668,0xfd2f,0xff31,0x1664,0xfd27\0"
1143 "END\0";
1145 static char BCMATTACHDATA(defaultsromvars_4335)[] =
1146 "sromrev=11\0"
1147 "boardrev=0x1104\0"
1148 "boardtype=0x0647\0"
1149 "boardflags=0x10401001\0"
1150 "boardflags2=0x0\0"
1151 "boardflags3=0x0\0"
1152 "macaddr=00:90:4c:c5:43:55\0"
1153 "ccode=0\0"
1154 "regrev=0\0"
1155 "antswitch=0\0"
1156 "pdgain2g=0\0"
1157 "pdgain5g=0\0"
1158 "tworangetssi2g=0\0"
1159 "tworangetssi5g=0\0"
1160 "femctrl=4\0"
1161 "pcieingress_war=15\0"
1162 "vendid=0x14e4\0"
1163 "devid=0x43ae\0"
1164 "manfid=0x2d0\0"
1165 "#prodid=0x052e\0"
1166 "nocrc=1\0"
1167 "xtalfreq=40000\0"
1168 "extpagain2g=1\0"
1169 "pdetrange2g=2\0"
1170 "extpagain5g=1\0"
1171 "pdetrange5g=2\0"
1172 "rxgains2gelnagaina0=3\0"
1173 "rxgains2gtrisoa0=3\0"
1174 "rxgains2gtrelnabypa0=1\0"
1175 "rxgains5gelnagaina0=3\0"
1176 "rxgains5gtrisoa0=4\0"
1177 "rxgains5gtrelnabypa0=1\0"
1178 "pdgain5g=10\0"
1179 "pdgain2g=10\0"
1180 "rxchain=1\0"
1181 "txchain=1\0"
1182 "aa2g=1\0"
1183 "aa5g=1\0"
1184 "tssipos5g=1\0"
1185 "tssipos2g=1\0"
1186 "pa2ga0=0x0,0x0,0x0\0"
1187 "pa5ga0=-217,5493,-673\0"
1188 "tssifloor2g=0x3ff\0"
1189 "tssifloor5g=0x3ff,0x3ff,0x3ff,0x3ff\0"
1190 "pdoffset40ma0=0\0"
1191 "pdoffset80ma0=0\0"
1192 "END\0";
1193 #endif
1195 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
1196 #if defined(BCMHOSTVARS)
1197 static char BCMATTACHDATA(defaultsromvars_wltest)[] =
1198 "macaddr=00:90:4c:f8:00:01\0"
1199 "et0macaddr=00:11:22:33:44:52\0"
1200 "et0phyaddr=30\0"
1201 "et0mdcport=0\0"
1202 "gpio2=robo_reset\0"
1203 "boardvendor=0x14e4\0"
1204 "boardflags=0x210\0"
1205 "boardflags2=0\0"
1206 "boardtype=0x04c3\0"
1207 "boardrev=0x1100\0"
1208 "sromrev=8\0"
1209 "devid=0x432c\0"
1210 "ccode=0\0"
1211 "regrev=0\0"
1212 "ledbh0=255\0"
1213 "ledbh1=255\0"
1214 "ledbh2=255\0"
1215 "ledbh3=255\0"
1216 "leddc=0xffff\0"
1217 "aa2g=3\0"
1218 "ag0=2\0"
1219 "ag1=2\0"
1220 "aa5g=3\0"
1221 "aa0=2\0"
1222 "aa1=2\0"
1223 "txchain=3\0"
1224 "rxchain=3\0"
1225 "antswitch=0\0"
1226 "itt2ga0=0x20\0"
1227 "maxp2ga0=0x48\0"
1228 "pa2gw0a0=0xfe9e\0"
1229 "pa2gw1a0=0x15d5\0"
1230 "pa2gw2a0=0xfae9\0"
1231 "itt2ga1=0x20\0"
1232 "maxp2ga1=0x48\0"
1233 "pa2gw0a1=0xfeb3\0"
1234 "pa2gw1a1=0x15c9\0"
1235 "pa2gw2a1=0xfaf7\0"
1236 "tssipos2g=1\0"
1237 "extpagain2g=0\0"
1238 "pdetrange2g=0\0"
1239 "triso2g=3\0"
1240 "antswctl2g=0\0"
1241 "tssipos5g=1\0"
1242 "extpagain5g=0\0"
1243 "pdetrange5g=0\0"
1244 "triso5g=3\0"
1245 "antswctl5g=0\0"
1246 "cck2gpo=0\0"
1247 "ofdm2gpo=0\0"
1248 "mcs2gpo0=0\0"
1249 "mcs2gpo1=0\0"
1250 "mcs2gpo2=0\0"
1251 "mcs2gpo3=0\0"
1252 "mcs2gpo4=0\0"
1253 "mcs2gpo5=0\0"
1254 "mcs2gpo6=0\0"
1255 "mcs2gpo7=0\0"
1256 "cddpo=0\0"
1257 "stbcpo=0\0"
1258 "bw40po=4\0"
1259 "bwduppo=0\0"
1260 "END\0";
1261 #endif
1263 static bool srvars_inited = FALSE; /* Use OTP/SROM as global variables */
1265 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
1266 #if defined(BCMHOSTVARS) || (defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND))
1267 /* It must end with pattern of "END" */
1268 static uint
1269 BCMATTACHFN(srom_vars_len)(char *vars)
1271 uint pos = 0;
1272 uint len;
1273 char *s;
1275 for (s = vars; s && *s;) {
1277 if (strcmp(s, "END") == 0)
1278 break;
1280 len = strlen(s);
1281 s += strlen(s) + 1;
1282 pos += len + 1;
1283 /* BS_ERROR(("len %d vars[pos] %s\n", pos, s)); */
1284 if (pos > 4000) {
1285 return 0;
1289 return pos + 4; /* include the "END\0" */
1291 #endif
1293 /* Initialization of varbuf structure */
1294 static void
1295 BCMATTACHFN(varbuf_init)(varbuf_t *b, char *buf, uint size)
1297 b->size = size;
1298 b->base = b->buf = buf;
1301 /* append a null terminated var=value string */
1302 static int
1303 BCMATTACHFN(varbuf_append)(varbuf_t *b, const char *fmt, ...)
1305 va_list ap;
1306 int r;
1307 size_t len;
1308 char *s;
1310 if (b->size < 2)
1311 return 0;
1313 va_start(ap, fmt);
1314 r = vsnprintf(b->buf, b->size, fmt, ap);
1315 va_end(ap);
1317 /* C99 snprintf behavior returns r >= size on overflow,
1318 * others return -1 on overflow.
1319 * All return -1 on format error.
1320 * We need to leave room for 2 null terminations, one for the current var
1321 * string, and one for final null of the var table. So check that the
1322 * strlen written, r, leaves room for 2 chars.
1324 if ((r == -1) || (r > (int)(b->size - 2))) {
1325 b->size = 0;
1326 return 0;
1329 /* Remove any earlier occurrence of the same variable */
1330 if ((s = strchr(b->buf, '=')) != NULL) {
1331 len = (size_t)(s - b->buf);
1332 for (s = b->base; s < b->buf;) {
1333 if ((bcmp(s, b->buf, len) == 0) && s[len] == '=') {
1334 len = strlen(s) + 1;
1335 memmove(s, (s + len), ((b->buf + r + 1) - (s + len)));
1336 b->buf -= len;
1337 b->size += (unsigned int)len;
1338 break;
1341 while (*s++)
1346 /* skip over this string's null termination */
1347 r++;
1348 b->size -= r;
1349 b->buf += r;
1351 return r;
1355 * Initialize local vars from the right source for this platform.
1356 * Return 0 on success, nonzero on error.
1359 BCMATTACHFN(srom_var_init)(si_t *sih, uint bustype, void *curmap, osl_t *osh,
1360 char **vars, uint *count)
1362 ASSERT(bustype == BUSTYPE(bustype));
1363 if (vars == NULL || count == NULL)
1364 return (0);
1366 *vars = NULL;
1367 *count = 0;
1369 switch (BUSTYPE(bustype)) {
1370 case SI_BUS:
1371 case JTAG_BUS:
1372 return initvars_srom_si(sih, osh, curmap, vars, count);
1374 case PCI_BUS:
1375 ASSERT(curmap != NULL);
1376 if (curmap == NULL)
1377 return (-1);
1379 return initvars_srom_pci(sih, curmap, vars, count);
1381 case PCMCIA_BUS:
1382 return initvars_cis_pcmcia(sih, osh, vars, count);
1385 #ifdef BCMSPI
1386 case SPI_BUS:
1387 return initvars_cis_spi(osh, vars, count);
1388 #endif /* BCMSPI */
1390 default:
1391 ASSERT(0);
1393 return (-1);
1396 /* support only 16-bit word read from srom */
1398 srom_read(si_t *sih, uint bustype, void *curmap, osl_t *osh,
1399 uint byteoff, uint nbytes, uint16 *buf, bool check_crc)
1401 uint i, off, nw;
1403 ASSERT(bustype == BUSTYPE(bustype));
1405 /* check input - 16-bit access only */
1406 if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > SROM_MAX)
1407 return 1;
1409 off = byteoff / 2;
1410 nw = nbytes / 2;
1412 if (BUSTYPE(bustype) == PCI_BUS) {
1413 if (!curmap)
1414 return 1;
1416 if (si_is_sprom_available(sih)) {
1417 uint16 *srom;
1419 srom = (uint16 *)SROM_OFFSET(sih);
1420 if (srom == NULL)
1421 return 1;
1423 if (sprom_read_pci(osh, sih, srom, off, buf, nw, check_crc))
1424 return 1;
1426 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
1427 else {
1428 if (otp_read_pci(osh, sih, buf, nbytes))
1429 return 1;
1431 #endif
1432 } else if (BUSTYPE(bustype) == PCMCIA_BUS) {
1433 for (i = 0; i < nw; i++) {
1434 if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16 *)(buf + i)))
1435 return 1;
1437 #ifdef BCMSPI
1438 } else if (BUSTYPE(bustype) == SPI_BUS) {
1439 if (bcmsdh_cis_read(NULL, SDIO_FUNC_1, (uint8 *)buf, byteoff + nbytes) != 0)
1440 return 1;
1441 #endif /* BCMSPI */
1442 } else if (BUSTYPE(bustype) == SI_BUS) {
1443 #if defined(BCMUSBDEV)
1444 if (SPROMBUS == PCMCIA_BUS) {
1445 uint origidx;
1446 void *regs;
1447 int rc;
1448 bool wasup;
1450 /* Don't bother if we can't talk to SPROM */
1451 if (!si_is_sprom_available(sih))
1452 return 1;
1454 origidx = si_coreidx(sih);
1455 regs = si_setcore(sih, PCMCIA_CORE_ID, 0);
1456 if (!regs)
1457 regs = si_setcore(sih, SDIOD_CORE_ID, 0);
1458 ASSERT(regs != NULL);
1460 if (!(wasup = si_iscoreup(sih)))
1461 si_core_reset(sih, 0, 0);
1463 rc = get_si_pcmcia_srom(sih, osh, regs, byteoff, buf, nbytes, check_crc);
1465 if (!wasup)
1466 si_core_disable(sih, 0);
1468 si_setcoreidx(sih, origidx);
1469 return rc;
1471 #endif
1473 return 1;
1474 } else {
1475 return 1;
1478 return 0;
1481 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
1482 /* support only 16-bit word write into srom */
1484 srom_write(si_t *sih, uint bustype, void *curmap, osl_t *osh,
1485 uint byteoff, uint nbytes, uint16 *buf)
1487 uint i, nw, crc_range;
1488 uint16 *old, *new;
1489 uint8 crc;
1490 volatile uint32 val32;
1491 int rc = 1;
1493 ASSERT(bustype == BUSTYPE(bustype));
1495 old = MALLOC(osh, SROM_MAXW * sizeof(uint16));
1496 new = MALLOC(osh, SROM_MAXW * sizeof(uint16));
1498 if (old == NULL || new == NULL)
1499 goto done;
1501 /* check input - 16-bit access only. use byteoff 0x55aa to indicate
1502 * srclear
1504 if ((byteoff != 0x55aa) && ((byteoff & 1) || (nbytes & 1)))
1505 goto done;
1507 if ((byteoff != 0x55aa) && ((byteoff + nbytes) > SROM_MAX))
1508 goto done;
1510 if (BUSTYPE(bustype) == PCMCIA_BUS) {
1511 crc_range = SROM_MAX;
1513 #if defined(BCMUSBDEV)
1514 else {
1515 crc_range = srom_size(sih, osh);
1517 #else
1518 else {
1519 crc_range = (SROM8_SIGN + 1) * 2; /* must big enough for SROM8 */
1521 #endif
1523 nw = crc_range / 2;
1524 /* read first small number words from srom, then adjust the length, read all */
1525 if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE))
1526 goto done;
1528 BS_ERROR(("%s: old[SROM4_SIGN] 0x%x, old[SROM8_SIGN] 0x%x\n",
1529 __FUNCTION__, old[SROM4_SIGN], old[SROM8_SIGN]));
1530 /* Deal with blank srom */
1531 if (old[0] == 0xffff) {
1532 /* see if the input buffer is valid SROM image or not */
1533 if (buf[SROM11_SIGN] == SROM11_SIGNATURE) {
1534 BS_ERROR(("%s: buf[SROM11_SIGN] 0x%x\n",
1535 __FUNCTION__, buf[SROM11_SIGN]));
1537 /* block invalid buffer size */
1538 if (nbytes < SROM11_WORDS * 2) {
1539 rc = BCME_BUFTOOSHORT;
1540 goto done;
1541 } else if (nbytes > SROM11_WORDS * 2) {
1542 rc = BCME_BUFTOOLONG;
1543 goto done;
1546 nw = SROM11_WORDS;
1547 } else if ((buf[SROM4_SIGN] == SROM4_SIGNATURE) ||
1548 (buf[SROM8_SIGN] == SROM4_SIGNATURE)) {
1549 BS_ERROR(("%s: buf[SROM4_SIGN] 0x%x, buf[SROM8_SIGN] 0x%x\n",
1550 __FUNCTION__, buf[SROM4_SIGN], buf[SROM8_SIGN]));
1552 /* block invalid buffer size */
1553 if (nbytes < SROM4_WORDS * 2) {
1554 rc = BCME_BUFTOOSHORT;
1555 goto done;
1556 } else if (nbytes > SROM4_WORDS * 2) {
1557 rc = BCME_BUFTOOLONG;
1558 goto done;
1561 nw = SROM4_WORDS;
1562 } else if (nbytes == SROM_WORDS * 2){ /* the other possible SROM format */
1563 BS_ERROR(("%s: Not SROM4 or SROM8.\n", __FUNCTION__));
1565 nw = SROM_WORDS;
1566 } else {
1567 BS_ERROR(("%s: Invalid input file signature\n", __FUNCTION__));
1568 rc = BCME_BADARG;
1569 goto done;
1571 crc_range = nw * 2;
1572 if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE))
1573 goto done;
1574 } else if (old[SROM11_SIGN] == SROM11_SIGNATURE) {
1575 nw = SROM11_WORDS;
1576 crc_range = nw * 2;
1577 if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE))
1578 goto done;
1579 } else if ((old[SROM4_SIGN] == SROM4_SIGNATURE) ||
1580 (old[SROM8_SIGN] == SROM4_SIGNATURE)) {
1581 nw = SROM4_WORDS;
1582 crc_range = nw * 2;
1583 if (srom_read(sih, bustype, curmap, osh, 0, crc_range, old, FALSE))
1584 goto done;
1585 } else {
1586 /* Assert that we have already read enough for sromrev 2 */
1587 ASSERT(crc_range >= SROM_WORDS * 2);
1588 nw = SROM_WORDS;
1589 crc_range = nw * 2;
1592 if (byteoff == 0x55aa) {
1593 /* Erase request */
1594 crc_range = 0;
1595 memset((void *)new, 0xff, nw * 2);
1596 } else {
1597 /* Copy old contents */
1598 bcopy((void *)old, (void *)new, nw * 2);
1599 /* make changes */
1600 bcopy((void *)buf, (void *)&new[byteoff / 2], nbytes);
1603 if (crc_range) {
1604 /* calculate crc */
1605 htol16_buf(new, crc_range);
1606 crc = ~hndcrc8((uint8 *)new, crc_range - 1, CRC8_INIT_VALUE);
1607 ltoh16_buf(new, crc_range);
1608 new[nw - 1] = (crc << 8) | (new[nw - 1] & 0xff);
1611 if (BUSTYPE(bustype) == PCI_BUS) {
1612 uint16 *srom = NULL;
1613 void *ccregs = NULL;
1614 uint32 ccval = 0;
1616 if ((CHIPID(sih->chip) == BCM4331_CHIP_ID) ||
1617 (CHIPID(sih->chip) == BCM43431_CHIP_ID) ||
1618 (CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
1619 (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
1620 (CHIPID(sih->chip) == BCM43526_CHIP_ID) ||
1621 (CHIPID(sih->chip) == BCM4352_CHIP_ID)) {
1622 /* save current control setting */
1623 ccval = si_chipcontrl_read(sih);
1626 if ((CHIPID(sih->chip) == BCM4331_CHIP_ID) ||
1627 (CHIPID(sih->chip) == BCM43431_CHIP_ID)) {
1628 /* Disable Ext PA lines to allow reading from SROM */
1629 si_chipcontrl_epa4331(sih, FALSE);
1630 } else if (((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
1631 (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
1632 (CHIPID(sih->chip) == BCM4352_CHIP_ID)) &&
1633 (CHIPREV(sih->chiprev) <= 2)) {
1634 si_chipcontrl_srom4360(sih, TRUE);
1637 /* enable writes to the SPROM */
1638 if (sih->ccrev > 31) {
1639 ccregs = (void *)((uint8 *)curmap + PCI_16KB0_CCREGS_OFFSET);
1640 srom = (uint16 *)((uint8 *)ccregs + CC_SROM_OTP);
1641 (void)srom_cc_cmd(sih, osh, ccregs, SRC_OP_WREN, 0, 0);
1642 } else {
1643 srom = (uint16 *)((uint8 *)curmap + PCI_BAR0_SPROM_OFFSET);
1644 val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
1645 val32 |= SPROM_WRITEEN;
1646 OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32);
1648 bcm_mdelay(WRITE_ENABLE_DELAY);
1649 /* write srom */
1650 for (i = 0; i < nw; i++) {
1651 if (old[i] != new[i]) {
1652 if (sih->ccrev > 31) {
1653 if ((sih->cccaps & CC_CAP_SROM) == 0) {
1654 /* No srom support in this chip */
1655 BS_ERROR(("srom_write, invalid srom, skip\n"));
1656 } else
1657 (void)srom_cc_cmd(sih, osh, ccregs, SRC_OP_WRITE,
1658 i, new[i]);
1659 } else {
1660 W_REG(osh, &srom[i], new[i]);
1662 bcm_mdelay(WRITE_WORD_DELAY);
1665 /* disable writes to the SPROM */
1666 if (sih->ccrev > 31) {
1667 (void)srom_cc_cmd(sih, osh, ccregs, SRC_OP_WRDIS, 0, 0);
1668 } else {
1669 OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 &
1670 ~SPROM_WRITEEN);
1673 if ((CHIPID(sih->chip) == BCM4331_CHIP_ID) ||
1674 (CHIPID(sih->chip) == BCM43431_CHIP_ID) ||
1675 (CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
1676 (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
1677 (CHIPID(sih->chip) == BCM4352_CHIP_ID)) {
1678 /* Restore config after reading SROM */
1679 si_chipcontrl_restore(sih, ccval);
1682 } else if (BUSTYPE(bustype) == PCMCIA_BUS) {
1683 /* enable writes to the SPROM */
1684 if (sprom_cmd_pcmcia(osh, SROM_WEN))
1685 goto done;
1686 bcm_mdelay(WRITE_ENABLE_DELAY);
1687 /* write srom */
1688 for (i = 0; i < nw; i++) {
1689 if (old[i] != new[i]) {
1690 sprom_write_pcmcia(osh, (uint16)(i), new[i]);
1691 bcm_mdelay(WRITE_WORD_DELAY);
1694 /* disable writes to the SPROM */
1695 if (sprom_cmd_pcmcia(osh, SROM_WDS))
1696 goto done;
1697 } else if (BUSTYPE(bustype) == SI_BUS) {
1698 #if defined(BCMUSBDEV)
1699 if (SPROMBUS == PCMCIA_BUS) {
1700 uint origidx;
1701 void *regs;
1702 bool wasup;
1704 origidx = si_coreidx(sih);
1705 regs = si_setcore(sih, PCMCIA_CORE_ID, 0);
1706 if (!regs)
1707 regs = si_setcore(sih, SDIOD_CORE_ID, 0);
1708 ASSERT(regs != NULL);
1710 if (!(wasup = si_iscoreup(sih)))
1711 si_core_reset(sih, 0, 0);
1713 rc = set_si_pcmcia_srom(sih, osh, regs, byteoff, buf, nbytes);
1715 if (!wasup)
1716 si_core_disable(sih, 0);
1718 si_setcoreidx(sih, origidx);
1719 goto done;
1721 #endif
1722 goto done;
1723 } else {
1724 goto done;
1727 bcm_mdelay(WRITE_ENABLE_DELAY);
1728 rc = 0;
1730 done:
1731 if (old != NULL)
1732 MFREE(osh, old, SROM_MAXW * sizeof(uint16));
1733 if (new != NULL)
1734 MFREE(osh, new, SROM_MAXW * sizeof(uint16));
1736 return rc;
1738 #endif
1740 #if defined(BCMUSBDEV)
1741 #define SI_PCMCIA_READ(osh, regs, fcr) \
1742 R_REG(osh, (volatile uint8 *)(regs) + 0x600 + (fcr) - 0x700 / 2)
1743 #define SI_PCMCIA_WRITE(osh, regs, fcr, v) \
1744 W_REG(osh, (volatile uint8 *)(regs) + 0x600 + (fcr) - 0x700 / 2, v)
1746 /* set PCMCIA srom command register */
1747 static int
1748 srom_cmd_si_pcmcia(osl_t *osh, uint8 *pcmregs, uint8 cmd)
1750 uint8 status = 0;
1751 uint wait_cnt = 0;
1753 /* write srom command register */
1754 SI_PCMCIA_WRITE(osh, pcmregs, SROM_CS, cmd);
1756 /* wait status */
1757 while (++wait_cnt < 1000000) {
1758 status = SI_PCMCIA_READ(osh, pcmregs, SROM_CS);
1759 if (status & SROM_DONE)
1760 return 0;
1761 OSL_DELAY(1);
1764 BS_ERROR(("sr_cmd: Give up after %d tries, stat = 0x%x\n", wait_cnt, status));
1765 return 1;
1768 /* read a word from the PCMCIA srom over SI */
1769 static int
1770 srom_read_si_pcmcia(osl_t *osh, uint8 *pcmregs, uint16 addr, uint16 *data)
1772 uint8 addr_l, addr_h, data_l, data_h;
1774 addr_l = (uint8)((addr * 2) & 0xff);
1775 addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
1777 /* set address */
1778 SI_PCMCIA_WRITE(osh, pcmregs, SROM_ADDRH, addr_h);
1779 SI_PCMCIA_WRITE(osh, pcmregs, SROM_ADDRL, addr_l);
1781 /* do read */
1782 if (srom_cmd_si_pcmcia(osh, pcmregs, SROM_READ))
1783 return 1;
1785 /* read data */
1786 data_h = SI_PCMCIA_READ(osh, pcmregs, SROM_DATAH);
1787 data_l = SI_PCMCIA_READ(osh, pcmregs, SROM_DATAL);
1788 *data = ((uint16)data_h << 8) | data_l;
1790 return 0;
1793 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
1794 /* write a word to the PCMCIA srom over SI */
1795 static int
1796 srom_write_si_pcmcia(osl_t *osh, uint8 *pcmregs, uint16 addr, uint16 data)
1798 uint8 addr_l, addr_h, data_l, data_h;
1799 int rc;
1801 addr_l = (uint8)((addr * 2) & 0xff);
1802 addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
1804 /* set address */
1805 SI_PCMCIA_WRITE(osh, pcmregs, SROM_ADDRH, addr_h);
1806 SI_PCMCIA_WRITE(osh, pcmregs, SROM_ADDRL, addr_l);
1808 data_l = (uint8)(data & 0xff);
1809 data_h = (uint8)((data >> 8) & 0xff);
1811 /* write data */
1812 SI_PCMCIA_WRITE(osh, pcmregs, SROM_DATAH, data_h);
1813 SI_PCMCIA_WRITE(osh, pcmregs, SROM_DATAL, data_l);
1815 /* do write */
1816 rc = srom_cmd_si_pcmcia(osh, pcmregs, SROM_WRITE);
1817 OSL_DELAY(20000);
1818 return rc;
1820 #endif
1823 * Read the srom for the pcmcia-srom over si case.
1824 * Return 0 on success, nonzero on error.
1826 static int
1827 get_si_pcmcia_srom(si_t *sih, osl_t *osh, uint8 *pcmregs,
1828 uint boff, uint16 *srom, uint bsz, bool check_crc)
1830 uint i, nw, woff, wsz;
1831 int err = 0;
1833 /* read must be at word boundary */
1834 ASSERT((boff & 1) == 0 && (bsz & 1) == 0);
1836 /* read sprom size and validate the parms */
1837 if ((nw = srom_size(sih, osh)) == 0) {
1838 BS_ERROR(("get_si_pcmcia_srom: sprom size unknown\n"));
1839 err = -1;
1840 goto out;
1842 if (boff + bsz > 2 * nw) {
1843 BS_ERROR(("get_si_pcmcia_srom: sprom size exceeded\n"));
1844 err = -2;
1845 goto out;
1848 /* read in sprom contents */
1849 for (woff = boff / 2, wsz = bsz / 2, i = 0;
1850 woff < nw && i < wsz; woff ++, i ++) {
1851 if (srom_read_si_pcmcia(osh, pcmregs, (uint16)woff, &srom[i])) {
1852 BS_ERROR(("get_si_pcmcia_srom: sprom read failed\n"));
1853 err = -3;
1854 goto out;
1858 if (check_crc) {
1859 if (srom[0] == 0xffff) {
1860 /* The hardware thinks that an srom that starts with 0xffff
1861 * is blank, regardless of the rest of the content, so declare
1862 * it bad.
1864 BS_ERROR(("%s: srom[0] == 0xffff, assuming unprogrammed srom\n",
1865 __FUNCTION__));
1866 err = -4;
1867 goto out;
1870 /* fixup the endianness so crc8 will pass */
1871 htol16_buf(srom, nw * 2);
1872 if (hndcrc8((uint8 *)srom, nw * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) {
1873 BS_ERROR(("%s: bad crc\n", __FUNCTION__));
1874 err = -5;
1876 /* now correct the endianness of the byte array */
1877 ltoh16_buf(srom, nw * 2);
1880 out:
1881 return err;
1884 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
1886 * Write the srom for the pcmcia-srom over si case.
1887 * Return 0 on success, nonzero on error.
1889 static int
1890 set_si_pcmcia_srom(si_t *sih, osl_t *osh, uint8 *pcmregs,
1891 uint boff, uint16 *srom, uint bsz)
1893 uint i, nw, woff, wsz;
1894 uint16 word;
1895 uint8 crc;
1896 int err = 0;
1898 /* write must be at word boundary */
1899 ASSERT((boff & 1) == 0 && (bsz & 1) == 0);
1901 /* read sprom size and validate the parms */
1902 if ((nw = srom_size(sih, osh)) == 0) {
1903 BS_ERROR(("set_si_pcmcia_srom: sprom size unknown\n"));
1904 err = -1;
1905 goto out;
1907 if (boff + bsz > 2 * nw) {
1908 BS_ERROR(("set_si_pcmcia_srom: sprom size exceeded\n"));
1909 err = -2;
1910 goto out;
1913 /* enable write */
1914 if (srom_cmd_si_pcmcia(osh, pcmregs, SROM_WEN)) {
1915 BS_ERROR(("set_si_pcmcia_srom: sprom wen failed\n"));
1916 err = -3;
1917 goto out;
1920 /* write buffer to sprom */
1921 for (woff = boff / 2, wsz = bsz / 2, i = 0;
1922 woff < nw && i < wsz; woff ++, i ++) {
1923 if (srom_write_si_pcmcia(osh, pcmregs, (uint16)woff, srom[i])) {
1924 BS_ERROR(("set_si_pcmcia_srom: sprom write failed\n"));
1925 err = -4;
1926 goto out;
1930 /* fix crc */
1931 crc = CRC8_INIT_VALUE;
1932 for (woff = 0; woff < nw; woff ++) {
1933 if (srom_read_si_pcmcia(osh, pcmregs, (uint16)woff, &word)) {
1934 BS_ERROR(("set_si_pcmcia_srom: sprom fix crc read failed\n"));
1935 err = -5;
1936 goto out;
1938 word = htol16(word);
1939 crc = hndcrc8((uint8 *)&word, woff != nw - 1 ? 2 : 1, crc);
1941 word = (~crc << 8) + (ltoh16(word) & 0xff);
1942 if (srom_write_si_pcmcia(osh, pcmregs, (uint16)(woff - 1), word)) {
1943 BS_ERROR(("set_si_pcmcia_srom: sprom fix crc write failed\n"));
1944 err = -6;
1945 goto out;
1948 /* disable write */
1949 if (srom_cmd_si_pcmcia(osh, pcmregs, SROM_WDS)) {
1950 BS_ERROR(("set_si_pcmcia_srom: sprom wds failed\n"));
1951 err = -7;
1952 goto out;
1955 out:
1956 return err;
1958 #endif
1959 #endif
1961 static const char BCMATTACHDATA(vstr_manf)[] = "manf=%s";
1962 static const char BCMATTACHDATA(vstr_productname)[] = "productname=%s";
1963 static const char BCMATTACHDATA(vstr_manfid)[] = "manfid=0x%x";
1964 static const char BCMATTACHDATA(vstr_prodid)[] = "prodid=0x%x";
1965 static const char BCMATTACHDATA(vstr_regwindowsz)[] = "regwindowsz=%d";
1966 static const char BCMATTACHDATA(vstr_sromrev)[] = "sromrev=%d";
1967 static const char BCMATTACHDATA(vstr_chiprev)[] = "chiprev=%d";
1968 static const char BCMATTACHDATA(vstr_subvendid)[] = "subvendid=0x%x";
1969 static const char BCMATTACHDATA(vstr_subdevid)[] = "subdevid=0x%x";
1970 static const char BCMATTACHDATA(vstr_boardrev)[] = "boardrev=0x%x";
1971 static const char BCMATTACHDATA(vstr_aa2g)[] = "aa2g=0x%x";
1972 static const char BCMATTACHDATA(vstr_aa5g)[] = "aa5g=0x%x";
1973 static const char BCMATTACHDATA(vstr_ag)[] = "ag%d=0x%x";
1974 static const char BCMATTACHDATA(vstr_cc)[] = "cc=%d";
1975 static const char BCMATTACHDATA(vstr_opo)[] = "opo=%d";
1976 static const char BCMATTACHDATA(vstr_pa0b)[][9] = { "pa0b0=%d", "pa0b1=%d", "pa0b2=%d" };
1977 static const char BCMATTACHDATA(vstr_pa0itssit)[] = "pa0itssit=%d";
1978 static const char BCMATTACHDATA(vstr_pa0maxpwr)[] = "pa0maxpwr=%d";
1979 static const char BCMATTACHDATA(vstr_pa1b)[][9] = { "pa1b0=%d", "pa1b1=%d", "pa1b2=%d" };
1980 static const char BCMATTACHDATA(vstr_pa1lob)[][11] =
1981 { "pa1lob0=%d", "pa1lob1=%d", "pa1lob2=%d" };
1982 static const char BCMATTACHDATA(vstr_pa1hib)[][11] =
1983 { "pa1hib0=%d", "pa1hib1=%d", "pa1hib2=%d" };
1984 static const char BCMATTACHDATA(vstr_pa1itssit)[] = "pa1itssit=%d";
1985 static const char BCMATTACHDATA(vstr_pa1maxpwr)[] = "pa1maxpwr=%d";
1986 static const char BCMATTACHDATA(vstr_pa1lomaxpwr)[] = "pa1lomaxpwr=%d";
1987 static const char BCMATTACHDATA(vstr_pa1himaxpwr)[] = "pa1himaxpwr=%d";
1988 static const char BCMATTACHDATA(vstr_oem)[] = "oem=%02x%02x%02x%02x%02x%02x%02x%02x";
1989 static const char BCMATTACHDATA(vstr_boardflags)[] = "boardflags=0x%x";
1990 static const char BCMATTACHDATA(vstr_boardflags2)[] = "boardflags2=0x%x";
1991 static const char BCMATTACHDATA(vstr_boardflags3)[] = "boardflags3=0x%x";
1992 static const char BCMATTACHDATA(vstr_ledbh)[] = "ledbh%d=0x%x";
1993 static const char BCMATTACHDATA(vstr_noccode)[] = "ccode=0x0";
1994 static const char BCMATTACHDATA(vstr_ccode)[] = "ccode=%c%c";
1995 static const char BCMATTACHDATA(vstr_cctl)[] = "cctl=0x%x";
1996 static const char BCMATTACHDATA(vstr_cckpo)[] = "cckpo=0x%x";
1997 static const char BCMATTACHDATA(vstr_ofdmpo)[] = "ofdmpo=0x%x";
1998 static const char BCMATTACHDATA(vstr_rdlid)[] = "rdlid=0x%x";
1999 static const char BCMATTACHDATA(vstr_rdlrndis)[] = "rdlrndis=%d";
2000 static const char BCMATTACHDATA(vstr_rdlrwu)[] = "rdlrwu=%d";
2001 static const char BCMATTACHDATA(vstr_usbfs)[] = "usbfs=%d";
2002 static const char BCMATTACHDATA(vstr_wpsgpio)[] = "wpsgpio=%d";
2003 static const char BCMATTACHDATA(vstr_wpsled)[] = "wpsled=%d";
2004 static const char BCMATTACHDATA(vstr_rdlsn)[] = "rdlsn=%d";
2005 static const char BCMATTACHDATA(vstr_rssismf2g)[] = "rssismf2g=%d";
2006 static const char BCMATTACHDATA(vstr_rssismc2g)[] = "rssismc2g=%d";
2007 static const char BCMATTACHDATA(vstr_rssisav2g)[] = "rssisav2g=%d";
2008 static const char BCMATTACHDATA(vstr_bxa2g)[] = "bxa2g=%d";
2009 static const char BCMATTACHDATA(vstr_rssismf5g)[] = "rssismf5g=%d";
2010 static const char BCMATTACHDATA(vstr_rssismc5g)[] = "rssismc5g=%d";
2011 static const char BCMATTACHDATA(vstr_rssisav5g)[] = "rssisav5g=%d";
2012 static const char BCMATTACHDATA(vstr_bxa5g)[] = "bxa5g=%d";
2013 static const char BCMATTACHDATA(vstr_tri2g)[] = "tri2g=%d";
2014 static const char BCMATTACHDATA(vstr_tri5gl)[] = "tri5gl=%d";
2015 static const char BCMATTACHDATA(vstr_tri5g)[] = "tri5g=%d";
2016 static const char BCMATTACHDATA(vstr_tri5gh)[] = "tri5gh=%d";
2017 static const char BCMATTACHDATA(vstr_rxpo2g)[] = "rxpo2g=%d";
2018 static const char BCMATTACHDATA(vstr_rxpo5g)[] = "rxpo5g=%d";
2019 static const char BCMATTACHDATA(vstr_boardtype)[] = "boardtype=0x%x";
2020 static const char BCMATTACHDATA(vstr_leddc)[] = "leddc=0x%04x";
2021 static const char BCMATTACHDATA(vstr_vendid)[] = "vendid=0x%x";
2022 static const char BCMATTACHDATA(vstr_devid)[] = "devid=0x%x";
2023 static const char BCMATTACHDATA(vstr_xtalfreq)[] = "xtalfreq=%d";
2024 static const char BCMATTACHDATA(vstr_txchain)[] = "txchain=0x%x";
2025 static const char BCMATTACHDATA(vstr_rxchain)[] = "rxchain=0x%x";
2026 static const char BCMNMIATTACHDATA(vstr_elna2g)[] = "elna2g=0x%x";
2027 static const char BCMNMIATTACHDATA(vstr_elna5g)[] = "elna5g=0x%x";
2028 static const char BCMATTACHDATA(vstr_antswitch)[] = "antswitch=0x%x";
2029 static const char BCMATTACHDATA(vstr_regrev)[] = "regrev=0x%x";
2030 static const char BCMATTACHDATA(vstr_antswctl2g)[] = "antswctl2g=0x%x";
2031 static const char BCMATTACHDATA(vstr_triso2g)[] = "triso2g=0x%x";
2032 static const char BCMATTACHDATA(vstr_pdetrange2g)[] = "pdetrange2g=0x%x";
2033 static const char BCMATTACHDATA(vstr_extpagain2g)[] = "extpagain2g=0x%x";
2034 static const char BCMATTACHDATA(vstr_tssipos2g)[] = "tssipos2g=0x%x";
2035 static const char BCMATTACHDATA(vstr_antswctl5g)[] = "antswctl5g=0x%x";
2036 static const char BCMATTACHDATA(vstr_triso5g)[] = "triso5g=0x%x";
2037 static const char BCMATTACHDATA(vstr_pdetrange5g)[] = "pdetrange5g=0x%x";
2038 static const char BCMATTACHDATA(vstr_extpagain5g)[] = "extpagain5g=0x%x";
2039 static const char BCMATTACHDATA(vstr_tssipos5g)[] = "tssipos5g=0x%x";
2040 static const char BCMATTACHDATA(vstr_maxp2ga)[] = "maxp2ga%d=0x%x";
2041 static const char BCMATTACHDATA(vstr_itt2ga0)[] = "itt2ga0=0x%x";
2042 static const char BCMATTACHDATA(vstr_pa)[] = "pa%dgw%da%d=0x%x";
2043 static const char BCMATTACHDATA(vstr_pahl)[] = "pa%dg%cw%da%d=0x%x";
2044 static const char BCMATTACHDATA(vstr_maxp5ga0)[] = "maxp5ga0=0x%x";
2045 static const char BCMATTACHDATA(vstr_itt5ga0)[] = "itt5ga0=0x%x";
2046 static const char BCMATTACHDATA(vstr_maxp5gha0)[] = "maxp5gha0=0x%x";
2047 static const char BCMATTACHDATA(vstr_maxp5gla0)[] = "maxp5gla0=0x%x";
2048 static const char BCMATTACHDATA(vstr_itt2ga1)[] = "itt2ga1=0x%x";
2049 static const char BCMATTACHDATA(vstr_maxp5ga1)[] = "maxp5ga1=0x%x";
2050 static const char BCMATTACHDATA(vstr_itt5ga1)[] = "itt5ga1=0x%x";
2051 static const char BCMATTACHDATA(vstr_maxp5gha1)[] = "maxp5gha1=0x%x";
2052 static const char BCMATTACHDATA(vstr_maxp5gla1)[] = "maxp5gla1=0x%x";
2053 static const char BCMATTACHDATA(vstr_cck2gpo)[] = "cck2gpo=0x%x";
2054 static const char BCMATTACHDATA(vstr_ofdm2gpo)[] = "ofdm2gpo=0x%x";
2055 static const char BCMATTACHDATA(vstr_ofdm5gpo)[] = "ofdm5gpo=0x%x";
2056 static const char BCMATTACHDATA(vstr_ofdm5glpo)[] = "ofdm5glpo=0x%x";
2057 static const char BCMATTACHDATA(vstr_ofdm5ghpo)[] = "ofdm5ghpo=0x%x";
2058 static const char BCMATTACHDATA(vstr_cddpo)[] = "cddpo=0x%x";
2059 static const char BCMATTACHDATA(vstr_stbcpo)[] = "stbcpo=0x%x";
2060 static const char BCMATTACHDATA(vstr_bw40po)[] = "bw40po=0x%x";
2061 static const char BCMATTACHDATA(vstr_bwduppo)[] = "bwduppo=0x%x";
2062 static const char BCMATTACHDATA(vstr_mcspo)[] = "mcs%dgpo%d=0x%x";
2063 static const char BCMATTACHDATA(vstr_mcspohl)[] = "mcs%dg%cpo%d=0x%x";
2064 static const char BCMATTACHDATA(vstr_custom)[] = "customvar%d=0x%x";
2065 static const char BCMATTACHDATA(vstr_cckdigfilttype)[] = "cckdigfilttype=%d";
2066 static const char BCMATTACHDATA(vstr_usbflags)[] = "usbflags=0x%x";
2067 #ifdef BCM_BOOTLOADER
2068 static const char BCMATTACHDATA(vstr_mdio)[] = "mdio%d=0x%%x";
2069 static const char BCMATTACHDATA(vstr_mdioex)[] = "mdioex%d=0x%%x";
2070 static const char BCMATTACHDATA(vstr_brmin)[] = "brmin=0x%x";
2071 static const char BCMATTACHDATA(vstr_brmax)[] = "brmax=0x%x";
2072 static const char BCMATTACHDATA(vstr_pllreg)[] = "pll%d=0x%x";
2073 static const char BCMATTACHDATA(vstr_ccreg)[] = "chipc%d=0x%x";
2074 static const char BCMATTACHDATA(vstr_regctrl)[] = "reg%d=0x%x";
2075 static const char BCMATTACHDATA(vstr_time)[] = "r%dt=0x%x";
2076 static const char BCMATTACHDATA(vstr_depreg)[] = "r%dd=0x%x";
2077 static const char BCMATTACHDATA(vstr_usbpredly)[] = "usbpredly=0x%x";
2078 static const char BCMATTACHDATA(vstr_usbpostdly)[] = "usbpostdly=0x%x";
2079 static const char BCMATTACHDATA(vstr_usbrdy)[] = "usbrdy=0x%x";
2080 static const char BCMATTACHDATA(vstr_hsicphyctrl1)[] = "hsicphyctrl1=0x%x";
2081 static const char BCMATTACHDATA(vstr_hsicphyctrl2)[] = "hsicphyctrl2=0x%x";
2082 static const char BCMATTACHDATA(vstr_usbdevctrl)[] = "usbdevctrl=0x%x";
2083 static const char BCMATTACHDATA(vstr_bldr_reset_timeout)[] = "bldr_to=0x%x";
2084 static const char BCMATTACHDATA(vstr_muxenab)[] = "muxenab=0x%x";
2085 static const char BCMATTACHDATA(vstr_pubkey)[] = "pubkey=%s";
2086 #endif /* BCM_BOOTLOADER */
2087 static const char BCMATTACHDATA(vstr_boardnum)[] = "boardnum=%d";
2088 static const char BCMATTACHDATA(vstr_macaddr)[] = "macaddr=%s";
2089 static const char BCMATTACHDATA(vstr_usbepnum)[] = "usbepnum=0x%x";
2090 #ifdef BCMUSBDEV_COMPOSITE
2091 static const char BCMATTACHDATA(vstr_usbdesc_composite)[] = "usbdesc_composite=0x%x";
2092 #endif /* BCMUSBDEV_COMPOSITE */
2093 static const char BCMATTACHDATA(vstr_usbutmi_ctl)[] = "usbutmi_ctl=0x%x";
2094 static const char BCMATTACHDATA(vstr_usbssphy_utmi_ctl0)[] = "usbssphy_utmi_ctl0=0x%x";
2095 static const char BCMATTACHDATA(vstr_usbssphy_utmi_ctl1)[] = "usbssphy_utmi_ctl1=0x%x";
2096 static const char BCMATTACHDATA(vstr_usbssphy_utmi_ctl2)[] = "usbssphy_utmi_ctl2=0x%x";
2097 static const char BCMATTACHDATA(vstr_usbssphy_sleep0)[] = "usbssphy_sleep0=0x%x";
2098 static const char BCMATTACHDATA(vstr_usbssphy_sleep1)[] = "usbssphy_sleep1=0x%x";
2099 static const char BCMATTACHDATA(vstr_usbssphy_sleep2)[] = "usbssphy_sleep2=0x%x";
2100 static const char BCMATTACHDATA(vstr_usbssphy_sleep3)[] = "usbssphy_sleep3=0x%x";
2102 /* Power per rate for SROM V9 */
2103 static const char BCMATTACHDATA(vstr_cckbw202gpo)[][19] =
2104 { "cckbw202gpo=0x%x", "cckbw20ul2gpo=0x%x" };
2105 static const char BCMATTACHDATA(vstr_legofdmbw202gpo)[][22] =
2106 { "legofdmbw202gpo=0x%x", "legofdmbw20ul2gpo=0x%x" };
2107 static const char BCMATTACHDATA(vstr_legofdmbw205gpo)[][24] =
2108 { "legofdmbw205glpo=0x%x", "legofdmbw20ul5glpo=0x%x",
2109 "legofdmbw205gmpo=0x%x", "legofdmbw20ul5gmpo=0x%x",
2110 "legofdmbw205ghpo=0x%x", "legofdmbw20ul5ghpo=0x%x" };
2112 static const char BCMATTACHDATA(vstr_mcs2gpo)[][19] =
2113 { "mcsbw202gpo=0x%x", "mcsbw20ul2gpo=0x%x", "mcsbw402gpo=0x%x"};
2115 static const char BCMATTACHDATA(vstr_mcs5glpo)[][20] =
2116 { "mcsbw205glpo=0x%x", "mcsbw20ul5glpo=0x%x", "mcsbw405glpo=0x%x"};
2118 static const char BCMATTACHDATA(vstr_mcs5gmpo)[][20] =
2119 { "mcsbw205gmpo=0x%x", "mcsbw20ul5gmpo=0x%x", "mcsbw405gmpo=0x%x"};
2121 static const char BCMATTACHDATA(vstr_mcs5ghpo)[][20] =
2122 { "mcsbw205ghpo=0x%x", "mcsbw20ul5ghpo=0x%x", "mcsbw405ghpo=0x%x"};
2124 static const char BCMATTACHDATA(vstr_mcs32po)[] = "mcs32po=0x%x";
2125 static const char BCMATTACHDATA(vstr_legofdm40duppo)[] = "legofdm40duppo=0x%x";
2127 /* SROM V11 */
2128 static const char BCMATTACHDATA(vstr_tempthresh)[] = "tempthresh=%d"; /* HNBU_TEMPTHRESH */
2129 static const char BCMATTACHDATA(vstr_temps_period)[] = "temps_period=%d";
2130 static const char BCMATTACHDATA(vstr_temps_hysteresis)[] = "temps_hysteresis=%d";
2131 static const char BCMATTACHDATA(vstr_tempoffset)[] = "tempoffset=%d";
2132 static const char BCMATTACHDATA(vstr_tempsense_slope)[] = "tempsense_slope=%d";
2133 static const char BCMATTACHDATA(vstr_temp_corrx)[] = "tempcorrx=%d";
2134 static const char BCMATTACHDATA(vstr_tempsense_option)[] = "tempsense_option=%d";
2135 static const char BCMATTACHDATA(vstr_phycal_tempdelta)[] = "phycal_tempdelta=%d";
2136 static const char BCMATTACHDATA(vstr_tssiposslopeg)[] = "tssiposslope%dg=%d"; /* HNBU_FEM_CFG */
2137 static const char BCMATTACHDATA(vstr_epagaing)[] = "epagain%dg=%d";
2138 static const char BCMATTACHDATA(vstr_pdgaing)[] = "pdgain%dg=%d";
2139 static const char BCMATTACHDATA(vstr_tworangetssi)[] = "tworangetssi%dg=%d";
2140 static const char BCMATTACHDATA(vstr_papdcap)[] = "papdcap%dg=%d";
2141 static const char BCMATTACHDATA(vstr_femctrl)[] = "femctrl=%d";
2142 static const char BCMATTACHDATA(vstr_gainctrlsph)[] = "gainctrlsph=%d";
2143 static const char BCMATTACHDATA(vstr_subband5gver)[] = "subband5gver=%d"; /* HNBU_ACPA_CX */
2144 static const char BCMATTACHDATA(vstr_pa2ga)[] = "pa2ga%d=0x%x,0x%x,0x%x";
2145 static const char BCMATTACHDATA(vstr_maxp5ga)[] = "maxp5ga%d=0x%x,0x%x,0x%x,0x%x";
2146 static const char BCMATTACHDATA(vstr_pa5ga)[] = "pa5ga%d=0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,"
2147 "0x%x,0x%x,0x%x,0x%x,0x%x,0x%x";
2148 static const char BCMATTACHDATA(vstr_rxgainsgelnagaina)[] = "rxgains%dgelnagaina=%d";
2149 static const char BCMATTACHDATA(vstr_rxgainsgtrisoa)[] = "rxgains%dgtrisoa%d=%d";
2150 static const char BCMATTACHDATA(vstr_rxgainsgtrelnabypa)[] = "rxgains%dgtrelnabypa%d=%d";
2151 static const char BCMATTACHDATA(vstr_rxgainsgxelnagaina)[] = "rxgains%dg%celnagaina%d=%d";
2152 static const char BCMATTACHDATA(vstr_rxgainsgxtrisoa)[] = "rxgains%dg%ctrisoa%d=%d";
2153 static const char BCMATTACHDATA(vstr_rxgainsgxtrelnabypa)[] = "rxgains%dg%ctrelnabypa%d=%d";
2154 static const char BCMATTACHDATA(vstr_measpower)[] = "measpower=0x%x"; /* HNBU_MEAS_PWR */
2155 static const char BCMATTACHDATA(vstr_measpowerX)[] = "measpower%d=0x%x";
2156 static const char BCMATTACHDATA(vstr_pdoffsetma)[] = "pdoffset%dma%d=0x%x"; /* HNBU_PDOFF */
2157 static const char BCMATTACHDATA(vstr_pdoffset2gma)[] = "pdoffset2g%dma%d=0x%x"; /* HNBU_PDOFF_2G */
2158 static const char BCMATTACHDATA(vstr_pdoffset2gmvalid)[] = "pdoffset2g%dmvalid=0x%x";
2159 static const char BCMATTACHDATA(vstr_rawtempsense)[] = "rawtempsense=0x%x";
2160 /* HNBU_ACPPR_2GPO */
2161 static const char BCMATTACHDATA(vstr_dot11agofdmhrbw202gpo)[] = "dot11agofdmhrbw202gpo=0x%x";
2162 static const char BCMATTACHDATA(vstr_ofdmlrbw202gpo)[] = "ofdmlrbw202gpo=0x%x";
2163 static const char BCMATTACHDATA(vstr_mcsbw805gpo)[] = "mcsbw805g%cpo=0x%x"; /* HNBU_ACPPR_5GPO */
2164 static const char BCMATTACHDATA(vstr_mcsbw1605gpo)[] = "mcsbw1605g%cpo=0x%x";
2165 static const char BCMATTACHDATA(vstr_mcslr5gpo)[] = "mcslr5g%cpo=0x%x";
2166 static const char BCMATTACHDATA(vstr_sb20in40rpo)[] = "sb20in40%crpo=0x%x"; /* HNBU_ACPPR_SBPO */
2167 static const char BCMATTACHDATA(vstr_sb20in80and160r5gpo)[] = "sb20in80and160%cr5g%cpo=0x%x";
2168 static const char BCMATTACHDATA(vstr_sb40and80r5gpo)[] = "sb40and80%cr5g%cpo=0x%x";
2169 static const char BCMATTACHDATA(vstr_dot11agduprpo)[] = "dot11agdup%crpo=0x%x";
2170 static const char BCMATTACHDATA(vstr_noiselvl2ga)[] = "noiselvl2ga%d=%d"; /* HNBU_NOISELVL */
2171 static const char BCMATTACHDATA(vstr_noiselvl5ga)[] = "noiselvl5ga%d=%d,%d,%d,%d";
2172 static const char BCMATTACHDATA(vstr_rxgainerr2ga)[] = "rxgainerr2ga%d=0x%x"; /* HNBU_RXGAIN_ERR */
2173 static const char BCMATTACHDATA(vstr_rxgainerr5ga)[] = "rxgainerr5ga%d=0x%x,0x%x,0x%x,0x%x";
2174 static const char BCMATTACHDATA(vstr_agbg)[] = "agbg%d=0x%x"; /* HNBU_AGBGA */
2175 static const char BCMATTACHDATA(vstr_aga)[] = "aga%d=0x%x";
2176 static const char BCMATTACHDATA(vstr_txduty_ofdm)[] = "tx_duty_cycle_ofdm_%d_5g=%d";
2177 static const char BCMATTACHDATA(vstr_txduty_thresh)[] = "tx_duty_cycle_thresh_%d_5g=%d";
2179 static const char BCMATTACHDATA(vstr_uuid)[] = "uuid=%s";
2181 static const char BCMATTACHDATA(vstr_end)[] = "END\0";
2183 uint8 patch_pair = 0;
2185 /* For dongle HW, accept partial calibration parameters */
2186 #if defined(BCMUSBDEV)
2187 #define BCMDONGLECASE(n) case n:
2188 #else
2189 #define BCMDONGLECASE(n)
2190 #endif
2192 #ifdef BCM_BOOTLOADER
2193 /* The format of the PMUREGS OTP Tuple ->
2194 * 1 byte -> Lower 5 bits has the address of the register
2195 * Higher 3 bits has the mode of the register like
2196 * PLL, ChipCtrl, RegCtrl, UpDwn or Dependency mask
2197 * 4 bytes -> Value of the register to be updated.
2199 #define PMUREGS_MODE_MASK 0xE0
2200 #define PMUREGS_MODE_SHIFT 5
2201 #define PMUREGS_ADDR_MASK 0x1F
2202 #define PMUREGS_TPL_SIZE 5
2204 enum {
2205 PMU_PLLREG_MODE,
2206 PMU_CCREG_MODE,
2207 PMU_VOLTREG_MODE,
2208 PMU_RES_TIME_MODE,
2209 PMU_RESDEPEND_MODE
2212 #define USBREGS_TPL_SIZE 5
2213 enum {
2214 USB_DEV_CTRL_REG,
2215 HSIC_PHY_CTRL1_REG,
2216 HSIC_PHY_CTRL2_REG
2219 #define USBRDY_DLY_TYPE 0x8000 /* Bit indicating if the byte is pre or post delay value */
2220 #define USBRDY_DLY_MASK 0x7FFF /* Bits indicating the amount of delay */
2221 #define USBRDY_MAXOTP_SIZE 5 /* Max size of the OTP parameter */
2223 #endif /* BCM_BOOTLOADER */
2225 #ifdef BCM_BMAC_VARS_APPEND
2227 BCMATTACHFN(srom_probe_boardtype)(uint8 *pcis[], uint ciscnt)
2229 int i;
2230 uint cisnum;
2231 uint8 *cis, tup, tlen;
2233 for (cisnum = 0; cisnum < ciscnt; cisnum++) {
2234 cis = *pcis++;
2235 i = 0;
2236 do {
2237 tup = cis[i++];
2238 if (tup == CISTPL_NULL || tup == CISTPL_END)
2239 tlen = 0;
2240 else
2241 tlen = cis[i++];
2243 if ((i + tlen) >= CIS_SIZE)
2244 break;
2246 if ((tup == CISTPL_BRCM_HNBU) && (cis[i] == HNBU_BOARDTYPE)) {
2247 return (int)((cis[i + 2] << 8) + cis[i + 1]);
2250 i += tlen;
2252 } while (tup != CISTPL_END);
2255 return 0;
2257 #endif /* BCM_BMAC_VARS_APPEND */
2260 BCMATTACHFN(srom_parsecis)(osl_t *osh, uint8 *pcis[], uint ciscnt, char **vars, uint *count)
2262 char eabuf[32];
2263 char *base;
2264 varbuf_t b;
2265 uint8 *cis, tup, tlen, sromrev = 1;
2266 int i, j;
2267 #ifndef BCM_BOOTLOADER
2268 bool ag_init = FALSE;
2269 #endif
2270 uint32 w32;
2271 uint funcid;
2272 uint cisnum;
2273 int32 boardnum;
2274 int err;
2275 bool standard_cis;
2277 ASSERT(vars != NULL);
2278 ASSERT(count != NULL);
2280 boardnum = -1;
2282 base = MALLOC(osh, MAXSZ_NVRAM_VARS);
2283 ASSERT(base != NULL);
2284 if (!base)
2285 return -2;
2287 varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
2288 bzero(base, MAXSZ_NVRAM_VARS);
2289 #ifdef BCM_BMAC_VARS_APPEND
2290 /* 43236 use defaultsromvars_43236usb as the base,
2291 * then append and update it with the content from OTP.
2292 * Only revision/board specfic content or updates used to override
2293 * the driver default will be stored in OTP
2295 *count -= (strlen(vstr_end) + 1 + 1); /* back off the termnating END\0\0 from fakenvram */
2296 bcopy(*vars, base, *count);
2297 b.buf += *count;
2298 #endif /* BCM_BMAC_VARS_APPEND */
2299 eabuf[0] = '\0';
2300 for (cisnum = 0; cisnum < ciscnt; cisnum++) {
2301 cis = *pcis++;
2302 i = 0;
2303 funcid = 0;
2304 standard_cis = TRUE;
2305 do {
2306 if (standard_cis) {
2307 tup = cis[i++];
2308 if (tup == CISTPL_NULL || tup == CISTPL_END)
2309 tlen = 0;
2310 else
2311 tlen = cis[i++];
2312 } else {
2313 if (cis[i] == CISTPL_NULL || cis[i] == CISTPL_END) {
2314 tlen = 0;
2315 tup = cis[i];
2316 } else {
2317 tlen = cis[i];
2318 tup = CISTPL_BRCM_HNBU;
2320 ++i;
2322 if ((i + tlen) >= CIS_SIZE)
2323 break;
2325 switch (tup) {
2326 case CISTPL_VERS_1:
2327 /* assume the strings are good if the version field checks out */
2328 if (((cis[i + 1] << 8) + cis[i]) >= 0x0008) {
2329 varbuf_append(&b, vstr_manf, &cis[i + 2]);
2330 varbuf_append(&b, vstr_productname,
2331 &cis[i + 3 + strlen((char *)&cis[i + 2])]);
2332 break;
2335 case CISTPL_MANFID:
2336 varbuf_append(&b, vstr_manfid, (cis[i + 1] << 8) + cis[i]);
2337 varbuf_append(&b, vstr_prodid, (cis[i + 3] << 8) + cis[i + 2]);
2338 break;
2340 case CISTPL_FUNCID:
2341 funcid = cis[i];
2342 break;
2344 case CISTPL_FUNCE:
2345 switch (funcid) {
2346 case CISTPL_FID_SDIO:
2347 funcid = 0;
2348 break;
2349 default:
2350 /* set macaddr if HNBU_MACADDR not seen yet */
2351 if (eabuf[0] == '\0' && cis[i] == LAN_NID &&
2352 !(ETHER_ISNULLADDR(&cis[i + 2])) &&
2353 !(ETHER_ISMULTI(&cis[i + 2]))) {
2354 ASSERT(cis[i + 1] == ETHER_ADDR_LEN);
2355 bcm_ether_ntoa((struct ether_addr *)&cis[i + 2],
2356 eabuf);
2358 /* set boardnum if HNBU_BOARDNUM not seen yet */
2359 if (boardnum == -1)
2360 boardnum = (cis[i + 6] << 8) + cis[i + 7];
2362 break;
2364 break;
2366 case CISTPL_CFTABLE:
2367 varbuf_append(&b, vstr_regwindowsz, (cis[i + 7] << 8) | cis[i + 6]);
2368 break;
2370 case CISTPL_BRCM_HNBU:
2371 switch (cis[i]) {
2372 case HNBU_SROMREV:
2373 sromrev = cis[i + 1];
2374 varbuf_append(&b, vstr_sromrev, sromrev);
2375 break;
2377 case HNBU_XTALFREQ:
2378 varbuf_append(&b, vstr_xtalfreq,
2379 (cis[i + 4] << 24) |
2380 (cis[i + 3] << 16) |
2381 (cis[i + 2] << 8) |
2382 cis[i + 1]);
2383 break;
2385 case HNBU_CHIPID:
2386 varbuf_append(&b, vstr_vendid, (cis[i + 2] << 8) +
2387 cis[i + 1]);
2388 varbuf_append(&b, vstr_devid, (cis[i + 4] << 8) +
2389 cis[i + 3]);
2390 if (tlen >= 7) {
2391 varbuf_append(&b, vstr_chiprev,
2392 (cis[i + 6] << 8) + cis[i + 5]);
2394 if (tlen >= 9) {
2395 varbuf_append(&b, vstr_subvendid,
2396 (cis[i + 8] << 8) + cis[i + 7]);
2398 if (tlen >= 11) {
2399 varbuf_append(&b, vstr_subdevid,
2400 (cis[i + 10] << 8) + cis[i + 9]);
2401 /* subdevid doubles for boardtype */
2402 varbuf_append(&b, vstr_boardtype,
2403 (cis[i + 10] << 8) + cis[i + 9]);
2405 break;
2407 case HNBU_BOARDNUM:
2408 boardnum = (cis[i + 2] << 8) + cis[i + 1];
2409 break;
2411 case HNBU_PATCH:
2413 char vstr_paddr[16];
2414 char vstr_pdata[16];
2416 /* retrieve the patch pairs
2417 * from tlen/6; where 6 is
2418 * sizeof(patch addr(2)) +
2419 * sizeof(patch data(4)).
2421 patch_pair = tlen/6;
2423 for (j = 0; j < patch_pair; j++) {
2424 snprintf(vstr_paddr, sizeof(vstr_paddr),
2425 "pa%d=0x%%x", j);
2426 snprintf(vstr_pdata, sizeof(vstr_pdata),
2427 "pd%d=0x%%x", j);
2429 varbuf_append(&b, vstr_paddr,
2430 (cis[i + (j*6) + 2] << 8) |
2431 cis[i + (j*6) + 1]);
2433 varbuf_append(&b, vstr_pdata,
2434 (cis[i + (j*6) + 6] << 24) |
2435 (cis[i + (j*6) + 5] << 16) |
2436 (cis[i + (j*6) + 4] << 8) |
2437 cis[i + (j*6) + 3]);
2440 break;
2442 case HNBU_BOARDREV:
2443 if (tlen == 2)
2444 varbuf_append(&b, vstr_boardrev, cis[i + 1]);
2445 else
2446 varbuf_append(&b, vstr_boardrev,
2447 (cis[i + 2] << 8) + cis[i + 1]);
2448 break;
2450 case HNBU_BOARDFLAGS:
2451 w32 = (cis[i + 2] << 8) + cis[i + 1];
2452 if (tlen >= 5)
2453 w32 |= ((cis[i + 4] << 24) + (cis[i + 3] << 16));
2454 varbuf_append(&b, vstr_boardflags, w32);
2456 if (tlen >= 7) {
2457 w32 = (cis[i + 6] << 8) + cis[i + 5];
2458 if (tlen >= 9)
2459 w32 |= ((cis[i + 8] << 24) +
2460 (cis[i + 7] << 16));
2461 varbuf_append(&b, vstr_boardflags2, w32);
2463 if (tlen >= 11) {
2464 w32 = (cis[i + 10] << 8) + cis[i + 9];
2465 if (tlen >= 13)
2466 w32 |= ((cis[i + 12] << 24) +
2467 (cis[i + 11] << 16));
2468 varbuf_append(&b, vstr_boardflags3, w32);
2470 break;
2472 case HNBU_USBFS:
2473 varbuf_append(&b, vstr_usbfs, cis[i + 1]);
2474 break;
2476 case HNBU_BOARDTYPE:
2477 varbuf_append(&b, vstr_boardtype,
2478 (cis[i + 2] << 8) + cis[i + 1]);
2479 break;
2481 case HNBU_HNBUCIS:
2483 * what follows is a nonstandard HNBU CIS
2484 * that lacks CISTPL_BRCM_HNBU tags
2486 * skip 0xff (end of standard CIS)
2487 * after this tuple
2489 tlen++;
2490 standard_cis = FALSE;
2491 break;
2493 case HNBU_USBEPNUM:
2494 varbuf_append(&b, vstr_usbepnum,
2495 (cis[i + 2] << 8) | cis[i + 1]);
2496 break;
2498 case HNBU_PATCH_AUTOINC: {
2499 char vstr_paddr[16];
2500 char vstr_pdata[16];
2501 uint32 addr_inc;
2502 uint8 pcnt;
2504 addr_inc = (cis[i + 4] << 24) |
2505 (cis[i + 3] << 16) |
2506 (cis[i + 2] << 8) |
2507 (cis[i + 1]);
2509 pcnt = (tlen - 5)/4;
2510 for (j = 0; j < pcnt; j++) {
2511 snprintf(vstr_paddr, sizeof(vstr_paddr),
2512 "pa%d=0x%%x", j + patch_pair);
2513 snprintf(vstr_pdata, sizeof(vstr_pdata),
2514 "pd%d=0x%%x", j + patch_pair);
2516 varbuf_append(&b, vstr_paddr, addr_inc);
2517 varbuf_append(&b, vstr_pdata,
2518 (cis[i + (j*4) + 8] << 24) |
2519 (cis[i + (j*4) + 7] << 16) |
2520 (cis[i + (j*4) + 6] << 8) |
2521 cis[i + (j*4) + 5]);
2522 addr_inc += 4;
2524 patch_pair += pcnt;
2526 break;
2527 case HNBU_PATCH2:
2529 char vstr_paddr[16];
2530 char vstr_pdata[16];
2532 /* retrieve the patch pairs
2533 * from tlen/8; where 8 is
2534 * sizeof(patch addr(4)) +
2535 * sizeof(patch data(4)).
2537 patch_pair = tlen/8;
2539 for (j = 0; j < patch_pair; j++) {
2540 snprintf(vstr_paddr, sizeof(vstr_paddr),
2541 "pa%d=0x%%x", j);
2542 snprintf(vstr_pdata, sizeof(vstr_pdata),
2543 "pd%d=0x%%x", j);
2545 varbuf_append(&b, vstr_paddr,
2546 (cis[i + (j*8) + 4] << 24) |
2547 (cis[i + (j*8) + 3] << 16) |
2548 (cis[i + (j*8) + 2] << 8) |
2549 cis[i + (j*8) + 1]);
2551 varbuf_append(&b, vstr_pdata,
2552 (cis[i + (j*8) + 8] << 24) |
2553 (cis[i + (j*8) + 7] << 16) |
2554 (cis[i + (j*8) + 6] << 8) |
2555 cis[i + (j*8) + 5]);
2558 break;
2559 case HNBU_USBFLAGS:
2560 varbuf_append(&b, vstr_usbflags,
2561 (cis[i + 4] << 24) |
2562 (cis[i + 3] << 16) |
2563 (cis[i + 2] << 8) |
2564 cis[i + 1]);
2565 break;
2566 #ifdef BCM_BOOTLOADER
2567 case HNBU_MDIOEX_REGLIST:
2568 case HNBU_MDIO_REGLIST: {
2569 /* Format: addr (8 bits) | val (16 bits) */
2570 const uint8 msize = 3;
2571 char mdiostr[24];
2572 const char *mdiodesc;
2573 uint8 *st;
2575 mdiodesc = (cis[i] == HNBU_MDIO_REGLIST) ?
2576 vstr_mdio : vstr_mdioex;
2578 ASSERT(((tlen - 1) % msize) == 0);
2580 st = &cis[i + 1]; /* start of reg list */
2581 for (j = 0; j < (tlen - 1); j += msize, st += msize) {
2582 snprintf(mdiostr, sizeof(mdiostr),
2583 mdiodesc, st[0]);
2584 varbuf_append(&b, mdiostr, (st[2] << 8) | st[1]);
2587 break;
2588 case HNBU_BRMIN:
2589 varbuf_append(&b, vstr_brmin,
2590 (cis[i + 4] << 24) |
2591 (cis[i + 3] << 16) |
2592 (cis[i + 2] << 8) |
2593 cis[i + 1]);
2594 break;
2596 case HNBU_BRMAX:
2597 varbuf_append(&b, vstr_brmax,
2598 (cis[i + 4] << 24) |
2599 (cis[i + 3] << 16) |
2600 (cis[i + 2] << 8) |
2601 cis[i + 1]);
2602 break;
2603 #endif /* BCM_BOOTLOADER */
2605 case HNBU_RDLID:
2606 varbuf_append(&b, vstr_rdlid,
2607 (cis[i + 2] << 8) | cis[i + 1]);
2608 break;
2610 case HNBU_GCI_CCR:
2612 /* format:
2613 * |0x80 | <== brcm
2614 * |len| <== variable, multiple of 5
2615 * |tup| <== tupletype
2616 * |ccreg_ix0|<== ix of ccreg [1byte]
2617 * |ccreg_val0|<= corr value [4bytes]
2618 * ---
2619 * Multiple registers are possible. for eg: we
2620 * can specify reg_ix3val3 and reg_ix5val5, etc
2622 char vstr_gci_ccreg_entry[16];
2623 int num_entries = 0;
2625 /* retrieve the index-value pairs
2626 * from tlen/5; where 5 is
2627 * sizeof(ccreg_ix(1)) +
2628 * sizeof(ccreg_val(4)).
2630 num_entries = tlen/5;
2632 for (j = 0; j < num_entries; j++) {
2633 snprintf(vstr_gci_ccreg_entry,
2634 sizeof(vstr_gci_ccreg_entry),
2635 "gcr%d=0x%%x", cis[i + (j*5) + 1]);
2637 varbuf_append(&b, vstr_gci_ccreg_entry,
2638 (cis[i + (j*5) + 5] << 24) |
2639 (cis[i + (j*5) + 4] << 16) |
2640 (cis[i + (j*5) + 3] << 8) |
2641 cis[i + (j*5) + 2]);
2644 break;
2646 #ifdef BCM_BOOTLOADER
2647 case HNBU_RDLRNDIS:
2648 varbuf_append(&b, vstr_rdlrndis, cis[i + 1]);
2649 break;
2651 case HNBU_RDLRWU:
2652 varbuf_append(&b, vstr_rdlrwu, cis[i + 1]);
2653 break;
2655 case HNBU_RDLSN:
2656 if (tlen >= 5)
2657 varbuf_append(&b, vstr_rdlsn,
2658 (cis[i + 4] << 24) |
2659 (cis[i + 3] << 16) |
2660 (cis[i + 2] << 8) |
2661 cis[i + 1]);
2662 else
2663 varbuf_append(&b, vstr_rdlsn,
2664 (cis[i + 2] << 8) |
2665 cis[i + 1]);
2666 break;
2668 case HNBU_PMUREGS:
2670 uint8 offset = 1, mode_addr, mode, addr;
2671 const char *fmt;
2673 do {
2674 mode_addr = cis[i+offset];
2676 mode = (mode_addr & PMUREGS_MODE_MASK)
2677 >> PMUREGS_MODE_SHIFT;
2678 addr = mode_addr & PMUREGS_ADDR_MASK;
2680 switch (mode) {
2681 case PMU_PLLREG_MODE:
2682 fmt = vstr_pllreg;
2683 break;
2684 case PMU_CCREG_MODE:
2685 fmt = vstr_ccreg;
2686 break;
2687 case PMU_VOLTREG_MODE:
2688 fmt = vstr_regctrl;
2689 break;
2690 case PMU_RES_TIME_MODE:
2691 fmt = vstr_time;
2692 break;
2693 case PMU_RESDEPEND_MODE:
2694 fmt = vstr_depreg;
2695 break;
2696 default:
2697 fmt = NULL;
2698 break;
2701 if (fmt != NULL) {
2702 varbuf_append(&b, fmt, addr,
2703 (cis[i + offset + 4] << 24) |
2704 (cis[i + offset + 3] << 16) |
2705 (cis[i + offset + 2] << 8) |
2706 cis[i + offset + 1]);
2709 offset += PMUREGS_TPL_SIZE;
2710 } while (offset < tlen);
2712 break;
2714 case HNBU_USBREGS:
2716 uint8 offset = 1, usb_reg;
2717 const char *fmt;
2719 do {
2720 usb_reg = cis[i+offset];
2722 switch (usb_reg) {
2723 case USB_DEV_CTRL_REG:
2724 fmt = vstr_usbdevctrl;
2725 break;
2726 case HSIC_PHY_CTRL1_REG:
2727 fmt = vstr_hsicphyctrl1;
2728 break;
2729 case HSIC_PHY_CTRL2_REG:
2730 fmt = vstr_hsicphyctrl2;
2731 break;
2732 default:
2733 fmt = NULL;
2734 break;
2737 if (fmt != NULL) {
2738 varbuf_append(&b, fmt,
2739 (cis[i + offset + 4] << 24) |
2740 (cis[i + offset + 3] << 16) |
2741 (cis[i + offset + 2] << 8) |
2742 cis[i + offset + 1]);
2745 offset += USBREGS_TPL_SIZE;
2746 } while (offset < tlen);
2748 break;
2750 case HNBU_USBRDY:
2751 /* The first byte of this tuple indicate if the host
2752 * needs to be informed about the readiness of
2753 * the HSIC/USB for enumeration on which GPIO should
2754 * the device assert this event.
2756 varbuf_append(&b, vstr_usbrdy, cis[i + 1]);
2758 /* The following fields in this OTP are optional.
2759 * The remaining bytes will indicate the delay required
2760 * before and/or after the ch_init(). The delay is defined
2761 * using 16-bits of this the MSB(bit15 of 15:0) will be
2762 * used indicate if the parameter is for Pre or Post delay.
2764 for (j = 2; j < USBRDY_MAXOTP_SIZE && j < tlen;
2765 j += 2) {
2766 uint16 usb_delay;
2768 usb_delay = cis[i + j] | (cis[i + j + 1] << 8);
2770 /* The bit-15 of the delay field will indicate the
2771 * type of delay (pre or post).
2773 if (usb_delay & USBRDY_DLY_TYPE) {
2774 varbuf_append(&b, vstr_usbpostdly,
2775 (usb_delay & USBRDY_DLY_MASK));
2776 } else {
2777 varbuf_append(&b, vstr_usbpredly,
2778 (usb_delay & USBRDY_DLY_MASK));
2781 break;
2783 case HNBU_BLDR_TIMEOUT:
2784 /* The Delay after USBConnect for timeout till dongle
2785 * receives get_descriptor request.
2787 varbuf_append(&b, vstr_bldr_reset_timeout,
2788 (cis[i + 1] | (cis[i + 2] << 8)));
2789 break;
2790 case HNBU_MUXENAB:
2791 varbuf_append(&b, vstr_muxenab, cis[i + 1]);
2792 break;
2793 case HNBU_PUBKEY:
2794 /* The public key is in binary format in OTP,
2795 * convert to string format before appending
2796 * buffer string.
2797 * public key(12 bytes) + crc (1byte) = 129
2800 unsigned char a[300];
2801 int k, j;
2803 for (k = 1, j = 0; k < 129; k++)
2804 j += sprintf((char *)(a + j), "%02x",
2805 cis[i + k]);
2807 a[256] = 0;
2809 varbuf_append(&b, vstr_pubkey, a);
2811 break;
2812 #else
2813 case HNBU_AA:
2814 varbuf_append(&b, vstr_aa2g, cis[i + 1]);
2815 if (tlen >= 3)
2816 varbuf_append(&b, vstr_aa5g, cis[i + 2]);
2817 break;
2819 case HNBU_AG:
2820 varbuf_append(&b, vstr_ag, 0, cis[i + 1]);
2821 if (tlen >= 3)
2822 varbuf_append(&b, vstr_ag, 1, cis[i + 2]);
2823 if (tlen >= 4)
2824 varbuf_append(&b, vstr_ag, 2, cis[i + 3]);
2825 if (tlen >= 5)
2826 varbuf_append(&b, vstr_ag, 3, cis[i + 4]);
2827 ag_init = TRUE;
2828 break;
2830 case HNBU_ANT5G:
2831 varbuf_append(&b, vstr_aa5g, cis[i + 1]);
2832 varbuf_append(&b, vstr_ag, 1, cis[i + 2]);
2833 break;
2835 case HNBU_CC:
2836 ASSERT(sromrev == 1);
2837 varbuf_append(&b, vstr_cc, cis[i + 1]);
2838 break;
2840 case HNBU_PAPARMS:
2841 switch (tlen) {
2842 case 2:
2843 ASSERT(sromrev == 1);
2844 varbuf_append(&b, vstr_pa0maxpwr, cis[i + 1]);
2845 break;
2846 case 10:
2847 ASSERT(sromrev >= 2);
2848 varbuf_append(&b, vstr_opo, cis[i + 9]);
2849 /* FALLTHROUGH */
2850 case 9:
2851 varbuf_append(&b, vstr_pa0maxpwr, cis[i + 8]);
2852 /* FALLTHROUGH */
2853 BCMDONGLECASE(8)
2854 varbuf_append(&b, vstr_pa0itssit, cis[i + 7]);
2855 /* FALLTHROUGH */
2856 BCMDONGLECASE(7)
2857 for (j = 0; j < 3; j++) {
2858 varbuf_append(&b, vstr_pa0b[j],
2859 (cis[i + (j * 2) + 2] << 8) +
2860 cis[i + (j * 2) + 1]);
2862 break;
2863 default:
2864 ASSERT((tlen == 2) || (tlen == 9) || (tlen == 10));
2865 break;
2867 break;
2869 case HNBU_PAPARMS5G:
2870 ASSERT((sromrev == 2) || (sromrev == 3));
2871 switch (tlen) {
2872 case 23:
2873 varbuf_append(&b, vstr_pa1himaxpwr, cis[i + 22]);
2874 varbuf_append(&b, vstr_pa1lomaxpwr, cis[i + 21]);
2875 varbuf_append(&b, vstr_pa1maxpwr, cis[i + 20]);
2876 /* FALLTHROUGH */
2877 case 20:
2878 varbuf_append(&b, vstr_pa1itssit, cis[i + 19]);
2879 /* FALLTHROUGH */
2880 case 19:
2881 for (j = 0; j < 3; j++) {
2882 varbuf_append(&b, vstr_pa1b[j],
2883 (cis[i + (j * 2) + 2] << 8) +
2884 cis[i + (j * 2) + 1]);
2886 for (j = 3; j < 6; j++) {
2887 varbuf_append(&b, vstr_pa1lob[j - 3],
2888 (cis[i + (j * 2) + 2] << 8) +
2889 cis[i + (j * 2) + 1]);
2891 for (j = 6; j < 9; j++) {
2892 varbuf_append(&b, vstr_pa1hib[j - 6],
2893 (cis[i + (j * 2) + 2] << 8) +
2894 cis[i + (j * 2) + 1]);
2896 break;
2897 default:
2898 ASSERT((tlen == 19) ||
2899 (tlen == 20) || (tlen == 23));
2900 break;
2902 break;
2904 case HNBU_OEM:
2905 ASSERT(sromrev == 1);
2906 varbuf_append(&b, vstr_oem,
2907 cis[i + 1], cis[i + 2],
2908 cis[i + 3], cis[i + 4],
2909 cis[i + 5], cis[i + 6],
2910 cis[i + 7], cis[i + 8]);
2911 break;
2913 case HNBU_LEDS:
2914 for (j = 1; j <= 4; j++) {
2915 if (cis[i + j] != 0xff) {
2916 varbuf_append(&b, vstr_ledbh, j-1,
2917 cis[i + j]);
2920 if (tlen < 13) break;
2922 for (j = 5; j <= 12; j++) {
2923 if (cis[i + j] != 0xff) {
2924 varbuf_append(&b, vstr_ledbh, j-1,
2925 cis[i + j]);
2928 break;
2930 case HNBU_CCODE:
2931 ASSERT(sromrev > 1);
2932 if ((cis[i + 1] == 0) || (cis[i + 2] == 0))
2933 varbuf_append(&b, vstr_noccode);
2934 else
2935 varbuf_append(&b, vstr_ccode,
2936 cis[i + 1], cis[i + 2]);
2937 varbuf_append(&b, vstr_cctl, cis[i + 3]);
2938 break;
2940 case HNBU_CCKPO:
2941 ASSERT(sromrev > 2);
2942 varbuf_append(&b, vstr_cckpo,
2943 (cis[i + 2] << 8) | cis[i + 1]);
2944 break;
2946 case HNBU_OFDMPO:
2947 ASSERT(sromrev > 2);
2948 varbuf_append(&b, vstr_ofdmpo,
2949 (cis[i + 4] << 24) |
2950 (cis[i + 3] << 16) |
2951 (cis[i + 2] << 8) |
2952 cis[i + 1]);
2953 break;
2955 case HNBU_WPS:
2956 varbuf_append(&b, vstr_wpsgpio, cis[i + 1]);
2957 if (tlen >= 3)
2958 varbuf_append(&b, vstr_wpsled, cis[i + 2]);
2959 break;
2961 case HNBU_RSSISMBXA2G:
2962 ASSERT(sromrev == 3);
2963 varbuf_append(&b, vstr_rssismf2g, cis[i + 1] & 0xf);
2964 varbuf_append(&b, vstr_rssismc2g, (cis[i + 1] >> 4) & 0xf);
2965 varbuf_append(&b, vstr_rssisav2g, cis[i + 2] & 0x7);
2966 varbuf_append(&b, vstr_bxa2g, (cis[i + 2] >> 3) & 0x3);
2967 break;
2969 case HNBU_RSSISMBXA5G:
2970 ASSERT(sromrev == 3);
2971 varbuf_append(&b, vstr_rssismf5g, cis[i + 1] & 0xf);
2972 varbuf_append(&b, vstr_rssismc5g, (cis[i + 1] >> 4) & 0xf);
2973 varbuf_append(&b, vstr_rssisav5g, cis[i + 2] & 0x7);
2974 varbuf_append(&b, vstr_bxa5g, (cis[i + 2] >> 3) & 0x3);
2975 break;
2977 case HNBU_TRI2G:
2978 ASSERT(sromrev == 3);
2979 varbuf_append(&b, vstr_tri2g, cis[i + 1]);
2980 break;
2982 case HNBU_TRI5G:
2983 ASSERT(sromrev == 3);
2984 varbuf_append(&b, vstr_tri5gl, cis[i + 1]);
2985 varbuf_append(&b, vstr_tri5g, cis[i + 2]);
2986 varbuf_append(&b, vstr_tri5gh, cis[i + 3]);
2987 break;
2989 case HNBU_RXPO2G:
2990 ASSERT(sromrev == 3);
2991 varbuf_append(&b, vstr_rxpo2g, cis[i + 1]);
2992 break;
2994 case HNBU_RXPO5G:
2995 ASSERT(sromrev == 3);
2996 varbuf_append(&b, vstr_rxpo5g, cis[i + 1]);
2997 break;
2999 case HNBU_MACADDR:
3000 if (!(ETHER_ISNULLADDR(&cis[i+1])) &&
3001 !(ETHER_ISMULTI(&cis[i+1]))) {
3002 bcm_ether_ntoa((struct ether_addr *)&cis[i + 1],
3003 eabuf);
3005 /* set boardnum if HNBU_BOARDNUM not seen yet */
3006 if (boardnum == -1)
3007 boardnum = (cis[i + 5] << 8) + cis[i + 6];
3009 break;
3011 case HNBU_LEDDC:
3012 /* CIS leddc only has 16bits, convert it to 32bits */
3013 w32 = ((cis[i + 2] << 24) | /* oncount */
3014 (cis[i + 1] << 8)); /* offcount */
3015 varbuf_append(&b, vstr_leddc, w32);
3016 break;
3018 case HNBU_CHAINSWITCH:
3019 varbuf_append(&b, vstr_txchain, cis[i + 1]);
3020 varbuf_append(&b, vstr_rxchain, cis[i + 2]);
3021 varbuf_append(&b, vstr_antswitch,
3022 (cis[i + 4] << 8) + cis[i + 3]);
3023 break;
3025 case HNBU_ELNA2G:
3026 varbuf_append(&b, vstr_elna2g, cis[i + 1]);
3027 break;
3029 case HNBU_ELNA5G:
3030 varbuf_append(&b, vstr_elna5g, cis[i + 1]);
3031 break;
3033 case HNBU_REGREV:
3034 varbuf_append(&b, vstr_regrev, cis[i + 1]);
3035 break;
3037 case HNBU_FEM: {
3038 uint16 fem = (cis[i + 2] << 8) + cis[i + 1];
3039 varbuf_append(&b, vstr_antswctl2g, (fem &
3040 SROM8_FEM_ANTSWLUT_MASK) >>
3041 SROM8_FEM_ANTSWLUT_SHIFT);
3042 varbuf_append(&b, vstr_triso2g, (fem &
3043 SROM8_FEM_TR_ISO_MASK) >>
3044 SROM8_FEM_TR_ISO_SHIFT);
3045 varbuf_append(&b, vstr_pdetrange2g, (fem &
3046 SROM8_FEM_PDET_RANGE_MASK) >>
3047 SROM8_FEM_PDET_RANGE_SHIFT);
3048 varbuf_append(&b, vstr_extpagain2g, (fem &
3049 SROM8_FEM_EXTPA_GAIN_MASK) >>
3050 SROM8_FEM_EXTPA_GAIN_SHIFT);
3051 varbuf_append(&b, vstr_tssipos2g, (fem &
3052 SROM8_FEM_TSSIPOS_MASK) >>
3053 SROM8_FEM_TSSIPOS_SHIFT);
3054 if (tlen < 5) break;
3056 fem = (cis[i + 4] << 8) + cis[i + 3];
3057 varbuf_append(&b, vstr_antswctl5g, (fem &
3058 SROM8_FEM_ANTSWLUT_MASK) >>
3059 SROM8_FEM_ANTSWLUT_SHIFT);
3060 varbuf_append(&b, vstr_triso5g, (fem &
3061 SROM8_FEM_TR_ISO_MASK) >>
3062 SROM8_FEM_TR_ISO_SHIFT);
3063 varbuf_append(&b, vstr_pdetrange5g, (fem &
3064 SROM8_FEM_PDET_RANGE_MASK) >>
3065 SROM8_FEM_PDET_RANGE_SHIFT);
3066 varbuf_append(&b, vstr_extpagain5g, (fem &
3067 SROM8_FEM_EXTPA_GAIN_MASK) >>
3068 SROM8_FEM_EXTPA_GAIN_SHIFT);
3069 varbuf_append(&b, vstr_tssipos5g, (fem &
3070 SROM8_FEM_TSSIPOS_MASK) >>
3071 SROM8_FEM_TSSIPOS_SHIFT);
3072 break;
3075 case HNBU_PAPARMS_C0:
3076 varbuf_append(&b, vstr_maxp2ga, 0, cis[i + 1]);
3077 varbuf_append(&b, vstr_itt2ga0, cis[i + 2]);
3078 varbuf_append(&b, vstr_pa, 2, 0, 0,
3079 (cis[i + 4] << 8) + cis[i + 3]);
3080 varbuf_append(&b, vstr_pa, 2, 1, 0,
3081 (cis[i + 6] << 8) + cis[i + 5]);
3082 varbuf_append(&b, vstr_pa, 2, 2, 0,
3083 (cis[i + 8] << 8) + cis[i + 7]);
3084 if (tlen < 31) break;
3086 varbuf_append(&b, vstr_maxp5ga0, cis[i + 9]);
3087 varbuf_append(&b, vstr_itt5ga0, cis[i + 10]);
3088 varbuf_append(&b, vstr_maxp5gha0, cis[i + 11]);
3089 varbuf_append(&b, vstr_maxp5gla0, cis[i + 12]);
3090 varbuf_append(&b, vstr_pa, 5, 0, 0,
3091 (cis[i + 14] << 8) + cis[i + 13]);
3092 varbuf_append(&b, vstr_pa, 5, 1, 0,
3093 (cis[i + 16] << 8) + cis[i + 15]);
3094 varbuf_append(&b, vstr_pa, 5, 2, 0,
3095 (cis[i + 18] << 8) + cis[i + 17]);
3096 varbuf_append(&b, vstr_pahl, 5, 'l', 0, 0,
3097 (cis[i + 20] << 8) + cis[i + 19]);
3098 varbuf_append(&b, vstr_pahl, 5, 'l', 1, 0,
3099 (cis[i + 22] << 8) + cis[i + 21]);
3100 varbuf_append(&b, vstr_pahl, 5, 'l', 2, 0,
3101 (cis[i + 24] << 8) + cis[i + 23]);
3102 varbuf_append(&b, vstr_pahl, 5, 'h', 0, 0,
3103 (cis[i + 26] << 8) + cis[i + 25]);
3104 varbuf_append(&b, vstr_pahl, 5, 'h', 1, 0,
3105 (cis[i + 28] << 8) + cis[i + 27]);
3106 varbuf_append(&b, vstr_pahl, 5, 'h', 2, 0,
3107 (cis[i + 30] << 8) + cis[i + 29]);
3108 break;
3110 case HNBU_PAPARMS_C1:
3111 varbuf_append(&b, vstr_maxp2ga, 1, cis[i + 1]);
3112 varbuf_append(&b, vstr_itt2ga1, cis[i + 2]);
3113 varbuf_append(&b, vstr_pa, 2, 0, 1,
3114 (cis[i + 4] << 8) + cis[i + 3]);
3115 varbuf_append(&b, vstr_pa, 2, 1, 1,
3116 (cis[i + 6] << 8) + cis[i + 5]);
3117 varbuf_append(&b, vstr_pa, 2, 2, 1,
3118 (cis[i + 8] << 8) + cis[i + 7]);
3119 if (tlen < 31) break;
3121 varbuf_append(&b, vstr_maxp5ga1, cis[i + 9]);
3122 varbuf_append(&b, vstr_itt5ga1, cis[i + 10]);
3123 varbuf_append(&b, vstr_maxp5gha1, cis[i + 11]);
3124 varbuf_append(&b, vstr_maxp5gla1, cis[i + 12]);
3125 varbuf_append(&b, vstr_pa, 5, 0, 1,
3126 (cis[i + 14] << 8) + cis[i + 13]);
3127 varbuf_append(&b, vstr_pa, 5, 1, 1,
3128 (cis[i + 16] << 8) + cis[i + 15]);
3129 varbuf_append(&b, vstr_pa, 5, 2, 1,
3130 (cis[i + 18] << 8) + cis[i + 17]);
3131 varbuf_append(&b, vstr_pahl, 5, 'l', 0, 1,
3132 (cis[i + 20] << 8) + cis[i + 19]);
3133 varbuf_append(&b, vstr_pahl, 5, 'l', 1, 1,
3134 (cis[i + 22] << 8) + cis[i + 21]);
3135 varbuf_append(&b, vstr_pahl, 5, 'l', 2, 1,
3136 (cis[i + 24] << 8) + cis[i + 23]);
3137 varbuf_append(&b, vstr_pahl, 5, 'h', 0, 1,
3138 (cis[i + 26] << 8) + cis[i + 25]);
3139 varbuf_append(&b, vstr_pahl, 5, 'h', 1, 1,
3140 (cis[i + 28] << 8) + cis[i + 27]);
3141 varbuf_append(&b, vstr_pahl, 5, 'h', 2, 1,
3142 (cis[i + 30] << 8) + cis[i + 29]);
3143 break;
3145 case HNBU_PO_CCKOFDM:
3146 varbuf_append(&b, vstr_cck2gpo,
3147 (cis[i + 2] << 8) + cis[i + 1]);
3148 varbuf_append(&b, vstr_ofdm2gpo,
3149 (cis[i + 6] << 24) + (cis[i + 5] << 16) +
3150 (cis[i + 4] << 8) + cis[i + 3]);
3151 if (tlen < 19) break;
3153 varbuf_append(&b, vstr_ofdm5gpo,
3154 (cis[i + 10] << 24) + (cis[i + 9] << 16) +
3155 (cis[i + 8] << 8) + cis[i + 7]);
3156 varbuf_append(&b, vstr_ofdm5glpo,
3157 (cis[i + 14] << 24) + (cis[i + 13] << 16) +
3158 (cis[i + 12] << 8) + cis[i + 11]);
3159 varbuf_append(&b, vstr_ofdm5ghpo,
3160 (cis[i + 18] << 24) + (cis[i + 17] << 16) +
3161 (cis[i + 16] << 8) + cis[i + 15]);
3162 break;
3164 case HNBU_PO_MCS2G:
3165 for (j = 0; j <= (tlen/2); j++) {
3166 varbuf_append(&b, vstr_mcspo, 2, j,
3167 (cis[i + 2 + 2*j] << 8) + cis[i + 1 + 2*j]);
3169 break;
3171 case HNBU_PO_MCS5GM:
3172 for (j = 0; j <= (tlen/2); j++) {
3173 varbuf_append(&b, vstr_mcspo, 5, j,
3174 (cis[i + 2 + 2*j] << 8) + cis[i + 1 + 2*j]);
3176 break;
3178 case HNBU_PO_MCS5GLH:
3179 for (j = 0; j <= (tlen/4); j++) {
3180 varbuf_append(&b, vstr_mcspohl, 5, 'l', j,
3181 (cis[i + 2 + 2*j] << 8) + cis[i + 1 + 2*j]);
3184 for (j = 0; j <= (tlen/4); j++) {
3185 varbuf_append(&b, vstr_mcspohl, 5, 'h', j,
3186 (cis[i + ((tlen/2)+2) + 2*j] << 8) +
3187 cis[i + ((tlen/2)+1) + 2*j]);
3190 break;
3192 case HNBU_PO_CDD:
3193 varbuf_append(&b, vstr_cddpo,
3194 (cis[i + 2] << 8) + cis[i + 1]);
3195 break;
3197 case HNBU_PO_STBC:
3198 varbuf_append(&b, vstr_stbcpo,
3199 (cis[i + 2] << 8) + cis[i + 1]);
3200 break;
3202 case HNBU_PO_40M:
3203 varbuf_append(&b, vstr_bw40po,
3204 (cis[i + 2] << 8) + cis[i + 1]);
3205 break;
3207 case HNBU_PO_40MDUP:
3208 varbuf_append(&b, vstr_bwduppo,
3209 (cis[i + 2] << 8) + cis[i + 1]);
3210 break;
3212 case HNBU_OFDMPO5G:
3213 varbuf_append(&b, vstr_ofdm5gpo,
3214 (cis[i + 4] << 24) + (cis[i + 3] << 16) +
3215 (cis[i + 2] << 8) + cis[i + 1]);
3216 varbuf_append(&b, vstr_ofdm5glpo,
3217 (cis[i + 8] << 24) + (cis[i + 7] << 16) +
3218 (cis[i + 6] << 8) + cis[i + 5]);
3219 varbuf_append(&b, vstr_ofdm5ghpo,
3220 (cis[i + 12] << 24) + (cis[i + 11] << 16) +
3221 (cis[i + 10] << 8) + cis[i + 9]);
3222 break;
3223 /* Power per rate for SROM V9 */
3224 case HNBU_CCKBW202GPO:
3225 varbuf_append(&b, vstr_cckbw202gpo[0],
3226 ((cis[i + 2] << 8) + cis[i + 1]));
3227 if (tlen > 4)
3228 varbuf_append(&b, vstr_cckbw202gpo[1],
3229 ((cis[i + 4] << 8) + cis[i + 3]));
3230 break;
3232 case HNBU_LEGOFDMBW202GPO:
3233 varbuf_append(&b, vstr_legofdmbw202gpo[0],
3234 ((cis[i + 4] << 24) + (cis[i + 3] << 16) +
3235 (cis[i + 2] << 8) + cis[i + 1]));
3236 if (tlen > 6) {
3237 varbuf_append(&b, vstr_legofdmbw202gpo[1],
3238 ((cis[i + 8] << 24) + (cis[i + 7] << 16) +
3239 (cis[i + 6] << 8) + cis[i + 5]));
3241 break;
3243 case HNBU_LEGOFDMBW205GPO:
3244 for (j = 0; j < 6; j++) {
3245 if (tlen < (2 + 4 * j))
3246 break;
3247 varbuf_append(&b, vstr_legofdmbw205gpo[j],
3248 ((cis[4 * j + i + 4] << 24)
3249 + (cis[4 * j + i + 3] << 16)
3250 + (cis[4 * j + i + 2] << 8)
3251 + cis[4 * j + i + 1]));
3253 break;
3255 case HNBU_MCS2GPO:
3256 for (j = 0; j < 3; j++) {
3257 if (tlen < (2 + 4 * j))
3258 break;
3259 varbuf_append(&b, vstr_mcs2gpo[j],
3260 ((cis[4 * j + i + 4] << 24)
3261 + (cis[4 * j + i + 3] << 16)
3262 + (cis[4 * j + i + 2] << 8)
3263 + cis[4 * j + i + 1]));
3265 break;
3267 case HNBU_MCS5GLPO:
3268 for (j = 0; j < 3; j++) {
3269 if (tlen < (2 + 4 * j))
3270 break;
3271 varbuf_append(&b, vstr_mcs5glpo[j],
3272 ((cis[4 * j + i + 4] << 24)
3273 + (cis[4 * j + i + 3] << 16)
3274 + (cis[4 * j + i + 2] << 8)
3275 + cis[4 * j + i + 1]));
3277 break;
3279 case HNBU_MCS5GMPO:
3280 for (j = 0; j < 3; j++) {
3281 if (tlen < (2 + 4 * j))
3282 break;
3283 varbuf_append(&b, vstr_mcs5gmpo[j],
3284 ((cis[4 * j + i + 4] << 24)
3285 + (cis[4 * j + i + 3] << 16)
3286 + (cis[4 * j + i + 2] << 8)
3287 + cis[4 * j + i + 1]));
3289 break;
3291 case HNBU_MCS5GHPO:
3292 for (j = 0; j < 3; j++) {
3293 if (tlen < (2 + 4 * j))
3294 break;
3295 varbuf_append(&b, vstr_mcs5ghpo[j],
3296 ((cis[4 * j + i + 4] << 24)
3297 + (cis[4 * j + i + 3] << 16)
3298 + (cis[4 * j + i + 2] << 8)
3299 + cis[4 * j + i + 1]));
3301 break;
3303 case HNBU_MCS32PO:
3304 varbuf_append(&b, vstr_mcs32po,
3305 (cis[i + 2] << 8) + cis[i + 1]);
3306 break;
3308 case HNBU_LEG40DUPPO:
3309 varbuf_append(&b, vstr_legofdm40duppo,
3310 (cis[i + 2] << 8) + cis[i + 1]);
3311 break;
3313 case HNBU_CUSTOM1:
3314 varbuf_append(&b, vstr_custom, 1, ((cis[i + 4] << 24) +
3315 (cis[i + 3] << 16) + (cis[i + 2] << 8) +
3316 cis[i + 1]));
3317 break;
3319 #if defined(BCMCCISSR3)
3320 case HNBU_SROM3SWRGN:
3321 if (tlen >= 73) {
3322 uint16 srom[35];
3323 uint8 srev = cis[i + 1 + 70];
3324 ASSERT(srev == 3);
3325 /* make tuple value 16-bit aligned and parse it */
3326 bcopy(&cis[i + 1], srom, sizeof(srom));
3327 _initvars_srom_pci(srev, srom, SROM3_SWRGN_OFF, &b);
3328 /* 2.4G antenna gain is included in SROM */
3329 ag_init = TRUE;
3330 /* Ethernet MAC address is included in SROM */
3331 eabuf[0] = 0;
3332 boardnum = -1;
3334 /* create extra variables */
3335 if (tlen >= 75)
3336 varbuf_append(&b, vstr_vendid,
3337 (cis[i + 1 + 73] << 8) +
3338 cis[i + 1 + 72]);
3339 if (tlen >= 77)
3340 varbuf_append(&b, vstr_devid,
3341 (cis[i + 1 + 75] << 8) +
3342 cis[i + 1 + 74]);
3343 if (tlen >= 79)
3344 varbuf_append(&b, vstr_xtalfreq,
3345 (cis[i + 1 + 77] << 8) +
3346 cis[i + 1 + 76]);
3347 break;
3348 #endif
3350 case HNBU_CCKFILTTYPE:
3351 varbuf_append(&b, vstr_cckdigfilttype,
3352 (cis[i + 1]));
3353 break;
3355 case HNBU_TEMPTHRESH:
3356 varbuf_append(&b, vstr_tempthresh,
3357 (cis[i + 1]));
3358 /* period in msb nibble */
3359 varbuf_append(&b, vstr_temps_period,
3360 (cis[i + 2] & SROM11_TEMPS_PERIOD_MASK) >>
3361 SROM11_TEMPS_PERIOD_SHIFT);
3362 /* hysterisis in lsb nibble */
3363 varbuf_append(&b, vstr_temps_hysteresis,
3364 (cis[i + 2] & SROM11_TEMPS_HYSTERESIS_MASK) >>
3365 SROM11_TEMPS_HYSTERESIS_SHIFT);
3366 if (tlen >= 4) {
3367 varbuf_append(&b, vstr_tempoffset,
3368 (cis[i + 3]));
3369 varbuf_append(&b, vstr_tempsense_slope,
3370 (cis[i + 4]));
3371 varbuf_append(&b, vstr_temp_corrx,
3372 (cis[i + 5] & SROM11_TEMPCORRX_MASK) >>
3373 SROM11_TEMPCORRX_SHIFT);
3374 varbuf_append(&b, vstr_tempsense_option,
3375 (cis[i + 5] & SROM11_TEMPSENSE_OPTION_MASK) >>
3376 SROM11_TEMPSENSE_OPTION_SHIFT);
3377 varbuf_append(&b, vstr_phycal_tempdelta,
3378 (cis[i + 6]));
3380 break;
3382 case HNBU_FEM_CFG: {
3383 /* fem_cfg1 */
3384 uint16 fem_cfg = (cis[i + 2] << 8) + cis[i + 1];
3385 varbuf_append(&b, vstr_femctrl,
3386 (fem_cfg & SROM11_FEMCTRL_MASK) >>
3387 SROM11_FEMCTRL_SHIFT);
3388 varbuf_append(&b, vstr_papdcap, 2,
3389 (fem_cfg & SROM11_PAPDCAP_MASK) >>
3390 SROM11_PAPDCAP_SHIFT);
3391 varbuf_append(&b, vstr_tworangetssi, 2,
3392 (fem_cfg & SROM11_TWORANGETSSI_MASK) >>
3393 SROM11_TWORANGETSSI_SHIFT);
3394 varbuf_append(&b, vstr_pdgaing, 2,
3395 (fem_cfg & SROM11_PDGAIN_MASK) >>
3396 SROM11_PDGAIN_SHIFT);
3397 varbuf_append(&b, vstr_epagaing, 2,
3398 (fem_cfg & SROM11_EPAGAIN_MASK) >>
3399 SROM11_EPAGAIN_SHIFT);
3400 varbuf_append(&b, vstr_tssiposslopeg, 2,
3401 (fem_cfg & SROM11_TSSIPOSSLOPE_MASK) >>
3402 SROM11_TSSIPOSSLOPE_SHIFT);
3403 /* fem_cfg2 */
3404 fem_cfg = (cis[i + 4] << 8) + cis[i + 3];
3405 varbuf_append(&b, vstr_gainctrlsph,
3406 (fem_cfg & SROM11_GAINCTRLSPH_MASK) >>
3407 SROM11_GAINCTRLSPH_SHIFT);
3408 varbuf_append(&b, vstr_papdcap, 5,
3409 (fem_cfg & SROM11_PAPDCAP_MASK) >>
3410 SROM11_PAPDCAP_SHIFT);
3411 varbuf_append(&b, vstr_tworangetssi, 5,
3412 (fem_cfg & SROM11_TWORANGETSSI_MASK) >>
3413 SROM11_TWORANGETSSI_SHIFT);
3414 varbuf_append(&b, vstr_pdgaing, 5,
3415 (fem_cfg & SROM11_PDGAIN_MASK) >>
3416 SROM11_PDGAIN_SHIFT);
3417 varbuf_append(&b, vstr_epagaing, 5,
3418 (fem_cfg & SROM11_EPAGAIN_MASK) >>
3419 SROM11_EPAGAIN_SHIFT);
3420 varbuf_append(&b, vstr_tssiposslopeg, 5,
3421 (fem_cfg & SROM11_TSSIPOSSLOPE_MASK) >>
3422 SROM11_TSSIPOSSLOPE_SHIFT);
3423 break;
3426 case HNBU_ACPA_C0:
3428 const int a = 0;
3430 varbuf_append(&b, vstr_subband5gver,
3431 (cis[i + 2] << 8) + cis[i + 1]);
3432 varbuf_append(&b, vstr_maxp2ga, a,
3433 (cis[i + 4] << 8) + cis[i + 3]);
3434 /* pa2g */
3435 varbuf_append(&b, vstr_pa2ga, a,
3436 (cis[i + 6] << 8) + cis[i + 5],
3437 (cis[i + 8] << 8) + cis[i + 7],
3438 (cis[i + 10] << 8) + cis[i + 9]);
3439 /* maxp5g */
3440 varbuf_append(&b, vstr_maxp5ga, a,
3441 cis[i + 11],
3442 cis[i + 12],
3443 cis[i + 13],
3444 cis[i + 14]);
3445 /* pa5g */
3446 varbuf_append(&b, vstr_pa5ga, a,
3447 (cis[i + 16] << 8) + cis[i + 15],
3448 (cis[i + 18] << 8) + cis[i + 17],
3449 (cis[i + 20] << 8) + cis[i + 19],
3450 (cis[i + 22] << 8) + cis[i + 21],
3451 (cis[i + 24] << 8) + cis[i + 23],
3452 (cis[i + 26] << 8) + cis[i + 25],
3453 (cis[i + 28] << 8) + cis[i + 27],
3454 (cis[i + 30] << 8) + cis[i + 29],
3455 (cis[i + 32] << 8) + cis[i + 31],
3456 (cis[i + 34] << 8) + cis[i + 33],
3457 (cis[i + 36] << 8) + cis[i + 35],
3458 (cis[i + 38] << 8) + cis[i + 37]);
3459 break;
3462 case HNBU_ACPA_C1:
3464 const int a = 1;
3466 varbuf_append(&b, vstr_maxp2ga, a,
3467 (cis[i + 2] << 8) + cis[i + 1]);
3468 /* pa2g */
3469 varbuf_append(&b, vstr_pa2ga, a,
3470 (cis[i + 4] << 8) + cis[i + 3],
3471 (cis[i + 6] << 8) + cis[i + 5],
3472 (cis[i + 8] << 8) + cis[i + 7]);
3473 /* maxp5g */
3474 varbuf_append(&b, vstr_maxp5ga, a,
3475 cis[i + 9],
3476 cis[i + 10],
3477 cis[i + 11],
3478 cis[i + 12]);
3479 /* pa5g */
3480 varbuf_append(&b, vstr_pa5ga, a,
3481 (cis[i + 14] << 8) + cis[i + 13],
3482 (cis[i + 16] << 8) + cis[i + 15],
3483 (cis[i + 18] << 8) + cis[i + 17],
3484 (cis[i + 20] << 8) + cis[i + 19],
3485 (cis[i + 22] << 8) + cis[i + 21],
3486 (cis[i + 24] << 8) + cis[i + 23],
3487 (cis[i + 26] << 8) + cis[i + 25],
3488 (cis[i + 28] << 8) + cis[i + 27],
3489 (cis[i + 30] << 8) + cis[i + 29],
3490 (cis[i + 32] << 8) + cis[i + 31],
3491 (cis[i + 34] << 8) + cis[i + 33],
3492 (cis[i + 36] << 8) + cis[i + 35]);
3493 break;
3496 case HNBU_ACPA_C2:
3498 const int a = 2;
3500 varbuf_append(&b, vstr_maxp2ga, a,
3501 (cis[i + 2] << 8) + cis[i + 1]);
3502 /* pa2g */
3503 varbuf_append(&b, vstr_pa2ga, a,
3504 (cis[i + 4] << 8) + cis[i + 3],
3505 (cis[i + 6] << 8) + cis[i + 5],
3506 (cis[i + 8] << 8) + cis[i + 7]);
3507 /* maxp5g */
3508 varbuf_append(&b, vstr_maxp5ga, a,
3509 cis[i + 9],
3510 cis[i + 10],
3511 cis[i + 11],
3512 cis[i + 12]);
3513 /* pa5g */
3514 varbuf_append(&b, vstr_pa5ga, a,
3515 (cis[i + 14] << 8) + cis[i + 13],
3516 (cis[i + 16] << 8) + cis[i + 15],
3517 (cis[i + 18] << 8) + cis[i + 17],
3518 (cis[i + 20] << 8) + cis[i + 19],
3519 (cis[i + 22] << 8) + cis[i + 21],
3520 (cis[i + 24] << 8) + cis[i + 23],
3521 (cis[i + 26] << 8) + cis[i + 25],
3522 (cis[i + 28] << 8) + cis[i + 27],
3523 (cis[i + 30] << 8) + cis[i + 29],
3524 (cis[i + 32] << 8) + cis[i + 31],
3525 (cis[i + 34] << 8) + cis[i + 33],
3526 (cis[i + 36] << 8) + cis[i + 35]);
3527 break;
3530 case HNBU_MEAS_PWR:
3531 varbuf_append(&b, vstr_measpower, cis[i + 1]);
3532 varbuf_append(&b, vstr_measpowerX, 1, (cis[i + 2]));
3533 varbuf_append(&b, vstr_measpowerX, 2, (cis[i + 3]));
3534 varbuf_append(&b, vstr_rawtempsense,
3535 ((cis[i + 5] & 0x1) << 8) + cis[i + 4]);
3536 break;
3538 case HNBU_PDOFF:
3539 varbuf_append(&b, vstr_pdoffsetma, 40, 0,
3540 (cis[i + 2] << 8) + cis[i + 1]);
3541 varbuf_append(&b, vstr_pdoffsetma, 40, 1,
3542 (cis[i + 4] << 8) + cis[i + 3]);
3543 varbuf_append(&b, vstr_pdoffsetma, 40, 2,
3544 (cis[i + 6] << 8) + cis[i + 5]);
3545 varbuf_append(&b, vstr_pdoffsetma, 80, 0,
3546 (cis[i + 8] << 8) + cis[i + 7]);
3547 varbuf_append(&b, vstr_pdoffsetma, 80, 1,
3548 (cis[i + 10] << 8) + cis[i + 9]);
3549 varbuf_append(&b, vstr_pdoffsetma, 80, 2,
3550 (cis[i + 12] << 8) + cis[i + 11]);
3551 break;
3553 case HNBU_ACPPR_2GPO:
3554 varbuf_append(&b, vstr_dot11agofdmhrbw202gpo,
3555 (cis[i + 2] << 8) + cis[i + 1]);
3556 varbuf_append(&b, vstr_ofdmlrbw202gpo,
3557 (cis[i + 4] << 8) + cis[i + 3]);
3558 break;
3560 case HNBU_ACPPR_5GPO:
3561 varbuf_append(&b, vstr_mcsbw805gpo, 'l',
3562 (cis[i + 4] << 24) + (cis[i + 3] << 16) +
3563 (cis[i + 2] << 8) + cis[i + 1]);
3564 varbuf_append(&b, vstr_mcsbw1605gpo, 'l',
3565 (cis[i + 8] << 24) + (cis[i + 7] << 16) +
3566 (cis[i + 6] << 8) + cis[i + 5]);
3567 varbuf_append(&b, vstr_mcsbw805gpo, 'm',
3568 (cis[i + 12] << 24) + (cis[i + 11] << 16) +
3569 (cis[i + 10] << 8) + cis[i + 9]);
3570 varbuf_append(&b, vstr_mcsbw1605gpo, 'm',
3571 (cis[i + 16] << 24) + (cis[i + 15] << 16) +
3572 (cis[i + 14] << 8) + cis[i + 13]);
3573 varbuf_append(&b, vstr_mcsbw805gpo, 'h',
3574 (cis[i + 20] << 24) + (cis[i + 19] << 16) +
3575 (cis[i + 18] << 8) + cis[i + 17]);
3576 varbuf_append(&b, vstr_mcsbw1605gpo, 'h',
3577 (cis[i + 24] << 24) + (cis[i + 23] << 16) +
3578 (cis[i + 22] << 8) + cis[i + 21]);
3579 varbuf_append(&b, vstr_mcslr5gpo, 'l',
3580 (cis[i + 26] << 8) + cis[i + 25]);
3581 varbuf_append(&b, vstr_mcslr5gpo, 'm',
3582 (cis[i + 28] << 8) + cis[i + 27]);
3583 varbuf_append(&b, vstr_mcslr5gpo, 'h',
3584 (cis[i + 30] << 8) + cis[i + 29]);
3585 break;
3587 case HNBU_ACPPR_SBPO:
3588 varbuf_append(&b, vstr_sb20in40rpo, 'h',
3589 (cis[i + 2] << 8) + cis[i + 1]);
3590 varbuf_append(&b, vstr_sb20in80and160r5gpo, 'h', 'l',
3591 (cis[i + 4] << 8) + cis[i + 3]);
3592 varbuf_append(&b, vstr_sb40and80r5gpo, 'h', 'l',
3593 (cis[i + 6] << 8) + cis[i + 5]);
3594 varbuf_append(&b, vstr_sb20in80and160r5gpo, 'h', 'm',
3595 (cis[i + 8] << 8) + cis[i + 7]);
3596 varbuf_append(&b, vstr_sb40and80r5gpo, 'h', 'm',
3597 (cis[i + 10] << 8) + cis[i + 9]);
3598 varbuf_append(&b, vstr_sb20in80and160r5gpo, 'h', 'h',
3599 (cis[i + 12] << 8) + cis[i + 11]);
3600 varbuf_append(&b, vstr_sb40and80r5gpo, 'h', 'h',
3601 (cis[i + 14] << 8) + cis[i + 13]);
3602 varbuf_append(&b, vstr_sb20in40rpo, 'l',
3603 (cis[i + 16] << 8) + cis[i + 15]);
3604 varbuf_append(&b, vstr_sb20in80and160r5gpo, 'l', 'l',
3605 (cis[i + 18] << 8) + cis[i + 17]);
3606 varbuf_append(&b, vstr_sb40and80r5gpo, 'l', 'l',
3607 (cis[i + 20] << 8) + cis[i + 19]);
3608 varbuf_append(&b, vstr_sb20in80and160r5gpo, 'l', 'm',
3609 (cis[i + 22] << 8) + cis[i + 21]);
3610 varbuf_append(&b, vstr_sb40and80r5gpo, 'l', 'm',
3611 (cis[i + 24] << 8) + cis[i + 23]);
3612 varbuf_append(&b, vstr_sb20in80and160r5gpo, 'l', 'h',
3613 (cis[i + 26] << 8) + cis[i + 25]);
3614 varbuf_append(&b, vstr_sb40and80r5gpo, 'l', 'h',
3615 (cis[i + 28] << 8) + cis[i + 27]);
3616 varbuf_append(&b, vstr_dot11agduprpo, 'h',
3617 (cis[i + 30] << 8) + cis[i + 24]);
3618 varbuf_append(&b, vstr_dot11agduprpo, 'l',
3619 (cis[i + 32] << 8) + cis[i + 26]);
3620 break;
3622 case HNBU_NOISELVL:
3623 /* noiselvl2g */
3624 varbuf_append(&b, vstr_noiselvl2ga, 0,
3625 (cis[i + 1] & 0x1f));
3626 varbuf_append(&b, vstr_noiselvl2ga, 1,
3627 (cis[i + 2] & 0x1f));
3628 varbuf_append(&b, vstr_noiselvl2ga, 2,
3629 (cis[i + 3] & 0x1f));
3630 /* noiselvl5g */
3631 varbuf_append(&b, vstr_noiselvl5ga, 0,
3632 (cis[i + 4] & 0x1f),
3633 (cis[i + 5] & 0x1f),
3634 (cis[i + 6] & 0x1f),
3635 (cis[i + 7] & 0x1f));
3636 varbuf_append(&b, vstr_noiselvl5ga, 1,
3637 (cis[i + 8] & 0x1f),
3638 (cis[i + 9] & 0x1f),
3639 (cis[i + 10] & 0x1f),
3640 (cis[i + 11] & 0x1f));
3641 varbuf_append(&b, vstr_noiselvl5ga, 2,
3642 (cis[i + 12] & 0x1f),
3643 (cis[i + 13] & 0x1f),
3644 (cis[i + 14] & 0x1f),
3645 (cis[i + 15] & 0x1f));
3646 break;
3648 case HNBU_RXGAIN_ERR:
3649 varbuf_append(&b, vstr_rxgainerr2ga, 0,
3650 (cis[i + 1] & 0x3f));
3651 varbuf_append(&b, vstr_rxgainerr2ga, 1,
3652 (cis[i + 2] & 0x1f));
3653 varbuf_append(&b, vstr_rxgainerr2ga, 2,
3654 (cis[i + 3] & 0x1f));
3655 varbuf_append(&b, vstr_rxgainerr5ga, 0,
3656 (cis[i + 4] & 0x3f),
3657 (cis[i + 5] & 0x3f),
3658 (cis[i + 6] & 0x3f),
3659 (cis[i + 7] & 0x3f));
3660 varbuf_append(&b, vstr_rxgainerr5ga, 1,
3661 (cis[i + 8] & 0x1f),
3662 (cis[i + 9] & 0x1f),
3663 (cis[i + 10] & 0x1f),
3664 (cis[i + 11] & 0x1f));
3665 varbuf_append(&b, vstr_rxgainerr5ga, 2,
3666 (cis[i + 12] & 0x1f),
3667 (cis[i + 13] & 0x1f),
3668 (cis[i + 14] & 0x1f),
3669 (cis[i + 15] & 0x1f));
3670 break;
3672 case HNBU_AGBGA:
3673 varbuf_append(&b, vstr_agbg, 0, cis[i + 1]);
3674 varbuf_append(&b, vstr_agbg, 1, cis[i + 2]);
3675 varbuf_append(&b, vstr_agbg, 2, cis[i + 3]);
3676 varbuf_append(&b, vstr_aga, 0, cis[i + 4]);
3677 varbuf_append(&b, vstr_aga, 1, cis[i + 5]);
3678 varbuf_append(&b, vstr_aga, 2, cis[i + 6]);
3679 break;
3681 case HNBU_ACRXGAINS_C0: {
3682 int a = 0;
3684 /* rxgains */
3685 uint16 rxgains = (cis[i + 2] << 8) + cis[i + 1];
3686 varbuf_append(&b, vstr_rxgainsgtrelnabypa, 5, a,
3687 (rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3688 SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3689 varbuf_append(&b, vstr_rxgainsgtrisoa, 5, a,
3690 (rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3691 SROM11_RXGAINS5GTRISOA_SHIFT);
3692 varbuf_append(&b, vstr_rxgainsgelnagaina, 5, a,
3693 (rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3694 SROM11_RXGAINS5GELNAGAINA_SHIFT);
3695 varbuf_append(&b, vstr_rxgainsgtrelnabypa, 2, a,
3696 (rxgains & SROM11_RXGAINS2GTRELNABYPA_MASK) >>
3697 SROM11_RXGAINS2GTRELNABYPA_SHIFT);
3698 varbuf_append(&b, vstr_rxgainsgtrisoa, 2, a,
3699 (rxgains & SROM11_RXGAINS2GTRISOA_MASK) >>
3700 SROM11_RXGAINS2GTRISOA_SHIFT);
3701 varbuf_append(&b, vstr_rxgainsgelnagaina, 2, a,
3702 (rxgains & SROM11_RXGAINS2GELNAGAINA_MASK) >>
3703 SROM11_RXGAINS2GELNAGAINA_SHIFT);
3704 /* rxgains1 */
3705 rxgains = (cis[i + 4] << 8) + cis[i + 3];
3706 varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'h', a,
3707 (rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3708 SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3709 varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'h', a,
3710 (rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3711 SROM11_RXGAINS5GTRISOA_SHIFT);
3712 varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'h', a,
3713 (rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3714 SROM11_RXGAINS5GELNAGAINA_SHIFT);
3715 varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'm', a,
3716 (rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3717 SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3718 varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'm', a,
3719 (rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3720 SROM11_RXGAINS5GTRISOA_SHIFT);
3721 varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'm', a,
3722 (rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3723 SROM11_RXGAINS5GELNAGAINA_SHIFT);
3724 break;
3727 case HNBU_ACRXGAINS_C1: {
3728 int a = 1;
3730 /* rxgains */
3731 uint16 rxgains = (cis[i + 2] << 8) + cis[i + 1];
3732 varbuf_append(&b, vstr_rxgainsgtrelnabypa, 5, a,
3733 (rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3734 SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3735 varbuf_append(&b, vstr_rxgainsgtrisoa, 5, a,
3736 (rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3737 SROM11_RXGAINS5GTRISOA_SHIFT);
3738 varbuf_append(&b, vstr_rxgainsgelnagaina, 5, a,
3739 (rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3740 SROM11_RXGAINS5GELNAGAINA_SHIFT);
3741 varbuf_append(&b, vstr_rxgainsgtrelnabypa, 2, a,
3742 (rxgains & SROM11_RXGAINS2GTRELNABYPA_MASK) >>
3743 SROM11_RXGAINS2GTRELNABYPA_SHIFT);
3744 varbuf_append(&b, vstr_rxgainsgtrisoa, 2, a,
3745 (rxgains & SROM11_RXGAINS2GTRISOA_MASK) >>
3746 SROM11_RXGAINS2GTRISOA_SHIFT);
3747 varbuf_append(&b, vstr_rxgainsgelnagaina, 2, a,
3748 (rxgains & SROM11_RXGAINS2GELNAGAINA_MASK) >>
3749 SROM11_RXGAINS2GELNAGAINA_SHIFT);
3750 /* rxgains1 */
3751 rxgains = (cis[i + 4] << 8) + cis[i + 3];
3752 varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'h', a,
3753 (rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3754 SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3755 varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'h', a,
3756 (rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3757 SROM11_RXGAINS5GTRISOA_SHIFT);
3758 varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'h', a,
3759 (rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3760 SROM11_RXGAINS5GELNAGAINA_SHIFT);
3761 varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'm', a,
3762 (rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3763 SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3764 varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'm', a,
3765 (rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3766 SROM11_RXGAINS5GTRISOA_SHIFT);
3767 varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'm', a,
3768 (rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3769 SROM11_RXGAINS5GELNAGAINA_SHIFT);
3770 break;
3773 case HNBU_ACRXGAINS_C2: {
3774 int a = 2;
3776 /* rxgains */
3777 uint16 rxgains = (cis[i + 2] << 8) + cis[i + 1];
3778 varbuf_append(&b, vstr_rxgainsgtrelnabypa, 5, a,
3779 (rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3780 SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3781 varbuf_append(&b, vstr_rxgainsgtrisoa, 5, a,
3782 (rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3783 SROM11_RXGAINS5GTRISOA_SHIFT);
3784 varbuf_append(&b, vstr_rxgainsgelnagaina, 5, a,
3785 (rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3786 SROM11_RXGAINS5GELNAGAINA_SHIFT);
3787 varbuf_append(&b, vstr_rxgainsgtrelnabypa, 2, a,
3788 (rxgains & SROM11_RXGAINS2GTRELNABYPA_MASK) >>
3789 SROM11_RXGAINS2GTRELNABYPA_SHIFT);
3790 varbuf_append(&b, vstr_rxgainsgtrisoa, 2, a,
3791 (rxgains & SROM11_RXGAINS2GTRISOA_MASK) >>
3792 SROM11_RXGAINS2GTRISOA_SHIFT);
3793 varbuf_append(&b, vstr_rxgainsgelnagaina, 2, a,
3794 (rxgains & SROM11_RXGAINS2GELNAGAINA_MASK) >>
3795 SROM11_RXGAINS2GELNAGAINA_SHIFT);
3796 /* rxgains1 */
3797 rxgains = (cis[i + 4] << 8) + cis[i + 3];
3798 varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'h', a,
3799 (rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3800 SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3801 varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'h', a,
3802 (rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3803 SROM11_RXGAINS5GTRISOA_SHIFT);
3804 varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'h', a,
3805 (rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3806 SROM11_RXGAINS5GELNAGAINA_SHIFT);
3807 varbuf_append(&b, vstr_rxgainsgxtrelnabypa, 5, 'm', a,
3808 (rxgains & SROM11_RXGAINS5GTRELNABYPA_MASK) >>
3809 SROM11_RXGAINS5GTRELNABYPA_SHIFT);
3810 varbuf_append(&b, vstr_rxgainsgxtrisoa, 5, 'm', a,
3811 (rxgains & SROM11_RXGAINS5GTRISOA_MASK) >>
3812 SROM11_RXGAINS5GTRISOA_SHIFT);
3813 varbuf_append(&b, vstr_rxgainsgxelnagaina, 5, 'm', a,
3814 (rxgains & SROM11_RXGAINS5GELNAGAINA_MASK) >>
3815 SROM11_RXGAINS5GELNAGAINA_SHIFT);
3816 break;
3819 case HNBU_TXDUTY: {
3820 varbuf_append(&b, vstr_txduty_ofdm, 40,
3821 (cis[i + 2] << 8) + cis[i + 1]);
3822 varbuf_append(&b, vstr_txduty_thresh, 40,
3823 (cis[i + 4] << 8) + cis[i + 3]);
3824 varbuf_append(&b, vstr_txduty_ofdm, 80,
3825 (cis[i + 6] << 8) + cis[i + 5]);
3826 varbuf_append(&b, vstr_txduty_thresh, 80,
3827 (cis[i + 8] << 8) + cis[i + 7]);
3828 break;
3831 case HNBU_UUID:
3833 /* uuid format 12345678-1234-5678-1234-567812345678 */
3835 char uuidstr[37]; /* 32 ids, 4 '-', 1 Null */
3837 snprintf(uuidstr, sizeof(uuidstr),
3838 "%02X%02X%02X%02X-%02X%02X-%02X%02X-"
3839 "%02X%02X-%02X%02X%02X%02X%02X%02X",
3840 cis[i + 1], cis[i + 2], cis[i + 3], cis[i + 4],
3841 cis[i + 5], cis[i + 6], cis[i + 7], cis[i + 8],
3842 cis[i + 9], cis[i + 10], cis[i + 11], cis[i + 12],
3843 cis[i + 13], cis[i + 14], cis[i + 15], cis[i + 16]);
3845 varbuf_append(&b, vstr_uuid, uuidstr);
3846 break;
3849 #endif /* !BCM_BOOTLOADER */
3850 #ifdef BCMUSBDEV_COMPOSITE
3851 case HNBU_USBDESC_COMPOSITE:
3852 varbuf_append(&b, vstr_usbdesc_composite,
3853 (cis[i + 2] << 8) | cis[i + 1]);
3854 break;
3855 #endif /* BCMUSBDEV_COMPOSITE */
3856 case HNBU_USBUTMI_CTL:
3857 varbuf_append(&b, vstr_usbutmi_ctl,
3858 (cis[i + 2] << 8) | cis[i + 1]);
3859 break;
3861 case HNBU_USBSSPHY_UTMI_CTL0:
3862 varbuf_append(&b, vstr_usbssphy_utmi_ctl0,
3863 (cis[i + 4] << 24) | (cis[i + 3] << 16) |
3864 (cis[i + 2] << 8) | cis[i + 1]);
3865 break;
3867 case HNBU_USBSSPHY_UTMI_CTL1:
3868 varbuf_append(&b, vstr_usbssphy_utmi_ctl1,
3869 (cis[i + 4] << 24) | (cis[i + 3] << 16) |
3870 (cis[i + 2] << 8) | cis[i + 1]);
3871 break;
3873 case HNBU_USBSSPHY_UTMI_CTL2:
3874 varbuf_append(&b, vstr_usbssphy_utmi_ctl2,
3875 (cis[i + 4] << 24) | (cis[i + 3] << 16) |
3876 (cis[i + 2] << 8) | cis[i + 1]);
3877 break;
3879 case HNBU_USBSSPHY_SLEEP0:
3880 varbuf_append(&b, vstr_usbssphy_sleep0,
3881 (cis[i + 2] << 8) | cis[i + 1]);
3882 break;
3884 case HNBU_USBSSPHY_SLEEP1:
3885 varbuf_append(&b, vstr_usbssphy_sleep1,
3886 (cis[i + 2] << 8) | cis[i + 1]);
3887 break;
3889 case HNBU_USBSSPHY_SLEEP2:
3890 varbuf_append(&b, vstr_usbssphy_sleep2,
3891 (cis[i + 2] << 8) | cis[i + 1]);
3892 break;
3894 case HNBU_USBSSPHY_SLEEP3:
3895 varbuf_append(&b, vstr_usbssphy_sleep3,
3896 (cis[i + 2] << 8) | cis[i + 1]);
3897 break;
3899 case HNBU_PDOFF_2G:
3901 uint16 pdoff_2g = (cis[i + 2] << 8) + cis[i + 1];
3902 varbuf_append(&b, vstr_pdoffset2gma, 40, 0,
3903 (pdoff_2g & SROM11_PDOFF_2G_40M_A0_MASK) >>
3904 SROM11_PDOFF_2G_40M_A0_SHIFT);
3905 varbuf_append(&b, vstr_pdoffset2gma, 40, 1,
3906 (pdoff_2g & SROM11_PDOFF_2G_40M_A1_MASK) >>
3907 SROM11_PDOFF_2G_40M_A1_SHIFT);
3908 varbuf_append(&b, vstr_pdoffset2gma, 40, 2,
3909 (pdoff_2g & SROM11_PDOFF_2G_40M_A2_MASK) >>
3910 SROM11_PDOFF_2G_40M_A2_SHIFT);
3911 varbuf_append(&b, vstr_pdoffset2gmvalid, 40,
3912 (pdoff_2g & SROM11_PDOFF_2G_40M_VALID_MASK) >>
3913 SROM11_PDOFF_2G_40M_VALID_SHIFT);
3914 break;
3918 break;
3920 i += tlen;
3921 } while (tup != CISTPL_END);
3924 if (boardnum != -1) {
3925 varbuf_append(&b, vstr_boardnum, boardnum);
3928 if (eabuf[0]) {
3929 varbuf_append(&b, vstr_macaddr, eabuf);
3932 #ifndef BCM_BOOTLOADER
3933 /* if there is no antenna gain field, set default */
3934 if (sromrev <= 10 && getvar(NULL, "ag0") == NULL && ag_init == FALSE) {
3935 varbuf_append(&b, vstr_ag, 0, 0xff);
3937 #endif
3939 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
3940 varbuf_append(&b, vstr_end, NULL);
3941 #endif /* BCMUSBDEV_BMAC */
3943 /* final nullbyte terminator */
3944 ASSERT(b.size >= 1);
3945 *b.buf++ = '\0';
3947 ASSERT(b.buf - base <= MAXSZ_NVRAM_VARS);
3948 err = initvars_table(osh, base, b.buf, vars, count);
3950 MFREE(osh, base, MAXSZ_NVRAM_VARS);
3951 return err;
3954 /* set PCMCIA sprom command register */
3955 static int
3956 sprom_cmd_pcmcia(osl_t *osh, uint8 cmd)
3958 uint8 status = 0;
3959 uint wait_cnt = 1000;
3961 /* write sprom command register */
3962 OSL_PCMCIA_WRITE_ATTR(osh, SROM_CS, &cmd, 1);
3964 /* wait status */
3965 while (wait_cnt--) {
3966 OSL_PCMCIA_READ_ATTR(osh, SROM_CS, &status, 1);
3967 if (status & SROM_DONE)
3968 return 0;
3971 return 1;
3974 /* read a word from the PCMCIA srom */
3975 static int
3976 sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data)
3978 uint8 addr_l, addr_h, data_l, data_h;
3980 addr_l = (uint8)((addr * 2) & 0xff);
3981 addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
3983 /* set address */
3984 OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
3985 OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
3987 /* do read */
3988 if (sprom_cmd_pcmcia(osh, SROM_READ))
3989 return 1;
3991 /* read data */
3992 data_h = data_l = 0;
3993 OSL_PCMCIA_READ_ATTR(osh, SROM_DATAH, &data_h, 1);
3994 OSL_PCMCIA_READ_ATTR(osh, SROM_DATAL, &data_l, 1);
3996 *data = (data_h << 8) | data_l;
3997 return 0;
4000 #if defined(WLTEST) || defined(DHD_SPROM) || defined(BCMDBG)
4001 /* write a word to the PCMCIA srom */
4002 static int
4003 sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data)
4005 uint8 addr_l, addr_h, data_l, data_h;
4007 addr_l = (uint8)((addr * 2) & 0xff);
4008 addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
4009 data_l = (uint8)(data & 0xff);
4010 data_h = (uint8)((data >> 8) & 0xff);
4012 /* set address */
4013 OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
4014 OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
4016 /* write data */
4017 OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAH, &data_h, 1);
4018 OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAL, &data_l, 1);
4020 /* do write */
4021 return sprom_cmd_pcmcia(osh, SROM_WRITE);
4023 #endif
4025 /* In chips with chipcommon rev 32 and later, the srom is in chipcommon,
4026 * not in the bus cores.
4028 static uint16
4029 srom_cc_cmd(si_t *sih, osl_t *osh, void *ccregs, uint32 cmd, uint wordoff, uint16 data)
4031 chipcregs_t *cc = (chipcregs_t *)ccregs;
4032 uint wait_cnt = 1000;
4034 if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) {
4035 W_REG(osh, &cc->sromaddress, wordoff * 2);
4036 if (cmd == SRC_OP_WRITE)
4037 W_REG(osh, &cc->sromdata, data);
4040 W_REG(osh, &cc->sromcontrol, SRC_START | cmd);
4042 while (wait_cnt--) {
4043 if ((R_REG(osh, &cc->sromcontrol) & SRC_BUSY) == 0)
4044 break;
4047 if (!wait_cnt) {
4048 BS_ERROR(("%s: Command 0x%x timed out\n", __FUNCTION__, cmd));
4049 return 0xffff;
4051 if (cmd == SRC_OP_READ)
4052 return (uint16)R_REG(osh, &cc->sromdata);
4053 else
4054 return 0xffff;
4058 * Read in and validate sprom.
4059 * Return 0 on success, nonzero on error.
4061 static int
4062 sprom_read_pci(osl_t *osh, si_t *sih, uint16 *sprom, uint wordoff, uint16 *buf, uint nwords,
4063 bool check_crc)
4065 int err = 0;
4066 uint i;
4067 void *ccregs = NULL;
4068 uint32 ccval = 0;
4070 if ((CHIPID(sih->chip) == BCM4331_CHIP_ID) ||
4071 (CHIPID(sih->chip) == BCM43431_CHIP_ID) ||
4072 (CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
4073 (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
4074 (CHIPID(sih->chip) == BCM4352_CHIP_ID)) {
4075 /* save current control setting */
4076 ccval = si_chipcontrl_read(sih);
4079 if ((CHIPID(sih->chip) == BCM4331_CHIP_ID) ||
4080 (CHIPID(sih->chip) == BCM43431_CHIP_ID)) {
4081 /* Disable Ext PA lines to allow reading from SROM */
4082 si_chipcontrl_epa4331(sih, FALSE);
4083 } else if (((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
4084 (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
4085 (CHIPID(sih->chip) == BCM4352_CHIP_ID)) &&
4086 (CHIPREV(sih->chiprev) <= 2)) {
4087 si_chipcontrl_srom4360(sih, TRUE);
4090 /* read the sprom */
4091 for (i = 0; i < nwords; i++) {
4093 if (sih->ccrev > 31 && ISSIM_ENAB(sih)) {
4094 /* use indirect since direct is too slow on QT */
4095 if ((sih->cccaps & CC_CAP_SROM) == 0) {
4096 err = 1;
4097 goto error;
4100 ccregs = (void *)((uint8 *)sprom - CC_SROM_OTP);
4101 buf[i] = srom_cc_cmd(sih, osh, ccregs, SRC_OP_READ, wordoff + i, 0);
4103 } else {
4104 if (ISSIM_ENAB(sih))
4105 buf[i] = R_REG(osh, &sprom[wordoff + i]);
4107 buf[i] = R_REG(osh, &sprom[wordoff + i]);
4112 /* bypass crc checking for simulation to allow srom hack */
4113 if (ISSIM_ENAB(sih)) {
4114 goto error;
4117 if (check_crc) {
4119 if (buf[0] == 0xffff) {
4120 /* The hardware thinks that an srom that starts with 0xffff
4121 * is blank, regardless of the rest of the content, so declare
4122 * it bad.
4124 BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n", __FUNCTION__, buf[0]));
4125 err = 1;
4126 goto error;
4129 /* fixup the endianness so crc8 will pass */
4130 htol16_buf(buf, nwords * 2);
4131 if (hndcrc8((uint8 *)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) {
4132 /* DBG only pci always read srom4 first, then srom8/9 */
4133 /* BS_ERROR(("%s: bad crc\n", __FUNCTION__)); */
4134 err = 1;
4136 /* now correct the endianness of the byte array */
4137 ltoh16_buf(buf, nwords * 2);
4140 error:
4141 if ((CHIPID(sih->chip) == BCM4331_CHIP_ID) ||
4142 (CHIPID(sih->chip) == BCM43431_CHIP_ID) ||
4143 (CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
4144 (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
4145 (CHIPID(sih->chip) == BCM4352_CHIP_ID)) {
4147 /* Restore config after reading SROM */
4148 si_chipcontrl_restore(sih, ccval);
4151 return err;
4154 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
4155 static int
4156 otp_read_pci(osl_t *osh, si_t *sih, uint16 *buf, uint bufsz)
4158 uint8 *otp;
4159 uint sz = OTP_SZ_MAX/2; /* size in words */
4160 int err = 0;
4162 ASSERT(bufsz <= OTP_SZ_MAX);
4164 if ((otp = MALLOC(osh, OTP_SZ_MAX)) == NULL) {
4165 return BCME_ERROR;
4168 bzero(otp, OTP_SZ_MAX);
4170 err = otp_read_region(sih, OTP_HW_RGN, (uint16 *)otp, &sz);
4172 if (err) {
4173 MFREE(osh, otp, OTP_SZ_MAX);
4174 return err;
4177 bcopy(otp, buf, bufsz);
4179 /* Check CRC */
4180 if (((uint16 *)otp)[0] == 0xffff) {
4181 /* The hardware thinks that an srom that starts with 0xffff
4182 * is blank, regardless of the rest of the content, so declare
4183 * it bad.
4185 BS_ERROR(("%s: otp[0] = 0x%x, returning bad-crc\n",
4186 __FUNCTION__, ((uint16 *)otp)[0]));
4187 MFREE(osh, otp, OTP_SZ_MAX);
4188 return 1;
4191 /* fixup the endianness so crc8 will pass */
4192 htol16_buf((uint16 *)otp, OTP_SZ_MAX);
4193 if (hndcrc8(otp, SROM4_WORDS * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE &&
4194 hndcrc8(otp, SROM10_WORDS * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE &&
4195 hndcrc8(otp, SROM11_WORDS * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) {
4196 BS_ERROR(("%s: bad crc\n", __FUNCTION__));
4197 err = 1;
4200 MFREE(osh, otp, OTP_SZ_MAX);
4202 return err;
4204 #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
4207 srom_otp_write_region_crc(si_t *sih, uint nbytes, uint16* buf16, bool write)
4209 #if defined(WLTEST) || defined(BCMDBG)
4210 int err = 0, crc = 0;
4211 uint8 *buf8;
4213 /* Check nbytes is not odd or too big */
4214 if ((nbytes & 1) || (nbytes > SROM_MAX))
4215 return 1;
4217 /* block invalid buffer size */
4218 if (nbytes < SROM4_WORDS * 2)
4219 return BCME_BUFTOOSHORT;
4220 else if (nbytes > SROM11_WORDS * 2)
4221 return BCME_BUFTOOLONG;
4223 /* Verify signatures */
4224 if (!((buf16[SROM4_SIGN] == SROM4_SIGNATURE) ||
4225 (buf16[SROM8_SIGN] == SROM4_SIGNATURE) ||
4226 (buf16[SROM10_SIGN] == SROM4_SIGNATURE) ||
4227 (buf16[SROM11_SIGN] == SROM11_SIGNATURE))) {
4228 BS_ERROR(("%s: wrong signature SROM4_SIGN %x SROM8_SIGN %x SROM10_SIGN %x\n",
4229 __FUNCTION__, buf16[SROM4_SIGN], buf16[SROM8_SIGN], buf16[SROM10_SIGN]));
4230 return BCME_ERROR;
4233 /* Check CRC */
4234 if (buf16[0] == 0xffff) {
4235 /* The hardware thinks that an srom that starts with 0xffff
4236 * is blank, regardless of the rest of the content, so declare
4237 * it bad.
4239 BS_ERROR(("%s: invalid buf16[0] = 0x%x\n", __FUNCTION__, buf16[0]));
4240 goto out;
4243 buf8 = (uint8*)buf16;
4244 /* fixup the endianness and then calculate crc */
4245 htol16_buf(buf8, nbytes);
4246 crc = ~hndcrc8(buf8, nbytes - 1, CRC8_INIT_VALUE);
4247 /* now correct the endianness of the byte array */
4248 ltoh16_buf(buf8, nbytes);
4249 if (nbytes == SROM11_WORDS * 2)
4250 buf16[SROM11_CRCREV] = (crc << 8) | (buf16[SROM11_CRCREV] & 0xff);
4251 else if (nbytes == SROM10_WORDS * 2)
4252 buf16[SROM10_CRCREV] = (crc << 8) | (buf16[SROM10_CRCREV] & 0xff);
4253 else
4254 buf16[SROM4_CRCREV] = (crc << 8) | (buf16[SROM4_CRCREV] & 0xff);
4256 #ifdef BCMNVRAMW
4257 /* Write the CRC back */
4258 if (write)
4259 err = otp_write_region(sih, OTP_HW_RGN, buf16, nbytes/2);
4260 #endif /* BCMNVRAMW */
4262 out:
4263 return write ? err : crc;
4264 #else
4265 return 0;
4266 #endif
4270 * Create variable table from memory.
4271 * Return 0 on success, nonzero on error.
4273 static int
4274 BCMATTACHFN(initvars_table)(osl_t *osh, char *start, char *end, char **vars, uint *count)
4276 int c = (int)(end - start);
4278 /* do it only when there is more than just the null string */
4279 if (c > 1) {
4280 char *vp = MALLOC(osh, c);
4281 ASSERT(vp != NULL);
4282 if (!vp)
4283 return BCME_NOMEM;
4284 bcopy(start, vp, c);
4285 *vars = vp;
4286 *count = c;
4288 else {
4289 *vars = NULL;
4290 *count = 0;
4293 return 0;
4297 * Find variables with <devpath> from flash. 'base' points to the beginning
4298 * of the table upon enter and to the end of the table upon exit when success.
4299 * Return 0 on success, nonzero on error.
4301 static int
4302 BCMATTACHFN(initvars_flash)(si_t *sih, osl_t *osh, char **base, uint len)
4304 char *vp = *base;
4305 char *flash;
4306 int err;
4307 char *s;
4308 uint l, dl, copy_len;
4309 char devpath[SI_DEVPATH_BUFSZ];
4310 char coded_name[SI_DEVPATH_BUFSZ] = {0};
4311 int path_len, coded_len, devid_len;
4313 /* allocate memory and read in flash */
4314 if (!(flash = MALLOC(osh, MAX_NVRAM_SPACE)))
4315 return BCME_NOMEM;
4316 if ((err = nvram_getall(flash, MAX_NVRAM_SPACE)))
4317 goto exit;
4319 /* create legacy devpath prefix */
4320 si_devpath(sih, devpath, sizeof(devpath));
4321 path_len = strlen(devpath);
4323 /* create coded devpath prefix */
4324 si_coded_devpathvar(sih, coded_name, sizeof(coded_name), "devid");
4326 /* coded_name now is 'xx:devid, eat ending 'devid' */
4327 /* to be 'xx:' */
4328 devid_len = strlen("devid");
4329 coded_len = strlen(coded_name);
4330 if (coded_len > devid_len) {
4331 coded_name[coded_len - devid_len] = '\0';
4332 coded_len -= devid_len;
4334 else
4335 coded_len = 0;
4337 /* grab vars with the <devpath> prefix or <coded_name> previx in name */
4338 for (s = flash; s && *s; s += l + 1) {
4339 l = strlen(s);
4341 /* skip non-matching variable */
4342 if (strncmp(s, devpath, path_len) == 0)
4343 dl = path_len;
4344 else if (coded_len && strncmp(s, coded_name, coded_len) == 0)
4345 dl = coded_len;
4346 else
4347 continue;
4349 /* is there enough room to copy? */
4350 copy_len = l - dl + 1;
4351 if (len < copy_len) {
4352 err = BCME_BUFTOOSHORT;
4353 goto exit;
4356 /* no prefix, just the name=value */
4357 strncpy(vp, &s[dl], copy_len);
4358 vp += copy_len;
4359 len -= copy_len;
4362 /* add null string as terminator */
4363 if (len < 1) {
4364 err = BCME_BUFTOOSHORT;
4365 goto exit;
4367 *vp++ = '\0';
4369 *base = vp;
4371 exit: MFREE(osh, flash, MAX_NVRAM_SPACE);
4372 return err;
4375 #if !defined(BCMUSBDEV_ENABLED) && !defined(BCMSDIODEV_ENABLED)
4377 * Initialize nonvolatile variable table from flash.
4378 * Return 0 on success, nonzero on error.
4380 static int
4381 BCMATTACHFN(initvars_flash_si)(si_t *sih, char **vars, uint *count)
4383 osl_t *osh = si_osh(sih);
4384 char *vp, *base;
4385 int err;
4387 ASSERT(vars != NULL);
4388 ASSERT(count != NULL);
4390 base = vp = MALLOC(osh, MAXSZ_NVRAM_VARS);
4391 ASSERT(vp != NULL);
4392 if (!vp)
4393 return BCME_NOMEM;
4395 if ((err = initvars_flash(sih, osh, &vp, MAXSZ_NVRAM_VARS)) == 0)
4396 err = initvars_table(osh, base, vp, vars, count);
4398 MFREE(osh, base, MAXSZ_NVRAM_VARS);
4400 return err;
4402 #endif
4404 /* Parse SROM and create name=value pairs. 'srom' points to
4405 * the SROM word array. 'off' specifies the offset of the
4406 * first word 'srom' points to, which should be either 0 or
4407 * SROM3_SWRG_OFF (full SROM or software region).
4410 static uint
4411 mask_shift(uint16 mask)
4413 uint i;
4414 for (i = 0; i < (sizeof(mask) << 3); i ++) {
4415 if (mask & (1 << i))
4416 return i;
4418 ASSERT(mask);
4419 return 0;
4422 static uint
4423 mask_width(uint16 mask)
4425 int i;
4426 for (i = (sizeof(mask) << 3) - 1; i >= 0; i --) {
4427 if (mask & (1 << i))
4428 return (uint)(i - mask_shift(mask) + 1);
4430 ASSERT(mask);
4431 return 0;
4434 #ifdef BCMASSERT_SUPPORT
4435 static bool
4436 mask_valid(uint16 mask)
4438 uint shift = mask_shift(mask);
4439 uint width = mask_width(mask);
4440 return mask == ((~0 << shift) & ~(~0 << (shift + width)));
4442 #endif
4444 static void
4445 BCMATTACHFN(_initvars_srom_pci)(uint8 sromrev, uint16 *srom, uint off, varbuf_t *b)
4447 uint16 w;
4448 uint32 val;
4449 const sromvar_t *srv;
4450 uint width;
4451 uint flags;
4452 uint32 sr = (1 << sromrev);
4453 bool in_array = FALSE;
4454 static char array_temp[256];
4455 uint array_curr = 0;
4456 const char* array_name = NULL;
4458 varbuf_append(b, "sromrev=%d", sromrev);
4460 for (srv = pci_sromvars; srv->name != NULL; srv ++) {
4461 const char *name;
4462 static bool in_array2 = FALSE;
4463 static char array_temp2[256];
4464 static uint array_curr2 = 0;
4465 static const char* array_name2 = NULL;
4467 if ((srv->revmask & sr) == 0)
4468 continue;
4470 if (srv->off < off)
4471 continue;
4473 flags = srv->flags;
4474 name = srv->name;
4476 /* This entry is for mfgc only. Don't generate param for it, */
4477 if (flags & SRFL_NOVAR)
4478 continue;
4480 if (flags & SRFL_ETHADDR) {
4481 char eabuf[ETHER_ADDR_STR_LEN];
4482 struct ether_addr ea;
4484 ea.octet[0] = (srom[srv->off - off] >> 8) & 0xff;
4485 ea.octet[1] = srom[srv->off - off] & 0xff;
4486 ea.octet[2] = (srom[srv->off + 1 - off] >> 8) & 0xff;
4487 ea.octet[3] = srom[srv->off + 1 - off] & 0xff;
4488 ea.octet[4] = (srom[srv->off + 2 - off] >> 8) & 0xff;
4489 ea.octet[5] = srom[srv->off + 2 - off] & 0xff;
4490 bcm_ether_ntoa(&ea, eabuf);
4492 varbuf_append(b, "%s=%s", name, eabuf);
4494 else {
4495 ASSERT(mask_valid(srv->mask));
4496 ASSERT(mask_width(srv->mask));
4498 /* Start of an array */
4499 if (sromrev >= 10 && (srv->flags & SRFL_ARRAY) && !in_array2) {
4500 array_curr2 = 0;
4501 array_name2 = (const char*)srv->name;
4502 memset((void*)array_temp2, 0, sizeof(array_temp2));
4503 in_array2 = TRUE;
4506 w = srom[srv->off - off];
4507 val = (w & srv->mask) >> mask_shift(srv->mask);
4508 width = mask_width(srv->mask);
4510 while (srv->flags & SRFL_MORE) {
4511 srv ++;
4512 ASSERT(srv->name != NULL);
4514 if (srv->off == 0 || srv->off < off)
4515 continue;
4517 ASSERT(mask_valid(srv->mask));
4518 ASSERT(mask_width(srv->mask));
4520 w = srom[srv->off - off];
4521 val += ((w & srv->mask) >> mask_shift(srv->mask)) << width;
4522 width += mask_width(srv->mask);
4525 if ((flags & SRFL_NOFFS) && ((int)val == (1 << width) - 1))
4526 continue;
4528 /* Array support starts in sromrev 10. Skip arrays for sromrev <= 9 */
4529 if (sromrev <= 9 && srv->flags & SRFL_ARRAY) {
4530 while (srv->flags & SRFL_ARRAY)
4531 srv ++;
4532 srv ++;
4535 if (in_array2) {
4536 int ret;
4538 if (flags & SRFL_PRHEX) {
4539 ret = snprintf(array_temp2 + array_curr2,
4540 sizeof(array_temp2) - array_curr2, "0x%x,", val);
4541 } else if ((flags & SRFL_PRSIGN) &&
4542 (val & (1 << (width - 1)))) {
4543 ret = snprintf(array_temp2 + array_curr2,
4544 sizeof(array_temp2) - array_curr2, "%d,",
4545 (int)(val | (~0 << width)));
4546 } else {
4547 ret = snprintf(array_temp2 + array_curr2,
4548 sizeof(array_temp2) - array_curr2, "%u,", val);
4551 if (ret > 0) {
4552 array_curr2 += ret;
4553 } else {
4554 BS_ERROR(("%s: array %s parsing error. buffer too short.\n",
4555 __FUNCTION__, array_name2));
4556 ASSERT(0);
4558 /* buffer too small, skip this param */
4559 while (srv->flags & SRFL_ARRAY)
4560 srv ++;
4561 srv ++;
4562 in_array2 = FALSE;
4563 continue;
4566 if (!(srv->flags & SRFL_ARRAY)) { /* Array ends */
4567 /* Remove the last ',' */
4568 array_temp2[array_curr2-1] = '\0';
4569 in_array2 = FALSE;
4570 varbuf_append(b, "%s=%s", array_name2, array_temp2);
4572 } else if (flags & SRFL_CCODE) {
4573 if (val == 0)
4574 varbuf_append(b, "ccode=");
4575 else
4576 varbuf_append(b, "ccode=%c%c", (val >> 8), (val & 0xff));
4578 /* LED Powersave duty cycle has to be scaled:
4579 *(oncount >> 24) (offcount >> 8)
4581 else if (flags & SRFL_LEDDC) {
4582 uint32 w32 = (((val >> 8) & 0xff) << 24) | /* oncount */
4583 (((val & 0xff)) << 8); /* offcount */
4584 varbuf_append(b, "leddc=%d", w32);
4586 else if (flags & SRFL_PRHEX)
4587 varbuf_append(b, "%s=0x%x", name, val);
4588 else if ((flags & SRFL_PRSIGN) && (val & (1 << (width - 1))))
4589 varbuf_append(b, "%s=%d", name, (int)(val | (~0 << width)));
4590 else
4591 varbuf_append(b, "%s=%u", name, val);
4595 if (sromrev >= 4) {
4596 /* Do per-path variables */
4597 uint p, pb, psz, path_num;
4599 if (sromrev >= 11) {
4600 pb = SROM11_PATH0;
4601 psz = SROM11_PATH1 - SROM11_PATH0;
4602 path_num = MAX_PATH_SROM_11;
4603 } else if (sromrev >= 8) {
4604 pb = SROM8_PATH0;
4605 psz = SROM8_PATH1 - SROM8_PATH0;
4606 path_num = MAX_PATH_SROM;
4607 } else {
4608 pb = SROM4_PATH0;
4609 psz = SROM4_PATH1 - SROM4_PATH0;
4610 path_num = MAX_PATH_SROM;
4613 for (p = 0; p < path_num; p++) {
4614 for (srv = perpath_pci_sromvars; srv->name != NULL; srv ++) {
4615 if ((srv->revmask & sr) == 0)
4616 continue;
4618 if (pb + srv->off < off)
4619 continue;
4621 /* This entry is for mfgc only. Don't generate param for it, */
4622 if (srv->flags & SRFL_NOVAR)
4623 continue;
4625 /* Start of an array */
4626 if (sromrev >= 10 && (srv->flags & SRFL_ARRAY) && !in_array) {
4627 array_curr = 0;
4628 array_name = (const char*)srv->name;
4629 memset((void*)array_temp, 0, sizeof(array_temp));
4630 in_array = TRUE;
4633 w = srom[pb + srv->off - off];
4635 ASSERT(mask_valid(srv->mask));
4636 val = (w & srv->mask) >> mask_shift(srv->mask);
4637 width = mask_width(srv->mask);
4639 flags = srv->flags;
4641 /* Cheating: no per-path var is more than 1 word */
4643 if ((srv->flags & SRFL_NOFFS) && ((int)val == (1 << width) - 1))
4644 continue;
4646 if (in_array) {
4647 int ret;
4649 if (flags & SRFL_PRHEX) {
4650 ret = snprintf(array_temp + array_curr,
4651 sizeof(array_temp) - array_curr, "0x%x,", val);
4652 } else if ((flags & SRFL_PRSIGN) &&
4653 (val & (1 << (width - 1)))) {
4654 ret = snprintf(array_temp + array_curr,
4655 sizeof(array_temp) - array_curr, "%d,",
4656 (int)(val | (~0 << width)));
4657 } else {
4658 ret = snprintf(array_temp + array_curr,
4659 sizeof(array_temp) - array_curr, "%u,", val);
4662 if (ret > 0) {
4663 array_curr += ret;
4664 } else {
4665 BS_ERROR(
4666 ("%s: array %s parsing error. buffer too short.\n",
4667 __FUNCTION__, array_name));
4668 ASSERT(0);
4670 /* buffer too small, skip this param */
4671 while (srv->flags & SRFL_ARRAY)
4672 srv ++;
4673 srv ++;
4674 in_array = FALSE;
4675 continue;
4678 if (!(srv->flags & SRFL_ARRAY)) { /* Array ends */
4679 /* Remove the last ',' */
4680 array_temp[array_curr-1] = '\0';
4681 in_array = FALSE;
4682 varbuf_append(b, "%s%d=%s",
4683 array_name, p, array_temp);
4685 } else if (srv->flags & SRFL_PRHEX)
4686 varbuf_append(b, "%s%d=0x%x", srv->name, p, val);
4687 else
4688 varbuf_append(b, "%s%d=%d", srv->name, p, val);
4690 pb += psz;
4696 * Initialize nonvolatile variable table from sprom.
4697 * Return 0 on success, nonzero on error.
4699 static int
4700 BCMATTACHFN(initvars_srom_pci)(si_t *sih, void *curmap, char **vars, uint *count)
4702 uint16 *srom, *sromwindow;
4703 uint8 sromrev = 0;
4704 uint32 sr;
4705 varbuf_t b;
4706 char *vp, *base = NULL;
4707 osl_t *osh = si_osh(sih);
4708 bool flash = FALSE;
4709 int err = 0;
4712 * Apply CRC over SROM content regardless SROM is present or not,
4713 * and use variable <devpath>sromrev's existance in flash to decide
4714 * if we should return an error when CRC fails or read SROM variables
4715 * from flash.
4717 srom = MALLOC(osh, SROM_MAX);
4718 ASSERT(srom != NULL);
4719 if (!srom)
4720 return -2;
4722 sromwindow = (uint16 *)SROM_OFFSET(sih);
4723 if (si_is_sprom_available(sih)) {
4724 err = sprom_read_pci(osh, sih, sromwindow, 0, srom, SROM11_WORDS, TRUE);
4726 if (err == 0) {
4727 if (srom[SROM11_SIGN] == SROM11_SIGNATURE) /* srom 11 */
4728 sromrev = srom[SROM11_CRCREV] & 0xff;
4729 } else {
4730 err = sprom_read_pci(osh, sih, sromwindow, 0, srom, SROM4_WORDS, TRUE);
4732 if (err == 0) {
4733 if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) || /* srom 4 */
4734 (srom[SROM8_SIGN] == SROM4_SIGNATURE) ) { /* srom 8, 9 */
4735 sromrev = srom[SROM4_CRCREV] & 0xff;
4737 } else {
4738 err = sprom_read_pci(osh, sih, sromwindow, 0,
4739 srom, SROM_WORDS, TRUE);
4741 if (err == 0) {
4742 /* srom is good and is rev < 4 */
4743 /* top word of sprom contains version and crc8 */
4744 sromrev = srom[SROM_CRCREV] & 0xff;
4745 /* bcm4401 sroms misprogrammed */
4746 if (sromrev == 0x10)
4747 sromrev = 1;
4753 #if defined(BCMNVRAMW) || defined(BCMNVRAMR)
4754 /* Use OTP if SPROM not available */
4755 else if ((err = otp_read_pci(osh, sih, srom, SROM_MAX)) == 0) {
4756 /* OTP only contain SROM rev8/rev9/rev10/Rev11 for now */
4757 if (srom[SROM11_SIGN] == SROM11_SIGNATURE)
4758 sromrev = srom[SROM11_CRCREV] & 0xff;
4759 else if (srom[SROM10_SIGN] == SROM10_SIGNATURE)
4760 sromrev = srom[SROM10_CRCREV] & 0xff;
4761 else
4762 sromrev = srom[SROM4_CRCREV] & 0xff;
4764 #endif /* defined(BCMNVRAMW) || defined(BCMNVRAMR) */
4765 else {
4766 err = 1;
4767 BS_ERROR(("Neither SPROM nor OTP has valid image\n"));
4770 BS_ERROR(("srom rev:%d\n", sromrev));
4773 /* We want internal/wltest driver to come up with default sromvars so we can
4774 * program a blank SPROM/OTP.
4776 if (err) {
4777 char *value;
4778 uint32 val;
4779 val = 0;
4780 BCM_REFERENCE(val);
4782 if ((value = si_getdevpathvar(sih, "sromrev"))) {
4783 sromrev = (uint8)bcm_strtoul(value, NULL, 0);
4784 flash = TRUE;
4785 goto varscont;
4788 BS_ERROR(("%s, SROM CRC Error\n", __FUNCTION__));
4790 #ifndef DONGLEBUILD
4791 if ((value = si_getnvramflvar(sih, "sromrev"))) {
4792 err = 0;
4793 goto errout;
4795 #endif
4796 /* BCMHOSTVARS is enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
4797 #if defined(BCMHOSTVARS)
4798 val = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
4799 if ((si_is_sprom_available(sih) && srom[0] == 0xffff) ||
4800 (val & SPROM_OTPIN_USE)) {
4801 vp = base = mfgsromvars;
4803 if (defvarslen == 0) {
4804 BS_ERROR(("No nvm file, use generic default (for programming"
4805 " SPROM/OTP only)\n"));
4807 if (((sih->chip == BCM4331_CHIP_ID) ||
4808 (sih->chip == BCM43431_CHIP_ID)) &&
4809 (sih->chiprev < 3)) {
4811 defvarslen = srom_vars_len(defaultsromvars_4331);
4812 bcopy(defaultsromvars_4331, vp, defvarslen);
4814 } else if ((sih->chip == BCM4360_CHIP_ID) ||
4815 (sih->chip == BCM4352_CHIP_ID)) {
4816 defvarslen = srom_vars_len(defaultsromvars_4360);
4817 bcopy(defaultsromvars_4360, vp, defvarslen);
4818 } else if (sih->chip == BCM4335_CHIP_ID ||
4819 0) {
4820 defvarslen = srom_vars_len(defaultsromvars_4335);
4821 bcopy(defaultsromvars_4335, vp, defvarslen);
4822 } else {
4823 /* For 4311 A1 there is no signature to indicate that OTP is
4824 * programmed, so can't really verify the OTP is
4825 * unprogrammed or a bad OTP.
4827 if (sih->chip == BCM4311_CHIP_ID) {
4828 const char *devid = "devid=0x4311";
4829 const size_t devid_strlen = strlen(devid);
4830 BS_ERROR(("setting the devid to be 4311\n"));
4831 bcopy(devid, vp, devid_strlen + 1);
4832 vp += devid_strlen + 1;
4834 defvarslen = srom_vars_len(defaultsromvars_wltest);
4835 bcopy(defaultsromvars_wltest, vp, defvarslen);
4837 } else {
4838 BS_ERROR(("Use nvm file as default\n"));
4841 vp += defvarslen;
4842 /* add final null terminator */
4843 *vp++ = '\0';
4845 BS_ERROR(("Used %d bytes of defaultsromvars\n", defvarslen));
4846 goto varsdone;
4848 } else if ((((sih->chip == BCM4331_CHIP_ID) ||
4849 (sih->chip == BCM43431_CHIP_ID)) &&
4850 (sih->chiprev < 3)) || (sih->chip == BCM4360_CHIP_ID) ||
4851 (sih->chip == BCM43460_CHIP_ID) ||
4852 (sih->chip == BCM4352_CHIP_ID)) {
4853 base = vp = mfgsromvars;
4855 if ((sih->chip == BCM4360_CHIP_ID) ||
4856 (sih->chip == BCM43460_CHIP_ID) ||
4857 (sih->chip == BCM4352_CHIP_ID))
4858 BS_ERROR(("4360 BOOT w/o SPROM or OTP\n"));
4859 else
4860 BS_ERROR(("4331 BOOT w/o SPROM or OTP\n"));
4862 if (defvarslen == 0) {
4863 if ((sih->chip == BCM4360_CHIP_ID) ||
4864 (sih->chip == BCM4352_CHIP_ID)) {
4865 defvarslen = srom_vars_len(defaultsromvars_4360);
4866 bcopy(defaultsromvars_4360, vp, defvarslen);
4867 } else {
4868 defvarslen = srom_vars_len(defaultsromvars_4331);
4869 bcopy(defaultsromvars_4331, vp, defvarslen);
4872 vp += defvarslen;
4873 *vp++ = '\0';
4874 goto varsdone;
4875 } else if (sih->chip == BCM4335_CHIP_ID ||
4876 0) {
4877 base = vp = mfgsromvars;
4879 defvarslen = srom_vars_len(defaultsromvars_4335);
4880 bcopy(defaultsromvars_4335, vp, defvarslen);
4882 vp += defvarslen;
4883 *vp++ = '\0';
4884 goto varsdone;
4885 } else
4886 #endif
4888 err = -1;
4889 goto errout;
4893 varscont:
4894 /* Bitmask for the sromrev */
4895 sr = 1 << sromrev;
4897 /* srom version check: Current valid versions: 1-5, 8-11, SROM_MAXREV */
4898 if ((sr & 0xf3e) == 0) {
4899 BS_ERROR(("Invalid SROM rev %d\n", sromrev));
4900 err = -2;
4901 goto errout;
4904 ASSERT(vars != NULL);
4905 ASSERT(count != NULL);
4907 base = vp = MALLOC(osh, MAXSZ_NVRAM_VARS);
4908 ASSERT(vp != NULL);
4909 if (!vp) {
4910 err = -2;
4911 goto errout;
4914 /* read variables from flash */
4915 if (flash) {
4916 if ((err = initvars_flash(sih, osh, &vp, MAXSZ_NVRAM_VARS)))
4917 goto errout;
4918 goto varsdone;
4921 varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
4923 /* parse SROM into name=value pairs. */
4924 _initvars_srom_pci(sromrev, srom, 0, &b);
4927 /* final nullbyte terminator */
4928 ASSERT(b.size >= 1);
4929 vp = b.buf;
4930 *vp++ = '\0';
4932 ASSERT((vp - base) <= MAXSZ_NVRAM_VARS);
4934 varsdone:
4935 err = initvars_table(osh, base, vp, vars, count);
4937 errout:
4938 /* BCMHOSTVARS are enabled only if WLTEST is enabled or BCMEXTNVM is enabled */
4939 #if defined(BCMHOSTVARS)
4940 if (base && (base != mfgsromvars))
4941 #else
4942 if (base)
4943 #endif
4944 MFREE(osh, base, MAXSZ_NVRAM_VARS);
4946 MFREE(osh, srom, SROM_MAX);
4947 return err;
4951 * Read the cis and call parsecis to initialize the vars.
4952 * Return 0 on success, nonzero on error.
4954 static int
4955 BCMATTACHFN(initvars_cis_pcmcia)(si_t *sih, osl_t *osh, char **vars, uint *count)
4957 uint8 *cis = NULL;
4958 int rc;
4959 uint data_sz;
4961 data_sz = (sih->buscorerev == 1) ? SROM_MAX : CIS_SIZE;
4963 if ((cis = MALLOC(osh, data_sz)) == NULL)
4964 return (-2);
4966 if (sih->buscorerev == 1) {
4967 if (srom_read(sih, PCMCIA_BUS, (void *)NULL, osh, 0, data_sz, (uint16 *)cis,
4968 TRUE)) {
4969 MFREE(osh, cis, data_sz);
4970 return (-1);
4972 /* fix up endianess for 16-bit data vs 8-bit parsing */
4973 htol16_buf((uint16 *)cis, data_sz);
4974 } else
4975 OSL_PCMCIA_READ_ATTR(osh, 0, cis, data_sz);
4977 rc = srom_parsecis(osh, &cis, SROM_CIS_SINGLE, vars, count);
4979 MFREE(osh, cis, data_sz);
4981 return (rc);
4985 #ifdef BCMSPI
4987 * Read the SPI cis and call parsecis to initialize the vars.
4988 * Return 0 on success, nonzero on error.
4990 static int
4991 BCMATTACHFN(initvars_cis_spi)(osl_t *osh, char **vars, uint *count)
4993 uint8 *cis;
4994 int rc;
4996 #if defined(NDIS) && !defined(UNDER_CE)
4997 uint8 cisd[SBSDIO_CIS_SIZE_LIMIT];
4998 cis = (uint8*)cisd;
4999 #else
5000 if ((cis = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT)) == NULL) {
5001 return -1;
5003 #endif /* defined(NDIS) && (!defined(UNDER_CE)) */
5005 bzero(cis, SBSDIO_CIS_SIZE_LIMIT);
5007 if (bcmsdh_cis_read(NULL, SDIO_FUNC_1, cis, SBSDIO_CIS_SIZE_LIMIT) != 0) {
5008 #if defined(NDIS) && !defined(UNDER_CE)
5009 /* nothing to do */
5010 #else
5011 MFREE(osh, cis, SBSDIO_CIS_SIZE_LIMIT);
5012 #endif /* defined(NDIS) && (!defined(UNDER_CE)) */
5013 return -2;
5016 rc = srom_parsecis(osh, &cis, SDIO_FUNC_1, vars, count);
5018 #if defined(NDIS) && !defined(UNDER_CE)
5019 /* nothing to do here */
5020 #else
5021 MFREE(osh, cis, SBSDIO_CIS_SIZE_LIMIT);
5022 #endif
5024 return (rc);
5026 #endif /* BCMSPI */
5028 #if defined(BCMUSBDEV)
5029 /* Return sprom size in 16-bit words */
5030 uint
5031 srom_size(si_t *sih, osl_t *osh)
5033 uint size = 0;
5034 if (SPROMBUS == PCMCIA_BUS) {
5035 uint32 origidx;
5036 sdpcmd_regs_t *pcmregs;
5037 bool wasup;
5039 origidx = si_coreidx(sih);
5040 pcmregs = si_setcore(sih, PCMCIA_CORE_ID, 0);
5041 if (!pcmregs)
5042 pcmregs = si_setcore(sih, SDIOD_CORE_ID, 0);
5043 ASSERT(pcmregs);
5045 if (!(wasup = si_iscoreup(sih)))
5046 si_core_reset(sih, 0, 0);
5048 /* not worry about earlier core revs */
5049 /* valid for only pcmcia core */
5050 if (si_coreid(sih) == PCMCIA_CORE_ID)
5051 if (si_corerev(sih) < 8)
5052 goto done;
5055 switch (SI_PCMCIA_READ(osh, pcmregs, SROM_INFO) & SRI_SZ_MASK) {
5056 case 1:
5057 size = 256; /* SROM_INFO == 1 means 4kbit */
5058 break;
5059 case 2:
5060 size = 1024; /* SROM_INFO == 2 means 16kbit */
5061 break;
5062 default:
5063 break;
5066 done:
5067 if (!wasup)
5068 si_core_disable(sih, 0);
5070 si_setcoreidx(sih, origidx);
5072 return size;
5074 #endif
5077 * initvars are different for BCMUSBDEV and BCMSDIODEV. This is OK when supporting both at
5078 * the same time, but only because all of the code is in attach functions and not in ROM.
5081 #if defined(BCMUSBDEV_ENABLED)
5082 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
5084 * Read the USB cis and call parsecis to initialize the vars.
5085 * Return 0 on success, nonzero on error.
5087 static int
5088 BCMATTACHFN(initvars_cis_usbdriver)(si_t *sih, osl_t *osh, char **vars, uint *count)
5090 uint8 *cis;
5091 uint sz = OTP_SZ_MAX/2; /* size in words */
5092 int rc = BCME_OK;
5094 if ((cis = MALLOC(osh, OTP_SZ_MAX)) == NULL) {
5095 return -1;
5098 bzero(cis, OTP_SZ_MAX);
5100 if (otp_read_region(sih, OTP_SW_RGN, (uint16 *)cis, &sz)) {
5101 BS_ERROR(("%s: OTP read SW region failure.\n*", __FUNCTION__));
5102 rc = -2;
5103 } else {
5104 BS_ERROR(("%s: OTP programmed. use OTP for srom vars\n*", __FUNCTION__));
5105 rc = srom_parsecis(osh, &cis, SROM_CIS_SINGLE, vars, count);
5108 MFREE(osh, cis, OTP_SZ_MAX);
5110 return (rc);
5113 /* For driver(not bootloader), if nvram is not downloadable or missing, use default */
5114 static int
5115 BCMATTACHFN(initvars_srom_si_usbdriver)(si_t *sih, osl_t *osh, char **vars, uint *varsz)
5117 uint len;
5118 char *base;
5119 char *fakevars;
5120 int rc = -1;
5122 base = fakevars = NULL;
5123 len = 0;
5124 switch (CHIPID(sih->chip)) {
5125 case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID:
5126 fakevars = defaultsromvars_4322usb;
5127 break;
5128 case BCM43236_CHIP_ID: case BCM43235_CHIP_ID: case BCM43238_CHIP_ID:
5129 case BCM43234_CHIP_ID:
5130 /* check against real chipid instead of compile time flag */
5131 if (sih->chip == BCM43234_CHIP_ID) {
5132 fakevars = defaultsromvars_43234usb;
5133 } else if (sih->chip == BCM43235_CHIP_ID) {
5134 fakevars = defaultsromvars_43235usb;
5135 } else
5136 fakevars = defaultsromvars_43236usb;
5137 break;
5139 case BCM4319_CHIP_ID:
5140 fakevars = defaultsromvars_4319usb;
5141 break;
5142 case BCM43242_CHIP_ID:
5143 case BCM43243_CHIP_ID:
5144 fakevars = defaultsromvars_43242usb;
5145 break;
5147 case BCM4350_CHIP_ID:
5148 fakevars = defaultsromvars_4350usb;
5149 break;
5151 case BCM4360_CHIP_ID:
5152 case BCM4352_CHIP_ID:
5153 case BCM43460_CHIP_ID:
5154 case BCM43526_CHIP_ID:
5155 fakevars = defaultsromvars_4360usb;
5156 break;
5157 case BCM43143_CHIP_ID:
5158 fakevars = defaultsromvars_43143usb;
5159 break;
5160 default:
5161 ASSERT(0);
5162 return rc;
5165 #ifndef BCM_BMAC_VARS_APPEND
5166 if (BCME_OK == initvars_cis_usbdriver(sih, osh, vars, varsz)) {
5167 /* Make OTP/SROM variables global */
5168 if (srvars_inited == FALSE)
5169 nvram_append((void *)sih, *vars, *varsz);
5170 return BCME_OK;
5172 #endif /* BCM_BMAC_VARS_APPEND */
5174 /* NO OTP, if nvram downloaded, use it */
5175 if ((_varsz != 0) && (_vars != NULL)) {
5176 len = _varsz + (strlen(vstr_end));
5177 base = MALLOC(osh, len + 2); /* plus 2 terminating \0 */
5178 if (base == NULL) {
5179 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
5180 return BCME_ERROR;
5182 bzero(base, len + 2);
5184 /* make a copy of the _vars, _vars is at the top of the memory, cannot append
5185 * END\0\0 to it. copy the download vars to base, back of the terminating \0,
5186 * then append END\0\0
5188 bcopy((void *)_vars, base, _varsz);
5189 /* backoff all the terminating \0s except the one the for the last string */
5190 len = _varsz;
5191 while (!base[len - 1])
5192 len--;
5193 len++; /* \0 for the last string */
5194 /* append END\0\0 to the end */
5195 bcopy((void *)vstr_end, (base + len), strlen(vstr_end));
5196 len += (strlen(vstr_end) + 2);
5197 *vars = base;
5198 *varsz = len;
5200 BS_ERROR(("%s USB nvram downloaded %d bytes\n", __FUNCTION__, _varsz));
5201 } else {
5202 /* Fall back to fake srom vars if OTP not programmed */
5203 len = srom_vars_len(fakevars);
5204 base = MALLOC(osh, (len + 1));
5205 if (base == NULL) {
5206 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
5207 return BCME_ERROR;
5209 bzero(base, (len + 1));
5210 bcopy(fakevars, base, len);
5211 *(base + len) = '\0'; /* add final nullbyte terminator */
5212 *vars = base;
5213 *varsz = len + 1;
5214 BS_ERROR(("initvars_srom_usbdriver: faked nvram %d bytes\n", len));
5217 #ifdef BCM_BMAC_VARS_APPEND
5218 if (BCME_OK == initvars_cis_usbdriver(sih, osh, vars, varsz)) {
5219 if (base)
5220 MFREE(osh, base, (len + 1));
5222 #endif /* BCM_BMAC_VARS_APPEND */
5223 /* Make OTP/SROM variables global */
5224 if (srvars_inited == FALSE) {
5225 nvram_append((void *)sih, *vars, *varsz);
5226 srvars_inited = TRUE;
5228 return BCME_OK;
5231 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
5233 #ifdef BCM_DONGLEVARS
5234 static int
5235 BCMATTACHFN(initvars_srom_si_bl)(si_t *sih, osl_t *osh, void *curmap, char **vars, uint *varsz)
5237 int sel = 0; /* where to read srom/cis: 0 - none, 1 - otp, 2 - sprom */
5238 uint sz = 0; /* srom size in bytes */
5239 void *oh = NULL;
5240 int rc = BCME_OK;
5242 if ((oh = otp_init(sih)) != NULL && (otp_status(oh) & OTPS_GUP_SW)) {
5243 /* Access OTP if it is present, powered on, and programmed */
5244 sz = otp_size(oh);
5245 sel = 1;
5246 } else if ((sz = srom_size(sih, osh)) != 0) {
5247 /* Access the SPROM if it is present */
5248 sz <<= 1;
5249 sel = 2;
5252 /* Read CIS in OTP/SPROM */
5253 if (sel != 0) {
5254 uint16 *srom;
5255 uint8 *body = NULL;
5256 uint otpsz = sz;
5258 ASSERT(sz);
5260 /* Allocate memory */
5261 if ((srom = (uint16 *)MALLOC(osh, sz)) == NULL)
5262 return BCME_NOMEM;
5264 /* Read CIS */
5265 switch (sel) {
5266 case 1:
5267 rc = otp_read_region(sih, OTP_SW_RGN, srom, &otpsz);
5268 sz = otpsz;
5269 body = (uint8 *)srom;
5270 break;
5271 case 2:
5272 rc = srom_read(sih, SI_BUS, curmap, osh, 0, sz, srom, TRUE);
5273 /* sprom has 8 byte h/w header */
5274 body = (uint8 *)srom + SBSDIO_SPROM_CIS_OFFSET;
5275 break;
5276 default:
5277 /* impossible to come here */
5278 ASSERT(0);
5279 break;
5282 /* Parse CIS */
5283 if (rc == BCME_OK) {
5284 /* each word is in host endian */
5285 htol16_buf((uint8 *)srom, sz);
5286 ASSERT(body);
5287 rc = srom_parsecis(osh, &body, SROM_CIS_SINGLE, vars, varsz);
5290 MFREE(osh, srom, sz); /* Clean up */
5292 /* Make SROM variables global */
5293 if (rc == BCME_OK)
5294 nvram_append((void *)sih, *vars, *varsz);
5297 return BCME_OK;
5299 #endif /* #ifdef BCM_DONGLEVARS */
5301 static int
5302 BCMATTACHFN(initvars_srom_si)(si_t *sih, osl_t *osh, void *curmap, char **vars, uint *varsz)
5305 /* Bail out if we've dealt with OTP/SPROM before! */
5306 if (srvars_inited)
5307 goto exit;
5309 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
5310 /* read OTP or use faked var array */
5311 switch (CHIPID(sih->chip)) {
5312 case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID:
5313 case BCM43236_CHIP_ID: case BCM43235_CHIP_ID: case BCM43238_CHIP_ID:
5314 case BCM43234_CHIP_ID:
5315 case BCM4319_CHIP_ID:
5316 case BCM43242_CHIP_ID:
5317 case BCM43243_CHIP_ID:
5318 case BCM4360_CHIP_ID:
5319 case BCM43460_CHIP_ID:
5320 case BCM4352_CHIP_ID:
5321 case BCM43526_CHIP_ID:
5322 case BCM4350_CHIP_ID:
5323 case BCM43143_CHIP_ID:
5324 if (BCME_OK != initvars_srom_si_usbdriver(sih, osh, vars, varsz))
5325 goto exit;
5326 return BCME_OK;
5327 default:
5328 UNUSED_PARAMETER(defaultsromvars_4322usb);
5329 UNUSED_PARAMETER(defaultsromvars_43234usb);
5330 UNUSED_PARAMETER(defaultsromvars_43235usb);
5331 UNUSED_PARAMETER(defaultsromvars_43236usb);
5332 UNUSED_PARAMETER(defaultsromvars_4319usb);
5333 UNUSED_PARAMETER(defaultsromvars_43242usb);
5334 UNUSED_PARAMETER(defaultsromvars_43143usb);
5336 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
5338 #ifdef BCM_DONGLEVARS /* this flag should be defined for usb bootloader, to read \
5339 OTP or SROM */
5340 if (BCME_OK != initvars_srom_si_bl(sih, osh, curmap, vars, varsz))
5341 return BCME_ERROR;
5342 #endif
5344 /* update static local var to skip for next call */
5345 srvars_inited = TRUE;
5347 exit:
5348 /* Tell the caller there is no individual SROM variables */
5349 *vars = NULL;
5350 *varsz = 0;
5352 /* return OK so the driver will load & use defaults if bad srom/otp */
5353 return BCME_OK;
5356 #elif defined(BCMSDIODEV_ENABLED)
5358 #ifdef BCM_DONGLEVARS
5359 static uint8 BCMATTACHDATA(defcis4325)[] = { 0x20, 0x4, 0xd0, 0x2, 0x25, 0x43, 0xff, 0xff };
5360 static uint8 BCMATTACHDATA(defcis4315)[] = { 0x20, 0x4, 0xd0, 0x2, 0x15, 0x43, 0xff, 0xff };
5361 static uint8 BCMATTACHDATA(defcis4329)[] = { 0x20, 0x4, 0xd0, 0x2, 0x29, 0x43, 0xff, 0xff };
5362 static uint8 BCMATTACHDATA(defcis4319)[] = { 0x20, 0x4, 0xd0, 0x2, 0x19, 0x43, 0xff, 0xff };
5363 static uint8 BCMATTACHDATA(defcis4336)[] = { 0x20, 0x4, 0xd0, 0x2, 0x36, 0x43, 0xff, 0xff };
5364 static uint8 BCMATTACHDATA(defcis4330)[] = { 0x20, 0x4, 0xd0, 0x2, 0x30, 0x43, 0xff, 0xff };
5365 static uint8 BCMATTACHDATA(defcis43237)[] = { 0x20, 0x4, 0xd0, 0x2, 0xe5, 0xa8, 0xff, 0xff };
5366 static uint8 BCMATTACHDATA(defcis4324)[] = { 0x20, 0x4, 0xd0, 0x2, 0x24, 0x43, 0xff, 0xff };
5367 static uint8 BCMATTACHDATA(defcis4335)[] = { 0x20, 0x4, 0xd0, 0x2, 0x24, 0x43, 0xff, 0xff };
5368 static uint8 BCMATTACHDATA(defcis4350)[] = { 0x20, 0x4, 0xd0, 0x2, 0x50, 0x43, 0xff, 0xff };
5369 static uint8 BCMATTACHDATA(defcis43143)[] = { 0x20, 0x4, 0xd0, 0x2, 0x87, 0xa8, 0xff, 0xff };
5371 #ifdef BCM_BMAC_VARS_APPEND
5373 static char BCMATTACHDATA(defaultsromvars_4319sdio)[] =
5374 "sromrev=3\0"
5375 "vendid=0x14e4\0"
5376 "devid=0x4338\0"
5377 "boardtype=0x05a1\0"
5378 "boardrev=0x1102\0"
5379 "boardflags=0x400201\0"
5380 "boardflags2=0x80\0"
5381 "xtalfreq=26000\0"
5382 "aa2g=3\0"
5383 "aa5g=0\0"
5384 "ag0=0\0"
5385 "opo=0\0"
5386 "pa0b0=0x1675\0"
5387 "pa0b1=0xfa74\0"
5388 "pa0b2=0xfea1\0"
5389 "pa0itssit=62\0"
5390 "pa0maxpwr=78\0"
5391 "rssismf2g=0xa\0"
5392 "rssismc2g=0xb\0"
5393 "rssisav2g=0x3\0"
5394 "bxa2g=0\0"
5395 "cckdigfilttype=6\0"
5396 "rxpo2g=2\0"
5397 "cckpo=0\0"
5398 "ofdmpo=0x55553333\0"
5399 "mcs2gpo0=0x9999\0"
5400 "mcs2gpo1=0x9999\0"
5401 "mcs2gpo2=0x0000\0"
5402 "mcs2gpo3=0x0000\0"
5403 "mcs2gpo4=0x9999\0"
5404 "mcs2gpo5=0x9999\0"
5405 "macaddr=00:90:4c:06:c0:19\0"
5406 "END\0";
5408 static char BCMATTACHDATA(defaultsromvars_4319sdio_hmb)[] =
5409 "sromrev=3\0"
5410 "vendid=0x14e4\0"
5411 "devid=0x4338\0"
5412 "boardtype=0x058c\0"
5413 "boardrev=0x1102\0"
5414 "boardflags=0x400201\0"
5415 "boardflags2=0x80\0"
5416 "xtalfreq=26000\0"
5417 "aa2g=3\0"
5418 "aa5g=0\0"
5419 "ag0=0\0"
5420 "opo=0\0"
5421 "pa0b0=0x1675\0"
5422 "pa0b1=0xfa74\0"
5423 "pa0b2=0xfea1\0"
5424 "pa0itssit=62\0"
5425 "pa0maxpwr=78\0"
5426 "rssismf2g=0xa \0"
5427 "rssismc2g=0xb \0"
5428 "rssisav2g=0x3 \0"
5429 "bxa2g=0\0"
5430 "cckdigfilttype=6\0"
5431 "rxpo2g=2\0"
5432 "cckpo=0\0"
5433 "ofdmpo=0x55553333\0"
5434 "mcs2gpo0=0x9999\0"
5435 "mcs2gpo1=0x9999\0"
5436 "mcs2gpo2=0x0000\0"
5437 "mcs2gpo3=0x0000\0"
5438 "mcs2gpo4=0x9999\0"
5439 "mcs2gpo5=0x9999\0"
5440 "macaddr=00:90:4c:06:c0:19\0"
5441 "END\0";
5443 static char BCMATTACHDATA(defaultsromvars_4319sdio_usbsd)[] =
5444 "sromrev=3\0"
5445 "vendid=0x14e4\0"
5446 "devid=0x4338\0"
5447 "boardtype=0x05a2\0"
5448 "boardrev=0x1100\0"
5449 "boardflags=0x400201\0"
5450 "boardflags2=0x80\0"
5451 "xtalfreq=30000\0"
5452 "aa2g=3\0"
5453 "aa5g=0\0"
5454 "ag0=0\0"
5455 "opo=0\0"
5456 "pa0b0=0x1675\0"
5457 "pa0b1=0xfa74\0"
5458 "pa0b2=0xfea1\0"
5459 "pa0itssit=62\0"
5460 "pa0maxpwr=78\0"
5461 "rssismf2g=0xa \0"
5462 "rssismc2g=0xb \0"
5463 "rssisav2g=0x3 \0"
5464 "bxa2g=0\0"
5465 "cckdigfilttype=6\0"
5466 "rxpo2g=2\0"
5467 "cckpo=0\0"
5468 "ofdmpo=0x55553333\0"
5469 "mcs2gpo0=0x9999\0"
5470 "mcs2gpo1=0x9999\0"
5471 "mcs2gpo2=0x0000\0"
5472 "mcs2gpo3=0x0000\0"
5473 "mcs2gpo4=0x9999\0"
5474 "mcs2gpo5=0x9999\0"
5475 "macaddr=00:90:4c:08:90:00\0"
5476 "END\0";
5478 static char BCMATTACHDATA(defaultsromvars_43237)[] =
5479 "vendid=0x14e4\0"
5480 "devid=0x4355\0"
5481 "boardtype=0x0583\0"
5482 "boardrev=0x1103\0"
5483 "boardnum=0x1\0"
5484 "boardflags=0x200\0"
5485 "boardflags2=0\0"
5486 "sromrev=8\0"
5487 "macaddr=00:90:4c:51:a8:e4\0"
5488 "ccode=0\0"
5489 "regrev=0\0"
5490 "ledbh0=0xff\0"
5491 "ledbh1=0xff\0"
5492 "ledbh2=0xff\0"
5493 "ledbh3=0xff\0"
5494 "leddc=0xffff\0"
5495 "opo=0x0\0"
5496 "aa2g=0x3\0"
5497 "aa5g=0x3\0"
5498 "ag0=0x2\0"
5499 "ag1=0x2\0"
5500 "ag2=0xff\0"
5501 "ag3=0xff\0"
5502 "pa0b0=0xfed1\0"
5503 "pa0b1=0x15fd\0"
5504 "pa0b2=0xfac2\0"
5505 "pa0itssit=0x20\0"
5506 "pa0maxpwr=0x4c\0"
5507 "pa1b0=0xfecd\0"
5508 "pa1b1=0x1497\0"
5509 "pa1b2=0xfae3\0"
5510 "pa1lob0=0xfe87\0"
5511 "pa1lob1=0x1637\0"
5512 "pa1lob2=0xfa8e\0"
5513 "pa1hib0=0xfedc\0"
5514 "pa1hib1=0x144b\0"
5515 "pa1hib2=0xfb01\0"
5516 "pa1itssit=0x3e\0"
5517 "pa1maxpwr=0x40\0"
5518 "pa1lomaxpwr=0x3a\0"
5519 "pa1himaxpwr=0x3c\0"
5520 "bxa2g=0x3\0"
5521 "rssisav2g=0x7\0"
5522 "rssismc2g=0xf\0"
5523 "rssismf2g=0xf\0"
5524 "bxa5g=0x3\0"
5525 "rssisav5g=0x7\0"
5526 "rssismc5g=0xf\0"
5527 "rssismf5g=0xf\0"
5528 "tri2g=0xff\0"
5529 "tri5g=0xff\0"
5530 "tri5gl=0xff\0"
5531 "tri5gh=0xff\0"
5532 "rxpo2g=0xff\0"
5533 "rxpo5g=0xff\0"
5534 "txchain=0x3\0"
5535 "rxchain=0x3\0"
5536 "antswitch=0x0\0"
5537 "tssipos2g=0x1\0"
5538 "extpagain2g=0x2\0"
5539 "pdetrange2g=0x2\0"
5540 "triso2g=0x3\0"
5541 "antswctl2g=0x0\0"
5542 "tssipos5g=0x1\0"
5543 "extpagain5g=0x2\0"
5544 "pdetrange5g=0x2\0"
5545 "triso5g=0x3\0"
5546 "cck2gpo=0x0\0"
5547 "ofdm2gpo=0x0\0"
5548 "ofdm5gpo=0x0\0"
5549 "ofdm5glpo=0x0\0"
5550 "ofdm5ghpo=0x0\0"
5551 "mcs2gpo0=0x0\0"
5552 "mcs2gpo1=0x0\0"
5553 "mcs2gpo2=0x0\0"
5554 "mcs2gpo3=0x0\0"
5555 "mcs2gpo4=0x0\0"
5556 "mcs2gpo5=0x0\0"
5557 "mcs2gpo6=0x0\0"
5558 "mcs2gpo7=0x0\0"
5559 "mcs5gpo0=0x0\0"
5560 "mcs5gpo1=0x0\0"
5561 "mcs5gpo2=0x0\0"
5562 "mcs5gpo3=0x0\0"
5563 "mcs5gpo4=0x0\0"
5564 "mcs5gpo5=0x0\0"
5565 "mcs5gpo6=0x0\0"
5566 "mcs5gpo7=0x0\0"
5567 "mcs5glpo0=0x0\0"
5568 "mcs5glpo1=0x0\0"
5569 "mcs5glpo2=0x0\0"
5570 "mcs5glpo3=0x0\0"
5571 "mcs5glpo4=0x0\0"
5572 "mcs5glpo5=0x0\0"
5573 "mcs5glpo6=0x0\0"
5574 "mcs5glpo7=0x0\0"
5575 "mcs5ghpo0=0x0\0"
5576 "mcs5ghpo1=0x0\0"
5577 "mcs5ghpo2=0x0\0"
5578 "mcs5ghpo3=0x0\0"
5579 "mcs5ghpo4=0x0\0"
5580 "mcs5ghpo5=0x0\0"
5581 "mcs5ghpo6=0x0\0"
5582 "mcs5ghpo7=0x0\0"
5583 "cddpo=0x0\0"
5584 "stbcpo=0x0\0"
5585 "bw40po=0x0\0"
5586 "bwduppo=0x0\0"
5587 "maxp2ga0=0x4c\0"
5588 "pa2gw0a0=0xfed1\0"
5589 "pa2gw1a0=0x15fd\0"
5590 "pa2gw2a0=0xfac2\0"
5591 "maxp5ga0=0x3c\0"
5592 "maxp5gha0=0x3c\0"
5593 "maxp5gla0=0x3c\0"
5594 "pa5gw0a0=0xfeb0\0"
5595 "pa5gw1a0=0x1491\0"
5596 "pa5gw2a0=0xfaf8\0"
5597 "pa5glw0a0=0xfeaa\0"
5598 "pa5glw1a0=0x14b9\0"
5599 "pa5glw2a0=0xfaf0\0"
5600 "pa5ghw0a0=0xfec5\0"
5601 "pa5ghw1a0=0x1439\0"
5602 "pa5ghw2a0=0xfb18\0"
5603 "maxp2ga1=0x4c\0"
5604 "itt2ga0=0x20\0"
5605 "itt5ga0=0x3e\0"
5606 "itt2ga1=0x20\0"
5607 "itt5ga1=0x3e\0"
5608 "pa2gw0a1=0xfed2\0"
5609 "pa2gw1a1=0x15d9\0"
5610 "pa2gw2a1=0xfac6\0"
5611 "maxp5ga1=0x3a\0"
5612 "maxp5gha1=0x3a\0"
5613 "maxp5gla1=0x3a\0"
5614 "pa5gw0a1=0xfebe\0"
5615 "pa5gw1a1=0x1306\0"
5616 "pa5gw2a1=0xfb63\0"
5617 "pa5glw0a1=0xfece\0"
5618 "pa5glw1a1=0x1361\0"
5619 "pa5glw2a1=0xfb5f\0"
5620 "pa5ghw0a1=0xfe9e\0"
5621 "pa5ghw1a1=0x12ca\0"
5622 "pa5ghw2a1=0xfb41\0"
5623 "END\0";
5625 static char BCMATTACHDATA(defaultsromvars_43143sdio)[] =
5626 "vendid=0x14e4\0"
5627 "subvendid=0x0a5c\0"
5628 "subdevid=0xbdc\0"
5629 "macaddr=00:90:4c:0e:81:23\0"
5630 "xtalfreq=20000\0"
5631 "cctl=0\0"
5632 "ccode=US\0"
5633 "regrev=0x0\0"
5634 "ledbh0=0xff\0"
5635 "ledbh1=0xff\0"
5636 "ledbh2=0xff\0"
5637 "ledbh3=0xff\0"
5638 "leddc=0xffff\0"
5639 "aa2g=0x3\0"
5640 "ag0=0x2\0"
5641 "txchain=0x1\0"
5642 "rxchain=0x1\0"
5643 "antswitch=0\0"
5644 "sromrev=10\0"
5645 "devid=0x4366\0"
5646 "boardrev=0x1100\0"
5647 "boardflags=0x200\0"
5648 "boardflags2=0x2000\0"
5649 "boardtype=0x0628\0"
5650 "tssipos2g=0x1\0"
5651 "extpagain2g=0x0\0"
5652 "pdetrange2g=0x0\0"
5653 "triso2g=0x3\0"
5654 "antswctl2g=0x0\0"
5655 "ofdm2gpo=0x0\0"
5656 "mcs2gpo0=0x0\0"
5657 "mcs2gpo1=0x0\0"
5658 "maxp2ga0=0x48\0"
5659 "tempthresh=120\0"
5660 "temps_period=5\0"
5661 "temp_hysteresis=5\0"
5662 "boardnum=0x1100\0"
5663 "pa0b0=5832\0"
5664 "pa0b1=-705\0"
5665 "pa0b2=-170\0"
5666 "cck2gpo=0\0"
5667 "swctrlmap_2g=0x06020602,0x0c080c08,0x04000400,0x00080808,0x6ff\0"
5668 "otpimagesize=154\0"
5669 "END\0";
5671 static int
5672 srom_load_nvram(si_t *sih, osl_t *osh, uint8 *pcis[], uint ciscnt, char **vars, uint *varsz)
5674 uint len = 0, base_len;
5675 char *base;
5676 char *fakevars;
5678 base = fakevars = NULL;
5679 switch (CHIPID(sih->chip)) {
5680 case BCM4319_CHIP_ID:
5681 printf("load driver default for chip %x\n", CHIPID(sih->chip));
5682 fakevars = defaultsromvars_4319sdio;
5683 if (si_cis_source(sih) == CIS_OTP) {
5684 switch (srom_probe_boardtype(pcis, ciscnt)) {
5685 case BCM94319SDHMB_SSID:
5686 fakevars = defaultsromvars_4319sdio_hmb;
5687 break;
5688 case BCM94319USBSDB_SSID:
5689 fakevars = defaultsromvars_4319sdio_usbsd;
5690 break;
5691 default:
5692 fakevars = defaultsromvars_4319sdio;
5693 break;
5696 break;
5697 case BCM43237_CHIP_ID:
5698 printf("load driver default for chip %x\n", CHIPID(sih->chip));
5699 fakevars = defaultsromvars_43237;
5700 break;
5701 case BCM43143_CHIP_ID:
5702 printf("load driver default for chip %x\n", CHIPID(sih->chip));
5703 fakevars = defaultsromvars_43143sdio;
5704 break;
5705 default:
5706 printf("unknown chip %x\n", CHIPID(sih->chip));
5707 return BCME_ERROR; /* fakevars == NULL for switch default */
5711 /* NO OTP, if nvram downloaded, use it */
5712 if ((_varsz != 0) && (_vars != NULL)) {
5713 len = _varsz + (strlen(vstr_end));
5714 base_len = len + 2; /* plus 2 terminating \0 */
5715 base = MALLOC(osh, base_len);
5716 if (base == NULL) {
5717 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
5718 return BCME_ERROR;
5720 bzero(base, base_len);
5722 /* make a copy of the _vars, _vars is at the top of the memory, cannot append
5723 * END\0\0 to it. copy the download vars to base, back of the terminating \0,
5724 * then append END\0\0
5726 bcopy((void *)_vars, base, _varsz);
5727 /* backoff all the terminating \0s except the one the for the last string */
5728 len = _varsz;
5729 while (!base[len - 1])
5730 len--;
5731 len++; /* \0 for the last string */
5732 /* append END\0\0 to the end */
5733 bcopy((void *)vstr_end, (base + len), strlen(vstr_end));
5734 len += (strlen(vstr_end) + 2);
5735 *vars = base;
5736 *varsz = len;
5738 BS_ERROR(("%s nvram downloaded %d bytes\n", __FUNCTION__, _varsz));
5739 } else {
5740 /* Fall back to fake srom vars if OTP not programmed */
5741 len = srom_vars_len(fakevars);
5742 base = MALLOC(osh, (len + 1));
5743 base_len = len + 1;
5744 if (base == NULL) {
5745 BS_ERROR(("initvars_srom_si: MALLOC failed.\n"));
5746 return BCME_ERROR;
5748 bzero(base, base_len);
5749 bcopy(fakevars, base, len);
5750 *(base + len) = '\0'; /* add final nullbyte terminator */
5751 *vars = base;
5752 *varsz = len + 1;
5753 BS_ERROR(("srom_load_driver)default: faked nvram %d bytes\n", len));
5755 /* Parse the CIS */
5756 if ((srom_parsecis(osh, pcis, ciscnt, vars, varsz)) == BCME_OK)
5757 nvram_append((void *)sih, *vars, *varsz);
5758 MFREE(osh, base, base_len);
5759 return BCME_OK;
5762 #endif /* BCM_BMAC_VARS_APPEND */
5764 static int
5765 BCMATTACHFN(initvars_srom_si)(si_t *sih, osl_t *osh, void *curmap, char **vars, uint *varsz)
5767 int cis_src;
5768 uint msz = 0;
5769 uint sz = 0;
5770 void *oh = NULL;
5771 int rc = BCME_OK;
5772 bool new_cisformat = FALSE;
5774 uint16 *cisbuf = NULL;
5776 /* # sdiod fns + common + extra */
5777 uint8 *cis[SBSDIO_NUM_FUNCTION + 2] = { 0 };
5779 uint ciss = 0;
5780 uint8 *defcis;
5781 uint hdrsz;
5783 /* Bail out if we've dealt with OTP/SPROM before! */
5784 if (srvars_inited)
5785 goto exit;
5787 /* Initialize default and cis format count */
5788 switch (CHIPID(sih->chip)) {
5789 case BCM4325_CHIP_ID: ciss = 3; defcis = defcis4325; hdrsz = 8; break;
5790 case BCM4315_CHIP_ID: ciss = 3; defcis = defcis4315; hdrsz = 8; break;
5791 case BCM4329_CHIP_ID: ciss = 4; defcis = defcis4329; hdrsz = 12; break;
5792 case BCM4319_CHIP_ID: ciss = 3; defcis = defcis4319; hdrsz = 12; break;
5793 case BCM4336_CHIP_ID: ciss = 1; defcis = defcis4336; hdrsz = 4; break;
5794 case BCM43362_CHIP_ID: ciss = 1; defcis = defcis4336; hdrsz = 4; break;
5795 case BCM4330_CHIP_ID: ciss = 1; defcis = defcis4330; hdrsz = 4; break;
5796 case BCM43237_CHIP_ID: ciss = 1; defcis = defcis43237; hdrsz = 4; break;
5797 case BCM4324_CHIP_ID: ciss = 1; defcis = defcis4324; hdrsz = 4; break;
5798 case BCM4314_CHIP_ID: ciss = 1; defcis = defcis4330; hdrsz = 4; break;
5799 case BCM4334_CHIP_ID: ciss = 1; defcis = defcis4330; hdrsz = 4; break;
5800 case BCM4335_CHIP_ID: ciss = 1; defcis = defcis4335; hdrsz = 4; break;
5801 case BCM43143_CHIP_ID: ciss = 1; defcis = defcis43143; hdrsz = 4; break;
5802 default:
5803 BS_ERROR(("%s: Unknown chip 0x%04x\n", __FUNCTION__, sih->chip));
5804 return BCME_ERROR;
5806 if (sih->ccrev >= 36) {
5807 uint32 otplayout;
5808 otplayout = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, otplayout), 0, 0);
5809 if (otplayout & OTP_CISFORMAT_NEW) {
5810 ciss = 1;
5811 hdrsz = 2;
5812 new_cisformat = TRUE;
5814 else {
5815 ciss = 3;
5816 hdrsz = 12;
5820 cis_src = si_cis_source(sih);
5821 switch (cis_src) {
5822 case CIS_SROM:
5823 sz = srom_size(sih, osh) << 1;
5824 break;
5825 case CIS_OTP:
5826 if (((oh = otp_init(sih)) != NULL) && (otp_status(oh) & OTPS_GUP_HW))
5827 sz = otp_size(oh);
5828 break;
5831 if (sz != 0) {
5832 if ((cisbuf = (uint16*)MALLOC(osh, sz)) == NULL)
5833 return BCME_NOMEM;
5834 msz = sz;
5836 switch (cis_src) {
5837 case CIS_SROM:
5838 rc = srom_read(sih, SI_BUS, curmap, osh, 0, sz, cisbuf, FALSE);
5839 break;
5840 case CIS_OTP:
5841 sz >>= 1;
5842 rc = otp_read_region(sih, OTP_HW_RGN, cisbuf, &sz);
5843 sz <<= 1;
5844 break;
5847 ASSERT(sz > hdrsz);
5848 if (rc == BCME_OK) {
5849 if ((cisbuf[0] == 0xffff) || (cisbuf[0] == 0)) {
5850 MFREE(osh, cisbuf, msz);
5851 cisbuf = NULL;
5852 } else if (new_cisformat) {
5853 cis[0] = (uint8*)(cisbuf + hdrsz);
5854 } else {
5855 cis[0] = (uint8*)cisbuf + hdrsz;
5856 cis[1] = (uint8*)cisbuf + hdrsz +
5857 (cisbuf[1] >> 8) + ((cisbuf[2] & 0x00ff) << 8) -
5858 SBSDIO_CIS_BASE_COMMON;
5859 cis[2] = (uint8*)cisbuf + hdrsz +
5860 cisbuf[3] - SBSDIO_CIS_BASE_COMMON;
5861 cis[3] = (uint8*)cisbuf + hdrsz +
5862 cisbuf[4] - SBSDIO_CIS_BASE_COMMON;
5863 ASSERT((cis[1] >= cis[0]) && (cis[1] < (uint8*)cisbuf + sz));
5864 ASSERT((cis[2] >= cis[0]) && (cis[2] < (uint8*)cisbuf + sz));
5865 ASSERT(((cis[3] >= cis[0]) && (cis[3] < (uint8*)cisbuf + sz)) ||
5866 (ciss <= 3));
5871 /* Use default if strapped to, or strapped source empty */
5872 if (cisbuf == NULL) {
5873 ciss = 1;
5874 cis[0] = defcis;
5877 #ifdef BCM_BMAC_VARS_APPEND
5878 srom_load_nvram(sih, osh, cis, ciss, vars, varsz);
5879 #else
5880 /* Parse the CIS */
5881 if (rc == BCME_OK) {
5882 if ((rc = srom_parsecis(osh, cis, ciss, vars, varsz)) == BCME_OK)
5883 nvram_append((void *)sih, *vars, *varsz);
5885 #endif /* BCM_BMAC_VARS_APPEND */
5886 /* Clean up */
5887 if (cisbuf != NULL)
5888 MFREE(osh, cisbuf, msz);
5890 srvars_inited = TRUE;
5891 exit:
5892 /* Tell the caller there is no individual SROM variables */
5893 *vars = NULL;
5894 *varsz = 0;
5896 /* return OK so the driver will load & use defaults if bad srom/otp */
5897 return BCME_OK;
5899 #else /* BCM_DONGLEVARS */
5900 static int
5901 BCMATTACHFN(initvars_srom_si)(si_t *sih, osl_t *osh, void *curmap, char **vars, uint *varsz)
5903 *vars = NULL;
5904 *varsz = 0;
5905 return BCME_OK;
5907 #endif /* BCM_DONGLEVARS */
5909 #else /* !BCMUSBDEV && !BCMSDIODEV */
5911 static int
5912 BCMATTACHFN(initvars_srom_si)(si_t *sih, osl_t *osh, void *curmap, char **vars, uint *varsz)
5914 /* Search flash nvram section for srom variables */
5915 return initvars_flash_si(sih, vars, varsz);
5917 #endif
5919 void
5920 srom_var_deinit(si_t *sih)
5922 srvars_inited = FALSE;
5925 extern void _make_gcc_happy_about_unused_variabe_(void);
5926 void
5927 _make_gcc_happy_about_unused_variabe_(void)
5929 #if defined(BCMUSBDEV)
5930 #if defined(BCMUSBDEV_BMAC) || defined(BCM_BMAC_VARS_APPEND)
5931 UNUSED_PARAMETER(defaultsromvars_4322usb);
5932 UNUSED_PARAMETER(defaultsromvars_43234usb);
5933 UNUSED_PARAMETER(defaultsromvars_43235usb);
5934 UNUSED_PARAMETER(defaultsromvars_43236usb);
5935 UNUSED_PARAMETER(defaultsromvars_4319usb);
5936 #endif /* BCMUSBDEV_BMAC || BCM_BMAC_VARS_APPEND */
5937 #endif /* BCMUSBDEV */